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 :
20 :
21 : #include "sfx2/taskpane.hxx"
22 : #include "imagemgr.hxx"
23 : #include "sfx2/sfxsids.hrc"
24 : #include "sfx2/bindings.hxx"
25 : #include "sfx2/dispatch.hxx"
26 : #include "sfxresid.hxx"
27 : #include "sfxlocal.hrc"
28 : #include "helpid.hrc"
29 :
30 : #include <com/sun/star/frame/ModuleManager.hpp>
31 : #include <com/sun/star/container/XNameAccess.hpp>
32 : #include <com/sun/star/ui/XToolPanel.hpp>
33 : #include <com/sun/star/ui/XUIElementFactory.hpp>
34 : #include <com/sun/star/awt/XWindowPeer.hpp>
35 : #include <com/sun/star/awt/PosSize.hpp>
36 : #include <com/sun/star/graphic/GraphicProvider.hpp>
37 : #include <com/sun/star/graphic/XGraphicProvider.hpp>
38 : #include <com/sun/star/accessibility/XAccessible.hpp>
39 : #include <com/sun/star/awt/XControl.hpp>
40 : #include <com/sun/star/ui/UIElementFactoryManager.hpp>
41 :
42 : #include <comphelper/componentcontext.hxx>
43 : #include <comphelper/namedvaluecollection.hxx>
44 : #include <comphelper/types.hxx>
45 : #include <comphelper/processfactory.hxx>
46 : #include <tools/diagnose_ex.h>
47 : #include <svtools/toolpanel/toolpaneldeck.hxx>
48 : #include <svtools/toolpanel/tablayouter.hxx>
49 : #include <svtools/toolpanel/drawerlayouter.hxx>
50 : #include <unotools/confignode.hxx>
51 : #include <vcl/menu.hxx>
52 : #include <vcl/svapp.hxx>
53 : #include <toolkit/helper/vclunohelper.hxx>
54 : #include <tools/urlobj.hxx>
55 : #include <boost/noncopyable.hpp>
56 :
57 : //......................................................................................................................
58 : namespace sfx2
59 : {
60 : //......................................................................................................................
61 :
62 : /** === begin UNO using === **/
63 : using ::com::sun::star::uno::Reference;
64 : using ::com::sun::star::uno::XComponentContext;
65 : using ::com::sun::star::uno::XInterface;
66 : using ::com::sun::star::uno::UNO_QUERY;
67 : using ::com::sun::star::uno::UNO_QUERY_THROW;
68 : using ::com::sun::star::uno::UNO_SET_THROW;
69 : using ::com::sun::star::uno::Exception;
70 : using ::com::sun::star::uno::RuntimeException;
71 : using ::com::sun::star::uno::Any;
72 : using ::com::sun::star::uno::makeAny;
73 : using ::com::sun::star::uno::Sequence;
74 : using ::com::sun::star::uno::Type;
75 : using ::com::sun::star::frame::ModuleManager;
76 : using ::com::sun::star::frame::XModuleManager2;
77 : using ::com::sun::star::container::XNameAccess;
78 : using ::com::sun::star::ui::XToolPanel;
79 : using ::com::sun::star::ui::XUIElementFactory;
80 : using ::com::sun::star::ui::XUIElementFactoryManager;
81 : using ::com::sun::star::ui::UIElementFactoryManager;
82 : using ::com::sun::star::ui::XUIElement;
83 : using ::com::sun::star::awt::XWindow;
84 : using ::com::sun::star::frame::XFrame;
85 : using ::com::sun::star::lang::XComponent;
86 : using ::com::sun::star::graphic::XGraphicProvider;
87 : using ::com::sun::star::graphic::XGraphic;
88 : using ::com::sun::star::accessibility::XAccessible;
89 : using ::com::sun::star::awt::XControl;
90 : /** === end UNO using === **/
91 : namespace PosSize = ::com::sun::star::awt::PosSize;
92 :
93 : //==================================================================================================================
94 : //= helpers
95 : //==================================================================================================================
96 : namespace
97 : {
98 : //--------------------------------------------------------------------------------------------------------------
99 0 : ::utl::OConfigurationTreeRoot lcl_getModuleUIElementStatesConfig( const ::rtl::OUString& i_rModuleIdentifier,
100 : const ::rtl::OUString& i_rResourceURL = ::rtl::OUString() )
101 : {
102 0 : const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
103 0 : ::rtl::OUStringBuffer aPathComposer;
104 : try
105 : {
106 0 : const Reference< XModuleManager2 > xModuleAccess( ModuleManager::create(aContext.getUNOContext()) );
107 0 : const ::comphelper::NamedValueCollection aModuleProps( xModuleAccess->getByName( i_rModuleIdentifier ) );
108 :
109 0 : const ::rtl::OUString sWindowStateRef( aModuleProps.getOrDefault( "ooSetupFactoryWindowStateConfigRef", ::rtl::OUString() ) );
110 :
111 : aPathComposer.appendAscii(RTL_CONSTASCII_STRINGPARAM(
112 0 : "org.openoffice.Office.UI."));
113 0 : aPathComposer.append( sWindowStateRef );
114 0 : aPathComposer.appendAscii(RTL_CONSTASCII_STRINGPARAM("/UIElements/States"));
115 0 : if ( !i_rResourceURL.isEmpty() )
116 : {
117 0 : aPathComposer.append('/').append( i_rResourceURL );
118 0 : }
119 : }
120 0 : catch( const Exception& )
121 : {
122 : DBG_UNHANDLED_EXCEPTION();
123 : }
124 0 : return ::utl::OConfigurationTreeRoot( aContext, aPathComposer.makeStringAndClear(), false );
125 : }
126 :
127 : //--------------------------------------------------------------------------------------------------------------
128 0 : ::rtl::OUString lcl_identifyModule( const Reference< XFrame >& i_rDocumentFrame )
129 : {
130 0 : ::rtl::OUString sModuleName;
131 : try
132 : {
133 0 : const Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
134 0 : const Reference< XModuleManager2 > xModuleManager( ModuleManager::create(xContext) );
135 0 : sModuleName = xModuleManager->identify( i_rDocumentFrame );
136 : }
137 0 : catch( const Exception& )
138 : {
139 : DBG_UNHANDLED_EXCEPTION();
140 : }
141 0 : return sModuleName;
142 : }
143 :
144 : //--------------------------------------------------------------------------------------------------------------
145 0 : Reference< XFrame > lcl_getFrame( const SfxBindings* i_pBindings )
146 : {
147 0 : const SfxViewFrame* pViewFrame = i_pBindings->GetDispatcher()->GetFrame();
148 0 : const SfxFrame& rFrame = pViewFrame->GetFrame();
149 0 : const Reference< XFrame > xFrame( rFrame.GetFrameInterface() );
150 0 : return xFrame;
151 : }
152 :
153 : //--------------------------------------------------------------------------------------------------------------
154 0 : ::rtl::OUString lcl_getPanelHelpURL( const ::utl::OConfigurationNode& i_rPanelConfigNode )
155 : {
156 0 : const ::rtl::OUString sHelpURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "HelpURL" ) ) );
157 0 : return sHelpURL;
158 : }
159 :
160 : //--------------------------------------------------------------------------------------------------------------
161 0 : Image lcl_getPanelImage( const Reference< XFrame >& i_rDocFrame, const ::utl::OConfigurationNode& i_rPanelConfigNode )
162 : {
163 0 : const ::rtl::OUString sImageURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "ImageURL" ) ) );
164 0 : if ( !sImageURL.isEmpty() )
165 : {
166 : try
167 : {
168 0 : ::comphelper::NamedValueCollection aMediaProperties;
169 0 : aMediaProperties.put( "URL", sImageURL );
170 :
171 : // special handling: if the ImageURL denotes a CommandName, then retrieve the image for that command
172 0 : const sal_Char* pCommandImagePrefix = "private:commandimage/";
173 0 : const sal_Int32 nCommandImagePrefixLen = strlen( pCommandImagePrefix );
174 0 : if ( sImageURL.compareToAscii( pCommandImagePrefix, nCommandImagePrefixLen ) == 0 )
175 : {
176 0 : ::rtl::OUStringBuffer aCommandName;
177 0 : aCommandName.appendAscii(RTL_CONSTASCII_STRINGPARAM(".uno:"));
178 0 : aCommandName.append( sImageURL.copy( nCommandImagePrefixLen ) );
179 0 : const ::rtl::OUString sCommandName( aCommandName.makeStringAndClear() );
180 :
181 0 : const Image aPanelImage( GetImage( i_rDocFrame, sCommandName, sal_False ) );
182 0 : return aPanelImage.GetXGraphic();
183 : }
184 :
185 : // otherwise, delegate to the GraphicProvider
186 0 : const Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
187 0 : const Reference< XGraphicProvider > xGraphicProvider( com::sun::star::graphic::GraphicProvider::create(xContext) );
188 :
189 0 : const Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_SET_THROW );
190 0 : return Image( xGraphic );
191 : }
192 0 : catch( const Exception& )
193 : {
194 : DBG_UNHANDLED_EXCEPTION();
195 : }
196 : }
197 0 : return Image();
198 : }
199 : }
200 :
201 : //==================================================================================================================
202 : //= TaskPaneDockingWindow
203 : //==================================================================================================================
204 : //------------------------------------------------------------------------------------------------------------------
205 0 : TaskPaneDockingWindow::TaskPaneDockingWindow( SfxBindings* i_pBindings, TaskPaneWrapper& i_rWrapper, Window* i_pParent, WinBits i_nBits )
206 : :TitledDockingWindow( i_pBindings, &i_rWrapper, i_pParent, i_nBits )
207 0 : ,m_aTaskPane( GetContentWindow(), lcl_getFrame( i_pBindings ) )
208 0 : ,m_aPaneController( m_aTaskPane, *this )
209 : {
210 0 : m_aTaskPane.Show();
211 0 : SetText( SfxResId( SID_TASKPANE ).toString() );
212 0 : }
213 :
214 : //------------------------------------------------------------------------------------------------------------------
215 0 : void TaskPaneDockingWindow::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
216 : {
217 0 : m_aPaneController.ActivateToolPanel( i_rPanelURL );
218 0 : }
219 :
220 : //------------------------------------------------------------------------------------------------------------------
221 0 : void TaskPaneDockingWindow::GetFocus()
222 : {
223 0 : TitledDockingWindow::GetFocus();
224 0 : m_aTaskPane.GrabFocus();
225 0 : }
226 :
227 : //------------------------------------------------------------------------------------------------------------------
228 0 : void TaskPaneDockingWindow::onLayoutDone()
229 : {
230 0 : m_aTaskPane.SetPosSizePixel( Point(), GetContentWindow().GetOutputSizePixel() );
231 0 : }
232 :
233 : //==================================================================================================================
234 : //= TaskPaneWrapper
235 : //==================================================================================================================
236 : //------------------------------------------------------------------------------------------------------------------
237 19 : SFX_IMPL_DOCKINGWINDOW( TaskPaneWrapper, SID_TASKPANE );
238 :
239 : //------------------------------------------------------------------------------------------------------------------
240 0 : TaskPaneWrapper::TaskPaneWrapper( Window* i_pParent, sal_uInt16 i_nId, SfxBindings* i_pBindings, SfxChildWinInfo* i_pInfo )
241 0 : :SfxChildWindow( i_pParent, i_nId )
242 : {
243 : pWindow = new TaskPaneDockingWindow( i_pBindings, *this, i_pParent,
244 0 : WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE);
245 0 : eChildAlignment = SFX_ALIGN_RIGHT;
246 :
247 0 : pWindow->SetHelpId( HID_TASKPANE_WINDOW );
248 0 : pWindow->SetOutputSizePixel( Size( 300, 450 ) );
249 :
250 0 : dynamic_cast< SfxDockingWindow* >( pWindow )->Initialize( i_pInfo );
251 0 : SetHideNotDelete( sal_True );
252 :
253 0 : pWindow->Show();
254 0 : }
255 :
256 : //------------------------------------------------------------------------------------------------------------------
257 0 : void TaskPaneWrapper::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
258 : {
259 0 : TaskPaneDockingWindow* pDockingWindow = dynamic_cast< TaskPaneDockingWindow* >( GetWindow() );
260 0 : ENSURE_OR_RETURN_VOID( pDockingWindow, "TaskPaneWrapper::ActivateToolPanel: invalid docking window implementation!" );
261 0 : pDockingWindow->ActivateToolPanel( i_rPanelURL );
262 : }
263 :
264 : //==================================================================================================================
265 : //= CustomPanelUIElement
266 : //==================================================================================================================
267 0 : class CustomPanelUIElement
268 : {
269 : public:
270 0 : CustomPanelUIElement()
271 : :m_xUIElement()
272 : ,m_xToolPanel()
273 0 : ,m_xPanelWindow()
274 : {
275 0 : }
276 :
277 0 : CustomPanelUIElement( const Reference< XUIElement >& i_rUIElement )
278 : :m_xUIElement( i_rUIElement, UNO_SET_THROW )
279 0 : ,m_xToolPanel( i_rUIElement->getRealInterface(), UNO_QUERY_THROW )
280 0 : ,m_xPanelWindow( m_xToolPanel->getWindow(), UNO_SET_THROW )
281 : {
282 0 : }
283 :
284 0 : bool is() const { return m_xPanelWindow.is(); }
285 :
286 0 : const Reference< XUIElement >& getUIElement() const { return m_xUIElement; }
287 0 : const Reference< XToolPanel >& getToolPanel() const { return m_xToolPanel; }
288 0 : const Reference< XWindow >& getPanelWindow() const { return m_xPanelWindow; }
289 :
290 : private:
291 : Reference< XUIElement > m_xUIElement;
292 : Reference< XToolPanel > m_xToolPanel;
293 : Reference< XWindow > m_xPanelWindow;
294 : };
295 :
296 : //==================================================================================================================
297 : //= CustomToolPanel
298 : //==================================================================================================================
299 : class CustomToolPanel : public ::svt::ToolPanelBase
300 : {
301 : public:
302 : CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame );
303 :
304 : virtual ::rtl::OUString GetDisplayName() const;
305 : virtual Image GetImage() const;
306 : virtual rtl::OString GetHelpID() const;
307 : virtual void Activate( Window& i_rParentWindow );
308 : virtual void Deactivate();
309 : virtual void SetSizePixel( const Size& i_rPanelWindowSize );
310 : virtual void GrabFocus();
311 : virtual void Dispose();
312 : virtual Reference< XAccessible >
313 : CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible );
314 :
315 : const ::rtl::OUString&
316 0 : GetResourceURL() const { return m_sResourceURL; }
317 :
318 : protected:
319 : ~CustomToolPanel();
320 :
321 : private:
322 : bool impl_ensureToolPanelWindow( Window& i_rPanelParentWindow );
323 : void impl_updatePanelConfig( const bool i_bVisible ) const;
324 :
325 : private:
326 : const ::rtl::OUString m_sUIName;
327 : const Image m_aPanelImage;
328 : const ::rtl::OUString m_aPanelHelpURL;
329 : const ::rtl::OUString m_sResourceURL;
330 : const ::rtl::OUString m_sPanelConfigPath;
331 : Reference< XFrame > m_xFrame;
332 : CustomPanelUIElement m_aCustomPanel;
333 : bool m_bAttemptedCreation;
334 : };
335 :
336 : //------------------------------------------------------------------------------------------------------------------
337 0 : CustomToolPanel::CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame )
338 : :m_sUIName( ::comphelper::getString( i_rPanelWindowState.getNodeValue( "UIName" ) ) )
339 : ,m_aPanelImage( lcl_getPanelImage( i_rFrame, i_rPanelWindowState ) )
340 : ,m_aPanelHelpURL( lcl_getPanelHelpURL( i_rPanelWindowState ) )
341 : ,m_sResourceURL( i_rPanelWindowState.getLocalName() )
342 : ,m_sPanelConfigPath( i_rPanelWindowState.getNodePath() )
343 : ,m_xFrame( i_rFrame )
344 : ,m_aCustomPanel()
345 0 : ,m_bAttemptedCreation( false )
346 : {
347 0 : }
348 :
349 : //------------------------------------------------------------------------------------------------------------------
350 0 : CustomToolPanel::~CustomToolPanel()
351 : {
352 0 : }
353 :
354 : //------------------------------------------------------------------------------------------------------------------
355 0 : bool CustomToolPanel::impl_ensureToolPanelWindow( Window& i_rPanelParentWindow )
356 : {
357 0 : if ( m_bAttemptedCreation )
358 0 : return m_aCustomPanel.is();
359 :
360 0 : m_bAttemptedCreation = true;
361 : try
362 : {
363 0 : const Reference< XUIElementFactoryManager > xFactory = UIElementFactoryManager::create( ::comphelper::getProcessComponentContext() );
364 :
365 0 : ::comphelper::NamedValueCollection aCreationArgs;
366 0 : aCreationArgs.put( "Frame", makeAny( m_xFrame ) );
367 0 : aCreationArgs.put( "ParentWindow", makeAny( i_rPanelParentWindow.GetComponentInterface() ) );
368 :
369 : const Reference< XUIElement > xElement(
370 0 : xFactory->createUIElement( m_sResourceURL, aCreationArgs.getPropertyValues() ),
371 0 : UNO_SET_THROW );
372 :
373 0 : m_aCustomPanel = CustomPanelUIElement( xElement );
374 : }
375 0 : catch( const Exception& )
376 : {
377 : DBG_UNHANDLED_EXCEPTION();
378 : }
379 0 : return m_aCustomPanel.is();
380 : }
381 :
382 : //------------------------------------------------------------------------------------------------------------------
383 0 : void CustomToolPanel::impl_updatePanelConfig( const bool i_bVisible ) const
384 : {
385 0 : ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
386 0 : ::utl::OConfigurationTreeRoot aConfig( aContext, m_sPanelConfigPath, true );
387 :
388 0 : aConfig.setNodeValue( "Visible", makeAny( i_bVisible ) );
389 0 : aConfig.commit();
390 0 : }
391 :
392 : //------------------------------------------------------------------------------------------------------------------
393 0 : ::rtl::OUString CustomToolPanel::GetDisplayName() const
394 : {
395 0 : return m_sUIName;
396 : }
397 :
398 : //------------------------------------------------------------------------------------------------------------------
399 0 : Image CustomToolPanel::GetImage() const
400 : {
401 0 : return m_aPanelImage;
402 : }
403 :
404 0 : static rtl::OString lcl_getHelpId( const ::rtl::OUString& _rHelpURL )
405 : {
406 0 : INetURLObject aHID( _rHelpURL );
407 0 : if ( aHID.GetProtocol() == INET_PROT_HID )
408 0 : return rtl::OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 );
409 : else
410 0 : return rtl::OUStringToOString( _rHelpURL, RTL_TEXTENCODING_UTF8 );
411 : }
412 :
413 : //------------------------------------------------------------------------------------------------------------------
414 0 : rtl::OString CustomToolPanel::GetHelpID() const
415 : {
416 0 : return lcl_getHelpId( m_aPanelHelpURL );
417 : }
418 :
419 : //------------------------------------------------------------------------------------------------------------------
420 0 : void CustomToolPanel::Activate( Window& i_rParentWindow )
421 : {
422 0 : ENSURE_OR_RETURN_VOID( impl_ensureToolPanelWindow( i_rParentWindow ), "no panel to activate!" );
423 :
424 : // TODO: we might need a mechanism to decide whether the panel should be destroyed/re-created, or (as it is
425 : // done now) hidden/shown
426 0 : m_aCustomPanel.getPanelWindow()->setVisible( sal_True );
427 :
428 : // update the panel's configuration
429 0 : impl_updatePanelConfig( true );
430 : }
431 :
432 : //------------------------------------------------------------------------------------------------------------------
433 0 : void CustomToolPanel::Deactivate()
434 : {
435 0 : ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to deactivate!" );
436 :
437 0 : m_aCustomPanel.getPanelWindow()->setVisible( sal_False );
438 :
439 : // update the panel's configuration
440 0 : impl_updatePanelConfig( false );
441 : }
442 :
443 : //------------------------------------------------------------------------------------------------------------------
444 0 : void CustomToolPanel::SetSizePixel( const Size& i_rPanelWindowSize )
445 : {
446 0 : ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to position!" );
447 :
448 : try
449 : {
450 0 : m_aCustomPanel.getPanelWindow()->setPosSize( 0, 0, i_rPanelWindowSize.Width(), i_rPanelWindowSize.Height(),
451 0 : PosSize::POSSIZE );
452 : }
453 0 : catch( const Exception& )
454 : {
455 : DBG_UNHANDLED_EXCEPTION();
456 : }
457 : }
458 :
459 : //------------------------------------------------------------------------------------------------------------------
460 0 : void CustomToolPanel::GrabFocus()
461 : {
462 0 : ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to focus!" );
463 :
464 0 : m_aCustomPanel.getPanelWindow()->setFocus();
465 : }
466 :
467 : //------------------------------------------------------------------------------------------------------------------
468 0 : void CustomToolPanel::Dispose()
469 : {
470 0 : if ( !m_bAttemptedCreation )
471 : // nothing to dispose
472 0 : return;
473 :
474 0 : ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to destroy!" );
475 : try
476 : {
477 0 : Reference< XComponent > xUIElementComponent( m_aCustomPanel.getUIElement(), UNO_QUERY_THROW );
478 0 : xUIElementComponent->dispose();
479 : }
480 0 : catch( const Exception& )
481 : {
482 : DBG_UNHANDLED_EXCEPTION();
483 : }
484 : }
485 :
486 : //------------------------------------------------------------------------------------------------------------------
487 0 : Reference< XAccessible > CustomToolPanel::CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible )
488 : {
489 0 : ENSURE_OR_RETURN( m_aCustomPanel.is(), "no panel to ask!", NULL );
490 :
491 0 : Reference< XAccessible > xPanelAccessible;
492 : try
493 : {
494 0 : xPanelAccessible.set( m_aCustomPanel.getToolPanel()->createAccessible( i_rParentAccessible ), UNO_SET_THROW );
495 : }
496 0 : catch( const Exception& )
497 : {
498 : DBG_UNHANDLED_EXCEPTION();
499 : }
500 0 : return xPanelAccessible;
501 : }
502 :
503 : //==================================================================================================================
504 : //= ModuleTaskPane_Impl
505 : //==================================================================================================================
506 : class ModuleTaskPane_Impl : public ::boost::noncopyable
507 : {
508 : public:
509 0 : ModuleTaskPane_Impl( ModuleTaskPane& i_rAntiImpl, const Reference< XFrame >& i_rDocumentFrame,
510 : const IToolPanelCompare* i_pPanelCompare )
511 : :m_rAntiImpl( i_rAntiImpl )
512 : ,m_sModuleIdentifier( lcl_identifyModule( i_rDocumentFrame ) )
513 : ,m_xFrame( i_rDocumentFrame )
514 0 : ,m_aPanelDeck( i_rAntiImpl )
515 : {
516 0 : m_aPanelDeck.Show();
517 0 : OnResize();
518 0 : impl_initFromConfiguration( i_pPanelCompare );
519 0 : }
520 :
521 0 : ~ModuleTaskPane_Impl()
522 0 : {
523 0 : }
524 :
525 : void OnResize();
526 : void OnGetFocus();
527 :
528 : static bool ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier );
529 :
530 0 : ::svt::ToolPanelDeck& GetPanelDeck() { return m_aPanelDeck; }
531 : const ::svt::ToolPanelDeck& GetPanelDeck() const { return m_aPanelDeck; }
532 :
533 : ::boost::optional< size_t >
534 : GetPanelPos( const ::rtl::OUString& i_rResourceURL );
535 : ::rtl::OUString
536 : GetPanelResourceURL( const size_t i_nPanelPos ) const;
537 :
538 : void SetDrawersLayout();
539 : void SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent );
540 :
541 : private:
542 : void impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare );
543 :
544 : static bool
545 : impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL );
546 :
547 : DECL_LINK( OnActivatePanel, void* );
548 :
549 : private:
550 : ModuleTaskPane& m_rAntiImpl;
551 : const ::rtl::OUString m_sModuleIdentifier;
552 : const Reference< XFrame > m_xFrame;
553 : ::svt::ToolPanelDeck m_aPanelDeck;
554 : };
555 :
556 : //------------------------------------------------------------------------------------------------------------------
557 0 : void ModuleTaskPane_Impl::OnResize()
558 : {
559 0 : m_aPanelDeck.SetPosSizePixel( Point(), m_rAntiImpl.GetOutputSizePixel() );
560 0 : }
561 :
562 : //------------------------------------------------------------------------------------------------------------------
563 0 : void ModuleTaskPane_Impl::OnGetFocus()
564 : {
565 0 : m_aPanelDeck.GrabFocus();
566 0 : }
567 :
568 : //------------------------------------------------------------------------------------------------------------------
569 0 : IMPL_LINK( ModuleTaskPane_Impl, OnActivatePanel, void*, i_pArg )
570 : {
571 0 : m_aPanelDeck.ActivatePanel( reinterpret_cast< size_t >( i_pArg ) );
572 0 : return 1L;
573 : }
574 :
575 : //------------------------------------------------------------------------------------------------------------------
576 0 : bool ModuleTaskPane_Impl::impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL )
577 : {
578 0 : return i_rResourceURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/" ) );
579 : }
580 :
581 : //------------------------------------------------------------------------------------------------------------------
582 0 : void ModuleTaskPane_Impl::impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare )
583 : {
584 0 : const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( m_sModuleIdentifier ) );
585 0 : if ( !aWindowStateConfig.isValid() )
586 0 : return;
587 :
588 0 : ::rtl::OUString sFirstVisiblePanelResource;
589 0 : ::rtl::OUString sFirstPanelResource;
590 :
591 0 : const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() );
592 0 : for ( const ::rtl::OUString* resource = aUIElements.getConstArray();
593 0 : resource != aUIElements.getConstArray() + aUIElements.getLength();
594 : ++resource
595 : )
596 : {
597 0 : if ( !impl_isToolPanelResource( *resource ) )
598 0 : continue;
599 :
600 0 : sFirstPanelResource = *resource;
601 :
602 0 : ::utl::OConfigurationNode aResourceNode( aWindowStateConfig.openNode( *resource ) );
603 0 : ::svt::PToolPanel pCustomPanel( new CustomToolPanel( aResourceNode, m_xFrame ) );
604 :
605 0 : size_t nPanelPos = m_aPanelDeck.GetPanelCount();
606 0 : if ( i_pPanelCompare )
607 : {
608 : // assuming that nobody will insert hundreths of panels, a simple O(n) search should suffice here ...
609 0 : while ( nPanelPos > 0 )
610 : {
611 : const short nCompare = i_pPanelCompare->compareToolPanelsURLs(
612 : *resource,
613 : GetPanelResourceURL( --nPanelPos )
614 0 : );
615 0 : if ( nCompare >= 0 )
616 : {
617 0 : ++nPanelPos;
618 0 : break;
619 : }
620 : }
621 : }
622 0 : nPanelPos = m_aPanelDeck.InsertPanel( pCustomPanel, nPanelPos );
623 :
624 0 : if ( ::comphelper::getBOOL( aResourceNode.getNodeValue( "Visible" ) ) )
625 0 : sFirstVisiblePanelResource = *resource;
626 0 : }
627 :
628 0 : if ( sFirstVisiblePanelResource.isEmpty() )
629 0 : sFirstVisiblePanelResource = sFirstPanelResource;
630 :
631 0 : if ( !sFirstVisiblePanelResource.isEmpty() )
632 : {
633 0 : ::boost::optional< size_t > aPanelPos( GetPanelPos( sFirstVisiblePanelResource ) );
634 : OSL_ENSURE( !!aPanelPos, "ModuleTaskPane_Impl::impl_isToolPanelResource: just inserted it, and it's not there?!" );
635 0 : if ( !!aPanelPos )
636 0 : m_rAntiImpl.PostUserEvent( LINK( this, ModuleTaskPane_Impl, OnActivatePanel ), reinterpret_cast< void* >( *aPanelPos ) );
637 0 : }
638 : }
639 :
640 : //------------------------------------------------------------------------------------------------------------------
641 0 : bool ModuleTaskPane_Impl::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier )
642 : {
643 0 : const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( i_rModuleIdentifier ) );
644 0 : if ( !aWindowStateConfig.isValid() )
645 0 : return false;
646 :
647 0 : const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() );
648 0 : for ( const ::rtl::OUString* resource = aUIElements.getConstArray();
649 0 : resource != aUIElements.getConstArray() + aUIElements.getLength();
650 : ++resource
651 : )
652 : {
653 0 : if ( impl_isToolPanelResource( *resource ) )
654 0 : return true;
655 : }
656 0 : return false;
657 : }
658 :
659 : //------------------------------------------------------------------------------------------------------------------
660 0 : ::boost::optional< size_t > ModuleTaskPane_Impl::GetPanelPos( const ::rtl::OUString& i_rResourceURL )
661 : {
662 0 : ::boost::optional< size_t > aPanelPos;
663 0 : for ( size_t i = 0; i < m_aPanelDeck.GetPanelCount(); ++i )
664 : {
665 0 : const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i ) );
666 0 : const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() );
667 0 : if ( !pCustomPanel )
668 : {
669 : SAL_WARN( "sfx2.dialog", "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!" );
670 0 : continue;
671 : }
672 :
673 0 : if ( pCustomPanel->GetResourceURL() == i_rResourceURL )
674 : {
675 0 : aPanelPos = i;
676 : break;
677 : }
678 0 : }
679 0 : return aPanelPos;
680 : }
681 :
682 : //------------------------------------------------------------------------------------------------------------------
683 0 : ::rtl::OUString ModuleTaskPane_Impl::GetPanelResourceURL( const size_t i_nPanelPos ) const
684 : {
685 0 : ENSURE_OR_RETURN( i_nPanelPos < m_aPanelDeck.GetPanelCount(), "ModuleTaskPane_Impl::GetPanelResourceURL: illegal panel position!", ::rtl::OUString() );
686 0 : const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i_nPanelPos ) );
687 0 : const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() );
688 0 : ENSURE_OR_RETURN( pCustomPanel != NULL, "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!", ::rtl::OUString() );
689 0 : return pCustomPanel->GetResourceURL();
690 : }
691 :
692 : //------------------------------------------------------------------------------------------------------------------
693 0 : void ModuleTaskPane_Impl::SetDrawersLayout()
694 : {
695 0 : const ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() );
696 0 : const ::svt::DrawerDeckLayouter* pDrawerLayouter = dynamic_cast< const ::svt::DrawerDeckLayouter* >( pLayouter.get() );
697 0 : if ( pDrawerLayouter != NULL )
698 : // already have the proper layout
699 0 : return;
700 0 : m_aPanelDeck.SetLayouter( new ::svt::DrawerDeckLayouter( m_aPanelDeck, m_aPanelDeck ) );
701 : }
702 :
703 : //------------------------------------------------------------------------------------------------------------------
704 0 : void ModuleTaskPane_Impl::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent )
705 : {
706 0 : ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() );
707 0 : ::svt::TabDeckLayouter* pTabLayouter = dynamic_cast< ::svt::TabDeckLayouter* >( pLayouter.get() );
708 0 : if ( ( pTabLayouter != NULL )
709 0 : && ( pTabLayouter->GetTabAlignment() == i_eTabAlignment )
710 0 : && ( pTabLayouter->GetTabItemContent() == i_eTabContent )
711 : )
712 : // already have the requested layout
713 : return;
714 :
715 0 : if ( pTabLayouter && ( pTabLayouter->GetTabAlignment() == i_eTabAlignment ) )
716 : {
717 : // changing only the item content does not require a new layouter instance
718 0 : pTabLayouter->SetTabItemContent( i_eTabContent );
719 : return;
720 : }
721 :
722 0 : m_aPanelDeck.SetLayouter( new ::svt::TabDeckLayouter( m_aPanelDeck, m_aPanelDeck, i_eTabAlignment, i_eTabContent ) );
723 : }
724 :
725 : //==================================================================================================================
726 : //= ModuleTaskPane
727 : //==================================================================================================================
728 : //------------------------------------------------------------------------------------------------------------------
729 0 : ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame )
730 : :Window( &i_rParentWindow, WB_DIALOGCONTROL )
731 0 : ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, NULL ) )
732 : {
733 0 : }
734 :
735 : //------------------------------------------------------------------------------------------------------------------
736 0 : ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame,
737 : const IToolPanelCompare& i_rCompare )
738 : :Window( &i_rParentWindow, WB_DIALOGCONTROL )
739 0 : ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, &i_rCompare ) )
740 : {
741 0 : }
742 :
743 : //------------------------------------------------------------------------------------------------------------------
744 0 : ModuleTaskPane::~ModuleTaskPane()
745 : {
746 0 : }
747 :
748 : //------------------------------------------------------------------------------------------------------------------
749 0 : bool ModuleTaskPane::ModuleHasToolPanels( const Reference< XFrame >& i_rDocumentFrame )
750 : {
751 0 : return ModuleTaskPane_Impl::ModuleHasToolPanels( lcl_identifyModule( i_rDocumentFrame ) );
752 : }
753 :
754 : //------------------------------------------------------------------------------------------------------------------
755 0 : void ModuleTaskPane::Resize()
756 : {
757 0 : Window::Resize();
758 0 : m_pImpl->OnResize();
759 0 : }
760 :
761 : //------------------------------------------------------------------------------------------------------------------
762 0 : void ModuleTaskPane::GetFocus()
763 : {
764 0 : Window::GetFocus();
765 0 : m_pImpl->OnGetFocus();
766 0 : }
767 :
768 : //------------------------------------------------------------------------------------------------------------------
769 0 : ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck()
770 : {
771 0 : return m_pImpl->GetPanelDeck();
772 : }
773 :
774 : //------------------------------------------------------------------------------------------------------------------
775 0 : const ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck() const
776 : {
777 0 : return m_pImpl->GetPanelDeck();
778 : }
779 :
780 : //------------------------------------------------------------------------------------------------------------------
781 0 : ::boost::optional< size_t > ModuleTaskPane::GetPanelPos( const ::rtl::OUString& i_rResourceURL )
782 : {
783 0 : return m_pImpl->GetPanelPos( i_rResourceURL );
784 : }
785 :
786 : //------------------------------------------------------------------------------------------------------------------
787 0 : ::rtl::OUString ModuleTaskPane::GetPanelResourceURL( const size_t i_nPanelPos ) const
788 : {
789 0 : return m_pImpl->GetPanelResourceURL( i_nPanelPos );
790 : }
791 :
792 : //------------------------------------------------------------------------------------------------------------------
793 0 : void ModuleTaskPane::SetDrawersLayout()
794 : {
795 0 : m_pImpl->SetDrawersLayout();
796 0 : }
797 :
798 : //------------------------------------------------------------------------------------------------------------------
799 0 : void ModuleTaskPane::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent )
800 : {
801 0 : m_pImpl->SetTabsLayout( i_eTabAlignment, i_eTabContent );
802 0 : }
803 :
804 : // =====================================================================================================================
805 : // = PanelSelectorLayout
806 : // =====================================================================================================================
807 : enum PanelSelectorLayout
808 : {
809 : LAYOUT_DRAWERS,
810 : LAYOUT_TABS_RIGHT,
811 : LAYOUT_TABS_LEFT,
812 : LAYOUT_TABS_TOP,
813 : LAYOUT_TABS_BOTTOM
814 : };
815 :
816 : //==================================================================================================================
817 : //= helper
818 : //==================================================================================================================
819 : namespace
820 : {
821 0 : PanelSelectorLayout lcl_getTabLayoutFromAlignment( const SfxChildAlignment i_eAlignment )
822 : {
823 0 : switch ( i_eAlignment )
824 : {
825 : case SFX_ALIGN_LEFT:
826 0 : return LAYOUT_TABS_LEFT;
827 : case SFX_ALIGN_TOP:
828 0 : return LAYOUT_TABS_TOP;
829 : case SFX_ALIGN_BOTTOM:
830 0 : return LAYOUT_TABS_BOTTOM;
831 : default:
832 0 : return LAYOUT_TABS_RIGHT;
833 : }
834 : }
835 : }
836 :
837 : // =====================================================================================================================
838 : // = PanelDescriptor
839 : // =====================================================================================================================
840 : /** is a helper class for TaskPaneController_Impl, holding the details about a single panel which is not
841 : contained in the IToolPanel implementation itself.
842 : */
843 0 : struct PanelDescriptor
844 : {
845 : ::svt::PToolPanel pPanel;
846 : bool bHidden;
847 :
848 : PanelDescriptor()
849 : :pPanel()
850 : ,bHidden( false )
851 : {
852 : }
853 :
854 0 : PanelDescriptor( const ::svt::PToolPanel& i_rPanel )
855 : :pPanel( i_rPanel )
856 0 : ,bHidden( false )
857 : {
858 0 : }
859 : };
860 :
861 : //==================================================================================================================
862 : //= TaskPaneController_Impl
863 : //==================================================================================================================
864 : class TaskPaneController_Impl :public ::boost::noncopyable
865 : ,public ::svt::IToolPanelDeckListener
866 : {
867 : public:
868 : TaskPaneController_Impl(
869 : ModuleTaskPane& i_rTaskPane,
870 : TitledDockingWindow& i_rDockingWindow
871 : );
872 : virtual ~TaskPaneController_Impl();
873 :
874 : void SetDefaultTitle( const String& i_rTitle );
875 : void ActivateToolPanel( const ::rtl::OUString& i_rPanelURL );
876 :
877 : protected:
878 : // IToolPanelDeckListener overridables
879 : virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition );
880 : virtual void PanelRemoved( const size_t i_nPosition );
881 : virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
882 : virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter );
883 : virtual void Dying();
884 :
885 : private:
886 : DECL_LINK( OnToolboxClicked, ToolBox* );
887 : DECL_LINK( OnMenuItemSelected, Menu* );
888 : DECL_LINK( DockingChanged, TitledDockingWindow* );
889 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
890 : ::std::auto_ptr< PopupMenu > impl_createPopupMenu() const;
891 : SAL_WNODEPRECATED_DECLARATIONS_POP
892 :
893 : /// sets the given layout for the panel selector
894 : void impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce = false );
895 :
896 : /// returns the current layout of the panel selector
897 : PanelSelectorLayout
898 0 : impl_getLayout() const { return m_eCurrentLayout; }
899 :
900 : void impl_updateDockingWindowTitle();
901 : void impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex );
902 : size_t impl_getLogicalPanelIndex( const size_t i_nVisibleIndex );
903 :
904 : private:
905 : enum MenuId
906 : {
907 : MID_UNLOCK_TASK_PANEL = 1,
908 : MID_LOCK_TASK_PANEL = 2,
909 : MID_LAYOUT_TABS = 3,
910 : MID_LAYOUT_DRAWERS = 4,
911 : MID_FIRST_PANEL = 5
912 : };
913 :
914 : private:
915 : typedef ::std::vector< PanelDescriptor > PanelDescriptors;
916 :
917 : ModuleTaskPane& m_rTaskPane;
918 : TitledDockingWindow& m_rDockingWindow;
919 : sal_uInt16 m_nViewMenuID;
920 : PanelSelectorLayout m_eCurrentLayout;
921 : PanelDescriptors m_aPanelRepository;
922 : bool m_bTogglingPanelVisibility;
923 : ::rtl::OUString m_sDefaultTitle;
924 : };
925 :
926 : //------------------------------------------------------------------------------------------------------------------
927 0 : TaskPaneController_Impl::TaskPaneController_Impl( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow )
928 : :m_rTaskPane( i_rTaskPane )
929 : ,m_rDockingWindow( i_rDockingWindow )
930 : ,m_nViewMenuID( 0 )
931 : ,m_eCurrentLayout( LAYOUT_DRAWERS )
932 : ,m_aPanelRepository()
933 : ,m_bTogglingPanelVisibility( false )
934 0 : ,m_sDefaultTitle()
935 : {
936 0 : m_rDockingWindow.ResetToolBox();
937 : m_nViewMenuID = m_rDockingWindow.AddDropDownToolBoxItem(
938 : SfxResId( STR_SFX_TASK_PANE_VIEW ).toString(),
939 : HID_TASKPANE_VIEW_MENU,
940 : LINK( this, TaskPaneController_Impl, OnToolboxClicked )
941 0 : );
942 0 : m_rDockingWindow.SetEndDockingHdl( LINK( this, TaskPaneController_Impl, DockingChanged ) );
943 0 : impl_setLayout( LAYOUT_DRAWERS, true );
944 :
945 0 : m_rTaskPane.GetPanelDeck().AddListener( *this );
946 :
947 : // initialize the panel repository
948 0 : for ( size_t i = 0; i < m_rTaskPane.GetPanelDeck().GetPanelCount(); ++i )
949 : {
950 0 : ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( i ) );
951 0 : m_aPanelRepository.push_back( PanelDescriptor( pPanel ) );
952 0 : }
953 :
954 0 : SetDefaultTitle( SfxResId( STR_SFX_TASKS ).toString() );
955 0 : }
956 :
957 : //------------------------------------------------------------------------------------------------------------------
958 0 : TaskPaneController_Impl::~TaskPaneController_Impl()
959 : {
960 0 : m_rTaskPane.GetPanelDeck().RemoveListener( *this );
961 0 : int i = 0;
962 :
963 : // remove the panels which are not under the control of the panel deck currently
964 0 : for ( PanelDescriptors::iterator panelPos = m_aPanelRepository.begin();
965 0 : panelPos != m_aPanelRepository.end();
966 : ++panelPos, ++i
967 : )
968 : {
969 0 : if ( panelPos->bHidden )
970 0 : impl_togglePanelVisibility( i );
971 : }
972 0 : m_aPanelRepository.clear();
973 0 : }
974 :
975 : // -----------------------------------------------------------------------------------------------------------------
976 0 : void TaskPaneController_Impl::SetDefaultTitle( const String& i_rTitle )
977 : {
978 0 : m_sDefaultTitle = i_rTitle;
979 0 : impl_updateDockingWindowTitle();
980 0 : }
981 :
982 : //------------------------------------------------------------------------------------------------------------------
983 0 : void TaskPaneController_Impl::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
984 : {
985 0 : ::boost::optional< size_t > aPanelPos( m_rTaskPane.GetPanelPos( i_rPanelURL ) );
986 0 : ENSURE_OR_RETURN_VOID( !!aPanelPos, "TaskPaneController_Impl::ActivateToolPanel: no such panel!" );
987 :
988 0 : if ( aPanelPos == m_rTaskPane.GetPanelDeck().GetActivePanel() )
989 : {
990 0 : ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( *aPanelPos ) );
991 0 : pPanel->GrabFocus();
992 : }
993 : else
994 : {
995 0 : m_rTaskPane.GetPanelDeck().ActivatePanel( aPanelPos );
996 0 : }
997 : }
998 :
999 : // -----------------------------------------------------------------------------------------------------------------
1000 0 : IMPL_LINK( TaskPaneController_Impl, DockingChanged, TitledDockingWindow*, i_pDockingWindow )
1001 : {
1002 0 : ENSURE_OR_RETURN( i_pDockingWindow && &m_rDockingWindow, "TaskPaneController_Impl::DockingChanged: where does this come from?", 0L );
1003 :
1004 0 : if ( impl_getLayout() == LAYOUT_DRAWERS )
1005 0 : return 0L;
1006 :
1007 0 : impl_setLayout( lcl_getTabLayoutFromAlignment( i_pDockingWindow->GetAlignment() ) );
1008 0 : return 1L;
1009 : }
1010 :
1011 : // -----------------------------------------------------------------------------------------------------------------
1012 0 : IMPL_LINK( TaskPaneController_Impl, OnToolboxClicked, ToolBox*, i_pToolBox )
1013 : {
1014 0 : if ( i_pToolBox->GetCurItemId() == m_nViewMenuID )
1015 : {
1016 0 : i_pToolBox->EndSelection();
1017 :
1018 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1019 0 : ::std::auto_ptr< PopupMenu > pMenu = impl_createPopupMenu();
1020 : SAL_WNODEPRECATED_DECLARATIONS_POP
1021 0 : pMenu->SetSelectHdl( LINK( this, TaskPaneController_Impl, OnMenuItemSelected ) );
1022 :
1023 : // pass toolbox button rect so the menu can stay open on button up
1024 0 : Rectangle aMenuRect( i_pToolBox->GetItemRect( m_nViewMenuID ) );
1025 0 : aMenuRect.SetPos( i_pToolBox->GetPosPixel() );
1026 0 : pMenu->Execute( &m_rDockingWindow, aMenuRect, POPUPMENU_EXECUTE_DOWN );
1027 : }
1028 :
1029 0 : return 0;
1030 : }
1031 :
1032 : // ---------------------------------------------------------------------------------------------------------------------
1033 0 : IMPL_LINK( TaskPaneController_Impl, OnMenuItemSelected, Menu*, i_pMenu )
1034 : {
1035 0 : ENSURE_OR_RETURN( i_pMenu, "TaskPaneController_Impl::OnMenuItemSelected: illegal menu!", 0L );
1036 :
1037 0 : i_pMenu->Deactivate();
1038 0 : switch ( i_pMenu->GetCurItemId() )
1039 : {
1040 : case MID_UNLOCK_TASK_PANEL:
1041 0 : m_rDockingWindow.SetFloatingMode( sal_True );
1042 0 : break;
1043 :
1044 : case MID_LOCK_TASK_PANEL:
1045 0 : m_rDockingWindow.SetFloatingMode( sal_False );
1046 0 : break;
1047 :
1048 : case MID_LAYOUT_DRAWERS:
1049 0 : impl_setLayout( LAYOUT_DRAWERS );
1050 0 : break;
1051 :
1052 : case MID_LAYOUT_TABS:
1053 0 : impl_setLayout( lcl_getTabLayoutFromAlignment( m_rDockingWindow.GetAlignment() ) );
1054 0 : break;
1055 :
1056 : default:
1057 : {
1058 0 : size_t nPanelIndex = size_t( i_pMenu->GetCurItemId() - MID_FIRST_PANEL );
1059 0 : impl_togglePanelVisibility( nPanelIndex );
1060 : }
1061 0 : break;
1062 : }
1063 :
1064 0 : return 1L;
1065 : }
1066 :
1067 : // ---------------------------------------------------------------------------------------------------------------------
1068 0 : size_t TaskPaneController_Impl::impl_getLogicalPanelIndex( const size_t i_nVisibleIndex )
1069 : {
1070 0 : size_t nLogicalIndex = 0;
1071 0 : size_t nVisibleIndex( i_nVisibleIndex );
1072 0 : for ( size_t i=0; i < m_aPanelRepository.size(); ++i )
1073 : {
1074 0 : if ( !m_aPanelRepository[i].bHidden )
1075 : {
1076 0 : if ( !nVisibleIndex )
1077 0 : break;
1078 0 : --nVisibleIndex;
1079 : }
1080 0 : ++nLogicalIndex;
1081 : }
1082 0 : return nLogicalIndex;
1083 : }
1084 :
1085 : // ---------------------------------------------------------------------------------------------------------------------
1086 0 : void TaskPaneController_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition )
1087 : {
1088 0 : if ( m_bTogglingPanelVisibility )
1089 0 : return;
1090 :
1091 0 : const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) );
1092 0 : m_aPanelRepository.insert( m_aPanelRepository.begin() + nLogicalIndex, PanelDescriptor( i_pPanel ) );
1093 : }
1094 :
1095 : // ---------------------------------------------------------------------------------------------------------------------
1096 0 : void TaskPaneController_Impl::PanelRemoved( const size_t i_nPosition )
1097 : {
1098 0 : if ( m_bTogglingPanelVisibility )
1099 0 : return;
1100 :
1101 0 : const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) );
1102 0 : m_aPanelRepository.erase( m_aPanelRepository.begin() + nLogicalIndex );
1103 : }
1104 :
1105 : // ---------------------------------------------------------------------------------------------------------------------
1106 0 : void TaskPaneController_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
1107 : {
1108 0 : if ( impl_getLayout() == LAYOUT_DRAWERS )
1109 : // no adjustment of the title when we use the classical "drawers" layout
1110 0 : return;
1111 :
1112 0 : impl_updateDockingWindowTitle( );
1113 : (void)i_rOldActive;
1114 : (void)i_rNewActive;
1115 : }
1116 :
1117 : // ---------------------------------------------------------------------------------------------------------------------
1118 0 : void TaskPaneController_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter )
1119 : {
1120 : // not interested in
1121 : (void)i_rNewLayouter;
1122 0 : }
1123 :
1124 : // ---------------------------------------------------------------------------------------------------------------------
1125 0 : void TaskPaneController_Impl::Dying()
1126 : {
1127 : OSL_FAIL( "TaskPaneController_Impl::Dying: unexpected call!" );
1128 : // We are expected to live longer than the ToolPanelDeck we work with. Since we remove ourself, in our dtor,
1129 : // as listener from the panel deck, this method here should never be called.
1130 0 : }
1131 :
1132 : // ---------------------------------------------------------------------------------------------------------------------
1133 0 : void TaskPaneController_Impl::impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex )
1134 : {
1135 0 : ENSURE_OR_RETURN_VOID( i_nLogicalPanelIndex < m_aPanelRepository.size(), "illegal index" );
1136 :
1137 : // get the actual panel index, within the deck
1138 0 : size_t nActualPanelIndex(0);
1139 0 : for ( size_t i=0; i < i_nLogicalPanelIndex; ++i )
1140 : {
1141 0 : if ( !m_aPanelRepository[i].bHidden )
1142 0 : ++nActualPanelIndex;
1143 : }
1144 :
1145 0 : ::boost::optional< size_t > aActivatePanel;
1146 :
1147 0 : m_bTogglingPanelVisibility = true;
1148 0 : if ( m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden )
1149 : {
1150 0 : OSL_VERIFY( m_rTaskPane.GetPanelDeck().InsertPanel( m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel, nActualPanelIndex ) == nActualPanelIndex );
1151 : // if there has not been an active panel before, activate the newly inserted one
1152 0 : ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() );
1153 0 : if ( !aActivePanel )
1154 0 : aActivatePanel = nActualPanelIndex;
1155 : }
1156 : else
1157 : {
1158 0 : OSL_VERIFY( m_rTaskPane.GetPanelDeck().RemovePanel( nActualPanelIndex ).get() == m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel.get() );
1159 : }
1160 0 : m_bTogglingPanelVisibility = false;
1161 0 : m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden = !m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden;
1162 :
1163 0 : if ( !!aActivatePanel )
1164 0 : m_rTaskPane.GetPanelDeck().ActivatePanel( *aActivatePanel );
1165 : }
1166 :
1167 : // ---------------------------------------------------------------------------------------------------------------------
1168 0 : void TaskPaneController_Impl::impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce )
1169 : {
1170 0 : if ( !i_bForce && ( m_eCurrentLayout == i_eLayout ) )
1171 0 : return;
1172 :
1173 0 : switch ( i_eLayout )
1174 : {
1175 : case LAYOUT_DRAWERS:
1176 0 : m_rTaskPane.SetDrawersLayout();
1177 0 : break;
1178 : case LAYOUT_TABS_TOP:
1179 0 : m_rTaskPane.SetTabsLayout( ::svt::TABS_TOP, ::svt::TABITEM_IMAGE_ONLY );
1180 0 : break;
1181 : case LAYOUT_TABS_BOTTOM:
1182 0 : m_rTaskPane.SetTabsLayout( ::svt::TABS_BOTTOM, ::svt::TABITEM_IMAGE_ONLY );
1183 0 : break;
1184 : case LAYOUT_TABS_LEFT:
1185 0 : m_rTaskPane.SetTabsLayout( ::svt::TABS_LEFT, ::svt::TABITEM_IMAGE_ONLY );
1186 0 : break;
1187 : case LAYOUT_TABS_RIGHT:
1188 0 : m_rTaskPane.SetTabsLayout( ::svt::TABS_RIGHT, ::svt::TABITEM_IMAGE_ONLY );
1189 0 : break;
1190 : }
1191 0 : m_eCurrentLayout = i_eLayout;
1192 :
1193 0 : impl_updateDockingWindowTitle();
1194 : }
1195 :
1196 : // ---------------------------------------------------------------------------------------------------------------------
1197 0 : void TaskPaneController_Impl::impl_updateDockingWindowTitle()
1198 : {
1199 0 : ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() );
1200 0 : if ( !aActivePanel || ( impl_getLayout() == LAYOUT_DRAWERS ) )
1201 0 : m_rDockingWindow.SetTitle( m_sDefaultTitle );
1202 : else
1203 : {
1204 0 : size_t nNewActive( *aActivePanel );
1205 0 : for ( size_t i=0; i < m_aPanelRepository.size(); ++i )
1206 : {
1207 0 : if ( m_aPanelRepository[i].bHidden )
1208 0 : continue;
1209 :
1210 0 : if ( !nNewActive )
1211 : {
1212 0 : m_rDockingWindow.SetTitle( m_aPanelRepository[i].pPanel->GetDisplayName() );
1213 0 : break;
1214 : }
1215 0 : --nNewActive;
1216 : }
1217 0 : }
1218 0 : }
1219 :
1220 : // ---------------------------------------------------------------------------------------------------------------------
1221 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1222 0 : ::std::auto_ptr< PopupMenu > TaskPaneController_Impl::impl_createPopupMenu() const
1223 : {
1224 0 : ::std::auto_ptr<PopupMenu> pMenu( new PopupMenu );
1225 0 : FloatingWindow* pMenuWindow = static_cast< FloatingWindow* >( pMenu->GetWindow() );
1226 0 : if ( pMenuWindow != NULL )
1227 : {
1228 0 : pMenuWindow->SetPopupModeFlags ( pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE );
1229 : }
1230 :
1231 : // Add one entry for every tool panel element to individually make
1232 : // them visible or hide them.
1233 0 : sal_uInt16 nIndex = MID_FIRST_PANEL;
1234 0 : for ( size_t i=0; i<m_aPanelRepository.size(); ++i, ++nIndex )
1235 : {
1236 0 : const PanelDescriptor& rPanelDesc( m_aPanelRepository[i] );
1237 0 : pMenu->InsertItem( nIndex, rPanelDesc.pPanel->GetDisplayName(), MIB_CHECKABLE );
1238 0 : pMenu->CheckItem( nIndex, !rPanelDesc.bHidden );
1239 : }
1240 0 : pMenu->InsertSeparator();
1241 :
1242 : #if OSL_DEBUG_LEVEL > 0
1243 : pMenu->InsertItem( MID_LAYOUT_TABS, rtl::OUString("Tab-Layout (exp.)"), MIB_CHECKABLE );
1244 : pMenu->CheckItem( MID_LAYOUT_TABS, impl_getLayout() != LAYOUT_DRAWERS );
1245 : pMenu->InsertItem( MID_LAYOUT_DRAWERS, rtl::OUString("Drawer-Layout"), MIB_CHECKABLE );
1246 : pMenu->CheckItem( MID_LAYOUT_DRAWERS, impl_getLayout() == LAYOUT_DRAWERS );
1247 :
1248 : pMenu->InsertSeparator();
1249 : #endif
1250 :
1251 : // Add entry for docking or un-docking the tool panel.
1252 0 : if ( m_rDockingWindow.IsFloatingMode() )
1253 0 : pMenu->InsertItem(
1254 : MID_LOCK_TASK_PANEL,
1255 : SfxResId( STR_SFX_DOCK ).toString()
1256 0 : );
1257 : else
1258 0 : pMenu->InsertItem(
1259 : MID_UNLOCK_TASK_PANEL,
1260 : SfxResId( STR_SFX_UNDOCK ).toString()
1261 0 : );
1262 :
1263 0 : pMenu->RemoveDisabledEntries( sal_False, sal_False );
1264 :
1265 0 : return pMenu;
1266 : }
1267 : SAL_WNODEPRECATED_DECLARATIONS_POP
1268 :
1269 : //==================================================================================================================
1270 : //= TaskPaneController
1271 : //==================================================================================================================
1272 : //------------------------------------------------------------------------------------------------------------------
1273 0 : TaskPaneController::TaskPaneController( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow )
1274 0 : :m_pImpl( new TaskPaneController_Impl( i_rTaskPane, i_rDockingWindow ) )
1275 : {
1276 0 : }
1277 :
1278 : //------------------------------------------------------------------------------------------------------------------
1279 0 : TaskPaneController::~TaskPaneController()
1280 : {
1281 0 : }
1282 :
1283 : //------------------------------------------------------------------------------------------------------------------
1284 0 : void TaskPaneController::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
1285 : {
1286 0 : m_pImpl->ActivateToolPanel( i_rPanelURL );
1287 0 : }
1288 :
1289 : //......................................................................................................................
1290 : } // namespace sfx2
1291 : //......................................................................................................................
1292 :
1293 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|