1
0
Fork 0
libreoffice/UnoControls/source/controls/progressmonitor.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

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: */