Branch libreoffice-5-0-4
[LibreOffice.git] / sfx2 / source / appl / workwin.cxx
blobb9999cb8b69832404385ea18231e0f2ee86a891c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
21 #include <comphelper/processfactory.hxx>
23 #include <sfx2/docfile.hxx>
24 #include <sfx2/objsh.hxx>
25 #include <sfx2/app.hxx>
26 #include "workwin.hxx"
27 #include <sfx2/viewfrm.hxx>
28 #include <sfx2/module.hxx>
29 #include <sfx2/dispatch.hxx>
30 #include <sfx2/dockwin.hxx>
31 #include <sfx2/viewsh.hxx>
32 #include "splitwin.hxx"
33 #include "childwinimpl.hxx"
34 #include <sfx2/msgpool.hxx>
35 #include <sfx2/sfxresid.hxx>
36 #include <sfx2/request.hxx>
37 #include <vcl/taskpanelist.hxx>
38 #include <vcl/toolbox.hxx>
39 #include <tools/rcid.h>
40 #include <tools/diagnose_ex.h>
41 #include <toolkit/helper/vclunohelper.hxx>
42 #include <svl/itempool.hxx>
43 #include <svl/itemiter.hxx>
44 #include <svl/whiter.hxx>
45 #include <svl/intitem.hxx>
46 #include <svl/eitem.hxx>
47 #include <unotools/moduleoptions.hxx>
48 #include <com/sun/star/ui/XUIElement.hpp>
49 #include <com/sun/star/frame/LayoutManagerEvents.hpp>
50 #include <com/sun/star/frame/ModuleManager.hpp>
51 #include <com/sun/star/frame/XLayoutManager.hpp>
52 #include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 #include <com/sun/star/awt/XWindow.hpp>
55 #include <com/sun/star/lang/DisposedException.hpp>
56 #include <unordered_map>
58 using namespace ::com::sun::star;
59 using namespace ::com::sun::star::uno;
61 struct ResIdToResName
63 sal_uInt16 nId;
64 const char* pName;
67 static const ResIdToResName pToolBarResToName[] =
69 // OMG! hardcoded numbers that have nice (?) symbolic names
70 // elsewhere.
71 { 558, "fullscreenbar" }, // This 558 for instance equals RID_FULLSCREENTOOLBOX (in
72 // value, and presumably also in semantics) from app.hrc in
73 // this very same directory, so why RID_FULLSCREENTOOLBOX
74 // can't be used I have no idea.
76 { 560, "standardbar", }, // 560 is called RID_ENVTOOLBOX in app.hrc, still the same?
78 { 18001, "formsnavigationbar" }, // Probably the rest are defined in .hrc files that are higher
79 // up in the dependency chain and/or later in the build order,
80 // and that is the (bad) reason why their symbolic names are
81 // not available? Would it really be so owful to move the .hrc
82 // files in question out from the modules where they now are?
84 { 18002, "formsfilterbar" },
85 { 18003, "formtextobjectbar" },
86 { 18004, "formcontrols" },
87 { 18005, "moreformcontrols" },
88 { 18006, "formdesign" },
89 { 20050, "toolbar" }, //math
90 { 30001, "objectbar" }, //chart
91 { 30513, "toolbar" }, //chart
92 { 25005, "textobjectbar" }, //calc
93 { 25053, "drawobjectbar" },
94 { 25054, "graphicobjectbar" },
95 { 25001, "formatobjectbar" },
96 { 25006, "previewbar" },
97 { 25035, "toolbar" }, //calc
98 { 23015, "bezierobjectbar" }, //draw/impress
99 { 23019, "gluepointsobjectbar" },
100 { 23030, "graphicobjectbar" },
101 { 23013, "drawingobjectbar" }, //impress
102 { 23016, "textobjectbar" }, //impress
103 { 23028, "textobjectbar" }, //draw
104 { 23011, "toolbar" }, //impress
105 { 23020, "optionsbar" },
106 { 23021, "commontaskbar" },
107 { 23025, "toolbar" }, //draw
108 { 23026, "optionsbar" },
109 { 23027, "drawingobjectbar" }, //draw
110 { 23017, "outlinetoolbar" }, //impress
111 { 23012, "slideviewtoolbar" },
112 { 23014, "slideviewobjectbar" },
113 { 23283, "bezierobjectbar" }, //writer
114 { 23269, "drawingobjectbar" },
115 { 23270, "drawtextobjectbar" },
116 { 23267, "frameobjectbar" },
117 { 23268, "graphicobjectbar" },
118 { 23271, "numobjectbar" },
119 { 23272, "oleobjectbar" },
120 { 23266, "tableobjectbar" },
121 { 23265, "textobjectbar" },
122 { 20631, "previewobjectbar" }, //writer
123 { 20402, "toolbar" }, //web
124 { 20403, "textobjectbar" },
125 { 23273, "toolbar" }, //writer
126 { 20408, "frameobjectbar" }, //web
127 { 20410, "graphicobjectbar" },
128 { 20411, "oleobjectbar" },
129 { 14850, "macrobar" },
130 { 10987, "fontworkobjectbar" }, //global
131 { 10986, "extrusionobjectbar" },
132 { 23022, "formsobjectbar" },
133 { 23310, "viewerbar" }, //writer (plugin)
134 { 25000, "viewerbar" }, //calc (plugin)
135 { 23023, "viewerbar" }, //impress(plugin)
136 { 23024, "viewerbar" }, //draw (plugin)
137 { 23031, "mediaobjectbar" }, //draw/impress
138 { 25060, "mediaobjectbar" }, //calc
139 { 23311, "mediaobjectbar" }, //writer
140 { 23313, "navigationobjectbar" }, //writer
141 { 0, "" }
144 //SV_IMPL_OBJARR( SfxObjectBarArr_Impl, SfxObjectBar_Impl );
147 // Sort the Children according their alignment
148 // The order corresponds to the enum SfxChildAlignment (->CHILDWIN.HXX).
151 // Help to make changes to the alignment compatible!
154 LayoutManagerListener::LayoutManagerListener(
155 SfxWorkWindow* pWrkWin ) :
156 m_bHasFrame( false ),
157 m_pWrkWin( pWrkWin ),
158 m_aLayoutManagerPropName( "LayoutManager" )
162 LayoutManagerListener::~LayoutManagerListener()
166 void LayoutManagerListener::setFrame( const css::uno::Reference< css::frame::XFrame >& xFrame )
168 SolarMutexGuard aGuard;
169 if ( m_pWrkWin && !m_bHasFrame )
171 m_xFrame = xFrame;
172 m_bHasFrame = true;
174 if ( xFrame.is() )
176 css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
177 css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager;
178 if ( xPropSet.is() )
182 Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName );
183 aValue >>= xLayoutManager;
185 if ( xLayoutManager.is() )
186 xLayoutManager->addLayoutManagerEventListener(
187 css::uno::Reference< css::frame::XLayoutManagerListener >(
188 static_cast< OWeakObject* >( this ), css::uno::UNO_QUERY ));
190 xPropSet = css::uno::Reference< css::beans::XPropertySet >( xLayoutManager, UNO_QUERY );
191 if ( xPropSet.is() )
193 aValue = xPropSet->getPropertyValue(
194 OUString( "LockCount" ) );
195 aValue >>= m_pWrkWin->m_nLock;
198 catch ( css::lang::DisposedException& )
201 catch ( const css::uno::RuntimeException& )
203 throw;
205 catch ( css::uno::Exception& )
214 // XComponent
216 void SAL_CALL LayoutManagerListener::addEventListener(
217 const css::uno::Reference< css::lang::XEventListener >& )
218 throw (::com::sun::star::uno::RuntimeException, std::exception)
220 // do nothing, only internal class
223 void SAL_CALL LayoutManagerListener::removeEventListener(
224 const css::uno::Reference< css::lang::XEventListener >& )
225 throw (::com::sun::star::uno::RuntimeException, std::exception)
227 // do nothing, only internal class
230 void SAL_CALL LayoutManagerListener::dispose()
231 throw( css::uno::RuntimeException, std::exception )
233 SolarMutexGuard aGuard;
235 // reset member
236 m_pWrkWin = 0;
238 css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame.get(), css::uno::UNO_QUERY );
239 if ( xFrame.is() )
241 m_xFrame = css::uno::Reference< css::frame::XFrame >();
242 m_bHasFrame = false;
244 css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
245 css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager;
246 if ( xPropSet.is() )
250 css::uno::Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName );
251 aValue >>= xLayoutManager;
253 // remove as listener from layout manager
254 if ( xLayoutManager.is() )
255 xLayoutManager->removeLayoutManagerEventListener(
256 css::uno::Reference< css::frame::XLayoutManagerListener >(
257 static_cast< OWeakObject* >( this ), css::uno::UNO_QUERY ));
259 catch ( css::lang::DisposedException& )
262 catch ( const css::uno::RuntimeException& )
264 throw;
266 catch ( css::uno::Exception& )
274 // XEventListener
276 void SAL_CALL LayoutManagerListener::disposing(
277 const css::lang::EventObject& )
278 throw( css::uno::RuntimeException, std::exception )
280 SolarMutexGuard aGuard;
281 m_pWrkWin = 0;
282 m_bHasFrame = false;
283 m_xFrame = css::uno::Reference< css::frame::XFrame >();
287 // XLayoutManagerEventListener
289 void SAL_CALL LayoutManagerListener::layoutEvent(
290 const css::lang::EventObject&,
291 ::sal_Int16 eLayoutEvent,
292 const css::uno::Any& )
293 throw (css::uno::RuntimeException, std::exception)
295 SolarMutexGuard aGuard;
296 if ( m_pWrkWin )
298 if ( eLayoutEvent == css::frame::LayoutManagerEvents::VISIBLE )
300 m_pWrkWin->MakeVisible_Impl( true );
301 m_pWrkWin->ShowChildren_Impl();
302 m_pWrkWin->ArrangeChildren_Impl( true );
304 else if ( eLayoutEvent == css::frame::LayoutManagerEvents::INVISIBLE )
306 m_pWrkWin->MakeVisible_Impl( false );
307 m_pWrkWin->HideChildren_Impl();
308 m_pWrkWin->ArrangeChildren_Impl( true );
310 else if ( eLayoutEvent == css::frame::LayoutManagerEvents::LOCK )
312 m_pWrkWin->Lock_Impl( true );
314 else if ( eLayoutEvent == css::frame::LayoutManagerEvents::UNLOCK )
316 m_pWrkWin->Lock_Impl( false );
321 namespace
323 class FilledToolBarResIdToResourceURLMap
325 private:
326 typedef std::unordered_map< sal_Int32, OUString > ToolBarResIdToResourceURLMap;
327 ToolBarResIdToResourceURLMap m_aResIdToResourceURLMap;
328 public:
329 FilledToolBarResIdToResourceURLMap()
331 sal_Int32 nIndex( 0 );
332 while ( pToolBarResToName[nIndex].nId != 0 )
334 OUString aResourceURL( OUString::createFromAscii( pToolBarResToName[nIndex].pName ));
335 m_aResIdToResourceURLMap.insert( ToolBarResIdToResourceURLMap::value_type(
336 sal_Int32( pToolBarResToName[nIndex].nId ), aResourceURL ));
337 ++nIndex;
341 OUString findURL(sal_uInt16 nResId) const
343 ToolBarResIdToResourceURLMap::const_iterator aIter = m_aResIdToResourceURLMap.find( nResId );
344 if ( aIter != m_aResIdToResourceURLMap.end() )
345 return aIter->second;
346 return OUString();
350 class theFilledToolBarResIdToResourceURLMap
351 : public rtl::Static<FilledToolBarResIdToResourceURLMap,
352 theFilledToolBarResIdToResourceURLMap>
357 static OUString GetResourceURLFromResId( sal_uInt16 nResId )
359 return theFilledToolBarResIdToResourceURLMap::get().findURL(nResId);
362 bool IsAppWorkWinToolbox_Impl( sal_uInt16 nPos )
364 switch ( nPos )
366 case SFX_OBJECTBAR_APPLICATION :
367 case SFX_OBJECTBAR_MACRO:
368 case SFX_OBJECTBAR_FULLSCREEN:
369 return true;
370 default:
371 return false;
375 sal_uInt16 TbxMatch( sal_uInt16 nPos )
377 switch ( nPos )
379 case SFX_OBJECTBAR_APPLICATION :
380 return 0;
381 case SFX_OBJECTBAR_OPTIONS:
382 return 1;
383 case SFX_OBJECTBAR_MACRO:
384 return 2;
385 case SFX_OBJECTBAR_OBJECT:
386 return 3;
387 case SFX_OBJECTBAR_TOOLS:
388 return 4;
389 case SFX_OBJECTBAR_FULLSCREEN:
390 case SFX_OBJECTBAR_COMMONTASK:
391 case SFX_OBJECTBAR_RECORDING:
392 return nPos+1;
393 default:
394 return nPos;
398 sal_uInt16 ChildAlignValue(SfxChildAlignment eAlign)
400 sal_uInt16 ret = 17;
402 switch (eAlign)
404 case SfxChildAlignment::HIGHESTTOP:
405 ret = 1;
406 break;
407 case SfxChildAlignment::LOWESTBOTTOM:
408 ret = 2;
409 break;
410 case SfxChildAlignment::FIRSTLEFT:
411 ret = 3;
412 break;
413 case SfxChildAlignment::LASTRIGHT:
414 ret = 4;
415 break;
416 case SfxChildAlignment::LEFT:
417 ret = 5;
418 break;
419 case SfxChildAlignment::RIGHT:
420 ret = 6;
421 break;
422 case SfxChildAlignment::FIRSTRIGHT:
423 ret = 7;
424 break;
425 case SfxChildAlignment::LASTLEFT:
426 ret = 8;
427 break;
428 case SfxChildAlignment::TOP:
429 ret = 9;
430 break;
431 case SfxChildAlignment::BOTTOM:
432 ret = 10;
433 break;
434 case SfxChildAlignment::TOOLBOXTOP:
435 ret = 11;
436 break;
437 case SfxChildAlignment::TOOLBOXBOTTOM:
438 ret = 12;
439 break;
440 case SfxChildAlignment::LOWESTTOP:
441 ret = 13;
442 break;
443 case SfxChildAlignment::HIGHESTBOTTOM:
444 ret = 14;
445 break;
446 case SfxChildAlignment::TOOLBOXLEFT:
447 ret = 15;
448 break;
449 case SfxChildAlignment::TOOLBOXRIGHT:
450 ret = 16;
451 break;
452 case SfxChildAlignment::NOALIGNMENT:
453 break; // -Wall not handled...
456 return ret;
459 sal_uInt16 ChildTravelValue( SfxChildAlignment eAlign )
461 sal_uInt16 ret = 17;
463 switch (eAlign)
465 case SfxChildAlignment::FIRSTLEFT:
466 ret = 1;
467 break;
468 case SfxChildAlignment::LEFT:
469 ret = 2;
470 break;
471 case SfxChildAlignment::LASTLEFT:
472 ret = 3;
473 break;
474 case SfxChildAlignment::TOOLBOXLEFT:
475 ret = 4;
476 break;
477 case SfxChildAlignment::HIGHESTTOP:
478 ret = 5;
479 break;
480 case SfxChildAlignment::TOP:
481 ret = 6;
482 break;
483 case SfxChildAlignment::TOOLBOXTOP:
484 ret = 7;
485 break;
486 case SfxChildAlignment::LOWESTTOP:
487 ret = 8;
488 break;
489 case SfxChildAlignment::HIGHESTBOTTOM:
490 ret = 9;
491 break;
492 case SfxChildAlignment::TOOLBOXBOTTOM:
493 ret = 10;
494 break;
495 case SfxChildAlignment::BOTTOM:
496 ret = 11;
497 break;
498 case SfxChildAlignment::LOWESTBOTTOM:
499 ret = 12;
500 break;
501 case SfxChildAlignment::TOOLBOXRIGHT:
502 ret = 13;
503 break;
504 case SfxChildAlignment::FIRSTRIGHT:
505 ret = 14;
506 break;
507 case SfxChildAlignment::RIGHT:
508 ret = 15;
509 break;
510 case SfxChildAlignment::LASTRIGHT:
511 ret = 16;
512 break;
513 case SfxChildAlignment::NOALIGNMENT:
514 break; // -Wall not handled.
517 return ret;
520 void SfxWorkWindow::Sort_Impl()
522 aSortedList.clear();
523 for (sal_uInt16 i = 0; i < aChildren.size(); ++i)
525 SfxChild_Impl *pCli = aChildren[i];
526 if (pCli)
528 sal_uInt16 k;
529 for (k=0; k<aSortedList.size(); k++)
530 if (ChildAlignValue( aChildren[aSortedList[k]]->eAlign ) >
531 ChildAlignValue(pCli->eAlign))
532 break;
533 aSortedList.insert( aSortedList.begin() + k, i );
537 bSorted = true;
542 // constructor for workwin of a Frame
544 SfxFrameWorkWin_Impl::SfxFrameWorkWin_Impl( vcl::Window *pWin, SfxFrame *pFrm, SfxFrame* pMaster )
545 : SfxWorkWindow(
546 pWin,
547 pFrm->GetCurrentViewFrame()->GetBindings(),
548 pFrm->GetParentFrame() ? pFrm->GetParentFrame()->GetWorkWindow_Impl() : NULL )
549 , pMasterFrame( pMaster )
550 , pFrame( pFrm )
552 pConfigShell = pFrm->GetCurrentViewFrame();
553 if ( pConfigShell && pConfigShell->GetObjectShell() )
555 bShowStatusBar = ( !pConfigShell->GetObjectShell()->IsInPlaceActive() );
556 bDockingAllowed = true;
557 bInternalDockingAllowed = true;
560 // The required split windows (one for each side) can be created
561 for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
563 // The SplitWindows excludes direct ChildWindows of the WorkWindows
564 // and receives the docked window.
566 SfxChildAlignment eAlign =
567 ( n == SFX_SPLITWINDOWS_LEFT ? SfxChildAlignment::LEFT :
568 n == SFX_SPLITWINDOWS_RIGHT ? SfxChildAlignment::RIGHT :
569 n == SFX_SPLITWINDOWS_TOP ? SfxChildAlignment::TOP :
570 SfxChildAlignment::BOTTOM );
571 VclPtr<SfxSplitWindow> pSplitWin = VclPtr<SfxSplitWindow>::Create(pWorkWin, eAlign, this, pParent==0 );
572 pSplit[n] = pSplitWin;
575 nOrigMode = SFX_VISIBILITY_STANDARD;
576 nUpdateMode = SFX_VISIBILITY_STANDARD;
580 // Constructor of the base class
582 SfxWorkWindow::SfxWorkWindow( vcl::Window *pWin, SfxBindings& rB, SfxWorkWindow* pParentWorkwin ) :
583 pParent( pParentWorkwin ),
584 pBindings(&rB),
585 pWorkWin (pWin),
586 pConfigShell( 0 ),
587 pActiveChild( 0 ),
588 nUpdateMode(SFX_VISIBILITY_STANDARD),
589 nChildren( 0 ),
590 nOrigMode( 0 ),
591 bSorted( true ),
592 bDockingAllowed(true),
593 bInternalDockingAllowed(true),
594 bAllChildrenVisible(true),
595 #if HAVE_FEATURE_DESKTOP
596 bIsFullScreen( false ),
597 bShowStatusBar( true ),
598 #else
599 bIsFullScreen( sal_True ),
600 bShowStatusBar( sal_False ),
601 #endif
602 m_nLock( 0 ),
603 m_aStatusBarResName( "private:resource/statusbar/statusbar" ),
604 m_aLayoutManagerPropName( "LayoutManager" ),
605 m_aTbxTypeName( "private:resource/toolbar/" ),
606 m_aProgressBarResName( "private:resource/progressbar/progressbar" )
608 DBG_ASSERT (pBindings, "No Bindings!");
610 pBindings->SetWorkWindow_Impl( this );
612 // For the ObjectBars a integral place in the Childlist is reserved,
613 // so that they always come in a defined order.
614 aChildren.insert( aChildren.begin(), SFX_OBJECTBAR_MAX, (SfxChild_Impl*)NULL );
616 // create and initialize layout manager listener
617 Reference< com::sun::star::frame::XFrame > xFrame = GetFrameInterface();
618 LayoutManagerListener* pLayoutManagerListener = new LayoutManagerListener( this );
619 m_xLayoutManagerListener = css::uno::Reference< css::lang::XComponent >(
620 static_cast< cppu::OWeakObject* >( pLayoutManagerListener ),
621 css::uno::UNO_QUERY );
622 pLayoutManagerListener->setFrame( xFrame );
626 // Destructor
628 SfxWorkWindow::~SfxWorkWindow()
631 // Delete SplitWindows
632 for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
634 VclPtr<SfxSplitWindow> p = pSplit[n];
635 if (p->GetWindowCount())
636 ReleaseChild_Impl(*p);
637 pSplit[n].disposeAndClear();
640 // Delete help structure for Child-Windows
641 DBG_ASSERT( aChildren.empty(), "dangling children" );
643 if ( m_xLayoutManagerListener.is() )
644 m_xLayoutManagerListener->dispose();
647 void SfxWorkWindow::Lock_Impl( bool bLock )
649 if ( bLock )
650 m_nLock++;
651 else
652 --m_nLock;
653 if ( m_nLock<0 )
655 OSL_FAIL("Lock count underflow!");
656 m_nLock = 0;
659 if ( !m_nLock )
660 ArrangeChildren_Impl();
664 // Helper method to release the child lists. Should the destructor not be
665 // called after this, instead work continues, then space for the object bars
666 // and split windows has to be reserved in the same way as in the constructor
667 // of SfxWorkWindow.
669 void SfxWorkWindow::DeleteControllers_Impl()
672 // Lock SplitWindows (which means suppressing the Resize-Reaction of the
673 // DockingWindows)
674 sal_uInt16 n;
675 for ( n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
677 SfxSplitWindow *p = pSplit[n];
678 if (p->GetWindowCount())
679 p->Lock();
682 // Delete Child-Windows
683 for ( n=0; n<aChildWins.size(); )
685 SfxChildWin_Impl* pCW = aChildWins[n];
686 aChildWins.erase(aChildWins.begin());
687 SfxChildWindow *pChild = pCW->pWin;
688 if (pChild)
690 pChild->Hide();
692 // If the child window is a direct child window and not in a
693 // SplitWindow, cancel it at the workwindow.
694 // After TH a cancellation on the SplitWindow is not necessary
695 // since this window is also destroyed (see below).
696 if (pCW->pCli)
697 ReleaseChild_Impl(*pChild->GetWindow());
698 pCW->pWin = 0;
699 pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChild->GetWindow() );
700 pChild->Destroy();
703 delete pCW;
705 // ATTENTION: The array itself is cleared after this loop!!
706 // Therefore we have to set every array entry to zero as it could be
707 // accessed by calling pChild->Destroy().
708 // Window::NotifyAllChildren() calls SfxWorkWindow::DataChanged_Impl for
709 // 8-bit displays (WM_QUERYPALETTECHANGED message due to focus change)!!
712 Reference< com::sun::star::frame::XFrame > xFrame = GetFrameInterface();
713 Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
714 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
715 if ( xPropSet.is() )
719 Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName );
720 aValue >>= xLayoutManager;
722 catch ( Exception& )
727 if ( xLayoutManager.is() )
729 xLayoutManager->reset();
731 // Delete StatusBar
732 ResetStatusBar_Impl();
734 // Delete ObjectBars (this is done last, so that aChildren does not
735 // receive dead Pointers)
736 for ( sal_uInt16 i = 0; i < aObjBarList.size(); i++ )
738 // Not every position must be occupied
739 sal_uInt16 nId = aObjBarList[i].nId;
740 if ( nId )
741 aObjBarList[i].nId = 0;
745 // ObjectBars are all released at once, since they occupy a
746 // fixed contiguous area in the array pChild
747 aChildren.clear();
748 bSorted = false;
750 nChildren = 0;
754 // Virtual method for placing the child window.
756 void SfxWorkWindow::ArrangeChildren_Impl( bool /*bForce*/)
758 Arrange_Impl();
761 void SfxFrameWorkWin_Impl::ArrangeChildren_Impl( bool bForce )
763 if ( pFrame->IsClosing_Impl() || ( m_nLock && !bForce ))
764 return;
766 SfxInPlaceClient *pClient = 0;
767 SfxViewFrame *pF = pFrame->GetCurrentViewFrame();
768 if ( pF && pF->GetViewShell() )
769 pClient = pF->GetViewShell()->GetIPClient();
771 if ( pClient )
772 return;
774 aClientArea = GetTopRect_Impl();
775 if ( aClientArea.IsEmpty() )
776 return;
778 SvBorder aBorder;
779 if ( nChildren )
781 if ( IsVisible_Impl() )
782 aBorder = Arrange_Impl();
784 // If the current application document contains a IPClient, then the
785 // object through SetTopToolFramePixel has to be assigned the available
786 // space. The object will then point to its UITools and sets the app border
787 // (-> SfxInPlaceEnv_Impl:: ArrangeChildren_Impl ()). Otherwise the
788 // app border is set here directly to possibly overwrite the Border that
789 // was set by an object from another document. The object does not set
790 // the SetAppBorder when it removes its UI tools so that no-dithering
791 // ObjectBar arises.
792 // (->SfxInPlaceEnv_Impl::ArrangeChildren_Impl())
794 pMasterFrame->SetToolSpaceBorderPixel_Impl( aBorder );
796 ArrangeAutoHideWindows( NULL );
801 SvBorder SfxWorkWindow::Arrange_Impl()
803 /* [Description]
805 This method organizes all visible child windows so that the docked window
806 sorted in order from the outside to the inside are placed after one
807 another. If a visible window does not fit anymore into the free
808 ClientArea, it is set to "not visible".
812 aClientArea = GetTopRect_Impl();
813 aUpperClientArea = aClientArea;
815 SvBorder aBorder;
816 if ( !nChildren )
817 return aBorder;
819 if (!bSorted)
820 Sort_Impl();
822 Point aPos;
823 Size aSize;
824 Rectangle aTmp( aClientArea );
826 for ( sal_uInt16 n=0; n<aSortedList.size(); ++n )
828 SfxChild_Impl* pCli = aChildren[aSortedList[n]];
829 if ( !pCli->pWin )
830 continue;
832 // First, we assume that there is room for the window.
833 pCli->nVisible |= SfxChildVisibility::FITS_IN;
835 // Skip invisiable windows
836 if (pCli->nVisible != SfxChildVisibility::VISIBLE)
837 continue;
839 if ( pCli->bResize )
840 aSize = pCli->aSize;
841 else
842 aSize = pCli->pWin->GetSizePixel();
844 SvBorder aTemp = aBorder;
845 bool bAllowHiding = true;
846 switch ( pCli->eAlign )
848 case SfxChildAlignment::HIGHESTTOP:
849 case SfxChildAlignment::TOP:
850 case SfxChildAlignment::TOOLBOXTOP:
851 case SfxChildAlignment::LOWESTTOP:
852 aSize.Width() = aTmp.GetWidth();
853 if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW )
854 aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
855 bAllowHiding = false;
856 aBorder.Top() += aSize.Height();
857 aPos = aTmp.TopLeft();
858 aTmp.Top() += aSize.Height();
859 if ( pCli->eAlign == SfxChildAlignment::HIGHESTTOP )
860 aUpperClientArea.Top() += aSize.Height();
861 break;
863 case SfxChildAlignment::LOWESTBOTTOM:
864 case SfxChildAlignment::BOTTOM:
865 case SfxChildAlignment::TOOLBOXBOTTOM:
866 case SfxChildAlignment::HIGHESTBOTTOM:
867 aSize.Width() = aTmp.GetWidth();
868 if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW )
869 aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
870 aBorder.Bottom() += aSize.Height();
871 aPos = aTmp.BottomLeft();
872 aPos.Y() -= (aSize.Height()-1);
873 aTmp.Bottom() -= aSize.Height();
874 if ( pCli->eAlign == SfxChildAlignment::LOWESTBOTTOM )
875 aUpperClientArea.Bottom() -= aSize.Height();
876 break;
878 case SfxChildAlignment::FIRSTLEFT:
879 case SfxChildAlignment::LEFT:
880 case SfxChildAlignment::LASTLEFT:
881 case SfxChildAlignment::TOOLBOXLEFT:
882 aSize.Height() = aTmp.GetHeight();
883 if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW )
884 aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
885 bAllowHiding = false;
886 aBorder.Left() += aSize.Width();
887 aPos = aTmp.TopLeft();
888 aTmp.Left() += aSize.Width();
889 if ( pCli->eAlign != SfxChildAlignment::TOOLBOXLEFT )
890 aUpperClientArea.Left() += aSize.Width();
891 break;
893 case SfxChildAlignment::FIRSTRIGHT:
894 case SfxChildAlignment::RIGHT:
895 case SfxChildAlignment::LASTRIGHT:
896 case SfxChildAlignment::TOOLBOXRIGHT:
897 aSize.Height() = aTmp.GetHeight();
898 if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW )
899 aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
900 aBorder.Right() += aSize.Width();
901 aPos = aTmp.TopRight();
902 aPos.X() -= (aSize.Width()-1);
903 aTmp.Right() -= aSize.Width();
904 if ( pCli->eAlign != SfxChildAlignment::TOOLBOXRIGHT )
905 aUpperClientArea.Right() -= aSize.Width();
906 break;
908 default:
909 pCli->aSize = pCli->pWin->GetSizePixel();
910 pCli->bResize = false;
911 continue;
914 pCli->pWin->SetPosSizePixel( aPos, aSize );
915 pCli->bResize = false;
916 pCli->aSize = aSize;
917 if( bAllowHiding && !RequestTopToolSpacePixel_Impl( aBorder ) )
919 pCli->nVisible ^= SfxChildVisibility::FITS_IN;
920 aBorder = aTemp;
924 if ( aClientArea.GetWidth() >= aBorder.Left() + aBorder.Right() )
926 aClientArea.Left() += aBorder.Left();
927 aClientArea.Right() -= aBorder.Right();
929 else
931 aBorder.Left() = aClientArea.Left();
932 aBorder.Right() = aClientArea.Right();
933 aClientArea.Right() = aClientArea.Left() = aTmp.Left();
936 if ( aClientArea.GetHeight() >= aBorder.Top() + aBorder.Bottom() )
938 aClientArea.Top() += aBorder.Top();
939 aClientArea.Bottom() -= aBorder.Bottom();
941 else
943 aBorder.Top() = aClientArea.Top();
944 aBorder.Bottom() = aClientArea.Bottom();
945 aClientArea.Top() = aClientArea.Bottom() = aTmp.Top();
948 return IsDockingAllowed() ? aBorder : SvBorder();
951 bool SfxWorkWindow::PrepareClose_Impl()
953 for (sal_uInt16 n=0; n<aChildWins.size(); n++)
955 SfxChildWin_Impl *pCW = aChildWins[n];
956 SfxChildWindow *pChild = pCW->pWin;
957 if ( pChild && !pChild->QueryClose() )
958 return false;
961 return true;
966 SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( vcl::Window& rWindow,
967 SfxChildAlignment eAlign, bool bCanGetFocus )
969 DBG_ASSERT( aChildren.size() < 255, "too many children" );
970 DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" );
971 DBG_ASSERT( !FindChild_Impl(rWindow), "child registered more than once" );
974 if ( rWindow.GetParent() != pWorkWin )
975 rWindow.SetParent( pWorkWin );
977 SfxChild_Impl *pChild = new SfxChild_Impl(rWindow, rWindow.GetSizePixel(),
978 eAlign, rWindow.IsVisible());
979 pChild->bCanGetFocus = bCanGetFocus;
981 aChildren.push_back(pChild);
982 bSorted = false;
983 nChildren++;
984 return aChildren.back();
989 void SfxWorkWindow::ReleaseChild_Impl( vcl::Window& rWindow )
992 SfxChild_Impl *pChild = 0;
993 sal_uInt16 nPos;
994 for ( nPos = 0; nPos < aChildren.size(); ++nPos )
996 pChild = aChildren[nPos];
997 if ( pChild && pChild->pWin == &rWindow )
998 break;
1001 if ( nPos < aChildren.size() )
1003 bSorted = false;
1004 nChildren--;
1005 aChildren.erase(aChildren.begin() + nPos);
1006 delete pChild;
1008 else {
1009 OSL_FAIL( "releasing unregistered child" );
1015 SfxChild_Impl* SfxWorkWindow::FindChild_Impl( const vcl::Window& rWindow ) const
1018 sal_uInt16 nCount = aChildren.size();
1019 for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
1021 SfxChild_Impl *pChild = aChildren[nPos];
1022 if ( pChild && pChild->pWin == &rWindow )
1023 return pChild;
1026 return 0;
1031 void SfxWorkWindow::ShowChildren_Impl()
1034 bool bInvisible = ( !IsVisible_Impl() || ( !pWorkWin->IsReallyVisible() && !pWorkWin->IsReallyShown() ));
1036 for ( sal_uInt16 nPos = 0; nPos < aChildren.size(); ++nPos )
1038 SfxChildWin_Impl* pCW = 0;
1039 SfxChild_Impl *pCli = aChildren[nPos];
1041 if ( pCli && pCli->pWin )
1043 // We have to find the SfxChildWin_Impl to retrieve the
1044 // SFX_CHILDWIN flags that can influence visibility.
1045 for (sal_uInt16 n=0; n<aChildWins.size(); n++)
1047 SfxChildWin_Impl* pCWin = aChildWins[n];
1048 SfxChild_Impl* pChild = pCWin->pCli;
1049 if ( pChild == pCli )
1051 pCW = pCWin;
1052 break;
1056 bool bVisible( !bInvisible );
1057 if ( pCW )
1059 // Check flag SFX_CHILDWIN_NEVERHIDE that forces us to show
1060 // the child window even in situations where no child window is
1061 // visible.
1062 SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
1063 bVisible = !bInvisible || ( nFlags & SfxChildWindowFlags::NEVERHIDE );
1066 if ( SfxChildVisibility::VISIBLE == (pCli->nVisible & SfxChildVisibility::VISIBLE) && bVisible )
1068 sal_uInt16 nFlags = pCli->bSetFocus ? 0 : SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE;
1069 switch ( pCli->pWin->GetType() )
1071 case RSC_DOCKINGWINDOW :
1072 static_cast<DockingWindow*>(pCli->pWin.get())->Show( true, nFlags );
1073 break;
1074 case RSC_SPLITWINDOW :
1075 static_cast<SplitWindow*>(pCli->pWin.get())->Show( true, nFlags );
1076 break;
1077 default:
1078 pCli->pWin->Show( true, nFlags );
1079 break;
1082 pCli->bSetFocus = false;
1084 else
1086 switch ( pCli->pWin->GetType() )
1088 case RSC_DOCKINGWINDOW :
1089 static_cast<DockingWindow*>(pCli->pWin.get())->Hide();
1090 break;
1091 default:
1092 pCli->pWin->Hide();
1093 break;
1102 void SfxWorkWindow::HideChildren_Impl()
1104 for ( sal_uInt16 nPos = aChildren.size(); nPos > 0; --nPos )
1106 SfxChild_Impl *pChild = aChildren[nPos-1];
1107 if (pChild && pChild->pWin)
1109 switch ( pChild->pWin->GetType() )
1111 case RSC_DOCKINGWINDOW :
1112 static_cast<DockingWindow*>(pChild->pWin.get())->Hide();
1113 break;
1114 default:
1115 pChild->pWin->Hide();
1116 break;
1124 void SfxWorkWindow::ResetObjectBars_Impl()
1126 sal_uInt16 n;
1127 for ( n = 0; n < aObjBarList.size(); n++ )
1128 aObjBarList[n].bDestroy = true;
1130 for ( n = 0; n < aChildWins.size(); ++n )
1131 aChildWins[n]->nId = 0;
1134 void SfxWorkWindow::SetObjectBar_Impl(sal_uInt16 nPos, sal_uInt32 nResId,
1135 SfxInterface* pIFace)
1137 DBG_ASSERT( (nPos & SFX_POSITION_MASK) < SFX_OBJECTBAR_MAX,
1138 "object bar position overflow" );
1140 sal_uInt16 nRealPos = nPos & SFX_POSITION_MASK;
1141 if ( pParent && IsAppWorkWinToolbox_Impl( nRealPos ) )
1143 pParent->SetObjectBar_Impl(nPos, nResId, pIFace);
1144 return;
1147 SfxObjectBar_Impl aObjBar;
1148 aObjBar.pIFace = pIFace;
1149 aObjBar.nId = sal::static_int_cast<sal_uInt16>(nResId);
1150 aObjBar.nPos = nRealPos;
1151 aObjBar.nMode = (nPos & SFX_VISIBILITY_MASK);
1153 for ( sal_uInt16 n=0; n<aObjBarList.size(); n++ )
1155 if ( aObjBarList[n].nId == aObjBar.nId )
1157 aObjBarList[n] = aObjBar;
1158 return;
1162 aObjBarList.push_back( aObjBar );
1165 bool SfxWorkWindow::KnowsObjectBar_Impl( sal_uInt16 nPos ) const
1167 /* [Description]
1169 Determines if a object list is available at the position in question.
1170 This is independent for the fact whether it is actually turned on or off.
1174 sal_uInt16 nRealPos = nPos & SFX_POSITION_MASK;
1175 if ( pParent && IsAppWorkWinToolbox_Impl( nRealPos ) )
1176 return pParent->KnowsObjectBar_Impl( nPos );
1178 for ( sal_uInt16 n=0; n<aObjBarList.size(); n++ )
1180 if ( aObjBarList[n].nPos == nRealPos )
1181 return true;
1184 return false;
1189 bool SfxWorkWindow::IsVisible_Impl( sal_uInt16 nMode ) const
1191 switch( nUpdateMode )
1193 case SFX_VISIBILITY_STANDARD:
1194 return true;
1195 case SFX_VISIBILITY_UNVISIBLE:
1196 return false;
1197 case SFX_VISIBILITY_CLIENT:
1198 case SFX_VISIBILITY_SERVER:
1199 return !!(nMode & nUpdateMode);
1200 default:
1201 return !!(nMode & nOrigMode ) ||
1202 nOrigMode == SFX_VISIBILITY_STANDARD;
1206 void SfxFrameWorkWin_Impl::UpdateObjectBars_Impl()
1208 if ( pFrame->IsClosing_Impl() )
1209 return;
1211 SfxWorkWindow *pWork = pParent;
1212 while ( pWork )
1214 pWork->SfxWorkWindow::UpdateObjectBars_Impl();
1215 pWork = pWork->GetParent_Impl();
1218 SfxWorkWindow::UpdateObjectBars_Impl();
1221 pWork = pParent;
1222 while ( pWork )
1224 pWork->ArrangeChildren_Impl();
1225 pWork = pWork->GetParent_Impl();
1228 ArrangeChildren_Impl( false );
1230 pWork = pParent;
1231 while ( pWork )
1233 pWork->ShowChildren_Impl();
1234 pWork = pWork->GetParent_Impl();
1237 ShowChildren_Impl();
1240 ShowChildren_Impl();
1243 Reference< ::com::sun::star::task::XStatusIndicator > SfxWorkWindow::GetStatusIndicator()
1245 Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
1246 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1247 Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
1249 if ( xPropSet.is() )
1251 Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName );
1252 aValue >>= xLayoutManager;
1253 if ( xLayoutManager.is() )
1255 xLayoutManager->createElement( m_aProgressBarResName );
1256 xLayoutManager->showElement( m_aProgressBarResName );
1258 Reference< ::com::sun::star::ui::XUIElement > xProgressBar =
1259 xLayoutManager->getElement( m_aProgressBarResName );
1260 if ( xProgressBar.is() )
1262 xStatusIndicator = Reference< ::com::sun::star::task::XStatusIndicator >(
1263 xProgressBar->getRealInterface(), UNO_QUERY );
1268 return xStatusIndicator;
1273 bool SfxWorkWindow::IsPluginMode( SfxObjectShell* pObjShell )
1275 if ( pObjShell && pObjShell->GetMedium() )
1277 SFX_ITEMSET_ARG( pObjShell->GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, false );
1278 if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
1279 return true;
1282 return false;
1287 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxWorkWindow::GetFrameInterface()
1289 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame;
1291 SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() );
1292 if ( pDispatcher )
1294 SfxViewFrame* pFrame = pDispatcher->GetFrame();
1295 if ( pFrame )
1296 xFrame = pFrame->GetFrame().GetFrameInterface();
1299 return xFrame;
1304 void SfxWorkWindow::UpdateObjectBars_Impl()
1306 // Lock SplitWindows (which means suppressing the Resize-Reaction of the
1307 // DockingWindows)
1308 sal_uInt16 n;
1309 for ( n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
1311 SfxSplitWindow *p = pSplit[n];
1312 if (p->GetWindowCount())
1313 p->Lock();
1316 // you realize what is needed often (saves Code and execution time)
1317 SfxGetpApp();
1319 Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
1320 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1322 if ( xPropSet.is() )
1324 Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName );
1325 aValue >>= xLayoutManager;
1328 if ( !xLayoutManager.is() )
1329 return;
1331 bool bPluginMode( false );
1332 SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() );
1334 if ( pDispatcher )
1336 SfxViewFrame* pFrame = pDispatcher->GetFrame();
1337 if ( pFrame )
1338 bPluginMode = IsPluginMode( pFrame->GetObjectShell() );
1341 // Iterate over all Toolboxes
1342 xLayoutManager->lock();
1343 for ( n = 0; n < aObjBarList.size(); ++n )
1345 sal_uInt16 nId = aObjBarList[n].nId;
1346 bool bDestroy = aObjBarList[n].bDestroy;
1348 // Determine the valid mode for the ToolBox
1349 sal_uInt16 nTbxMode = aObjBarList[n].nMode;
1350 bool bFullScreenTbx = SFX_VISIBILITY_FULLSCREEN ==
1351 ( nTbxMode & SFX_VISIBILITY_FULLSCREEN );
1352 nTbxMode &= ~SFX_VISIBILITY_FULLSCREEN;
1353 nTbxMode &= ~SFX_VISIBILITY_VIEWER;
1355 // Is a ToolBox required in this context ?
1356 bool bModesMatching = ( nUpdateMode && ( nTbxMode & nUpdateMode) == nUpdateMode );
1357 if ( bDestroy )
1359 OUString aTbxId( m_aTbxTypeName );
1360 aTbxId += GetResourceURLFromResId( aObjBarList[n].nId );
1361 xLayoutManager->destroyElement( aTbxId );
1363 else if ( nId != 0 && ( ( bModesMatching && !bIsFullScreen ) ||
1364 ( bIsFullScreen && bFullScreenTbx ) ) )
1366 OUString aTbxId( m_aTbxTypeName );
1367 aTbxId += GetResourceURLFromResId( aObjBarList[n].nId );
1368 if ( !IsDockingAllowed() && !xLayoutManager->isElementFloating( aTbxId ))
1369 xLayoutManager->destroyElement( aTbxId );
1370 else
1372 xLayoutManager->requestElement( aTbxId );
1373 if ( bPluginMode )
1374 xLayoutManager->lockWindow( aTbxId );
1377 else if ( nId != 0 )
1379 // Delete the Toolbox at this Position if possible
1380 OUString aTbxId( m_aTbxTypeName );
1381 aTbxId += GetResourceURLFromResId( aObjBarList[n].nId );
1382 xLayoutManager->destroyElement( aTbxId );
1386 UpdateStatusBar_Impl();
1388 // unlocking automatically forces Layout
1389 xLayoutManager->unlock();
1391 UpdateChildWindows_Impl();
1393 // Unlock the SplitWindows again
1394 for ( n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
1396 SfxSplitWindow *p = pSplit[n];
1397 if (p->GetWindowCount())
1398 p->Lock(false);
1402 bool SfxWorkWindow::AllowChildWindowCreation_Impl( const SfxChildWin_Impl& i_rCW ) const
1404 // or checking the availability of child windows, we need access to the module
1405 const SfxViewFrame* pViewFrame = pBindings->GetDispatcher_Impl()->GetFrame();
1406 const SfxObjectShell* pShell = pViewFrame ? pViewFrame->GetObjectShell() : NULL;
1407 const SfxModule* pModule = pShell ? pShell->GetModule() : NULL;
1408 ENSURE_OR_RETURN( pModule, "SfxWorkWindow::UpdateChildWindows_Impl: did not find an SfxModule to ask for the child win availability!", true );
1409 return pModule->IsChildWindowAvailable( i_rCW.nId, pViewFrame );
1412 void SfxWorkWindow::UpdateChildWindows_Impl()
1414 // any current or in the context available Childwindows
1415 for ( sal_uInt16 n=0; n<aChildWins.size(); n++ )
1417 SfxChildWin_Impl *pCW = aChildWins[n];
1418 SfxChildWindow *pChildWin = pCW->pWin;
1419 bool bCreate = false;
1420 if ( pCW->nId && !pCW->bDisabled && (pCW->aInfo.nFlags & SfxChildWindowFlags::ALWAYSAVAILABLE || IsVisible_Impl( pCW->nVisibility ) ) )
1422 // In the context is an appropriate ChildWindow allowed;
1423 // it is also turned on?
1424 if ( pChildWin == NULL && pCW->bCreate )
1426 // Internal docking is only used for embedding into another
1427 // container. We force the floating state of all floatable
1428 // child windows.
1429 if ( !bInternalDockingAllowed )
1431 // Special case for all non-floatable child windows. We have
1432 // to prevent the creation here!
1433 bCreate = !( pCW->aInfo.nFlags & SfxChildWindowFlags::FORCEDOCK );
1435 else if ( !IsDockingAllowed() || bIsFullScreen ) // || !bInternalDocking )
1437 // In Presentation mode or FullScreen only FloatingWindows
1438 SfxChildAlignment eAlign;
1439 if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) )
1440 bCreate = ( eAlign == SfxChildAlignment::NOALIGNMENT );
1442 else
1443 bCreate = true;
1445 if ( bCreate )
1446 bCreate = AllowChildWindowCreation_Impl( *pCW );
1448 // Currently, no window here, but it is enabled; windows
1449 // Create window and if possible theContext
1450 if ( bCreate )
1451 CreateChildWin_Impl( pCW, false );
1453 if ( !bAllChildrenVisible )
1455 if ( pCW->pCli )
1456 pCW->pCli->nVisible &= ~SfxChildVisibility::ACTIVE;
1459 else if ( pChildWin )
1461 // Window already exists, it should also be visible?
1462 if ( ( !bIsFullScreen || pChildWin->GetAlignment() == SfxChildAlignment::NOALIGNMENT ) && bAllChildrenVisible )
1464 // Update Mode is compatible; definitely enable it
1465 bCreate = AllowChildWindowCreation_Impl( *pCW );
1466 if ( bCreate )
1468 if ( pCW->pCli )
1470 // The window is a direct Child
1471 if ( bAllChildrenVisible && ( (IsDockingAllowed() && bInternalDockingAllowed) || pCW->pCli->eAlign == SfxChildAlignment::NOALIGNMENT ) )
1472 pCW->pCli->nVisible |= SfxChildVisibility::NOT_HIDDEN;
1474 else
1476 if ( pCW->bCreate && IsDockingAllowed() && bInternalDockingAllowed )
1477 // The window ia within a SplitWindow
1478 static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Reappear_Impl();
1481 if ( pCW->nInterfaceId != pChildWin->GetContextId() )
1482 pChildWin->CreateContext( pCW->nInterfaceId, GetBindings() );
1488 if ( pChildWin && !bCreate )
1490 if ( !pChildWin->QueryClose() || pChildWin->IsHideNotDelete() || Application::IsUICaptured() )
1492 if ( pCW->pCli )
1494 if ( pCW->pCli->nVisible & SfxChildVisibility::NOT_HIDDEN )
1495 pCW->pCli->nVisible ^= SfxChildVisibility::NOT_HIDDEN;
1497 else
1498 static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Disappear_Impl();
1500 else
1501 RemoveChildWin_Impl( pCW );
1506 void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl *pCW, bool bSetFocus )
1508 pCW->aInfo.bVisible = true;
1510 SfxChildWindow *pChildWin = SfxChildWindow::CreateChildWindow( pCW->nId, pWorkWin, &GetBindings(), pCW->aInfo);
1511 if (pChildWin)
1513 if ( bSetFocus )
1514 bSetFocus = pChildWin->WantsFocus();
1515 pChildWin->SetWorkWindow_Impl( this );
1517 // At least the extra string is changed during the evaluation,
1518 // also get it anewed
1519 SfxChildWinInfo aInfo = pChildWin->GetInfo();
1520 pCW->aInfo.aExtraString = aInfo.aExtraString;
1521 pCW->aInfo.bVisible = aInfo.bVisible;
1522 pCW->aInfo.nFlags |= aInfo.nFlags;
1524 // The creation was successful
1525 GetBindings().Invalidate(pCW->nId);
1527 sal_uInt16 nPos = pChildWin->GetPosition();
1528 if (nPos != CHILDWIN_NOPOS)
1530 DBG_ASSERT(nPos < SFX_OBJECTBAR_MAX, "Illegal objectbar position!");
1531 if ( aChildren[TbxMatch(nPos)] )// &&
1533 // ChildWindow replaces ObjectBar
1534 aChildren[TbxMatch(nPos)]->nVisible ^= SfxChildVisibility::NOT_HIDDEN;
1538 // make childwin keyboard accessible
1539 pWorkWin->GetSystemWindow()->GetTaskPaneList()->AddWindow( pChildWin->GetWindow() );
1541 pCW->pWin = pChildWin;
1543 if ( pChildWin->GetAlignment() == SfxChildAlignment::NOALIGNMENT || pChildWin->GetWindow()->GetParent() == pWorkWin)
1545 // The window is not docked or docked outside of one split windows
1546 // and must therefore be registered explicitly as a Child
1547 pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment(), pChildWin->CanGetFocus());
1548 pCW->pCli->nVisible = SfxChildVisibility::VISIBLE;
1549 if ( pChildWin->GetAlignment() != SfxChildAlignment::NOALIGNMENT && bIsFullScreen )
1550 pCW->pCli->nVisible ^= SfxChildVisibility::ACTIVE;
1551 pCW->pCli->bSetFocus = bSetFocus;
1553 else
1555 // A docked window which parent is not a WorkingWindow, must lie
1556 // in a SplitWindow and thus not be explicitly registered.
1557 // This happens already in the initialization of SfxDockingWindows!
1560 if ( pCW->nInterfaceId != pChildWin->GetContextId() )
1561 pChildWin->CreateContext( pCW->nInterfaceId, GetBindings() );
1563 // Save the information in the INI file
1564 SaveStatus_Impl(pChildWin, pCW->aInfo);
1568 void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl *pCW )
1570 sal_uInt16 nId = pCW->nSaveId;
1571 SfxChildWindow *pChildWin = pCW->pWin;
1573 // Save the information in the INI file
1574 SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
1575 pCW->aInfo = pChildWin->GetInfo();
1576 pCW->aInfo.nFlags |= nFlags;
1577 SaveStatus_Impl(pChildWin, pCW->aInfo);
1579 pChildWin->Hide();
1581 if ( pCW->pCli )
1583 // Child window is a direct child window and must therefore unregister
1584 // itself from the WorkWindow
1585 pCW->pCli = 0;
1586 ReleaseChild_Impl(*pChildWin->GetWindow());
1588 else
1590 // ChildWindow is within a SplitWindow and unregister itself in
1591 // the destructor.
1594 pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChildWin->GetWindow() );
1595 pCW->pWin = 0;
1596 pChildWin->Destroy();
1598 GetBindings().Invalidate( nId );
1601 void SfxWorkWindow::ResetStatusBar_Impl()
1603 aStatBar.nId = 0;
1607 void SfxWorkWindow::SetStatusBar_Impl( sal_uInt32 nResId, SfxShell*, SfxBindings& )
1609 if ( nResId && bShowStatusBar && IsVisible_Impl() )
1610 aStatBar.nId = sal::static_int_cast<sal_uInt16>(nResId);
1613 void SfxWorkWindow::UpdateStatusBar_Impl()
1615 Reference< ::com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
1616 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1618 Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName );
1619 aValue >>= xLayoutManager;
1621 // No status bar, if no ID is required or when in FullScreenView or
1622 // if disabled
1623 if ( aStatBar.nId && IsDockingAllowed() && bInternalDockingAllowed && bShowStatusBar &&
1624 ( (aStatBar.bOn && !bIsFullScreen) || aStatBar.bTemp ) )
1626 // Id has changed, thus create a suitable Statusbarmanager, this takes
1627 // over the current status bar;
1628 if ( xLayoutManager.is() )
1629 xLayoutManager->requestElement( m_aStatusBarResName );
1631 else
1633 // Destroy the current StatusBar
1634 // The Manager only creates the Status bar, does not destroy it.
1635 if ( xLayoutManager.is() )
1636 xLayoutManager->destroyElement( m_aStatusBarResName );
1640 void SfxWorkWindow::MakeVisible_Impl( bool bVis )
1642 if ( bVis )
1643 nOrigMode = SFX_VISIBILITY_STANDARD;
1644 else
1645 nOrigMode = SFX_VISIBILITY_UNVISIBLE;
1647 if ( nOrigMode != nUpdateMode)
1648 nUpdateMode = nOrigMode;
1651 bool SfxWorkWindow::IsVisible_Impl()
1653 return nOrigMode != SFX_VISIBILITY_UNVISIBLE;
1657 void SfxWorkWindow::HidePopups_Impl(bool bHide, bool bParent, sal_uInt16 nId )
1659 for ( sal_uInt16 n = 0; n < aChildWins.size(); ++n )
1661 SfxChildWindow *pCW = aChildWins[n]->pWin;
1662 if (pCW && pCW->GetAlignment() == SfxChildAlignment::NOALIGNMENT && pCW->GetType() != nId)
1664 vcl::Window *pWin = pCW->GetWindow();
1665 SfxChild_Impl *pChild = FindChild_Impl(*pWin);
1666 if (bHide)
1668 pChild->nVisible &= ~SfxChildVisibility::ACTIVE;
1669 pCW->Hide();
1671 else
1673 pChild->nVisible |= SfxChildVisibility::ACTIVE;
1674 if ( SfxChildVisibility::VISIBLE == (pChild->nVisible & SfxChildVisibility::VISIBLE) )
1675 pCW->Show( SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
1680 if ( bParent && pParent )
1681 pParent->HidePopups_Impl( bHide, bParent, nId );
1686 void SfxWorkWindow::ConfigChild_Impl(SfxChildIdentifier eChild,
1687 SfxDockingConfig eConfig, sal_uInt16 nId)
1689 SfxDockingWindow* pDockWin=0;
1690 sal_uInt16 nPos = USHRT_MAX;
1691 vcl::Window *pWin=0;
1692 SfxChildWin_Impl *pCW = 0;
1694 if ( eChild == SfxChildIdentifier::OBJECTBAR )
1695 return;
1697 // configure direct childwindow
1698 for (sal_uInt16 n=0; n<aChildWins.size(); n++)
1700 pCW = aChildWins[n];
1701 SfxChildWindow *pChild = pCW->pWin;
1702 if ( pChild )
1704 if ( pChild->GetType() == nId )
1706 if ( pChild->GetWindow()->GetType() == RSC_DOCKINGWINDOW )
1707 // it's a DockingWindow
1708 pDockWin = static_cast<SfxDockingWindow*>( pChild->GetWindow() );
1709 else
1710 // FloatingWindow or ModelessDialog
1711 pWin = pChild->GetWindow();
1712 break;
1717 if ( pDockWin )
1719 if ( eChild == SfxChildIdentifier::DOCKINGWINDOW || pDockWin->GetAlignment() == SfxChildAlignment::NOALIGNMENT )
1721 if ( eChild == SfxChildIdentifier::SPLITWINDOW && eConfig == SfxDockingConfig::TOGGLEFLOATMODE)
1723 // DockingWindow was dragged out of a SplitWindow
1724 pCW->pCli = RegisterChild_Impl(*pDockWin, pDockWin->GetAlignment(), pCW->pWin->CanGetFocus());
1725 pCW->pCli->nVisible = SfxChildVisibility::VISIBLE;
1728 pWin = pDockWin;
1730 else
1732 SfxSplitWindow *pSplitWin = GetSplitWindow_Impl(pDockWin->GetAlignment());
1734 // configure DockingWindow inside a SplitWindow
1735 if ( eConfig == SfxDockingConfig::TOGGLEFLOATMODE)
1737 // DockingWindow was dragged into a SplitWindow
1738 pCW->pCli = 0;
1739 ReleaseChild_Impl(*pDockWin);
1742 pWin = pSplitWin->GetSplitWindow();
1743 if ( pSplitWin->GetWindowCount() == 1 )
1744 static_cast<SplitWindow*>(pWin)->Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
1748 DBG_ASSERT( pCW, "Unknown window!" );
1749 if ( !pCW && pParent )
1751 pParent->ConfigChild_Impl( eChild, eConfig, nId );
1752 return;
1755 if ( !bSorted )
1756 // windows may have been registered and released without an update until now
1757 Sort_Impl();
1759 sal_uInt16 n;
1760 for ( n=0; n<aSortedList.size(); ++n )
1762 SfxChild_Impl *pChild = aChildren[aSortedList[n]];
1763 if ( pChild )
1764 if ( pChild->pWin == pWin )
1765 break;
1768 if ( n < aSortedList.size() )
1769 // sometimes called while toggeling float mode
1770 nPos = aSortedList[n];
1772 switch ( eConfig )
1774 case SfxDockingConfig::SETDOCKINGRECTS :
1776 if (nPos == USHRT_MAX || !pDockWin)
1777 return;
1779 Rectangle aOuterRect( GetTopRect_Impl() );
1780 aOuterRect.SetPos( pWorkWin->OutputToScreenPixel( aOuterRect.TopLeft() ));
1781 Rectangle aInnerRect( aOuterRect );
1783 // The current affected window is included in the calculation of
1784 // the inner rectangle!
1785 for ( sal_uInt16 m=0; m<aSortedList.size(); ++m )
1787 sal_uInt16 i=aSortedList[m];
1788 SfxChild_Impl* pCli = aChildren[i];
1790 if ( pCli && pCli->nVisible == SfxChildVisibility::VISIBLE && pCli->pWin )
1792 switch ( pCli->eAlign )
1794 case SfxChildAlignment::TOP:
1795 // Objekt-Toolboxes come always last
1796 aInnerRect.Top() += pCli->aSize.Height();
1797 break;
1799 case SfxChildAlignment::HIGHESTTOP:
1800 // Always performed first
1801 aInnerRect.Top() += pCli->aSize.Height();
1802 break;
1804 case SfxChildAlignment::LOWESTTOP:
1805 // Is only counted if it is the current window
1806 if ( i == nPos )
1807 aInnerRect.Top() += pCli->aSize.Height();
1808 break;
1810 case SfxChildAlignment::BOTTOM:
1811 // Objekt-Toolboxes come always last
1812 aInnerRect.Bottom() -= pCli->aSize.Height();
1813 break;
1815 case SfxChildAlignment::LOWESTBOTTOM:
1816 // Always performed first
1817 aInnerRect.Bottom() -= pCli->aSize.Height();
1818 break;
1820 case SfxChildAlignment::HIGHESTBOTTOM:
1821 // Is only counted if it is the current window
1822 if ( i == nPos )
1823 aInnerRect.Bottom() -= pCli->aSize.Height();
1824 break;
1826 case SfxChildAlignment::LEFT:
1827 // Toolboxes come always last
1828 aInnerRect.Left() += pCli->aSize.Width();
1829 break;
1831 case SfxChildAlignment::FIRSTLEFT:
1832 // Always performed first
1833 aInnerRect.Left() += pCli->aSize.Width();
1834 break;
1836 case SfxChildAlignment::LASTLEFT:
1837 // Is only counted if it is the current window
1838 if (i == nPos)
1839 aInnerRect.Left() += pCli->aSize.Width();
1841 case SfxChildAlignment::RIGHT:
1842 // Toolboxes come always last
1843 aInnerRect.Right() -= pCli->aSize.Width();
1844 break;
1846 case SfxChildAlignment::FIRSTRIGHT:
1847 // Is only counted if it is the current window
1848 if (i == nPos)
1849 aInnerRect.Right() -= pCli->aSize.Width();
1850 break;
1852 case SfxChildAlignment::LASTRIGHT:
1853 // Always performed first
1854 aInnerRect.Right() -= pCli->aSize.Width();
1855 break;
1857 default:
1858 break;
1863 pDockWin->SetDockingRects(aOuterRect, aInnerRect);
1864 break;
1867 case SfxDockingConfig::MOVEDOCKINGWINDOW :
1868 case SfxDockingConfig::ALIGNDOCKINGWINDOW :
1869 case SfxDockingConfig::TOGGLEFLOATMODE:
1871 if ( nPos == USHRT_MAX && !pCW )
1872 return;
1874 SfxChildAlignment eAlign = SfxChildAlignment::NOALIGNMENT;
1875 SfxChild_Impl *pCli = ( nPos != USHRT_MAX ) ? aChildren[nPos] : 0;
1876 if ( pCli && pDockWin )
1878 eAlign = pDockWin->GetAlignment();
1879 if ( eChild == SfxChildIdentifier::DOCKINGWINDOW || eAlign == SfxChildAlignment::NOALIGNMENT)
1881 // configuration inside the SplitWindow, no change for the SplitWindows' configuration
1882 pCli->bResize = true;
1883 pCli->aSize = pDockWin->GetSizePixel();
1887 if ( pCli )
1889 if( pCli->eAlign != eAlign )
1891 bSorted = false;
1892 pCli->eAlign = eAlign;
1895 ArrangeChildren_Impl();
1896 ShowChildren_Impl();
1899 if ( pCW && pCW->pWin )
1901 // store changed configuration
1902 SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
1903 pCW->aInfo = pCW->pWin->GetInfo();
1904 pCW->aInfo.nFlags |= nFlags;
1905 if ( eConfig != SfxDockingConfig::MOVEDOCKINGWINDOW )
1906 SaveStatus_Impl( pCW->pWin, pCW->aInfo);
1909 break;
1916 void SfxWorkWindow::SetChildWindowVisible_Impl( sal_uInt32 lId, bool bEnabled, sal_uInt16 nMode )
1918 sal_uInt16 nInter = (sal_uInt16) ( lId >> 16 );
1919 sal_uInt16 nId = (sal_uInt16) ( lId & 0xFFFF );
1921 SfxChildWin_Impl *pCW=NULL;
1922 SfxWorkWindow *pWork = pParent;
1924 // Get the top parent, child windows are always registered at the
1925 // task of the WorkWindow for example the frame or on AppWorkWindow
1926 while ( pWork && pWork->pParent )
1927 pWork = pWork->pParent;
1929 if ( pWork )
1931 // The Parent already known?
1932 sal_uInt16 nCount = pWork->aChildWins.size();
1933 for (sal_uInt16 n=0; n<nCount; n++)
1934 if (pWork->aChildWins[n]->nSaveId == nId)
1936 pCW = pWork->aChildWins[n];
1937 break;
1941 if ( !pCW )
1943 // If no Parent or the Parent us still unknown, then search here
1944 sal_uInt16 nCount = aChildWins.size();
1945 for (sal_uInt16 n=0; n<nCount; n++)
1946 if (aChildWins[n]->nSaveId == nId)
1948 pCW = aChildWins[n];
1949 break;
1953 if ( !pCW )
1955 // If new, then initialize, add this here depending on the flag or
1956 // the Parent
1957 pCW = new SfxChildWin_Impl( lId );
1958 pCW->nId = nId;
1959 InitializeChild_Impl( pCW );
1960 if ( pWork && !( pCW->aInfo.nFlags & SfxChildWindowFlags::TASK ) )
1961 pWork->aChildWins.push_back( pCW );
1962 else
1963 aChildWins.push_back( pCW );
1966 pCW->nId = nId;
1967 if ( nInter )
1968 pCW->nInterfaceId = nInter;
1969 pCW->nVisibility = nMode;
1970 pCW->bEnable = bEnabled;
1971 pCW->nVisibility = nMode;
1975 // The on/off status of a ChildWindow is switched
1977 void SfxWorkWindow::ToggleChildWindow_Impl(sal_uInt16 nId, bool bSetFocus)
1979 sal_uInt16 nCount = aChildWins.size();
1980 sal_uInt16 n;
1981 for (n=0; n<nCount; n++)
1982 if (aChildWins[n]->nId == nId)
1983 break;
1985 if ( n<nCount )
1987 // The Window is already known
1988 SfxChildWin_Impl *pCW = aChildWins[n];
1989 SfxChildWindow *pChild = pCW->pWin;
1991 bool bCreationAllowed( true );
1992 if ( !bInternalDockingAllowed )
1994 // Special case for all non-floatable child windows. We have
1995 // to prevent the creation here!
1996 bCreationAllowed = !( pCW->aInfo.nFlags & SfxChildWindowFlags::FORCEDOCK );
1999 if ( bCreationAllowed )
2001 if ( pCW->bCreate )
2003 if ( pChild )
2005 if ( pChild->QueryClose() )
2007 pCW->bCreate = false;
2008 if ( pChild->IsHideAtToggle() )
2010 ShowChildWindow_Impl( nId, false, bSetFocus );
2012 else
2014 // The Window should be switched off
2015 pChild->SetVisible_Impl( false );
2016 RemoveChildWin_Impl( pCW );
2020 else
2022 // no actual Window exists, yet => just remember the "switched off" state
2023 pCW->bCreate = false;
2026 else
2028 pCW->bCreate = AllowChildWindowCreation_Impl( *pCW );
2029 if ( pCW->bCreate )
2031 if ( pChild )
2033 ShowChildWindow_Impl( nId, true, bSetFocus );
2035 else
2037 // create actual Window
2038 CreateChildWin_Impl( pCW, bSetFocus );
2039 if ( !pCW->pWin )
2040 // no success
2041 pCW->bCreate = false;
2047 ArrangeChildren_Impl();
2048 ShowChildren_Impl();
2050 if ( pCW->bCreate && bCreationAllowed )
2052 if ( !pCW->pCli )
2054 SfxDockingWindow *pDock =
2055 static_cast<SfxDockingWindow*>( pCW->pWin->GetWindow() );
2056 if ( pDock->IsAutoHide_Impl() )
2057 pDock->AutoShow_Impl();
2061 return;
2063 else if ( pParent )
2065 pParent->ToggleChildWindow_Impl( nId, bSetFocus );
2066 return;
2069 #ifdef DBG_UTIL
2070 nCount = aChildWins.size();
2071 for (n=0; n<nCount; n++)
2072 if (aChildWins[n]->nSaveId == nId)
2073 break;
2075 if ( n < nCount )
2077 OSL_FAIL("The ChildWindow is not in context!");
2079 else
2081 OSL_FAIL("The ChildWindow is not registered!");
2083 #endif
2088 bool SfxWorkWindow::HasChildWindow_Impl(sal_uInt16 nId)
2090 sal_uInt16 nCount = aChildWins.size();
2091 sal_uInt16 n;
2092 for (n=0; n<nCount; n++)
2093 if (aChildWins[n]->nSaveId == nId)
2094 break;
2096 if (n<nCount)
2098 SfxChildWin_Impl *pCW = aChildWins[n];
2099 SfxChildWindow *pChild = pCW->pWin;
2100 return ( pChild && pCW->bCreate );
2103 if ( pParent )
2104 return pParent->HasChildWindow_Impl( nId );
2106 return false;
2109 bool SfxWorkWindow::IsFloating( sal_uInt16 nId )
2111 SfxChildWin_Impl *pCW=NULL;
2112 SfxWorkWindow *pWork = pParent;
2114 // Get the top parent, child windows are always registered at the
2115 // task of the WorkWindow for example the frame or on AppWorkWindow
2116 while ( pWork && pWork->pParent )
2117 pWork = pWork->pParent;
2119 if ( pWork )
2121 // The Parent already known?
2122 sal_uInt16 nCount = pWork->aChildWins.size();
2123 for (sal_uInt16 n=0; n<nCount; n++)
2124 if (pWork->aChildWins[n]->nSaveId == nId)
2126 pCW = pWork->aChildWins[n];
2127 break;
2131 if ( !pCW )
2133 // If no Parent or the Parent us still unknown, then search here
2134 sal_uInt16 nCount = aChildWins.size();
2135 for (sal_uInt16 n=0; n<nCount; n++)
2136 if (aChildWins[n]->nSaveId == nId)
2138 pCW = aChildWins[n];
2139 break;
2143 if ( !pCW )
2145 // If new, then initialize, add this here depending on the flag or
2146 // the Parent
2147 pCW = new SfxChildWin_Impl( nId );
2148 pCW->bEnable = false;
2149 pCW->nId = 0;
2150 pCW->nVisibility = 0;
2151 InitializeChild_Impl( pCW );
2152 if ( pWork && !( pCW->aInfo.nFlags & SfxChildWindowFlags::TASK ) )
2153 pWork->aChildWins.push_back( pCW );
2154 else
2155 aChildWins.push_back( pCW );
2158 SfxChildAlignment eAlign;
2159 if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) )
2160 return( eAlign == SfxChildAlignment::NOALIGNMENT );
2161 else
2162 return true;
2167 bool SfxWorkWindow::KnowsChildWindow_Impl(sal_uInt16 nId)
2169 SfxChildWin_Impl *pCW=0;
2170 sal_uInt16 nCount = aChildWins.size();
2171 sal_uInt16 n;
2172 for (n=0; n<nCount; n++)
2174 pCW = aChildWins[n];
2175 if ( pCW->nSaveId == nId)
2176 break;
2179 if (n<nCount)
2181 if ( !(pCW->aInfo.nFlags & SfxChildWindowFlags::ALWAYSAVAILABLE) && !IsVisible_Impl( pCW->nVisibility ) )
2182 return false;
2183 return pCW->bEnable;
2185 else if ( pParent )
2186 return pParent->KnowsChildWindow_Impl( nId );
2187 else
2188 return false;
2193 void SfxWorkWindow::SetChildWindow_Impl(sal_uInt16 nId, bool bOn, bool bSetFocus)
2195 SfxChildWin_Impl *pCW=NULL;
2196 SfxWorkWindow *pWork = pParent;
2198 // Get the top parent, child windows are always registered at the
2199 // task of the WorkWindow for example the frame or on AppWorkWindow
2200 while ( pWork && pWork->pParent )
2201 pWork = pWork->pParent;
2203 if ( pWork )
2205 // The Parent already known?
2206 sal_uInt16 nCount = pWork->aChildWins.size();
2207 for (sal_uInt16 n=0; n<nCount; n++)
2208 if (pWork->aChildWins[n]->nSaveId == nId)
2210 pCW = pWork->aChildWins[n];
2211 break;
2215 if ( !pCW )
2217 // If no Parent or the Parent us still unknown, then search here
2218 sal_uInt16 nCount = aChildWins.size();
2219 for (sal_uInt16 n=0; n<nCount; n++)
2220 if (aChildWins[n]->nSaveId == nId)
2222 pCW = aChildWins[n];
2223 pWork = this;
2224 break;
2228 if ( !pCW )
2230 // If new, then initialize, add this here depending on the flag or
2231 // the Parent
2232 pCW = new SfxChildWin_Impl( nId );
2233 InitializeChild_Impl( pCW );
2234 if ( !pWork || pCW->aInfo.nFlags & SfxChildWindowFlags::TASK )
2235 pWork = this;
2236 pWork->aChildWins.push_back( pCW );
2239 if ( pCW->bCreate != bOn )
2240 pWork->ToggleChildWindow_Impl(nId,bSetFocus);
2245 void SfxWorkWindow::ShowChildWindow_Impl(sal_uInt16 nId, bool bVisible, bool bSetFocus)
2247 sal_uInt16 nCount = aChildWins.size();
2248 SfxChildWin_Impl* pCW=0;
2249 sal_uInt16 n;
2250 for (n=0; n<nCount; n++)
2252 pCW = aChildWins[n];
2253 if (pCW->nId == nId)
2254 break;
2257 if ( n<nCount )
2259 SfxChildWindow *pChildWin = pCW->pWin;
2260 if ( pChildWin )
2262 if ( bVisible )
2264 if ( pCW->pCli )
2266 pCW->pCli->bSetFocus = bSetFocus;
2267 pCW->pCli->nVisible = SfxChildVisibility::VISIBLE;
2268 pChildWin->Show( bSetFocus && pChildWin->WantsFocus() ? 0 : SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
2270 else
2271 static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Reappear_Impl();
2274 else
2276 if ( pCW->pCli )
2278 pCW->pCli->nVisible = SfxChildVisibility::VISIBLE ^ SfxChildVisibility::NOT_HIDDEN;
2279 pCW->pWin->Hide();
2281 else
2282 static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Disappear_Impl();
2286 ArrangeChildren_Impl();
2287 ShowChildren_Impl();
2289 else if ( bVisible )
2291 SetChildWindow_Impl( nId, true, bSetFocus );
2292 pChildWin = pCW->pWin;
2295 if ( pChildWin )
2297 pChildWin->SetVisible_Impl( bVisible );
2298 SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
2299 pCW->aInfo = pChildWin->GetInfo();
2300 pCW->aInfo.nFlags |= nFlags;
2301 if ( !pCW->bCreate )
2302 SaveStatus_Impl( pChildWin, pCW->aInfo );
2305 return;
2308 if ( pParent )
2310 pParent->ShowChildWindow_Impl( nId, bVisible, bSetFocus );
2311 return;
2314 #ifdef DBG_UTIL
2315 nCount = aChildWins.size();
2316 for (n=0; n<nCount; n++)
2317 if (aChildWins[n]->nSaveId == nId)
2318 break;
2320 if ( n<nCount )
2322 OSL_FAIL("The ChildWindow is not in context!");
2324 else
2326 OSL_FAIL("The ChildWindow is not registered");
2328 #endif
2333 SfxChildWindow* SfxWorkWindow::GetChildWindow_Impl(sal_uInt16 nId)
2335 sal_uInt16 nCount = aChildWins.size();
2336 sal_uInt16 n;
2337 for (n=0; n<nCount; n++)
2338 if (aChildWins[n]->nSaveId == nId)
2339 break;
2341 if (n<nCount)
2342 return aChildWins[n]->pWin;
2343 else if ( pParent )
2344 return pParent->GetChildWindow_Impl( nId );
2345 return 0;
2350 void SfxWorkWindow::ResetChildWindows_Impl()
2352 for ( sal_uInt16 n = 0; n < aChildWins.size(); ++n )
2354 aChildWins[n]->nId = 0;
2355 aChildWins[n]->bEnable = false;
2360 // Virtual method that returns the size of the area (client area) of the
2361 // parent windows, in which the ChildWindow can be fitted.
2363 Rectangle SfxWorkWindow::GetTopRect_Impl()
2365 return Rectangle (Point(), pWorkWin->GetOutputSizePixel() );
2369 // Virtual method that returns the size of the area (client area) of the
2370 // parent windows, in which the ChildWindow can be fitted.
2372 Rectangle SfxFrameWorkWin_Impl::GetTopRect_Impl()
2374 return pMasterFrame->GetTopOuterRectPixel_Impl();
2378 // Virtual method to find out if there is room for a ChildWindow in the
2379 // client area of the parent.
2381 bool SfxWorkWindow::RequestTopToolSpacePixel_Impl( SvBorder aBorder )
2383 if ( !IsDockingAllowed() ||
2384 aClientArea.GetWidth() < aBorder.Left() + aBorder.Right() ||
2385 aClientArea.GetHeight() < aBorder.Top() + aBorder.Bottom() )
2386 return false;
2387 else
2388 return true;;
2391 void SfxWorkWindow::SaveStatus_Impl(SfxChildWindow *pChild, const SfxChildWinInfo &rInfo)
2393 // The Status of the Presentation mode is not saved
2394 if ( IsDockingAllowed() && bInternalDockingAllowed )
2395 pChild->SaveStatus(rInfo);
2398 void SfxWorkWindow::InitializeChild_Impl(SfxChildWin_Impl *pCW)
2400 SfxDispatcher *pDisp = pBindings->GetDispatcher_Impl();
2401 SfxViewFrame *pFrame = pDisp ? pDisp->GetFrame() :0;
2402 SfxModule *pMod = pFrame ? SfxModule::GetActiveModule(pFrame) :0;
2404 OUString sModule;
2405 if (pFrame)
2409 using namespace ::com::sun::star;
2410 uno::Reference< frame::XModuleManager2 > xModuleManager(
2411 frame::ModuleManager::create(::comphelper::getProcessComponentContext()));
2412 sModule = xModuleManager->identify(pFrame->GetFrame().GetFrameInterface());
2413 SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(sModule);
2414 sModule = SvtModuleOptions::GetFactoryShortName(eFac);
2416 catch (...)
2421 SfxChildWinFactory* pFact=0;
2422 SfxApplication *pApp = SfxGetpApp();
2424 SfxChildWinFactArr_Impl &rFactories = pApp->GetChildWinFactories_Impl();
2425 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.size(); ++nFactory )
2427 pFact = &rFactories[nFactory];
2428 if ( pFact->nId == pCW->nSaveId )
2430 pCW->aInfo = pFact->aInfo;
2431 pCW->aInfo.aModule = sModule;
2432 SfxChildWindow::InitializeChildWinFactory_Impl(
2433 pCW->nSaveId, pCW->aInfo);
2434 pCW->bCreate = pCW->aInfo.bVisible;
2435 SfxChildWindowFlags nFlags = pFact->aInfo.nFlags;
2436 if ( nFlags & SfxChildWindowFlags::TASK )
2437 pCW->aInfo.nFlags |= SfxChildWindowFlags::TASK;
2438 if ( nFlags & SfxChildWindowFlags::CANTGETFOCUS )
2439 pCW->aInfo.nFlags |= SfxChildWindowFlags::CANTGETFOCUS;
2440 if ( nFlags & SfxChildWindowFlags::FORCEDOCK )
2441 pCW->aInfo.nFlags |= SfxChildWindowFlags::FORCEDOCK;
2442 pFact->aInfo = pCW->aInfo;
2443 return;
2448 if ( pMod )
2450 SfxChildWinFactArr_Impl *pFactories = pMod->GetChildWinFactories_Impl();
2451 if ( pFactories )
2453 SfxChildWinFactArr_Impl &rFactories = *pFactories;
2454 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.size(); ++nFactory )
2456 pFact = &rFactories[nFactory];
2457 if ( pFact->nId == pCW->nSaveId )
2459 pCW->aInfo = pFact->aInfo;
2460 pCW->aInfo.aModule = sModule;
2461 SfxChildWindow::InitializeChildWinFactory_Impl(
2462 pCW->nSaveId, pCW->aInfo);
2463 pCW->bCreate = pCW->aInfo.bVisible;
2464 SfxChildWindowFlags nFlags = pFact->aInfo.nFlags;
2465 if ( nFlags & SfxChildWindowFlags::TASK )
2466 pCW->aInfo.nFlags |= SfxChildWindowFlags::TASK;
2467 if ( nFlags & SfxChildWindowFlags::CANTGETFOCUS )
2468 pCW->aInfo.nFlags |= SfxChildWindowFlags::CANTGETFOCUS;
2469 if ( nFlags & SfxChildWindowFlags::FORCEDOCK )
2470 pCW->aInfo.nFlags |= SfxChildWindowFlags::FORCEDOCK;
2471 if ( nFlags & SfxChildWindowFlags::ALWAYSAVAILABLE )
2472 pCW->aInfo.nFlags |= SfxChildWindowFlags::ALWAYSAVAILABLE;
2473 pFact->aInfo = pCW->aInfo;
2474 return;
2481 SfxSplitWindow* SfxWorkWindow::GetSplitWindow_Impl( SfxChildAlignment eAlign )
2483 switch ( eAlign )
2485 case SfxChildAlignment::TOP:
2486 return pSplit[2];
2488 case SfxChildAlignment::BOTTOM:
2489 return pSplit[3];
2491 case SfxChildAlignment::LEFT:
2492 return pSplit[0];
2494 case SfxChildAlignment::RIGHT:
2495 return pSplit[1];
2497 default:
2498 return 0;
2502 void SfxWorkWindow::MakeChildrenVisible_Impl( bool bVis )
2504 if ( pParent )
2505 pParent->MakeChildrenVisible_Impl( bVis );
2507 bAllChildrenVisible = bVis;
2508 if ( bVis )
2510 if ( !bSorted )
2511 Sort_Impl();
2512 for ( sal_uInt16 n=0; n<aSortedList.size(); ++n )
2514 SfxChild_Impl* pCli = aChildren[aSortedList[n]];
2515 if ( (pCli->eAlign == SfxChildAlignment::NOALIGNMENT) || (IsDockingAllowed() && bInternalDockingAllowed) )
2516 pCli->nVisible |= SfxChildVisibility::ACTIVE;
2519 else
2521 if ( !bSorted )
2522 Sort_Impl();
2523 for ( sal_uInt16 n=0; n<aSortedList.size(); ++n )
2525 SfxChild_Impl* pCli = aChildren[aSortedList[n]];
2526 pCli->nVisible &= ~SfxChildVisibility::ACTIVE;
2531 bool SfxWorkWindow::IsAutoHideMode( const SfxSplitWindow *pSplitWin )
2533 for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
2535 if ( pSplit[n].get() != pSplitWin && pSplit[n]->IsAutoHide( true ) )
2536 return true;
2538 return false;
2542 void SfxWorkWindow::EndAutoShow_Impl( Point aPos )
2544 if ( pParent )
2545 pParent->EndAutoShow_Impl( aPos );
2547 for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
2549 SfxSplitWindow *p = pSplit[n];
2550 if ( p && p->IsAutoHide() )
2552 Point aLocalPos = p->ScreenToOutputPixel( aPos );
2553 Point aEmptyPoint = Point();
2554 Rectangle aRect( aEmptyPoint, p->GetSizePixel() );
2555 if ( !aRect.IsInside( aLocalPos ) )
2556 p->FadeOut();
2561 void SfxWorkWindow::ArrangeAutoHideWindows( SfxSplitWindow *pActSplitWin )
2563 if ( m_nLock )
2564 return;
2566 if ( pParent )
2567 pParent->ArrangeAutoHideWindows( pActSplitWin );
2569 Rectangle aArea( aUpperClientArea );
2570 for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
2572 // Either dummy window or window in the auto-show-mode are processed
2573 // (not pinned, FadeIn).
2574 // Only the abandoned window may be invisible, because perhaps its
2575 // size is just being calculated before it is displayed.
2576 SfxSplitWindow* pSplitWin = pSplit[n];
2577 bool bDummyWindow = !pSplitWin->IsFadeIn();
2578 vcl::Window *pDummy = pSplitWin->GetSplitWindow();
2579 vcl::Window *pWin = bDummyWindow ? pDummy : pSplitWin;
2580 if ( (pSplitWin->IsPinned() && !bDummyWindow) || (!pWin->IsVisible() && pActSplitWin != pSplitWin) )
2581 continue;
2583 // Width and position of the dummy window as a starting point
2584 Size aSize = pDummy->GetSizePixel();
2585 Point aPos = pDummy->GetPosPixel();
2587 switch ( n )
2589 case ( 0 ) :
2591 // Left SplitWindow
2592 // Get the width of the Window yourself, if no DummyWindow
2593 if ( !bDummyWindow )
2594 aSize.Width() = pSplitWin->GetSizePixel().Width();
2596 // If a Window is visible to the left, then the free region
2597 // starts to the right from it, for example at the Client area
2598 long nLeft = aPos.X() + aSize.Width();
2599 if ( nLeft > aArea.Left() )
2600 aArea.Left() = nLeft;
2601 break;
2603 case ( 1 ) :
2605 // Right SplitWindow
2606 // Position to correct the difference of the widths
2607 aPos.X() += aSize.Width();
2609 // Get the width of the Window yourself, if no DummyWindow
2610 if ( !bDummyWindow )
2611 aSize.Width() = pSplitWin->GetSizePixel().Width();
2613 aPos.X() -= aSize.Width();
2615 // If already a window is opened at the left side, then the
2616 // right is not allowed to overlap this one.
2617 if ( aPos.X() < aArea.Left() )
2619 aPos.X() = aArea.Left();
2620 aSize.Width() = aArea.GetWidth();
2623 // If a Window is visible to the right, then the free region
2624 // starts to the left from it, for example at the Client area
2625 long nRight = aPos.X();
2626 if ( nRight < aArea.Right() )
2627 aArea.Right() = nRight;
2628 break;
2630 case ( 2 ) :
2632 // Top SplitWindow
2633 // Get the height of the Window yourself, if no DummyWindow
2634 if ( !bDummyWindow )
2635 aSize.Height() = pSplitWin->GetSizePixel().Height();
2638 // Adjust width with regard to if a Window is already open
2639 // to the left or right
2640 aPos.X() = aArea.Left();
2641 aSize.Width() = aArea.GetWidth();
2643 // If a Window is visible at the top, then the free region
2644 // starts beneath it, for example at the Client area
2645 long nTop = aPos.Y() + aSize.Height();
2646 if ( nTop > aArea.Top() )
2647 aArea.Top() = nTop;
2648 break;
2650 case ( 3 ) :
2652 // The bottom SplitWindow
2653 // Position to correct the difference of the heights
2654 aPos.Y() += aSize.Height();
2656 // Get the height of the Window yourself, if no DummyWindow
2657 if ( !bDummyWindow )
2658 aSize.Height() = pSplitWin->GetSizePixel().Height();
2660 aPos.Y() -= aSize.Height();
2662 // Adjust width with regard to if a Window is already open
2663 // to the left or right.
2664 aPos.X() = aArea.Left();
2665 aSize.Width() = aArea.GetWidth();
2667 // If already a window is opened at the top, then the
2668 // bottom one is not allowed to overlap this one.
2669 if ( aPos.Y() < aArea.Top() )
2671 aPos.Y() = aArea.Top();
2672 aSize.Height() = aArea.GetHeight();
2675 break;
2679 if ( !bDummyWindow )
2680 // the FadeIn-Window is a Floating window, which coordinates are
2681 // set in Screen coordinates.
2682 pSplitWin->SetPosSizePixel( pWorkWin->OutputToScreenPixel(aPos), aSize );
2683 else
2684 // the docked DummyWindow
2685 pDummy->SetPosSizePixel( aPos, aSize );
2689 Rectangle SfxWorkWindow::GetFreeArea( bool bAutoHide ) const
2691 if ( bAutoHide )
2693 Rectangle aArea( aClientArea );
2694 for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
2696 if ( pSplit[n]->IsPinned() || !pSplit[n]->IsVisible() )
2697 continue;
2699 Size aSize = pSplit[n]->GetSizePixel();
2700 switch ( n )
2702 case ( 0 ) :
2703 aArea.Left() += aSize.Width();
2704 break;
2705 case ( 1 ) :
2706 aArea.Right() -= aSize.Width();
2707 break;
2708 case ( 2 ) :
2709 aArea.Top() += aSize.Height();
2710 break;
2711 case ( 3 ) :
2712 aArea.Bottom() -= aSize.Height();
2713 break;
2717 return aArea;
2719 else
2720 return aClientArea;
2723 void SfxWorkWindow::SetActiveChild_Impl( vcl::Window *pChild )
2725 pActiveChild = pChild;
2728 bool SfxWorkWindow::ActivateNextChild_Impl( bool bForward )
2730 // Sort all children under list
2731 std::vector<sal_uInt16> aList;
2732 for ( sal_uInt16 i=SFX_OBJECTBAR_MAX; i<aChildren.size(); i++)
2734 SfxChild_Impl *pCli = aChildren[i];
2735 if ( pCli && pCli->bCanGetFocus && pCli->pWin )
2737 sal_uInt16 k;
2738 for (k=0; k<aList.size(); k++)
2739 if ( ChildTravelValue( aChildren[aList[k]]->eAlign) > ChildTravelValue(pCli->eAlign) )
2740 break;
2741 aList.insert( aList.begin() + k, i );
2745 if ( aList.empty() )
2746 return false;
2748 sal_uInt16 nTopValue = ChildTravelValue( SfxChildAlignment::LOWESTTOP );
2749 for ( sal_uInt16 i=0; i<aList.size(); i++ )
2751 SfxChild_Impl* pCli = aChildren[aList[i]];
2752 if ( pCli->pWin && ChildTravelValue( pCli->eAlign ) > nTopValue )
2753 break;
2756 sal_uInt16 n = bForward ? 0 : aList.size()-1;
2757 SfxChild_Impl *pAct=NULL;
2758 if ( pActiveChild )
2760 // Look for the active window
2761 for ( n=0; n<aList.size(); n++ )
2763 SfxChild_Impl* pCli = aChildren[aList[n]];
2764 if ( pCli && pCli->pWin && ( pCli->pWin == pActiveChild || !pActiveChild ) )
2766 pAct = pCli;
2767 break;
2772 // dummy entries for the container window
2773 aList.insert( aList.begin(), 0xFFFF );
2774 aList.push_back( 0xFFFF );
2775 n = n + 1;
2776 if ( pAct )
2778 for ( sal_uInt16 i=0; i<SFX_SPLITWINDOWS_MAX; i++ )
2780 // Maybe the pNext is a Splitwindow
2781 SfxSplitWindow *p = pSplit[i];
2782 if ( pAct->pWin == p )
2784 if( p->ActivateNextChild_Impl( bForward ) )
2785 return true;
2786 break;
2790 // pAct is a direct ChildWindow
2791 // continue with the successor or predecessor of the active window
2792 if ( bForward )
2793 n = n+1;
2794 else
2795 n = n-1;
2797 if ( n == 0 || n == aList.size()-1 )
2798 return false;
2801 for( ;; )
2803 SfxChild_Impl* pCli = aChildren[aList[n]];
2804 if ( pCli->pWin )
2806 SfxChild_Impl* pNext = pCli;
2807 for ( sal_uInt16 i=0; n<SFX_SPLITWINDOWS_MAX; n++ )
2809 // Maybe the pNext is a Splitwindow
2810 SfxSplitWindow *p = pSplit[i];
2811 if ( pNext->pWin == p )
2813 // Activate the first/last window
2814 p->SetActiveWindow_Impl( NULL );
2815 pNext = NULL;
2816 if( p->ActivateNextChild_Impl( bForward ) )
2817 return true;
2818 break;
2822 if ( pNext )
2824 pNext->pWin->GrabFocus();
2825 pActiveChild = pNext->pWin;
2826 return true;
2830 if ( bForward )
2831 n = n+1;
2832 else
2833 n = n-1;
2835 if ( n == 0 || n == aList.size()-1 )
2836 break;
2839 return false;
2842 void SfxWorkWindow::DataChanged_Impl( const DataChangedEvent& )
2844 sal_uInt16 n;
2845 sal_uInt16 nCount = aChildWins.size();
2846 for (n=0; n<nCount; n++)
2848 SfxChildWin_Impl*pCW = aChildWins[n];
2849 if ( pCW && pCW->pWin )
2850 pCW->pWin->GetWindow()->UpdateSettings( Application::GetSettings() );
2853 ArrangeChildren_Impl();
2856 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */