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