diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /sfx2/source/notebookbar | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sfx2/source/notebookbar')
-rw-r--r-- | sfx2/source/notebookbar/ContextVBox.cxx | 76 | ||||
-rw-r--r-- | sfx2/source/notebookbar/DropdownBox.cxx | 126 | ||||
-rw-r--r-- | sfx2/source/notebookbar/DropdownBox.hxx | 49 | ||||
-rw-r--r-- | sfx2/source/notebookbar/NotebookbarPopup.cxx | 159 | ||||
-rw-r--r-- | sfx2/source/notebookbar/NotebookbarPopup.hxx | 57 | ||||
-rw-r--r-- | sfx2/source/notebookbar/NotebookbarTabControl.cxx | 386 | ||||
-rw-r--r-- | sfx2/source/notebookbar/PriorityHBox.cxx | 202 | ||||
-rw-r--r-- | sfx2/source/notebookbar/PriorityHBox.hxx | 64 | ||||
-rw-r--r-- | sfx2/source/notebookbar/PriorityMergedHBox.cxx | 113 | ||||
-rw-r--r-- | sfx2/source/notebookbar/SfxNotebookBar.cxx | 550 |
10 files changed, 1782 insertions, 0 deletions
diff --git a/sfx2/source/notebookbar/ContextVBox.cxx b/sfx2/source/notebookbar/ContextVBox.cxx new file mode 100644 index 000000000..b1494340f --- /dev/null +++ b/sfx2/source/notebookbar/ContextVBox.cxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <vcl/NotebookbarContextControl.hxx> +#include <vcl/builderfactory.hxx> +#include <vcl/layout.hxx> +#include <sfx2/dllapi.h> + +/* + * ContextVBox is a VclVBox which shows own children depending on current context. + * This control can be used in the notebookbar .ui files + */ + +class SFX2_DLLPUBLIC ContextVBox : public VclVBox, + public NotebookbarContextControl +{ +public: + explicit ContextVBox( vcl::Window *pParent ) + : VclVBox( pParent ) + { + } + + virtual ~ContextVBox() override + { + disposeOnce(); + } + + void SetContext( vcl::EnumContext::Context eContext ) override + { + for (int nChild = 0; nChild < GetChildCount(); ++nChild) + { + if ( GetChild( nChild )->GetType() == WindowType::CONTAINER ) + { + VclContainer* pChild = static_cast<VclContainer*>( GetChild( nChild ) ); + + if ( pChild->HasContext( eContext ) || pChild->HasContext( vcl::EnumContext::Context::Any ) ) + { + Size aSize( pChild->GetOptimalSize() ); + aSize.AdjustHeight(6 ); + pChild->Show(); + pChild->SetSizePixel( aSize ); + } + else + { + pChild->Hide(); + pChild->SetSizePixel( Size( 0, 0 ) ); + } + } + } + Size aSize( GetOptimalSize() ); + aSize.AdjustWidth(6 ); + SetSizePixel( aSize ); + } +}; + +VCL_BUILDER_FACTORY(ContextVBox) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notebookbar/DropdownBox.cxx b/sfx2/source/notebookbar/DropdownBox.cxx new file mode 100644 index 000000000..450cae82a --- /dev/null +++ b/sfx2/source/notebookbar/DropdownBox.cxx @@ -0,0 +1,126 @@ +/* -*- 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/button.hxx> +#include <vcl/layout.hxx> +#include "DropdownBox.hxx" + +#define NOTEBOOK_HEADER_HEIGHT 30 + +/* + * DropdownBox - shows content or moves it to the popup + * which can be opened by clicking on a button + */ + +DropdownBox::DropdownBox(vcl::Window *pParent) + : VclHBox(pParent) + , IPrioritable() + , m_bInFullView(true) +{ + m_pButton = VclPtr<PushButton>::Create(this, WB_FLATBUTTON); + m_pButton->SetClickHdl(LINK(this, DropdownBox, PBClickHdl)); + m_pButton->SetSymbol(SymbolType::MENU); + m_pButton->set_width_request(15); + m_pButton->SetQuickHelpText(GetQuickHelpText()); + m_pButton->Resize(); +} + +DropdownBox::~DropdownBox() +{ + disposeOnce(); +} + +void DropdownBox::dispose() +{ + m_pButton.disposeAndClear(); + if (m_pPopup) + m_pPopup.disposeAndClear(); + + VclHBox::dispose(); +} + +void DropdownBox::HideContent() +{ + if (m_bInFullView) + { + m_bInFullView = false; + + for (int i = 0; i < GetChildCount(); i++) + GetChild(i)->Hide(); + + m_pButton->Show(); + SetOutputSizePixel(Size(m_pButton->GetSizePixel().Width(), GetSizePixel().Height())); + } +} + +bool DropdownBox::IsHidden() +{ + return !m_bInFullView; +} + +void DropdownBox::ShowContent() +{ + if (!m_bInFullView) + { + m_bInFullView = true; + + for (int i = 0; i < GetChildCount(); i++) + GetChild(i)->Show(); + + m_pButton->Hide(); + } +} + +IMPL_LINK(DropdownBox, PBClickHdl, Button*, /*pButton*/, void) +{ + if (m_pPopup) + m_pPopup.disposeAndClear(); + + m_pPopup = VclPtr<NotebookbarPopup>::Create(this); + + for (int i = 0; i < GetChildCount(); i++) + { + if (GetChild(i) != m_pButton) + { + Window* pChild = GetChild(i); + pChild->Show(); + + pChild->SetParent(m_pPopup->getBox()); + // count is decreased because we moved child + i--; + } + } + + m_pPopup->hideSeparators(true); + + m_pPopup->getBox()->set_height_request(GetSizePixel().Height()); + + long x = GetPosPixel().getX(); + long y = GetPosPixel().getY() + NOTEBOOK_HEADER_HEIGHT + GetSizePixel().Height(); + tools::Rectangle aRect(x, y, x, y); + + m_pPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down + |FloatWinPopupFlags::GrabFocus + |FloatWinPopupFlags::AllMouseButtonClose); +} + +VCL_BUILDER_FACTORY(DropdownBox) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notebookbar/DropdownBox.hxx b/sfx2/source/notebookbar/DropdownBox.hxx new file mode 100644 index 000000000..769cd2e42 --- /dev/null +++ b/sfx2/source/notebookbar/DropdownBox.hxx @@ -0,0 +1,49 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_SFX2_NOTEBOOKBAR_DROPDOWNBOX_HXX +#define INCLUDED_SFX2_NOTEBOOKBAR_DROPDOWNBOX_HXX + +#include <vcl/IPrioritable.hxx> +#include <vcl/layout.hxx> +#include "NotebookbarPopup.hxx" + +class DropdownBox : public VclHBox, public vcl::IPrioritable +{ +private: + bool m_bInFullView; + VclPtr<PushButton> m_pButton; + VclPtr<NotebookbarPopup> m_pPopup; + +public: + explicit DropdownBox(vcl::Window* pParent); + virtual ~DropdownBox() override; + virtual void dispose() override; + + void HideContent() override; + void ShowContent() override; + bool IsHidden() override; + +private: + DECL_LINK(PBClickHdl, Button*, void); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notebookbar/NotebookbarPopup.cxx b/sfx2/source/notebookbar/NotebookbarPopup.cxx new file mode 100644 index 000000000..cba325a43 --- /dev/null +++ b/sfx2/source/notebookbar/NotebookbarPopup.cxx @@ -0,0 +1,159 @@ +/* -*- 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 "NotebookbarPopup.hxx" +#include <vcl/IPrioritable.hxx> +#include <vcl/layout.hxx> + +NotebookbarPopup::NotebookbarPopup(const VclPtr<VclHBox>& pParent) + : FloatingWindow(pParent, "Popup", "sfx/ui/notebookbarpopup.ui") + , m_pParent(pParent) +{ + get(m_pBox, "box"); + m_pBox->SetSizePixel(Size(100, 75)); + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + const BitmapEx& aPersona = rStyleSettings.GetPersonaHeader(); + + if (!aPersona.IsEmpty()) + m_pBox->SetBackground(Wallpaper(aPersona)); + else + m_pBox->SetBackground(rStyleSettings.GetDialogColor()); +} + +NotebookbarPopup::~NotebookbarPopup() { disposeOnce(); } + +VclHBox* NotebookbarPopup::getBox() { return m_pBox.get(); } + +void NotebookbarPopup::PopupModeEnd() +{ + hideSeparators(false); + while (m_pBox->GetChildCount()) + { + vcl::IPrioritable* pChild = dynamic_cast<vcl::IPrioritable*>(GetChild(0)); + if (pChild) + pChild->HideContent(); + + vcl::Window* pWindow = m_pBox->GetChild(0); + pWindow->SetParent(m_pParent); + + // resize after all children of box are empty + if (m_pParent && !m_pBox->GetChildCount()) + m_pParent->Resize(); + } + + FloatingWindow::PopupModeEnd(); +} + +void NotebookbarPopup::hideSeparators(bool bHide) +{ + // separator on the beginning + vcl::Window* pWindow = m_pBox->GetChild(0); + while (pWindow && pWindow->GetType() == WindowType::CONTAINER) + { + pWindow = pWindow->GetChild(0); + } + if (pWindow && pWindow->GetType() == WindowType::FIXEDLINE) + { + if (bHide) + pWindow->Hide(); + else + pWindow->Show(); + } + + // separator on the end + pWindow = m_pBox->GetChild(m_pBox->GetChildCount() - 1); + while (pWindow && pWindow->GetType() == WindowType::CONTAINER) + { + pWindow = pWindow->GetChild(pWindow->GetChildCount() - 1); + } + if (pWindow && pWindow->GetType() == WindowType::FIXEDLINE) + { + if (bHide) + pWindow->Hide(); + else + pWindow->Show(); + } + + if (bHide) + { + sal_Int32 BoxId = 0; + while (BoxId <= m_pBox->GetChildCount() - 1) + { + if (m_pBox->GetChild(BoxId)) + { + pWindow = m_pBox->GetChild(BoxId); + ApplyBackground(pWindow); + } + BoxId++; + } + } + else + { + sal_Int32 BoxId = m_pBox->GetChildCount() - 1; + while (BoxId >= 0) + { + if (m_pBox->GetChild(BoxId)) + { + pWindow = m_pBox->GetChild(BoxId); + RemoveBackground(pWindow); + } + BoxId--; + } + } +} + +void NotebookbarPopup::dispose() +{ + PopupModeEnd(); + m_pBox.disposeAndClear(); + m_pParent.clear(); + + FloatingWindow::dispose(); +} + +void NotebookbarPopup::ApplyBackground(vcl::Window* pWindow) +{ + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + const BitmapEx& aPersona = rStyleSettings.GetPersonaHeader(); + + if (!aPersona.IsEmpty()) + pWindow->SetBackground(Wallpaper(aPersona)); + else + pWindow->SetBackground(rStyleSettings.GetDialogColor()); + + sal_Int32 nNext = 0; + VclPtr<vcl::Window> pChild = pWindow->GetChild(nNext); + while (pChild && pWindow->GetType() == WindowType::CONTAINER) + { + ApplyBackground(pChild); + nNext++; + if (pWindow->GetChild(nNext) && pWindow->GetType() == WindowType::CONTAINER) + pChild = pWindow->GetChild(nNext); + else + break; + } +} + +void NotebookbarPopup::RemoveBackground(vcl::Window* pWindow) +{ + pWindow->SetBackground(Wallpaper(COL_TRANSPARENT)); + + sal_Int32 nNext = 0; + VclPtr<vcl::Window> pChild = pWindow->GetChild(nNext); + while (pChild && pWindow->GetType() == WindowType::CONTAINER) + { + RemoveBackground(pChild); + nNext++; + if (pWindow->GetChild(nNext) && pWindow->GetType() == WindowType::CONTAINER) + pChild = pWindow->GetChild(nNext); + else + break; + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notebookbar/NotebookbarPopup.hxx b/sfx2/source/notebookbar/NotebookbarPopup.hxx new file mode 100644 index 000000000..c417a75f4 --- /dev/null +++ b/sfx2/source/notebookbar/NotebookbarPopup.hxx @@ -0,0 +1,57 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_SFX2_NOTEBOOKBAR_NOTEBOOKBARPOPUP_HXX +#define INCLUDED_SFX2_NOTEBOOKBAR_NOTEBOOKBARPOPUP_HXX + +#include <vcl/layout.hxx> +#include <vcl/floatwin.hxx> + +/* + * Popup - shows hidden content, controls are moved to this popup + * and after close moved to the original parent + */ + +class NotebookbarPopup : public FloatingWindow +{ +private: + VclPtr<VclHBox> m_pBox; + ScopedVclPtr<VclHBox> m_pParent; + +public: + explicit NotebookbarPopup(const VclPtr<VclHBox>& pParent); + + virtual ~NotebookbarPopup() override; + + VclHBox* getBox(); + + virtual void PopupModeEnd() override; + + void hideSeparators(bool bHide); + + void dispose() override; + + void ApplyBackground(vcl::Window* pWindow); + + void RemoveBackground(vcl::Window* pWindow); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notebookbar/NotebookbarTabControl.cxx b/sfx2/source/notebookbar/NotebookbarTabControl.cxx new file mode 100644 index 000000000..79f0cd7ef --- /dev/null +++ b/sfx2/source/notebookbar/NotebookbarTabControl.cxx @@ -0,0 +1,386 @@ +/* -*- 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/button.hxx> +#include <vcl/layout.hxx> +#include <vcl/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 <toolkit/awt/vclxmenu.hxx> +#include <com/sun/star/frame/XPopupMenuController.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> +#include <sfx2/sidebar/SidebarToolBox.hxx> +#include <cppuhelper/implbase.hxx> + +#define ICON_SIZE 25 +#define TOOLBAR_STR "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() ); + PushButton* 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 { + makeAny(comphelper::makePropertyValue("Value", OUString("notebookbar"))), + makeAny(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); + VCLXMenu* pAwtMenu = comphelper::getUnoTunnelImplementation<VCLXMenu>(xPopupMenu); + PopupMenu* pVCLMenu = static_cast<PopupMenu*>(pAwtMenu->GetMenu()); + Point aPos(pNotebookbar->GetSizePixel().getWidth(), NotebookbarTabControl::GetHeaderHeight() - ICON_SIZE + 10); + pVCLMenu->Execute(pNotebookbar, tools::Rectangle(aPos, aPos),PopupMenuFlags::ExecuteDown|PopupMenuFlags::NoMouseUpClose); + + 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 = VclAlignment::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/PriorityHBox.cxx b/sfx2/source/notebookbar/PriorityHBox.cxx new file mode 100644 index 000000000..763114c72 --- /dev/null +++ b/sfx2/source/notebookbar/PriorityHBox.cxx @@ -0,0 +1,202 @@ +/* -*- 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 <sfx2/viewfrm.hxx> +#include "PriorityHBox.hxx" + +namespace +{ + bool lcl_comparePriority(const vcl::IPrioritable* a, const vcl::IPrioritable* b) + { + return a->GetPriority() < b->GetPriority(); + } +} + +PriorityHBox::PriorityHBox(vcl::Window *pParent) + : VclHBox(pParent) + , m_bInitialized(false) +{ +} + +PriorityHBox::~PriorityHBox() +{ + disposeOnce(); +} + +void PriorityHBox::Initialize() +{ + m_bInitialized = true; + + GetChildrenWithPriorities(); + SetSizeFromParent(); +} + +int PriorityHBox::GetHiddenCount() const +{ + int nCount = 0; + + for (auto pWindow : m_aSortedChildren) + if (pWindow->IsHidden()) + nCount++; + + return nCount; +} + +void PriorityHBox::SetSizeFromParent() +{ + vcl::Window* pParent = GetParent(); + if (pParent) + { + Size aParentSize = pParent->GetSizePixel(); + SetSizePixel(Size(aParentSize.getWidth(), aParentSize.getHeight())); + } +} + +Size PriorityHBox::calculateRequisition() const +{ + if (!m_bInitialized) + { + return VclHBox::calculateRequisition(); + } + + sal_uInt16 nVisibleChildren = 0; + + Size aSize; + for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next)) + { + if (!pChild->IsVisible()) + continue; + ++nVisibleChildren; + Size aChildSize = getLayoutRequisition(*pChild); + + bool bAllwaysExpanded = true; + + vcl::IPrioritable* pPrioritable = dynamic_cast<vcl::IPrioritable*>(pChild); + if (pPrioritable && pPrioritable->GetPriority() != VCL_PRIORITY_DEFAULT) + bAllwaysExpanded = false; + + if (bAllwaysExpanded) + { + long nPrimaryDimension = getPrimaryDimension(aChildSize); + nPrimaryDimension += pChild->get_padding() * 2; + setPrimaryDimension(aChildSize, nPrimaryDimension); + } + else + setPrimaryDimension(aChildSize, 0); + + accumulateMaxes(aChildSize, aSize); + } + + return finalizeMaxes(aSize, nVisibleChildren); +} + +void PriorityHBox::Resize() +{ + if (!m_bInitialized && SfxViewFrame::Current()) + Initialize(); + + if (!m_bInitialized) + { + return VclHBox::Resize(); + } + + long nWidth = GetSizePixel().Width(); + long nCurrentWidth = VclHBox::calculateRequisition().getWidth(); + + // Hide lower priority controls + for (vcl::IPrioritable* pPrioritable : m_aSortedChildren) + { + if (nCurrentWidth <= nWidth) + break; + + vcl::Window* pWindow = dynamic_cast<vcl::Window*>(pPrioritable); + + if (pWindow && pWindow->GetParent() == this) + { + nCurrentWidth -= pWindow->GetOutputWidthPixel() + get_spacing(); + pWindow->Show(); + pPrioritable->HideContent(); + nCurrentWidth += pWindow->GetOutputWidthPixel() + get_spacing(); + } + } + + auto pChildR = m_aSortedChildren.rbegin(); + // Show higher priority controls if we already have enough space + while (pChildR != m_aSortedChildren.rend()) + { + vcl::Window* pWindow = dynamic_cast<vcl::Window*>(*pChildR); + vcl::IPrioritable* pPrioritable = *pChildR; + + if(pWindow->GetParent() != this) + { + pChildR++; + continue; + } + + if (pWindow) + { + nCurrentWidth -= pWindow->GetOutputWidthPixel() + get_spacing(); + pWindow->Show(); + pPrioritable->ShowContent(); + nCurrentWidth += getLayoutRequisition(*pWindow).Width() + get_spacing(); + + if (nCurrentWidth > nWidth) + { + pPrioritable->HideContent(); + break; + } + } + + pChildR++; + } + + VclHBox::Resize(); +} + +void PriorityHBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) +{ + if (!m_bInitialized && SfxViewFrame::Current()) + Initialize(); + + VclHBox::Paint(rRenderContext, rRect); +} + +void PriorityHBox::GetChildrenWithPriorities() +{ + for (sal_uInt16 i = 0; i < GetChildCount(); ++i) + { + vcl::Window* pChild = GetChild(i); + + // Add only containers which have explicitly assigned priority. + vcl::IPrioritable* pPrioritable = dynamic_cast<vcl::IPrioritable*>(pChild); + if (pPrioritable && pPrioritable->GetPriority() != VCL_PRIORITY_DEFAULT) + m_aSortedChildren.push_back(pPrioritable); + } + + if (m_aSortedChildren.empty()) + m_bInitialized = false; + + std::sort(m_aSortedChildren.begin(), m_aSortedChildren.end(), lcl_comparePriority); +} + +VCL_BUILDER_FACTORY(PriorityHBox) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notebookbar/PriorityHBox.hxx b/sfx2/source/notebookbar/PriorityHBox.hxx new file mode 100644 index 000000000..04b884ddf --- /dev/null +++ b/sfx2/source/notebookbar/PriorityHBox.hxx @@ -0,0 +1,64 @@ +/* -*- 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/IPrioritable.hxx> +#include <vcl/layout.hxx> + +#include <vector> + +#ifndef INCLUDED_SFX2_NOTEBOOKBAR_PRIORITYHBOX_HXX +#define INCLUDED_SFX2_NOTEBOOKBAR_PRIORITYHBOX_HXX + +/* + * PriorityHBox is a VclHBox which hides its own children if there is no sufficient space. + * Hiding order can be modified using child's priorities. If a control have default + * priority assigned (VCL_PRIORITY_DEFAULT), it is always shown. + */ + +class PriorityHBox : public VclHBox +{ +private: + bool m_bInitialized; + + std::vector<vcl::IPrioritable*> m_aSortedChildren; + +protected: + int GetHiddenCount() const; + +public: + explicit PriorityHBox(vcl::Window* pParent); + + virtual ~PriorityHBox() override; + + void Initialize(); + + void SetSizeFromParent(); + + virtual Size calculateRequisition() const override; + + virtual void Resize() override; + + virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; + + void GetChildrenWithPriorities(); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notebookbar/PriorityMergedHBox.cxx b/sfx2/source/notebookbar/PriorityMergedHBox.cxx new file mode 100644 index 000000000..8a5bcd014 --- /dev/null +++ b/sfx2/source/notebookbar/PriorityMergedHBox.cxx @@ -0,0 +1,113 @@ +/* -*- 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/button.hxx> +#include <vcl/layout.hxx> +#include <bitmaps.hlst> +#include "PriorityHBox.hxx" +#include "NotebookbarPopup.hxx" + +/* +* PriorityMergedHBox is a VclHBox which hides its own children if there is no sufficient space. +*/ + +namespace +{ +class PriorityMergedHBox : public PriorityHBox +{ +private: + VclPtr<PushButton> m_pButton; + VclPtr<NotebookbarPopup> m_pPopup; + + DECL_LINK(PBClickHdl, Button*, void); + +public: + explicit PriorityMergedHBox(vcl::Window* pParent) + : PriorityHBox(pParent) + { + m_pButton = VclPtr<PushButton>::Create(this, WB_FLATBUTTON); + m_pButton->SetClickHdl(LINK(this, PriorityMergedHBox, PBClickHdl)); + m_pButton->SetModeImage(Image(StockImage::Yes, CHEVRON)); + m_pButton->set_width_request(25); + m_pButton->set_pack_type(VclPackType::End); + m_pButton->Show(); + } + + virtual ~PriorityMergedHBox() override { disposeOnce(); } + + virtual void Resize() override + { + PriorityHBox::Resize(); + if (GetHiddenCount()) + m_pButton->Show(); + else + m_pButton->Hide(); + } + + virtual void dispose() override + { + m_pButton.disposeAndClear(); + if (m_pPopup) + m_pPopup.disposeAndClear(); + PriorityHBox::dispose(); + } +}; +} + +IMPL_LINK(PriorityMergedHBox, PBClickHdl, Button*, /*pButton*/, void) +{ + if (m_pPopup) + m_pPopup.disposeAndClear(); + + m_pPopup = VclPtr<NotebookbarPopup>::Create(this); + + for (int i = 0; i < GetChildCount(); i++) + { + vcl::Window* pWindow = GetChild(i); + if (pWindow != m_pButton) + { + vcl::IPrioritable* pChild = dynamic_cast<vcl::IPrioritable*>(pWindow); + + if (pChild && pChild->IsHidden()) + { + pChild->ShowContent(); + pWindow->Show(); + pWindow->SetParent(m_pPopup->getBox()); + // count is decreased because we moved child + i--; + } + } + } + + m_pPopup->hideSeparators(true); + + m_pPopup->getBox()->set_height_request(GetSizePixel().Height()); + + long x = m_pButton->GetPosPixel().getX(); + long y = m_pButton->GetPosPixel().getY() + GetSizePixel().Height(); + tools::Rectangle aRect(x, y, x, y); + + m_pPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus + | FloatWinPopupFlags::AllMouseButtonClose); +} + +VCL_BUILDER_FACTORY(PriorityMergedHBox) + +/* 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..674caf4b0 --- /dev/null +++ b/sfx2/source/notebookbar/SfxNotebookBar.cxx @@ -0,0 +1,550 @@ +/* -*- 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.hxx> +#include <vcl/syswin.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/sfxsids.hrc> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/frame/UnknownModuleException.hpp> +#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp> +#include <com/sun/star/ui/XContextChangeEventMultiplexer.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/NotebookBarAddonsMerger.hxx> +#include <vector> +using namespace sfx2; +using namespace css::uno; +using namespace css::ui; +using namespace css; + +#define MENUBAR_STR "private:resource/menubar/menubar" + +static const char MERGE_NOTEBOOKBAR_URL[] = "URL"; +static const char MERGE_NOTEBOOKBAR_IMAGEID[] = "ImageIdentifier"; + +bool SfxNotebookBar::m_bLock = false; +bool SfxNotebookBar::m_bHide = false; + +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) + { + OUString sImage; + if (rProp.Name == MERGE_NOTEBOOKBAR_IMAGEID) + { + rProp.Value >>= sImage; + aImage = framework::AddonsOptions().GetImageFromURL(sImage, isBigImage); + } + } + if(!aImage) + { + for (const auto& rProp : rExtensionVal) + { + OUString sImage; + if (rProp.Name == MERGE_NOTEBOOKBAR_URL) + { + rProp.Value >>= sImage; + aImage = framework::AddonsOptions().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"; + break; + case vcl::EnumContext::Application::Calc: + return "Calc"; + break; + case vcl::EnumContext::Application::Impress: + return "Impress"; + break; + case vcl::EnumContext::Application::Draw: + return "Draw"; + break; + case vcl::EnumContext::Application::Formula: + return "Formula"; + break; + default: + return OUString(); + break; + } +} + +static void lcl_setNotebookbarFileName( vcl::EnumContext::Application eApp, const OUString& sFileName ) +{ + std::shared_ptr<comphelper::ConfigurationChanges> aBatch( + comphelper::ConfigurationChanges::create( ::comphelper::getProcessComponentContext() ) ); + 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(); + break; + case vcl::EnumContext::Application::Calc: + return officecfg::Office::UI::ToolbarMode::ActiveCalc::get(); + break; + case vcl::EnumContext::Application::Impress: + return officecfg::Office::UI::ToolbarMode::ActiveImpress::get(); + break; + case vcl::EnumContext::Application::Draw: + return officecfg::Office::UI::ToolbarMode::ActiveDraw::get(); + break; + + 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" ) ); + + 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::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, const OUString& 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, + const OUString& 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 = lcl_getNotebookbarFileName( eApp ); + OUString sNewFile = rUIFile + sFile; + OUString sCurrentFile; + VclPtr<NotebookBar> pNotebookBar = pSysWindow->GetNotebookBar(); + if ( pNotebookBar ) + sCurrentFile = OStringToOUString( pNotebookBar->getUIFile(), RTL_TEXTENCODING_ASCII_US ); + + bool bChangedFile = true; + if ( sCurrentFile.getLength() && sNewFile.getLength() ) + { + // delete "/" + sCurrentFile = sCurrentFile.copy( 0, sCurrentFile.getLength() - 1 ); + // delete ".ui" + sNewFile = sNewFile.copy( 0, sNewFile.getLength() - 3 ); + + bChangedFile = sNewFile != sCurrentFile; + } + + if ((!sFile.isEmpty() && bChangedFile) || !pNotebookBar || !pNotebookBar->IsVisible() + || bReloadNotebookbar) + { + 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 + pSysWindow->SetNotebookBar(aBuf, xFrame, aNotebookBarAddonsItem , bReloadNotebookbar); + pNotebookBar = pSysWindow->GetNotebookBar(); + pNotebookBar->Show(); + 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()) + { + pNotebookBar->Hide(); + pNotebookBar->GetParent()->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()) + { + xLayoutManager->lock(); + + 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); + } + + xLayoutManager->unlock(); + } + } + } + + 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()) + { + xLayoutManager->lock(); + + 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); + } + + xLayoutManager->unlock(); + } + } + 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(const OUString& sUIPath) +{ + if (SfxNotebookBar::IsActive()) + { + SfxViewShell* pViewShell = SfxViewShell::Current(); + sfx2::SfxNotebookBar::StateMethod(pViewShell->GetViewFrame()->GetBindings(), sUIPath, true); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |