summaryrefslogtreecommitdiffstats
path: root/framework/source/fwe/helper/titlehelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--framework/source/fwe/helper/titlehelper.cxx705
1 files changed, 705 insertions, 0 deletions
diff --git a/framework/source/fwe/helper/titlehelper.cxx b/framework/source/fwe/helper/titlehelper.cxx
new file mode 100644
index 000000000..fba89ae42
--- /dev/null
+++ b/framework/source/fwe/helper/titlehelper.cxx
@@ -0,0 +1,705 @@
+/* -*- 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 <config_features.h>
+
+#include <framework/titlehelper.hxx>
+#include <classes/fwkresid.hxx>
+#include <strings.hrc>
+#include <properties.h>
+
+#include <com/sun/star/frame/UntitledNumbersConst.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/XUntitledNumbers.hpp>
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
+
+#include <unotools/configmgr.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/mutex.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/opengl/OpenGLWrapper.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
+#include <vcl/svapp.hxx>
+
+
+using namespace css;
+using namespace css::uno;
+using namespace css::frame;
+
+namespace framework{
+
+TitleHelper::TitleHelper(const css::uno::Reference< css::uno::XComponentContext >& rxContext)
+ : ::cppu::BaseMutex ()
+ , m_xContext (rxContext)
+ , m_xOwner ()
+ , m_xUntitledNumbers()
+ , m_xSubTitle ()
+ , m_bExternalTitle (false)
+ , m_sTitle ()
+ , m_nLeasedNumber (css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ , m_aListener (m_aMutex)
+{
+}
+
+TitleHelper::~TitleHelper()
+{
+}
+
+void TitleHelper::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner)
+{
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ m_xOwner = xOwner;
+ }
+ // <- SYNCHRONIZED
+
+ css::uno::Reference< css::frame::XModel > xModel(xOwner, css::uno::UNO_QUERY);
+ if (xModel.is ())
+ {
+ impl_startListeningForModel (xModel);
+ return;
+ }
+
+ css::uno::Reference< css::frame::XController > xController(xOwner, css::uno::UNO_QUERY);
+ if (xController.is ())
+ {
+ impl_startListeningForController (xController);
+ return;
+ }
+
+ css::uno::Reference< css::frame::XFrame > xFrame(xOwner, css::uno::UNO_QUERY);
+ if (xFrame.is ())
+ {
+ impl_startListeningForFrame (xFrame);
+ return;
+ }
+}
+
+OUString SAL_CALL TitleHelper::getTitle()
+{
+ // SYNCHRONIZED ->
+ osl::MutexGuard aLock(m_aMutex);
+
+ // An external title will win always and disable all internal logic about
+ // creating/using a title value.
+ // Even an empty string will be accepted as valid title !
+ if (m_bExternalTitle)
+ return m_sTitle;
+
+ // Title seems to be up-to-date. Return it directly.
+ if (!m_sTitle.isEmpty())
+ return m_sTitle;
+
+ // Title seems to be unused till now ... do bootstraping
+ impl_updateTitle (true);
+
+ return m_sTitle;
+ // <- SYNCHRONIZED
+}
+
+void TitleHelper::connectWithUntitledNumbers (const css::uno::Reference< css::frame::XUntitledNumbers >& xNumbers)
+{
+ // SYNCHRONIZED ->
+ osl::MutexGuard aLock(m_aMutex);
+
+ m_xUntitledNumbers = xNumbers;
+ // <- SYNCHRONIZED
+}
+
+void SAL_CALL TitleHelper::setTitle(const OUString& sTitle)
+{
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ m_bExternalTitle = true;
+ m_sTitle = sTitle;
+ }
+ // <- SYNCHRONIZED
+
+ impl_sendTitleChangedEvent ();
+}
+
+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 );
+}
+
+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 );
+}
+
+void SAL_CALL TitleHelper::titleChanged(const css::frame::TitleChangedEvent& aEvent)
+{
+ css::uno::Reference< css::frame::XTitle > xSubTitle;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ xSubTitle.set(m_xSubTitle.get (), css::uno::UNO_QUERY);
+ }
+ // <- SYNCHRONIZED
+
+ if (aEvent.Source != xSubTitle)
+ return;
+
+ impl_updateTitle ();
+}
+
+void SAL_CALL TitleHelper::documentEventOccured(const css::document::DocumentEvent& aEvent)
+{
+ if ( ! aEvent.EventName.equalsIgnoreAsciiCase("OnSaveAsDone")
+ && ! aEvent.EventName.equalsIgnoreAsciiCase("OnModeChanged")
+ && ! aEvent.EventName.equalsIgnoreAsciiCase("OnTitleChanged"))
+ return;
+
+ css::uno::Reference< css::frame::XModel > xOwner;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ xOwner.set(m_xOwner.get (), css::uno::UNO_QUERY);
+ }
+ // <- SYNCHRONIZED
+
+ if (aEvent.Source != xOwner
+ || ((aEvent.EventName.equalsIgnoreAsciiCase("OnModeChanged")
+ || aEvent.EventName.equalsIgnoreAsciiCase("OnTitleChanged"))
+ && !xOwner.is()))
+ {
+ return;
+ }
+
+ impl_updateTitle ();
+}
+
+void SAL_CALL TitleHelper::frameAction(const css::frame::FrameActionEvent& aEvent)
+{
+ css::uno::Reference< css::frame::XFrame > xOwner;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ xOwner.set(m_xOwner.get (), css::uno::UNO_QUERY);
+ }
+ // <- SYNCHRONIZED
+
+ if (aEvent.Source != xOwner)
+ return;
+
+ // 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_updateListeningForFrame (xOwner);
+ impl_updateTitle ();
+ }
+}
+
+void SAL_CALL TitleHelper::disposing(const css::lang::EventObject& aEvent)
+{
+ css::uno::Reference< css::uno::XInterface > xOwner;
+ css::uno::Reference< css::frame::XUntitledNumbers > xNumbers;
+ ::sal_Int32 nLeasedNumber;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ xOwner = m_xOwner;
+ xNumbers.set(m_xUntitledNumbers.get(), css::uno::UNO_QUERY);
+ nLeasedNumber = m_nLeasedNumber;
+ }
+ // <- SYNCHRONIZED
+
+ if ( ! xOwner.is ())
+ return;
+
+ if (xOwner != aEvent.Source)
+ return;
+
+ if (
+ (xNumbers.is () ) &&
+ (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ )
+ xNumbers->releaseNumber (nLeasedNumber);
+
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ m_xOwner = nullptr;
+ m_sTitle = OUString ();
+ m_nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER;
+ }
+ // <- SYNCHRONIZED
+}
+
+void TitleHelper::impl_sendTitleChangedEvent ()
+{
+ css::uno::Reference<css::uno::XInterface> xOwner;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ xOwner = m_xOwner;
+ }
+ // <- SYNCHRONIZED
+
+ css::frame::TitleChangedEvent aEvent(xOwner, m_sTitle);
+
+ if( ! aEvent.Source.is() )
+ return;
+
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListener.getContainer( cppu::UnoType<css::frame::XTitleChangeListener>::get());
+ if ( ! pContainer)
+ return;
+
+ ::cppu::OInterfaceIteratorHelper pIt( *pContainer );
+ while ( pIt.hasMoreElements() )
+ {
+ try
+ {
+ static_cast<css::frame::XTitleChangeListener*>(pIt.next())->titleChanged( aEvent );
+ }
+ catch(const css::uno::Exception&)
+ {
+ pIt.remove();
+ }
+ }
+}
+
+void TitleHelper::impl_updateTitle (bool init)
+{
+ css::uno::Reference< css::frame::XModel > xModel;
+ css::uno::Reference< css::frame::XController > xController;
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard 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);
+ }
+ // <- SYNCHRONIZED
+
+ if (xModel.is ())
+ {
+ impl_updateTitleForModel (xModel, init);
+ }
+ else if (xController.is ())
+ {
+ impl_updateTitleForController (xController, init);
+ }
+ else if (xFrame.is ())
+ {
+ impl_updateTitleForFrame (xFrame, init);
+ }
+}
+
+void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::frame::XModel >& xModel, bool init)
+{
+ css::uno::Reference< css::uno::XInterface > xOwner;
+ css::uno::Reference< css::frame::XUntitledNumbers > xNumbers;
+ ::sal_Int32 nLeasedNumber;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ // external title won't be updated internally!
+ // It has to be set from outside new.
+ if (m_bExternalTitle)
+ return;
+
+ xOwner = m_xOwner;
+ xNumbers.set (m_xUntitledNumbers.get(), css::uno::UNO_QUERY);
+ nLeasedNumber = m_nLeasedNumber;
+ }
+ // <- SYNCHRONIZED
+
+ if (
+ ( ! xOwner.is ()) ||
+ ( ! xNumbers.is ()) ||
+ ( ! xModel.is ())
+ )
+ 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->getArgs());
+ const OUString sSuggestedSaveAsName = aDescriptor.getUnpackedValueOrDefault(
+ utl::MediaDescriptor::PROP_SUGGESTEDSAVEASNAME(), OUString());
+
+ if (!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())
+ {
+ // tdf#121537 Use suggested save as name for title if file has not yet been saved
+ sTitle = sSuggestedSaveAsName;
+ }
+ else
+ {
+ 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);
+ else
+ sNewTitle.append("?");
+
+ sTitle = sNewTitle.makeStringAndClear ();
+ }
+
+ bool bChanged;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ // WORKAROUND: the notification is currently sent always,
+ // can be changed after shared mode is supported per UNO API
+ bChanged = !init; // && m_sTitle != sTitle
+
+ m_sTitle = sTitle;
+ m_nLeasedNumber = nLeasedNumber;
+ }
+ // <- SYNCHRONIZED
+
+ if (bChanged)
+ impl_sendTitleChangedEvent ();
+}
+
+void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css::frame::XController >& xController, bool init)
+{
+ css::uno::Reference< css::uno::XInterface > xOwner;
+ css::uno::Reference< css::frame::XUntitledNumbers > xNumbers;
+ ::sal_Int32 nLeasedNumber;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ // external title won't be updated internally!
+ // It has to be set from outside new.
+ if (m_bExternalTitle)
+ return;
+
+ xOwner = m_xOwner;
+ xNumbers.set (m_xUntitledNumbers.get(), css::uno::UNO_QUERY);
+ nLeasedNumber = m_nLeasedNumber;
+ }
+ // <- SYNCHRONIZED
+
+ if (
+ ( ! xOwner.is ()) ||
+ ( ! xNumbers.is ()) ||
+ ( ! xController.is ())
+ )
+ return;
+
+ OUStringBuffer sTitle(256);
+
+ if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ nLeasedNumber = xNumbers->leaseNumber (xOwner);
+
+ css::uno::Reference< css::frame::XTitle > xModelTitle(xController->getModel (), css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel ();
+ if (!xModelTitle.is ())
+ xModelTitle.set(xController, css::uno::UNO_QUERY);
+ if (xModelTitle.is ())
+ {
+ sTitle.append (xModelTitle->getTitle ());
+ if ( nLeasedNumber > 1 )
+ {
+ sTitle.append(" : ");
+ sTitle.append(nLeasedNumber);
+ }
+ if (xModel.is ())
+ {
+ INetURLObject aURL (xModel->getURL ());
+ if (aURL.GetProtocol () != INetProtocol::File
+ && aURL.GetProtocol () != INetProtocol::NotValid)
+ {
+ OUString sRemoteText (FwkResId (STR_REMOTE_TITLE));
+ sTitle.append (sRemoteText);
+ }
+ }
+ }
+ else
+ {
+ sTitle.append (xNumbers->getUntitledPrefix ());
+ if ( nLeasedNumber > 1 )
+ {
+ sTitle.append(nLeasedNumber );
+ }
+ }
+
+ bool bChanged;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ OUString sNewTitle = sTitle.makeStringAndClear ();
+ bChanged = !init && m_sTitle != sNewTitle;
+ m_sTitle = sNewTitle;
+ m_nLeasedNumber = nLeasedNumber;
+ }
+ // <- SYNCHRONIZED
+
+ if (bChanged)
+ impl_sendTitleChangedEvent ();
+}
+
+void TitleHelper::impl_updateTitleForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame, bool init)
+{
+ if ( ! xFrame.is ())
+ return;
+
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ // external title won't be updated internally!
+ // It has to be set from outside new.
+ if (m_bExternalTitle)
+ return;
+ }
+ // <- SYNCHRONIZED
+
+ css::uno::Reference< css::uno::XInterface > xComponent = xFrame->getController ();
+ if ( ! xComponent.is ())
+ xComponent = xFrame->getComponentWindow ();
+
+ OUStringBuffer sTitle (256);
+
+ 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);
+#endif
+ impl_appendSafeMode (sTitle);
+
+ bool bChanged;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ OUString sNewTitle = sTitle.makeStringAndClear ();
+ bChanged = !init && m_sTitle != sNewTitle;
+ m_sTitle = sNewTitle;
+ }
+ // <- SYNCHRONIZED
+
+ if (bChanged)
+ impl_sendTitleChangedEvent ();
+}
+
+void TitleHelper::impl_appendComponentTitle ( OUStringBuffer& sTitle ,
+ const css::uno::Reference< css::uno::XInterface >& xComponent)
+{
+ css::uno::Reference< css::frame::XTitle > xTitle(xComponent, css::uno::UNO_QUERY);
+
+ // Note: Title has to be used (even if it's empty) if the right interface is supported.
+ if (xTitle.is ())
+ sTitle.append (xTitle->getTitle ());
+}
+
+void TitleHelper::impl_appendProductName (OUStringBuffer& sTitle)
+{
+ OUString name(utl::ConfigManager::getProductName());
+ if (!name.isEmpty())
+ {
+ if (!sTitle.isEmpty())
+ sTitle.append(" - ");
+ sTitle.append(name);
+ }
+}
+
+void TitleHelper::impl_appendModuleName (OUStringBuffer& sTitle)
+{
+ css::uno::Reference< css::uno::XInterface > xOwner;
+ css::uno::Reference< css::uno::XComponentContext > xContext;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ xOwner = m_xOwner.get();
+ xContext = m_xContext;
+ }
+ // <- SYNCHRONIZED
+
+ try
+ {
+ css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
+ css::frame::ModuleManager::create(xContext);
+
+ const OUString sID = xModuleManager->identify(xOwner);
+ ::comphelper::SequenceAsHashMap lProps = xModuleManager->getByName (sID);
+ const OUString sUIName = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_ASCII_UINAME, OUString());
+
+ // An UIname property is an optional value !
+ // So please add it to the title in case it does really exists only.
+ if (!sUIName.isEmpty())
+ {
+ sTitle.append (" " );
+ sTitle.append (sUIName);
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+#ifdef DBG_UTIL
+void TitleHelper::impl_appendDebugVersion (OUStringBuffer& sTitle)
+{
+ OUString version(utl::ConfigManager::getProductVersion());
+ sTitle.append(' ');
+ sTitle.append(version);
+ OUString sVersion = ::utl::Bootstrap::getBuildIdData("development");
+ sTitle.append(" [");
+ sTitle.append(sVersion);
+#if HAVE_FEATURE_UI
+ if (OpenGLWrapper::isVCLOpenGLEnabled() && !SkiaHelper::isVCLSkiaEnabled())
+ sTitle.append("-GL");
+#endif
+ sTitle.append("]");
+}
+#else
+void TitleHelper::impl_appendDebugVersion (OUStringBuffer&)
+{
+}
+#endif
+
+void TitleHelper::impl_appendSafeMode (OUStringBuffer& sTitle)
+{
+ if (Application::IsSafeModeEnabled())
+ sTitle.append(FwkResId (STR_SAFEMODE_TITLE));
+}
+
+void TitleHelper::impl_startListeningForModel (const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ css::uno::Reference< css::document::XDocumentEventBroadcaster > xBroadcaster(xModel, css::uno::UNO_QUERY);
+ if ( ! xBroadcaster.is ())
+ return;
+
+ xBroadcaster->addDocumentEventListener (static_cast< css::document::XDocumentEventListener* >(this));
+}
+
+void TitleHelper::impl_startListeningForController (const css::uno::Reference< css::frame::XController >& xController)
+{
+ xController->addEventListener (static_cast< css::lang::XEventListener* > (static_cast< css::frame::XFrameActionListener* > (this) ) );
+ css::uno::Reference< css::frame::XTitle > xSubTitle(xController->getModel (), css::uno::UNO_QUERY);
+ impl_setSubTitle (xSubTitle);
+}
+
+void TitleHelper::impl_startListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ xFrame->addFrameActionListener(this );
+ impl_updateListeningForFrame (xFrame);
+}
+
+void TitleHelper::impl_updateListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::frame::XTitle > xSubTitle(xFrame->getController (), css::uno::UNO_QUERY);
+ impl_setSubTitle (xSubTitle);
+}
+
+void TitleHelper::impl_setSubTitle (const css::uno::Reference< css::frame::XTitle >& xSubTitle)
+{
+ css::uno::Reference< css::frame::XTitle > xOldSubTitle;
+ // SYNCHRONIZED ->
+ {
+ osl::MutexGuard aLock(m_aMutex);
+
+ // ignore duplicate calls. Makes outside using of this helper more easy :-)
+ xOldSubTitle.set(m_xSubTitle.get(), css::uno::UNO_QUERY);
+ if (xOldSubTitle == xSubTitle)
+ return;
+
+ m_xSubTitle = xSubTitle;
+ }
+ // <- SYNCHRONIZED
+
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xOldBroadcaster(xOldSubTitle , css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xNewBroadcaster(xSubTitle , css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XTitleChangeListener > xThis (static_cast< css::frame::XTitleChangeListener* >(this), css::uno::UNO_QUERY_THROW);
+
+ if (xOldBroadcaster.is())
+ xOldBroadcaster->removeTitleChangeListener (xThis);
+
+ if (xNewBroadcaster.is())
+ xNewBroadcaster->addTitleChangeListener (xThis);
+}
+
+OUString TitleHelper::impl_convertURL2Title(const OUString& sURL)
+{
+ INetURLObject aURL (sURL);
+ OUString sTitle;
+
+ if (aURL.GetProtocol() == INetProtocol::File)
+ {
+ if (aURL.HasMark())
+ aURL = INetURLObject(aURL.GetURLNoMark());
+
+ sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset);
+ }
+ else
+ {
+ if (aURL.hasExtension())
+ sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset);
+
+ if ( sTitle.isEmpty() )
+ sTitle = aURL.GetHostPort(INetURLObject::DecodeMechanism::WithCharset);
+
+ if ( sTitle.isEmpty() )
+ sTitle = aURL.GetURLNoPass(INetURLObject::DecodeMechanism::WithCharset);
+ }
+
+ return sTitle;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */