Avoid potential negative array index access to cached text.
[LibreOffice.git] / include / sfx2 / sidebar / SidebarController.hxx
blob06e092bceec80f3fa44a21211118b68e776c07dc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
19 #pragma once
21 #include <memory>
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>
39 #include <optional>
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,
49 css::ui::XSidebar,
50 css::frame::XStatusListener,
51 css::frame::XFrameActionListener
52 > SidebarControllerInterfaceBase;
54 class SfxSplitWindow;
55 class SfxViewShell;
57 namespace sfx2::sidebar {
59 class DeckDescriptor;
60 class SidebarDockingWindow;
62 class SFX2_DLLPUBLIC SidebarController final
63 : public SidebarControllerInterfaceBase
65 public:
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
73 the given XFrame.
74 @return
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;
88 // XEventListener
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;
100 // ui::XSidebar
101 virtual void SAL_CALL requestLayout() override;
103 void NotifyResize();
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 void OpenThenSwitchToDeck(std::u16string_view rsDeckId);
117 void OpenThenToggleDeck(const OUString& rsDeckId);
119 /** Show only the tab bar, not the deck.
121 void RequestCloseDeck();
123 /** Open the deck area and restore the parent window to its old width.
125 void RequestOpenDeck();
127 /** Returns true when the given deck is the currently visible deck
129 bool IsDeckVisible(std::u16string_view rsDeckId);
131 bool IsDeckOpen(const sal_Int32 nIndex = -1);
133 FocusManager& GetFocusManager() { return maFocusManager;}
135 ResourceManager* GetResourceManager() { return mpResourceManager.get();}
137 // std::unique_ptr<ResourceManager> GetResourceManager() { return mpResourceManager;}
139 const Context& GetCurrentContext() const { return maCurrentContext;}
140 bool IsDocumentReadOnly (void) const { return mbIsDocumentReadOnly;}
142 void SwitchToDeck(std::u16string_view rsDeckId);
143 void SwitchToDefaultDeck();
144 bool WasFloatingDeckClosed() const { return mbFloatingDeckClosed; }
145 void SetFloatingDeckClosed(bool bWasClosed) { mbFloatingDeckClosed = bWasClosed; }
147 void CreateDeck(std::u16string_view rDeckId);
148 void CreateDeck(std::u16string_view rDeckId, const Context& rContext, bool bForceCreate = false);
150 ResourceManager::DeckContextDescriptorContainer GetMatchingDecks();
151 ResourceManager::PanelContextDescriptorContainer GetMatchingPanels(std::u16string_view rDeckId);
153 void notifyDeckTitle(std::u16string_view targetDeckId);
155 void updateModel(const css::uno::Reference<css::frame::XModel>& xModel);
157 void disposeDecks();
159 void FadeIn();
160 void FadeOut();
162 tools::Rectangle GetDeckDragArea() const;
164 css::uno::Reference<css::frame::XFrame> const & getXFrame() const {return mxFrame;}
166 sal_Int32 getMaximumWidth() const { return mnMaximumSidebarWidth; }
167 void setMaximumWidth(sal_Int32 nMaximumWidth) { mnMaximumSidebarWidth = nMaximumWidth; }
169 void saveDeckState();
171 void SyncUpdate();
173 // Used to avoid wrong context update when an embedded object activation is in progress
174 bool hasChartOrMathContextCurrently() const;
176 static SidebarController* GetSidebarControllerForView(const SfxViewShell* pViewShell);
178 private:
179 SidebarController(SidebarDockingWindow* pParentWindow, const SfxViewFrame* pViewFrame);
181 VclPtr<Deck> mpCurrentDeck;
182 VclPtr<SidebarDockingWindow> mpParentWindow;
183 const SfxViewFrame* mpViewFrame;
184 css::uno::Reference<css::frame::XFrame> mxFrame;
185 VclPtr<TabBar> mpTabBar;
186 Context maCurrentContext;
187 Context maRequestedContext;
188 css::uno::Reference<css::frame::XController> mxCurrentController;
189 /// Use a combination of SwitchFlag_* as value.
190 sal_Int32 mnRequestedForceFlags;
191 sal_Int32 mnMaximumSidebarWidth;
192 bool mbMinimumSidebarWidth;
193 OUString msCurrentDeckId;
194 AsynchronousCall maPropertyChangeForwarder;
195 AsynchronousCall maContextChangeUpdate;
196 css::uno::Reference<css::beans::XPropertySet> mxThemePropertySet;
198 /** Two flags control whether the deck is displayed or if only the
199 tab bar remains visible.
200 The mbIsDeckOpen flag stores the current state while
201 mbIsDeckRequestedOpen stores how this state should be. User
202 actions like clicking on the deck closer affect the
203 mbIsDeckRequestedOpen. Normally both flags have the same
204 value. A document being read-only can prevent the deck from opening.
206 ::std::optional<bool> mbIsDeckRequestedOpen;
207 ::std::optional<bool> mbIsDeckOpen;
209 bool mbFloatingDeckClosed;
211 /** Before the deck is closed the sidebar width is saved into this variable,
212 so that it can be restored when the deck is reopened.
214 sal_Int32 mnSavedSidebarWidth;
215 FocusManager maFocusManager;
216 css::uno::Reference<css::frame::XDispatch> mxReadOnlyModeDispatch;
217 bool mbIsDocumentReadOnly;
218 VclPtr<SfxSplitWindow> mpSplitWindow;
219 /** When the user moves the splitter then we remember the
220 width at that time.
222 sal_Int32 mnWidthOnSplitterButtonDown;
223 /** Control that is temporarily used as replacement for the deck
224 to indicate that when the current mouse drag operation ends, the
225 sidebar will only show the tab bar.
227 VclPtr<vcl::Window> mpCloseIndicator;
229 DECL_DLLPRIVATE_LINK(WindowEventHandler, VclWindowEvent&, void);
230 /** Make maRequestedContext the current context.
232 void UpdateConfigurations();
234 css::uno::Reference<css::ui::XUIElement> CreateUIElement (
235 const css::uno::Reference<css::awt::XWindow>& rxWindow,
236 const OUString& rsImplementationURL,
237 const bool bWantsCanvas,
238 const Context& rContext);
240 void CreatePanels(
241 std::u16string_view rDeckId,
242 const Context& rContext);
243 std::shared_ptr<Panel> CreatePanel (
244 std::u16string_view rsPanelId,
245 weld::Widget* pParentWindow,
246 const bool bIsInitiallyExpanded,
247 const Context& rContext,
248 const VclPtr<Deck>& pDeck);
250 void SwitchToDeck (
251 const DeckDescriptor& rDeckDescriptor,
252 const Context& rContext);
254 void ShowPopupMenu (
255 weld::Menu& rMainMenu,
256 weld::Menu& rSubMenu,
257 const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
258 void PopulatePopupMenus(
259 weld::Menu& rMainButton,
260 weld::Menu& rSubMenu,
261 const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
262 DECL_DLLPRIVATE_LINK(OnMenuItemSelected, const OUString&, void);
263 DECL_DLLPRIVATE_LINK(OnSubMenuItemSelected, const OUString&, void);
264 void BroadcastPropertyChange();
266 /** The close of the deck changes the width of the child window.
267 That is only possible if there is no other docking window docked above or below the sidebar.
268 Return whether the width of the child window can be modified.
270 bool CanModifyChildWindowWidth();
272 /** Set the child window container to a new width.
273 Return the old width.
275 sal_Int32 SetChildWindowWidth (const sal_Int32 nNewWidth);
277 /** Update the icons displayed in the title bars of the deck and
278 the panels. This is called once when a deck is created and
279 every time when a data change event is processed.
281 void UpdateTitleBarIcons();
283 void UpdateDeckOpenState();
284 void RestrictWidth (sal_Int32 nWidth);
285 SfxSplitWindow* GetSplitWindow();
286 void ProcessNewWidth (const sal_Int32 nNewWidth);
287 void UpdateCloseIndicator (const bool bIsIndicatorVisible);
289 /** Typically called when a panel is focused via keyboard.
290 Tries to scroll the deck up or down to make the given panel
291 completely visible.
293 void ShowPanel (const Panel& rPanel);
295 virtual void disposing(std::unique_lock<std::mutex>&) override;
297 std::unique_ptr<ResourceManager> mpResourceManager;
301 } // end of namespace sfx2::sidebar
303 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */