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