summaryrefslogtreecommitdiffstats
path: root/include/sfx2/sidebar
diff options
context:
space:
mode:
Diffstat (limited to 'include/sfx2/sidebar')
-rw-r--r--include/sfx2/sidebar/AsynchronousCall.hxx52
-rw-r--r--include/sfx2/sidebar/Context.hxx58
-rw-r--r--include/sfx2/sidebar/ControllerItem.hxx79
-rw-r--r--include/sfx2/sidebar/Deck.hxx89
-rw-r--r--include/sfx2/sidebar/FocusManager.hxx137
-rw-r--r--include/sfx2/sidebar/IContextChangeReceiver.hxx40
-rw-r--r--include/sfx2/sidebar/ILayoutableWindow.hxx40
-rw-r--r--include/sfx2/sidebar/Panel.hxx122
-rw-r--r--include/sfx2/sidebar/PanelLayout.hxx52
-rw-r--r--include/sfx2/sidebar/ResourceManager.hxx132
-rw-r--r--include/sfx2/sidebar/Sidebar.hxx68
-rw-r--r--include/sfx2/sidebar/SidebarChildWindow.hxx46
-rw-r--r--include/sfx2/sidebar/SidebarController.hxx303
-rw-r--r--include/sfx2/sidebar/SidebarDockingWindow.hxx66
-rw-r--r--include/sfx2/sidebar/SidebarModelUpdate.hxx33
-rw-r--r--include/sfx2/sidebar/SidebarPanelBase.hxx102
-rw-r--r--include/sfx2/sidebar/TabBar.hxx138
-rw-r--r--include/sfx2/sidebar/Theme.hxx184
18 files changed, 1741 insertions, 0 deletions
diff --git a/include/sfx2/sidebar/AsynchronousCall.hxx b/include/sfx2/sidebar/AsynchronousCall.hxx
new file mode 100644
index 0000000000..c7e522401d
--- /dev/null
+++ b/include/sfx2/sidebar/AsynchronousCall.hxx
@@ -0,0 +1,52 @@
+/* -*- 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 <tools/link.hxx>
+
+#include <functional>
+
+struct ImplSVEvent;
+
+namespace sfx2::sidebar
+{
+/** A simple asynchronous call via Application::PostUserCall.
+*/
+class AsynchronousCall
+{
+public:
+ typedef ::std::function<void()> Action;
+
+ AsynchronousCall(Action aAction);
+ ~AsynchronousCall();
+
+ void RequestCall();
+ void CancelRequest();
+ void Sync();
+
+private:
+ Action maAction;
+ ImplSVEvent* mnCallId;
+
+ DECL_LINK(HandleUserCall, void*, void);
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/Context.hxx b/include/sfx2/sidebar/Context.hxx
new file mode 100644
index 0000000000..c1ea1f5e4a
--- /dev/null
+++ b/include/sfx2/sidebar/Context.hxx
@@ -0,0 +1,58 @@
+/* -*- 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 <rtl/ustring.hxx>
+
+#include <sfx2/dllapi.h>
+
+namespace sfx2::sidebar
+{
+class SFX2_DLLPUBLIC Context
+{
+public:
+ OUString msApplication;
+ OUString msContext;
+
+ Context();
+ Context(OUString sApplication, OUString sContext);
+
+ /** When two contexts are matched against each other, then
+ application or context name may have the wildcard value 'any'.
+ In order to prefer matches without wildcards over matches with
+ wildcards we introduce an integer evaluation for matches.
+ */
+ const static sal_Int32 NoMatch;
+ const static sal_Int32 OptimalMatch;
+ const static sal_Int32 ApplicationWildcardMatch;
+ const static sal_Int32 ContextWildcardMatch;
+
+ /** Return the numeric value that describes how good the match
+ between two contexts is.
+ Smaller values represent better matches.
+ */
+ sal_Int32 EvaluateMatch(const Context& rOther) const;
+
+ bool operator==(const Context& rOther) const;
+ bool operator!=(const Context& rOther) const;
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/ControllerItem.hxx b/include/sfx2/sidebar/ControllerItem.hxx
new file mode 100644
index 0000000000..a8f82195a4
--- /dev/null
+++ b/include/sfx2/sidebar/ControllerItem.hxx
@@ -0,0 +1,79 @@
+/* -*- 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 <sfx2/ctrlitem.hxx>
+
+namespace com::sun::star::lang { class XComponent; }
+
+
+namespace sfx2::sidebar {
+
+/** The sfx2::sidebar::ControllerItem is a wrapper around the
+ SfxControllerItem that becomes necessary to allow objects (think
+ sidebar panels) to receive state changes without having one
+ SfxControllerItem per supported item as base class (which is not
+ possible in C++ anyway).
+
+ It also gives access to the label and icon of a slot/command.
+*/
+class SFX2_DLLPUBLIC ControllerItem final
+ : public SfxControllerItem
+{
+public:
+ class SFX2_DLLPUBLIC ItemUpdateReceiverInterface
+ {
+ public:
+ virtual void NotifyItemUpdate(
+ const sal_uInt16 nSId,
+ const SfxItemState eState,
+ const SfxPoolItem* pState) = 0;
+ virtual void GetControlState(
+ const sal_uInt16 nSId,
+ boost::property_tree::ptree& rState) = 0;
+ virtual ~ItemUpdateReceiverInterface();
+ };
+
+ /** This is the simpler constructor variant that still exists for
+ compatibility reasons. Note that GetLabel() and GetIcon() will
+ return empty strings/images.
+ */
+ ControllerItem (
+ const sal_uInt16 nId,
+ SfxBindings &rBindings,
+ ItemUpdateReceiverInterface& rItemUpdateReceiver);
+
+ virtual ~ControllerItem() override;
+
+ /** Force the controller item to call its NotifyItemUpdate
+ callback with up-to-date data.
+ */
+ void RequestUpdate();
+
+private:
+
+ virtual void StateChangedAtToolBoxControl (sal_uInt16 nSId, SfxItemState eState, const SfxPoolItem* pState) override;
+ virtual void GetControlState (sal_uInt16 nSId, boost::property_tree::ptree& rState) override;
+
+ ItemUpdateReceiverInterface& mrItemUpdateReceiver;
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/Deck.hxx b/include/sfx2/sidebar/Deck.hxx
new file mode 100644
index 0000000000..215d3d2156
--- /dev/null
+++ b/include/sfx2/sidebar/Deck.hxx
@@ -0,0 +1,89 @@
+/* -*- 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 <sfx2/sidebar/Panel.hxx>
+#include <vcl/InterimItemWindow.hxx>
+#include <vcl/weld.hxx>
+
+namespace sfx2::sidebar
+{
+class DeckDescriptor;
+class DeckTitleBar;
+class SidebarDockingWindow;
+
+/** This is the parent window of the panels.
+ It displays the deck title.
+
+ A deck consists of multiple panels.
+ E.g. Properties, Styles, Navigator.
+*/
+class Deck final : public InterimItemWindow
+{
+public:
+ Deck(const DeckDescriptor& rDeckDescriptor, SidebarDockingWindow* pParentWindow,
+ const std::function<void()>& rCloserAction);
+ virtual ~Deck() override;
+ virtual void dispose() override;
+
+ const OUString& GetId() const { return msId; }
+
+ DeckTitleBar* GetTitleBar() const;
+ tools::Rectangle GetContentArea() const;
+ void ResetPanels(SharedPanelContainer&& rPanels);
+ const SharedPanelContainer& GetPanels() const { return maPanels; }
+
+ std::shared_ptr<Panel> GetPanel(std::u16string_view panelId);
+
+ void RequestLayout();
+ weld::Widget* GetPanelParentWindow();
+
+ /** Try to make the panel completely visible.
+ When the whole panel does not fit then make its top visible
+ and it off at the bottom.
+ */
+ void ShowPanel(const Panel& rPanel);
+
+ virtual void DataChanged(const DataChangedEvent& rEvent) override;
+
+ virtual void DumpAsPropertyTree(tools::JsonWriter&) override;
+
+ sal_Int32 GetMinimalWidth() const { return mnMinimalWidth; }
+
+ static void LOKSendSidebarFullUpdate();
+
+private:
+ void RequestLayoutInternal();
+
+private:
+ const OUString msId;
+ sal_Int32 mnMinimalWidth;
+ sal_Int32 mnScrolledWindowExtraWidth;
+ sal_Int32 mnMinimalHeight;
+ SharedPanelContainer maPanels;
+
+ VclPtr<SidebarDockingWindow> mxParentWindow;
+ std::unique_ptr<DeckTitleBar> mxTitleBar;
+ std::unique_ptr<weld::ScrolledWindow> mxVerticalScrollBar;
+ std::unique_ptr<weld::Box> mxContents;
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/FocusManager.hxx b/include/sfx2/sidebar/FocusManager.hxx
new file mode 100644
index 0000000000..6eaa877b4d
--- /dev/null
+++ b/include/sfx2/sidebar/FocusManager.hxx
@@ -0,0 +1,137 @@
+/* -*- 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 <sfx2/sidebar/Panel.hxx>
+#include <tools/link.hxx>
+#include <vcl/keycod.hxx>
+
+namespace weld {
+class Widget;
+}
+
+namespace sfx2::sidebar {
+
+class DeckTitleBar;
+
+/** Concentrate all focus handling in this class.
+
+ There is one ring of windows that accept the input focus which are
+ cycled through with the arrow keys:
+ - the closer in the deck title (present only when docked)
+ - the panel title bars
+ - the tab bar items
+
+ When the focus is in a panel title then focus travels over
+ - the panel title
+ - the panel closer
+ - the panel content
+
+ Once the focus is in the panel content then focus cycles through
+ all controls inside the panel but not back to the title bar of
+ the panel. Escape places the focus back in the panel title.
+*/
+class FocusManager
+{
+public:
+ FocusManager(std::function<void(const Panel&)> aShowPanelFunctor);
+ ~FocusManager();
+
+ /** Forget all panels and buttons. Remove all window listeners.
+ */
+ void Clear();
+
+ /** Transfer the focus into the sidebar tree of windows. This is
+ typically called from the SidebarChildWindow as result of
+ pressing the F6 key.
+ */
+ void GrabFocus();
+ void GrabFocusPanel();
+
+ void SetDeck(Deck* pDeck);
+ void SetPanels(const SharedPanelContainer& rPanels);
+ void SetButtons(const std::vector<weld::Widget*>& rButtons);
+
+private:
+ VclPtr<Deck> mxDeck;
+ DeckTitleBar* mpDeckTitleBar;
+ SharedPanelContainer maPanels;
+ std::vector<weld::Widget*> maButtons;
+ const std::function<void(const Panel&)> maShowPanelFunctor;
+
+ enum PanelComponent
+ {
+ PC_DeckToolBox,
+ PC_PanelTitle,
+ PC_PanelToolBox,
+ PC_PanelContent,
+ PC_TabBar,
+ PC_None
+ };
+ class FocusLocation
+ {
+ public:
+ PanelComponent meComponent;
+ sal_Int32 mnIndex;
+ FocusLocation(const PanelComponent eComponent, const sal_Int32 nIndex);
+ };
+
+ /** Listen for key events for panels and buttons.
+ */
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+ void ClearPanels();
+ void ClearButtons();
+
+ /** Let the focus manager listen for window events for the given
+ window.
+ */
+ void RegisterWindow(weld::Widget& rWidget);
+ static void UnregisterWindow(weld::Widget& rWidget);
+
+ void FocusDeckTitle();
+ bool IsDeckTitleVisible() const;
+
+ /** Set the focus to the title bar of the panel or, if the
+ title bar is not visible, directly to the panel.
+ @param nPanelIndex
+ Index of the panel to focus.
+ @param bFallbackToDeckTitle
+ When the panel title bar is not visible then The fallback
+ bias defines whether to focus the deck (true) or the panel
+ content (false) will be focused instead.
+ */
+ void FocusPanel(const sal_Int32 nPanelIndex,
+ const bool bFallbackToDeckTitle);
+
+ void FocusPanelContent(const sal_Int32 nPanelIndex);
+ void FocusButton(const sal_Int32 nButtonIndex);
+ void MoveFocusInsidePanel(const FocusLocation& rLocation,
+ const sal_Int32 nDirection);
+
+ bool HandleKeyEvent(const vcl::KeyCode& rKeyCode,
+ const FocusLocation& rLocation);
+
+ FocusLocation GetFocusLocation() const;
+
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/IContextChangeReceiver.hxx b/include/sfx2/sidebar/IContextChangeReceiver.hxx
new file mode 100644
index 0000000000..2667201444
--- /dev/null
+++ b/include/sfx2/sidebar/IContextChangeReceiver.hxx
@@ -0,0 +1,40 @@
+/* -*- 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 <sfx2/dllapi.h>
+
+namespace vcl
+{
+class EnumContext;
+}
+
+namespace sfx2::sidebar
+{
+class SFX2_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") IContextChangeReceiver
+{
+public:
+ virtual ~IContextChangeReceiver();
+
+ virtual void HandleContextChange(const vcl::EnumContext& rContext) = 0;
+};
+
+} // end of namespace ::sd::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/ILayoutableWindow.hxx b/include/sfx2/sidebar/ILayoutableWindow.hxx
new file mode 100644
index 0000000000..d5124a8983
--- /dev/null
+++ b/include/sfx2/sidebar/ILayoutableWindow.hxx
@@ -0,0 +1,40 @@
+/* -*- 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 <sfx2/dllapi.h>
+#include <sal/types.h>
+#include <com/sun/star/ui/LayoutSize.hpp>
+
+namespace sfx2::sidebar
+{
+class SFX2_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") ILayoutableWindow
+{
+public:
+ virtual ~ILayoutableWindow();
+
+ /** Return the preferred height with the constraint, that the
+ window will be set to the given width.
+ */
+ virtual css::ui::LayoutSize GetHeightForWidth(const sal_Int32 nWidth) = 0;
+};
+
+} // end of namespace ::sd::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/Panel.hxx b/include/sfx2/sidebar/Panel.hxx
new file mode 100644
index 0000000000..c04c6a53a1
--- /dev/null
+++ b/include/sfx2/sidebar/Panel.hxx
@@ -0,0 +1,122 @@
+/* -*- 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 <sfx2/dllapi.h>
+#include <vcl/weld.hxx>
+#include <vector>
+
+namespace com::sun::star::frame
+{
+class XFrame;
+}
+namespace com::sun::star::ui
+{
+class XSidebarPanel;
+}
+namespace com::sun::star::ui
+{
+class XUIElement;
+}
+namespace com::sun::star::awt
+{
+class XWindow;
+}
+
+namespace sfx2::sidebar
+{
+class Context;
+class Deck;
+class PanelDescriptor;
+class PanelTitleBar;
+
+/**
+ * Multiple panels form a single deck.
+ * E.g. the Properties deck has panels like Styles, Character, paragraph.
+ */
+class SFX2_DLLPUBLIC Panel final
+{
+public:
+ Panel(const PanelDescriptor& rPanelDescriptor, weld::Widget* pParentWindow,
+ const bool bIsInitiallyExpanded, Deck* pDeck, std::function<Context()> aContextAccess,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame);
+
+ ~Panel();
+
+ PanelTitleBar* GetTitleBar() const;
+ weld::Box* GetContents() const;
+ void Show(bool bShow);
+ bool IsTitleBarOptional() const { return mbIsTitleBarOptional; }
+ void SetUIElement(const css::uno::Reference<css::ui::XUIElement>& rxElement);
+ const css::uno::Reference<css::ui::XSidebarPanel>& GetPanelComponent() const
+ {
+ return mxPanelComponent;
+ }
+ const css::uno::Reference<css::awt::XWindow>& GetElementParentWindow();
+ css::uno::Reference<css::awt::XWindow> GetElementWindow();
+ void SetExpanded(const bool bIsExpanded);
+ bool IsExpanded() const { return mbIsExpanded; }
+ bool HasIdPredicate(std::u16string_view rsId) const;
+ const OUString& GetId() const { return msPanelId; }
+ const OUString& GetTitle() const { return msTitle; }
+ void TriggerDeckLayouting();
+
+ void SetHeightPixel(int nHeight);
+
+ bool get_extents(tools::Rectangle& rExtents) const;
+
+ /// Set whether a panel should be present but invisible / inactive
+ void SetLurkMode(bool bLurk);
+ bool IsLurking() const { return mbLurking; }
+
+ void set_margin_top(int nMargin);
+ void set_margin_bottom(int nMargin);
+ void set_vexpand(bool bExpand);
+
+ weld::Window* GetFrameWeld();
+
+ void DataChanged();
+
+private:
+ std::unique_ptr<weld::Builder> mxBuilder;
+ const OUString msPanelId;
+ const OUString msTitle;
+ const bool mbIsTitleBarOptional;
+ const bool mbWantsAWT;
+ css::uno::Reference<css::ui::XUIElement> mxElement;
+ css::uno::Reference<css::ui::XSidebarPanel> mxPanelComponent;
+ bool mbIsExpanded;
+ bool mbLurking;
+ const std::function<Context()> maContextAccess;
+ const css::uno::Reference<css::frame::XFrame>& mxFrame;
+ weld::Widget* mpParentWindow;
+ VclPtr<Deck> mxDeck;
+ std::unique_ptr<weld::Box> mxContainer;
+ std::unique_ptr<PanelTitleBar> mxTitleBar;
+ std::unique_ptr<weld::Box> mxContents;
+ css::uno::Reference<css::awt::XWindow> mxXWindow;
+
+ DECL_DLLPRIVATE_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void);
+};
+
+typedef std::vector<std::shared_ptr<Panel>> SharedPanelContainer;
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/PanelLayout.hxx b/include/sfx2/sidebar/PanelLayout.hxx
new file mode 100644
index 0000000000..3058c9d514
--- /dev/null
+++ b/include/sfx2/sidebar/PanelLayout.hxx
@@ -0,0 +1,52 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <sfx2/dllapi.h>
+#include <vcl/weld.hxx>
+
+class DataChangedEvent;
+class VclSimpleEvent;
+namespace sfx2 { namespace sidebar { class Panel; } }
+namespace tools { class JsonWriter; }
+
+/// This class is the base for the Widget Layout-based sidebar panels.
+class SFX2_DLLPUBLIC PanelLayout
+{
+protected:
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Container> m_xContainer;
+ sfx2::sidebar::Panel* m_pPanel;
+
+ virtual void DataChanged(const DataChangedEvent& rEvent);
+ virtual void DumpAsPropertyTree(tools::JsonWriter&);
+
+ virtual weld::Window* GetFrameWeld() const;
+
+private:
+ DECL_DLLPRIVATE_LINK(DataChangedEventListener, VclSimpleEvent&, void);
+ DECL_DLLPRIVATE_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void);
+
+public:
+ PanelLayout(weld::Widget* pParent, const OUString& rID, const OUString& rUIXMLDescription);
+
+ void SetPanel(sfx2::sidebar::Panel* pPanel);
+
+ virtual ~PanelLayout();
+
+ Size get_preferred_size() const
+ {
+ return m_xContainer->get_preferred_size();
+ }
+
+ void queue_resize();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/ResourceManager.hxx b/include/sfx2/sidebar/ResourceManager.hxx
new file mode 100644
index 0000000000..9ac1130cc2
--- /dev/null
+++ b/include/sfx2/sidebar/ResourceManager.hxx
@@ -0,0 +1,132 @@
+/* -*- 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 <unotools/confignode.hxx>
+#include <map>
+#include <vector>
+#include <set>
+
+#include <sfx2/dllapi.h>
+
+namespace com::sun::star::frame { class XController; }
+namespace com::sun::star::frame { class XModel; }
+namespace sfx2::sidebar { class DeckDescriptor; }
+namespace sfx2::sidebar { class PanelDescriptor; }
+
+namespace sfx2::sidebar {
+
+class Context;
+class ContextList;
+
+/** Read the content of the Sidebar.xcu file and provide access
+ methods so that the sidebar can easily decide which content panels
+ to display for a certain context.
+*/
+class SFX2_DLLPUBLIC ResourceManager
+{
+public:
+
+ ResourceManager();
+ ~ResourceManager();
+
+ std::shared_ptr<DeckDescriptor> GetDeckDescriptor(std::u16string_view rsDeckId) const;
+ std::shared_ptr<PanelDescriptor> GetPanelDescriptor(std::u16string_view rsPanelId) const;
+
+ void UpdateModel(const css::uno::Reference<css::frame::XModel>& xModel);
+
+ void InitDeckContext(const Context& rContex);
+ void SaveDecksSettings(const Context& rContext);
+ void SaveDeckSettings(const DeckDescriptor* pDeckDesc);
+ void SaveLastActiveDeck(const Context& rContext, const OUString& rActiveDeck);
+
+ void disposeDecks();
+
+ class DeckContextDescriptor
+ {
+ public:
+ OUString msId;
+ bool mbIsEnabled;
+ };
+ typedef std::vector<DeckContextDescriptor> DeckContextDescriptorContainer;
+
+ class PanelContextDescriptor
+ {
+ public:
+ OUString msId;
+ OUString msMenuCommand;
+ bool mbIsInitiallyVisible;
+ bool mbShowForReadOnlyDocuments;
+ };
+ typedef std::vector<PanelContextDescriptor> PanelContextDescriptorContainer;
+
+ const DeckContextDescriptorContainer& GetMatchingDecks(
+ DeckContextDescriptorContainer& rDeckDescriptors,
+ const Context& rContext,
+ const bool bIsDocumentReadOnly,
+ const css::uno::Reference<css::frame::XController>& rxController);
+
+ const PanelContextDescriptorContainer& GetMatchingPanels(
+ PanelContextDescriptorContainer& rPanelDescriptors,
+ const Context& rContext,
+ std::u16string_view rsDeckId,
+ const css::uno::Reference<css::frame::XController>& rxController);
+
+ const OUString& GetLastActiveDeck( const Context& rContext );
+ void SetLastActiveDeck( const Context& rContext, const OUString& rsDeckId );
+
+ /** Remember the expansions state per panel and context.
+ */
+ void StorePanelExpansionState(std::u16string_view rsPanelId,
+ const bool bExpansionState,
+ const Context& rContext);
+
+private:
+
+
+ typedef std::vector<std::shared_ptr<DeckDescriptor>> DeckContainer;
+ DeckContainer maDecks;
+
+ typedef std::vector<std::shared_ptr<PanelDescriptor>> PanelContainer;
+ PanelContainer maPanels;
+ mutable std::set<OUString> maProcessedApplications;
+ std::map<OUString, OUString> maLastActiveDecks;
+
+ void ReadDeckList();
+ void ReadPanelList();
+ void ReadLastActive();
+ static void ReadContextList(const utl::OConfigurationNode& rNode,
+ ContextList& rContextList,
+ const OUString& rsDefaultMenuCommand);
+
+ void ReadLegacyAddons(const css::uno::Reference<css::frame::XController>& rxController);
+ static utl::OConfigurationTreeRoot GetLegacyAddonRootNode(const OUString& rsModuleName);
+ static void GetToolPanelNodeNames(std::vector<OUString>& rMatchingNames,
+ const utl::OConfigurationTreeRoot& aRoot);
+ bool IsDeckEnabled(std::u16string_view rsDeckId,
+ const Context& rContext,
+ const css::uno::Reference<css::frame::XController>& rxController);
+
+ std::shared_ptr<DeckDescriptor> ImplGetDeckDescriptor(std::u16string_view rsDeckId) const;
+ std::shared_ptr<PanelDescriptor> ImplGetPanelDescriptor(std::u16string_view rsPanelId) const;
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/Sidebar.hxx b/include/sfx2/sidebar/Sidebar.hxx
new file mode 100644
index 0000000000..f4d0c1cc9b
--- /dev/null
+++ b/include/sfx2/sidebar/Sidebar.hxx
@@ -0,0 +1,68 @@
+/* -*- 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 <sfx2/dllapi.h>
+#include <sfx2/viewfrm.hxx>
+
+#include <string_view>
+
+namespace com::sun::star::frame { class XFrame; }
+namespace com::sun::star::uno { template <typename > class Reference; }
+
+
+namespace sfx2::sidebar {
+
+/** Accept requests for switching to certain panels or decks.
+*/
+class SFX2_DLLPUBLIC Sidebar
+{
+public:
+ static void ShowDeck(std::u16string_view rsDeckId, SfxViewFrame* pViewFrame,
+ bool bToggle);
+
+ /** Switch to the deck that contains the specified panel and make
+ sure that the panel is visible (expanded and scrolled into the
+ visible area.)
+ Note that most of the work is done asynchronously and that
+ this function probably returns before the requested panel is visible.
+ */
+ static void ShowPanel (
+ std::u16string_view rsPanelId,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame, bool bFocus = false);
+
+ /** Switch to the deck that contains the specified panel and toggle
+ the visibility of the panel (expanded and scrolled into the
+ visible area when visible)
+ Note that most of the work is done asynchronously and that
+ this function probably returns before the requested panel is visible.
+ */
+ static void TogglePanel (
+ std::u16string_view rsPanelId,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame);
+
+ static bool IsPanelVisible(
+ std::u16string_view rsPanelId,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame);
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/SidebarChildWindow.hxx b/include/sfx2/sidebar/SidebarChildWindow.hxx
new file mode 100644
index 0000000000..279aa79b5f
--- /dev/null
+++ b/include/sfx2/sidebar/SidebarChildWindow.hxx
@@ -0,0 +1,46 @@
+/* -*- 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 <sfx2/childwin.hxx>
+
+
+namespace sfx2::sidebar {
+
+/** Outer container of the sidebar window.
+
+ Has to be registered for every application via the
+ RegisterChildWindow() method from the RegisterControllers() method
+ of the applications DLL.
+*/
+class SFX2_DLLPUBLIC SidebarChildWindow final : public SfxChildWindow
+{
+public:
+ SidebarChildWindow(vcl::Window* pParent, sal_uInt16 nId,
+ SfxBindings* pBindings, SfxChildWinInfo* pInfo);
+
+ SFX_DECL_CHILDWINDOW_WITHID(SidebarChildWindow);
+
+ static sal_Int32 GetDefaultWidth(vcl::Window const * pWindow);
+};
+
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/SidebarController.hxx b/include/sfx2/sidebar/SidebarController.hxx
new file mode 100644
index 0000000000..06e092bcee
--- /dev/null
+++ b/include/sfx2/sidebar/SidebarController.hxx
@@ -0,0 +1,303 @@
+/* -*- 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 <memory>
+#include <sal/config.h>
+
+#include <sfx2/sidebar/AsynchronousCall.hxx>
+#include <sfx2/sidebar/Context.hxx>
+#include <sfx2/sidebar/Deck.hxx>
+#include <sfx2/sidebar/FocusManager.hxx>
+#include <sfx2/sidebar/ResourceManager.hxx>
+#include <sfx2/sidebar/TabBar.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/ui/XContextChangeEventListener.hpp>
+#include <com/sun/star/ui/XSidebar.hpp>
+
+#include <optional>
+#include <comphelper/compbase.hxx>
+
+namespace com::sun::star::awt { class XWindow; }
+namespace com::sun::star::frame { class XDispatch; }
+namespace com::sun::star::ui { class XUIElement; }
+
+typedef comphelper::WeakComponentImplHelper <
+ css::ui::XContextChangeEventListener,
+ css::beans::XPropertyChangeListener,
+ css::ui::XSidebar,
+ css::frame::XStatusListener,
+ css::frame::XFrameActionListener
+ > SidebarControllerInterfaceBase;
+
+class SfxSplitWindow;
+class SfxViewShell;
+
+namespace sfx2::sidebar {
+
+class DeckDescriptor;
+class SidebarDockingWindow;
+
+class SFX2_DLLPUBLIC SidebarController final
+ : public SidebarControllerInterfaceBase
+{
+public:
+ static rtl::Reference<SidebarController> create(SidebarDockingWindow* pParentWindow,
+ const SfxViewFrame* pViewFrame);
+ virtual ~SidebarController() override;
+ SidebarController(const SidebarController&) = delete;
+ SidebarController& operator=( const SidebarController& ) = delete;
+
+ /** Return the SidebarController object that is associated with
+ the given XFrame.
+ @return
+ When there is no SidebarController object for the given
+ XFrame then <NULL/> is returned.
+ */
+ static SidebarController* GetSidebarControllerForFrame (
+ const css::uno::Reference<css::frame::XFrame>& rxFrame);
+
+ void registerSidebarForFrame(const css::uno::Reference<css::frame::XController>& xFrame);
+
+ void unregisterSidebarForFrame(const css::uno::Reference<css::frame::XController>& xFrame);
+
+ // ui::XContextChangeEventListener
+ virtual void SAL_CALL notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent) override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEventObject) override;
+
+ // beans::XPropertyChangeListener
+ virtual void SAL_CALL propertyChange (const css::beans::PropertyChangeEvent& rEvent) override;
+
+ // frame::XStatusListener
+ virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent) override;
+
+ // frame::XFrameActionListener
+ virtual void SAL_CALL frameAction (const css::frame::FrameActionEvent& rEvent) override;
+
+ // ui::XSidebar
+ virtual void SAL_CALL requestLayout() override;
+
+ void NotifyResize();
+
+ /** In some situations it is necessary to force an update of the
+ current deck and its panels. One reason is a change of the
+ view scale. Some panels can handle this only when
+ constructed. In this case we have to a context change and
+ also force that all panels are destroyed and created new.
+ */
+ const static sal_Int32 SwitchFlag_NoForce = 0x00;
+ const static sal_Int32 SwitchFlag_ForceSwitch = 0x01;
+ const static sal_Int32 SwitchFlag_ForceNewDeck = 0x02;
+ const static sal_Int32 SwitchFlag_ForceNewPanels = 0x02;
+
+ void OpenThenSwitchToDeck(std::u16string_view rsDeckId);
+ void OpenThenToggleDeck(const OUString& rsDeckId);
+
+ /** Show only the tab bar, not the deck.
+ */
+ void RequestCloseDeck();
+
+ /** Open the deck area and restore the parent window to its old width.
+ */
+ void RequestOpenDeck();
+
+ /** Returns true when the given deck is the currently visible deck
+ */
+ bool IsDeckVisible(std::u16string_view rsDeckId);
+
+ bool IsDeckOpen(const sal_Int32 nIndex = -1);
+
+ FocusManager& GetFocusManager() { return maFocusManager;}
+
+ ResourceManager* GetResourceManager() { return mpResourceManager.get();}
+
+ // std::unique_ptr<ResourceManager> GetResourceManager() { return mpResourceManager;}
+
+ const Context& GetCurrentContext() const { return maCurrentContext;}
+ bool IsDocumentReadOnly (void) const { return mbIsDocumentReadOnly;}
+
+ void SwitchToDeck(std::u16string_view rsDeckId);
+ void SwitchToDefaultDeck();
+ bool WasFloatingDeckClosed() const { return mbFloatingDeckClosed; }
+ void SetFloatingDeckClosed(bool bWasClosed) { mbFloatingDeckClosed = bWasClosed; }
+
+ void CreateDeck(std::u16string_view rDeckId);
+ void CreateDeck(std::u16string_view rDeckId, const Context& rContext, bool bForceCreate = false);
+
+ ResourceManager::DeckContextDescriptorContainer GetMatchingDecks();
+ ResourceManager::PanelContextDescriptorContainer GetMatchingPanels(std::u16string_view rDeckId);
+
+ void notifyDeckTitle(std::u16string_view targetDeckId);
+
+ void updateModel(const css::uno::Reference<css::frame::XModel>& xModel);
+
+ void disposeDecks();
+
+ void FadeIn();
+ void FadeOut();
+
+ tools::Rectangle GetDeckDragArea() const;
+
+ css::uno::Reference<css::frame::XFrame> const & getXFrame() const {return mxFrame;}
+
+ sal_Int32 getMaximumWidth() const { return mnMaximumSidebarWidth; }
+ void setMaximumWidth(sal_Int32 nMaximumWidth) { mnMaximumSidebarWidth = nMaximumWidth; }
+
+ void saveDeckState();
+
+ void SyncUpdate();
+
+ // Used to avoid wrong context update when an embedded object activation is in progress
+ bool hasChartOrMathContextCurrently() const;
+
+ static SidebarController* GetSidebarControllerForView(const SfxViewShell* pViewShell);
+
+private:
+ SidebarController(SidebarDockingWindow* pParentWindow, const SfxViewFrame* pViewFrame);
+
+ VclPtr<Deck> mpCurrentDeck;
+ VclPtr<SidebarDockingWindow> mpParentWindow;
+ const SfxViewFrame* mpViewFrame;
+ css::uno::Reference<css::frame::XFrame> mxFrame;
+ VclPtr<TabBar> mpTabBar;
+ Context maCurrentContext;
+ Context maRequestedContext;
+ css::uno::Reference<css::frame::XController> mxCurrentController;
+ /// Use a combination of SwitchFlag_* as value.
+ sal_Int32 mnRequestedForceFlags;
+ sal_Int32 mnMaximumSidebarWidth;
+ bool mbMinimumSidebarWidth;
+ OUString msCurrentDeckId;
+ AsynchronousCall maPropertyChangeForwarder;
+ AsynchronousCall maContextChangeUpdate;
+ css::uno::Reference<css::beans::XPropertySet> mxThemePropertySet;
+
+ /** Two flags control whether the deck is displayed or if only the
+ tab bar remains visible.
+ The mbIsDeckOpen flag stores the current state while
+ mbIsDeckRequestedOpen stores how this state should be. User
+ actions like clicking on the deck closer affect the
+ mbIsDeckRequestedOpen. Normally both flags have the same
+ value. A document being read-only can prevent the deck from opening.
+ */
+ ::std::optional<bool> mbIsDeckRequestedOpen;
+ ::std::optional<bool> mbIsDeckOpen;
+
+ bool mbFloatingDeckClosed;
+
+ /** Before the deck is closed the sidebar width is saved into this variable,
+ so that it can be restored when the deck is reopened.
+ */
+ sal_Int32 mnSavedSidebarWidth;
+ FocusManager maFocusManager;
+ css::uno::Reference<css::frame::XDispatch> mxReadOnlyModeDispatch;
+ bool mbIsDocumentReadOnly;
+ VclPtr<SfxSplitWindow> mpSplitWindow;
+ /** When the user moves the splitter then we remember the
+ width at that time.
+ */
+ sal_Int32 mnWidthOnSplitterButtonDown;
+ /** Control that is temporarily used as replacement for the deck
+ to indicate that when the current mouse drag operation ends, the
+ sidebar will only show the tab bar.
+ */
+ VclPtr<vcl::Window> mpCloseIndicator;
+
+ DECL_DLLPRIVATE_LINK(WindowEventHandler, VclWindowEvent&, void);
+ /** Make maRequestedContext the current context.
+ */
+ void UpdateConfigurations();
+
+ css::uno::Reference<css::ui::XUIElement> CreateUIElement (
+ const css::uno::Reference<css::awt::XWindow>& rxWindow,
+ const OUString& rsImplementationURL,
+ const bool bWantsCanvas,
+ const Context& rContext);
+
+ void CreatePanels(
+ std::u16string_view rDeckId,
+ const Context& rContext);
+ std::shared_ptr<Panel> CreatePanel (
+ std::u16string_view rsPanelId,
+ weld::Widget* pParentWindow,
+ const bool bIsInitiallyExpanded,
+ const Context& rContext,
+ const VclPtr<Deck>& pDeck);
+
+ void SwitchToDeck (
+ const DeckDescriptor& rDeckDescriptor,
+ const Context& rContext);
+
+ void ShowPopupMenu (
+ weld::Menu& rMainMenu,
+ weld::Menu& rSubMenu,
+ const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
+ void PopulatePopupMenus(
+ weld::Menu& rMainButton,
+ weld::Menu& rSubMenu,
+ const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
+ DECL_DLLPRIVATE_LINK(OnMenuItemSelected, const OUString&, void);
+ DECL_DLLPRIVATE_LINK(OnSubMenuItemSelected, const OUString&, void);
+ void BroadcastPropertyChange();
+
+ /** The close of the deck changes the width of the child window.
+ That is only possible if there is no other docking window docked above or below the sidebar.
+ Return whether the width of the child window can be modified.
+ */
+ bool CanModifyChildWindowWidth();
+
+ /** Set the child window container to a new width.
+ Return the old width.
+ */
+ sal_Int32 SetChildWindowWidth (const sal_Int32 nNewWidth);
+
+ /** Update the icons displayed in the title bars of the deck and
+ the panels. This is called once when a deck is created and
+ every time when a data change event is processed.
+ */
+ void UpdateTitleBarIcons();
+
+ void UpdateDeckOpenState();
+ void RestrictWidth (sal_Int32 nWidth);
+ SfxSplitWindow* GetSplitWindow();
+ void ProcessNewWidth (const sal_Int32 nNewWidth);
+ void UpdateCloseIndicator (const bool bIsIndicatorVisible);
+
+ /** Typically called when a panel is focused via keyboard.
+ Tries to scroll the deck up or down to make the given panel
+ completely visible.
+ */
+ void ShowPanel (const Panel& rPanel);
+
+ virtual void disposing(std::unique_lock<std::mutex>&) override;
+
+ std::unique_ptr<ResourceManager> mpResourceManager;
+
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/SidebarDockingWindow.hxx b/include/sfx2/sidebar/SidebarDockingWindow.hxx
new file mode 100644
index 0000000000..f433086297
--- /dev/null
+++ b/include/sfx2/sidebar/SidebarDockingWindow.hxx
@@ -0,0 +1,66 @@
+/* -*- 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 <sfx2/dockwin.hxx>
+
+#include <rtl/ref.hxx>
+
+class SfxViewShell;
+
+namespace svt { class AcceleratorExecute; }
+
+namespace sfx2::sidebar {
+
+class SidebarChildWindow;
+
+class SidebarController;
+
+class SFX2_DLLPUBLIC SidebarDockingWindow final : public SfxDockingWindow
+{
+public:
+ SidebarDockingWindow(SfxBindings* pBindings, SidebarChildWindow& rChildWindow,
+ vcl::Window* pParent, WinBits nBits);
+ virtual ~SidebarDockingWindow() override;
+ virtual void dispose() override;
+ virtual bool EventNotify(NotifyEvent& rEvent) override;
+ virtual bool Close() override;
+
+ /// Force generation of all panels by completion.
+ void SyncUpdate();
+
+ rtl::Reference<sfx2::sidebar::SidebarController>& GetOrCreateSidebarController();
+ using SfxDockingWindow::Close;
+
+private:
+ // Window overridables
+ virtual void GetFocus() override;
+
+ virtual SfxChildAlignment CheckAlignment (
+ SfxChildAlignment eCurrentAlignment,
+ SfxChildAlignment eRequestedAlignment) override;
+
+ ::rtl::Reference<sfx2::sidebar::SidebarController> mpSidebarController;
+ bool mbIsReadyToDrag;
+ std::unique_ptr<svt::AcceleratorExecute> mpAccel;
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/SidebarModelUpdate.hxx b/include/sfx2/sidebar/SidebarModelUpdate.hxx
new file mode 100644
index 0000000000..33b273f143
--- /dev/null
+++ b/include/sfx2/sidebar/SidebarModelUpdate.hxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <sfx2/dllapi.h>
+
+namespace com::sun::star::frame
+{
+class XModel;
+}
+namespace com::sun::star::uno
+{
+template <typename> class Reference;
+}
+
+namespace sfx2::sidebar
+{
+class SFX2_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") SidebarModelUpdate
+{
+public:
+ virtual ~SidebarModelUpdate();
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) = 0;
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/SidebarPanelBase.hxx b/include/sfx2/sidebar/SidebarPanelBase.hxx
new file mode 100644
index 0000000000..c1c99cd24a
--- /dev/null
+++ b/include/sfx2/sidebar/SidebarPanelBase.hxx
@@ -0,0 +1,102 @@
+/* -*- 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 <sal/config.h>
+
+#include <memory>
+
+#include <sfx2/dllapi.h>
+
+#include <comphelper/compbase.hxx>
+
+#include <com/sun/star/ui/XContextChangeEventListener.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/ui/XToolPanel.hpp>
+#include <com/sun/star/ui/XSidebarPanel.hpp>
+#include <com/sun/star/ui/XUpdateModel.hpp>
+
+class PanelLayout;
+
+namespace sfx2::sidebar {
+
+class Panel;
+
+typedef comphelper::WeakComponentImplHelper<css::ui::XContextChangeEventListener,
+ css::ui::XUIElement,
+ css::ui::XToolPanel,
+ css::ui::XSidebarPanel,
+ css::ui::XUpdateModel>
+ SidebarPanelBaseInterfaceBase;
+
+/** Base class for sidebar panels that provides some convenience
+ functionality.
+*/
+class SFX2_DLLPUBLIC SidebarPanelBase final : public SidebarPanelBaseInterfaceBase
+{
+public:
+ static css::uno::Reference<css::ui::XUIElement> Create(const OUString& rsResourceURL,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ std::unique_ptr<PanelLayout> xControl,
+ const css::ui::LayoutSize& rLayoutSize);
+
+ // XContextChangeEventListener
+ virtual void SAL_CALL notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent) override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) override;
+
+ // XUIElement
+ virtual css::uno::Reference<css::frame::XFrame> SAL_CALL getFrame() override;
+ virtual OUString SAL_CALL getResourceURL() override;
+ virtual sal_Int16 SAL_CALL getType() override;
+ virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getRealInterface() override;
+
+ // XToolPanel
+ virtual css::uno::Reference<css::accessibility::XAccessible> SAL_CALL createAccessible(
+ const css::uno::Reference<css::accessibility::XAccessible>& rxParentAccessible) override;
+ virtual css::uno::Reference<css::awt::XWindow> SAL_CALL getWindow() override;
+
+ // XSidebarPanel
+ virtual css::ui::LayoutSize SAL_CALL getHeightForWidth(sal_Int32 nWidth) override;
+ virtual sal_Int32 SAL_CALL getMinimalWidth() override;
+
+ // XUpdateModel
+ virtual void SAL_CALL updateModel(const css::uno::Reference<css::frame::XModel>& xModel) override;
+
+ void SetParentPanel(sfx2::sidebar::Panel* pPanel);
+
+private:
+ SidebarPanelBase(OUString sResourceURL, css::uno::Reference<css::frame::XFrame> xFrame,
+ std::unique_ptr<PanelLayout> xControl, const css::ui::LayoutSize& rLayoutSize);
+ virtual ~SidebarPanelBase() override;
+ SidebarPanelBase(const SidebarPanelBase&) = delete;
+ SidebarPanelBase& operator=( const SidebarPanelBase& ) = delete;
+
+ virtual void disposing(std::unique_lock<std::mutex>&) override;
+
+ css::uno::Reference<css::frame::XFrame> mxFrame;
+ std::unique_ptr<PanelLayout> mxControl;
+ const OUString msResourceURL;
+ const css::ui::LayoutSize maLayoutSize;
+};
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/TabBar.hxx b/include/sfx2/sidebar/TabBar.hxx
new file mode 100644
index 0000000000..6ef0fc9c3d
--- /dev/null
+++ b/include/sfx2/sidebar/TabBar.hxx
@@ -0,0 +1,138 @@
+/* -*- 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 <sfx2/sidebar/ResourceManager.hxx>
+
+#include <vcl/InterimItemWindow.hxx>
+
+#include <functional>
+
+namespace com::sun::star::frame { class XFrame; }
+
+namespace svt { class AcceleratorExecute; }
+
+namespace weld { class Toolbar; }
+
+namespace sfx2::sidebar {
+
+class FocusManager;
+class SidebarController;
+
+/** The tab bar is the container for the individual tabs.
+*/
+class TabBar final : public InterimItemWindow
+{
+ friend class TabBarUIObject;
+public:
+ /** DeckMenuData has entries for display name, and a flag:
+ - isCurrentDeck for the deck selection data
+ - isEnabled for the show/hide menu
+ */
+ class DeckMenuData
+ {
+ public:
+ OUString msDisplayName;
+ bool mbIsCurrentDeck;
+ bool mbIsActive;
+ bool mbIsEnabled;
+ };
+ typedef ::std::function<void (
+ weld::Menu& rMainMenu, weld::Menu& rSubMenu,
+ const ::std::vector<DeckMenuData>& rMenuData)> PopupMenuProvider;
+ TabBar (
+ vcl::Window* pParentWindow,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ::std::function<void (const OUString& rsDeckId)> aDeckActivationFunctor,
+ PopupMenuProvider aPopupMenuProvider,
+ SidebarController* rParentSidebarController);
+
+ weld::Container* GetContainer() { return m_xContainer.get(); }
+
+ virtual ~TabBar() override;
+ virtual void dispose() override;
+
+ virtual void DataChanged (const DataChangedEvent& rDataChangedEvent) override;
+ virtual bool EventNotify (NotifyEvent& rEvent) override;
+
+ static sal_Int32 GetDefaultWidth();
+
+ void SetDecks (
+ const ResourceManager::DeckContextDescriptorContainer& rDecks);
+ void HighlightDeck (std::u16string_view rsDeckId);
+ void RemoveDeckHighlight ();
+ OUString const & GetDeckIdForIndex (const sal_Int32 nIndex) const;
+ void ToggleHideFlag (const sal_Int32 nIndex);
+ void RestoreHideFlags();
+
+ void UpdateFocusManager (FocusManager& rFocusManager);
+
+ /// Enables/Disables the menu button. Used by LoKit.
+ void EnableMenuButton(const bool bEnable);
+
+ virtual FactoryFunction GetUITestFactory() const override;
+private:
+ css::uno::Reference<css::frame::XFrame> mxFrame;
+
+ // This unusual auxiliary 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::Box> 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:
+ Item(TabBar& rTabBar);
+ ~Item();
+ DECL_LINK(HandleClick, const OUString&, void);
+ std::unique_ptr<weld::Toolbar> mxButton;
+ OUString msDeckId;
+ ::std::function<void (const OUString& rsDeckId)> maDeckActivationFunctor;
+ bool mbIsHidden;
+ bool mbIsHiddenByDefault;
+ };
+ typedef ::std::vector<std::unique_ptr<Item>> ItemContainer;
+ ItemContainer maItems;
+ const ::std::function<void (const OUString& rsDeckId)> maDeckActivationFunctor;
+ PopupMenuProvider maPopupMenuProvider;
+
+ void CreateTabItem(weld::Toolbar& rButton, const DeckDescriptor& rDeckDescriptor);
+ css::uno::Reference<css::graphic::XGraphic> GetItemImage(const DeckDescriptor& rDeskDescriptor) const;
+ void UpdateButtonIcons();
+
+ DECL_LINK(OnToolboxClicked, weld::Toggleable&, void);
+
+ SidebarController* pParentSidebarController;
+ std::unique_ptr<svt::AcceleratorExecute> mpAccel;
+
+};
+
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/sidebar/Theme.hxx b/include/sfx2/sidebar/Theme.hxx
new file mode 100644
index 0000000000..a3f827f4a5
--- /dev/null
+++ b/include/sfx2/sidebar/Theme.hxx
@@ -0,0 +1,184 @@
+/* -*- 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 <sfx2/dllapi.h>
+
+#include <tools/color.hxx>
+#include <comphelper/compbase.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <map>
+#include <unordered_map>
+
+
+namespace sfx2::sidebar {
+
+typedef comphelper::WeakComponentImplHelper <
+ css::beans::XPropertySet,
+ css::beans::XPropertySetInfo
+ > ThemeInterfaceBase;
+
+/** Simple collection of colors, gradients, fonts that define the
+ look of the sidebar and its controls.
+*/
+class SFX2_DLLPUBLIC Theme final
+ : public ThemeInterfaceBase
+{
+public:
+ enum ThemeItem
+ {
+ Begin_,
+ Pre_Color_ = Begin_,
+
+ AnyItem_ = Pre_Color_,
+
+ Image_Color_,
+
+ Color_Highlight,
+ Color_HighlightText,
+ Color_DeckBackground,
+ Color_DeckTitleBarBackground,
+ Color_PanelBackground,
+ Color_PanelTitleBarBackground,
+ Color_TabBarBackground,
+
+ Color_Int_,
+
+ Int_DeckBorderSize,
+ Int_DeckSeparatorHeight,
+ Int_DeckLeftPadding,
+ Int_DeckTopPadding,
+ Int_DeckRightPadding,
+ Int_DeckBottomPadding,
+
+ Int_Bool_,
+
+ Bool_UseSystemColors,
+ Bool_IsHighContrastModeActive,
+
+ Post_Bool_,
+ End_=Post_Bool_
+ };
+
+ static Color GetColor (const ThemeItem eItem);
+ static sal_Int32 GetInteger (const ThemeItem eItem);
+
+ static bool IsHighContrastMode();
+
+ static void HandleDataChange();
+
+ void InitializeTheme();
+
+ Theme();
+ virtual ~Theme() override;
+ Theme(const Theme&) = delete;
+ Theme& operator=( const Theme& ) = delete;
+
+ virtual void disposing(std::unique_lock<std::mutex>&) override;
+
+ static css::uno::Reference<css::beans::XPropertySet> GetPropertySet();
+
+ // beans::XPropertySet
+ virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
+ virtual void SAL_CALL setPropertyValue (
+ const OUString& rsPropertyName,
+ const css::uno::Any& rValue) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue (
+ const OUString& rsPropertyName) override;
+ virtual void SAL_CALL addPropertyChangeListener(
+ const OUString& rsPropertyName,
+ const css::uno::Reference<css::beans::XPropertyChangeListener>& rxListener) override;
+ virtual void SAL_CALL removePropertyChangeListener(
+ const OUString& rsPropertyName,
+ const css::uno::Reference<css::beans::XPropertyChangeListener>& rxListener) override;
+ virtual void SAL_CALL addVetoableChangeListener(
+ const OUString& rsPropertyName,
+ const css::uno::Reference<css::beans::XVetoableChangeListener>& rxListener) override;
+ virtual void SAL_CALL removeVetoableChangeListener(
+ const OUString& rsPropertyName,
+ const css::uno::Reference<css::beans::XVetoableChangeListener>& rxListener) override;
+
+ // beans::XPropertySetInfo
+ virtual css::uno::Sequence<css::beans::Property> SAL_CALL getProperties() override;
+ virtual css::beans::Property SAL_CALL getPropertyByName (const OUString& rsName) override;
+ virtual sal_Bool SAL_CALL hasPropertyByName (const OUString& rsName) override;
+
+private:
+ static Theme& GetCurrentTheme();
+
+ std::vector<Color> maColors;
+ std::vector<sal_Int32> maIntegers;
+ std::vector<bool> maBooleans;
+ bool mbIsHighContrastMode;
+ bool mbIsHighContrastModeSetManually;
+
+ typedef std::unordered_map<OUString,ThemeItem> PropertyNameToIdMap;
+ PropertyNameToIdMap maPropertyNameToIdMap;
+ typedef std::vector<OUString> PropertyIdToNameMap;
+ PropertyIdToNameMap maPropertyIdToNameMap;
+ typedef ::std::vector<css::uno::Any> RawValueContainer;
+ RawValueContainer maRawValues;
+
+ typedef std::vector<css::uno::Reference<css::beans::XPropertyChangeListener> > ChangeListenerContainer;
+ typedef std::map<ThemeItem,ChangeListenerContainer> ChangeListeners;
+ ChangeListeners maChangeListeners;
+ typedef std::vector<css::uno::Reference<css::beans::XVetoableChangeListener> > VetoableListenerContainer;
+ typedef std::map<ThemeItem,VetoableListenerContainer> VetoableListeners;
+ VetoableListeners maVetoableListeners;
+
+ enum PropertyType
+ {
+ PT_Color,
+ PT_Integer,
+ PT_Boolean,
+ PT_Invalid
+ };
+
+ void SetupPropertyMaps();
+ void UpdateTheme();
+ static PropertyType GetPropertyType (const ThemeItem eItem);
+ static css::uno::Type const & GetCppuType (const PropertyType eType);
+ static sal_Int32 GetIndex (
+ const ThemeItem eItem,
+ const PropertyType eType);
+
+ VetoableListenerContainer* GetVetoableListeners (
+ const ThemeItem eItem,
+ const bool bCreate);
+ ChangeListenerContainer* GetChangeListeners (
+ const ThemeItem eItem,
+ const bool bCreate);
+ static bool DoVetoableListenersVeto (
+ const VetoableListenerContainer* pListeners,
+ const css::beans::PropertyChangeEvent& rEvent);
+ static void BroadcastPropertyChange (
+ const ChangeListenerContainer* pListeners,
+ const css::beans::PropertyChangeEvent& rEvent);
+ void ProcessNewValue (
+ const css::uno::Any& rValue,
+ const ThemeItem eItem,
+ const PropertyType eType);
+};
+
+
+} // end of namespace sfx2::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */