830 lines
30 KiB
C++
830 lines
30 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <progressmonitor.hxx>
|
|
|
|
#include <com/sun/star/awt/XFixedText.hpp>
|
|
#include <com/sun/star/awt/XGraphics.hpp>
|
|
#include <com/sun/star/awt/PosSize.hpp>
|
|
#include <com/sun/star/uno/XComponentContext.hpp>
|
|
#include <cppuhelper/typeprovider.hxx>
|
|
#include <cppuhelper/queryinterface.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
#include <tools/debug.hxx>
|
|
#include <algorithm>
|
|
|
|
#include <progressbar.hxx>
|
|
|
|
using namespace ::cppu;
|
|
using namespace ::osl;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star::lang;
|
|
using namespace ::com::sun::star::awt;
|
|
|
|
using ::std::vector;
|
|
|
|
constexpr OUString FIXEDTEXT_SERVICENAME = u"com.sun.star.awt.UnoControlFixedText"_ustr;
|
|
constexpr OUString FIXEDTEXT_MODELNAME = u"com.sun.star.awt.UnoControlFixedTextModel"_ustr;
|
|
constexpr OUString CONTROLNAME_TEXT = u"Text"_ustr; // identifier the control in container
|
|
constexpr OUStringLiteral CONTROLNAME_PROGRESSBAR = u"ProgressBar";
|
|
constexpr OUStringLiteral BUTTON_SERVICENAME = u"com.sun.star.awt.UnoControlButton";
|
|
constexpr OUStringLiteral CONTROLNAME_BUTTON = u"Button";
|
|
constexpr OUStringLiteral BUTTON_MODELNAME = u"com.sun.star.awt.UnoControlButtonModel";
|
|
constexpr OUStringLiteral DEFAULT_BUTTONLABEL = u"Abbrechen";
|
|
|
|
namespace unocontrols {
|
|
|
|
ProgressMonitor::ProgressMonitor( const css::uno::Reference< XComponentContext >& rxContext )
|
|
: BaseContainerControl ( rxContext )
|
|
{
|
|
// It's not allowed to work with member in this method (refcounter !!!)
|
|
// But with a HACK (++refcount) its "OK" :-(
|
|
osl_atomic_increment(&m_refCount);
|
|
|
|
// Create instances for fixedtext, button and progress ...
|
|
|
|
m_xTopic_Top.set ( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_SERVICENAME, rxContext ), UNO_QUERY );
|
|
m_xText_Top.set ( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_SERVICENAME, rxContext ), UNO_QUERY );
|
|
m_xTopic_Bottom.set( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_SERVICENAME, rxContext ), UNO_QUERY );
|
|
m_xText_Bottom.set ( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_SERVICENAME, rxContext ), UNO_QUERY );
|
|
m_xButton.set ( rxContext->getServiceManager()->createInstanceWithContext( BUTTON_SERVICENAME, rxContext ), UNO_QUERY );
|
|
m_xProgressBar = new ProgressBar(rxContext);
|
|
|
|
// ... cast controls to Reference< XControl > (for "setModel"!) ...
|
|
css::uno::Reference< XControl > xRef_Topic_Top ( m_xTopic_Top , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Text_Top ( m_xText_Top , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Topic_Bottom ( m_xTopic_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Text_Bottom ( m_xText_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Button ( m_xButton , UNO_QUERY );
|
|
|
|
// ... set models ...
|
|
xRef_Topic_Top->setModel ( css::uno::Reference< XControlModel > ( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_MODELNAME, rxContext ), UNO_QUERY ) );
|
|
xRef_Text_Top->setModel ( css::uno::Reference< XControlModel > ( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_MODELNAME, rxContext ), UNO_QUERY ) );
|
|
xRef_Topic_Bottom->setModel ( css::uno::Reference< XControlModel > ( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_MODELNAME, rxContext ), UNO_QUERY ) );
|
|
xRef_Text_Bottom->setModel ( css::uno::Reference< XControlModel > ( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_MODELNAME, rxContext ), UNO_QUERY ) );
|
|
xRef_Button->setModel ( css::uno::Reference< XControlModel > ( rxContext->getServiceManager()->createInstanceWithContext( BUTTON_MODELNAME, rxContext ), UNO_QUERY ) );
|
|
// ProgressBar has no model !!!
|
|
|
|
// ... and add controls to basecontainercontrol!
|
|
addControl ( CONTROLNAME_TEXT, xRef_Topic_Top );
|
|
addControl ( CONTROLNAME_TEXT, xRef_Text_Top );
|
|
addControl ( CONTROLNAME_TEXT, xRef_Topic_Bottom );
|
|
addControl ( CONTROLNAME_TEXT, xRef_Text_Bottom );
|
|
addControl ( CONTROLNAME_BUTTON, xRef_Button );
|
|
addControl ( CONTROLNAME_PROGRESSBAR, m_xProgressBar );
|
|
|
|
// FixedText make it automatically visible by himself ... but not the progressbar !!!
|
|
// it must be set explicitly
|
|
m_xProgressBar->setVisible( true );
|
|
|
|
// Reset to defaults !!!
|
|
// (progressbar take automatically its own defaults)
|
|
m_xButton->setLabel ( DEFAULT_BUTTONLABEL );
|
|
m_xTopic_Top->setText ( PROGRESSMONITOR_DEFAULT_TOPIC );
|
|
m_xText_Top->setText ( PROGRESSMONITOR_DEFAULT_TEXT );
|
|
m_xTopic_Bottom->setText ( PROGRESSMONITOR_DEFAULT_TOPIC );
|
|
m_xText_Bottom->setText ( PROGRESSMONITOR_DEFAULT_TEXT );
|
|
|
|
osl_atomic_decrement(&m_refCount);
|
|
}
|
|
|
|
ProgressMonitor::~ProgressMonitor()
|
|
{
|
|
impl_cleanMemory ();
|
|
}
|
|
|
|
// XInterface
|
|
Any SAL_CALL ProgressMonitor::queryInterface( const Type& rType )
|
|
{
|
|
// Ask for my own supported interfaces ...
|
|
// Attention: XTypeProvider and XInterface are supported by WeakComponentImplHelper!
|
|
Any aReturn ( ::cppu::queryInterface( rType ,
|
|
static_cast< XLayoutConstrains* > ( this ) ,
|
|
static_cast< XButton* > ( this ) ,
|
|
static_cast< XProgressMonitor* > ( this )
|
|
)
|
|
);
|
|
|
|
if (aReturn.hasValue())
|
|
return aReturn;
|
|
|
|
// If searched interface not supported by this class ...
|
|
// ... ask baseclasses.
|
|
return BaseControl::queryInterface(rType);
|
|
}
|
|
|
|
// XInterface
|
|
void SAL_CALL ProgressMonitor::acquire() noexcept
|
|
{
|
|
// Attention:
|
|
// Don't use mutex or guard in this method!!! Is a method of XInterface.
|
|
|
|
// Forward to baseclass
|
|
BaseControl::acquire();
|
|
}
|
|
|
|
// XInterface
|
|
void SAL_CALL ProgressMonitor::release() noexcept
|
|
{
|
|
// Attention:
|
|
// Don't use mutex or guard in this method!!! Is a method of XInterface.
|
|
|
|
// Forward to baseclass
|
|
BaseControl::release();
|
|
}
|
|
|
|
// XTypeProvider
|
|
Sequence< Type > SAL_CALL ProgressMonitor::getTypes()
|
|
{
|
|
static OTypeCollection ourTypeCollection(
|
|
cppu::UnoType<XLayoutConstrains>::get(),
|
|
cppu::UnoType<XButton>::get(),
|
|
cppu::UnoType<XProgressMonitor>::get(),
|
|
BaseContainerControl::getTypes() );
|
|
|
|
return ourTypeCollection.getTypes();
|
|
}
|
|
|
|
// XProgressMonitor
|
|
void SAL_CALL ProgressMonitor::addText(
|
|
const OUString& rTopic,
|
|
const OUString& rText,
|
|
sal_Bool bbeforeProgress
|
|
)
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// Safe impossible cases
|
|
// Check valid call of this method.
|
|
DBG_ASSERT ( impl_debug_checkParameter ( rTopic, rText ), "ProgressMonitor::addText()\nCall without valid parameters!\n");
|
|
DBG_ASSERT ( !(impl_searchTopic ( rTopic, bbeforeProgress ) != nullptr ), "ProgressMonitor::addText()\nThe text already exist.\n" );
|
|
|
|
// Do nothing (in Release), if topic already exist.
|
|
if ( impl_searchTopic ( rTopic, bbeforeProgress ) != nullptr )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Else ... take memory for new item ...
|
|
IMPL_TextlistItem aTextItem;
|
|
|
|
// Set values ...
|
|
aTextItem.sTopic = rTopic;
|
|
aTextItem.sText = rText;
|
|
|
|
// ... and insert it in right list.
|
|
if ( bbeforeProgress )
|
|
{
|
|
maTextlist_Top.push_back( aTextItem );
|
|
}
|
|
else
|
|
{
|
|
maTextlist_Bottom.push_back( aTextItem );
|
|
}
|
|
|
|
// ... update window
|
|
impl_rebuildFixedText ();
|
|
impl_recalcLayout ();
|
|
}
|
|
|
|
// XProgressMonitor
|
|
void SAL_CALL ProgressMonitor::removeText ( const OUString& rTopic, sal_Bool bbeforeProgress )
|
|
{
|
|
// Safe impossible cases
|
|
// Check valid call of this method.
|
|
DBG_ASSERT ( impl_debug_checkParameter ( rTopic ), "ProgressMonitor::removeText()\nCall without valid parameters!" );
|
|
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// Search the topic ...
|
|
IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress );
|
|
|
|
if ( pSearchItem == nullptr )
|
|
return;
|
|
|
|
// ... delete item from right list ...
|
|
if ( bbeforeProgress )
|
|
{
|
|
auto itr = std::find_if( maTextlist_Top.begin(), maTextlist_Top.end(),
|
|
[&] (IMPL_TextlistItem const &p)
|
|
{ return &p == pSearchItem; } );
|
|
if (itr != maTextlist_Top.end())
|
|
maTextlist_Top.erase(itr);
|
|
}
|
|
else
|
|
{
|
|
auto itr = std::find_if( maTextlist_Bottom.begin(), maTextlist_Bottom.end(),
|
|
[&] (IMPL_TextlistItem const &p)
|
|
{ return &p == pSearchItem; } );
|
|
if (itr != maTextlist_Bottom.end())
|
|
maTextlist_Bottom.erase(itr);
|
|
}
|
|
|
|
// ... and update window.
|
|
impl_rebuildFixedText ();
|
|
impl_recalcLayout ();
|
|
}
|
|
|
|
// XProgressMonitor
|
|
void SAL_CALL ProgressMonitor::updateText (
|
|
const OUString& rTopic,
|
|
const OUString& rText,
|
|
sal_Bool bbeforeProgress
|
|
)
|
|
{
|
|
// Safe impossible cases
|
|
// Check valid call of this method.
|
|
DBG_ASSERT ( impl_debug_checkParameter ( rTopic, rText ), "ProgressMonitor::updateText()\nCall without valid parameters!\n" );
|
|
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// Search topic ...
|
|
IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress );
|
|
|
|
if ( pSearchItem != nullptr )
|
|
{
|
|
// ... update text ...
|
|
pSearchItem->sText = rText;
|
|
|
|
// ... and update window.
|
|
impl_rebuildFixedText ();
|
|
impl_recalcLayout ();
|
|
}
|
|
}
|
|
|
|
// XProgressBar
|
|
void SAL_CALL ProgressMonitor::setForegroundColor ( sal_Int32 nColor )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
m_xProgressBar->setForegroundColor ( nColor );
|
|
}
|
|
|
|
// XProgressBar
|
|
void SAL_CALL ProgressMonitor::setBackgroundColor ( sal_Int32 nColor )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
m_xProgressBar->setBackgroundColor ( nColor );
|
|
}
|
|
|
|
// XProgressBar
|
|
void SAL_CALL ProgressMonitor::setValue ( sal_Int32 nValue )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
m_xProgressBar->setValue ( nValue );
|
|
}
|
|
|
|
// XProgressBar
|
|
void SAL_CALL ProgressMonitor::setRange ( sal_Int32 nMin, sal_Int32 nMax )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
m_xProgressBar->setRange ( nMin, nMax );
|
|
}
|
|
|
|
// XProgressBar
|
|
sal_Int32 SAL_CALL ProgressMonitor::getValue ()
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
return m_xProgressBar->getValue ();
|
|
}
|
|
|
|
// XButton
|
|
void SAL_CALL ProgressMonitor::addActionListener ( const css::uno::Reference< XActionListener > & rListener )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
if ( m_xButton.is () )
|
|
{
|
|
m_xButton->addActionListener ( rListener );
|
|
}
|
|
}
|
|
|
|
// XButton
|
|
void SAL_CALL ProgressMonitor::removeActionListener ( const css::uno::Reference< XActionListener > & rListener )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
if ( m_xButton.is () )
|
|
{
|
|
m_xButton->removeActionListener ( rListener );
|
|
}
|
|
}
|
|
|
|
// XButton
|
|
void SAL_CALL ProgressMonitor::setLabel ( const OUString& rLabel )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
if ( m_xButton.is () )
|
|
{
|
|
m_xButton->setLabel ( rLabel );
|
|
}
|
|
}
|
|
|
|
// XButton
|
|
void SAL_CALL ProgressMonitor::setActionCommand ( const OUString& rCommand )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
if ( m_xButton.is () )
|
|
{
|
|
m_xButton->setActionCommand ( rCommand );
|
|
}
|
|
}
|
|
|
|
// XLayoutConstrains
|
|
Size SAL_CALL ProgressMonitor::getMinimumSize ()
|
|
{
|
|
return Size (PROGRESSMONITOR_DEFAULT_WIDTH, PROGRESSMONITOR_DEFAULT_HEIGHT);
|
|
}
|
|
|
|
// XLayoutConstrains
|
|
Size SAL_CALL ProgressMonitor::getPreferredSize ()
|
|
{
|
|
// Ready for multithreading
|
|
ClearableMutexGuard aGuard ( m_aMutex );
|
|
|
|
// get information about required place of child controls
|
|
css::uno::Reference< XLayoutConstrains > xTopicLayout_Top ( m_xTopic_Top , UNO_QUERY );
|
|
css::uno::Reference< XLayoutConstrains > xTopicLayout_Bottom ( m_xTopic_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XLayoutConstrains > xButtonLayout ( m_xButton , UNO_QUERY );
|
|
|
|
Size aTopicSize_Top = xTopicLayout_Top->getPreferredSize ();
|
|
Size aTopicSize_Bottom = xTopicLayout_Bottom->getPreferredSize ();
|
|
Size aButtonSize = xButtonLayout->getPreferredSize ();
|
|
Rectangle aTempRectangle = m_xProgressBar->getPosSize();
|
|
Size aProgressBarSize( aTempRectangle.Width, aTempRectangle.Height );
|
|
|
|
aGuard.clear ();
|
|
|
|
// calc preferred size of progressmonitor
|
|
sal_Int32 nWidth = 3 * PROGRESSMONITOR_FREEBORDER;
|
|
nWidth += aProgressBarSize.Width;
|
|
|
|
sal_Int32 nHeight = 6 * PROGRESSMONITOR_FREEBORDER;
|
|
nHeight += aTopicSize_Top.Height;
|
|
nHeight += aProgressBarSize.Height;
|
|
nHeight += aTopicSize_Bottom.Height;
|
|
nHeight += 2; // 1 for black line, 1 for white line = 3D-Line!
|
|
nHeight += aButtonSize.Height;
|
|
|
|
// norm to minimum
|
|
if ( nWidth < PROGRESSMONITOR_DEFAULT_WIDTH )
|
|
{
|
|
nWidth = PROGRESSMONITOR_DEFAULT_WIDTH;
|
|
}
|
|
if ( nHeight < PROGRESSMONITOR_DEFAULT_HEIGHT )
|
|
{
|
|
nHeight = PROGRESSMONITOR_DEFAULT_HEIGHT;
|
|
}
|
|
|
|
// return to caller
|
|
return Size ( nWidth, nHeight );
|
|
}
|
|
|
|
// XLayoutConstrains
|
|
Size SAL_CALL ProgressMonitor::calcAdjustedSize ( const Size& /*rNewSize*/ )
|
|
{
|
|
return getPreferredSize ();
|
|
}
|
|
|
|
// XControl
|
|
void SAL_CALL ProgressMonitor::createPeer ( const css::uno::Reference< XToolkit > & rToolkit, const css::uno::Reference< XWindowPeer > & rParent )
|
|
{
|
|
if (!getPeer().is())
|
|
{
|
|
BaseContainerControl::createPeer ( rToolkit, rParent );
|
|
|
|
// If user forget to call "setPosSize()", we have still a correct size.
|
|
// And a "MinimumSize" IS A "MinimumSize"!
|
|
// We change not the position of control at this point.
|
|
Size aDefaultSize = getMinimumSize ();
|
|
setPosSize ( 0, 0, aDefaultSize.Width, aDefaultSize.Height, PosSize::SIZE );
|
|
}
|
|
}
|
|
|
|
// XControl
|
|
sal_Bool SAL_CALL ProgressMonitor::setModel ( const css::uno::Reference< XControlModel > & /*rModel*/ )
|
|
{
|
|
// We have no model.
|
|
return false;
|
|
}
|
|
|
|
// XControl
|
|
css::uno::Reference< XControlModel > SAL_CALL ProgressMonitor::getModel ()
|
|
{
|
|
// We have no model.
|
|
// return (XControlModel*)this;
|
|
return css::uno::Reference< XControlModel > ();
|
|
}
|
|
|
|
// XComponent
|
|
void SAL_CALL ProgressMonitor::dispose ()
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// "removeControl()" control the state of a reference
|
|
css::uno::Reference< XControl > xRef_Topic_Top ( m_xTopic_Top , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Text_Top ( m_xText_Top , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Topic_Bottom ( m_xTopic_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Text_Bottom ( m_xText_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XControl > xRef_Button ( m_xButton , UNO_QUERY );
|
|
|
|
removeControl ( xRef_Topic_Top );
|
|
removeControl ( xRef_Text_Top );
|
|
removeControl ( xRef_Topic_Bottom );
|
|
removeControl ( xRef_Text_Bottom );
|
|
removeControl ( xRef_Button );
|
|
removeControl ( m_xProgressBar );
|
|
|
|
// don't use "...->clear ()" or "... = XFixedText ()"
|
|
// when other hold a reference at this object !!!
|
|
xRef_Topic_Top->dispose ();
|
|
xRef_Text_Top->dispose ();
|
|
xRef_Topic_Bottom->dispose ();
|
|
xRef_Text_Bottom->dispose ();
|
|
xRef_Button->dispose ();
|
|
m_xProgressBar->dispose();
|
|
|
|
BaseContainerControl::dispose ();
|
|
}
|
|
|
|
// XWindow
|
|
void SAL_CALL ProgressMonitor::setPosSize ( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags )
|
|
{
|
|
Rectangle aBasePosSize = getPosSize ();
|
|
BaseContainerControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
|
|
|
|
// if position or size changed
|
|
if (
|
|
( nWidth != aBasePosSize.Width ) ||
|
|
( nHeight != aBasePosSize.Height)
|
|
)
|
|
{
|
|
// calc new layout for controls
|
|
impl_recalcLayout ();
|
|
// clear background (!)
|
|
// [Children were repainted in "recalcLayout" by setPosSize() automatically!]
|
|
getPeer()->invalidate(2);
|
|
// and repaint the control
|
|
impl_paint ( 0, 0, impl_getGraphicsPeer() );
|
|
}
|
|
}
|
|
|
|
// protected method
|
|
void ProgressMonitor::impl_paint ( sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< XGraphics > & rGraphics )
|
|
{
|
|
if (!rGraphics.is())
|
|
return;
|
|
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// paint shadowed border around the progressmonitor
|
|
rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
|
|
rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY );
|
|
rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 );
|
|
|
|
rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
|
|
rGraphics->drawLine ( nX, nY, impl_getWidth(), nY );
|
|
rGraphics->drawLine ( nX, nY, nX , impl_getHeight() );
|
|
|
|
// Paint 3D-line
|
|
rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
|
|
rGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y );
|
|
|
|
rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
|
|
rGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 );
|
|
}
|
|
|
|
// private method
|
|
void ProgressMonitor::impl_recalcLayout ()
|
|
{
|
|
sal_Int32 nX_Button;
|
|
sal_Int32 nY_Button;
|
|
sal_Int32 nWidth_Button;
|
|
sal_Int32 nHeight_Button;
|
|
|
|
sal_Int32 nX_ProgressBar;
|
|
sal_Int32 nY_ProgressBar;
|
|
sal_Int32 nWidth_ProgressBar;
|
|
sal_Int32 nHeight_ProgressBar;
|
|
|
|
sal_Int32 nX_Text_Top;
|
|
sal_Int32 nY_Text_Top;
|
|
sal_Int32 nWidth_Text_Top;
|
|
sal_Int32 nHeight_Text_Top;
|
|
|
|
sal_Int32 nX_Topic_Top;
|
|
sal_Int32 nY_Topic_Top;
|
|
sal_Int32 nWidth_Topic_Top;
|
|
sal_Int32 nHeight_Topic_Top;
|
|
|
|
sal_Int32 nX_Text_Bottom;
|
|
sal_Int32 nY_Text_Bottom;
|
|
sal_Int32 nWidth_Text_Bottom;
|
|
sal_Int32 nHeight_Text_Bottom;
|
|
|
|
sal_Int32 nX_Topic_Bottom;
|
|
sal_Int32 nY_Topic_Bottom;
|
|
sal_Int32 nWidth_Topic_Bottom;
|
|
sal_Int32 nHeight_Topic_Bottom;
|
|
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// get information about required place of child controls
|
|
css::uno::Reference< XLayoutConstrains > xTopicLayout_Top ( m_xTopic_Top , UNO_QUERY );
|
|
css::uno::Reference< XLayoutConstrains > xTextLayout_Top ( m_xText_Top , UNO_QUERY );
|
|
css::uno::Reference< XLayoutConstrains > xTopicLayout_Bottom ( m_xTopic_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XLayoutConstrains > xTextLayout_Bottom ( m_xText_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XLayoutConstrains > xButtonLayout ( m_xButton , UNO_QUERY );
|
|
|
|
Size aTopicSize_Top = xTopicLayout_Top->getPreferredSize ();
|
|
Size aTextSize_Top = xTextLayout_Top->getPreferredSize ();
|
|
Size aTopicSize_Bottom = xTopicLayout_Bottom->getPreferredSize ();
|
|
Size aTextSize_Bottom = xTextLayout_Bottom->getPreferredSize ();
|
|
Size aButtonSize = xButtonLayout->getPreferredSize ();
|
|
|
|
// calc position and size of child controls
|
|
// Button has preferred size!
|
|
nWidth_Button = aButtonSize.Width;
|
|
nHeight_Button = aButtonSize.Height;
|
|
|
|
// Left column before progressbar has preferred size and fixed position.
|
|
// But "Width" is oriented on left column below progressbar to!!! "max(...)"
|
|
nX_Topic_Top = PROGRESSMONITOR_FREEBORDER;
|
|
nY_Topic_Top = PROGRESSMONITOR_FREEBORDER;
|
|
nWidth_Topic_Top = std::max( aTopicSize_Top.Width, aTopicSize_Bottom.Width );
|
|
nHeight_Topic_Top = aTopicSize_Top.Height;
|
|
|
|
// Right column before progressbar has relative position to left column ...
|
|
// ... and a size as rest of dialog size!
|
|
nX_Text_Top = nX_Topic_Top+nWidth_Topic_Top+PROGRESSMONITOR_FREEBORDER;
|
|
nY_Text_Top = nY_Topic_Top;
|
|
nWidth_Text_Top = std::max ( aTextSize_Top.Width, aTextSize_Bottom.Width );
|
|
// Fix size of this column to minimum!
|
|
sal_Int32 nSummaryWidth = nWidth_Text_Top+nWidth_Topic_Top+(3*PROGRESSMONITOR_FREEBORDER);
|
|
if ( nSummaryWidth < PROGRESSMONITOR_DEFAULT_WIDTH )
|
|
nWidth_Text_Top = PROGRESSMONITOR_DEFAULT_WIDTH-nWidth_Topic_Top-(3*PROGRESSMONITOR_FREEBORDER);
|
|
// Fix size of column to maximum!
|
|
if ( nSummaryWidth > impl_getWidth() )
|
|
nWidth_Text_Top = impl_getWidth()-nWidth_Topic_Top-(3*PROGRESSMONITOR_FREEBORDER);
|
|
nHeight_Text_Top = nHeight_Topic_Top;
|
|
|
|
// Position of progressbar is relative to columns before.
|
|
// Progressbar.Width = Dialog.Width !!!
|
|
// Progressbar.Height = Button.Height
|
|
nX_ProgressBar = nX_Topic_Top;
|
|
nY_ProgressBar = nY_Topic_Top+nHeight_Topic_Top+PROGRESSMONITOR_FREEBORDER;
|
|
nWidth_ProgressBar = PROGRESSMONITOR_FREEBORDER+nWidth_Topic_Top+nWidth_Text_Top;
|
|
nHeight_ProgressBar = nHeight_Button;
|
|
|
|
// Oriented by left column before progressbar.
|
|
nX_Topic_Bottom = nX_Topic_Top;
|
|
nY_Topic_Bottom = nY_ProgressBar+nHeight_ProgressBar+PROGRESSMONITOR_FREEBORDER;
|
|
nWidth_Topic_Bottom = nWidth_Topic_Top;
|
|
nHeight_Topic_Bottom = aTopicSize_Bottom.Height;
|
|
|
|
// Oriented by right column before progressbar.
|
|
nX_Text_Bottom = nX_Topic_Bottom+nWidth_Topic_Bottom+PROGRESSMONITOR_FREEBORDER;
|
|
nY_Text_Bottom = nY_Topic_Bottom;
|
|
nWidth_Text_Bottom = nWidth_Text_Top;
|
|
nHeight_Text_Bottom = nHeight_Topic_Bottom;
|
|
|
|
// Oriented by progressbar.
|
|
nX_Button = nX_ProgressBar+nWidth_ProgressBar-nWidth_Button;
|
|
nY_Button = nY_Topic_Bottom+nHeight_Topic_Bottom+PROGRESSMONITOR_FREEBORDER;
|
|
|
|
// Calc offsets to center controls
|
|
sal_Int32 nDx;
|
|
sal_Int32 nDy;
|
|
|
|
nDx = ( (2*PROGRESSMONITOR_FREEBORDER)+nWidth_ProgressBar );
|
|
nDy = ( (6*PROGRESSMONITOR_FREEBORDER)+nHeight_Topic_Top+nHeight_ProgressBar+nHeight_Topic_Bottom+2+nHeight_Button );
|
|
|
|
// At this point use original dialog size to center controls!
|
|
nDx = (impl_getWidth ()/2)-(nDx/2);
|
|
nDy = (impl_getHeight()/2)-(nDy/2);
|
|
|
|
if ( nDx<0 )
|
|
{
|
|
nDx=0;
|
|
}
|
|
if ( nDy<0 )
|
|
{
|
|
nDy=0;
|
|
}
|
|
|
|
// Set new position and size on all controls
|
|
css::uno::Reference< XWindow > xRef_Topic_Top ( m_xTopic_Top , UNO_QUERY );
|
|
css::uno::Reference< XWindow > xRef_Text_Top ( m_xText_Top , UNO_QUERY );
|
|
css::uno::Reference< XWindow > xRef_Topic_Bottom ( m_xTopic_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XWindow > xRef_Text_Bottom ( m_xText_Bottom , UNO_QUERY );
|
|
css::uno::Reference< XWindow > xRef_Button ( m_xButton , UNO_QUERY );
|
|
|
|
xRef_Topic_Top->setPosSize ( nDx+nX_Topic_Top , nDy+nY_Topic_Top , nWidth_Topic_Top , nHeight_Topic_Top , 15 );
|
|
xRef_Text_Top->setPosSize ( nDx+nX_Text_Top , nDy+nY_Text_Top , nWidth_Text_Top , nHeight_Text_Top , 15 );
|
|
xRef_Topic_Bottom->setPosSize ( nDx+nX_Topic_Bottom , nDy+nY_Topic_Bottom , nWidth_Topic_Bottom , nHeight_Topic_Bottom , 15 );
|
|
xRef_Text_Bottom->setPosSize ( nDx+nX_Text_Bottom , nDy+nY_Text_Bottom , nWidth_Text_Bottom , nHeight_Text_Bottom , 15 );
|
|
xRef_Button->setPosSize ( nDx+nX_Button , nDy+nY_Button , nWidth_Button , nHeight_Button , 15 );
|
|
m_xProgressBar->setPosSize( nDx+nX_ProgressBar, nDy+nY_ProgressBar, nWidth_ProgressBar, nHeight_ProgressBar, 15 );
|
|
|
|
m_a3DLine.X = nDx+nX_Topic_Top;
|
|
m_a3DLine.Y = nDy+nY_Topic_Bottom+nHeight_Topic_Bottom+(PROGRESSMONITOR_FREEBORDER/2);
|
|
m_a3DLine.Width = nWidth_ProgressBar;
|
|
m_a3DLine.Height = nHeight_ProgressBar;
|
|
|
|
// All childcontrols make an implicit repaint in setPosSize()!
|
|
// Make it also for this 3D-line ...
|
|
css::uno::Reference< XGraphics > xGraphics = impl_getGraphicsPeer ();
|
|
|
|
xGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
|
|
xGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y );
|
|
|
|
xGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
|
|
xGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 );
|
|
}
|
|
|
|
// private method
|
|
void ProgressMonitor::impl_rebuildFixedText ()
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// Rebuild fixedtext before progress
|
|
|
|
// Rebuild left site of text
|
|
if (m_xTopic_Top.is())
|
|
{
|
|
OUStringBuffer aCollectString;
|
|
|
|
// Collect all topics from list and format text.
|
|
// "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
|
|
for (auto const & rSearchItem : maTextlist_Top)
|
|
{
|
|
aCollectString.append(rSearchItem.sTopic + "\n");
|
|
}
|
|
|
|
m_xTopic_Top->setText ( aCollectString.makeStringAndClear() );
|
|
}
|
|
|
|
// Rebuild right site of text
|
|
if (m_xText_Top.is())
|
|
{
|
|
OUStringBuffer aCollectString;
|
|
|
|
// Collect all topics from list and format text.
|
|
// "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
|
|
for (auto const & rSearchItem : maTextlist_Top)
|
|
{
|
|
aCollectString.append(rSearchItem.sText + "\n");
|
|
}
|
|
|
|
m_xText_Top->setText ( aCollectString.makeStringAndClear() );
|
|
}
|
|
|
|
// Rebuild fixedtext below progress
|
|
|
|
// Rebuild left site of text
|
|
if (m_xTopic_Bottom.is())
|
|
{
|
|
OUStringBuffer aCollectString;
|
|
|
|
// Collect all topics from list and format text.
|
|
// "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
|
|
for (auto const & rSearchItem : maTextlist_Bottom)
|
|
{
|
|
aCollectString.append(rSearchItem.sTopic + "\n");
|
|
}
|
|
|
|
m_xTopic_Bottom->setText ( aCollectString.makeStringAndClear() );
|
|
}
|
|
|
|
// Rebuild right site of text
|
|
if (!m_xText_Bottom.is())
|
|
return;
|
|
|
|
OUStringBuffer aCollectString;
|
|
|
|
// Collect all topics from list and format text.
|
|
// "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
|
|
for (auto const & rSearchItem : maTextlist_Bottom)
|
|
{
|
|
aCollectString.append(rSearchItem.sText + "\n");
|
|
}
|
|
|
|
m_xText_Bottom->setText ( aCollectString.makeStringAndClear() );
|
|
}
|
|
|
|
// private method
|
|
void ProgressMonitor::impl_cleanMemory ()
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard ( m_aMutex );
|
|
|
|
// Delete all of lists.
|
|
maTextlist_Top.clear();
|
|
maTextlist_Bottom.clear();
|
|
}
|
|
|
|
// private method
|
|
IMPL_TextlistItem* ProgressMonitor::impl_searchTopic ( std::u16string_view rTopic, bool bbeforeProgress )
|
|
{
|
|
// Get right textlist for following operations.
|
|
::std::vector< IMPL_TextlistItem >* pTextList;
|
|
|
|
if (bbeforeProgress)
|
|
{
|
|
pTextList = &maTextlist_Top;
|
|
}
|
|
else
|
|
{
|
|
pTextList = &maTextlist_Bottom;
|
|
}
|
|
|
|
// Search the topic in textlist.
|
|
size_t nPosition = 0;
|
|
size_t nCount = pTextList->size();
|
|
|
|
for ( nPosition = 0; nPosition < nCount; ++nPosition )
|
|
{
|
|
auto& rSearchItem = pTextList->at( nPosition );
|
|
|
|
if ( rSearchItem.sTopic == rTopic )
|
|
{
|
|
// We have found this topic... return a valid pointer.
|
|
return &rSearchItem;
|
|
}
|
|
}
|
|
|
|
// We haven't found this topic... return a nonvalid pointer.
|
|
return nullptr;
|
|
}
|
|
|
|
// debug methods
|
|
|
|
// addText, updateText
|
|
bool ProgressMonitor::impl_debug_checkParameter (
|
|
std::u16string_view rTopic,
|
|
std::u16string_view rText
|
|
) {
|
|
if ( rTopic.empty() ) return false; // ""
|
|
|
|
if ( rText.empty() ) return false; // ""
|
|
|
|
// Parameter OK ... return true.
|
|
return true;
|
|
}
|
|
|
|
// removeText
|
|
bool ProgressMonitor::impl_debug_checkParameter ( std::u16string_view rTopic )
|
|
{
|
|
if ( rTopic.empty() ) return false; // ""
|
|
|
|
// Parameter OK ... return true.
|
|
return true;
|
|
}
|
|
|
|
} // namespace unocontrols
|
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
|
|
stardiv_UnoControls_ProgressMonitor_get_implementation(
|
|
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
|
|
{
|
|
return cppu::acquire(new unocontrols::ProgressMonitor(context));
|
|
}
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|