1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <sal/config.h>
24 #include <sfx2/sidebar/AsynchronousCall.hxx>
25 #include <sfx2/sidebar/Context.hxx>
26 #include <sfx2/sidebar/Deck.hxx>
27 #include <sfx2/sidebar/FocusManager.hxx>
28 #include <sfx2/sidebar/ResourceManager.hxx>
29 #include <sfx2/sidebar/TabBar.hxx>
30 #include <sfx2/viewfrm.hxx>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
34 #include <com/sun/star/frame/XStatusListener.hpp>
35 #include <com/sun/star/frame/XFrameActionListener.hpp>
36 #include <com/sun/star/ui/XContextChangeEventListener.hpp>
37 #include <com/sun/star/ui/XSidebar.hpp>
40 #include <comphelper/compbase.hxx>
42 namespace com::sun::star::awt
{ class XWindow
; }
43 namespace com::sun::star::frame
{ class XDispatch
; }
44 namespace com::sun::star::ui
{ class XUIElement
; }
46 typedef comphelper::WeakComponentImplHelper
<
47 css::ui::XContextChangeEventListener
,
48 css::beans::XPropertyChangeListener
,
50 css::frame::XStatusListener
,
51 css::frame::XFrameActionListener
52 > SidebarControllerInterfaceBase
;
57 namespace sfx2::sidebar
{
60 class SidebarDockingWindow
;
62 class SFX2_DLLPUBLIC SidebarController final
63 : public SidebarControllerInterfaceBase
66 static rtl::Reference
<SidebarController
> create(SidebarDockingWindow
* pParentWindow
,
67 const SfxViewFrame
* pViewFrame
);
68 virtual ~SidebarController() override
;
69 SidebarController(const SidebarController
&) = delete;
70 SidebarController
& operator=( const SidebarController
& ) = delete;
72 /** Return the SidebarController object that is associated with
75 When there is no SidebarController object for the given
76 XFrame then <NULL/> is returned.
78 static SidebarController
* GetSidebarControllerForFrame (
79 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
);
81 void registerSidebarForFrame(const css::uno::Reference
<css::frame::XController
>& xFrame
);
83 void unregisterSidebarForFrame(const css::uno::Reference
<css::frame::XController
>& xFrame
);
85 // ui::XContextChangeEventListener
86 virtual void SAL_CALL
notifyContextChangeEvent (const css::ui::ContextChangeEventObject
& rEvent
) override
;
89 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEventObject
) override
;
91 // beans::XPropertyChangeListener
92 virtual void SAL_CALL
propertyChange (const css::beans::PropertyChangeEvent
& rEvent
) override
;
94 // frame::XStatusListener
95 virtual void SAL_CALL
statusChanged (const css::frame::FeatureStateEvent
& rEvent
) override
;
97 // frame::XFrameActionListener
98 virtual void SAL_CALL
frameAction (const css::frame::FrameActionEvent
& rEvent
) override
;
101 virtual void SAL_CALL
requestLayout() override
;
105 /** In some situations it is necessary to force an update of the
106 current deck and its panels. One reason is a change of the
107 view scale. Some panels can handle this only when
108 constructed. In this case we have to a context change and
109 also force that all panels are destroyed and created new.
111 const static sal_Int32 SwitchFlag_NoForce
= 0x00;
112 const static sal_Int32 SwitchFlag_ForceSwitch
= 0x01;
113 const static sal_Int32 SwitchFlag_ForceNewDeck
= 0x02;
114 const static sal_Int32 SwitchFlag_ForceNewPanels
= 0x02;
116 bool IsDocked() const;
118 void OpenThenSwitchToDeck(std::u16string_view rsDeckId
);
119 void OpenThenToggleDeck(const OUString
& rsDeckId
);
121 /** Show only the tab bar, not the deck.
123 void RequestCloseDeck();
125 /** Open the deck area and restore the parent window to its old width.
127 void RequestOpenDeck();
129 /** Returns true when the given deck is the currently visible deck
131 bool IsDeckVisible(std::u16string_view rsDeckId
);
133 bool IsDeckOpen(const sal_Int32 nIndex
= -1);
135 FocusManager
& GetFocusManager() { return maFocusManager
;}
137 ResourceManager
* GetResourceManager() { return mpResourceManager
.get();}
139 // std::unique_ptr<ResourceManager> GetResourceManager() { return mpResourceManager;}
141 const Context
& GetCurrentContext() const { return maCurrentContext
;}
142 bool IsDocumentReadOnly (void) const { return mbIsDocumentReadOnly
;}
144 void SwitchToDeck(std::u16string_view rsDeckId
);
145 void SwitchToDefaultDeck();
146 bool WasFloatingDeckClosed() const { return mbFloatingDeckClosed
; }
147 void SetFloatingDeckClosed(bool bWasClosed
) { mbFloatingDeckClosed
= bWasClosed
; }
149 void CreateDeck(std::u16string_view rDeckId
);
150 void CreateDeck(std::u16string_view rDeckId
, const Context
& rContext
, bool bForceCreate
= false);
152 ResourceManager::DeckContextDescriptorContainer
GetMatchingDecks();
153 ResourceManager::PanelContextDescriptorContainer
GetMatchingPanels(std::u16string_view rDeckId
);
155 void notifyDeckTitle(std::u16string_view targetDeckId
);
157 void updateModel(const css::uno::Reference
<css::frame::XModel
>& xModel
);
164 tools::Rectangle
GetDeckDragArea() const;
166 css::uno::Reference
<css::frame::XFrame
> const & getXFrame() const {return mxFrame
;}
168 sal_Int32
getMaximumWidth() const { return mnMaximumSidebarWidth
; }
169 void setMaximumWidth(sal_Int32 nMaximumWidth
) { mnMaximumSidebarWidth
= nMaximumWidth
; }
171 void saveDeckState();
175 // Used to avoid wrong context update when an embedded object activation is in progress
176 bool hasChartOrMathContextCurrently() const;
178 static SidebarController
* GetSidebarControllerForView(const SfxViewShell
* pViewShell
);
181 SidebarController(SidebarDockingWindow
* pParentWindow
, const SfxViewFrame
* pViewFrame
);
183 VclPtr
<Deck
> mpCurrentDeck
;
184 VclPtr
<SidebarDockingWindow
> mpParentWindow
;
185 const SfxViewFrame
* mpViewFrame
;
186 css::uno::Reference
<css::frame::XFrame
> mxFrame
;
187 VclPtr
<TabBar
> mpTabBar
;
188 Context maCurrentContext
;
189 Context maRequestedContext
;
190 css::uno::Reference
<css::frame::XController
> mxCurrentController
;
191 /// Use a combination of SwitchFlag_* as value.
192 sal_Int32 mnRequestedForceFlags
;
193 sal_Int32 mnMaximumSidebarWidth
;
194 bool mbMinimumSidebarWidth
;
195 OUString msCurrentDeckId
;
196 AsynchronousCall maPropertyChangeForwarder
;
197 AsynchronousCall maContextChangeUpdate
;
198 css::uno::Reference
<css::beans::XPropertySet
> mxThemePropertySet
;
200 /** Two flags control whether the deck is displayed or if only the
201 tab bar remains visible.
202 The mbIsDeckOpen flag stores the current state while
203 mbIsDeckRequestedOpen stores how this state should be. User
204 actions like clicking on the deck closer affect the
205 mbIsDeckRequestedOpen. Normally both flags have the same
206 value. A document being read-only can prevent the deck from opening.
208 ::std::optional
<bool> mbIsDeckRequestedOpen
;
209 ::std::optional
<bool> mbIsDeckOpen
;
211 bool mbFloatingDeckClosed
;
213 /** Before the deck is closed the sidebar width is saved into this variable,
214 so that it can be restored when the deck is reopened.
216 sal_Int32 mnSavedSidebarWidth
;
217 FocusManager maFocusManager
;
218 css::uno::Reference
<css::frame::XDispatch
> mxReadOnlyModeDispatch
;
219 bool mbIsDocumentReadOnly
;
220 VclPtr
<SfxSplitWindow
> mpSplitWindow
;
221 /** When the user moves the splitter then we remember the
224 sal_Int32 mnWidthOnSplitterButtonDown
;
225 /** Control that is temporarily used as replacement for the deck
226 to indicate that when the current mouse drag operation ends, the
227 sidebar will only show the tab bar.
229 VclPtr
<vcl::Window
> mpCloseIndicator
;
231 DECL_DLLPRIVATE_LINK(WindowEventHandler
, VclWindowEvent
&, void);
232 /** Make maRequestedContext the current context.
234 void UpdateConfigurations();
236 css::uno::Reference
<css::ui::XUIElement
> CreateUIElement (
237 const css::uno::Reference
<css::awt::XWindow
>& rxWindow
,
238 const OUString
& rsImplementationURL
,
239 const bool bWantsCanvas
,
240 const Context
& rContext
);
243 std::u16string_view rDeckId
,
244 const Context
& rContext
);
245 std::shared_ptr
<Panel
> CreatePanel (
246 std::u16string_view rsPanelId
,
247 weld::Widget
* pParentWindow
,
248 const bool bIsInitiallyExpanded
,
249 const Context
& rContext
,
250 const VclPtr
<Deck
>& pDeck
);
253 const DeckDescriptor
& rDeckDescriptor
,
254 const Context
& rContext
);
256 void ConnectMenuActivateHandlers(weld::Menu
& rMainMenu
, weld::Menu
& rSubMenu
) const;
258 DECL_DLLPRIVATE_LINK(OnMenuItemSelected
, const OUString
&, void);
259 DECL_DLLPRIVATE_LINK(OnSubMenuItemSelected
, const OUString
&, void);
260 void BroadcastPropertyChange();
262 /** The close of the deck changes the width of the child window.
263 That is only possible if there is no other docking window docked above or below the sidebar.
264 Return whether the width of the child window can be modified.
266 bool CanModifyChildWindowWidth();
268 /** Set the child window container to a new width.
269 Return the old width.
271 sal_Int32
SetChildWindowWidth (const sal_Int32 nNewWidth
);
273 /** Update the icons displayed in the title bars of the deck and
274 the panels. This is called once when a deck is created and
275 every time when a data change event is processed.
277 void UpdateTitleBarIcons();
279 void UpdateDeckOpenState();
280 void RestrictWidth (sal_Int32 nWidth
);
281 SfxSplitWindow
* GetSplitWindow();
282 void ProcessNewWidth (const sal_Int32 nNewWidth
);
283 void UpdateCloseIndicator (const bool bIsIndicatorVisible
);
285 /** Typically called when a panel is focused via keyboard.
286 Tries to scroll the deck up or down to make the given panel
289 void ShowPanel (const Panel
& rPanel
);
291 virtual void disposing(std::unique_lock
<std::mutex
>&) override
;
293 std::unique_ptr
<ResourceManager
> mpResourceManager
;
297 } // end of namespace sfx2::sidebar
299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */