summaryrefslogtreecommitdiffstats
path: root/sfx2/source/notebookbar
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 /sfx2/source/notebookbar
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.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 '')
-rw-r--r--sfx2/source/notebookbar/NotebookbarTabControl.cxx385
-rw-r--r--sfx2/source/notebookbar/SfxNotebookBar.cxx584
2 files changed, 969 insertions, 0 deletions
diff --git a/sfx2/source/notebookbar/NotebookbarTabControl.cxx b/sfx2/source/notebookbar/NotebookbarTabControl.cxx
new file mode 100644
index 000000000..78929e5b1
--- /dev/null
+++ b/sfx2/source/notebookbar/NotebookbarTabControl.cxx
@@ -0,0 +1,385 @@
+/* -*- 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 <vcl/builderfactory.hxx>
+#include <vcl/layout.hxx>
+#include <vcl/notebookbar/notebookbar.hxx>
+#include <vcl/tabpage.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <notebookbar/NotebookbarTabControl.hxx>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/awt/PopupMenuDirection.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <sidebar/SidebarToolBox.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#define ICON_SIZE 25
+constexpr OUStringLiteral TOOLBAR_STR = u"private:resource/toolbar/notebookbarshortcuts";
+
+using namespace css::uno;
+using namespace css::ui;
+using namespace css::frame;
+
+class ChangedUIEventListener : public ::cppu::WeakImplHelper<XUIConfigurationListener>
+{
+ VclPtr<NotebookbarTabControl> m_pParent;
+
+public:
+ explicit ChangedUIEventListener(NotebookbarTabControl *p)
+ : m_pParent(p)
+ {
+ try
+ {
+ if( SfxViewFrame::Current() )
+ {
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ const Reference<XModuleManager> xModuleManager = ModuleManager::create( xContext );
+ Reference<XFrame> xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ OUString aModuleName = xModuleManager->identify( xFrame );
+
+ Reference<XUIConfigurationManager> m_xConfigManager;
+ Reference<XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
+ theModuleUIConfigurationManagerSupplier::get( xContext ) );
+ m_xConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleName ) );
+ css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY_THROW );
+ xConfig->addConfigurationListener( this );
+ }
+ }
+ catch( const css::uno::RuntimeException& ) {}
+ }
+
+ // XUIConfigurationListener
+ virtual void SAL_CALL elementInserted( const ConfigurationEvent& rEvent ) override
+ {
+ if( rEvent.ResourceURL == TOOLBAR_STR )
+ {
+ m_pParent->m_bInvalidate = true;
+ m_pParent->StateChanged(StateChangedType::UpdateMode);
+ }
+ }
+
+ virtual void SAL_CALL elementRemoved( const ConfigurationEvent& rEvent ) override
+ {
+ elementInserted( rEvent );
+ }
+
+ virtual void SAL_CALL elementReplaced( const ConfigurationEvent& rEvent ) override
+ {
+ elementInserted( rEvent );
+ }
+
+ virtual void SAL_CALL disposing(const ::css::lang::EventObject&) override
+ {
+ try
+ {
+ if( SfxViewFrame::Current() )
+ {
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ const Reference<XModuleManager> xModuleManager = ModuleManager::create( xContext );
+ Reference<XFrame> xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ OUString aModuleName = xModuleManager->identify( xFrame );
+
+ Reference<XUIConfigurationManager> m_xConfigManager;
+ Reference<XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
+ theModuleUIConfigurationManagerSupplier::get( xContext ) );
+ m_xConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleName ) );
+ css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY_THROW );
+ xConfig->removeConfigurationListener( this );
+ }
+ }
+ catch( const css::uno::RuntimeException& ) {}
+
+ m_pParent.clear();
+ }
+};
+
+namespace {
+
+class ShortcutsToolBox : public sfx2::sidebar::SidebarToolBox
+{
+public:
+ ShortcutsToolBox( Window* pParent )
+ : sfx2::sidebar::SidebarToolBox( pParent )
+ {
+ mbUseDefaultButtonSize = false;
+ mbSideBar = false;
+ SetToolboxButtonSize(ToolBoxButtonSize::Small);
+ }
+
+ virtual void KeyInput( const KeyEvent& rKEvt ) override
+ {
+ if ( rKEvt.GetKeyCode().IsMod1() )
+ {
+ sal_uInt16 nCode( rKEvt.GetKeyCode().GetCode() );
+ if ( nCode == KEY_RIGHT || nCode == KEY_LEFT )
+ {
+ GetParent()->KeyInput( rKEvt );
+ return;
+ }
+ }
+ return sfx2::sidebar::SidebarToolBox::KeyInput( rKEvt );
+ }
+};
+
+}
+
+NotebookbarTabControl::NotebookbarTabControl( Window* pParent )
+: NotebookbarTabControlBase( pParent )
+, m_bInitialized( false )
+, m_bInvalidate( true )
+{
+}
+
+NotebookbarTabControl::~NotebookbarTabControl()
+{
+}
+
+void NotebookbarTabControl::ArrowStops( sal_uInt16 nCode )
+{
+ ToolBox* pToolBox( GetToolBox() );
+ Control* pOpenMenu( GetOpenMenu() );
+
+ if ( nCode == KEY_LEFT )
+ {
+ if ( HasFocus() )
+ {
+ if ( pToolBox )
+ pToolBox->GrabFocus();
+ else if ( pOpenMenu )
+ pOpenMenu->GrabFocus();
+ }
+ else if ( pToolBox && pToolBox->HasFocus() )
+ {
+ if ( pOpenMenu )
+ pOpenMenu->GrabFocus();
+ else
+ GrabFocus();
+ }
+ else if ( pOpenMenu && pOpenMenu->HasFocus() )
+ {
+ GrabFocus();
+ }
+ }
+ else if ( nCode == KEY_RIGHT )
+ {
+ if ( HasFocus() )
+ {
+ if ( pOpenMenu )
+ pOpenMenu->GrabFocus();
+ else if ( pToolBox )
+ pToolBox->GrabFocus();
+ }
+ else if ( pToolBox && pToolBox->HasFocus() )
+ {
+ GrabFocus();
+ }
+ else if ( pOpenMenu && pOpenMenu->HasFocus() )
+ {
+ if ( pToolBox )
+ pToolBox->GrabFocus();
+ else
+ GrabFocus();
+ }
+ }
+}
+
+void NotebookbarTabControl::KeyInput( const KeyEvent& rKEvt )
+{
+ if ( rKEvt.GetKeyCode().IsMod1() )
+ {
+ sal_uInt16 nCode( rKEvt.GetKeyCode().GetCode() );
+ if ( nCode == KEY_RIGHT || nCode == KEY_LEFT )
+ {
+ ArrowStops( nCode );
+ return;
+ }
+ }
+ return NotebookbarTabControlBase::KeyInput( rKEvt );
+}
+
+bool NotebookbarTabControl::EventNotify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
+ {
+ const vcl::KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
+ sal_uInt16 nCode = rKey.GetCode();
+ if ( rKey.IsMod1() && ( nCode == KEY_RIGHT || nCode == KEY_LEFT ) )
+ {
+ ArrowStops( nCode );
+ return true;
+ }
+ }
+ return NotebookbarTabControlBase::EventNotify( rNEvt );
+}
+
+void NotebookbarTabControl::StateChanged(StateChangedType nStateChange)
+{
+ if( !m_bInitialized && SfxViewFrame::Current() )
+ {
+ VclPtr<ShortcutsToolBox> pShortcuts = VclPtr<ShortcutsToolBox>::Create( this );
+ pShortcuts->Show();
+
+ SetToolBox( static_cast<ToolBox*>( pShortcuts.get() ) );
+ SetIconClickHdl( LINK( this, NotebookbarTabControl, OpenNotebookbarPopupMenu ) );
+
+ m_pListener = new ChangedUIEventListener( this );
+
+ m_bInitialized = true;
+ }
+ if( m_bInitialized && m_bInvalidate && SfxViewFrame::Current() )
+ {
+ ToolBox* pToolBox = GetToolBox();
+ if( !pToolBox )
+ return;
+
+ pToolBox->Clear();
+
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ const Reference<XModuleManager> xModuleManager = ModuleManager::create( xContext );
+ m_xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ OUString aModuleName = xModuleManager->identify( m_xFrame );
+
+ FillShortcutsToolBox( xContext, m_xFrame, aModuleName, pToolBox );
+
+ Size aSize( pToolBox->GetOptimalSize() );
+ Point aPos( ICON_SIZE + 10, 0 );
+ pToolBox->SetPosSizePixel( aPos, aSize );
+ ImplPlaceTabs( GetSizePixel().getWidth() );
+
+ m_bInvalidate = false;
+ }
+ NotebookbarTabControlBase::StateChanged( nStateChange );
+}
+
+void NotebookbarTabControl::FillShortcutsToolBox(Reference<XComponentContext> const & xContext,
+ const Reference<XFrame>& xFrame,
+ const OUString& aModuleName,
+ ToolBox* pShortcuts
+)
+{
+ Reference<::com::sun::star::container::XIndexAccess> xIndex;
+
+ try
+ {
+ Reference<XUIConfigurationManager> m_xConfigManager;
+ Reference<XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
+ theModuleUIConfigurationManagerSupplier::get( xContext ) );
+ m_xConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleName ) );
+ xIndex = m_xConfigManager->getSettings( TOOLBAR_STR, false );
+ }
+ catch( const Exception& ) {}
+
+ if ( !xIndex.is() )
+ return;
+
+ Sequence< css::beans::PropertyValue > aPropSequence;
+ for ( sal_Int32 i = 0; i < xIndex->getCount(); ++i )
+ {
+ try
+ {
+ if ( xIndex->getByIndex( i ) >>= aPropSequence )
+ {
+ OUString aCommandURL;
+ sal_uInt16 nType = ItemType::DEFAULT;
+ bool bVisible = true;
+
+ for ( const auto& aProp: std::as_const(aPropSequence) )
+ {
+ if ( aProp.Name == "CommandURL" )
+ aProp.Value >>= aCommandURL;
+ else if ( aProp.Name == "Type" )
+ aProp.Value >>= nType;
+ else if ( aProp.Name == "IsVisible" )
+ aProp.Value >>= bVisible;
+ }
+ if ( bVisible && ( nType == ItemType::DEFAULT ) )
+ pShortcuts->InsertItem( aCommandURL, xFrame, ToolBoxItemBits::ICON_ONLY, Size( ICON_SIZE, ICON_SIZE ) );
+ }
+ }
+ catch ( const Exception& )
+ {
+ break;
+ }
+ }
+}
+
+IMPL_LINK(NotebookbarTabControl, OpenNotebookbarPopupMenu, NotebookBar*, pNotebookbar, void)
+{
+ if (!pNotebookbar || !m_xFrame.is())
+ return;
+
+ Sequence<Any> aArgs {
+ Any(comphelper::makePropertyValue("Value", OUString("notebookbar"))),
+ Any(comphelper::makePropertyValue("Frame", m_xFrame)) };
+
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ Reference<XPopupMenuController> xPopupController(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), UNO_QUERY);
+
+ Reference<css::awt::XPopupMenu> xPopupMenu(xContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.awt.PopupMenu", xContext), UNO_QUERY);
+
+ if (!xPopupController.is() || !xPopupMenu.is())
+ return;
+
+ xPopupController->setPopupMenu(xPopupMenu);
+ Point aPos(pNotebookbar->GetSizePixel().getWidth(), NotebookbarTabControl::GetHeaderHeight() - ICON_SIZE + 10);
+ xPopupMenu->execute(pNotebookbar->GetComponentInterface(),
+ css::awt::Rectangle(aPos.X(), aPos.Y(), 1, 1),
+ css::awt::PopupMenuDirection::EXECUTE_DOWN);
+
+ Reference<css::lang::XComponent> xComponent(xPopupController, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+}
+
+Size NotebookbarTabControl::calculateRequisition() const
+{
+ Size aSize = NotebookbarTabControlBase::calculateRequisition();
+
+ for (int i = 0; i < GetPageCount(); i++)
+ {
+ vcl::Window* pChild = GetTabPage(TabControl::GetPageId(i));
+
+ if (pChild)
+ {
+ Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
+
+ if (aChildSize.getWidth() < aSize.getWidth())
+ aSize.setWidth( aChildSize.Width() );
+ }
+ }
+
+ if (aSize.Width() < 400)
+ aSize.setWidth( 400 );
+
+ return aSize;
+}
+
+VCL_BUILDER_FACTORY( NotebookbarTabControl )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/notebookbar/SfxNotebookBar.cxx b/sfx2/source/notebookbar/SfxNotebookBar.cxx
new file mode 100644
index 000000000..aa602ba17
--- /dev/null
+++ b/sfx2/source/notebookbar/SfxNotebookBar.cxx
@@ -0,0 +1,584 @@
+/* -*- 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/.
+ */
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <vcl/notebookbar/notebookbar.hxx>
+#include <vcl/syswin.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/lok.hxx>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <officecfg/Office/UI/ToolbarMode.hxx>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <unotools/confignode.hxx>
+#include <comphelper/types.hxx>
+#include <framework/addonsoptions.hxx>
+#include <vcl/notebookbar/NotebookBarAddonsMerger.hxx>
+#include <vector>
+#include <map>
+#include <vcl/WeldedTabbedNotebookbar.hxx>
+
+using namespace sfx2;
+using namespace css::uno;
+using namespace css::ui;
+using namespace css;
+
+constexpr OUStringLiteral MENUBAR_STR = u"private:resource/menubar/menubar";
+
+const char MERGE_NOTEBOOKBAR_URL[] = "URL";
+
+bool SfxNotebookBar::m_bLock = false;
+bool SfxNotebookBar::m_bHide = false;
+std::map<const SfxViewShell*, std::shared_ptr<WeldedTabbedNotebookbar>> SfxNotebookBar::m_pNotebookBarWeldedWrapper;
+
+static void NotebookbarAddonValues(
+ std::vector<Image>& aImageValues,
+ std::vector<css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>>>&
+ aExtensionValues)
+{
+ framework::AddonsOptions aAddonsItems;
+
+ for (int nIdx = 0; nIdx < aAddonsItems.GetAddonsNotebookBarCount(); nIdx++)
+ {
+ const css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>> aExtension
+ = aAddonsItems.GetAddonsNotebookBarPart(nIdx);
+ for (const css::uno::Sequence<css::beans::PropertyValue>& rExtensionVal : aExtension)
+ {
+ Image aImage;
+ bool isBigImage = true;
+ for (const auto& rProp : rExtensionVal)
+ {
+ if (rProp.Name == MERGE_NOTEBOOKBAR_URL)
+ {
+ OUString sImage;
+ rProp.Value >>= sImage;
+ aImage = Image(aAddonsItems.GetImageFromURL(sImage, isBigImage));
+ }
+ }
+ aImageValues.push_back(aImage);
+ }
+ aExtensionValues.push_back(aExtension);
+ }
+}
+
+static Reference<frame::XLayoutManager> lcl_getLayoutManager( const Reference<frame::XFrame>& xFrame )
+{
+ css::uno::Reference<css::frame::XLayoutManager> xLayoutManager;
+
+ if (xFrame.is())
+ {
+ Reference<css::beans::XPropertySet> xPropSet(xFrame, UNO_QUERY);
+
+ if (xPropSet.is())
+ {
+ Any aValue = xPropSet->getPropertyValue("LayoutManager");
+ aValue >>= xLayoutManager;
+ }
+ }
+
+ return xLayoutManager;
+}
+
+static OUString lcl_getAppName( vcl::EnumContext::Application eApp )
+{
+ switch ( eApp )
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "Writer";
+ case vcl::EnumContext::Application::Calc:
+ return "Calc";
+ case vcl::EnumContext::Application::Impress:
+ return "Impress";
+ case vcl::EnumContext::Application::Draw:
+ return "Draw";
+ case vcl::EnumContext::Application::Formula:
+ return "Formula";
+ default:
+ return OUString();
+ }
+}
+
+static void lcl_setNotebookbarFileName( vcl::EnumContext::Application eApp, const OUString& sFileName )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> aBatch(
+ comphelper::ConfigurationChanges::create() );
+ switch ( eApp )
+ {
+ case vcl::EnumContext::Application::Writer:
+ officecfg::Office::UI::ToolbarMode::ActiveWriter::set( sFileName, aBatch );
+ break;
+ case vcl::EnumContext::Application::Calc:
+ officecfg::Office::UI::ToolbarMode::ActiveCalc::set( sFileName, aBatch );
+ break;
+ case vcl::EnumContext::Application::Impress:
+ officecfg::Office::UI::ToolbarMode::ActiveImpress::set( sFileName, aBatch );
+ break;
+ case vcl::EnumContext::Application::Draw:
+ officecfg::Office::UI::ToolbarMode::ActiveDraw::set( sFileName, aBatch );
+ break;
+ default:
+ break;
+ }
+ aBatch->commit();
+}
+
+static OUString lcl_getNotebookbarFileName( vcl::EnumContext::Application eApp )
+{
+ switch ( eApp )
+ {
+ case vcl::EnumContext::Application::Writer:
+ return officecfg::Office::UI::ToolbarMode::ActiveWriter::get();
+ case vcl::EnumContext::Application::Calc:
+ return officecfg::Office::UI::ToolbarMode::ActiveCalc::get();
+ case vcl::EnumContext::Application::Impress:
+ return officecfg::Office::UI::ToolbarMode::ActiveImpress::get();
+ case vcl::EnumContext::Application::Draw:
+ return officecfg::Office::UI::ToolbarMode::ActiveDraw::get();
+
+ default:
+ break;
+ }
+ return OUString();
+}
+
+static utl::OConfigurationTreeRoot lcl_getCurrentImplConfigRoot()
+{
+ return utl::OConfigurationTreeRoot(::comphelper::getProcessComponentContext(),
+ "org.openoffice.Office.UI.ToolbarMode/",
+ true);
+}
+
+static utl::OConfigurationNode lcl_getCurrentImplConfigNode(const Reference<css::frame::XFrame>& xFrame,
+ utl::OConfigurationTreeRoot const & rNotebookbarNode )
+{
+ if (!rNotebookbarNode.isValid())
+ return utl::OConfigurationNode();
+
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
+
+ vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
+ OUString aActive = lcl_getNotebookbarFileName( eApp );
+
+ const utl::OConfigurationNode aImplsNode = rNotebookbarNode.openNode("Applications/" + lcl_getAppName( eApp) + "/Modes");
+ const Sequence<OUString> aModeNodeNames( aImplsNode.getNodeNames() );
+
+ for ( const auto& rModeNodeName : aModeNodeNames )
+ {
+ const utl::OConfigurationNode aImplNode( aImplsNode.openNode( rModeNodeName ) );
+ if ( !aImplNode.isValid() )
+ continue;
+
+ OUString aCommandArg = comphelper::getString( aImplNode.getNodeValue( "CommandArg" ) );
+
+ if ( aCommandArg == aActive )
+ {
+ return aImplNode;
+ }
+ }
+
+ return utl::OConfigurationNode();
+}
+
+void SfxNotebookBar::CloseMethod(SfxBindings& rBindings)
+{
+ SfxFrame& rFrame = rBindings.GetDispatcher_Impl()->GetFrame()->GetFrame();
+ CloseMethod(rFrame.GetSystemWindow());
+}
+
+void SfxNotebookBar::CloseMethod(SystemWindow* pSysWindow)
+{
+ if (pSysWindow)
+ {
+ RemoveListeners(pSysWindow);
+ if(pSysWindow->GetNotebookBar())
+ pSysWindow->CloseNotebookBar();
+ if (SfxViewFrame::Current())
+ SfxNotebookBar::ShowMenubar(SfxViewFrame::Current(), true);
+ }
+}
+
+void SfxNotebookBar::LockNotebookBar()
+{
+ m_bHide = true;
+ m_bLock = true;
+}
+
+void SfxNotebookBar::UnlockNotebookBar()
+{
+ m_bHide = false;
+ m_bLock = false;
+}
+
+bool SfxNotebookBar::IsActive()
+{
+ if (m_bHide)
+ return false;
+
+ vcl::EnumContext::Application eApp = vcl::EnumContext::Application::Any;
+
+ if (SfxViewFrame::Current())
+ {
+ const Reference<frame::XFrame>& xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ if (!xFrame.is())
+ return false;
+
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
+ try
+ {
+ eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+ }
+ catch (css::frame::UnknownModuleException& e)
+ {
+ SAL_WARN("sfx.appl", "SfxNotebookBar::IsActive(): " + e.Message);
+ return false;
+ }
+ }
+ else
+ return false;
+
+ OUString appName(lcl_getAppName( eApp ));
+
+ if (appName.isEmpty())
+ return false;
+
+
+ OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" + appName;
+
+ const utl::OConfigurationTreeRoot aAppNode(
+ ::comphelper::getProcessComponentContext(),
+ aPath,
+ false);
+ if ( !aAppNode.isValid() )
+ return false;
+
+ OUString aActive = comphelper::getString( aAppNode.getNodeValue( "Active" ) );
+
+ if (comphelper::LibreOfficeKit::isActive() && aActive == "notebookbar_online.ui")
+ return true;
+
+ const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
+ const Sequence<OUString> aModeNodeNames( aModesNode.getNodeNames() );
+
+ for ( const auto& rModeNodeName : aModeNodeNames )
+ {
+ const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
+ if ( !aModeNode.isValid() )
+ continue;
+
+ OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
+
+ if ( aCommandArg == aActive )
+ {
+ return comphelper::getBOOL( aModeNode.getNodeValue( "HasNotebookbar" ) );
+ }
+ }
+ return false;
+}
+
+void SfxNotebookBar::ResetActiveToolbarModeToDefault(vcl::EnumContext::Application eApp)
+{
+ const OUString appName( lcl_getAppName( eApp ) );
+
+ if ( appName.isEmpty() )
+ return;
+
+ const OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" + appName;
+
+ utl::OConfigurationTreeRoot aAppNode(
+ ::comphelper::getProcessComponentContext(),
+ aPath,
+ true);
+ if ( !aAppNode.isValid() )
+ return;
+
+ aAppNode.setNodeValue( "Active", Any( OUString( "Default" ) ) );
+ aAppNode.commit();
+}
+
+void SfxNotebookBar::ExecMethod(SfxBindings& rBindings, const OUString& rUIName)
+{
+ // Save active UI file name
+ if ( !rUIName.isEmpty() && SfxViewFrame::Current() )
+ {
+ const Reference<frame::XFrame>& xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ if (xFrame.is())
+ {
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
+ vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+ lcl_setNotebookbarFileName( eApp, rUIName );
+ }
+ }
+
+ // trigger the StateMethod
+ rBindings.Invalidate(SID_NOTEBOOKBAR);
+ rBindings.Update();
+}
+
+bool SfxNotebookBar::StateMethod(SfxBindings& rBindings, std::u16string_view rUIFile,
+ bool bReloadNotebookbar)
+{
+ SfxFrame& rFrame = rBindings.GetDispatcher_Impl()->GetFrame()->GetFrame();
+ return StateMethod(rFrame.GetSystemWindow(), rFrame.GetFrameInterface(), rUIFile,
+ bReloadNotebookbar);
+}
+
+bool SfxNotebookBar::StateMethod(SystemWindow* pSysWindow,
+ const Reference<css::frame::XFrame>& xFrame,
+ std::u16string_view rUIFile, bool bReloadNotebookbar)
+{
+ if (!pSysWindow)
+ {
+ if (SfxViewFrame::Current() && SfxViewFrame::Current()->GetWindow().GetSystemWindow())
+ pSysWindow = SfxViewFrame::Current()->GetWindow().GetSystemWindow();
+ else
+ return false;
+ }
+
+ if (IsActive())
+ {
+ css::uno::Reference<css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
+ OUString aModuleName = xModuleManager->identify( xFrame );
+ vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( aModuleName );
+
+ OUString sFile;
+ if (comphelper::LibreOfficeKit::isActive())
+ sFile = "notebookbar_online.ui";
+ else
+ sFile = lcl_getNotebookbarFileName( eApp );
+
+ OUString sNewFile = rUIFile + sFile;
+ OUString sCurrentFile;
+ VclPtr<NotebookBar> pNotebookBar = pSysWindow->GetNotebookBar();
+ if ( pNotebookBar )
+ sCurrentFile = pNotebookBar->GetUIFilePath();
+
+ bool bChangedFile = sNewFile != sCurrentFile;
+
+ if ((!sFile.isEmpty() && bChangedFile) || !pNotebookBar || !pNotebookBar->IsVisible()
+ || bReloadNotebookbar || comphelper::LibreOfficeKit::isActive())
+ {
+ const SfxViewShell* pViewShell = SfxViewShell::Current();
+
+ // Notebookbar was loaded too early what caused:
+ // * in LOK: Paste Special feature was incorrectly initialized
+ // Skip first request so Notebookbar will be initialized after document was loaded
+ static std::map<const void*, bool> bSkippedFirstInit;
+ if (comphelper::LibreOfficeKit::isActive() && eApp == vcl::EnumContext::Application::Writer
+ && bSkippedFirstInit.find(pViewShell) == bSkippedFirstInit.end())
+ {
+ bSkippedFirstInit[pViewShell] = true;
+ ResetActiveToolbarModeToDefault(eApp);
+ return false;
+ }
+
+ RemoveListeners(pSysWindow);
+
+ OUString aBuf = rUIFile + sFile;
+
+ //Addons For Notebookbar
+ std::vector<Image> aImageValues;
+ std::vector<css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > > aExtensionValues;
+ NotebookBarAddonsItem aNotebookBarAddonsItem;
+ NotebookbarAddonValues(aImageValues , aExtensionValues);
+ aNotebookBarAddonsItem.aAddonValues = aExtensionValues;
+ aNotebookBarAddonsItem.aImageValues = aImageValues;
+
+ // setup if necessary
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // update the current LOK language and locale for the dialog tunneling
+ comphelper::LibreOfficeKit::setLanguageTag(pViewShell->GetLOKLanguageTag());
+ comphelper::LibreOfficeKit::setLocale(pViewShell->GetLOKLocale());
+ }
+
+ pSysWindow->SetNotebookBar(aBuf, xFrame, aNotebookBarAddonsItem , bReloadNotebookbar);
+ pNotebookBar = pSysWindow->GetNotebookBar();
+ pNotebookBar->Show();
+
+
+ bool hasWeldedWrapper = m_pNotebookBarWeldedWrapper.find(pViewShell) != m_pNotebookBarWeldedWrapper.end();
+ if ((!hasWeldedWrapper || bReloadNotebookbar) && pNotebookBar->IsWelded())
+ {
+ sal_uInt64 nWindowId = reinterpret_cast<sal_uInt64>(pViewShell);
+ m_pNotebookBarWeldedWrapper.emplace(std::make_pair(pViewShell,
+ new WeldedTabbedNotebookbar(pNotebookBar->GetMainContainer(),
+ pNotebookBar->GetUIFilePath(),
+ xFrame,
+ nWindowId)));
+ pNotebookBar->SetDisposeCallback(LINK(nullptr, SfxNotebookBar, VclDisposeHdl), pViewShell);
+ }
+
+ pNotebookBar->GetParent()->Resize();
+
+ utl::OConfigurationTreeRoot aRoot(lcl_getCurrentImplConfigRoot());
+ const utl::OConfigurationNode aModeNode(lcl_getCurrentImplConfigNode(xFrame, aRoot));
+ SfxNotebookBar::ShowMenubar( comphelper::getBOOL( aModeNode.getNodeValue( "HasMenubar" ) ) );
+
+ SfxViewFrame* pView = SfxViewFrame::Current();
+
+ if(pView)
+ {
+ pNotebookBar->ControlListenerForCurrentController(true);
+ }
+ }
+
+ return true;
+ }
+ else if (auto pNotebookBar = pSysWindow->GetNotebookBar())
+ {
+ vcl::Window* pParent = pNotebookBar->GetParent();
+ RemoveListeners(pSysWindow);
+ pSysWindow->CloseNotebookBar();
+ pParent->Resize();
+ SfxNotebookBar::ShowMenubar(true);
+ }
+
+ return false;
+}
+
+void SfxNotebookBar::RemoveListeners(SystemWindow const * pSysWindow)
+{
+ if (auto pNotebookBar = pSysWindow->GetNotebookBar())
+ {
+ pNotebookBar->StopListeningAllControllers();
+ }
+}
+
+void SfxNotebookBar::ShowMenubar(bool bShow)
+{
+ if (m_bLock)
+ return;
+
+ m_bLock = true;
+
+ Reference<frame::XFrame> xFrame;
+ vcl::EnumContext::Application eCurrentApp = vcl::EnumContext::Application::NONE;
+ uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
+
+ if ( SfxViewFrame::Current() )
+ {
+ xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ eCurrentApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
+ }
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst();
+ while( pViewFrame )
+ {
+ xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ if ( xFrame.is() )
+ {
+ vcl::EnumContext::Application eApp =
+ vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
+
+ if ( eApp == eCurrentApp )
+ {
+ const Reference<frame::XLayoutManager>& xLayoutManager =
+ lcl_getLayoutManager( xFrame );
+
+ if (xLayoutManager.is())
+ {
+ if (xLayoutManager->getElement(MENUBAR_STR).is())
+ {
+ if (xLayoutManager->isElementVisible(MENUBAR_STR) && !bShow)
+ xLayoutManager->hideElement(MENUBAR_STR);
+ else if(!xLayoutManager->isElementVisible(MENUBAR_STR) && bShow)
+ xLayoutManager->showElement(MENUBAR_STR);
+ }
+ }
+ }
+ }
+
+ pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
+ }
+ m_bLock = false;
+}
+
+void SfxNotebookBar::ShowMenubar(SfxViewFrame const * pViewFrame, bool bShow)
+{
+ if (m_bLock)
+ return;
+
+ m_bLock = true;
+
+ Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ if (xFrame.is())
+ {
+ const Reference<frame::XLayoutManager>& xLayoutManager = lcl_getLayoutManager(xFrame);
+ if (xLayoutManager.is())
+ {
+ if (xLayoutManager->getElement(MENUBAR_STR).is())
+ {
+ if (xLayoutManager->isElementVisible(MENUBAR_STR) && !bShow)
+ xLayoutManager->hideElement(MENUBAR_STR);
+ else if (!xLayoutManager->isElementVisible(MENUBAR_STR) && bShow)
+ xLayoutManager->showElement(MENUBAR_STR);
+ }
+ }
+ }
+ m_bLock = false;
+}
+
+void SfxNotebookBar::ToggleMenubar()
+{
+ if (!SfxViewFrame::Current())
+ return;
+
+ const Reference<frame::XFrame>& xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ if (!xFrame.is())
+ return;
+
+ const Reference<frame::XLayoutManager>& xLayoutManager =
+ lcl_getLayoutManager(xFrame);
+
+ bool bShow = true;
+ if (xLayoutManager.is() && xLayoutManager->getElement(MENUBAR_STR).is())
+ {
+ if (xLayoutManager->isElementVisible(MENUBAR_STR))
+ {
+ SfxNotebookBar::ShowMenubar(false);
+ bShow = false;
+ }
+ else
+ SfxNotebookBar::ShowMenubar(true);
+ }
+
+ // Save menubar settings
+ if (IsActive())
+ {
+ utl::OConfigurationTreeRoot aRoot(lcl_getCurrentImplConfigRoot());
+ utl::OConfigurationNode aModeNode(lcl_getCurrentImplConfigNode(xFrame, aRoot));
+ aModeNode.setNodeValue( "HasMenubar", toAny<bool>( bShow ) );
+ aRoot.commit();
+ }
+}
+
+void SfxNotebookBar::ReloadNotebookBar(std::u16string_view sUIPath)
+{
+ if (SfxNotebookBar::IsActive())
+ {
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ sfx2::SfxNotebookBar::StateMethod(pViewShell->GetViewFrame()->GetBindings(), sUIPath, true);
+ }
+}
+
+IMPL_STATIC_LINK(SfxNotebookBar, VclDisposeHdl, const SfxViewShell*, pViewShell, void)
+{
+ m_pNotebookBarWeldedWrapper.erase(pViewShell);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */