diff options
Diffstat (limited to 'sfx2/source/sidebar/SidebarToolBox.cxx')
-rw-r--r-- | sfx2/source/sidebar/SidebarToolBox.cxx | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/sfx2/source/sidebar/SidebarToolBox.cxx b/sfx2/source/sidebar/SidebarToolBox.cxx new file mode 100644 index 000000000..f77e6d5ff --- /dev/null +++ b/sfx2/source/sidebar/SidebarToolBox.cxx @@ -0,0 +1,351 @@ +/* -*- 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 <sfx2/sidebar/SidebarToolBox.hxx> +#include <sidebar/ControllerFactory.hxx> +#include <sfx2/viewfrm.hxx> + +#include <vcl/commandinfoprovider.hxx> +#include <vcl/event.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <svtools/miscopt.hxx> +#include <com/sun/star/frame/XSubToolbarController.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XToolbarController.hpp> + +using namespace css; +using namespace css::uno; + +namespace { + void lcl_RTLizeCommandURL( OUString& rCommandURL ) + { + if (rCommandURL == ".uno:ParaLeftToRight") + rCommandURL = ".uno:ParaRightToLeft"; + else if (rCommandURL == ".uno:ParaRightToLeft") + rCommandURL = ".uno:ParaLeftToRight"; + else if (rCommandURL == ".uno:LeftPara") + rCommandURL = ".uno:RightPara"; + else if (rCommandURL == ".uno:RightPara") + rCommandURL = ".uno:LeftPara"; + else if (rCommandURL == ".uno:AlignLeft") + rCommandURL = ".uno:AlignRight"; + else if (rCommandURL == ".uno:AlignRight") + rCommandURL = ".uno:AlignLeft"; + } +} + +namespace sfx2::sidebar { + +SidebarToolBox::SidebarToolBox (vcl::Window* pParentWindow) + : ToolBox(pParentWindow, 0), + mbAreHandlersRegistered(false), + mbUseDefaultButtonSize(true), + mbSideBar(true) +{ + SetBackground(Wallpaper()); + SetPaintTransparent(true); + SetToolboxButtonSize(GetDefaultButtonSize()); + + SvtMiscOptions().AddListenerLink(LINK(this, SidebarToolBox, ChangedIconSizeHandler)); + +#ifdef DEBUG + SetText(OUString("SidebarToolBox")); +#endif +} + +SidebarToolBox::~SidebarToolBox() +{ + disposeOnce(); +} + +void SidebarToolBox::dispose() +{ + SvtMiscOptions().RemoveListenerLink(LINK(this, SidebarToolBox, ChangedIconSizeHandler)); + + ControllerContainer aControllers; + aControllers.swap(maControllers); + for (auto const& controller : aControllers) + { + Reference<lang::XComponent> xComponent(controller.second, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + } + + if (mbAreHandlersRegistered) + { + SetDropdownClickHdl(Link<ToolBox *, void>()); + SetClickHdl(Link<ToolBox *, void>()); + SetDoubleClickHdl(Link<ToolBox *, void>()); + SetSelectHdl(Link<ToolBox *, void>()); + SetActivateHdl(Link<ToolBox *, void>()); + SetDeactivateHdl(Link<ToolBox *, void>()); + mbAreHandlersRegistered = false; + } + + ToolBox::dispose(); +} + +ToolBoxButtonSize SidebarToolBox::GetDefaultButtonSize() const +{ + return SvtMiscOptions().GetSidebarIconSize(); +} + +void SidebarToolBox::InsertItem(const OUString& rCommand, + const css::uno::Reference<css::frame::XFrame>& rFrame, + ToolBoxItemBits nBits, const Size& rRequestedSize, ImplToolItems::size_type nPos) +{ + OUString aCommand( rCommand ); + + if( AllSettings::GetLayoutRTL() ) + { + lcl_RTLizeCommandURL( aCommand ); + } + + ToolBox::InsertItem(aCommand, rFrame, nBits, rRequestedSize, nPos); + + CreateController(GetItemId(aCommand), rFrame, std::max(rRequestedSize.Width(), 0L), mbSideBar); + RegisterHandlers(); +} + +bool SidebarToolBox::EventNotify (NotifyEvent& rEvent) +{ + if (rEvent.GetType() == MouseNotifyEvent::KEYINPUT) + { + if (rEvent.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB) + { + // Special handling for transferring handling of KEY_TAB + // that becomes necessary because of our parent that is + // not the dialog but a background control. + return DockingWindow::EventNotify(rEvent); + } + } + return ToolBox::EventNotify(rEvent); +} + +void SidebarToolBox::KeyInput(const KeyEvent& rKEvt) +{ + if (KEY_ESCAPE != rKEvt.GetKeyCode().GetCode()) + ToolBox::KeyInput(rKEvt); +} + +void SidebarToolBox::CreateController ( + const sal_uInt16 nItemId, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + const sal_Int32 nItemWidth, bool bSideBar) +{ + const OUString sCommandName (GetItemCommand(nItemId)); + + uno::Reference<frame::XToolbarController> xController(sfx2::sidebar::ControllerFactory::CreateToolBoxController( + this, nItemId, sCommandName, rxFrame, rxFrame->getController(), + VCLUnoHelper::GetInterface(this), nItemWidth, bSideBar)); + + if (xController.is()) + maControllers.insert(std::make_pair(nItemId, xController)); +} + +Reference<frame::XToolbarController> SidebarToolBox::GetControllerForItemId (const sal_uInt16 nItemId) const +{ + ControllerContainer::const_iterator iController (maControllers.find(nItemId)); + if (iController != maControllers.end()) + return iController->second; + + return Reference<frame::XToolbarController>(); +} + +void SidebarToolBox::SetController(const sal_uInt16 nItemId, + const css::uno::Reference<css::frame::XToolbarController>& rxController) +{ + ControllerContainer::iterator iController (maControllers.find(nItemId)); + if (iController != maControllers.end()) + { + Reference<lang::XComponent> xComponent(rxController, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + + iController->second = rxController; + } + else + { + maControllers[nItemId] = rxController; + } + + if (rxController.is()) + RegisterHandlers(); +} + +void SidebarToolBox::RegisterHandlers() +{ + if ( ! mbAreHandlersRegistered) + { + mbAreHandlersRegistered = true; + SetDropdownClickHdl(LINK(this, SidebarToolBox, DropDownClickHandler)); + SetClickHdl(LINK(this, SidebarToolBox, ClickHandler)); + SetDoubleClickHdl(LINK(this, SidebarToolBox, DoubleClickHandler)); + SetSelectHdl(LINK(this, SidebarToolBox, SelectHandler)); + } +} + +IMPL_LINK(SidebarToolBox, DropDownClickHandler, ToolBox*, pToolBox, void) +{ + if (pToolBox != nullptr) + { + Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); + if (xController.is()) + { + Reference<awt::XWindow> xWindow = xController->createPopupWindow(); + if (xWindow.is() ) + xWindow->setFocus(); + } + } +} + +IMPL_LINK(SidebarToolBox, ClickHandler, ToolBox*, pToolBox, void) +{ + if (pToolBox == nullptr) + return; + + Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); + if (xController.is()) + xController->click(); +} + +IMPL_LINK(SidebarToolBox, DoubleClickHandler, ToolBox*, pToolBox, void) +{ + if (pToolBox == nullptr) + return; + + Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); + if (xController.is()) + xController->doubleClick(); +} + +IMPL_LINK(SidebarToolBox, SelectHandler, ToolBox*, pToolBox, void) +{ + if (pToolBox == nullptr) + return; + + Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); + if (xController.is()) + xController->execute(static_cast<sal_Int16>(pToolBox->GetModifier())); +} + +IMPL_LINK_NOARG(SidebarToolBox, ChangedIconSizeHandler, LinkParamNone*, void) +{ + SolarMutexGuard g; + + if (mbUseDefaultButtonSize) + SetToolboxButtonSize(GetDefaultButtonSize()); + + for (auto const& it : maControllers) + { + Reference<frame::XSubToolbarController> xController(it.second, UNO_QUERY); + if (xController.is() && xController->opensSubToolbar()) + { + // The button should show the last function that was selected from the + // dropdown. The controller should know better than us what it was. + xController->updateImage(); + } + else if (SfxViewFrame::Current()) + { + OUString aCommandURL = GetItemCommand(it.first); + css::uno::Reference<frame::XFrame> xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface(); + Image aImage = vcl::CommandInfoProvider::GetImageForCommand(aCommandURL, xFrame, GetImageSize()); + SetItemImage(it.first, aImage); + } + } + + Resize(); + queue_resize(); +} + +void SidebarToolBox::InitToolBox(VclBuilder::stringmap& rMap) +{ + for (const auto& it : rMap) + { + if (it.first == "toolbar-style") + { + if (it.second == "text") + SetButtonType(ButtonType::TEXT); + else if (it.second == "both-horiz") + SetButtonType(ButtonType::SYMBOLTEXT); + else if (it.second == "both") + { + SetButtonType(ButtonType::SYMBOLTEXT); + SetToolBoxTextPosition(ToolBoxTextPosition::Bottom); + } + } + else if (it.first == "icon-size") + { + mbUseDefaultButtonSize = false; + if (it.second == "1" || it.second == "2" || it.second == "4") + SetToolboxButtonSize(ToolBoxButtonSize::Small); + else if (it.second == "3") + SetToolboxButtonSize(ToolBoxButtonSize::Large); + else if (it.second == "5") + SetToolboxButtonSize(ToolBoxButtonSize::Size32); + } + else if (it.first == "orientation" && it.second == "vertical") + SetAlign(WindowAlign::Left); + } +} + +namespace { + +class NotebookbarToolBox : public SidebarToolBox +{ +public: + explicit NotebookbarToolBox(vcl::Window* pParentWindow) + : SidebarToolBox(pParentWindow) + { + mbSideBar = false; + SetToolboxButtonSize(GetDefaultButtonSize()); + } + + virtual ToolBoxButtonSize GetDefaultButtonSize() const override + { + return SvtMiscOptions().GetNotebookbarIconSize(); + } +}; + +} + +extern "C" SAL_DLLPUBLIC_EXPORT void makeSidebarToolBox(VclPtr<vcl::Window> & rRet, const VclPtr<vcl::Window> & pParent, VclBuilder::stringmap & rMap) +{ + static_assert(std::is_same_v<std::remove_pointer_t<VclBuilder::customMakeWidget>, + decltype(makeSidebarToolBox)>); + VclPtrInstance<SidebarToolBox> pBox(pParent); + pBox->InitToolBox(rMap); + rRet = pBox; +} + +extern "C" SAL_DLLPUBLIC_EXPORT void makeNotebookbarToolBox(VclPtr<vcl::Window> & rRet, const VclPtr<vcl::Window> & pParent, VclBuilder::stringmap & rMap) +{ + static_assert(std::is_same_v<std::remove_pointer_t<VclBuilder::customMakeWidget>, + decltype(makeNotebookbarToolBox)>); + VclPtrInstance<NotebookbarToolBox> pBox(pParent); + pBox->InitToolBox(rMap); + rRet = pBox; +} + +} // end of namespace sfx2::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |