summaryrefslogtreecommitdiffstats
path: root/framework/source/helper
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /framework/source/helper
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'framework/source/helper')
-rw-r--r--framework/source/helper/dockingareadefaultacceptor.cxx129
-rw-r--r--framework/source/helper/ocomponentaccess.cxx167
-rw-r--r--framework/source/helper/ocomponentenumeration.cxx117
-rw-r--r--framework/source/helper/oframes.cxx370
-rw-r--r--framework/source/helper/persistentwindowstate.cxx267
-rw-r--r--framework/source/helper/statusindicator.cxx128
-rw-r--r--framework/source/helper/statusindicatorfactory.cxx577
-rw-r--r--framework/source/helper/tagwindowasmodified.cxx146
-rw-r--r--framework/source/helper/titlebarupdate.cxx316
-rw-r--r--framework/source/helper/uiconfigelementwrapperbase.cxx481
-rw-r--r--framework/source/helper/uielementwrapperbase.cxx203
-rw-r--r--framework/source/helper/vclstatusindicator.cxx140
-rw-r--r--framework/source/helper/wakeupthread.cxx60
13 files changed, 3101 insertions, 0 deletions
diff --git a/framework/source/helper/dockingareadefaultacceptor.cxx b/framework/source/helper/dockingareadefaultacceptor.cxx
new file mode 100644
index 000000000..59a43a1e3
--- /dev/null
+++ b/framework/source/helper/dockingareadefaultacceptor.cxx
@@ -0,0 +1,129 @@
+/* -*- 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 <helper/dockingareadefaultacceptor.hxx>
+
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+
+#include <vcl/svapp.hxx>
+
+namespace framework{
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::cppu;
+using namespace ::osl;
+
+// constructor
+
+DockingAreaDefaultAcceptor::DockingAreaDefaultAcceptor( const css::uno::Reference< XFrame >& xOwner )
+ : m_xOwner ( xOwner )
+{
+}
+
+// destructor
+
+DockingAreaDefaultAcceptor::~DockingAreaDefaultAcceptor()
+{
+}
+
+// XDockingAreaAcceptor
+css::uno::Reference< css::awt::XWindow > SAL_CALL DockingAreaDefaultAcceptor::getContainerWindow()
+{
+ SolarMutexGuard g;
+
+ // Try to "lock" the frame for access to taskscontainer.
+ css::uno::Reference< XFrame > xFrame( m_xOwner );
+ //TODO: check xFrame for null?
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
+
+ return xContainerWindow;
+}
+
+sal_Bool SAL_CALL DockingAreaDefaultAcceptor::requestDockingAreaSpace( const css::awt::Rectangle& RequestedSpace )
+{
+ // Try to "lock" the frame for access to taskscontainer.
+ css::uno::Reference< XFrame > xFrame( m_xOwner );
+
+ if ( !xFrame.is() )
+ return false;
+
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( xFrame->getComponentWindow() );
+
+ if ( !xContainerWindow.is() || !xComponentWindow.is() )
+ return false;
+
+ css::uno::Reference< css::awt::XDevice > xDevice( xContainerWindow, css::uno::UNO_QUERY );
+ // Convert relative size to output size.
+ css::awt::Rectangle aRectangle = xContainerWindow->getPosSize();
+ css::awt::DeviceInfo aInfo = xDevice->getInfo();
+ css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+
+ css::awt::Size aMinSize( 0, 0 ); // = xLayoutConstraints->getMinimumSize();
+
+ // Check if request border space would decrease component window size below minimum size
+ if ((( aSize.Width - RequestedSpace.X - RequestedSpace.Width ) < aMinSize.Width ) ||
+ (( aSize.Height - RequestedSpace.Y - RequestedSpace.Height ) < aMinSize.Height ) )
+ return false;
+
+ return true;
+}
+
+void SAL_CALL DockingAreaDefaultAcceptor::setDockingAreaSpace( const css::awt::Rectangle& BorderSpace )
+{
+ SolarMutexGuard g;
+
+ // Try to "lock" the frame for access to taskscontainer.
+ css::uno::Reference< XFrame > xFrame( m_xOwner );
+ if ( !xFrame.is() )
+ return;
+
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( xFrame->getComponentWindow() );
+
+ if ( !(xContainerWindow.is() && xComponentWindow.is()) )
+ return;
+
+ css::uno::Reference< css::awt::XDevice > xDevice( xContainerWindow, css::uno::UNO_QUERY );
+ // Convert relative size to output size.
+ css::awt::Rectangle aRectangle = xContainerWindow->getPosSize();
+ css::awt::DeviceInfo aInfo = xDevice->getInfo();
+ css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+ css::awt::Size aMinSize( 0, 0 );// = xLayoutConstraints->getMinimumSize();
+
+ // Check if request border space would decrease component window size below minimum size
+ sal_Int32 nWidth = aSize.Width - BorderSpace.X - BorderSpace.Width;
+ sal_Int32 nHeight = aSize.Height - BorderSpace.Y - BorderSpace.Height;
+
+ if (( nWidth > aMinSize.Width ) && ( nHeight > aMinSize.Height ))
+ {
+ // Resize our component window.
+ xComponentWindow->setPosSize( BorderSpace.X, BorderSpace.Y, nWidth, nHeight, css::awt::PosSize::POSSIZE );
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/ocomponentaccess.cxx b/framework/source/helper/ocomponentaccess.cxx
new file mode 100644
index 000000000..ad7409990
--- /dev/null
+++ b/framework/source/helper/ocomponentaccess.cxx
@@ -0,0 +1,167 @@
+/* -*- 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 <helper/ocomponentaccess.hxx>
+#include <helper/ocomponentenumeration.hxx>
+
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+
+namespace framework{
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::cppu;
+using namespace ::osl;
+
+// constructor
+
+OComponentAccess::OComponentAccess( const css::uno::Reference< XDesktop >& xOwner )
+ : m_xOwner ( xOwner )
+{
+ // Safe impossible cases
+ SAL_WARN_IF( !xOwner.is(), "fwk", "OComponentAccess::OComponentAccess(): Invalid parameter detected!" );
+}
+
+// destructor
+
+OComponentAccess::~OComponentAccess()
+{
+}
+
+// XEnumerationAccess
+css::uno::Reference< XEnumeration > SAL_CALL OComponentAccess::createEnumeration()
+{
+ SolarMutexGuard g;
+
+ // Set default return value, if method failed.
+ // If no desktop exist and there is no task container - return an empty enumeration!
+ css::uno::Reference< XEnumeration > xReturn;
+
+ // Try to "lock" the desktop for access to task container.
+ css::uno::Reference< XInterface > xLock = m_xOwner.get();
+ if ( xLock.is() )
+ {
+ // Desktop exist => pointer to task container must be valid.
+ // Initialize a new enumeration ... if some tasks and his components exist!
+ // (OTasksEnumeration will make an assert, if we initialize the new instance without valid values!)
+
+ std::vector< css::uno::Reference< XComponent > > seqComponents;
+ impl_collectAllChildComponents( css::uno::Reference< XFramesSupplier >( xLock, UNO_QUERY ), seqComponents );
+ xReturn = new OComponentEnumeration( std::move(seqComponents) );
+ }
+
+ // Return result of this operation.
+ return xReturn;
+}
+
+// XElementAccess
+Type SAL_CALL OComponentAccess::getElementType()
+{
+ // Elements in list an enumeration are components!
+ // Return the uno-type of XComponent.
+ return cppu::UnoType<XComponent>::get();
+}
+
+// XElementAccess
+sal_Bool SAL_CALL OComponentAccess::hasElements()
+{
+ SolarMutexGuard g;
+
+ // Set default return value, if method failed.
+ bool bReturn = false;
+
+ // Try to "lock" the desktop for access to task container.
+ css::uno::Reference< XFramesSupplier > xLock( m_xOwner.get(), UNO_QUERY );
+ if ( xLock.is() )
+ {
+ // Ask container of owner for existing elements.
+ bReturn = xLock->getFrames()->hasElements();
+ }
+
+ // Return result of this operation.
+ return bReturn;
+}
+
+
+void OComponentAccess::impl_collectAllChildComponents( const css::uno::Reference< XFramesSupplier >& xNode ,
+ std::vector< css::uno::Reference< XComponent > >& seqComponents )
+{
+ // If valid node was given ...
+ if( !xNode.is() )
+ return;
+
+ // ... continue collection at these.
+
+ // Get the container of current node, collect the components of existing child frames
+ // and go down to next level in tree (recursive!).
+
+ const css::uno::Reference< XFrames > xContainer = xNode->getFrames();
+ const Sequence< css::uno::Reference< XFrame > > seqFrames = xContainer->queryFrames( FrameSearchFlag::CHILDREN );
+
+ const sal_Int32 nFrameCount = seqFrames.getLength();
+ for( sal_Int32 nFrame=0; nFrame<nFrameCount; ++nFrame )
+ {
+ css::uno::Reference< XComponent > xComponent = impl_getFrameComponent( seqFrames[nFrame] );
+ if( xComponent.is() )
+ {
+ seqComponents.push_back( xComponent );
+ }
+ }
+ // ... otherwise break a recursive path and go back at current stack!
+}
+
+css::uno::Reference< XComponent > OComponentAccess::impl_getFrameComponent( const css::uno::Reference< XFrame >& xFrame ) const
+{
+ // Set default return value, if method failed.
+ css::uno::Reference< XComponent > xComponent;
+ // Does no controller exists?
+ css::uno::Reference< XController > xController = xFrame->getController();
+ if ( !xController.is() )
+ {
+ // Controller not exist - use the VCL-component.
+ xComponent = xFrame->getComponentWindow();
+ }
+ else
+ {
+ // Does no model exists?
+ css::uno::Reference< XModel > xModel = xController->getModel();
+ if ( xModel.is() )
+ {
+ // Model exist - use the model as component.
+ xComponent = xModel;
+ }
+ else
+ {
+ // Model not exist - use the controller as component.
+ xComponent = xController;
+ }
+ }
+
+ return xComponent;
+}
+
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/ocomponentenumeration.cxx b/framework/source/helper/ocomponentenumeration.cxx
new file mode 100644
index 000000000..3d00f75e5
--- /dev/null
+++ b/framework/source/helper/ocomponentenumeration.cxx
@@ -0,0 +1,117 @@
+/* -*- 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 <helper/ocomponentenumeration.hxx>
+
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+
+namespace framework{
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::cppu;
+using namespace ::osl;
+
+// constructor
+
+OComponentEnumeration::OComponentEnumeration( std::vector< css::uno::Reference< XComponent > >&& seqComponents )
+ : m_nPosition ( 0 ) // 0 is the first position for a valid list and the right value for an invalid list to!
+ , m_seqComponents ( std::move(seqComponents) )
+{}
+
+// destructor
+
+OComponentEnumeration::~OComponentEnumeration()
+{
+ // Reset instance, free memory...
+ impl_resetObject();
+}
+
+// XEventListener
+void SAL_CALL OComponentEnumeration::disposing( const EventObject& aEvent )
+{
+ SolarMutexGuard g;
+
+ // Safe impossible cases
+ // This method is not specified for all incoming parameters.
+ SAL_WARN_IF( !aEvent.Source.is(), "fwk", "OComponentEnumeration::disposing(): Invalid parameter detected!" );
+
+ // Reset instance to defaults, release references and free memory.
+ impl_resetObject();
+}
+
+// XEnumeration
+sal_Bool SAL_CALL OComponentEnumeration::hasMoreElements()
+{
+ SolarMutexGuard g;
+
+ // First position in a valid list is 0.
+ // => The last one is getLength() - 1!
+ // m_nPosition's current value is the position for the next element, which will be return, if user call "nextElement()"
+ // => We have more elements if current position less than the length of the list!
+ return ( m_nPosition < static_cast<sal_uInt32>(m_seqComponents.size()) );
+}
+
+// XEnumeration
+
+Any SAL_CALL OComponentEnumeration::nextElement()
+{
+ SolarMutexGuard g;
+
+ // If we have no elements or end of enumeration is arrived ...
+ if ( !hasMoreElements() )
+ {
+ // .. throw an exception!
+ throw NoSuchElementException();
+ }
+
+ // Else; Get next element from list ...
+ Any aComponent;
+ aComponent <<= m_seqComponents[m_nPosition];
+ // ... and step to next element!
+ ++m_nPosition;
+
+ // Return listitem.
+ return aComponent;
+}
+
+// protected method
+
+void OComponentEnumeration::impl_resetObject()
+{
+ // Attention:
+ // Write this for multiple calls - NOT AT THE SAME TIME - but for more than one call again)!
+ // It exist two ways to call this method. From destructor and from disposing().
+ // I can't say, which one is the first. Normally the disposing-call - but other way...
+
+ // Delete list of components.
+ m_seqComponents.clear();
+ // Reset position in list.
+ // The list has no elements anymore. m_nPosition is normally the current position in list for nextElement!
+ // But a position of 0 in a list of 0 items is an invalid state. This constellation can't work in future.
+ // End of enumeration is arrived!
+ // (see hasMoreElements() for more details...)
+ m_nPosition = 0;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/oframes.cxx b/framework/source/helper/oframes.cxx
new file mode 100644
index 000000000..a58949852
--- /dev/null
+++ b/framework/source/helper/oframes.cxx
@@ -0,0 +1,370 @@
+/* -*- 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 <helper/oframes.hxx>
+
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+
+namespace framework{
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::std;
+
+// constructor
+
+OFrames::OFrames( const css::uno::Reference< XFrame >& xOwner ,
+ FrameContainer* pFrameContainer )
+ : m_xOwner ( xOwner )
+ , m_pFrameContainer ( pFrameContainer )
+ , m_bRecursiveSearchProtection( false )
+{
+ // An instance of this class can only work with valid initialization.
+ // We share the mutex with our owner class, need a valid factory to instantiate new services and
+ // use the access to our owner for some operations.
+ SAL_WARN_IF( !xOwner.is() || !pFrameContainer, "fwk", "OFrames::OFrames(): Invalid parameter detected!" );
+}
+
+// (protected!) destructor
+
+OFrames::~OFrames()
+{
+ // Reset instance, free memory...
+ impl_resetObject();
+}
+
+// XFrames
+void SAL_CALL OFrames::append( const css::uno::Reference< XFrame >& xFrame )
+{
+ SolarMutexGuard g;
+
+ // Safe impossible cases
+ // Method is not defined for ALL incoming parameters!
+ SAL_WARN_IF( !xFrame.is(), "fwk", "OFrames::append(): Invalid parameter detected!" );
+
+ // Do the follow only, if owner instance valid!
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() )
+ {
+ // Append frame to the end of the container ...
+ m_pFrameContainer->append( xFrame );
+ // Set owner of this instance as parent of the new frame in container!
+ xFrame->setCreator( xOwner );
+ }
+ // Else; Do nothing! Our owner is dead.
+ SAL_WARN_IF( !xOwner.is(), "fwk", "OFrames::append():Our owner is dead - you can't append any frames ...!" );
+}
+
+// XFrames
+void SAL_CALL OFrames::remove( const css::uno::Reference< XFrame >& xFrame )
+{
+ SolarMutexGuard g;
+
+ // Safe impossible cases
+ // Method is not defined for ALL incoming parameters!
+ SAL_WARN_IF( !xFrame.is(), "fwk", "OFrames::remove(): Invalid parameter detected!" );
+
+ // Do the follow only, if owner instance valid!
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() )
+ {
+ // Search frame and remove it from container ...
+ m_pFrameContainer->remove( xFrame );
+ // Don't reset owner-property of removed frame!
+ // This must do the caller of this method himself.
+ // See documentation of interface XFrames for further information.
+ }
+ // Else; Do nothing! Our owner is dead.
+ SAL_WARN_IF( !xOwner.is(), "fwk", "OFrames::remove(): Our owner is dead - you can't remove any frames ...!" );
+}
+
+// XFrames
+Sequence< css::uno::Reference< XFrame > > SAL_CALL OFrames::queryFrames( sal_Int32 nSearchFlags )
+{
+ SolarMutexGuard g;
+
+ // Safe impossible cases
+ // Method is not defined for ALL incoming parameters!
+ SAL_WARN_IF( !impldbg_checkParameter_queryFrames( nSearchFlags ), "fwk", "OFrames::queryFrames(): Invalid parameter detected!" );
+
+ // Set default return value. (empty sequence)
+ Sequence< css::uno::Reference< XFrame > > seqFrames;
+
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() )
+ {
+ // Work only, if search was not started here ...!
+ if( !m_bRecursiveSearchProtection )
+ {
+ // This class is a helper for services, which must implement XFrames.
+ // His parent and children are MY parent and children to.
+ // All searchflags are supported by this implementation!
+ // If some flags should not be supported - don't call me with this flags!!!
+
+ // Search with AUTO-flag is not supported yet!
+ // We think about right implementation.
+ SAL_WARN_IF( (nSearchFlags & FrameSearchFlag::AUTO), "fwk", "OFrames::queryFrames(): Search with AUTO-flag is not supported yet!" );
+
+ // Search for ALL and GLOBAL is superfluous!
+ // We support all necessary flags, from which these two flags are derived.
+ // ALL = PARENT + SELF + CHILDREN + SIBLINGS
+ // GLOBAL = ALL + TASKS
+
+ // Add parent to list ... if any exist!
+ if( nSearchFlags & FrameSearchFlag::PARENT )
+ {
+ css::uno::Reference< XFrame > xParent = xOwner->getCreator();
+ if( xParent.is() )
+ {
+ impl_appendSequence( seqFrames, { xParent } );
+ }
+ }
+
+ // Add owner to list if SELF is searched.
+ if( nSearchFlags & FrameSearchFlag::SELF )
+ {
+ impl_appendSequence( seqFrames, { xOwner } );
+ }
+
+ // Add SIBLINGS to list.
+ if( nSearchFlags & FrameSearchFlag::SIBLINGS )
+ {
+ // Else; start a new search.
+ // Protect this instance against recursive calls from parents.
+ m_bRecursiveSearchProtection = true;
+ // Ask parent of my owner for frames and append results to return list.
+ css::uno::Reference< XFramesSupplier > xParent = xOwner->getCreator();
+ // If a parent exist ...
+ if ( xParent.is() )
+ {
+ // ... ask him for right frames.
+ impl_appendSequence( seqFrames, xParent->getFrames()->queryFrames( nSearchFlags ) );
+ }
+ // We have all searched information.
+ // Reset protection-mode.
+ m_bRecursiveSearchProtection = false;
+ }
+
+ // If searched for children, step over all elements in container and collect the information.
+ if ( nSearchFlags & FrameSearchFlag::CHILDREN )
+ {
+ // Don't search for parents, siblings and self at children!
+ // These things are supported by this instance himself.
+ sal_Int32 const nChildSearchFlags = FrameSearchFlag::SELF | FrameSearchFlag::CHILDREN;
+ // Step over all items of container and ask children for frames.
+ sal_uInt32 nCount = m_pFrameContainer->getCount();
+ for ( sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex )
+ {
+ // We don't must control this conversion.
+ // We have done this at append()!
+ css::uno::Reference< XFramesSupplier > xItem( (*m_pFrameContainer)[nIndex], UNO_QUERY );
+ impl_appendSequence( seqFrames, xItem->getFrames()->queryFrames( nChildSearchFlags ) );
+ }
+ }
+ }
+ }
+ // Else; Do nothing! Our owner is dead.
+ SAL_WARN_IF( !xOwner.is(), "fwk", "OFrames::queryFrames(): Our owner is dead - you can't query for frames ...!" );
+
+ // Return result of this operation.
+ return seqFrames;
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL OFrames::getCount()
+{
+ SolarMutexGuard g;
+
+ // Set default return value.
+ sal_Int32 nCount = 0;
+
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() )
+ {
+ // Set CURRENT size of container for return.
+ nCount = m_pFrameContainer->getCount();
+ }
+
+ // Return result.
+ return nCount;
+}
+
+// XIndexAccess
+
+Any SAL_CALL OFrames::getByIndex( sal_Int32 nIndex )
+{
+ SolarMutexGuard g;
+
+ sal_uInt32 nCount = m_pFrameContainer->getCount();
+ if ( nIndex < 0 || ( sal::static_int_cast< sal_uInt32 >( nIndex ) >= nCount ))
+ throw IndexOutOfBoundsException("OFrames::getByIndex - Index out of bounds",
+ static_cast<OWeakObject *>(this) );
+
+ // Set default return value.
+ Any aReturnValue;
+
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() )
+ {
+ // Get element form container.
+ // (If index not valid, FrameContainer return NULL!)
+ aReturnValue <<= (*m_pFrameContainer)[nIndex];
+ }
+
+ // Return result of this operation.
+ return aReturnValue;
+}
+
+// XElementAccess
+Type SAL_CALL OFrames::getElementType()
+{
+ // This "container" support XFrame-interfaces only!
+ return cppu::UnoType<XFrame>::get();
+}
+
+// XElementAccess
+sal_Bool SAL_CALL OFrames::hasElements()
+{
+ SolarMutexGuard g;
+
+ // Set default return value.
+ bool bHasElements = false;
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() )
+ {
+ // If some elements exist ...
+ if ( m_pFrameContainer->getCount() > 0 )
+ {
+ // ... change this state value!
+ bHasElements = true;
+ }
+ }
+ // Return result of this operation.
+ return bHasElements;
+}
+
+// protected method
+
+void OFrames::impl_resetObject()
+{
+ // Attention:
+ // Write this for multiple calls - NOT AT THE SAME TIME - but for more than one call again)!
+ // It exist two ways to call this method. From destructor and from disposing().
+ // I can't say, which one is the first. Normally the disposing-call - but other way...
+
+ // This instance can't work if the weakreference to owner is invalid!
+ // Destroy this to reset this object.
+ m_xOwner.clear();
+ // Reset pointer to shared container to!
+ m_pFrameContainer = nullptr;
+}
+
+void OFrames::impl_appendSequence( Sequence< css::uno::Reference< XFrame > >& seqDestination ,
+ const Sequence< css::uno::Reference< XFrame > >& seqSource )
+{
+ // Get some information about the sequences.
+ sal_Int32 nSourceCount = seqSource.getLength();
+ sal_Int32 nDestinationCount = seqDestination.getLength();
+ const css::uno::Reference< XFrame >* pSourceAccess = seqSource.getConstArray();
+ css::uno::Reference< XFrame >* pDestinationAccess = seqDestination.getArray();
+
+ // Get memory for result list.
+ Sequence< css::uno::Reference< XFrame > > seqResult ( nSourceCount + nDestinationCount );
+ css::uno::Reference< XFrame >* pResultAccess = seqResult.getArray();
+ sal_Int32 nResultPosition = 0;
+
+ // Copy all items from first sequence.
+ for ( sal_Int32 nSourcePosition=0; nSourcePosition<nSourceCount; ++nSourcePosition )
+ {
+ pResultAccess[nResultPosition] = pSourceAccess[nSourcePosition];
+ ++nResultPosition;
+ }
+
+ // Don't manipulate nResultPosition between these two loops!
+ // It's the current position in the result list.
+
+ // Copy all items from second sequence.
+ for ( sal_Int32 nDestinationPosition=0; nDestinationPosition<nDestinationCount; ++nDestinationPosition )
+ {
+ pResultAccess[nResultPosition] = pDestinationAccess[nDestinationPosition];
+ ++nResultPosition;
+ }
+
+ // Return result of this operation.
+ seqDestination.realloc( 0 );
+ seqDestination = seqResult;
+}
+
+// debug methods
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
+
+ ATTENTION
+
+ If you miss a test for one of this parameters, contact the author or add it himself !(?)
+ But ... look for right testing! See using of this methods!
+-----------------------------------------------------------------------------------------------------------------*/
+
+// A search for frames must initiate with right flags.
+// Some one are superfluous and not supported yet. But here we control only the range of incoming parameter!
+bool OFrames::impldbg_checkParameter_queryFrames( sal_Int32 nSearchFlags )
+{
+ // Set default return value.
+ bool bOK = true;
+ // Check parameter.
+ if (
+ ( nSearchFlags != FrameSearchFlag::AUTO ) &&
+ ( !( nSearchFlags & FrameSearchFlag::PARENT ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::SELF ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::CHILDREN ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::CREATE ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::SIBLINGS ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::TASKS ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::ALL ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::GLOBAL ) )
+ )
+ {
+ bOK = false;
+ }
+ // Return result of check.
+ return bOK;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/persistentwindowstate.cxx b/framework/source/helper/persistentwindowstate.cxx
new file mode 100644
index 000000000..2f7c99719
--- /dev/null
+++ b/framework/source/helper/persistentwindowstate.cxx
@@ -0,0 +1,267 @@
+/* -*- 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 <helper/persistentwindowstate.hxx>
+
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+
+#include <comphelper/lok.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <utility>
+#include <vcl/window.hxx>
+#include <vcl/syswin.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+namespace framework{
+
+PersistentWindowState::PersistentWindowState(css::uno::Reference< css::uno::XComponentContext > xContext)
+ : m_xContext (std::move(xContext ))
+ , m_bWindowStateAlreadySet(false )
+{
+}
+
+PersistentWindowState::~PersistentWindowState()
+{
+}
+
+void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+{
+ // check arguments
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ if (!lArguments.hasElements())
+ throw css::lang::IllegalArgumentException(
+ "Empty argument list!",
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ lArguments[0] >>= xFrame;
+ if (!xFrame.is())
+ throw css::lang::IllegalArgumentException(
+ "No valid frame specified!",
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ {
+ SolarMutexGuard g;
+ m_xFrame = xFrame;
+ }
+
+ // start listening
+ xFrame->addFrameActionListener(this);
+}
+
+void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
+{
+ // We don't want to do this stuff when being used through LibreOfficeKit
+ if( comphelper::LibreOfficeKit::isActive() )
+ return;
+
+ css::uno::Reference< css::uno::XComponentContext > xContext;
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ bool bRestoreWindowState;
+ {
+ SolarMutexGuard g;
+ xContext = m_xContext;
+ xFrame.set(m_xFrame.get(), css::uno::UNO_QUERY);
+ bRestoreWindowState = !m_bWindowStateAlreadySet;
+ }
+
+ // frame already gone ? We hold it weak only ...
+ if (!xFrame.is())
+ return;
+
+ // no window -> no position and size available
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
+ if (!xWindow.is())
+ return;
+
+ // unknown module -> no configuration available!
+ OUString sModuleName = PersistentWindowState::implst_identifyModule(xContext, xFrame);
+ if (sModuleName.isEmpty())
+ return;
+
+ switch(aEvent.Action)
+ {
+ case css::frame::FrameAction_COMPONENT_ATTACHED :
+ {
+ if (bRestoreWindowState)
+ {
+ OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xContext, sModuleName);
+ PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
+ SolarMutexGuard g;
+ m_bWindowStateAlreadySet = true;
+ }
+ }
+ break;
+
+ case css::frame::FrameAction_COMPONENT_REATTACHED :
+ {
+ // nothing todo here, because it's not allowed to change position and size
+ // of an already existing frame!
+ }
+ break;
+
+ case css::frame::FrameAction_COMPONENT_DETACHING :
+ {
+ OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
+ PersistentWindowState::implst_setWindowStateOnConfig(xContext, sModuleName, sWindowState);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
+{
+ css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
+ if (xFrame.is())
+ xFrame->removeFrameActionListener(this);
+
+ // nothing todo here - because we hold the frame as weak reference only
+}
+
+OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ OUString sModuleName;
+
+ css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
+ css::frame::ModuleManager::create( rxContext );
+
+ try
+ {
+ sModuleName = xModuleManager->identify(xFrame);
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { sModuleName.clear(); }
+
+ return sModuleName;
+}
+
+OUString PersistentWindowState::implst_getWindowStateFromConfig(
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ std::u16string_view sModuleName)
+{
+ OUString sWindowState;
+ try
+ {
+ ::comphelper::ConfigurationHelper::readDirectKey(rxContext,
+ "org.openoffice.Setup/",
+ OUString::Concat("Office/Factories/*[\"") + sModuleName + "\"]",
+ "ooSetupFactoryWindowAttributes",
+ ::comphelper::EConfigurationModes::ReadOnly) >>= sWindowState;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { sWindowState.clear(); }
+
+ return sWindowState;
+}
+
+void PersistentWindowState::implst_setWindowStateOnConfig(
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ std::u16string_view sModuleName, const OUString& sWindowState)
+{
+ try
+ {
+ ::comphelper::ConfigurationHelper::writeDirectKey(rxContext,
+ "org.openoffice.Setup/",
+ OUString::Concat("Office/Factories/*[\"") + sModuleName + "\"]",
+ "ooSetupFactoryWindowAttributes",
+ css::uno::Any(sWindowState),
+ ::comphelper::EConfigurationModes::Standard);
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
+{
+ OUString sWindowState;
+
+ if (xWindow.is())
+ {
+ // SOLAR SAFE -> ------------------------
+ SolarMutexGuard aSolarGuard;
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow);
+ // check for system window is necessary to guarantee correct pointer cast!
+ if ( pWindow && pWindow->IsSystemWindow() )
+ {
+ WindowStateMask const nMask = WindowStateMask::All & ~WindowStateMask::Minimized;
+ sWindowState = OStringToOUString(
+ static_cast<SystemWindow*>(pWindow.get())->GetWindowState(nMask),
+ RTL_TEXTENCODING_UTF8);
+ }
+ // <- SOLAR SAFE ------------------------
+ }
+
+ return sWindowState;
+}
+
+void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow ,
+ std::u16string_view sWindowState)
+{
+ if (
+ (!xWindow.is() ) ||
+ ( sWindowState.empty() )
+ )
+ return;
+
+ // SOLAR SAFE -> ------------------------
+ SolarMutexGuard aSolarGuard;
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if (!pWindow)
+ return;
+
+ // check for system and work window - it's necessary to guarantee correct pointer cast!
+ bool bSystemWindow = pWindow->IsSystemWindow();
+ bool bWorkWindow = (pWindow->GetType() == WindowType::WORKWINDOW);
+
+ if (!bSystemWindow && !bWorkWindow)
+ return;
+
+ SystemWindow* pSystemWindow = static_cast<SystemWindow*>(pWindow.get());
+ WorkWindow* pWorkWindow = static_cast<WorkWindow* >(pWindow.get());
+
+ // don't save this special state!
+ if (pWorkWindow->IsMinimized())
+ return;
+
+ OUString sOldWindowState = OStringToOUString( pSystemWindow->GetWindowState(), RTL_TEXTENCODING_ASCII_US );
+ if ( sOldWindowState != sWindowState )
+ pSystemWindow->SetWindowState(OUStringToOString(sWindowState,RTL_TEXTENCODING_UTF8));
+ // <- SOLAR SAFE ------------------------
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/statusindicator.cxx b/framework/source/helper/statusindicator.cxx
new file mode 100644
index 000000000..2deb4a0ae
--- /dev/null
+++ b/framework/source/helper/statusindicator.cxx
@@ -0,0 +1,128 @@
+/* -*- 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 <comphelper/lok.hxx>
+#include <helper/statusindicator.hxx>
+
+namespace framework
+{
+StatusIndicator::StatusIndicator(StatusIndicatorFactory* pFactory)
+ : m_xFactory(pFactory)
+ , m_nRange(100)
+ , m_nLastCallbackPercent(-1)
+{
+}
+
+StatusIndicator::~StatusIndicator() {}
+
+void SAL_CALL StatusIndicator::start(const OUString& sText, sal_Int32 nRange)
+{
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ m_nRange = nRange;
+ m_nLastCallbackPercent = -1;
+
+ comphelper::LibreOfficeKit::statusIndicatorStart(sText);
+ }
+#if !defined(IOS) && !defined(ANDROID)
+ css::uno::Reference<css::task::XStatusIndicatorFactory> xFactory(m_xFactory);
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = static_cast<StatusIndicatorFactory*>(xFactory.get());
+ pFactory->start(this, sText, nRange);
+ }
+#else
+ (void)sText;
+#endif
+}
+
+void SAL_CALL StatusIndicator::end()
+{
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ comphelper::LibreOfficeKit::statusIndicatorFinish();
+ }
+#if !defined(IOS) && !defined(ANDROID)
+ css::uno::Reference<css::task::XStatusIndicatorFactory> xFactory(m_xFactory);
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = static_cast<StatusIndicatorFactory*>(xFactory.get());
+ pFactory->end(this);
+ }
+#endif
+}
+
+void SAL_CALL StatusIndicator::reset()
+{
+ if (comphelper::LibreOfficeKit::isActive())
+ return;
+#if !defined(IOS) && !defined(ANDROID)
+ css::uno::Reference<css::task::XStatusIndicatorFactory> xFactory(m_xFactory);
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = static_cast<StatusIndicatorFactory*>(xFactory.get());
+ pFactory->reset(this);
+ }
+#endif
+}
+
+void SAL_CALL StatusIndicator::setText(const OUString& sText)
+{
+ if (comphelper::LibreOfficeKit::isActive())
+ return;
+#if !defined(IOS) && !defined(ANDROID)
+ css::uno::Reference<css::task::XStatusIndicatorFactory> xFactory(m_xFactory);
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = static_cast<StatusIndicatorFactory*>(xFactory.get());
+ pFactory->setText(this, sText);
+ }
+#else
+ (void)sText;
+#endif
+}
+
+void SAL_CALL StatusIndicator::setValue(sal_Int32 nValue)
+{
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ if (m_nRange > 0)
+ {
+ int nPercent = (100 * nValue) / m_nRange;
+ if (nPercent >= m_nLastCallbackPercent)
+ {
+ comphelper::LibreOfficeKit::statusIndicatorSetValue(nPercent);
+ m_nLastCallbackPercent = nPercent;
+ }
+ }
+ return;
+ }
+#if !defined(IOS) && !defined(ANDROID)
+ css::uno::Reference<css::task::XStatusIndicatorFactory> xFactory(m_xFactory);
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = static_cast<StatusIndicatorFactory*>(xFactory.get());
+ pFactory->setValue(this, nValue);
+ }
+#endif
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/statusindicatorfactory.cxx b/framework/source/helper/statusindicatorfactory.cxx
new file mode 100644
index 000000000..e9e54df6b
--- /dev/null
+++ b/framework/source/helper/statusindicatorfactory.cxx
@@ -0,0 +1,577 @@
+/* -*- 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 <algorithm>
+#include <utility>
+#include <helper/statusindicatorfactory.hxx>
+#include <helper/statusindicator.hxx>
+#include <helper/vclstatusindicator.hxx>
+#include <properties.h>
+
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XLayoutManager2.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <comphelper/sequenceashashmap.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <vcl/svapp.hxx>
+#include <mutex>
+#include <rtl/ref.hxx>
+
+#include <officecfg/Office/Common.hxx>
+
+namespace framework{
+
+sal_Int32 StatusIndicatorFactory::m_nInReschedule = 0; ///< static counter for rescheduling
+
+constexpr OUStringLiteral PROGRESS_RESOURCE = u"private:resource/progressbar/progressbar";
+
+StatusIndicatorFactory::StatusIndicatorFactory(css::uno::Reference< css::uno::XComponentContext > xContext)
+ : m_xContext (std::move(xContext ))
+ , m_bAllowReschedule (false)
+ , m_bAllowParentShow (false)
+ , m_bDisableReschedule(false)
+{
+}
+
+StatusIndicatorFactory::~StatusIndicatorFactory()
+{
+ impl_stopWakeUpThread();
+}
+
+void SAL_CALL StatusIndicatorFactory::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+{
+ if (lArguments.hasElements()) {
+ std::scoped_lock g(m_mutex);
+
+ css::uno::Reference< css::frame::XFrame > xTmpFrame;
+ css::uno::Reference< css::awt::XWindow > xTmpWindow;
+ bool b1 = lArguments[0] >>= xTmpFrame;
+ bool b2 = lArguments[0] >>= xTmpWindow;
+ if (lArguments.getLength() == 3 && b1) {
+ // it's the first service constructor "createWithFrame"
+ m_xFrame = xTmpFrame;
+ lArguments[1] >>= m_bDisableReschedule;
+ lArguments[2] >>= m_bAllowParentShow;
+ } else if (lArguments.getLength() == 3 && b2) {
+ // it's the second service constructor "createWithWindow"
+ m_xPluggWindow = xTmpWindow;
+ lArguments[1] >>= m_bDisableReschedule;
+ lArguments[2] >>= m_bAllowParentShow;
+ } else {
+ // it's an old-style initialisation using properties
+ ::comphelper::SequenceAsHashMap lArgs(lArguments);
+
+ m_xFrame = lArgs.getUnpackedValueOrDefault("Frame" , css::uno::Reference< css::frame::XFrame >());
+ m_xPluggWindow = lArgs.getUnpackedValueOrDefault("Window" , css::uno::Reference< css::awt::XWindow >() );
+ m_bAllowParentShow = lArgs.getUnpackedValueOrDefault("AllowParentShow" , false );
+ m_bDisableReschedule = lArgs.getUnpackedValueOrDefault("DisableReschedule", false );
+ }
+ }
+
+#ifdef EMSCRIPTEN
+ m_bDisableReschedule = true;
+#endif
+ impl_createProgress();
+}
+
+css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator()
+{
+ return new StatusIndicator(this);
+}
+
+void SAL_CALL StatusIndicatorFactory::update()
+{
+ std::scoped_lock g(m_mutex);
+ m_bAllowReschedule = true;
+}
+
+void StatusIndicatorFactory::start(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
+ const OUString& sText ,
+ sal_Int32 nRange)
+{
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aWriteLock(m_mutex);
+
+ // create new info structure for this child or move it to the front of our stack
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ m_aStack.erase(pItem);
+ IndicatorInfo aInfo(xChild, sText);
+ m_aStack.push_back (aInfo );
+
+ m_xActiveChild = xChild;
+ xProgress = m_xProgress;
+ }
+ // <- SAFE ----------------------------------
+
+ implts_makeParentVisibleIfAllowed();
+
+ if (xProgress.is())
+ xProgress->start(sText, nRange);
+
+ impl_startWakeUpThread();
+ impl_reschedule(true);
+}
+
+void StatusIndicatorFactory::reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
+{
+ css::uno::Reference< css::task::XStatusIndicator > xActive;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aReadLock(m_mutex);
+
+ // reset the internal info structure related to this child
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ {
+ pItem->m_nValue = 0;
+ pItem->m_sText.clear();
+ }
+
+ xActive = m_xActiveChild;
+ xProgress = m_xProgress;
+ }
+ // <- SAFE ----------------------------------
+
+ // not the top most child => don't change UI
+ // But don't forget Reschedule!
+ if (
+ (xChild == xActive) &&
+ (xProgress.is() )
+ )
+ xProgress->reset();
+
+ impl_reschedule(true);
+}
+
+void StatusIndicatorFactory::end(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
+{
+ css::uno::Reference< css::task::XStatusIndicator > xActive;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+ OUString sText;
+ sal_Int32 nValue = 0;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aWriteLock(m_mutex);
+
+ // remove this child from our stack
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ m_aStack.erase(pItem);
+
+ // activate next child ... or finish the progress if there is no further one.
+ m_xActiveChild.clear();
+ IndicatorStack::reverse_iterator pNext = m_aStack.rbegin();
+ if (pNext != m_aStack.rend())
+ {
+ m_xActiveChild = pNext->m_xIndicator;
+ sText = pNext->m_sText;
+ nValue = pNext->m_nValue;
+ }
+
+ xActive = m_xActiveChild;
+ xProgress = m_xProgress;
+ }
+ // <- SAFE ----------------------------------
+
+ if (xActive.is())
+ {
+ // There is at least one further child indicator.
+ // Actualize our progress, so it shows these values from now.
+ if (xProgress.is())
+ {
+ xProgress->setText (sText );
+ xProgress->setValue(nValue);
+ }
+ }
+ else
+ {
+ // Our stack is empty. No further child exists.
+ // Se we must "end" our progress really
+ if (xProgress.is())
+ xProgress->end();
+ // Now hide the progress bar again.
+ impl_hideProgress();
+
+ impl_stopWakeUpThread();
+ }
+
+ impl_reschedule(true);
+}
+
+void StatusIndicatorFactory::setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
+ const OUString& sText )
+{
+ css::uno::Reference< css::task::XStatusIndicator > xActive;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aWriteLock(m_mutex);
+
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ pItem->m_sText = sText;
+
+ xActive = m_xActiveChild;
+ xProgress = m_xProgress;
+ }
+ // SAFE -> ----------------------------------
+
+ // paint only the top most indicator
+ // but don't forget to Reschedule!
+ if (
+ (xChild == xActive) &&
+ (xProgress.is() )
+ )
+ {
+ xProgress->setText(sText);
+ }
+
+ impl_reschedule(true);
+}
+
+void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild ,
+ sal_Int32 nValue )
+{
+ sal_Int32 nOldValue = 0;
+ css::uno::Reference< css::task::XStatusIndicator > xActive;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aWriteLock(m_mutex);
+
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ {
+ nOldValue = pItem->m_nValue;
+ pItem->m_nValue = nValue;
+ }
+
+ xActive = m_xActiveChild;
+ xProgress = m_xProgress;
+ }
+ // SAFE -> ----------------------------------
+
+ if (
+ (xChild == xActive) &&
+ (nOldValue != nValue ) &&
+ (xProgress.is() )
+ )
+ {
+ xProgress->setValue(nValue);
+ }
+
+ impl_reschedule(false);
+}
+
+void StatusIndicatorFactory::implts_makeParentVisibleIfAllowed()
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ css::uno::Reference< css::awt::XWindow > xPluggWindow;
+ css::uno::Reference< css::uno::XComponentContext > xContext;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aReadLock(m_mutex);
+
+ if (!m_bAllowParentShow)
+ return;
+
+ xFrame = m_xFrame;
+ xPluggWindow = m_xPluggWindow;
+ xContext = m_xContext;
+ }
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::awt::XWindow > xParentWindow;
+ if (xFrame.is())
+ xParentWindow = xFrame->getContainerWindow();
+ else
+ xParentWindow = xPluggWindow;
+
+ // don't disturb user in case he put the loading document into the background!
+ // Suppress any setVisible() or toFront() call in case the initial show was
+ // already made.
+ css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xParentWindow, css::uno::UNO_QUERY);
+ bool bIsVisible = false;
+ if (xVisibleCheck.is())
+ bIsVisible = xVisibleCheck->isVisible();
+
+ if (bIsVisible)
+ {
+ impl_showProgress();
+ return;
+ }
+
+ // Check if the layout manager has been set to invisible state. It this case we are also
+ // not allowed to set the frame visible!
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_ASCII_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ if ( !xLayoutManager->isVisible() )
+ return;
+ }
+ }
+
+ // Ok the window should be made visible... because it is not currently visible.
+ // BUT..!
+ // We need a Hack for our applications: They get her progress from the frame directly
+ // on saving documents. Because there is no progress set on the MediaDescriptor.
+ // But that's wrong. In case the document was opened hidden, they should not use any progress .-(
+ // They only possible workaround: don't show the parent window here, if the document was opened hidden.
+ bool bHiddenDoc = false;
+ if (xFrame.is())
+ {
+ css::uno::Reference< css::frame::XController > xController;
+ css::uno::Reference< css::frame::XModel > xModel;
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+ if (xModel.is())
+ {
+ utl::MediaDescriptor lDocArgs(xModel->getArgs());
+ bHiddenDoc = lDocArgs.getUnpackedValueOrDefault(
+ utl::MediaDescriptor::PROP_HIDDEN,
+ false);
+ }
+ }
+
+ if (bHiddenDoc)
+ return;
+
+ // OK: The document was not opened in hidden mode ...
+ // and the window isn't already visible.
+ // Show it and bring it to front.
+ // But before we have to be sure, that our internal used helper progress
+ // is visible too.
+ impl_showProgress();
+
+ SolarMutexGuard aSolarGuard;
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xParentWindow);
+ if ( pWindow )
+ {
+ bool bForceFrontAndFocus(officecfg::Office::Common::View::NewDocumentHandling::ForceFocusAndToFront::get());
+ pWindow->Show(true, bForceFrontAndFocus ? ShowFlags::ForegroundTask : ShowFlags::NONE );
+ }
+
+}
+
+void StatusIndicatorFactory::impl_createProgress()
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ css::uno::Reference< css::awt::XWindow > xWindow;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aReadLock(m_mutex);
+
+ xFrame = m_xFrame;
+ xWindow = m_xPluggWindow;
+ }
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+
+ if (xWindow.is())
+ {
+ // use vcl based progress implementation in plugged mode
+ xProgress = new VCLStatusIndicator(xWindow);
+ }
+ else if (xFrame.is())
+ {
+ // use frame layouted progress implementation
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_ASCII_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ xLayoutManager->lock();
+ OUString sPROGRESS_RESOURCE(PROGRESS_RESOURCE);
+ xLayoutManager->createElement( sPROGRESS_RESOURCE );
+ xLayoutManager->hideElement( sPROGRESS_RESOURCE );
+
+ css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(sPROGRESS_RESOURCE);
+ if (xProgressBar.is())
+ xProgress.set(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
+ xLayoutManager->unlock();
+ }
+ }
+ }
+
+ std::scoped_lock g(m_mutex);
+ m_xProgress = xProgress;
+}
+
+void StatusIndicatorFactory::impl_showProgress()
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aReadLock(m_mutex);
+
+ xFrame = m_xFrame;
+ }
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+
+ if (!xFrame.is())
+ return;
+
+ // use frame layouted progress implementation
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_ASCII_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ // Be sure that we have always a progress. It can be that our frame
+ // was recycled and therefore the progress was destroyed!
+ // CreateElement does nothing if there is already a valid progress.
+ OUString sPROGRESS_RESOURCE(PROGRESS_RESOURCE);
+ xLayoutManager->createElement( sPROGRESS_RESOURCE );
+ xLayoutManager->showElement( sPROGRESS_RESOURCE );
+
+ css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(sPROGRESS_RESOURCE);
+ if (xProgressBar.is())
+ xProgress.set(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
+ }
+ }
+
+ std::scoped_lock g(m_mutex);
+ m_xProgress = xProgress;
+}
+
+void StatusIndicatorFactory::impl_hideProgress()
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ // SAFE -> ----------------------------------
+ {
+ std::scoped_lock aReadLock(m_mutex);
+
+ xFrame = m_xFrame;
+ }
+ // <- SAFE ----------------------------------
+
+ if (xFrame.is())
+ {
+ // use frame layouted progress implementation
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_ASCII_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ xLayoutManager->hideElement( PROGRESS_RESOURCE );
+ }
+ }
+}
+
+void StatusIndicatorFactory::impl_reschedule(bool bForce)
+{
+ // SAFE ->
+ {
+ std::scoped_lock aReadLock(m_mutex);
+ if (m_bDisableReschedule)
+ return;
+ }
+ // <- SAFE
+
+ bool bReschedule = bForce;
+ if (!bReschedule)
+ {
+ std::scoped_lock g(m_mutex);
+ bReschedule = m_bAllowReschedule;
+ m_bAllowReschedule = false;
+ }
+
+ if (!bReschedule)
+ return;
+
+ static std::mutex rescheduleLock;
+ // SAFE ->
+ std::unique_lock aRescheduleGuard(rescheduleLock);
+
+ if (m_nInReschedule != 0)
+ return;
+
+ // coverity[missing_lock: FALSE] - coverity fails to see the aRescheduleGuard ctor as taking a lock
+ ++m_nInReschedule;
+ aRescheduleGuard.unlock();
+ // <- SAFE
+
+ {
+ SolarMutexGuard g;
+ Application::Reschedule(true);
+ }
+
+ // SAFE ->
+ aRescheduleGuard.lock();
+ --m_nInReschedule;
+}
+
+void StatusIndicatorFactory::impl_startWakeUpThread()
+{
+ std::scoped_lock g(m_mutex);
+
+ if (m_bDisableReschedule)
+ return;
+
+ if (!m_pWakeUp.is())
+ {
+ m_pWakeUp = new WakeUpThread(this);
+ m_pWakeUp->launch();
+ }
+}
+
+void StatusIndicatorFactory::impl_stopWakeUpThread()
+{
+ rtl::Reference<WakeUpThread> wakeUp;
+ {
+ std::scoped_lock g(m_mutex);
+ std::swap(wakeUp, m_pWakeUp);
+ }
+ if (wakeUp.is())
+ {
+ wakeUp->stop();
+ }
+}
+
+} // namespace framework
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_StatusIndicatorFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new framework::StatusIndicatorFactory(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/tagwindowasmodified.cxx b/framework/source/helper/tagwindowasmodified.cxx
new file mode 100644
index 000000000..b113c4b96
--- /dev/null
+++ b/framework/source/helper/tagwindowasmodified.cxx
@@ -0,0 +1,146 @@
+/* -*- 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 <helper/tagwindowasmodified.hxx>
+
+#include <com/sun/star/awt/XWindow.hpp>
+
+#include <com/sun/star/frame/FrameAction.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/wintypes.hxx>
+
+namespace framework{
+
+TagWindowAsModified::TagWindowAsModified()
+{
+}
+
+TagWindowAsModified::~TagWindowAsModified()
+{
+}
+
+void SAL_CALL TagWindowAsModified::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+
+ if (lArguments.hasElements())
+ lArguments[0] >>= xFrame;
+
+ if (!xFrame)
+ return;
+
+ m_xFrame = xFrame;
+ xFrame->addFrameActionListener(this);
+ impl_update (xFrame);
+}
+
+void SAL_CALL TagWindowAsModified::modified(const css::lang::EventObject& aEvent)
+{
+ if (!m_xModel || !m_xWindow || aEvent.Source != m_xModel)
+ return;
+
+ bool bModified = m_xModel->isModified ();
+
+ // SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ if (m_xWindow->isDisposed())
+ return;
+
+ if (bModified)
+ m_xWindow->SetExtendedStyle(WindowExtendedStyle::DocModified);
+ else
+ m_xWindow->SetExtendedStyle(WindowExtendedStyle::NONE);
+ // <- SYNCHRONIZED
+}
+
+void SAL_CALL TagWindowAsModified::frameAction(const css::frame::FrameActionEvent& aEvent)
+{
+ if (
+ (aEvent.Action != css::frame::FrameAction_COMPONENT_REATTACHED) &&
+ (aEvent.Action != css::frame::FrameAction_COMPONENT_ATTACHED )
+ )
+ return;
+
+ if ( aEvent.Source != m_xFrame )
+ return;
+
+ impl_update (m_xFrame);
+}
+
+void SAL_CALL TagWindowAsModified::disposing(const css::lang::EventObject& aEvent)
+{
+ SolarMutexGuard g;
+
+ if (m_xFrame && aEvent.Source == m_xFrame)
+ {
+ m_xFrame->removeFrameActionListener(this);
+ m_xFrame.clear();
+ return;
+ }
+
+ if (m_xModel && aEvent.Source == m_xModel)
+ {
+ m_xModel->removeModifyListener(this);
+ m_xModel.clear();
+ return;
+ }
+}
+
+void TagWindowAsModified::impl_update (const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ if (!xFrame)
+ return;
+
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController ();
+ css::uno::Reference< css::util::XModifiable > xModel;
+ if (xController.is ())
+ xModel = css::uno::Reference< css::util::XModifiable >(xController->getModel(), css::uno::UNO_QUERY);
+
+ if (!xWindow || !xModel)
+ return;
+
+ {
+ SolarMutexGuard g;
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow);
+ bool bSystemWindow = pWindow->IsSystemWindow();
+ bool bWorkWindow = (pWindow->GetType() == WindowType::WORKWINDOW);
+ if (!bSystemWindow && !bWorkWindow)
+ return;
+
+ if (m_xModel)
+ m_xModel->removeModifyListener (this);
+
+ // Note: frame was set as member outside ! we have to refresh connections
+ // regarding window and model only here.
+ m_xWindow = pWindow;
+ m_xModel = xModel;
+ }
+
+ m_xModel->addModifyListener (this);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/titlebarupdate.cxx b/framework/source/helper/titlebarupdate.cxx
new file mode 100644
index 000000000..a9f27bd4a
--- /dev/null
+++ b/framework/source/helper/titlebarupdate.cxx
@@ -0,0 +1,316 @@
+/* -*- 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 <helper/titlebarupdate.hxx>
+
+#include <properties.h>
+
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/frame/XTitleChangeBroadcaster.hpp>
+
+#include <comphelper/sequenceashashmap.hxx>
+#include <unotools/configmgr.hxx>
+#include <utility>
+#include <vcl/window.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <tools/diagnose_ex.h>
+
+namespace framework{
+
+const ::sal_Int32 INVALID_ICON_ID = -1;
+const ::sal_Int32 DEFAULT_ICON_ID = 0;
+
+TitleBarUpdate::TitleBarUpdate(css::uno::Reference< css::uno::XComponentContext > xContext)
+ : m_xContext (std::move(xContext ))
+{
+}
+
+TitleBarUpdate::~TitleBarUpdate()
+{
+}
+
+void SAL_CALL TitleBarUpdate::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+{
+ // check arguments
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ if (!lArguments.hasElements())
+ throw css::lang::IllegalArgumentException(
+ "Empty argument list!",
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ lArguments[0] >>= xFrame;
+ if (!xFrame.is())
+ throw css::lang::IllegalArgumentException(
+ "No valid frame specified!",
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ {
+ SolarMutexGuard g;
+ // hold the frame as weak reference(!) so it can die everytimes :-)
+ m_xFrame = xFrame;
+ }
+
+ // start listening
+ xFrame->addFrameActionListener(this);
+
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(xFrame, css::uno::UNO_QUERY);
+ if (xBroadcaster.is ())
+ xBroadcaster->addTitleChangeListener (this);
+}
+
+void SAL_CALL TitleBarUpdate::frameAction(const css::frame::FrameActionEvent& aEvent)
+{
+ // we are interested on events only, which must trigger a title bar update
+ // because component was changed.
+ if (
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ) ||
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED) ||
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING )
+ )
+ {
+ impl_forceUpdate ();
+ }
+}
+
+void SAL_CALL TitleBarUpdate::titleChanged(const css::frame::TitleChangedEvent& /* aEvent */)
+{
+ impl_forceUpdate ();
+}
+
+void SAL_CALL TitleBarUpdate::disposing(const css::lang::EventObject&)
+{
+ css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
+ if (xFrame.is())
+ xFrame->removeFrameActionListener(this);
+
+ // nothing todo here - because we hold the frame as weak reference only
+}
+
+//http://live.gnome.org/GnomeShell/ApplicationBased
+//http://msdn.microsoft.com/en-us/library/dd378459(v=VS.85).aspx
+void TitleBarUpdate::impl_updateApplicationID(const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+ if ( ! xWindow.is() )
+ return;
+
+#if !defined(MACOSX)
+ OUString sApplicationID;
+ try
+ {
+ css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
+ css::frame::ModuleManager::create( m_xContext );
+
+ OUString sDesktopName;
+ OUString aModuleId = xModuleManager->identify(xFrame);
+ if ( aModuleId.startsWith("com.sun.star.text.") || aModuleId.startsWith("com.sun.star.xforms.") )
+ sDesktopName = "Writer";
+ else if ( aModuleId.startsWith("com.sun.star.sheet.") )
+ sDesktopName = "Calc";
+ else if ( aModuleId.startsWith("com.sun.star.presentation.") )
+ sDesktopName = "Impress";
+ else if ( aModuleId.startsWith("com.sun.star.drawing." ) )
+ sDesktopName = "Draw";
+ else if ( aModuleId.startsWith("com.sun.star.formula." ) )
+ sDesktopName = "Math";
+ else if ( aModuleId.startsWith("com.sun.star.sdb.") )
+ sDesktopName = "Base";
+ else
+ sDesktopName = "Startcenter";
+#if defined(_WIN32)
+ // We use a hardcoded product name matching the registry keys so applications can be associated with file types
+ sApplicationID = "TheDocumentFoundation.LibreOffice." + sDesktopName;
+#else
+ sApplicationID = utl::ConfigManager::getProductName().toAsciiLowerCase() + "-" + sDesktopName.toAsciiLowerCase();
+#endif
+ }
+ catch(const css::uno::Exception&)
+ {
+ }
+#else
+ OUString const sApplicationID;
+#endif
+
+ // VCL SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WindowType::WORKWINDOW )
+ {
+ WorkWindow* pWorkWindow = static_cast<WorkWindow*>(pWindow.get());
+ pWorkWindow->SetApplicationID( sApplicationID );
+ }
+ // <- VCL SYNCHRONIZED
+}
+
+bool TitleBarUpdate::implst_getModuleInfo(const css::uno::Reference< css::frame::XFrame >& xFrame,
+ TModuleInfo& rInfo )
+{
+ if ( ! xFrame.is ())
+ return false;
+
+ try
+ {
+ css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
+ css::frame::ModuleManager::create( m_xContext );
+
+ rInfo.sID = xModuleManager->identify(xFrame);
+ ::comphelper::SequenceAsHashMap lProps = xModuleManager->getByName (rInfo.sID);
+
+ rInfo.nIcon = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_ASCII_ICON , INVALID_ICON_ID );
+
+ // Note: If we could retrieve a module id ... everything is OK.
+ // UIName and Icon ID are optional values !
+ bool bSuccess = !rInfo.sID.isEmpty();
+ return bSuccess;
+ }
+ catch(const css::uno::Exception&)
+ {}
+
+ return false;
+}
+
+void TitleBarUpdate::impl_forceUpdate()
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ {
+ SolarMutexGuard g;
+ xFrame.set(m_xFrame.get(), css::uno::UNO_QUERY);
+ }
+
+ // frame already gone ? We hold it weak only ...
+ if ( ! xFrame.is())
+ return;
+
+ // no window -> no chance to set/update title and icon
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
+ if ( ! xWindow.is())
+ return;
+
+ impl_updateIcon (xFrame);
+ impl_updateTitle (xFrame);
+#if !defined(MACOSX)
+ impl_updateApplicationID (xFrame);
+#endif
+}
+
+void TitleBarUpdate::impl_updateIcon(const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController ();
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+
+ if (
+ ( ! xController.is() ) ||
+ ( ! xWindow.is() )
+ )
+ return;
+
+ // a) set default value to an invalid one. So we can start further searches for right icon id, if
+ // first steps failed!
+ sal_Int32 nIcon = INVALID_ICON_ID;
+
+ // b) try to find information on controller property set directly
+ // Don't forget to catch possible exceptions - because these property is an optional one!
+ css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySetInfo > const xPSI( xSet->getPropertySetInfo(), css::uno::UNO_SET_THROW );
+ if ( xPSI->hasPropertyByName( "IconId" ) )
+ xSet->getPropertyValue( "IconId" ) >>= nIcon;
+ }
+ catch(const css::uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("fwk");
+ }
+ }
+
+ // c) if b) failed ... identify the used module and retrieve set icon from module config.
+ // Tirck :-) Module was already specified outside and aInfo contains all needed information.
+ if ( nIcon == INVALID_ICON_ID )
+ {
+ TModuleInfo aInfo;
+ if (implst_getModuleInfo(xFrame, aInfo))
+ nIcon = aInfo.nIcon;
+ }
+
+ // d) if all steps failed - use fallback :-)
+ // ... means using the global staroffice icon
+ if( nIcon == INVALID_ICON_ID )
+ nIcon = DEFAULT_ICON_ID;
+
+ // e) set icon on container window now
+ // Don't forget SolarMutex! We use vcl directly :-(
+ // Check window pointer for right WorkWindow class too!!!
+
+ // VCL SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && ( pWindow->GetType() == WindowType::WORKWINDOW ) )
+ {
+ WorkWindow* pWorkWindow = static_cast<WorkWindow*>(pWindow.get());
+ pWorkWindow->SetIcon( static_cast<sal_uInt16>(nIcon) );
+
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ OUString aURL;
+ if( xModel.is() )
+ aURL = xModel->getURL();
+ pWorkWindow->SetRepresentedURL( aURL );
+ }
+ // <- VCL SYNCHRONIZED
+}
+
+void TitleBarUpdate::impl_updateTitle(const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ // no window ... no chance to set any title -> return
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+ if ( ! xWindow.is() )
+ return;
+
+ css::uno::Reference< css::frame::XTitle > xTitle(xFrame, css::uno::UNO_QUERY);
+ if ( ! xTitle.is() )
+ return;
+
+ const OUString sTitle = xTitle->getTitle ();
+
+ // VCL SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && ( pWindow->GetType() == WindowType::WORKWINDOW ) )
+ {
+ WorkWindow* pWorkWindow = static_cast<WorkWindow*>(pWindow.get());
+ pWorkWindow->SetText( sTitle );
+ }
+ // <- VCL SYNCHRONIZED
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/uiconfigelementwrapperbase.cxx b/framework/source/helper/uiconfigelementwrapperbase.cxx
new file mode 100644
index 000000000..95d5b4c65
--- /dev/null
+++ b/framework/source/helper/uiconfigelementwrapperbase.cxx
@@ -0,0 +1,481 @@
+/* -*- 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 <helper/uiconfigelementwrapperbase.hxx>
+#include <properties.h>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+
+#include <vcl/svapp.hxx>
+#include <comphelper/sequence.hxx>
+
+const int UIELEMENT_PROPHANDLE_CONFIGSOURCE = 1;
+const int UIELEMENT_PROPHANDLE_FRAME = 2;
+const int UIELEMENT_PROPHANDLE_PERSISTENT = 3;
+const int UIELEMENT_PROPHANDLE_RESOURCEURL = 4;
+const int UIELEMENT_PROPHANDLE_TYPE = 5;
+const int UIELEMENT_PROPHANDLE_XMENUBAR = 6;
+const int UIELEMENT_PROPHANDLE_CONFIGLISTENER = 7;
+const int UIELEMENT_PROPHANDLE_NOCLOSE = 8;
+constexpr OUStringLiteral UIELEMENT_PROPNAME_CONFIGLISTENER = u"ConfigListener";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_CONFIGSOURCE = u"ConfigurationSource";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_FRAME = u"Frame";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_PERSISTENT = u"Persistent";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_RESOURCEURL = u"ResourceURL";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_TYPE = u"Type";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_XMENUBAR = u"XMenuBar";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_NOCLOSE = u"NoClose";
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+UIConfigElementWrapperBase::UIConfigElementWrapperBase( sal_Int16 nType )
+ : ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aMutex )
+ , ::cppu::OPropertySetHelper ( *static_cast< ::cppu::OBroadcastHelper* >(this) )
+ , m_nType ( nType )
+ , m_bPersistent ( true )
+ , m_bInitialized ( false )
+ , m_bConfigListener ( false )
+ , m_bConfigListening ( false )
+ , m_bDisposed ( false )
+ , m_bNoClose ( false )
+ , m_aListenerContainer ( m_aMutex )
+{
+}
+
+UIConfigElementWrapperBase::~UIConfigElementWrapperBase()
+{
+}
+
+Any SAL_CALL UIConfigElementWrapperBase::queryInterface( const Type& _rType )
+{
+ Any aRet = UIConfigElementWrapperBase_BASE::queryInterface( _rType );
+ if ( !aRet.hasValue() )
+ aRet = OPropertySetHelper::queryInterface( _rType );
+ return aRet;
+}
+
+Sequence< Type > SAL_CALL UIConfigElementWrapperBase::getTypes( )
+{
+ return comphelper::concatSequences(
+ UIConfigElementWrapperBase_BASE::getTypes(),
+ ::cppu::OPropertySetHelper::getTypes()
+ );
+}
+
+// XComponent
+void SAL_CALL UIConfigElementWrapperBase::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ m_aListenerContainer.addInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
+}
+
+void SAL_CALL UIConfigElementWrapperBase::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener )
+{
+ m_aListenerContainer.removeInterface( cppu::UnoType<css::lang::XEventListener>::get(), aListener );
+}
+
+// XEventListener
+void SAL_CALL UIConfigElementWrapperBase::disposing( const EventObject& )
+{
+ SolarMutexGuard g;
+ m_xConfigSource.clear();
+}
+
+void SAL_CALL UIConfigElementWrapperBase::initialize( const Sequence< Any >& aArguments )
+{
+ SolarMutexGuard g;
+
+ if ( m_bInitialized )
+ return;
+
+ for ( const Any& rArg : aArguments )
+ {
+ PropertyValue aPropValue;
+ if ( rArg >>= aPropValue )
+ {
+ if ( aPropValue.Name == UIELEMENT_PROPNAME_CONFIGSOURCE )
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_CONFIGSOURCE, aPropValue.Value );
+ else if ( aPropValue.Name == UIELEMENT_PROPNAME_FRAME )
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_FRAME, aPropValue.Value );
+ else if ( aPropValue.Name == UIELEMENT_PROPNAME_PERSISTENT )
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_PERSISTENT, aPropValue.Value );
+ else if ( aPropValue.Name == UIELEMENT_PROPNAME_RESOURCEURL )
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_RESOURCEURL, aPropValue.Value );
+ else if ( aPropValue.Name == UIELEMENT_PROPNAME_TYPE )
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_TYPE, aPropValue.Value );
+ else if ( aPropValue.Name == UIELEMENT_PROPNAME_CONFIGLISTENER )
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_CONFIGLISTENER, aPropValue.Value );
+ else if ( aPropValue.Name == UIELEMENT_PROPNAME_NOCLOSE )
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_NOCLOSE, aPropValue.Value );
+ }
+ }
+
+ m_bInitialized = true;
+}
+
+// XUpdatable
+void SAL_CALL UIConfigElementWrapperBase::update()
+{
+ // can be implemented by derived class
+}
+
+void SAL_CALL UIConfigElementWrapperBase::elementInserted( const css::ui::ConfigurationEvent& )
+{
+ // can be implemented by derived class
+}
+
+void SAL_CALL UIConfigElementWrapperBase::elementRemoved( const css::ui::ConfigurationEvent& )
+{
+ // can be implemented by derived class
+}
+
+void SAL_CALL UIConfigElementWrapperBase::elementReplaced( const css::ui::ConfigurationEvent& )
+{
+ // can be implemented by derived class
+}
+
+// XPropertySet helper
+sal_Bool SAL_CALL UIConfigElementWrapperBase::convertFastPropertyValue( Any& aConvertedValue ,
+ Any& aOldValue ,
+ sal_Int32 nHandle ,
+ const Any& aValue )
+{
+ // Initialize state with sal_False !!!
+ // (Handle can be invalid)
+ bool bReturn = false;
+
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_CONFIGLISTENER:
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(m_bConfigListener),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_CONFIGSOURCE:
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(m_xConfigSource),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_FRAME:
+ {
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(xFrame),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ }
+ break;
+
+ case UIELEMENT_PROPHANDLE_PERSISTENT:
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(m_bPersistent),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(m_aResourceURL),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_TYPE :
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(m_nType),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_XMENUBAR :
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(m_xMenuBar),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_NOCLOSE:
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::Any(m_bNoClose),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn;
+}
+
+void SAL_CALL UIConfigElementWrapperBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
+ const css::uno::Any& aValue )
+{
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_CONFIGLISTENER:
+ {
+ bool bBool( m_bConfigListener );
+ aValue >>= bBool;
+ if ( m_bConfigListener != bBool )
+ {
+ if ( m_bConfigListening )
+ {
+ if ( m_xConfigSource.is() && !bBool )
+ {
+ try
+ {
+ Reference< XUIConfiguration > xUIConfig( m_xConfigSource, UNO_QUERY );
+ if ( xUIConfig.is() )
+ {
+ xUIConfig->removeConfigurationListener( Reference< XUIConfigurationListener >(this) );
+ m_bConfigListening = false;
+ }
+ }
+ catch ( const Exception& )
+ {
+ }
+ }
+ }
+ else
+ {
+ if ( m_xConfigSource.is() && bBool )
+ {
+ try
+ {
+ Reference< XUIConfiguration > xUIConfig( m_xConfigSource, UNO_QUERY );
+ if ( xUIConfig.is() )
+ {
+ xUIConfig->addConfigurationListener( Reference< XUIConfigurationListener >(this) );
+ m_bConfigListening = true;
+ }
+ }
+ catch ( const Exception& )
+ {
+ }
+ }
+ }
+
+ m_bConfigListener = bBool;
+ }
+ }
+ break;
+ case UIELEMENT_PROPHANDLE_CONFIGSOURCE:
+ aValue >>= m_xConfigSource;
+ break;
+ case UIELEMENT_PROPHANDLE_FRAME:
+ {
+ Reference< XFrame > xFrame;
+
+ aValue >>= xFrame;
+ m_xWeakFrame = xFrame;
+ break;
+ }
+ case UIELEMENT_PROPHANDLE_PERSISTENT:
+ {
+ bool bBool( m_bPersistent );
+ aValue >>= bBool;
+ m_bPersistent = bBool;
+ break;
+ }
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ aValue >>= m_aResourceURL;
+ break;
+ case UIELEMENT_PROPHANDLE_TYPE:
+ aValue >>= m_nType;
+ break;
+ case UIELEMENT_PROPHANDLE_XMENUBAR:
+ aValue >>= m_xMenuBar;
+ break;
+ case UIELEMENT_PROPHANDLE_NOCLOSE:
+ {
+ bool bBool( m_bNoClose );
+ aValue >>= bBool;
+ m_bNoClose = bBool;
+ break;
+ }
+ }
+}
+
+void SAL_CALL UIConfigElementWrapperBase::getFastPropertyValue( css::uno::Any& aValue ,
+ sal_Int32 nHandle ) const
+{
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_CONFIGLISTENER:
+ aValue <<= m_bConfigListener;
+ break;
+ case UIELEMENT_PROPHANDLE_CONFIGSOURCE:
+ aValue <<= m_xConfigSource;
+ break;
+ case UIELEMENT_PROPHANDLE_FRAME:
+ {
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ aValue <<= xFrame;
+ break;
+ }
+ case UIELEMENT_PROPHANDLE_PERSISTENT:
+ aValue <<= m_bPersistent;
+ break;
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ aValue <<= m_aResourceURL;
+ break;
+ case UIELEMENT_PROPHANDLE_TYPE:
+ aValue <<= m_nType;
+ break;
+ case UIELEMENT_PROPHANDLE_XMENUBAR:
+ aValue <<= m_xMenuBar;
+ break;
+ case UIELEMENT_PROPHANDLE_NOCLOSE:
+ aValue <<= m_bNoClose;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL UIConfigElementWrapperBase::getInfoHelper()
+{
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
+ // "true" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper ourInfoHelper( impl_getStaticPropertyDescriptor(), true );
+
+ return ourInfoHelper;
+}
+
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL UIConfigElementWrapperBase::getPropertySetInfo()
+{
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+
+ return xInfo;
+}
+
+css::uno::Sequence< css::beans::Property > UIConfigElementWrapperBase::impl_getStaticPropertyDescriptor()
+{
+ // Create property array to initialize sequence!
+ // Table of all predefined properties of this class. It's used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ return
+ {
+ css::beans::Property( UIELEMENT_PROPNAME_CONFIGLISTENER, UIELEMENT_PROPHANDLE_CONFIGLISTENER , cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::TRANSIENT ),
+ css::beans::Property( UIELEMENT_PROPNAME_CONFIGSOURCE, UIELEMENT_PROPHANDLE_CONFIGSOURCE , cppu::UnoType<css::ui::XUIConfigurationManager>::get(), css::beans::PropertyAttribute::TRANSIENT ),
+ css::beans::Property( UIELEMENT_PROPNAME_FRAME, UIELEMENT_PROPHANDLE_FRAME , cppu::UnoType<css::frame::XFrame>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( UIELEMENT_PROPNAME_NOCLOSE, UIELEMENT_PROPHANDLE_NOCLOSE , cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::TRANSIENT ),
+ css::beans::Property( UIELEMENT_PROPNAME_PERSISTENT, UIELEMENT_PROPHANDLE_PERSISTENT , cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::TRANSIENT ),
+ css::beans::Property( UIELEMENT_PROPNAME_RESOURCEURL, UIELEMENT_PROPHANDLE_RESOURCEURL , cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( UIELEMENT_PROPNAME_TYPE, UIELEMENT_PROPHANDLE_TYPE , cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( UIELEMENT_PROPNAME_XMENUBAR, UIELEMENT_PROPHANDLE_XMENUBAR , cppu::UnoType<css::awt::XMenuBar>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY )
+ };
+}
+
+void SAL_CALL UIConfigElementWrapperBase::setSettings( const Reference< XIndexAccess >& xSettings )
+{
+ SolarMutexClearableGuard aLock;
+
+ if ( !xSettings.is() )
+ return;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( xSettings, UNO_QUERY );
+ if ( xReplace.is() )
+ m_xConfigData = new ConstItemContainer( xSettings );
+ else
+ m_xConfigData = xSettings;
+
+ if ( m_xConfigSource.is() && m_bPersistent )
+ {
+ OUString aResourceURL( m_aResourceURL );
+ Reference< XUIConfigurationManager > xUICfgMgr( m_xConfigSource );
+
+ aLock.clear();
+
+ try
+ {
+ xUICfgMgr->replaceSettings( aResourceURL, m_xConfigData );
+ }
+ catch( const NoSuchElementException& )
+ {
+ }
+ }
+ else if ( !m_bPersistent )
+ {
+ // Transient menubar => Fill menubar with new data
+ impl_fillNewData();
+ }
+}
+void UIConfigElementWrapperBase::impl_fillNewData()
+{
+}
+Reference< XIndexAccess > SAL_CALL UIConfigElementWrapperBase::getSettings( sal_Bool bWriteable )
+{
+ SolarMutexGuard g;
+
+ if ( bWriteable )
+ return Reference< XIndexAccess >( new RootItemContainer( m_xConfigData ) );
+
+ return m_xConfigData;
+}
+
+Reference< XFrame > SAL_CALL UIConfigElementWrapperBase::getFrame()
+{
+ SolarMutexGuard g;
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ return xFrame;
+}
+
+OUString SAL_CALL UIConfigElementWrapperBase::getResourceURL()
+{
+ SolarMutexGuard g;
+ return m_aResourceURL;
+}
+
+::sal_Int16 SAL_CALL UIConfigElementWrapperBase::getType()
+{
+ SolarMutexGuard g;
+ return m_nType;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/uielementwrapperbase.cxx b/framework/source/helper/uielementwrapperbase.cxx
new file mode 100644
index 000000000..829e4f952
--- /dev/null
+++ b/framework/source/helper/uielementwrapperbase.cxx
@@ -0,0 +1,203 @@
+/* -*- 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 <helper/uielementwrapperbase.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#include <vcl/svapp.hxx>
+#include <comphelper/sequence.hxx>
+
+const int UIELEMENT_PROPHANDLE_RESOURCEURL = 1;
+const int UIELEMENT_PROPHANDLE_TYPE = 2;
+const int UIELEMENT_PROPHANDLE_FRAME = 3;
+constexpr OUStringLiteral UIELEMENT_PROPNAME_RESOURCEURL = u"ResourceURL";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_TYPE = u"Type";
+constexpr OUStringLiteral UIELEMENT_PROPNAME_FRAME = u"Frame";
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+
+UIElementWrapperBase::UIElementWrapperBase( sal_Int16 nType )
+ : ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aMutex )
+ , ::cppu::OPropertySetHelper ( *static_cast< ::cppu::OBroadcastHelper* >(this) )
+ , m_aListenerContainer ( m_aMutex )
+ , m_nType ( nType )
+ , m_bInitialized ( false )
+ , m_bDisposed ( false )
+{
+}
+
+UIElementWrapperBase::~UIElementWrapperBase()
+{
+}
+
+Any SAL_CALL UIElementWrapperBase::queryInterface( const Type& _rType )
+{
+ Any aRet = UIElementWrapperBase_BASE::queryInterface( _rType );
+ if ( !aRet.hasValue() )
+ aRet = OPropertySetHelper::queryInterface( _rType );
+ return aRet;
+}
+
+Sequence< Type > SAL_CALL UIElementWrapperBase::getTypes( )
+{
+ return comphelper::concatSequences(
+ UIElementWrapperBase_BASE::getTypes(),
+ ::cppu::OPropertySetHelper::getTypes()
+ );
+}
+
+void SAL_CALL UIElementWrapperBase::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ m_aListenerContainer.addInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
+}
+
+void SAL_CALL UIElementWrapperBase::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ m_aListenerContainer.removeInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
+}
+
+void SAL_CALL UIElementWrapperBase::initialize( const Sequence< Any >& aArguments )
+{
+ SolarMutexGuard g;
+
+ if ( m_bInitialized )
+ return;
+
+ for ( const Any& rArg : aArguments )
+ {
+ PropertyValue aPropValue;
+ if ( rArg >>= aPropValue )
+ {
+ if ( aPropValue.Name == "ResourceURL" )
+ aPropValue.Value >>= m_aResourceURL;
+ else if ( aPropValue.Name == "Frame" )
+ {
+ Reference< XFrame > xFrame;
+ aPropValue.Value >>= xFrame;
+ m_xWeakFrame = xFrame;
+ }
+ }
+ }
+
+ m_bInitialized = true;
+}
+
+// XUIElement
+css::uno::Reference< css::frame::XFrame > SAL_CALL UIElementWrapperBase::getFrame()
+{
+ css::uno::Reference< css::frame::XFrame > xFrame( m_xWeakFrame );
+ return xFrame;
+}
+
+OUString SAL_CALL UIElementWrapperBase::getResourceURL()
+{
+ return m_aResourceURL;
+}
+
+::sal_Int16 SAL_CALL UIElementWrapperBase::getType()
+{
+ return m_nType;
+}
+
+// XUpdatable
+void SAL_CALL UIElementWrapperBase::update()
+{
+ // can be implemented by derived class
+}
+
+// XPropertySet helper
+sal_Bool SAL_CALL UIElementWrapperBase::convertFastPropertyValue( Any& /*aConvertedValue*/ ,
+ Any& /*aOldValue*/ ,
+ sal_Int32 /*nHandle*/ ,
+ const Any& /*aValue*/ )
+{
+ // Initialize state with sal_False !!!
+ // (Handle can be invalid)
+ return false;
+}
+
+void SAL_CALL UIElementWrapperBase::setFastPropertyValue_NoBroadcast( sal_Int32 /*nHandle*/ ,
+ const css::uno::Any& /*aValue*/ )
+{
+}
+
+void SAL_CALL UIElementWrapperBase::getFastPropertyValue( css::uno::Any& aValue ,
+ sal_Int32 nHandle ) const
+{
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ aValue <<= m_aResourceURL;
+ break;
+ case UIELEMENT_PROPHANDLE_TYPE:
+ aValue <<= m_nType;
+ break;
+ case UIELEMENT_PROPHANDLE_FRAME:
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ aValue <<= xFrame;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL UIElementWrapperBase::getInfoHelper()
+{
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
+ // "true" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper ourInfoHelper( impl_getStaticPropertyDescriptor(), true );
+
+ return ourInfoHelper;
+}
+
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL UIElementWrapperBase::getPropertySetInfo()
+{
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+
+ return xInfo;
+}
+
+css::uno::Sequence< css::beans::Property > UIElementWrapperBase::impl_getStaticPropertyDescriptor()
+{
+ // Create a property array to initialize sequence!
+ // Table of all predefined properties of this class. It's used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ return
+ {
+ css::beans::Property( UIELEMENT_PROPNAME_FRAME, UIELEMENT_PROPHANDLE_FRAME , cppu::UnoType<XFrame>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( UIELEMENT_PROPNAME_RESOURCEURL, UIELEMENT_PROPHANDLE_RESOURCEURL , cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( UIELEMENT_PROPNAME_TYPE, UIELEMENT_PROPHANDLE_TYPE , cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY )
+ };
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/vclstatusindicator.cxx b/framework/source/helper/vclstatusindicator.cxx
new file mode 100644
index 000000000..b493eacc7
--- /dev/null
+++ b/framework/source/helper/vclstatusindicator.cxx
@@ -0,0 +1,140 @@
+/* -*- 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 <helper/vclstatusindicator.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+
+namespace framework {
+
+VCLStatusIndicator::VCLStatusIndicator(css::uno::Reference< css::awt::XWindow > xParentWindow)
+ : m_xParentWindow (std::move(xParentWindow ))
+ , m_pStatusBar (nullptr )
+ , m_nRange (0 )
+ , m_nValue (0 )
+{
+ if (!m_xParentWindow.is())
+ throw css::uno::RuntimeException(
+ "Can't work without a parent window!",
+ static_cast< css::task::XStatusIndicator* >(this));
+}
+
+VCLStatusIndicator::~VCLStatusIndicator()
+{
+}
+
+void SAL_CALL VCLStatusIndicator::start(const OUString& sText ,
+ sal_Int32 nRange)
+{
+ SolarMutexGuard aSolarGuard;
+
+ VclPtr<vcl::Window> pParentWindow = VCLUnoHelper::GetWindow(m_xParentWindow);
+ if (!m_pStatusBar)
+ m_pStatusBar = VclPtr<StatusBar>::Create(pParentWindow, WB_3DLOOK|WB_BORDER);
+
+ VCLStatusIndicator::impl_recalcLayout(m_pStatusBar, pParentWindow);
+
+ m_pStatusBar->Show();
+ m_pStatusBar->StartProgressMode(sText);
+ m_pStatusBar->SetProgressValue(0);
+
+ // force repaint!
+ pParentWindow->Show();
+ pParentWindow->Invalidate(InvalidateFlags::Children);
+ pParentWindow->GetOutDev()->Flush();
+
+ m_nRange = nRange;
+ m_nValue = 0;
+}
+
+void SAL_CALL VCLStatusIndicator::reset()
+{
+ SolarMutexGuard aSolarGuard;
+ if (m_pStatusBar)
+ {
+ m_pStatusBar->SetProgressValue(0);
+ m_pStatusBar->SetText(OUString());
+ }
+}
+
+void SAL_CALL VCLStatusIndicator::end()
+{
+ SolarMutexGuard aSolarGuard;
+
+ m_nRange = 0;
+ m_nValue = 0;
+
+ if (m_pStatusBar)
+ {
+ m_pStatusBar->EndProgressMode();
+ m_pStatusBar->Show(false);
+
+ m_pStatusBar.disposeAndClear();
+ }
+}
+
+void SAL_CALL VCLStatusIndicator::setText(const OUString& sText)
+{
+ SolarMutexGuard aSolarGuard;
+ if (m_pStatusBar)
+ m_pStatusBar->SetText(sText);
+}
+
+void SAL_CALL VCLStatusIndicator::setValue(sal_Int32 nValue)
+{
+ SolarMutexGuard aSolarGuard;
+
+ if (nValue <= m_nRange)
+ m_nValue = nValue;
+ else
+ m_nValue = m_nRange;
+
+ sal_Int32 nRange = m_nRange;
+ nValue = m_nValue;
+
+ // normalize value to fit the range of 0-100%
+ sal_uInt16 nPercent = sal::static_int_cast< sal_uInt16 >(
+ ::std::min(
+ ((nValue*100) / ::std::max(nRange,sal_Int32(1))), sal_Int32(100)));
+
+ if (m_pStatusBar)
+ m_pStatusBar->SetProgressValue(nPercent);
+}
+
+void VCLStatusIndicator::impl_recalcLayout(vcl::Window* pStatusBar ,
+ vcl::Window const * pParentWindow)
+{
+ if (
+ (!pStatusBar ) ||
+ (!pParentWindow)
+ )
+ return;
+
+ Size aParentSize = pParentWindow->GetSizePixel();
+ pStatusBar->setPosSizePixel(0,
+ 0,
+ aParentSize.Width(),
+ aParentSize.Height());
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/wakeupthread.cxx b/framework/source/helper/wakeupthread.cxx
new file mode 100644
index 000000000..40487c83b
--- /dev/null
+++ b/framework/source/helper/wakeupthread.cxx
@@ -0,0 +1,60 @@
+/* -*- 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 <sal/config.h>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/util/XUpdatable.hpp>
+
+#include <helper/wakeupthread.hxx>
+#include <chrono>
+
+using namespace std::chrono_literals;
+
+void framework::WakeUpThread::execute() {
+ for (;;) {
+ {
+ std::unique_lock g(mutex_);
+ condition_.wait_for(g, 25ms, [this] { return terminate_; });
+ if (terminate_) {
+ break;
+ }
+ }
+ css::uno::Reference<css::util::XUpdatable> up(updatable_);
+ if (up.is()) {
+ up->update();
+ }
+ }
+}
+
+framework::WakeUpThread::WakeUpThread(
+ css::uno::Reference<css::util::XUpdatable> const & updatable):
+ Thread("WakeUpThread"), updatable_(updatable), terminate_(false)
+{}
+
+void framework::WakeUpThread::stop() {
+ {
+ std::unique_lock g(mutex_);
+ terminate_ = true;
+ }
+ condition_.notify_one();
+ join();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */