Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : #ifndef INCLUDED_SFX2_SOURCE_SIDEBAR_SIDEBARCONTROLLER_HXX
20 : #define INCLUDED_SFX2_SOURCE_SIDEBAR_SIDEBARCONTROLLER_HXX
21 :
22 : #include <sal/config.h>
23 :
24 : #include <map>
25 :
26 : #include "AsynchronousCall.hxx"
27 : #include "Context.hxx"
28 : #include "FocusManager.hxx"
29 : #include "Panel.hxx"
30 : #include "ResourceManager.hxx"
31 : #include "TabBar.hxx"
32 :
33 : #include <vcl/menu.hxx>
34 :
35 : #include <com/sun/star/awt/XWindowPeer.hpp>
36 : #include <com/sun/star/beans/XPropertyChangeListener.hpp>
37 : #include <com/sun/star/frame/XDispatch.hpp>
38 : #include <com/sun/star/ui/XContextChangeEventListener.hpp>
39 : #include <com/sun/star/ui/XUIElement.hpp>
40 : #include <com/sun/star/ui/XSidebar.hpp>
41 :
42 : #include <boost/noncopyable.hpp>
43 : #include <boost/optional.hpp>
44 : #include <cppuhelper/compbase4.hxx>
45 : #include <cppuhelper/basemutex.hxx>
46 : #include <cppuhelper/weakref.hxx>
47 :
48 :
49 :
50 : namespace
51 : {
52 : typedef ::cppu::WeakComponentImplHelper4 <
53 : css::ui::XContextChangeEventListener,
54 : css::beans::XPropertyChangeListener,
55 : css::ui::XSidebar,
56 : css::frame::XStatusListener
57 : > SidebarControllerInterfaceBase;
58 : }
59 :
60 : class SfxSplitWindow;
61 : class FixedBitmap;
62 :
63 : namespace sfx2 { namespace sidebar {
64 :
65 : class ContentPanelDescriptor;
66 : class Deck;
67 : class DeckDescriptor;
68 : class SidebarDockingWindow;
69 : class TabBar;
70 : class TabBarConfiguration;
71 :
72 : class SidebarController
73 : : private ::boost::noncopyable,
74 : private ::cppu::BaseMutex,
75 : public SidebarControllerInterfaceBase
76 : {
77 : public:
78 : SidebarController(
79 : SidebarDockingWindow* pParentWindow,
80 : const css::uno::Reference<css::frame::XFrame>& rxFrame);
81 : virtual ~SidebarController (void);
82 :
83 : /** Return the SidebarController object that is associated with
84 : the given XFrame.
85 : @return
86 : When there is no SidebarController object for the given
87 : XFrame then <NULL/> is returned.
88 : */
89 : static SidebarController* GetSidebarControllerForFrame (
90 : const css::uno::Reference<css::frame::XFrame>& rxFrame);
91 :
92 : // ui::XContextChangeEventListener
93 : virtual void SAL_CALL notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent)
94 : throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
95 :
96 : // XEventListener
97 : virtual void SAL_CALL disposing (const css::lang::EventObject& rEventObject)
98 : throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
99 :
100 : // beans::XPropertyChangeListener
101 : virtual void SAL_CALL propertyChange (const css::beans::PropertyChangeEvent& rEvent)
102 : throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
103 :
104 : // frame::XStatusListener
105 : virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent)
106 : throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
107 :
108 : // ui::XSidebar
109 : virtual void SAL_CALL requestLayout (void)
110 : throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
111 :
112 : void NotifyResize (void);
113 :
114 : /** In some situations it is necessary to force an update of the
115 : current deck and its panels. One reason is a change of the
116 : view scale. Some panels can handle this only when
117 : constructed. In this case we have to a context change and
118 : also force that all panels are destroyed and created new.
119 : */
120 : const static sal_Int32 SwitchFlag_NoForce = 0x00;
121 : const static sal_Int32 SwitchFlag_ForceSwitch = 0x01;
122 : const static sal_Int32 SwitchFlag_ForceNewDeck = 0x02;
123 : const static sal_Int32 SwitchFlag_ForceNewPanels = 0x02;
124 :
125 : void OpenThenSwitchToDeck (
126 : const ::rtl::OUString& rsDeckId);
127 :
128 : /** Show only the tab bar, not the deck.
129 : */
130 : void RequestCloseDeck (void);
131 :
132 : /** Open the deck area and restore the parent window to its old width.
133 : */
134 : void RequestOpenDeck (void);
135 :
136 0 : FocusManager& GetFocusManager (void) { return maFocusManager;}
137 :
138 : private:
139 : typedef ::std::map<
140 : const css::uno::Reference<css::frame::XFrame>,
141 : css::uno::WeakReference<SidebarController>
142 : > SidebarControllerContainer;
143 : static SidebarControllerContainer maSidebarControllerContainer;
144 :
145 : ::boost::scoped_ptr<Deck> mpCurrentDeck;
146 : SidebarDockingWindow* mpParentWindow;
147 : ::boost::scoped_ptr<TabBar> mpTabBar;
148 : css::uno::Reference<css::frame::XFrame> mxFrame;
149 : Context maCurrentContext;
150 : Context maRequestedContext;
151 : /// Use a combination of SwitchFlag_* as value.
152 : sal_Int32 mnRequestedForceFlags;
153 : ::rtl::OUString msCurrentDeckId;
154 : ::rtl::OUString msCurrentDeckTitle;
155 : AsynchronousCall maPropertyChangeForwarder;
156 : AsynchronousCall maContextChangeUpdate;
157 : AsynchronousCall maAsynchronousDeckSwitch;
158 :
159 : /** Two flags control whether the deck is displayed or if only the
160 : tab bar remains visible.
161 : The mbIsDeckOpen flag stores the current state while
162 : mbIsDeckRequestedOpen stores how this state should be. User
163 : actions like clicking on the deck closer affect the
164 : mbIsDeckRequestedOpen. Normally both flags have the same
165 : value. A document being read-only can prevent the deck from opening.
166 : */
167 : ::boost::optional<bool> mbIsDeckRequestedOpen;
168 : ::boost::optional<bool> mbIsDeckOpen;
169 : bool mbCanDeckBeOpened;
170 :
171 : /** Before the deck is closed the sidebar width is saved into this variable,
172 : so that it can be restored when the deck is reopended.
173 : */
174 : sal_Int32 mnSavedSidebarWidth;
175 : FocusManager maFocusManager;
176 : css::uno::Reference<css::frame::XDispatch> mxReadOnlyModeDispatch;
177 : bool mbIsDocumentReadOnly;
178 : SfxSplitWindow* mpSplitWindow;
179 : /** When the user moves the splitter then we remember the
180 : width at that time.
181 : */
182 : sal_Int32 mnWidthOnSplitterButtonDown;
183 : /** Control that is temporarily used as replacement for the deck
184 : to indicate that when the current mouse drag operation ends, the
185 : sidebar will only show the tab bar.
186 : */
187 : ::boost::scoped_ptr<vcl::Window> mpCloseIndicator;
188 :
189 : DECL_LINK(WindowEventHandler, VclWindowEvent*);
190 : /** Make maRequestedContext the current context.
191 : */
192 : void UpdateConfigurations (void);
193 :
194 : css::uno::Reference<css::ui::XUIElement> CreateUIElement (
195 : const css::uno::Reference<css::awt::XWindowPeer>& rxWindow,
196 : const ::rtl::OUString& rsImplementationURL,
197 : const bool bWantsCanvas,
198 : const Context& rContext);
199 : SharedPanel CreatePanel (
200 : const ::rtl::OUString& rsPanelId,
201 : vcl::Window* pParentWindow,
202 : const bool bIsInitiallyExpanded,
203 : const Context& rContext);
204 : void SwitchToDeck (
205 : const ::rtl::OUString& rsDeckId);
206 : void SwitchToDeck (
207 : const DeckDescriptor& rDeckDescriptor,
208 : const Context& rContext);
209 : void ShowPopupMenu (
210 : const Rectangle& rButtonBox,
211 : const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
212 : ::boost::shared_ptr<PopupMenu> CreatePopupMenu (
213 : const ::std::vector<TabBar::DeckMenuData>& rMenuData) const;
214 : DECL_LINK(OnMenuItemSelected, Menu*);
215 : void BroadcastPropertyChange (void);
216 :
217 : /** The close of the deck changes the width of the child window.
218 : That is only possible if there is no other docking window docked above or below the sidebar.
219 : Return whether the width of the child window can be modified.
220 : */
221 : bool CanModifyChildWindowWidth (void);
222 :
223 : /** Set the child window container to a new width.
224 : Return the old width.
225 : */
226 : sal_Int32 SetChildWindowWidth (const sal_Int32 nNewWidth);
227 :
228 : /** Update the icons displayed in the title bars of the deck and
229 : the panels. This is called once when a deck is created and
230 : every time when a data change event is processed.
231 : */
232 : void UpdateTitleBarIcons (void);
233 :
234 : void UpdateDeckOpenState (void);
235 : void RestrictWidth (sal_Int32 nWidth);
236 : SfxSplitWindow* GetSplitWindow (void);
237 : void ProcessNewWidth (const sal_Int32 nNewWidth);
238 : void UpdateCloseIndicator (const bool bIsIndicatorVisible);
239 :
240 : /** Typically called when a panel is focused via keyboard.
241 : Tries to scroll the deck up or down to make the given panel
242 : completely visible.
243 : */
244 : void ShowPanel (const Panel& rPanel);
245 :
246 0 : Context GetCurrentContext (void) const { return maCurrentContext;}
247 :
248 : virtual void SAL_CALL disposing (void) SAL_OVERRIDE;
249 : };
250 :
251 :
252 : } } // end of namespace sfx2::sidebar
253 :
254 : #endif
255 :
256 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|