diff options
Diffstat (limited to '')
-rw-r--r-- | sfx2/source/notebookbar/NotebookbarTabControl.cxx | 385 | ||||
-rw-r--r-- | sfx2/source/notebookbar/SfxNotebookBar.cxx | 584 |
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: */ |