summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sfx2/sidebar/FocusManager.hxx24
-rw-r--r--include/sfx2/sidebar/SidebarController.hxx10
-rw-r--r--include/sfx2/sidebar/TabBar.hxx43
-rw-r--r--include/sfx2/sidebar/Theme.hxx12
-rw-r--r--include/sfx2/strings.hrc6
-rw-r--r--sfx2/Library_sfx.mk3
-rw-r--r--sfx2/UIConfig_sfx.mk3
-rw-r--r--sfx2/inc/pch/precompiled_sfx.hxx6
-rw-r--r--sfx2/inc/sidebar/ControlFactory.hxx50
-rw-r--r--sfx2/inc/sidebar/DrawHelper.hxx2
-rw-r--r--sfx2/inc/sidebar/MenuButton.hxx45
-rw-r--r--sfx2/inc/sidebar/PanelTitleBar.hxx5
-rw-r--r--sfx2/inc/sidebar/TabItem.hxx46
-rw-r--r--sfx2/source/sidebar/ControlFactory.cxx38
-rw-r--r--sfx2/source/sidebar/DrawHelper.cxx8
-rw-r--r--sfx2/source/sidebar/FocusManager.cxx202
-rw-r--r--sfx2/source/sidebar/MenuButton.cxx102
-rw-r--r--sfx2/source/sidebar/SidebarController.cxx228
-rw-r--r--sfx2/source/sidebar/TabBar.cxx275
-rw-r--r--sfx2/source/sidebar/TabItem.cxx108
-rw-r--r--sfx2/source/sidebar/Theme.cxx83
-rw-r--r--sfx2/source/view/sfxbasecontroller.cxx1
-rw-r--r--sfx2/uiconfig/ui/tabbar.ui13
-rw-r--r--sfx2/uiconfig/ui/tabbarcontents.ui145
-rw-r--r--sfx2/uiconfig/ui/tabbutton.ui25
-rw-r--r--solenv/clang-format/excludelist6
-rw-r--r--solenv/sanitizers/ui/sfx.suppr2
27 files changed, 527 insertions, 964 deletions
diff --git a/include/sfx2/sidebar/FocusManager.hxx b/include/sfx2/sidebar/FocusManager.hxx
index a51f4502ec97..0bebe247e634 100644
--- a/include/sfx2/sidebar/FocusManager.hxx
+++ b/include/sfx2/sidebar/FocusManager.hxx
@@ -22,7 +22,9 @@
#include <tools/link.hxx>
#include <vcl/keycod.hxx>
-class Button;
+namespace weld {
+class Widget;
+}
namespace sfx2::sidebar {
@@ -48,8 +50,7 @@ class DeckTitleBar;
class FocusManager
{
public:
- FocusManager(const std::function<void(const Panel&)>& rShowPanelFunctor,
- const std::function<bool(const sal_Int32)> &rIsDeckOpenFunctor);
+ FocusManager(const std::function<void(const Panel&)>& rShowPanelFunctor);
~FocusManager();
/** Forget all panels and buttons. Remove all window listeners.
@@ -65,18 +66,16 @@ public:
void SetDeckTitle(DeckTitleBar* pDeckTitleBar);
void SetPanels(const SharedPanelContainer& rPanels);
- void SetButtons(const ::std::vector<Button*>& rButtons);
+ void SetButtons(const std::vector<weld::Widget*>& rButtons);
private:
VclPtr<DeckTitleBar> mpDeckTitleBar;
std::vector<VclPtr<Panel> > maPanels;
- std::vector<VclPtr<Button> > maButtons;
+ std::vector<weld::Widget*> maButtons;
const std::function<void(const Panel&)> maShowPanelFunctor;
- const std::function<bool(const sal_Int32)> mbIsDeckOpenFunctor;
enum PanelComponent
{
- PC_DeckTitle,
PC_DeckToolBox,
PC_PanelTitle,
PC_PanelToolBox,
@@ -94,7 +93,7 @@ private:
/** Listen for key events for panels and buttons.
*/
- DECL_LINK( WindowEventListener, VclWindowEvent&, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
DECL_LINK(ChildEventListener, VclWindowEvent&, void);
void ClearPanels();
@@ -103,8 +102,8 @@ private:
/** Let the focus manager listen for window events for the given
window.
*/
- void RegisterWindow(vcl::Window& rWindow);
- void UnregisterWindow(vcl::Window& rWindow);
+ void RegisterWindow(weld::Widget& rWidget);
+ static void UnregisterWindow(weld::Widget& rWidget);
/** Remove the window from the panel or the button container.
*/
@@ -134,10 +133,11 @@ private:
void MoveFocusInsideDeckTitle(const FocusLocation& rLocation,
const sal_Int32 nDirection);
- void HandleKeyEvent(const vcl::KeyCode& rKeyCode,
- const vcl::Window& rWindow);
+ bool HandleKeyEvent(const vcl::KeyCode& rKeyCode,
+ const FocusLocation& rLocation);
FocusLocation GetFocusLocation(const vcl::Window& rWindow) const;
+ FocusLocation GetFocusLocation() const;
};
diff --git a/include/sfx2/sidebar/SidebarController.hxx b/include/sfx2/sidebar/SidebarController.hxx
index 3fe1e9a26c9e..cd4f329e99d9 100644
--- a/include/sfx2/sidebar/SidebarController.hxx
+++ b/include/sfx2/sidebar/SidebarController.hxx
@@ -246,11 +246,15 @@ private:
const Context& rContext);
void ShowPopupMenu (
- const tools::Rectangle& rButtonBox,
+ weld::Menu& rMainMenu,
+ weld::Menu& rSubMenu,
const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
- VclPtr<PopupMenu> CreatePopupMenu (
+ void PopulatePopupMenus(
+ weld::Menu& rMainButton,
+ weld::Menu& rSubMenu,
const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
- DECL_LINK(OnMenuItemSelected, Menu*, bool);
+ DECL_LINK(OnMenuItemSelected, const OString&, void);
+ DECL_LINK(OnSubMenuItemSelected, const OString&, void);
void BroadcastPropertyChange();
/** The close of the deck changes the width of the child window.
diff --git a/include/sfx2/sidebar/TabBar.hxx b/include/sfx2/sidebar/TabBar.hxx
index 4eda225a29a1..53135697230d 100644
--- a/include/sfx2/sidebar/TabBar.hxx
+++ b/include/sfx2/sidebar/TabBar.hxx
@@ -22,18 +22,16 @@
#include <sfx2//dllapi.h>
#include <sfx2/sidebar/ResourceManager.hxx>
-#include <vcl/button.hxx>
+#include <vcl/InterimItemWindow.hxx>
#include <vcl/menu.hxx>
#include <vcl/window.hxx>
#include <functional>
-class Button;
-class CheckBox;
-class RadioButton;
-
namespace svt { class AcceleratorExecute; }
+namespace weld { class Toolbar; }
+
namespace sfx2::sidebar {
class FocusManager;
@@ -41,7 +39,7 @@ class SidebarController;
/** The tab bar is the container for the individual tabs.
*/
-class TabBar final : public vcl::Window
+class TabBar final : public InterimItemWindow
{
public:
/** DeckMenuData has entries for display name, and a flag:
@@ -57,7 +55,7 @@ public:
bool mbIsEnabled;
};
typedef ::std::function<void (
- const tools::Rectangle&,
+ weld::Menu& rMainMenu, weld::Menu& rSubMenu,
const ::std::vector<DeckMenuData>& rMenuData)> PopupMenuProvider;
TabBar (
vcl::Window* pParentWindow,
@@ -66,6 +64,8 @@ public:
const PopupMenuProvider& rPopupMenuProvider,
SidebarController* rParentSidebarController);
+ weld::Container* GetContainer() { return m_xContainer.get(); }
+
virtual ~TabBar() override;
virtual void dispose() override;
@@ -90,29 +90,44 @@ public:
private:
css::uno::Reference<css::frame::XFrame> mxFrame;
- VclPtr<RadioButton> mpMenuButton;
+
+ // This unusual auxillary builder is because without a toplevel GtkWindow
+ // gtk will warn on loading a .ui with an accelerator defined, so use a
+ // temporary toplevel to suppress that and move the contents after load
+ std::unique_ptr<weld::Builder> mxAuxBuilder;
+ std::unique_ptr<weld::Container> mxTempToplevel;
+ std::unique_ptr<weld::Widget> mxContents;
+
+ std::unique_ptr<weld::MenuButton> mxMenuButton;
+ std::unique_ptr<weld::Menu> mxMainMenu;
+ std::unique_ptr<weld::Menu> mxSubMenu;
+ std::unique_ptr<weld::Widget> mxMeasureBox;
class Item
{
+ private:
+ TabBar& mrTabBar;
+ std::unique_ptr<weld::Builder> mxBuilder;
public:
- DECL_LINK(HandleClick, Button*, void);
- VclPtr<RadioButton> mpButton;
+ Item(TabBar& rTabBar);
+ ~Item();
+ DECL_LINK(HandleClick, const OString&, void);
+ std::unique_ptr<weld::Toolbar> mxButton;
OUString msDeckId;
::std::function<void (const OUString& rsDeckId)> maDeckActivationFunctor;
bool mbIsHidden;
bool mbIsHiddenByDefault;
};
- typedef ::std::vector<Item> ItemContainer;
+ typedef ::std::vector<std::unique_ptr<Item>> ItemContainer;
ItemContainer maItems;
const ::std::function<void (const OUString& rsDeckId)> maDeckActivationFunctor;
sal_Int32 mnMenuSeparatorY;
PopupMenuProvider maPopupMenuProvider;
- VclPtr<RadioButton> CreateTabItem (const DeckDescriptor& rDeckDescriptor);
+ static void CreateTabItem(weld::Toolbar& rButton, const DeckDescriptor& rDeckDescriptor);
css::uno::Reference<css::graphic::XGraphic> GetItemImage(const DeckDescriptor& rDeskDescriptor) const;
- void Layout();
void UpdateButtonIcons();
- DECL_LINK(OnToolboxClicked, Button*, void);
+ DECL_LINK(OnToolboxClicked, weld::ToggleButton&, void);
SidebarController* pParentSidebarController;
std::unique_ptr<svt::AcceleratorExecute> mpAccel;
diff --git a/include/sfx2/sidebar/Theme.hxx b/include/sfx2/sidebar/Theme.hxx
index 247d339958b1..9b35ce7aa6dd 100644
--- a/include/sfx2/sidebar/Theme.hxx
+++ b/include/sfx2/sidebar/Theme.hxx
@@ -55,7 +55,6 @@ public:
AnyItem_ = Pre_Image_,
- Image_TabBarMenu,
Image_CloseIndicator,
Image_Color_,
@@ -63,8 +62,6 @@ public:
Color_DeckTitleFont,
Color_PanelTitleFont,
Color_TabMenuSeparator,
- Color_TabItemBorder,
- Color_DropDownBorder,
Color_Highlight,
Color_HighlightText,
Color_DeckBackground,
@@ -72,8 +69,6 @@ public:
Color_PanelBackground,
Color_PanelTitleBarBackground,
Color_TabBarBackground,
- Color_TabItemBackgroundNormal,
- Color_TabItemBackgroundHighlight,
Color_HorizontalBorder,
Color_VerticalBorder,
Color_DropDownBackground,
@@ -86,17 +81,10 @@ public:
Int_PanelTitleBarHeight,
Int_TabMenuPadding,
Int_TabMenuSeparatorPadding,
- Int_TabItemWidth,
- Int_TabItemHeight,
Int_DeckLeftPadding,
Int_DeckTopPadding,
Int_DeckRightPadding,
Int_DeckBottomPadding,
- Int_TabBarLeftPadding,
- Int_TabBarTopPadding,
- Int_TabBarRightPadding,
- Int_TabBarBottomPadding,
- Int_ButtonCornerRadius,
Int_Bool_,
diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc
index 7930e5bbe24e..cb627807d8c8 100644
--- a/include/sfx2/strings.hrc
+++ b/include/sfx2/strings.hrc
@@ -294,15 +294,9 @@
#define STR_SIGNATURE_SHOW NC_("STR_SIGNATURE_SHOW", "Show Signatures")
#define STR_CLOSE_PANE NC_("STR_CLOSE_PANE", "Close Pane")
-#define STR_SFX_DOCK NC_("STR_SFX_DOCK", "Dock")
-#define STR_SFX_UNDOCK NC_("STR_SFX_UNDOCK", "Undock")
#define SFX_STR_SIDEBAR_MORE_OPTIONS NC_("SFX_STR_SIDEBAR_MORE_OPTIONS", "More Options")
#define SFX_STR_SIDEBAR_CLOSE_DECK NC_("SFX_STR_SIDEBAR_CLOSE_DECK", "Close Sidebar Deck")
-#define SFX_STR_SIDEBAR_SETTINGS NC_("SFX_STR_SIDEBAR_SETTINGS", "Sidebar Settings")
-#define SFX_STR_SIDEBAR_CUSTOMIZATION NC_("SFX_STR_SIDEBAR_CUSTOMIZATION", "Customization")
-#define SFX_STR_SIDEBAR_RESTORE NC_("SFX_STR_SIDEBAR_RESTORE", "Restore Default")
-#define SFX_STR_SIDEBAR_HIDE_SIDEBAR NC_("SFX_STR_SIDEBAR_HIDE_SIDEBAR", "Close Sidebar")
// Translators: default Impress template names
#define STR_TEMPLATE_NAME1 NC_("STR_TEMPLATE_NAME1", "Alizarin")
diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk
index aa722d248f48..cf3eaed6f81a 100644
--- a/sfx2/Library_sfx.mk
+++ b/sfx2/Library_sfx.mk
@@ -263,7 +263,6 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/sidebar/Context \
sfx2/source/sidebar/ContextChangeBroadcaster \
sfx2/source/sidebar/ContextList \
- sfx2/source/sidebar/ControlFactory \
sfx2/source/sidebar/ControllerFactory \
sfx2/source/sidebar/ControllerItem \
sfx2/source/sidebar/Deck \
@@ -272,7 +271,6 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/sidebar/DeckTitleBar \
sfx2/source/sidebar/DrawHelper \
sfx2/source/sidebar/FocusManager \
- sfx2/source/sidebar/MenuButton \
sfx2/source/sidebar/IContextChangeReceiver \
sfx2/source/sidebar/ILayoutableWindow \
sfx2/source/sidebar/Panel \
@@ -281,7 +279,6 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/sidebar/PanelTitleBar \
sfx2/source/sidebar/ResourceManager \
sfx2/source/sidebar/TabBar \
- sfx2/source/sidebar/TabItem \
sfx2/source/sidebar/TitleBar \
sfx2/source/sidebar/Theme \
sfx2/source/sidebar/Tools \
diff --git a/sfx2/UIConfig_sfx.mk b/sfx2/UIConfig_sfx.mk
index b2851a75e205..635b77324998 100644
--- a/sfx2/UIConfig_sfx.mk
+++ b/sfx2/UIConfig_sfx.mk
@@ -63,6 +63,9 @@ $(eval $(call gb_UIConfig_add_uifiles,sfx,\
sfx2/uiconfig/ui/singletabdialog \
sfx2/uiconfig/ui/startcenter \
sfx2/uiconfig/ui/stylecontextmenu \
+ sfx2/uiconfig/ui/tabbar \
+ sfx2/uiconfig/ui/tabbarcontents \
+ sfx2/uiconfig/ui/tabbutton \
sfx2/uiconfig/ui/templatedlg \
sfx2/uiconfig/ui/templatecategorydlg \
sfx2/uiconfig/ui/templatepanel \
diff --git a/sfx2/inc/pch/precompiled_sfx.hxx b/sfx2/inc/pch/precompiled_sfx.hxx
index 8b5d21edc38f..36b9d794c0af 100644
--- a/sfx2/inc/pch/precompiled_sfx.hxx
+++ b/sfx2/inc/pch/precompiled_sfx.hxx
@@ -13,7 +13,7 @@
manual changes will be rewritten by the next run of update_pch.sh (which presumably
also fixes all possible problems, so it's usually better to use it).
- Generated on 2020-09-03 20:51:12 using:
+ Generated on 2020-11-14 15:11:04 using:
./bin/update_pch sfx2 sfx --cutoff=3 --exclude:system --exclude:module --exclude:local
If after updating build fails, use the following command to locate conflicting headers:
@@ -25,6 +25,7 @@
#include <assert.h>
#include <cassert>
#include <cstddef>
+#include <cstdlib>
#include <functional>
#include <initializer_list>
#include <limits>
@@ -96,6 +97,7 @@
#include <vcl/commandevent.hxx>
#include <vcl/commandinfoprovider.hxx>
#include <vcl/ctrl.hxx>
+#include <vcl/customweld.hxx>
#include <vcl/dibtools.hxx>
#include <vcl/dllapi.h>
#include <vcl/errcode.hxx>
@@ -352,12 +354,14 @@
#include <tools/color.hxx>
#include <tools/datetime.hxx>
#include <tools/debug.hxx>
+#include <tools/degree.hxx>
#include <tools/diagnose_ex.h>
#include <tools/fract.hxx>
#include <tools/gen.hxx>
#include <tools/globname.hxx>
#include <tools/json_writer.hxx>
#include <tools/link.hxx>
+#include <tools/long.hxx>
#include <tools/poly.hxx>
#include <tools/ref.hxx>
#include <tools/solar.h>
diff --git a/sfx2/inc/sidebar/ControlFactory.hxx b/sfx2/inc/sidebar/ControlFactory.hxx
deleted file mode 100644
index 22fd2fdeb119..000000000000
--- a/sfx2/inc/sidebar/ControlFactory.hxx
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- 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_SIDEBAR_CONTROLFACTORY_HXX
-#define INCLUDED_SFX2_SIDEBAR_CONTROLFACTORY_HXX
-
-#include <sfx2/dllapi.h>
-#include <vcl/vclptr.hxx>
-
-class RadioButton;
-namespace vcl { class Window; }
-
-namespace sfx2::sidebar {
-
-/** Factory for controls used in sidebar panels.
- The reason to use this factory instead of creating the controls
- directly is that this way the sidebar has a little more control
- over look and feel of its controls.
-*/
-class ControlFactory
-{
-public:
- /** Create the menu button for the task bar.
- */
- static VclPtr<RadioButton> CreateMenuButton (vcl::Window* pParentWindow);
-
- static VclPtr<RadioButton> CreateTabItem (vcl::Window* pParentWindow);
-};
-
-
-} // end of namespace sfx2::sidebar
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/inc/sidebar/DrawHelper.hxx b/sfx2/inc/sidebar/DrawHelper.hxx
index a066b157aee4..8ac1c7e51c49 100644
--- a/sfx2/inc/sidebar/DrawHelper.hxx
+++ b/sfx2/inc/sidebar/DrawHelper.hxx
@@ -36,8 +36,6 @@ public:
const sal_Int32 nY, const sal_Int32 nHeight, const Color& rColor);
static void DrawVerticalLine(vcl::RenderContext& rRenderContext, const sal_Int32 nTop, const sal_Int32 nBottom,
const sal_Int32 nX, const sal_Int32 nWidth, const Color& rColor);
- static void DrawRoundedRectangle(vcl::RenderContext& rRenderContext, const tools::Rectangle& rBox, const sal_Int32 nCornerRadius,
- const Color& rBorderColor, const Color& rFillColor);
};
} // end of namespace sfx2::sidebar
diff --git a/sfx2/inc/sidebar/MenuButton.hxx b/sfx2/inc/sidebar/MenuButton.hxx
deleted file mode 100644
index eab32a463b64..000000000000
--- a/sfx2/inc/sidebar/MenuButton.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- 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 .
- */
-#pragma once
-
-#include <vcl/button.hxx>
-
-namespace sfx2::sidebar {
-
-class MenuButton final
- : public RadioButton
-{
-public:
- MenuButton (vcl::Window* pParentWindow);
-
- virtual void Paint (vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rUpdateArea) override;
- virtual void MouseMove (const MouseEvent& rEvent) override;
- virtual void MouseButtonDown (const MouseEvent& rMouseEvent) override;
- virtual void MouseButtonUp (const MouseEvent& rMouseEvent) override;
-
-protected:
- using RadioButton::FillLayoutData;
-
-private:
- bool mbIsLeftButtonDown;
-};
-
-} // end of namespace sfx2::sidebar
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/inc/sidebar/PanelTitleBar.hxx b/sfx2/inc/sidebar/PanelTitleBar.hxx
index 63b7a3b9e7af..745fc8cd3030 100644
--- a/sfx2/inc/sidebar/PanelTitleBar.hxx
+++ b/sfx2/inc/sidebar/PanelTitleBar.hxx
@@ -45,6 +45,11 @@ public:
void UpdateExpandedState();
+ weld::Expander& GetExpander()
+ {
+ return *mxExpander;
+ }
+
virtual void DataChanged(const DataChangedEvent& rEvent) override;
private:
diff --git a/sfx2/inc/sidebar/TabItem.hxx b/sfx2/inc/sidebar/TabItem.hxx
deleted file mode 100644
index 44e5cf6b5141..000000000000
--- a/sfx2/inc/sidebar/TabItem.hxx
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- 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 .
- */
-#pragma once
-
-#include <vcl/button.hxx>
-
-namespace vcl { class Window; }
-
-namespace sfx2::sidebar {
-
-/** A single button in the tab bar.
-*/
-class TabItem final
- : public RadioButton
-{
-public:
- TabItem (vcl::Window* pParentWindow);
-
- virtual void Paint (vcl::RenderContext& rRenderContext, const tools::Rectangle& rUpdateArea) override;
- virtual void MouseMove (const MouseEvent& rEvent) override;
- virtual void MouseButtonDown (const MouseEvent& rMouseEvent) override;
- virtual void MouseButtonUp (const MouseEvent& rMouseEvent) override;
-
-private:
- bool mbIsLeftButtonDown;
-};
-
-} // end of namespace sfx2::sidebar
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/sidebar/ControlFactory.cxx b/sfx2/source/sidebar/ControlFactory.cxx
deleted file mode 100644
index e310e2b9012a..000000000000
--- a/sfx2/source/sidebar/ControlFactory.cxx
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- 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 <sidebar/ControlFactory.hxx>
-
-#include <sidebar/MenuButton.hxx>
-#include <sidebar/TabItem.hxx>
-
-namespace sfx2::sidebar {
-
-VclPtr<RadioButton> ControlFactory::CreateMenuButton (vcl::Window* pParentWindow)
-{
- return VclPtr<MenuButton>::Create(pParentWindow);
-}
-
-VclPtr<RadioButton> ControlFactory::CreateTabItem (vcl::Window* pParentWindow)
-{
- return VclPtr<TabItem>::Create(pParentWindow);
-}
-
-} // end of namespace sfx2::sidebar
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/sidebar/DrawHelper.cxx b/sfx2/source/sidebar/DrawHelper.cxx
index 52da8bf8a422..ceb4d23717d6 100644
--- a/sfx2/source/sidebar/DrawHelper.cxx
+++ b/sfx2/source/sidebar/DrawHelper.cxx
@@ -64,14 +64,6 @@ void DrawHelper::DrawVerticalLine(vcl::RenderContext& rRenderContext, const sal_
}
}
-void DrawHelper::DrawRoundedRectangle(vcl::RenderContext& rRenderContext, const tools::Rectangle& rBox, const sal_Int32 nCornerRadius,
- const Color& rBorderColor, const Color& rFillColor)
-{
- rRenderContext.SetLineColor(rBorderColor);
- rRenderContext.SetFillColor(rFillColor);
- rRenderContext.DrawRect(rBox, nCornerRadius, nCornerRadius);
-}
-
} // end of namespace sfx2::sidebar
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/sidebar/FocusManager.cxx b/sfx2/source/sidebar/FocusManager.cxx
index 7c6ab781ff83..484aeef503cc 100644
--- a/sfx2/source/sidebar/FocusManager.cxx
+++ b/sfx2/source/sidebar/FocusManager.cxx
@@ -36,13 +36,11 @@ FocusManager::FocusLocation::FocusLocation (const PanelComponent eComponent, con
{
}
-FocusManager::FocusManager(const std::function<void(const Panel&)>& rShowPanelFunctor,
- const std::function<bool(const sal_Int32)>& rIsDeckOpenFunctor)
+FocusManager::FocusManager(const std::function<void(const Panel&)>& rShowPanelFunctor)
: mpDeckTitleBar(),
maPanels(),
maButtons(),
- maShowPanelFunctor(rShowPanelFunctor),
- mbIsDeckOpenFunctor(rIsDeckOpenFunctor)
+ maShowPanelFunctor(rShowPanelFunctor)
{
}
@@ -74,10 +72,10 @@ void FocusManager::ClearPanels()
aPanels.swap(maPanels);
for (auto const& panel : aPanels)
{
- UnregisterWindow(*panel);
if (panel->GetTitleBar())
{
- UnregisterWindow(*panel->GetTitleBar());
+ UnregisterWindow(panel->GetTitleBar()->GetToolBox());
+ UnregisterWindow(panel->GetTitleBar()->GetExpander());
}
panel->RemoveChildEventListener(LINK(this, FocusManager, ChildEventListener));
@@ -86,7 +84,7 @@ void FocusManager::ClearPanels()
void FocusManager::ClearButtons()
{
- std::vector<VclPtr<Button> > aButtons;
+ std::vector<weld::Widget*> aButtons;
aButtons.swap(maButtons);
for (auto const& button : aButtons)
{
@@ -97,15 +95,11 @@ void FocusManager::ClearButtons()
void FocusManager::SetDeckTitle (DeckTitleBar* pDeckTitleBar)
{
if (mpDeckTitleBar != nullptr)
- {
- UnregisterWindow(*mpDeckTitleBar);
- }
+ UnregisterWindow(mpDeckTitleBar->GetToolBox());
mpDeckTitleBar = pDeckTitleBar;
if (mpDeckTitleBar != nullptr)
- {
- RegisterWindow(*mpDeckTitleBar);
- }
+ RegisterWindow(mpDeckTitleBar->GetToolBox());
}
void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
@@ -113,10 +107,10 @@ void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
ClearPanels();
for (auto const& panel : rPanels)
{
- RegisterWindow(*panel);
if (panel->GetTitleBar())
{
- RegisterWindow(*panel->GetTitleBar());
+ RegisterWindow(panel->GetTitleBar()->GetToolBox());
+ RegisterWindow(panel->GetTitleBar()->GetExpander());
}
// Register also as child event listener at the panel.
@@ -126,7 +120,7 @@ void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
}
}
-void FocusManager::SetButtons (const ::std::vector<Button*>& rButtons)
+void FocusManager::SetButtons(const std::vector<weld::Widget*>& rButtons)
{
ClearButtons();
for (auto const& button : rButtons)
@@ -136,25 +130,19 @@ void FocusManager::SetButtons (const ::std::vector<Button*>& rButtons)
}
}
-void FocusManager::RegisterWindow (vcl::Window& rWindow)
+void FocusManager::RegisterWindow(weld::Widget& rWidget)
{
- rWindow.AddEventListener(LINK(this, FocusManager, WindowEventListener));
+ UnregisterWindow(rWidget); // explicitly unset key press handler so we can reconnect without warnings
+ rWidget.connect_key_press(LINK(this, FocusManager, KeyInputHdl));
}
-void FocusManager::UnregisterWindow (vcl::Window& rWindow)
+void FocusManager::UnregisterWindow(weld::Widget& rWidget)
{
- rWindow.RemoveEventListener(LINK(this, FocusManager, WindowEventListener));
+ rWidget.connect_key_press(Link<const KeyEvent&, bool>());
}
FocusManager::FocusLocation FocusManager::GetFocusLocation (const vcl::Window& rWindow) const
{
- // Check the deck title.
- if (mpDeckTitleBar != nullptr)
- {
- if (mpDeckTitleBar == &rWindow)
- return FocusLocation(PC_DeckTitle, -1);
- }
-
// Search the panels.
for (size_t nIndex = 0; nIndex < maPanels.size(); ++nIndex)
{
@@ -165,10 +153,31 @@ FocusManager::FocusLocation FocusManager::GetFocusLocation (const vcl::Window& r
return FocusLocation(PC_PanelTitle, nIndex);
}
+ return FocusLocation(PC_None, -1);
+}
+
+FocusManager::FocusLocation FocusManager::GetFocusLocation() const
+{
+ // Check the deck title.
+ if (mpDeckTitleBar && mpDeckTitleBar->GetToolBox().has_focus())
+ return FocusLocation(PC_DeckToolBox, -1);
+
+ // Search the panels.
+ for (size_t nIndex = 0; nIndex < maPanels.size(); ++nIndex)
+ {
+ VclPtr<PanelTitleBar> pTitleBar = maPanels[nIndex]->GetTitleBar();
+ if (!pTitleBar)
+ continue;
+ if (pTitleBar->GetExpander().has_focus())
+ return FocusLocation(PC_PanelTitle, nIndex);
+ if (pTitleBar->GetToolBox().has_focus())
+ return FocusLocation(PC_PanelToolBox, nIndex);
+ }
+
// Search the buttons.
for (size_t nIndex=0; nIndex < maButtons.size(); ++nIndex)
{
- if (maButtons[nIndex] == &rWindow)
+ if (maButtons[nIndex]->has_focus())
return FocusLocation(PC_TabBar, nIndex);
}
return FocusLocation(PC_None, -1);
@@ -178,11 +187,7 @@ void FocusManager::FocusDeckTitle()
{
if (mpDeckTitleBar != nullptr)
{
- if (IsDeckTitleVisible())
- {
- mpDeckTitleBar->GrabFocus();
- }
- else if (mpDeckTitleBar->GetToolBox().get_n_items() > 0)
+ if (mpDeckTitleBar->GetToolBox().get_n_items() > 0)
{
weld::Toolbar& rToolBox = mpDeckTitleBar->GetToolBox();
rToolBox.grab_focus();
@@ -222,11 +227,11 @@ void FocusManager::FocusPanel (
}
Panel& rPanel (*maPanels[nPanelIndex]);
- VclPtr<TitleBar> pTitleBar = rPanel.GetTitleBar();
+ VclPtr<PanelTitleBar> pTitleBar = rPanel.GetTitleBar();
if (pTitleBar && pTitleBar->IsVisible())
{
rPanel.SetExpanded(true);
- pTitleBar->GrabFocus();
+ pTitleBar->GetExpander().grab_focus();
}
else if (bFallbackToDeckTitle)
{
@@ -259,20 +264,7 @@ void FocusManager::FocusPanelContent (const sal_Int32 nPanelIndex)
void FocusManager::FocusButton (const sal_Int32 nButtonIndex)
{
- maButtons[nButtonIndex]->GrabFocus();
- maButtons[nButtonIndex]->Invalidate();
-}
-
-void FocusManager::ClickButton (const sal_Int32 nButtonIndex)
-{
- if (mbIsDeckOpenFunctor)
- {
- if (!mbIsDeckOpenFunctor(-1) || !mbIsDeckOpenFunctor(nButtonIndex-1))
- maButtons[nButtonIndex]->Click();
- }
- if (nButtonIndex > 0)
- FocusPanel(0, true);
- maButtons[nButtonIndex]->GetParent()->Invalidate();
+ maButtons[nButtonIndex]->grab_focus();
}
void FocusManager::RemoveWindow (vcl::Window& rWindow)
@@ -280,22 +272,14 @@ void FocusManager::RemoveWindow (vcl::Window& rWindow)
auto iPanel (::std::find(maPanels.begin(), maPanels.end(), &rWindow));
if (iPanel != maPanels.end())
{
- UnregisterWindow(rWindow);
if ((*iPanel)->GetTitleBar() != nullptr)
{
- UnregisterWindow(*(*iPanel)->GetTitleBar());
+ UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
+ UnregisterWindow((*iPanel)->GetTitleBar()->GetExpander());
}
maPanels.erase(iPanel);
return;
}
-
- auto iButton (::std::find(maButtons.begin(), maButtons.end(), &rWindow));
- if (iButton != maButtons.end())
- {
- UnregisterWindow(rWindow);
- maButtons.erase(iButton);
- return;
- }
}
void FocusManager::MoveFocusInsidePanel (
@@ -315,7 +299,7 @@ void FocusManager::MoveFocusInsidePanel (
case PC_PanelToolBox:
if (nDirection < 0 && bHasToolBoxItem)
- maPanels[rFocusLocation.mnIndex]->GetTitleBar()->GrabFocus();
+ maPanels[rFocusLocation.mnIndex]->GetTitleBar()->GetExpander().grab_focus();
else
FocusPanelContent(rFocusLocation.mnIndex);
break;
@@ -330,35 +314,23 @@ void FocusManager::MoveFocusInsideDeckTitle (
{
// Note that when the title bar of the first (and only) panel is
// not visible then the deck title takes its place and the focus
- // is moved between a) deck title, b) deck closer and c) content
- // of panel 0.
- const bool bHasToolBoxItem (
- mpDeckTitleBar->GetToolBox().get_n_items() > 0);
+ // is moved between a) deck closer and b) content of panel 0.
switch (rFocusLocation.meComponent)
{
- case PC_DeckTitle:
- if (nDirection<0 && ! IsPanelTitleVisible(0))
- FocusPanelContent(0);
- else if (bHasToolBoxItem)
- mpDeckTitleBar->GetToolBox().grab_focus();
- break;
-
case PC_DeckToolBox:
if (nDirection>0 && ! IsPanelTitleVisible(0))
FocusPanelContent(0);
- else
- mpDeckTitleBar->GrabFocus();
break;
default: break;
}
}
-void FocusManager::HandleKeyEvent (
+bool FocusManager::HandleKeyEvent(
const vcl::KeyCode& rKeyCode,
- const vcl::Window& rWindow)
+ const FocusLocation& aLocation)
{
- const FocusLocation aLocation (GetFocusLocation(rWindow));
+ bool bConsumed = false;
switch (rKeyCode.GetCode())
{
@@ -366,57 +338,42 @@ void FocusManager::HandleKeyEvent (
switch (aLocation.meComponent)
{
case PC_TabBar:
- case PC_DeckTitle:
case PC_DeckToolBox:
case PC_PanelTitle:
case PC_PanelToolBox:
{
vcl::Window* pFocusWin = Application::GetFocusWindow();
if (pFocusWin)
+ {
pFocusWin->GrabFocusToDocument();
+ bConsumed = true;
+ }
break;
}
default:
break;
}
- return;
-
- case KEY_SPACE:
- switch (aLocation.meComponent)
- {
- case PC_PanelTitle:
- // Toggle panel between expanded and collapsed.
- maPanels[aLocation.mnIndex]->SetExpanded( ! maPanels[aLocation.mnIndex]->IsExpanded());
- maPanels[aLocation.mnIndex]->GetTitleBar()->Invalidate();
- break;
-
- default:
- break;
- }
- return;
+ return bConsumed;
case KEY_RETURN:
switch (aLocation.meComponent)
{
case PC_DeckToolBox:
FocusButton(0);
+ bConsumed = true;
break;
case PC_PanelTitle:
// Enter the panel.
FocusPanelContent(aLocation.mnIndex);
- break;
-
- case PC_TabBar:
- // Activate the button.
- ClickButton(aLocation.mnIndex);
+ bConsumed = true;
break;
default:
break;
}
- return;
+ return bConsumed;
case KEY_TAB:
{
@@ -430,11 +387,12 @@ void FocusManager::HandleKeyEvent (
case PC_PanelToolBox:
case PC_PanelContent:
MoveFocusInsidePanel(aLocation, nDirection);
+ bConsumed = true;
break;
- case PC_DeckTitle:
case PC_DeckToolBox:
MoveFocusInsideDeckTitle(aLocation, nDirection);
+ bConsumed = true;
break;
default:
@@ -459,18 +417,19 @@ void FocusManager::HandleKeyEvent (
{
// Focus the last button.
sal_Int32 nIndex(maButtons.size()-1);
- while(!maButtons[nIndex]->IsVisible() && --nIndex > 0);
+ while(!maButtons[nIndex]->get_visible() && --nIndex > 0);
FocusButton(nIndex);
}
+ bConsumed = true;
break;
- case PC_DeckTitle:
case PC_DeckToolBox:
{
// Focus the last button.
sal_Int32 nIndex(maButtons.size()-1);
- while(!maButtons[nIndex]->IsVisible() && --nIndex > 0);
+ while(!maButtons[nIndex]->get_visible() && --nIndex > 0);
FocusButton(nIndex);
+ bConsumed = true;
break;
}
@@ -481,9 +440,10 @@ void FocusManager::HandleKeyEvent (
else
{
sal_Int32 nIndex((aLocation.mnIndex + maButtons.size() - 1) % maButtons.size());
- while(!maButtons[nIndex]->IsVisible() && --nIndex > 0);
+ while(!maButtons[nIndex]->get_visible() && --nIndex > 0);
FocusButton(nIndex);
}
+ bConsumed = true;
break;
default:
@@ -503,15 +463,16 @@ void FocusManager::HandleKeyEvent (
FocusPanel(aLocation.mnIndex+1, false);
else
FocusButton(0);
+ bConsumed = true;
break;
- case PC_DeckTitle:
case PC_DeckToolBox:
// Focus the first panel.
if (IsPanelTitleVisible(0))
FocusPanel(0, false);
else
FocusButton(0);
+ bConsumed = true;
break;
case PC_TabBar:
@@ -519,10 +480,11 @@ void FocusManager::HandleKeyEvent (
if (aLocation.mnIndex < static_cast<sal_Int32>(maButtons.size())-1)
{
sal_Int32 nIndex(aLocation.mnIndex + 1);
- while(!maButtons[nIndex]->IsVisible() && ++nIndex < static_cast<sal_Int32>(maButtons.size()));
+ while(!maButtons[nIndex]->get_visible() && ++nIndex < static_cast<sal_Int32>(maButtons.size()));
if (nIndex < static_cast<sal_Int32>(maButtons.size()))
{
FocusButton(nIndex);
+ bConsumed = true;
break;
}
}
@@ -530,6 +492,7 @@ void FocusManager::HandleKeyEvent (
FocusDeckTitle();
else
FocusPanel(0, true);
+ bConsumed = true;
break;
default:
@@ -537,35 +500,12 @@ void FocusManager::HandleKeyEvent (
}
break;
}
+ return bConsumed;
}
-IMPL_LINK(FocusManager, WindowEventListener, VclWindowEvent&, rWindowEvent, void)
+IMPL_LINK(FocusManager, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
{
- vcl::Window* pSource = rWindowEvent.GetWindow();
- if (pSource == nullptr)
- return;
-
- switch (rWindowEvent.GetId())
- {
- case VclEventId::WindowKeyInput:
- {
- KeyEvent* pKeyEvent = static_cast<KeyEvent*>(rWindowEvent.GetData());
- HandleKeyEvent(pKeyEvent->GetKeyCode(), *pSource);
- break;
- }
-
- case VclEventId::ObjectDying:
- RemoveWindow(*pSource);
- break;
-
- case VclEventId::WindowGetFocus:
- case VclEventId::WindowLoseFocus:
- pSource->Invalidate();
- break;
-
- default:
- break;
- }
+ return HandleKeyEvent(rKeyEvent.GetKeyCode(), GetFocusLocation());
}
IMPL_LINK(FocusManager, ChildEventListener, VclWindowEvent&, rEvent, void)
diff --git a/sfx2/source/sidebar/MenuButton.cxx b/sfx2/source/sidebar/MenuButton.cxx
deleted file mode 100644
index d89ef544f624..000000000000
--- a/sfx2/source/sidebar/MenuButton.cxx
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- 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 <sidebar/MenuButton.hxx>
-
-#include <sidebar/DrawHelper.hxx>
-#include <sfx2/sidebar/Theme.hxx>
-#include <vcl/event.hxx>
-
-using namespace css;
-using namespace css::uno;
-
-namespace sfx2::sidebar {
-
-MenuButton::MenuButton (vcl::Window* pParentWindow)
- : RadioButton(pParentWindow),
- mbIsLeftButtonDown(false)
-{
-#ifdef DEBUG
- SetText(OUString("MenuButton"));
-#endif
-}
-
-void MenuButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rUpdateArea*/)
-{
- const bool bIsSelected (IsChecked());
- const bool bIsHighlighted (IsMouseOver() || HasFocus());
- DrawHelper::DrawRoundedRectangle(
- rRenderContext,
- tools::Rectangle(Point(0,0), GetSizePixel()),
- 3,
- (bIsHighlighted || bIsSelected
- ? Theme::GetColor(Theme::Color_TabItemBorder)
- : COL_TRANSPARENT),
- (bIsHighlighted
- ? Theme::GetColor(Theme::Color_TabItemBackgroundHighlight)
- : Theme::GetColor(Theme::Color_TabItemBackgroundNormal)));
-
- const Image aIcon(Button::GetModeImage());
- const Size aIconSize(aIcon.GetSizePixel());
- const Point aIconLocation((GetSizePixel().Width() - aIconSize.Width()) / 2,
- (GetSizePixel().Height() - aIconSize.Height()) / 2);
- rRenderContext.DrawImage(aIconLocation, aIcon);
-}
-
-void MenuButton::MouseMove (const MouseEvent& rEvent)
-{
- if (rEvent.IsEnterWindow() || rEvent.IsLeaveWindow())
- Invalidate();
- RadioButton::MouseMove(rEvent);
-}
-
-void MenuButton::MouseButtonDown (const MouseEvent& rMouseEvent)
-{
- if (rMouseEvent.IsLeft())
- {
- mbIsLeftButtonDown = true;
- CaptureMouse();
- Invalidate();
- }
-}
-
-void MenuButton::MouseButtonUp (const MouseEvent& rMouseEvent)
-{
- if (IsMouseCaptured())
- ReleaseMouse();
-
- if (rMouseEvent.IsLeft())
- {
- if (mbIsLeftButtonDown)
- {
- Check();
- Click();
- GetParent()->Invalidate();
- }
- }
- if (mbIsLeftButtonDown)
- {
- mbIsLeftButtonDown = false;
- Invalidate();
- }
-}
-
-} // end of namespace sfx2::sidebar
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx
index f257b5e815ca..f359e768665e 100644
--- a/sfx2/source/sidebar/SidebarController.cxx
+++ b/sfx2/source/sidebar/SidebarController.cxx
@@ -129,7 +129,8 @@ SidebarController::SidebarController (
mpParentWindow,
mxFrame,
[this](const OUString& rsDeckId) { return this->OpenThenToggleDeck(rsDeckId); },
- [this](const tools::Rectangle& rButtonBox,const ::std::vector<TabBar::DeckMenuData>& rMenuData) { return this->ShowPopupMenu(rButtonBox,rMenuData); },
+ [this](weld::Menu& rMainMenu, weld::Menu& rSubMenu,
+ const ::std::vector<TabBar::DeckMenuData>& rMenuData) { return this->ShowPopupMenu(rMainMenu, rSubMenu, rMenuData); },
this)),
maCurrentContext(OUString(), OUString()),
maRequestedContext(),
@@ -142,8 +143,7 @@ SidebarController::SidebarController (
mbIsDeckOpen(),
mbFloatingDeckClosed(!pParentWindow->IsFloatingMode()),
mnSavedSidebarWidth(pParentWindow->GetSizePixel().Width()),
- maFocusManager([this](const Panel& rPanel){ return this->ShowPanel(rPanel); },
- [this](const sal_Int32 nIndex){ return this->IsDeckOpen(nIndex); }),
+ maFocusManager([this](const Panel& rPanel){ return this->ShowPanel(rPanel); }),
mxReadOnlyModeDispatch(),
mbIsDocumentReadOnly(false),
mpSplitWindow(nullptr),
@@ -547,6 +547,8 @@ void SidebarController::UpdateConfigurations()
mbIsDocumentReadOnly,
xController);
+ maFocusManager.Clear();
+
// Notify the tab bar about the updated set of decks.
mpTabBar->SetDecks(aDecks);
@@ -1052,187 +1054,147 @@ IMPL_LINK(SidebarController, WindowEventHandler, VclWindowEvent&, rEvent, void)
}
}
-void SidebarController::ShowPopupMenu (
- const tools::Rectangle& rButtonBox,
+void SidebarController::ShowPopupMenu(
+ weld::Menu& rMainMenu, weld::Menu& rSubMenu,
const ::std::vector<TabBar::DeckMenuData>& rMenuData) const
{
- VclPtr<PopupMenu> pMenu = CreatePopupMenu(rMenuData);
- pMenu->SetSelectHdl(LINK(const_cast<SidebarController*>(this), SidebarController, OnMenuItemSelected));
-
- // pass toolbox button rect so the menu can stay open on button up
- tools::Rectangle aBox (rButtonBox);
- aBox.Move(mpTabBar->GetPosPixel().X(), 0);
- const PopupMenuFlags aMenuDirection
- = (comphelper::LibreOfficeKit::isActive() ? PopupMenuFlags::ExecuteLeft
- : PopupMenuFlags::ExecuteDown);
- pMenu->Execute(mpParentWindow, aBox, aMenuDirection);
- pMenu.disposeAndClear();
+ PopulatePopupMenus(rMainMenu, rSubMenu, rMenuData);
+ rMainMenu.connect_activate(LINK(const_cast<SidebarController*>(this), SidebarController, OnMenuItemSelected));
+ rSubMenu.connect_activate(LINK(const_cast<SidebarController*>(this), SidebarController, OnSubMenuItemSelected));
}
-VclPtr<PopupMenu>
-SidebarController::CreatePopupMenu(const ::std::vector<TabBar::DeckMenuData>& rMenuData) const
+void SidebarController::PopulatePopupMenus(weld::Menu& rMenu, weld::Menu& rCustomizationMenu,
+ const std::vector<TabBar::DeckMenuData>& rMenuData) const
{
- // Create the top level popup menu.
- auto pMenu = VclPtr<PopupMenu>::Create();
- FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
- if (pMenuWindow != nullptr)
- {
- pMenuWindow->SetPopupModeFlags(pMenuWindow->GetPopupModeFlags()
- | FloatWinPopupFlags::NoMouseUpClose);
- }
-
- // Create sub menu for customization (hiding of deck tabs), only on desktop.
- VclPtr<PopupMenu> pCustomizationMenu
- = (comphelper::LibreOfficeKit::isActive() ? nullptr : VclPtr<PopupMenu>::Create());
-
// Add one entry for every tool panel element to individually make
// them visible or hide them.
sal_Int32 nIndex (0);
for (const auto& rItem : rMenuData)
{
- const sal_Int32 nMenuIndex (nIndex+MID_FIRST_PANEL);
- pMenu->InsertItem(nMenuIndex, rItem.msDisplayName, MenuItemBits::RADIOCHECK);
- pMenu->CheckItem(nMenuIndex, rItem.mbIsCurrentDeck);
- pMenu->EnableItem(nMenuIndex, rItem.mbIsEnabled && rItem.mbIsActive);
+ OString sIdent("select" + OString::number(nIndex));
+ rMenu.insert(nIndex, OUString::fromUtf8(sIdent), rItem.msDisplayName, nullptr, nullptr, TRISTATE_FALSE);
+ rMenu.set_active(sIdent, rItem.mbIsCurrentDeck);
+ rMenu.set_sensitive(sIdent, rItem.mbIsEnabled && rItem.mbIsActive);
if (!comphelper::LibreOfficeKit::isActive())
{
- const sal_Int32 nSubMenuIndex(nIndex + MID_FIRST_HIDE);
if (rItem.mbIsCurrentDeck)
{
// Don't allow the currently visible deck to be disabled.
- pCustomizationMenu->InsertItem(nSubMenuIndex, rItem.msDisplayName,
- MenuItemBits::RADIOCHECK);
- pCustomizationMenu->CheckItem(nSubMenuIndex);
+ OString sSubIdent("nocustomize" + OString::number(nIndex));
+ rCustomizationMenu.insert(nIndex, OUString::fromUtf8(sSubIdent), rItem.msDisplayName, nullptr, nullptr, TRISTATE_FALSE);
+ rCustomizationMenu.set_active(sSubIdent, true);
}
else
{
- pCustomizationMenu->InsertItem(nSubMenuIndex, rItem.msDisplayName,
- MenuItemBits::CHECKABLE);
- pCustomizationMenu->CheckItem(nSubMenuIndex, rItem.mbIsEnabled && rItem.mbIsActive);
+ OString sSubIdent("customize" + OString::number(nIndex));
+ rCustomizationMenu.insert(nIndex, OUString::fromUtf8(sSubIdent), rItem.msDisplayName, nullptr, nullptr, TRISTATE_TRUE);
+ rCustomizationMenu.set_active(sSubIdent, rItem.mbIsEnabled && rItem.mbIsActive);
}
}
++nIndex;
}
- pMenu->InsertSeparator();
-
+ bool bHideLock = true;
+ bool bHideUnLock = true;
// LOK doesn't support docked/undocked; Sidebar is floating but rendered docked in browser.
if (!comphelper::LibreOfficeKit::isActive())
{
// Add entry for docking or un-docking the tool panel.
if (mpParentWindow->IsFloatingMode())
- {
- pMenu->InsertItem(MID_LOCK_TASK_PANEL, SfxResId(STR_SFX_DOCK));
- pMenu->SetAccelKey(MID_LOCK_TASK_PANEL, vcl::KeyCode(KEY_F10, true, true, false, false));
- }
+ bHideLock = false;
else
- {
- pMenu->InsertItem(MID_UNLOCK_TASK_PANEL, SfxResId(STR_SFX_UNDOCK));
- pMenu->SetAccelKey(MID_UNLOCK_TASK_PANEL, vcl::KeyCode(KEY_F10, true, true, false, false));
- }
+ bHideUnLock = false;
}
-
- pMenu->InsertItem(MID_HIDE_SIDEBAR, SfxResId(SFX_STR_SIDEBAR_HIDE_SIDEBAR));
+ rMenu.set_visible("locktaskpanel", !bHideLock);
+ rMenu.set_visible("unlocktaskpanel", !bHideUnLock);
// No Restore or Customize options for LoKit.
- if (!comphelper::LibreOfficeKit::isActive())
- {
- pCustomizationMenu->InsertSeparator();
- pCustomizationMenu->InsertItem(MID_RESTORE_DEFAULT, SfxResId(SFX_STR_SIDEBAR_RESTORE));
-
- pMenu->InsertItem(MID_CUSTOMIZATION, SfxResId(SFX_STR_SIDEBAR_CUSTOMIZATION));
- pMenu->SetPopupMenu(MID_CUSTOMIZATION, pCustomizationMenu);
- }
-
- pMenu->RemoveDisabledEntries(false);
-
- return pMenu;
+ rMenu.set_visible("customization", !comphelper::LibreOfficeKit::isActive());
}
-IMPL_LINK(SidebarController, OnMenuItemSelected, Menu*, pMenu, bool)
+IMPL_LINK(SidebarController, OnMenuItemSelected, const OString&, rCurItemId, void)
{
- if (pMenu == nullptr)
+ if (rCurItemId == "unlocktaskpanel")
{
- OSL_ENSURE(pMenu!=nullptr, "sfx2::sidebar::SidebarController::OnMenuItemSelected: illegal menu!");
- return false;
+ mpParentWindow->SetFloatingMode(true);
+ if (mpParentWindow->IsFloatingMode())
+ mpParentWindow->ToTop(ToTopFlags::GrabFocusOnly);
}
-
- pMenu->Deactivate();
- const sal_Int32 nIndex (pMenu->GetCurItemId());
- switch (nIndex)
+ else if (rCurItemId == "locktaskpanel")
{
- case MID_UNLOCK_TASK_PANEL:
- mpParentWindow->SetFloatingMode(true);
- if (mpParentWindow->IsFloatingMode())
- mpParentWindow->ToTop(ToTopFlags::GrabFocusOnly);
- break;
-
- case MID_LOCK_TASK_PANEL:
- mpParentWindow->SetFloatingMode(false);
- break;
-
- case MID_RESTORE_DEFAULT:
- mpTabBar->RestoreHideFlags();
- break;
-
- case MID_HIDE_SIDEBAR:
+ mpParentWindow->SetFloatingMode(false);
+ }
+ else if (rCurItemId == "hidesidebar")
+ {
+ if (!comphelper::LibreOfficeKit::isActive())
{
- if (!comphelper::LibreOfficeKit::isActive())
- {
- const util::URL aURL(Tools::GetURL(".uno:Sidebar"));
- Reference<frame::XDispatch> xDispatch(Tools::GetDispatch(mxFrame, aURL));
- if (xDispatch.is())
- xDispatch->dispatch(aURL, Sequence<beans::PropertyValue>());
- }
- else
- {
- // In LOK we don't really destroy the sidebar when "closing";
- // we simply hide it. This is because recreating it is problematic
- // See notes in SidebarDockingWindow::NotifyResize().
- RequestCloseDeck();
- }
- break;
+ const util::URL aURL(Tools::GetURL(".uno:Sidebar"));
+ Reference<frame::XDispatch> xDispatch(Tools::GetDispatch(mxFrame, aURL));
+ if (xDispatch.is())
+ xDispatch->dispatch(aURL, Sequence<beans::PropertyValue>());
+ }
+ else
+ {
+ // In LOK we don't really destroy the sidebar when "closing";
+ // we simply hide it. This is because recreating it is problematic
+ // See notes in SidebarDockingWindow::NotifyResize().
+ RequestCloseDeck();
}
- default:
+ }
+ else
+ {
+ try
{
- try
+ OString sNumber;
+ if (rCurItemId.startsWith("select", &sNumber))
{
- if (nIndex >= MID_FIRST_PANEL && nIndex<MID_FIRST_HIDE)
- {
- RequestOpenDeck();
- SwitchToDeck(mpTabBar->GetDeckIdForIndex(nIndex - MID_FIRST_PANEL));
- }
- else if (nIndex >=MID_FIRST_HIDE)
- if (pMenu->GetItemBits(nIndex) == MenuItemBits::CHECKABLE)
- {
- mpTabBar->ToggleHideFlag(nIndex-MID_FIRST_HIDE);
-
- // Find the set of decks that could be displayed for the new context.
- ResourceManager::DeckContextDescriptorContainer aDecks;
- mpResourceManager->GetMatchingDecks (
- aDecks,
- GetCurrentContext(),
- IsDocumentReadOnly(),
- mxFrame->getController());
- // Notify the tab bar about the updated set of decks.
- mpTabBar->SetDecks(aDecks);
- mpTabBar->HighlightDeck(mpCurrentDeck->GetId());
- mpTabBar->UpdateFocusManager(maFocusManager);
- }
- mpParentWindow->GrabFocusToDocument();
+ RequestOpenDeck();
+ SwitchToDeck(mpTabBar->GetDeckIdForIndex(sNumber.toInt32()));
}
- catch (RuntimeException&)
+ mpParentWindow->GrabFocusToDocument();
+ }
+ catch (RuntimeException&)
+ {
+ }
+ }
+}
+
+IMPL_LINK(SidebarController, OnSubMenuItemSelected, const OString&, rCurItemId, void)
+{
+ if (rCurItemId == "restoredefault")
+ mpTabBar->RestoreHideFlags();
+ else
+ {
+ try
+ {
+ OString sNumber;
+ if (rCurItemId.startsWith("customize", &sNumber))
{
+ mpTabBar->ToggleHideFlag(sNumber.toInt32());
+
+ // Find the set of decks that could be displayed for the new context.
+ ResourceManager::DeckContextDescriptorContainer aDecks;
+ mpResourceManager->GetMatchingDecks (
+ aDecks,
+ GetCurrentContext(),
+ IsDocumentReadOnly(),
+ mxFrame->getController());
+ // Notify the tab bar about the updated set of decks.
+ mpTabBar->SetDecks(aDecks);
+ mpTabBar->HighlightDeck(mpCurrentDeck->GetId());
+ mpTabBar->UpdateFocusManager(maFocusManager);
}
+ mpParentWindow->GrabFocusToDocument();
+ }
+ catch (RuntimeException&)
+ {
}
- break;
}
-
- return true;
}
+
void SidebarController::RequestCloseDeck()
{
if (comphelper::LibreOfficeKit::isActive() && mpCurrentDeck)
diff --git a/sfx2/source/sidebar/TabBar.cxx b/sfx2/source/sidebar/TabBar.cxx
index 6d95e432fbba..ee6b901c65de 100644
--- a/sfx2/source/sidebar/TabBar.cxx
+++ b/sfx2/source/sidebar/TabBar.cxx
@@ -18,7 +18,6 @@
*/
#include <sfx2/sidebar/TabBar.hxx>
-#include <sidebar/ControlFactory.hxx>
#include <sidebar/DeckDescriptor.hxx>
#include <sfx2/sidebar/Theme.hxx>
#include <sidebar/Tools.hxx>
@@ -30,10 +29,8 @@
#include <comphelper/processfactory.hxx>
#include <o3tl/safeint.hxx>
-#include <vcl/button.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
-#include <vcl/image.hxx>
#include <vcl/svapp.hxx>
#include <tools/svborder.hxx>
#include <svtools/acceleratorexecute.hxx>
@@ -41,6 +38,8 @@
using namespace css;
using namespace css::uno;
+static int gDefaultWidth;
+
namespace sfx2::sidebar {
TabBar::TabBar(vcl::Window* pParentWindow,
@@ -49,21 +48,30 @@ TabBar::TabBar(vcl::Window* pParentWindow,
const PopupMenuProvider& rPopupMenuProvider,
SidebarController* rParentSidebarController
)
- : Window(pParentWindow, WB_DIALOGCONTROL),
- mxFrame(rxFrame),
- mpMenuButton(ControlFactory::CreateMenuButton(this)),
- maItems(),
- maDeckActivationFunctor(rDeckActivationFunctor),
- maPopupMenuProvider(rPopupMenuProvider),
- pParentSidebarController(rParentSidebarController)
+ : InterimItemWindow(pParentWindow, "sfx/ui/tabbar.ui", "TabBar")
+ , mxFrame(rxFrame)
+ , mxAuxBuilder(Application::CreateBuilder(m_xContainer.get(), "sfx/ui/tabbarcontents.ui"))
+ , mxTempToplevel(mxAuxBuilder->weld_container("toplevel"))
+ , mxContents(mxAuxBuilder->weld_widget("TabBarContents"))
+ , mxMenuButton(mxAuxBuilder->weld_menu_button("menubutton"))
+ , mxMainMenu(mxAuxBuilder->weld_menu("mainmenu"))
+ , mxSubMenu(mxAuxBuilder->weld_menu("submenu"))
+ , mxMeasureBox(mxAuxBuilder->weld_widget("measure"))
+ , maItems()
+ , maDeckActivationFunctor(rDeckActivationFunctor)
+ , maPopupMenuProvider(rPopupMenuProvider)
+ , pParentSidebarController(rParentSidebarController)
{
+ mxTempToplevel->move(mxContents.get(), m_xContainer.get());
+
+ gDefaultWidth = m_xContainer->get_preferred_size().Width();
+
+ // we have this widget just so we can measure best width for static TabBar::GetDefaultWidth
+ mxMeasureBox->hide();
SetBackground(Wallpaper(Theme::GetColor(Theme::Color_TabBarBackground)));
- mpMenuButton->SetModeImage(Theme::GetImage(Theme::Image_TabBarMenu));
- mpMenuButton->SetClickHdl(LINK(this, TabBar, OnToolboxClicked));
- mpMenuButton->SetQuickHelpText(SfxResId(SFX_STR_SIDEBAR_SETTINGS));
- Layout();
+ mxMenuButton->connect_toggled(LINK(this, TabBar, OnToolboxClicked));
#ifdef DEBUG
SetText(OUString("TabBar"));
@@ -77,16 +85,19 @@ TabBar::~TabBar()
void TabBar::dispose()
{
- for (auto & item : maItems)
- item.mpButton.disposeAndClear();
+ m_xContainer->move(mxContents.get(), mxTempToplevel.get());
maItems.clear();
- mpMenuButton.disposeAndClear();
- vcl::Window::dispose();
+ mxMeasureBox.reset();
+ mxSubMenu.reset();
+ mxMainMenu.reset();
+ mxMenuButton.reset();
+ mxAuxBuilder.reset();
+ InterimItemWindow::dispose();
}
void TabBar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rUpdateArea)
{
- Window::Paint(rRenderContext, rUpdateArea);
+ InterimItemWindow::Paint(rRenderContext, rUpdateArea);
const sal_Int32 nHorizontalPadding(Theme::GetInteger(Theme::Int_TabMenuSeparatorPadding));
rRenderContext.SetLineColor(Theme::GetColor(Theme::Color_TabMenuSeparator));
@@ -96,23 +107,19 @@ void TabBar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& r
sal_Int32 TabBar::GetDefaultWidth()
{
- return Theme::GetInteger(Theme::Int_TabItemWidth)
- + Theme::GetInteger(Theme::Int_TabBarLeftPadding)
- + Theme::GetInteger(Theme::Int_TabBarRightPadding);
+ if (!gDefaultWidth)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "sfx/ui/tabbarcontents.ui"));
+ std::unique_ptr<weld::Widget> xContainer(xBuilder->weld_widget("TabBarContents"));
+ gDefaultWidth = xContainer->get_preferred_size().Width();
+ }
+ return gDefaultWidth;
}
void TabBar::SetDecks(const ResourceManager::DeckContextDescriptorContainer& rDecks)
{
// Remove the current buttons.
- {
- for (auto & item : maItems)
- {
- item.mpButton.disposeAndClear();
- }
- maItems.clear();
- }
- maItems.resize(rDecks.size());
- sal_Int32 nIndex (0);
+ maItems.clear();
for (auto const& deck : rDecks)
{
std::shared_ptr<DeckDescriptor> xDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(deck.msId);
@@ -122,110 +129,50 @@ void TabBar::SetDecks(const ResourceManager::DeckContextDescriptorContainer& rDe
continue;
}
- Item& rItem (maItems[nIndex++]);
- rItem.msDeckId = xDescriptor->msId;
- rItem.mpButton.disposeAndClear();
- rItem.mpButton = CreateTabItem(*xDescriptor);
- rItem.mpButton->SetClickHdl(LINK(&rItem, TabBar::Item, HandleClick));
- rItem.maDeckActivationFunctor = maDeckActivationFunctor;
- rItem.mbIsHidden = ! xDescriptor->mbIsEnabled;
- rItem.mbIsHiddenByDefault = rItem.mbIsHidden; // the default is the state while creating
+ maItems.emplace_back(std::make_unique<Item>(*this));
+ auto& xItem(maItems.back());
+ xItem->msDeckId = xDescriptor->msId;
+ CreateTabItem(*xItem->mxButton, *xDescriptor);
+ xItem->mxButton->connect_clicked(LINK(xItem.get(), TabBar::Item, HandleClick));
+ xItem->maDeckActivationFunctor = maDeckActivationFunctor;
+ xItem->mbIsHidden = !xDescriptor->mbIsEnabled;
+ xItem->mbIsHiddenByDefault = xItem->mbIsHidden; // the default is the state while creating
- rItem.mpButton->Enable(deck.mbIsEnabled);
+ xItem->mxButton->set_sensitive(deck.mbIsEnabled);
}
UpdateButtonIcons();
- Layout();
}
void TabBar::UpdateButtonIcons()
{
- Image aImage = Theme::GetImage(Theme::Image_TabBarMenu);
- mpMenuButton->SetModeImage(aImage);
-
- for (auto const& item : maItems)
- {
- std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(item.msDeckId);
-
- if (xDeckDescriptor)
- {
- aImage = Image(GetItemImage(*xDeckDescriptor));
- item.mpButton->SetModeImage(aImage);
- }
- }
-
- Invalidate();
-}
-
-void TabBar::Layout()
-{
- const SvBorder aPadding (
- Theme::GetInteger(Theme::Int_TabBarLeftPadding),
- Theme::GetInteger(Theme::Int_TabBarTopPadding),
- Theme::GetInteger(Theme::Int_TabBarRightPadding),
- Theme::GetInteger(Theme::Int_TabBarBottomPadding));
- sal_Int32 nX (aPadding.Top());
- sal_Int32 nY (aPadding.Left());
- const Size aTabItemSize (
- Theme::GetInteger(Theme::Int_TabItemWidth) * GetDPIScaleFactor(),
- Theme::GetInteger(Theme::Int_TabItemHeight) * GetDPIScaleFactor());
-
- // Place the menu button and the separator.
- if (mpMenuButton != nullptr)
- {
- mpMenuButton->SetPosSizePixel(
- Point(nX,nY),
- aTabItemSize);
- mpMenuButton->Show();
- nY += mpMenuButton->GetSizePixel().Height() + 1 + Theme::GetInteger(Theme::Int_TabMenuPadding);
- mnMenuSeparatorY = nY - Theme::GetInteger(Theme::Int_TabMenuPadding)/2 - 1;
- }
-
- // Place the deck selection buttons.
for (auto const& item : maItems)
{
- Button& rButton (*item.mpButton);
- rButton.Show( ! item.mbIsHidden);
-
- if (item.mbIsHidden)
+ std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(item->msDeckId);
+ if (!xDeckDescriptor)
continue;
-
- // Place and size the icon.
- rButton.SetPosSizePixel(
- Point(nX,nY),
- aTabItemSize);
- rButton.Show();
-
- nY += rButton.GetSizePixel().Height() + 1 + aPadding.Bottom();
+ item->mxButton->set_item_image("toggle", GetItemImage(*xDeckDescriptor));
}
- Invalidate();
}
-void TabBar::HighlightDeck (const OUString& rsDeckId)
+void TabBar::HighlightDeck(const OUString& rsDeckId)
{
for (auto const& item : maItems)
- {
- if (item.msDeckId == rsDeckId)
- item.mpButton->Check();
- else
- item.mpButton->Check(false);
- }
+ item->mxButton->set_item_active("toggle", item->msDeckId == rsDeckId);
}
-void TabBar::RemoveDeckHighlight ()
+void TabBar::RemoveDeckHighlight()
{
for (auto const& item : maItems)
- {
- item.mpButton->Check(false);
- }
+ item->mxButton->set_item_active("toggle", false);
}
-void TabBar::DataChanged (const DataChangedEvent& rDataChangedEvent)
+void TabBar::DataChanged(const DataChangedEvent& rDataChangedEvent)
{
SetBackground(Theme::GetColor(Theme::Color_TabBarBackground));
UpdateButtonIcons();
- Window::DataChanged(rDataChangedEvent);
+ InterimItemWindow::DataChanged(rDataChangedEvent);
}
bool TabBar::EventNotify(NotifyEvent& rEvent)
@@ -242,7 +189,7 @@ bool TabBar::EventNotify(NotifyEvent& rEvent)
const OUString aCommand(mpAccel->findCommand(svt::AcceleratorExecute::st_VCLKey2AWTKey(rKeyCode)));
if (".uno:Sidebar" == aCommand ||
(rKeyCode.IsMod1() && rKeyCode.IsShift() && rKeyCode.GetCode() == KEY_F10))
- return vcl::Window::EventNotify(rEvent);
+ return InterimItemWindow::EventNotify(rEvent);
return true;
}
else if(MouseNotifyEvent::COMMAND == nType)
@@ -254,7 +201,7 @@ bool TabBar::EventNotify(NotifyEvent& rEvent)
if(!pData->GetModifier() && (pData->GetMode() == CommandWheelMode::SCROLL))
{
auto pItem = std::find_if(maItems.begin(), maItems.end(),
- [] (Item const& rItem) { return rItem.mpButton->IsChecked(); });
+ [] (const auto& item) { return item->mxButton->get_item_active("toggle"); });
if(pItem == maItems.end())
return true;
if(pData->GetNotchDelta()<0)
@@ -271,7 +218,7 @@ bool TabBar::EventNotify(NotifyEvent& rEvent)
}
try
{
- pItem->maDeckActivationFunctor(pItem->msDeckId);
+ (*pItem)->maDeckActivationFunctor((*pItem)->msDeckId);
}
catch(const css::uno::Exception&) {};
return true;
@@ -281,14 +228,11 @@ bool TabBar::EventNotify(NotifyEvent& rEvent)
return false;
}
-VclPtr<RadioButton> TabBar::CreateTabItem(const DeckDescriptor& rDeckDescriptor)
+void TabBar::CreateTabItem(weld::Toolbar& rItem, const DeckDescriptor& rDeckDescriptor)
{
- VclPtr<RadioButton> pItem = ControlFactory::CreateTabItem(this);
- pItem->SetAccessibleName(rDeckDescriptor.msTitle);
- pItem->SetAccessibleDescription(rDeckDescriptor.msHelpText);
- pItem->SetHelpText(rDeckDescriptor.msHelpText);
- pItem->SetQuickHelpText(rDeckDescriptor.msHelpText);
- return pItem;
+ rItem.set_accessible_name(rDeckDescriptor.msTitle);
+ rItem.set_accessible_description(rDeckDescriptor.msHelpText);
+ rItem.set_tooltip_text(rDeckDescriptor.msHelpText);
}
css::uno::Reference<css::graphic::XGraphic> TabBar::GetItemImage(const DeckDescriptor& rDeckDescriptor) const
@@ -299,10 +243,22 @@ css::uno::Reference<css::graphic::XGraphic> TabBar::GetItemImage(const DeckDescr
mxFrame);
}
-IMPL_LINK_NOARG(TabBar::Item, HandleClick, Button*, void)
+TabBar::Item::Item(TabBar& rTabBar)
+ : mrTabBar(rTabBar)
+ , mxBuilder(Application::CreateBuilder(rTabBar.GetContainer(), "sfx/ui/tabbutton.ui"))
+ , mxButton(mxBuilder->weld_toolbar("button"))
{
- vcl::Window* pFocusWin = Application::GetFocusWindow();
- pFocusWin->GrabFocusToDocument();
+}
+
+TabBar::Item::~Item()
+{
+ mrTabBar.GetContainer()->move(mxButton.get(), nullptr);
+}
+
+
+IMPL_LINK_NOARG(TabBar::Item, HandleClick, const OString&, void)
+{
+ mrTabBar.GrabFocusToDocument();
try
{
maDeckActivationFunctor(msDeckId);
@@ -315,7 +271,7 @@ OUString const & TabBar::GetDeckIdForIndex (const sal_Int32 nIndex) const
{
if (nIndex<0 || o3tl::make_unsigned(nIndex)>=maItems.size())
throw RuntimeException();
- return maItems[nIndex].msDeckId;
+ return maItems[nIndex]->msDeckId;
}
void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
@@ -323,12 +279,12 @@ void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
if (nIndex<0 || o3tl::make_unsigned(nIndex) >= maItems.size())
throw RuntimeException();
- maItems[nIndex].mbIsHidden = ! maItems[nIndex].mbIsHidden;
+ maItems[nIndex]->mbIsHidden = ! maItems[nIndex]->mbIsHidden;
- std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(maItems[nIndex].msDeckId);
+ std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(maItems[nIndex]->msDeckId);
if (xDeckDescriptor)
{
- xDeckDescriptor->mbIsEnabled = ! maItems[nIndex].mbIsHidden;
+ xDeckDescriptor->mbIsEnabled = ! maItems[nIndex]->mbIsHidden;
Context aContext;
aContext.msApplication = pParentSidebarController->GetCurrentContext().msApplication;
@@ -338,77 +294,76 @@ void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
xDeckDescriptor->maContextList.ToggleVisibilityForContext(
aContext, xDeckDescriptor->mbIsEnabled );
}
-
- Layout();
}
void TabBar::RestoreHideFlags()
{
- bool bNeedsLayout(false);
for (auto & item : maItems)
{
- if (item.mbIsHidden != item.mbIsHiddenByDefault)
+ if (item->mbIsHidden != item->mbIsHiddenByDefault)
{
- item.mbIsHidden = item.mbIsHiddenByDefault;
- bNeedsLayout = true;
-
- std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(item.msDeckId);
+ item->mbIsHidden = item->mbIsHiddenByDefault;
+ std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(item->msDeckId);
if (xDeckDescriptor)
- xDeckDescriptor->mbIsEnabled = ! item.mbIsHidden;
+ xDeckDescriptor->mbIsEnabled = !item->mbIsHidden;
}
}
- if (bNeedsLayout)
- Layout();
}
void TabBar::UpdateFocusManager(FocusManager& rFocusManager)
{
- std::vector<Button*> aButtons;
+ std::vector<weld::Widget*> aButtons;
aButtons.reserve(maItems.size()+1);
-
- aButtons.push_back(mpMenuButton.get());
+ aButtons.push_back(mxMenuButton.get());
for (auto const& item : maItems)
{
- aButtons.push_back(item.mpButton.get());
+ aButtons.push_back(item->mxButton.get());
}
rFocusManager.SetButtons(aButtons);
}
-IMPL_LINK_NOARG(TabBar, OnToolboxClicked, Button*, void)
+IMPL_LINK_NOARG(TabBar, OnToolboxClicked, weld::ToggleButton&, void)
{
- if (!mpMenuButton)
+ if (!mxMenuButton->get_active())
return;
std::vector<DeckMenuData> aMenuData;
for (auto const& item : maItems)
{
- std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(item.msDeckId);
+ std::shared_ptr<DeckDescriptor> xDeckDescriptor = pParentSidebarController->GetResourceManager()->GetDeckDescriptor(item->msDeckId);
- if (xDeckDescriptor)
- {
- DeckMenuData aData;
- aData.msDisplayName = xDeckDescriptor->msTitle;
- aData.mbIsCurrentDeck = item.mpButton->IsChecked();
- aData.mbIsActive = !item.mbIsHidden;
- aData.mbIsEnabled = item.mpButton->IsEnabled();
+ if (!xDeckDescriptor)
+ continue;
- aMenuData.push_back(aData);
- }
+ DeckMenuData aData;
+ aData.msDisplayName = xDeckDescriptor->msTitle;
+ aData.mbIsCurrentDeck = item->mxButton->get_item_active("toggle");
+ aData.mbIsActive = !item->mbIsHidden;
+ aData.mbIsEnabled = item->mxButton->get_sensitive();
+ aMenuData.push_back(aData);
+ }
+
+ for (int i = mxMainMenu->n_children() - 1; i >= 0; --i)
+ {
+ OString sIdent = mxMainMenu->get_id(i);
+ if (sIdent.startsWith("select"))
+ mxMainMenu->remove(sIdent);
+ }
+ for (int i = mxSubMenu->n_children() - 1; i >= 0; --i)
+ {
+ OString sIdent = mxSubMenu->get_id(i);
+ if (sIdent.indexOf("customize") != -1)
+ mxSubMenu->remove(sIdent);
}
- maPopupMenuProvider(
- tools::Rectangle(
- mpMenuButton->GetPosPixel(),
- mpMenuButton->GetSizePixel()),
- aMenuData);
- mpMenuButton->Check(false);
+ maPopupMenuProvider(*mxMainMenu, *mxSubMenu, aMenuData);
}
void TabBar::EnableMenuButton(const bool bEnable)
{
- mpMenuButton->Enable(bEnable);
+ mxMenuButton->set_sensitive(bEnable);
}
} // end of namespace sfx2::sidebar
diff --git a/sfx2/source/sidebar/TabItem.cxx b/sfx2/source/sidebar/TabItem.cxx
deleted file mode 100644
index c6cfa80fd2d6..000000000000
--- a/sfx2/source/sidebar/TabItem.cxx
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- 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 <sidebar/TabItem.hxx>
-
-#include <sidebar/DrawHelper.hxx>
-
-#include <sfx2/sidebar/Theme.hxx>
-#include <vcl/event.hxx>
-
-using namespace css;
-using namespace css::uno;
-
-namespace sfx2::sidebar {
-
-TabItem::TabItem (vcl::Window* pParentWindow)
- : RadioButton(pParentWindow, false, 0)
- , mbIsLeftButtonDown(false)
-{
- SetStyle(GetStyle() | WB_TABSTOP | WB_DIALOGCONTROL | WB_NOPOINTERFOCUS);
- SetBackground(Theme::GetColor(Theme::Color_TabBarBackground));
-#ifdef DEBUG
- SetText(OUString("TabItem"));
-#endif
-}
-
-void TabItem::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*UpdateArea*/)
-{
- const bool bIsSelected (IsChecked());
- const bool bIsHighlighted (IsMouseOver() || HasFocus());
- DrawHelper::DrawRoundedRectangle(
- rRenderContext,
- tools::Rectangle(Point(0,0), GetSizePixel()),
- Theme::GetInteger(Theme::Int_ButtonCornerRadius),
- bIsHighlighted||bIsSelected
- ? Theme::GetColor(Theme::Color_TabItemBorder)
- : COL_TRANSPARENT,
- bIsHighlighted
- ? Theme::GetColor(Theme::Color_TabItemBackgroundHighlight)
- : Theme::GetColor(Theme::Color_TabItemBackgroundNormal));
-
- const Image aIcon(Button::GetModeImage());
- const Size aIconSize (aIcon.GetSizePixel());
- const Point aIconLocation((GetSizePixel().Width() - aIconSize.Width()) / 2,
- (GetSizePixel().Height() - aIconSize.Height()) / 2);
- rRenderContext.DrawImage(aIconLocation, aIcon, IsEnabled() ? DrawImageFlags::NONE : DrawImageFlags::Disable);
-}
-
-void TabItem::MouseMove(const MouseEvent& rEvent)
-{
- if (rEvent.IsEnterWindow() || rEvent.IsLeaveWindow())
- Invalidate();
- RadioButton::MouseMove(rEvent);
-}
-
-void TabItem::MouseButtonDown(const MouseEvent& rMouseEvent)
-{
- if (rMouseEvent.IsLeft())
- {
- mbIsLeftButtonDown = true;
- CaptureMouse();
- Invalidate();
- }
-}
-
-void TabItem::MouseButtonUp(const MouseEvent& rMouseEvent)
-{
- if (IsMouseCaptured())
- ReleaseMouse();
-
- if (rMouseEvent.IsLeft())
- {
- if (mbIsLeftButtonDown)
- {
- Check();
- Click();
- vcl::Window* pParent = GetParent();
- if (pParent)
- pParent->Invalidate();
- }
- }
-
- if (mbIsLeftButtonDown)
- {
- mbIsLeftButtonDown = false;
- Invalidate();
- }
-}
-
-} // end of namespace sfx2::sidebar
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/sidebar/Theme.cxx b/sfx2/source/sidebar/Theme.cxx
index 66294a5cd9a3..063572b5c97e 100644
--- a/sfx2/source/sidebar/Theme.cxx
+++ b/sfx2/source/sidebar/Theme.cxx
@@ -179,18 +179,6 @@ void Theme::UpdateTheme()
setPropertyValue(
maPropertyIdToNameMap[Color_TabBarBackground],
Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
- setPropertyValue(
- maPropertyIdToNameMap[Int_TabBarLeftPadding],
- Any(sal_Int32(2)));
- setPropertyValue(
- maPropertyIdToNameMap[Int_TabBarTopPadding],
- Any(sal_Int32(2)));
- setPropertyValue(
- maPropertyIdToNameMap[Int_TabBarRightPadding],
- Any(sal_Int32(2)));
- setPropertyValue(
- maPropertyIdToNameMap[Int_TabBarBottomPadding],
- Any(sal_Int32(2)));
setPropertyValue(
maPropertyIdToNameMap[Int_TabMenuPadding],
@@ -203,21 +191,8 @@ void Theme::UpdateTheme()
Any(sal_Int32(3)));
setPropertyValue(
- maPropertyIdToNameMap[Int_TabItemWidth],
- Any(sal_Int32(32)));
- setPropertyValue(
- maPropertyIdToNameMap[Int_TabItemHeight],
- Any(sal_Int32(32)));
- setPropertyValue(
- maPropertyIdToNameMap[Color_TabItemBorder],
- Any(sal_Int32(rStyle.GetActiveBorderColor().GetRGBColor())));
-
- setPropertyValue(
maPropertyIdToNameMap[Color_DropDownBackground],
Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
- setPropertyValue(
- maPropertyIdToNameMap[Color_DropDownBorder],
- Any(sal_Int32(rStyle.GetActiveBorderColor().GetRGBColor())));
setPropertyValue(
maPropertyIdToNameMap[Color_Highlight],
@@ -227,13 +202,6 @@ void Theme::UpdateTheme()
Any(sal_Int32(rStyle.GetHighlightTextColor().GetRGBColor())));
setPropertyValue(
- maPropertyIdToNameMap[Color_TabItemBackgroundNormal],
- Any(sal_Int32(COL_TRANSPARENT)));
- setPropertyValue(
- maPropertyIdToNameMap[Color_TabItemBackgroundHighlight],
- Any(sal_Int32(rStyle.GetActiveTabColor().GetRGBColor())));
-
- setPropertyValue(
maPropertyIdToNameMap[Color_HorizontalBorder],
Any(sal_Int32(aBorderColor.GetRGBColor())));
@@ -241,9 +209,6 @@ void Theme::UpdateTheme()
maPropertyIdToNameMap[Color_VerticalBorder],
Any(sal_Int32(aBorderColor.GetRGBColor())));
setPropertyValue(
- maPropertyIdToNameMap[Image_TabBarMenu],
- Any(OUString("private:graphicrepository/sfx2/res/symphony/open_more.png")));
- setPropertyValue(
maPropertyIdToNameMap[Image_CloseIndicator],
Any(OUString("private:graphicrepository/cmd/lc_decrementlevel.png")));
}
@@ -537,9 +502,6 @@ void Theme::SetupPropertyMaps()
maIntegers.resize(Int_Bool_ - Color_Int_ - 1);
maBooleans.resize(Post_Bool_ - Int_Bool_ - 1);
- maPropertyNameToIdMap["Image_TabBarMenu"]=Image_TabBarMenu;
- maPropertyIdToNameMap[Image_TabBarMenu]="Image_TabBarMenu";
-
maPropertyNameToIdMap["Image_CloseIndicator"]=Image_CloseIndicator;
maPropertyIdToNameMap[Image_CloseIndicator]="Image_CloseIndicator";
@@ -553,12 +515,6 @@ void Theme::SetupPropertyMaps()
maPropertyNameToIdMap["Color_TabMenuSeparator"]=Color_TabMenuSeparator;
maPropertyIdToNameMap[Color_TabMenuSeparator]="Color_TabMenuSeparator";
- maPropertyNameToIdMap["Color_TabItemBorder"]=Color_TabItemBorder;
- maPropertyIdToNameMap[Color_TabItemBorder]="Color_TabItemBorder";
-
- maPropertyNameToIdMap["Color_DropDownBorder"]=Color_DropDownBorder;
- maPropertyIdToNameMap[Color_DropDownBorder]="Color_DropDownBorder";
-
maPropertyNameToIdMap["Color_Highlight"]=Color_Highlight;
maPropertyIdToNameMap[Color_Highlight]="Color_Highlight";
@@ -581,12 +537,6 @@ void Theme::SetupPropertyMaps()
maPropertyNameToIdMap["Color_TabBarBackground"]=Color_TabBarBackground;
maPropertyIdToNameMap[Color_TabBarBackground]="Color_TabBarBackground";
- maPropertyNameToIdMap["Color_TabItemBackgroundNormal"]=Color_TabItemBackgroundNormal;
- maPropertyIdToNameMap[Color_TabItemBackgroundNormal]="Color_TabItemBackgroundNormal";
-
- maPropertyNameToIdMap["Color_TabItemBackgroundHighlight"]=Color_TabItemBackgroundHighlight;
- maPropertyIdToNameMap[Color_TabItemBackgroundHighlight]="Color_TabItemBackgroundHighlight";
-
maPropertyNameToIdMap["Color_HorizontalBorder"]=Color_HorizontalBorder;
maPropertyIdToNameMap[Color_HorizontalBorder]="Color_HorizontalBorder";
@@ -615,12 +565,6 @@ void Theme::SetupPropertyMaps()
maPropertyNameToIdMap["Int_TabMenuSeparatorPadding"]=Int_TabMenuSeparatorPadding;
maPropertyIdToNameMap[Int_TabMenuSeparatorPadding]="Int_TabMenuSeparatorPadding";
- maPropertyNameToIdMap["Int_TabItemWidth"]=Int_TabItemWidth;
- maPropertyIdToNameMap[Int_TabItemWidth]="Int_TabItemWidth";
-
- maPropertyNameToIdMap["Int_TabItemHeight"]=Int_TabItemHeight;
- maPropertyIdToNameMap[Int_TabItemHeight]="Int_TabItemHeight";
-
maPropertyNameToIdMap["Int_DeckLeftPadding"]=Int_DeckLeftPadding;
maPropertyIdToNameMap[Int_DeckLeftPadding]="Int_DeckLeftPadding";
@@ -633,21 +577,6 @@ void Theme::SetupPropertyMaps()
maPropertyNameToIdMap["Int_DeckBottomPadding"]=Int_DeckBottomPadding;
maPropertyIdToNameMap[Int_DeckBottomPadding]="Int_DeckBottomPadding";
- maPropertyNameToIdMap["Int_TabBarLeftPadding"]=Int_TabBarLeftPadding;
- maPropertyIdToNameMap[Int_TabBarLeftPadding]="Int_TabBarLeftPadding";
-
- maPropertyNameToIdMap["Int_TabBarTopPadding"]=Int_TabBarTopPadding;
- maPropertyIdToNameMap[Int_TabBarTopPadding]="Int_TabBarTopPadding";
-
- maPropertyNameToIdMap["Int_TabBarRightPadding"]=Int_TabBarRightPadding;
- maPropertyIdToNameMap[Int_TabBarRightPadding]="Int_TabBarRightPadding";
-
- maPropertyNameToIdMap["Int_TabBarBottomPadding"]=Int_TabBarBottomPadding;
- maPropertyIdToNameMap[Int_TabBarBottomPadding]="Int_TabBarBottomPadding";
-
- maPropertyNameToIdMap["Int_ButtonCornerRadius"]=Int_ButtonCornerRadius;
- maPropertyIdToNameMap[Int_ButtonCornerRadius]="Int_ButtonCornerRadius";
-
maPropertyNameToIdMap["Bool_UseSystemColors"]=Bool_UseSystemColors;
maPropertyIdToNameMap[Bool_UseSystemColors]="Bool_UseSystemColors";
@@ -662,15 +591,12 @@ Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
{
switch(eItem)
{
- case Image_TabBarMenu:
case Image_CloseIndicator:
return PT_Image;
case Color_DeckTitleFont:
case Color_PanelTitleFont:
case Color_TabMenuSeparator:
- case Color_TabItemBorder:
- case Color_DropDownBorder:
case Color_Highlight:
case Color_HighlightText:
case Color_DeckBackground:
@@ -678,8 +604,6 @@ Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
case Color_PanelBackground:
case Color_PanelTitleBarBackground:
case Color_TabBarBackground:
- case Color_TabItemBackgroundNormal:
- case Color_TabItemBackgroundHighlight:
case Color_HorizontalBorder:
case Color_VerticalBorder:
case Color_DropDownBackground:
@@ -691,17 +615,10 @@ Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
case Int_PanelTitleBarHeight:
case Int_TabMenuPadding:
case Int_TabMenuSeparatorPadding:
- case Int_TabItemWidth:
- case Int_TabItemHeight:
case Int_DeckLeftPadding:
case Int_DeckTopPadding:
case Int_DeckRightPadding:
case Int_DeckBottomPadding:
- case Int_TabBarLeftPadding:
- case Int_TabBarTopPadding:
- case Int_TabBarRightPadding:
- case Int_TabBarBottomPadding:
- case Int_ButtonCornerRadius:
return PT_Integer;
case Bool_UseSystemColors:
diff --git a/sfx2/source/view/sfxbasecontroller.cxx b/sfx2/source/view/sfxbasecontroller.cxx
index 23b1aad5c3d0..f07f9b4a1fd0 100644
--- a/sfx2/source/view/sfxbasecontroller.cxx
+++ b/sfx2/source/view/sfxbasecontroller.cxx
@@ -64,7 +64,6 @@
#include <toolkit/helper/convert.hxx>
#include <framework/titlehelper.hxx>
#include <comphelper/processfactory.hxx>
-#include <vcl/button.hxx>
#include <vcl/svapp.hxx>
#include <tools/svborder.hxx>
diff --git a/sfx2/uiconfig/ui/tabbar.ui b/sfx2/uiconfig/ui/tabbar.ui
new file mode 100644
index 000000000000..66e9ad4e9fb9
--- /dev/null
+++ b/sfx2/uiconfig/ui/tabbar.ui
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.1 -->
+<interface domain="sfx">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="TabBar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/sfx2/uiconfig/ui/tabbarcontents.ui b/sfx2/uiconfig/ui/tabbarcontents.ui
new file mode 100644
index 000000000000..34aa02d360df
--- /dev/null
+++ b/sfx2/uiconfig/ui/tabbarcontents.ui
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.1 -->
+<interface domain="sfx">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">sfx2/res/symphony/open_more.png</property>
+ <property name="icon_size">2</property>
+ </object>
+ <object class="GtkMenu" id="mainmenu">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="separator1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="locktaskpanel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="tabbar|locktaskpanel">Dock</property>
+ <property name="use-underline">True</property>
+ <accelerator key="F10" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="unlocktaskpanel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="tabbar|unlocktaskpanel">Undock</property>
+ <property name="use-underline">True</property>
+ <accelerator key="F10" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="hidesidebar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="tabbar|hidesidebar">Close Sidebar</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="customization">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="tabbar|customization">Customization</property>
+ <property name="use-underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="submenu">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="seperator2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="restoredefault">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="tabbar|restoredefault">Restore Default</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkWindow" id="toplevel">
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox" id="TabBarContents">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="border-width">2</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkMenuButton" id="menubutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="tabbar|menubutton|tool_tip">Sidebar Settings</property>
+ <property name="halign">center</property>
+ <property name="margin-bottom">3</property>
+ <property name="image">image6</property>
+ <property name="relief">none</property>
+ <property name="always-show-image">True</property>
+ <property name="popup">mainmenu</property>
+ <property name="use-popover">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="measure">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="orientation">vertical</property>
+ <property name="toolbar-style">icons</property>
+ <property name="show-arrow">False</property>
+ <child>
+ <object class="GtkToggleToolButton" id="toggle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="icon-name">sfx2/res/symphony/open_more.png</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/sfx2/uiconfig/ui/tabbutton.ui b/sfx2/uiconfig/ui/tabbutton.ui
new file mode 100644
index 000000000000..c7cc2228d1a3
--- /dev/null
+++ b/sfx2/uiconfig/ui/tabbutton.ui
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.1 -->
+<interface domain="sfx">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkToolbar" id="button">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="hexpand">False</property>
+ <property name="orientation">vertical</property>
+ <property name="toolbar-style">icons</property>
+ <property name="show-arrow">False</property>
+ <child>
+ <object class="GtkToggleToolButton" id="toggle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index c92305942951..769695e2f178 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -11107,17 +11107,14 @@ sfx2/inc/recentdocsview.hxx
sfx2/inc/sidebar/Accessible.hxx
sfx2/inc/sidebar/ContextChangeBroadcaster.hxx
sfx2/inc/sidebar/ContextList.hxx
-sfx2/inc/sidebar/ControlFactory.hxx
sfx2/inc/sidebar/ControllerFactory.hxx
sfx2/inc/sidebar/DeckDescriptor.hxx
sfx2/inc/sidebar/DeckLayouter.hxx
sfx2/inc/sidebar/DeckTitleBar.hxx
sfx2/inc/sidebar/DrawHelper.hxx
-sfx2/inc/sidebar/MenuButton.hxx
sfx2/inc/sidebar/PanelDescriptor.hxx
sfx2/inc/sidebar/PanelTitleBar.hxx
sfx2/inc/sidebar/SidebarToolBox.hxx
-sfx2/inc/sidebar/TabItem.hxx
sfx2/inc/sidebar/TitleBar.hxx
sfx2/inc/sidebar/Tools.hxx
sfx2/inc/sidebar/UnoDeck.hxx
@@ -11358,7 +11355,6 @@ sfx2/source/sidebar/AsynchronousCall.cxx
sfx2/source/sidebar/Context.cxx
sfx2/source/sidebar/ContextChangeBroadcaster.cxx
sfx2/source/sidebar/ContextList.cxx
-sfx2/source/sidebar/ControlFactory.cxx
sfx2/source/sidebar/ControllerFactory.cxx
sfx2/source/sidebar/ControllerItem.cxx
sfx2/source/sidebar/Deck.cxx
@@ -11369,7 +11365,6 @@ sfx2/source/sidebar/DrawHelper.cxx
sfx2/source/sidebar/FocusManager.cxx
sfx2/source/sidebar/IContextChangeReceiver.cxx
sfx2/source/sidebar/ILayoutableWindow.cxx
-sfx2/source/sidebar/MenuButton.cxx
sfx2/source/sidebar/Panel.cxx
sfx2/source/sidebar/PanelDescriptor.cxx
sfx2/source/sidebar/PanelLayout.cxx
@@ -11383,7 +11378,6 @@ sfx2/source/sidebar/SidebarModelUpdate.cxx
sfx2/source/sidebar/SidebarPanelBase.cxx
sfx2/source/sidebar/SidebarToolBox.cxx
sfx2/source/sidebar/TabBar.cxx
-sfx2/source/sidebar/TabItem.cxx
sfx2/source/sidebar/Theme.cxx
sfx2/source/sidebar/TitleBar.cxx
sfx2/source/sidebar/Tools.cxx
diff --git a/solenv/sanitizers/ui/sfx.suppr b/solenv/sanitizers/ui/sfx.suppr
index 72aeef4dfec8..58a6dc14654f 100644
--- a/solenv/sanitizers/ui/sfx.suppr
+++ b/solenv/sanitizers/ui/sfx.suppr
@@ -36,6 +36,8 @@ sfx2/uiconfig/ui/managestylepage.ui://GtkLabel[@id='desc'] orphan-label
sfx2/uiconfig/ui/password.ui://GtkLabel[@id='minlenft'] orphan-label
sfx2/uiconfig/ui/startcenter.ui://GtkLabel[@id='create_label'] orphan-label
sfx2/uiconfig/ui/startcenter.ui://GtkLabel[@id='althelplabel'] orphan-label
+sfx2/uiconfig/ui/tabbarcontents.ui://GtkToggleToolButton[@id='toggle'] button-no-label
+sfx2/uiconfig/ui/tabbutton.ui://GtkToggleToolButton[@id='toggle'] button-no-label
sfx2/uiconfig/ui/templatepanel.ui://GtkToggleToolButton[@id='1'] button-no-label
sfx2/uiconfig/ui/templatepanel.ui://GtkToggleToolButton[@id='2'] button-no-label
sfx2/uiconfig/ui/templatepanel.ui://GtkToggleToolButton[@id='3'] button-no-label