diff options
Diffstat (limited to 'framework/source/fwe/helper')
-rw-r--r-- | framework/source/fwe/helper/actiontriggerhelper.cxx | 3 | ||||
-rw-r--r-- | framework/source/fwe/helper/documentundoguard.cxx | 70 | ||||
-rw-r--r-- | framework/source/fwe/helper/propertysetcontainer.cxx | 14 | ||||
-rw-r--r-- | framework/source/fwe/helper/titlehelper.cxx | 199 | ||||
-rw-r--r-- | framework/source/fwe/helper/undomanagerhelper.cxx | 125 |
5 files changed, 215 insertions, 196 deletions
diff --git a/framework/source/fwe/helper/actiontriggerhelper.cxx b/framework/source/fwe/helper/actiontriggerhelper.cxx index 82f5d558f3be..88edd70beb79 100644 --- a/framework/source/fwe/helper/actiontriggerhelper.cxx +++ b/framework/source/fwe/helper/actiontriggerhelper.cxx @@ -31,6 +31,7 @@ #include <vcl/dibtools.hxx> #include <vcl/graph.hxx> #include <vcl/svapp.hxx> +#include <o3tl/string_view.hxx> const sal_uInt16 START_ITEMID = 1000; @@ -139,7 +140,7 @@ static void InsertSubMenuItems(const Reference<XPopupMenu>& rSubMenu, sal_uInt16 // command url but uses the item id as a unique identifier. These entries // got a special url during conversion from menu=>actiontriggercontainer. // Now we have to extract this special url and set the correct item id!!! - nNewItemId = static_cast<sal_uInt16>(aCommandURL.copy( nIndex+aSlotURL.getLength() ).toInt32()); + nNewItemId = static_cast<sal_uInt16>(o3tl::toInt32(aCommandURL.subView( nIndex+aSlotURL.getLength() ))); rSubMenu->insertItem(nNewItemId, aLabel, 0, i); } else diff --git a/framework/source/fwe/helper/documentundoguard.cxx b/framework/source/fwe/helper/documentundoguard.cxx index 5f7d16041caa..f578d8682731 100644 --- a/framework/source/fwe/helper/documentundoguard.cxx +++ b/framework/source/fwe/helper/documentundoguard.cxx @@ -23,7 +23,7 @@ #include <cppuhelper/implbase.hxx> #include <rtl/ref.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> namespace framework { @@ -31,7 +31,6 @@ namespace framework using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::UNO_QUERY; - using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::document::XUndoManagerSupplier; using ::com::sun::star::document::XUndoManager; @@ -44,8 +43,6 @@ namespace framework typedef ::cppu::WeakImplHelper < XUndoManagerListener > UndoManagerContextListener_Base; - namespace { - class UndoManagerContextListener : public UndoManagerContextListener_Base { public: @@ -100,8 +97,6 @@ namespace framework bool m_documentDisposed; }; - } - void SAL_CALL UndoManagerContextListener::undoActionAdded( const UndoManagerEvent& ) { // not interested in @@ -162,60 +157,37 @@ namespace framework m_documentDisposed = true; } - //= DocumentUndoGuard_Data - - struct DocumentUndoGuard_Data - { - Reference< XUndoManager > xUndoManager; - ::rtl::Reference< UndoManagerContextListener > pContextListener; - }; + //= DocumentUndoGuard - namespace + DocumentUndoGuard::DocumentUndoGuard( const Reference< XInterface >& i_undoSupplierComponent ) { - - void lcl_init( DocumentUndoGuard_Data& i_data, const Reference< XInterface >& i_undoSupplierComponent ) + try { - try - { - Reference< XUndoManagerSupplier > xUndoSupplier( i_undoSupplierComponent, UNO_QUERY ); - if ( xUndoSupplier.is() ) - i_data.xUndoManager.set( xUndoSupplier->getUndoManager(), css::uno::UNO_SET_THROW ); + Reference< XUndoManagerSupplier > xUndoSupplier( i_undoSupplierComponent, UNO_QUERY ); + if ( xUndoSupplier.is() ) + mxUndoManager.set( xUndoSupplier->getUndoManager(), css::uno::UNO_SET_THROW ); - if ( i_data.xUndoManager.is() ) - i_data.pContextListener.set( new UndoManagerContextListener( i_data.xUndoManager ) ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("fwk"); - } + if ( mxUndoManager.is() ) + mxContextListener.set( new UndoManagerContextListener( mxUndoManager ) ); } - - void lcl_restore( DocumentUndoGuard_Data& i_data ) + catch( const Exception& ) { - try - { - if ( i_data.pContextListener.is() ) - i_data.pContextListener->finish(); - i_data.pContextListener.clear(); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("fwk"); - } + DBG_UNHANDLED_EXCEPTION("fwk"); } } - //= DocumentUndoGuard - - DocumentUndoGuard::DocumentUndoGuard( const Reference< XInterface >& i_undoSupplierComponent ) - :m_xData( new DocumentUndoGuard_Data ) - { - lcl_init( *m_xData, i_undoSupplierComponent ); - } - DocumentUndoGuard::~DocumentUndoGuard() { - lcl_restore( *m_xData ); + try + { + if ( mxContextListener.is() ) + mxContextListener->finish(); + mxContextListener.clear(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("fwk"); + } } } // namespace framework diff --git a/framework/source/fwe/helper/propertysetcontainer.cxx b/framework/source/fwe/helper/propertysetcontainer.cxx index ad7d639539b7..c766b40db56b 100644 --- a/framework/source/fwe/helper/propertysetcontainer.cxx +++ b/framework/source/fwe/helper/propertysetcontainer.cxx @@ -23,7 +23,7 @@ #include <cppuhelper/queryinterface.hxx> #include <vcl/svapp.hxx> -constexpr OUStringLiteral WRONG_TYPE_EXCEPTION = u"Only XPropertSet allowed!"; +constexpr OUString WRONG_TYPE_EXCEPTION = u"Only XPropertSet allowed!"_ustr; using namespace cppu; using namespace com::sun::star::uno; @@ -73,7 +73,7 @@ Any SAL_CALL PropertySetContainer::queryInterface( const Type& rType ) // XIndexContainer void SAL_CALL PropertySetContainer::insertByIndex( sal_Int32 Index, const css::uno::Any& Element ) { - SolarMutexGuard g; + std::unique_lock g(m_aMutex); sal_Int32 nSize = m_aPropertySetVector.size(); @@ -101,7 +101,7 @@ void SAL_CALL PropertySetContainer::insertByIndex( sal_Int32 Index, const css::u void SAL_CALL PropertySetContainer::removeByIndex( sal_Int32 nIndex ) { - SolarMutexGuard g; + std::unique_lock g(m_aMutex); if ( static_cast<sal_Int32>(m_aPropertySetVector.size()) <= nIndex ) throw IndexOutOfBoundsException( OUString(), static_cast<OWeakObject *>(this) ); @@ -112,6 +112,8 @@ void SAL_CALL PropertySetContainer::removeByIndex( sal_Int32 nIndex ) // XIndexReplace void SAL_CALL PropertySetContainer::replaceByIndex( sal_Int32 Index, const css::uno::Any& Element ) { + std::unique_lock g(m_aMutex); + if ( static_cast<sal_Int32>(m_aPropertySetVector.size()) <= Index ) throw IndexOutOfBoundsException( OUString(), static_cast<OWeakObject *>(this) ); @@ -130,14 +132,14 @@ void SAL_CALL PropertySetContainer::replaceByIndex( sal_Int32 Index, const css:: // XIndexAccess sal_Int32 SAL_CALL PropertySetContainer::getCount() { - SolarMutexGuard g; + std::unique_lock g(m_aMutex); return m_aPropertySetVector.size(); } Any SAL_CALL PropertySetContainer::getByIndex( sal_Int32 Index ) { - SolarMutexGuard g; + std::unique_lock g(m_aMutex); if ( static_cast<sal_Int32>(m_aPropertySetVector.size()) <= Index ) throw IndexOutOfBoundsException( OUString(), static_cast<OWeakObject *>(this) ); @@ -148,7 +150,7 @@ Any SAL_CALL PropertySetContainer::getByIndex( sal_Int32 Index ) // XElementAccess sal_Bool SAL_CALL PropertySetContainer::hasElements() { - SolarMutexGuard g; + std::unique_lock g(m_aMutex); return !( m_aPropertySetVector.empty() ); } diff --git a/framework/source/fwe/helper/titlehelper.cxx b/framework/source/fwe/helper/titlehelper.cxx index 740d98a753ec..58c28f8f8ef9 100644 --- a/framework/source/fwe/helper/titlehelper.cxx +++ b/framework/source/fwe/helper/titlehelper.cxx @@ -29,6 +29,7 @@ #include <com/sun/star/frame/XModel3.hpp> #include <com/sun/star/document/XDocumentEventBroadcaster.hpp> +#include <comphelper/configuration.hxx> #include <unotools/configmgr.hxx> #include <unotools/bootstrap.hxx> #include <unotools/mediadescriptor.hxx> @@ -36,6 +37,7 @@ #include <rtl/ustrbuf.hxx> #include <osl/mutex.hxx> #include <tools/urlobj.hxx> +#include <utility> #include <vcl/svapp.hxx> @@ -45,43 +47,28 @@ using namespace css::frame; namespace framework{ -TitleHelper::TitleHelper(const css::uno::Reference< css::uno::XComponentContext >& rxContext, +TitleHelper::TitleHelper(css::uno::Reference< css::uno::XComponentContext > xContext, const css::uno::Reference< css::uno::XInterface >& xOwner, const css::uno::Reference< css::frame::XUntitledNumbers >& xNumbers) - : ::cppu::BaseMutex () - , m_xContext (rxContext) + : + m_xContext (std::move(xContext)) + , m_xOwner (xOwner) + , m_xUntitledNumbers(xNumbers) , m_bExternalTitle (false) , m_nLeasedNumber (css::frame::UntitledNumbersConst::INVALID_NUMBER) - , m_aListener (m_aMutex) { - // SYNCHRONIZED -> - { - osl::MutexGuard aLock(m_aMutex); - - m_xOwner = xOwner; - m_xUntitledNumbers = xNumbers; - } - // <- SYNCHRONIZED - - css::uno::Reference< css::frame::XModel > xModel(xOwner, css::uno::UNO_QUERY); - if (xModel.is ()) + if (css::uno::Reference<css::frame::XModel> xModel{ xOwner, css::uno::UNO_QUERY }) { impl_startListeningForModel (xModel); - return; } - - css::uno::Reference< css::frame::XController > xController(xOwner, css::uno::UNO_QUERY); - if (xController.is ()) + else if (css::uno::Reference<css::frame::XController> xController{ xOwner, + css::uno::UNO_QUERY }) { impl_startListeningForController (xController); - return; } - - css::uno::Reference< css::frame::XFrame > xFrame(xOwner, css::uno::UNO_QUERY); - if (xFrame.is ()) + else if (css::uno::Reference<css::frame::XFrame> xFrame{ xOwner, css::uno::UNO_QUERY }) { impl_startListeningForFrame (xFrame); - return; } } @@ -92,7 +79,7 @@ TitleHelper::~TitleHelper() OUString SAL_CALL TitleHelper::getTitle() { // SYNCHRONIZED -> - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); // An external title will win always and disable all internal logic about // creating/using a title value. @@ -104,8 +91,10 @@ OUString SAL_CALL TitleHelper::getTitle() if (!m_sTitle.isEmpty()) return m_sTitle; - // Title seems to be unused till now ... do bootstraping + // Title seems to be unused till now ... do bootstrapping + aLock.unlock(); impl_updateTitle (true); + aLock.lock(); return m_sTitle; // <- SYNCHRONIZED @@ -115,7 +104,7 @@ void SAL_CALL TitleHelper::setTitle(const OUString& sTitle) { // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); m_bExternalTitle = true; m_sTitle = sTitle; @@ -127,14 +116,14 @@ void SAL_CALL TitleHelper::setTitle(const OUString& sTitle) void SAL_CALL TitleHelper::addTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener) { - // container is threadsafe by himself - m_aListener.addInterface( cppu::UnoType<css::frame::XTitleChangeListener>::get(), xListener ); + std::unique_lock aLock(m_aMutex); + m_aTitleChangeListeners.addInterface( aLock, xListener ); } void SAL_CALL TitleHelper::removeTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener) { - // container is threadsafe by himself - m_aListener.removeInterface( cppu::UnoType<css::frame::XTitleChangeListener>::get(), xListener ); + std::unique_lock aLock(m_aMutex); + m_aTitleChangeListeners.removeInterface( aLock, xListener ); } void SAL_CALL TitleHelper::titleChanged(const css::frame::TitleChangedEvent& aEvent) @@ -142,9 +131,9 @@ void SAL_CALL TitleHelper::titleChanged(const css::frame::TitleChangedEvent& aEv css::uno::Reference< css::frame::XTitle > xSubTitle; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); - xSubTitle.set(m_xSubTitle.get (), css::uno::UNO_QUERY); + xSubTitle = m_xSubTitle; } // <- SYNCHRONIZED @@ -164,9 +153,9 @@ void SAL_CALL TitleHelper::documentEventOccured(const css::document::DocumentEve css::uno::Reference< css::frame::XModel > xOwner; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); - xOwner.set(m_xOwner.get (), css::uno::UNO_QUERY); + xOwner.set(m_xOwner, css::uno::UNO_QUERY); } // <- SYNCHRONIZED @@ -186,9 +175,9 @@ void SAL_CALL TitleHelper::frameAction(const css::frame::FrameActionEvent& aEven css::uno::Reference< css::frame::XFrame > xOwner; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); - xOwner.set(m_xOwner.get (), css::uno::UNO_QUERY); + xOwner.set(m_xOwner, css::uno::UNO_QUERY); } // <- SYNCHRONIZED @@ -215,10 +204,10 @@ void SAL_CALL TitleHelper::disposing(const css::lang::EventObject& aEvent) ::sal_Int32 nLeasedNumber; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); xOwner = m_xOwner; - xNumbers.set(m_xUntitledNumbers.get(), css::uno::UNO_QUERY); + xNumbers = m_xUntitledNumbers; nLeasedNumber = m_nLeasedNumber; } // <- SYNCHRONIZED @@ -241,10 +230,10 @@ void SAL_CALL TitleHelper::disposing(const css::lang::EventObject& aEvent) // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); - m_xOwner = nullptr; - m_sTitle = OUString (); + m_xOwner.clear(); + m_sTitle.clear(); m_nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER; } // <- SYNCHRONIZED @@ -255,7 +244,7 @@ void TitleHelper::impl_sendTitleChangedEvent () css::uno::Reference<css::uno::XInterface> xOwner; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); xOwner = m_xOwner; } @@ -266,53 +255,60 @@ void TitleHelper::impl_sendTitleChangedEvent () if( ! aEvent.Source.is() ) return; - comphelper::OInterfaceContainerHelper2* pContainer = m_aListener.getContainer( cppu::UnoType<css::frame::XTitleChangeListener>::get()); - if ( ! pContainer) - return; - - comphelper::OInterfaceIteratorHelper2 pIt( *pContainer ); + std::unique_lock aLock(m_aMutex); + comphelper::OInterfaceIteratorHelper4 pIt( aLock, m_aTitleChangeListeners ); while ( pIt.hasMoreElements() ) { + aLock.unlock(); try { - static_cast<css::frame::XTitleChangeListener*>(pIt.next())->titleChanged( aEvent ); + uno::Reference<css::frame::XTitleChangeListener> i = pIt.next(); + i->titleChanged( aEvent ); } catch(const css::uno::Exception&) { - pIt.remove(); + aLock.lock(); + pIt.remove(aLock); + aLock.unlock(); } + aLock.lock(); } } void TitleHelper::impl_updateTitle (bool init) { - css::uno::Reference< css::frame::XModel3 > xModel; - css::uno::Reference< css::frame::XController > xController; - css::uno::Reference< css::frame::XFrame > xFrame; + css::uno::Reference<css::uno::XInterface> xOwner; + // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); - xModel.set (m_xOwner.get(), css::uno::UNO_QUERY); - xController.set(m_xOwner.get(), css::uno::UNO_QUERY); - xFrame.set (m_xOwner.get(), css::uno::UNO_QUERY); + xOwner = m_xOwner; } // <- SYNCHRONIZED - if (xModel.is ()) + if (css::uno::Reference<css::frame::XModel3> xModel{ xOwner, css::uno::UNO_QUERY }) { impl_updateTitleForModel (xModel, init); } - else if (xController.is ()) + else if (css::uno::Reference<css::frame::XController> xController{ xOwner, + css::uno::UNO_QUERY }) { impl_updateTitleForController (xController, init); } - else if (xFrame.is ()) + else if (css::uno::Reference<css::frame::XFrame> xFrame{ xOwner, css::uno::UNO_QUERY }) { impl_updateTitleForFrame (xFrame, init); } } +static OUString getURLFromModel(const css::uno::Reference< css::frame::XModel3 >& xModel) +{ + if (css::uno::Reference<css::frame::XStorable> xURLProvider{ xModel, css::uno::UNO_QUERY }) + return xURLProvider->getLocation(); + return {}; +} + void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::frame::XModel3 >& xModel, bool init) { css::uno::Reference< css::uno::XInterface > xOwner; @@ -320,7 +316,7 @@ void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::fram ::sal_Int32 nLeasedNumber; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); // external title won't be updated internally! // It has to be set from outside new. @@ -328,7 +324,7 @@ void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::fram return; xOwner = m_xOwner; - xNumbers.set (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); + xNumbers = m_xUntitledNumbers; nLeasedNumber = m_nLeasedNumber; } // <- SYNCHRONIZED @@ -341,24 +337,27 @@ void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::fram return; OUString sTitle; - OUString sURL; - - css::uno::Reference< css::frame::XStorable > xURLProvider(xModel , css::uno::UNO_QUERY); - if (xURLProvider.is()) - sURL = xURLProvider->getLocation (); - utl::MediaDescriptor aDescriptor(xModel->getArgs2( { utl::MediaDescriptor::PROP_SUGGESTEDSAVEASNAME } )); - const OUString sSuggestedSaveAsName = aDescriptor.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_SUGGESTEDSAVEASNAME, OUString()); + utl::MediaDescriptor aDescriptor( + xModel->getArgs2({ utl::MediaDescriptor::PROP_DOCUMENTTITLE, + utl::MediaDescriptor::PROP_SUGGESTEDSAVEASNAME })); - if (!sURL.isEmpty()) + if (const OUString sMediaTitle = aDescriptor.getUnpackedValueOrDefault( + utl::MediaDescriptor::PROP_DOCUMENTTITLE, OUString()); + !sMediaTitle.isEmpty()) + { + sTitle = sMediaTitle; + } + else if (const OUString sURL = getURLFromModel(xModel); !sURL.isEmpty()) { sTitle = impl_convertURL2Title(sURL); if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) xNumbers->releaseNumber (nLeasedNumber); nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER; } - else if (!sSuggestedSaveAsName.isEmpty()) + else if (const OUString sSuggestedSaveAsName = aDescriptor.getUnpackedValueOrDefault( + utl::MediaDescriptor::PROP_SUGGESTEDSAVEASNAME, OUString()); + !sSuggestedSaveAsName.isEmpty()) { // tdf#121537 Use suggested save as name for title if file has not yet been saved sTitle = sSuggestedSaveAsName; @@ -368,20 +367,16 @@ void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::fram if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) nLeasedNumber = xNumbers->leaseNumber (xOwner); - OUStringBuffer sNewTitle(256); - sNewTitle.append (xNumbers->getUntitledPrefix ()); if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) - sNewTitle.append(nLeasedNumber); + sTitle = xNumbers->getUntitledPrefix() + OUString::number(nLeasedNumber); else - sNewTitle.append("?"); - - sTitle = sNewTitle.makeStringAndClear (); + sTitle = xNumbers->getUntitledPrefix() + "?"; } bool bChanged; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); // WORKAROUND: the notification is currently sent always, // can be changed after shared mode is supported per UNO API @@ -403,7 +398,7 @@ void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css: ::sal_Int32 nLeasedNumber; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); // external title won't be updated internally! // It has to be set from outside new. @@ -411,7 +406,7 @@ void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css: return; xOwner = m_xOwner; - xNumbers.set (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); + xNumbers = m_xUntitledNumbers; nLeasedNumber = m_nLeasedNumber; } // <- SYNCHRONIZED @@ -437,8 +432,7 @@ void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css: sTitle.append (xModelTitle->getTitle ()); if ( nLeasedNumber > 1 ) { - sTitle.append(" : "); - sTitle.append(nLeasedNumber); + sTitle.append(" : " + OUString::number(nLeasedNumber)); } if (xModel.is ()) { @@ -463,7 +457,7 @@ void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css: bool bChanged; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); OUString sNewTitle = sTitle.makeStringAndClear (); bChanged = !init && m_sTitle != sNewTitle; @@ -483,7 +477,7 @@ void TitleHelper::impl_updateTitleForFrame (const css::uno::Reference< css::fram // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); // external title won't be updated internally! // It has to be set from outside new. @@ -500,18 +494,21 @@ void TitleHelper::impl_updateTitleForFrame (const css::uno::Reference< css::fram impl_appendComponentTitle (sTitle, xComponent); #ifndef MACOSX - // fdo#70376: We want the window title to contain just the - // document name (from the above "component title"). - impl_appendProductName (sTitle); - impl_appendModuleName (sTitle); - impl_appendDebugVersion (sTitle); + if (!comphelper::IsFuzzing()) + { + // fdo#70376: We want the window title to contain just the + // document name (from the above "component title"). + impl_appendProductName (sTitle); + impl_appendModuleName (sTitle); + impl_appendDebugVersion (sTitle); + } #endif impl_appendSafeMode (sTitle); bool bChanged; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); OUString sNewTitle = sTitle.makeStringAndClear (); bChanged = !init && m_sTitle != sNewTitle; @@ -523,6 +520,7 @@ void TitleHelper::impl_updateTitleForFrame (const css::uno::Reference< css::fram impl_sendTitleChangedEvent (); } +// static void TitleHelper::impl_appendComponentTitle ( OUStringBuffer& sTitle , const css::uno::Reference< css::uno::XInterface >& xComponent) { @@ -533,13 +531,17 @@ void TitleHelper::impl_appendComponentTitle ( OUStringBuffer& sTitle.append (xTitle->getTitle ()); } +// static void TitleHelper::impl_appendProductName (OUStringBuffer& sTitle) { OUString name(utl::ConfigManager::getProductName()); if (!name.isEmpty()) { if (!sTitle.isEmpty()) - sTitle.append(" - "); + { + OUString separator (FwkResId (STR_EMDASH_SEPARATOR)); + sTitle.append(separator); + } sTitle.append(name); } } @@ -550,9 +552,9 @@ void TitleHelper::impl_appendModuleName (OUStringBuffer& sTitle) css::uno::Reference< css::uno::XComponentContext > xContext; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); - xOwner = m_xOwner.get(); + xOwner = m_xOwner; xContext = m_xContext; } // <- SYNCHRONIZED @@ -579,6 +581,7 @@ void TitleHelper::impl_appendModuleName (OUStringBuffer& sTitle) } #ifdef DBG_UTIL +// static void TitleHelper::impl_appendDebugVersion (OUStringBuffer& sTitle) { OUString version(utl::ConfigManager::getProductVersion()); @@ -595,6 +598,7 @@ void TitleHelper::impl_appendDebugVersion (OUStringBuffer&) } #endif +// static void TitleHelper::impl_appendSafeMode (OUStringBuffer& sTitle) { if (Application::IsSafeModeEnabled()) @@ -634,10 +638,10 @@ void TitleHelper::impl_setSubTitle (const css::uno::Reference< css::frame::XTitl css::uno::Reference< css::frame::XTitle > xOldSubTitle; // SYNCHRONIZED -> { - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); // ignore duplicate calls. Makes outside using of this helper more easy :-) - xOldSubTitle.set(m_xSubTitle.get(), css::uno::UNO_QUERY); + xOldSubTitle = m_xSubTitle; if (xOldSubTitle == xSubTitle) return; @@ -656,7 +660,8 @@ void TitleHelper::impl_setSubTitle (const css::uno::Reference< css::frame::XTitl xNewBroadcaster->addTitleChangeListener (xThis); } -OUString TitleHelper::impl_convertURL2Title(const OUString& sURL) +// static +OUString TitleHelper::impl_convertURL2Title(std::u16string_view sURL) { INetURLObject aURL (sURL); OUString sTitle; diff --git a/framework/source/fwe/helper/undomanagerhelper.cxx b/framework/source/fwe/helper/undomanagerhelper.cxx index 4b33fdc9f0d6..3a2fdd6c066b 100644 --- a/framework/source/fwe/helper/undomanagerhelper.cxx +++ b/framework/source/fwe/helper/undomanagerhelper.cxx @@ -29,18 +29,20 @@ #include <com/sun/star/util/NotLockedException.hpp> #include <com/sun/star/util/XModifyListener.hpp> -#include <comphelper/interfacecontainer3.hxx> +#include <comphelper/interfacecontainer4.hxx> #include <cppuhelper/exc_hlp.hxx> #include <comphelper/flagguard.hxx> #include <comphelper/asyncnotification.hxx> #include <svl/undo.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <osl/conditn.hxx> +#include <vcl/svapp.hxx> #include <functional> #include <mutex> #include <stack> #include <queue> +#include <utility> namespace framework { @@ -145,8 +147,8 @@ namespace framework class UndoManagerRequest : public ::comphelper::AnyEvent { public: - explicit UndoManagerRequest( ::std::function<void ()> const& i_request ) - :m_request( i_request ) + explicit UndoManagerRequest( ::std::function<void ()> i_request ) + :m_request(std::move( i_request )) { m_finishCondition.reset(); } @@ -199,12 +201,14 @@ namespace framework { private: ::osl::Mutex m_aMutex; + /// Use different mutex for listeners to prevent ABBA deadlocks + std::mutex m_aListenerMutex; std::mutex m_aQueueMutex; bool m_bAPIActionRunning; bool m_bProcessingEvents; sal_Int32 m_nLockCount; - ::comphelper::OInterfaceContainerHelper3<XUndoManagerListener> m_aUndoListeners; - ::comphelper::OInterfaceContainerHelper3<XModifyListener> m_aModifyListeners; + ::comphelper::OInterfaceContainerHelper4<XUndoManagerListener> m_aUndoListeners; + ::comphelper::OInterfaceContainerHelper4<XModifyListener> m_aModifyListeners; IUndoManagerImplementation& m_rUndoManagerImplementation; ::std::stack< bool > m_aContextVisibilities; #if OSL_DEBUG_LEVEL > 0 @@ -222,8 +226,6 @@ namespace framework :m_bAPIActionRunning( false ) ,m_bProcessingEvents( false ) ,m_nLockCount( 0 ) - ,m_aUndoListeners( m_aMutex ) - ,m_aModifyListeners( m_aMutex ) ,m_rUndoManagerImplementation( i_undoManagerImpl ) { getUndoManager().AddUndoListener( *this ); @@ -271,22 +273,26 @@ namespace framework void addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) { - m_aUndoListeners.addInterface( i_listener ); + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.addInterface( g, i_listener ); } void removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) { - m_aUndoListeners.removeInterface( i_listener ); + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.removeInterface( g, i_listener ); } void addModifyListener( const Reference< XModifyListener >& i_listener ) { - m_aModifyListeners.addInterface( i_listener ); + std::unique_lock g(m_aListenerMutex); + m_aModifyListeners.addInterface( g, i_listener ); } void removeModifyListener( const Reference< XModifyListener >& i_listener ) { - m_aModifyListeners.removeInterface( i_listener ); + std::unique_lock g(m_aListenerMutex); + m_aModifyListeners.removeInterface( g, i_listener ); } UndoManagerEvent @@ -316,9 +322,11 @@ namespace framework { EventObject aEvent; aEvent.Source = getXUndoManager(); - m_aUndoListeners.disposeAndClear( aEvent ); - m_aModifyListeners.disposeAndClear( aEvent ); - + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.disposeAndClear( g, aEvent ); + m_aModifyListeners.disposeAndClear( g, aEvent ); + } ::osl::MutexGuard aGuard( m_aMutex ); getUndoManager().RemoveUndoListener( *this ); @@ -336,7 +344,8 @@ namespace framework void UndoManagerHelper_Impl::impl_notifyModified() { const EventObject aEvent( getXUndoManager() ); - m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent ); + std::unique_lock g(m_aListenerMutex); + m_aModifyListeners.notifyEach( g, &XModifyListener::modified, aEvent ); } void UndoManagerHelper_Impl::notify( OUString const& i_title, @@ -350,7 +359,10 @@ namespace framework // Fixing this properly would require outsourcing all the notifications into an own thread - which might lead // to problems of its own, since clients might expect synchronous notifications. - m_aUndoListeners.notifyEach( i_notificationMethod, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, i_notificationMethod, aEvent ); + } impl_notifyModified(); } @@ -359,8 +371,10 @@ namespace framework const EventObject aEvent( getXUndoManager() ); // TODO: the same comment as in the other notify, regarding SM locking applies here ... - - m_aUndoListeners.notifyEach( i_notificationMethod, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, i_notificationMethod, aEvent ); + } impl_notifyModified(); } @@ -536,7 +550,10 @@ namespace framework aGuard.clear(); // <--- SYNCHRONIZED - m_aUndoListeners.notifyEach( i_hidden ? &XUndoManagerListener::enteredHiddenContext : &XUndoManagerListener::enteredContext, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, i_hidden ? &XUndoManagerListener::enteredHiddenContext : &XUndoManagerListener::enteredContext, aEvent ); + } impl_notifyModified(); } @@ -593,9 +610,12 @@ namespace framework aGuard.clear(); // <--- SYNCHRONIZED - if ( bHadRedoActions && !bHasRedoActions ) - m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aClearedEvent ); - m_aUndoListeners.notifyEach( notificationMethod, aContextEvent ); + { + std::unique_lock g(m_aListenerMutex); + if ( bHadRedoActions && !bHasRedoActions ) + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::redoActionsCleared, aClearedEvent ); + m_aUndoListeners.notifyEach( g, notificationMethod, aContextEvent ); + } impl_notifyModified(); } @@ -669,31 +689,38 @@ namespace framework aGuard.clear(); // <--- SYNCHRONIZED - m_aUndoListeners.notifyEach( &XUndoManagerListener::undoActionAdded, aEventAdd ); - if ( bHadRedoActions && !bHasRedoActions ) - m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aEventClear ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::undoActionAdded, aEventAdd ); + if ( bHadRedoActions && !bHasRedoActions ) + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::redoActionsCleared, aEventClear ); + } impl_notifyModified(); } void UndoManagerHelper_Impl::impl_clear() { - // SYNCHRONIZED ---> - ::osl::ClearableMutexGuard aGuard( m_aMutex ); + EventObject aEvent; + { + SolarMutexGuard aGuard; + ::osl::MutexGuard aGuard2( m_aMutex ); - SfxUndoManager& rUndoManager = getUndoManager(); - if ( rUndoManager.IsInListAction() ) - throw UndoContextNotClosedException( OUString(), getXUndoManager() ); + SfxUndoManager& rUndoManager = getUndoManager(); + if ( rUndoManager.IsInListAction() ) + throw UndoContextNotClosedException( OUString(), getXUndoManager() ); - { - ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning ); - rUndoManager.Clear(); - } + { + ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning ); + rUndoManager.Clear(); + } - const EventObject aEvent( getXUndoManager() ); - aGuard.clear(); - // <--- SYNCHRONIZED + aEvent = EventObject( getXUndoManager() ); + } - m_aUndoListeners.notifyEach( &XUndoManagerListener::allActionsCleared, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::allActionsCleared, aEvent ); + } impl_notifyModified(); } @@ -715,7 +742,10 @@ namespace framework aGuard.clear(); // <--- SYNCHRONIZED - m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::redoActionsCleared, aEvent ); + } impl_notifyModified(); } @@ -734,7 +764,10 @@ namespace framework aGuard.clear(); // <--- SYNCHRONIZED - m_aUndoListeners.notifyEach( &XUndoManagerListener::resetAll, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::resetAll, aEvent ); + } impl_notifyModified(); } @@ -744,7 +777,10 @@ namespace framework aEvent.Source = getXUndoManager(); aEvent.UndoActionTitle = i_actionComment; aEvent.UndoContextDepth = 0; // Undo can happen on level 0 only - m_aUndoListeners.notifyEach( &XUndoManagerListener::actionUndone, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::actionUndone, aEvent ); + } impl_notifyModified(); } @@ -754,7 +790,10 @@ namespace framework aEvent.Source = getXUndoManager(); aEvent.UndoActionTitle = i_actionComment; aEvent.UndoContextDepth = 0; // Redo can happen on level 0 only - m_aUndoListeners.notifyEach( &XUndoManagerListener::actionRedone, aEvent ); + { + std::unique_lock g(m_aListenerMutex); + m_aUndoListeners.notifyEach( g, &XUndoManagerListener::actionRedone, aEvent ); + } impl_notifyModified(); } |