2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 #ifndef SFX_SIDEBAR_CONTROLLER_HXX
19 #define SFX_SIDEBAR_CONTROLLER_HXX
21 #include "AsynchronousCall.hxx"
22 #include "Context.hxx"
23 #include "FocusManager.hxx"
25 #include "ResourceManager.hxx"
28 #include <vcl/menu.hxx>
30 #include <com/sun/star/awt/XWindowPeer.hpp>
31 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
32 #include <com/sun/star/frame/XDispatch.hpp>
33 #include <com/sun/star/ui/XContextChangeEventListener.hpp>
34 #include <com/sun/star/ui/XUIElement.hpp>
35 #include <com/sun/star/ui/XSidebar.hpp>
37 #include <boost/noncopyable.hpp>
38 #include <boost/optional.hpp>
39 #include <cppuhelper/compbase4.hxx>
40 #include <cppuhelper/basemutex.hxx>
42 namespace css
= ::com::sun::star
;
43 namespace cssu
= ::com::sun::star::uno
;
48 typedef ::cppu::WeakComponentImplHelper4
<
49 css::ui::XContextChangeEventListener
,
50 css::beans::XPropertyChangeListener
,
52 css::frame::XStatusListener
53 > SidebarControllerInterfaceBase
;
59 namespace sfx2
{ namespace sidebar
{
61 class ContentPanelDescriptor
;
64 class SidebarDockingWindow
;
66 class TabBarConfiguration
;
68 class SidebarController
69 : private ::boost::noncopyable
,
70 private ::cppu::BaseMutex
,
71 public SidebarControllerInterfaceBase
75 SidebarDockingWindow
* pParentWindow
,
76 const cssu::Reference
<css::frame::XFrame
>& rxFrame
);
77 virtual ~SidebarController (void);
79 // ui::XContextChangeEventListener
80 virtual void SAL_CALL
notifyContextChangeEvent (const css::ui::ContextChangeEventObject
& rEvent
)
81 throw(cssu::RuntimeException
);
84 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEventObject
)
85 throw(cssu::RuntimeException
);
87 // beans::XPropertyChangeListener
88 virtual void SAL_CALL
propertyChange (const css::beans::PropertyChangeEvent
& rEvent
)
89 throw(cssu::RuntimeException
);
91 // frame::XStatusListener
92 virtual void SAL_CALL
statusChanged (const css::frame::FeatureStateEvent
& rEvent
)
93 throw(cssu::RuntimeException
);
96 virtual void SAL_CALL
requestLayout (void)
97 throw(cssu::RuntimeException
);
99 void NotifyResize (void);
101 /** In some situations it is necessary to force an update of the
102 current deck and its panels. One reason is a change of the
103 view scale. Some panels can handle this only when
104 constructed. In this case we have to a context change and
105 also force that all panels are destroyed and created new.
107 const static sal_Int32 SwitchFlag_NoForce
= 0x00;
108 const static sal_Int32 SwitchFlag_ForceSwitch
= 0x01;
109 const static sal_Int32 SwitchFlag_ForceNewDeck
= 0x02;
110 const static sal_Int32 SwitchFlag_ForceNewPanels
= 0x02;
113 const ::rtl::OUString
& rsDeckId
);
114 void OpenThenSwitchToDeck (
115 const ::rtl::OUString
& rsDeckId
);
117 /** Show only the tab bar, not the deck.
119 void RequestCloseDeck (void);
121 /** Open the deck area and restore the parent window to its old width.
123 void RequestOpenDeck (void);
125 FocusManager
& GetFocusManager (void);
128 ::boost::scoped_ptr
<Deck
> mpCurrentDeck
;
129 SidebarDockingWindow
* mpParentWindow
;
130 ::boost::scoped_ptr
<TabBar
> mpTabBar
;
131 cssu::Reference
<css::frame::XFrame
> mxFrame
;
132 Context maCurrentContext
;
133 Context maRequestedContext
;
134 /// Use a combination of SwitchFlag_* as value.
135 sal_Int32 mnRequestedForceFlags
;
136 ::rtl::OUString msCurrentDeckId
;
137 ::rtl::OUString msCurrentDeckTitle
;
138 AsynchronousCall maPropertyChangeForwarder
;
139 AsynchronousCall maContextChangeUpdate
;
141 /** Two flags control whether the deck is displayed or if only the
142 tab bar remains visible.
143 The mbIsDeckOpen flag stores the current state while
144 mbIsDeckRequestedOpen stores how this state should be. User
145 actions like clicking on the deck closer affect the
146 mbIsDeckRequestedOpen. Normally both flags have the same
147 value. A document being read-only can prevent the deck from opening.
149 ::boost::optional
<bool> mbIsDeckRequestedOpen
;
150 ::boost::optional
<bool> mbIsDeckOpen
;
151 bool mbCanDeckBeOpened
;
153 /** Before the deck is closed the sidebar width is saved into this variable,
154 so that it can be restored when the deck is reopended.
156 sal_Int32 mnSavedSidebarWidth
;
157 FocusManager maFocusManager
;
158 cssu::Reference
<css::frame::XDispatch
> mxReadOnlyModeDispatch
;
159 bool mbIsDocumentReadOnly
;
160 SfxSplitWindow
* mpSplitWindow
;
161 /** When the user moves the splitter then we remember the
164 sal_Int32 mnWidthOnSplitterButtonDown
;
165 /** Control that is temporarily used as replacement for the deck
166 to indicate that when the current mouse drag operation ends, the
167 sidebar will only show the tab bar.
169 ::boost::scoped_ptr
<Window
> mpCloseIndicator
;
171 DECL_LINK(WindowEventHandler
, VclWindowEvent
*);
172 /** Make maRequestedContext the current context.
174 void UpdateConfigurations (void);
176 cssu::Reference
<css::ui::XUIElement
> CreateUIElement (
177 const cssu::Reference
<css::awt::XWindowPeer
>& rxWindow
,
178 const ::rtl::OUString
& rsImplementationURL
,
179 const bool bWantsCanvas
,
180 const Context
& rContext
);
181 SharedPanel
CreatePanel (
182 const ::rtl::OUString
& rsPanelId
,
183 ::Window
* pParentWindow
,
184 const bool bIsInitiallyExpanded
,
185 const Context
& rContext
);
187 const DeckDescriptor
& rDeckDescriptor
,
188 const Context
& rContext
);
190 const Rectangle
& rButtonBox
,
191 const ::std::vector
<TabBar::DeckMenuData
>& rMenuData
) const;
192 void ShowDetailMenu (const ::rtl::OUString
& rsMenuCommand
) const;
193 ::boost::shared_ptr
<PopupMenu
> CreatePopupMenu (
194 const ::std::vector
<TabBar::DeckMenuData
>& rMenuData
) const;
195 DECL_LINK(OnMenuItemSelected
, Menu
*);
196 void BroadcastPropertyChange (void);
198 /** The close of the deck changes the width of the child window.
199 That is only possible if there is no other docking window docked above or below the sidebar.
200 Return whether the width of the child window can be modified.
202 bool CanModifyChildWindowWidth (void);
204 /** Set the child window container to a new width.
205 Return the old width.
207 sal_Int32
SetChildWindowWidth (const sal_Int32 nNewWidth
);
209 /** Update the icons displayed in the title bars of the deck and
210 the panels. This is called once when a deck is created and
211 every time when a data change event is processed.
213 void UpdateTitleBarIcons (void);
215 void UpdateDeckOpenState (void);
216 void RestrictWidth (sal_Int32 nWidth
);
217 SfxSplitWindow
* GetSplitWindow (void);
218 void ProcessNewWidth (const sal_Int32 nNewWidth
);
219 void UpdateCloseIndicator (const bool bIsIndicatorVisible
);
221 /** Typically called when a panel is focused via keyboard.
222 Tries to scroll the deck up or down to make the given panel
225 void ShowPanel (const Panel
& rPanel
);
227 Context
GetCurrentContext (void) const;
229 virtual void SAL_CALL
disposing (void);
233 } } // end of namespace sfx2::sidebar