1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <config_feature_desktop.h>
22 #include <comphelper/lok.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include <osl/diagnose.h>
26 #include <sfx2/docfile.hxx>
27 #include <sfx2/objface.hxx>
28 #include <sfx2/objsh.hxx>
29 #include <sfx2/app.hxx>
30 #include <workwin.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include <sfx2/module.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/dockwin.hxx>
35 #include <sfx2/viewsh.hxx>
36 #include <splitwin.hxx>
37 #include <childwinimpl.hxx>
38 #include <sfx2/sfxsids.hrc>
39 #include <sfx2/toolbarids.hxx>
40 #include <vcl/taskpanelist.hxx>
41 #include <vcl/svapp.hxx>
42 #include <svl/eitem.hxx>
43 #include <tools/svborder.hxx>
44 #include <tools/debug.hxx>
45 #include <unotools/moduleoptions.hxx>
46 #include <com/sun/star/ui/XUIElement.hpp>
47 #include <com/sun/star/frame/LayoutManagerEvents.hpp>
48 #include <com/sun/star/frame/ModuleManager.hpp>
49 #include <com/sun/star/frame/XLayoutManager.hpp>
50 #include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
51 #include <com/sun/star/beans/XPropertySet.hpp>
52 #include <com/sun/star/lang/DisposedException.hpp>
53 #include <type_traits>
54 #include <unordered_map>
55 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::uno
;
70 const ResIdToResName pToolBarResToName
[] =
72 { ToolbarId::FullScreenToolbox
, "fullscreenbar" },
73 { ToolbarId::EnvToolbox
, "standardbar", },
74 { ToolbarId::SvxTbx_Form_Navigation
, "formsnavigationbar" },
75 { ToolbarId::SvxTbx_Form_Filter
, "formsfilterbar" },
76 { ToolbarId::SvxTbx_Text_Control_Attributes
, "formtextobjectbar" },
77 { ToolbarId::SvxTbx_Controls
, "formcontrols" },
78 { ToolbarId::SvxTbx_FormDesign
, "formdesign" },
79 { ToolbarId::Math_Toolbox
, "toolbar" }, //math
80 { ToolbarId::Text_Toolbox_Sc
, "textobjectbar" }, //calc
81 { ToolbarId::Draw_Objectbar
, "drawobjectbar" },
82 { ToolbarId::Graphic_Objectbar
, "graphicobjectbar" },
83 { ToolbarId::Objectbar_Format
, "formatobjectbar" },
84 { ToolbarId::Objectbar_Preview
, "previewbar" },
85 { ToolbarId::Objectbar_Tools
, "toolbar" }, //calc
86 { ToolbarId::Bezier_Toolbox_Sd
, "bezierobjectbar" }, //draw/impress
87 { ToolbarId::Gluepoints_Toolbox
, "gluepointsobjectbar" },
88 { ToolbarId::Draw_Graf_Toolbox
, "graphicobjectbar" },
89 { ToolbarId::Draw_Obj_Toolbox
, "drawingobjectbar" }, //impress
90 { ToolbarId::Draw_Text_Toolbox_Sd
, "textobjectbar" }, //impress
91 { ToolbarId::Draw_Toolbox_Sd
, "toolbar" }, //impress
92 { ToolbarId::Draw_Options_Toolbox
, "optionsbar" },
93 { ToolbarId::Draw_CommonTask_Toolbox
, "commontaskbar" },
94 { ToolbarId::Graphic_Obj_Toolbox
, "drawingobjectbar" }, //draw
95 { ToolbarId::Outline_Toolbox
, "outlinetoolbar" }, //impress
96 { ToolbarId::Slide_Toolbox
, "slideviewtoolbar" },
97 { ToolbarId::Slide_Obj_Toolbox
, "slideviewobjectbar" },
98 { ToolbarId::Bezier_Toolbox_Sw
, "bezierobjectbar" },
99 { ToolbarId::Draw_Toolbox_Sw
, "drawingobjectbar" },
100 { ToolbarId::Draw_Text_Toolbox_Sw
, "drawtextobjectbar" },
101 { ToolbarId::Frame_Toolbox
, "frameobjectbar" },
102 { ToolbarId::Grafik_Toolbox
, "graphicobjectbar" },
103 { ToolbarId::Num_Toolbox
, "numobjectbar" },
104 { ToolbarId::Ole_Toolbox
, "oleobjectbar" },
105 { ToolbarId::Table_Toolbox
, "tableobjectbar" },
106 { ToolbarId::Text_Toolbox_Sw
, "textobjectbar" },
107 { ToolbarId::PView_Toolbox
, "previewobjectbar" }, //writer
108 { ToolbarId::Webtools_Toolbox
, "toolbar" }, //web
109 { ToolbarId::Webtext_Toolbox
, "textobjectbar" },
110 { ToolbarId::Tools_Toolbox
, "toolbar" }, //writer
111 { ToolbarId::Webframe_Toolbox
, "frameobjectbar" }, //web
112 { ToolbarId::Webgraphic_Toolbox
, "graphicobjectbar" },
113 { ToolbarId::Webole_Toolbox
, "oleobjectbar" },
114 { ToolbarId::Basicide_Objectbar
, "macrobar" },
115 { ToolbarId::Svx_Fontwork_Bar
, "fontworkobjectbar" }, //global
116 { ToolbarId::Svx_Extrusion_Bar
, "extrusionobjectbar" },
117 { ToolbarId::FormLayer_Toolbox
, "formsobjectbar" },
118 { ToolbarId::Module_Toolbox
, "viewerbar" }, //writer (plugin)
119 { ToolbarId::Objectbar_App
, "viewerbar" }, //calc (plugin)
120 { ToolbarId::Draw_Viewer_Toolbox
, "viewerbar" }, //impress(plugin)
121 { ToolbarId::Draw_Media_Toolbox
, "mediaobjectbar" }, //draw/impress
122 { ToolbarId::Media_Objectbar
, "mediaobjectbar" }, //calc
123 { ToolbarId::Media_Toolbox
, "mediaobjectbar" }, //writer
124 { ToolbarId::None
, "" }
127 // Sort the Children according their alignment
128 // The order corresponds to the enum SfxChildAlignment (->CHILDWIN.HXX).
130 constexpr OUStringLiteral g_aLayoutManagerPropName
= u
"LayoutManager";
132 // Help to make changes to the alignment compatible!
133 LayoutManagerListener::LayoutManagerListener(
134 SfxWorkWindow
* pWrkWin
) :
135 m_bHasFrame( false ),
140 LayoutManagerListener::~LayoutManagerListener()
144 void LayoutManagerListener::setFrame( const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
146 SolarMutexGuard aGuard
;
147 if ( !m_pWrkWin
|| m_bHasFrame
)
156 css::uno::Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
157 css::uno::Reference
< css::frame::XLayoutManagerEventBroadcaster
> xLayoutManager
;
158 if ( !xPropSet
.is() )
163 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
164 aValue
>>= xLayoutManager
;
166 if ( xLayoutManager
.is() )
167 xLayoutManager
->addLayoutManagerEventListener(
168 css::uno::Reference
< css::frame::XLayoutManagerListener
>(
169 static_cast< OWeakObject
* >( this ), css::uno::UNO_QUERY
));
171 xPropSet
.set( xLayoutManager
, UNO_QUERY
);
174 aValue
= xPropSet
->getPropertyValue( "LockCount" );
175 aValue
>>= m_pWrkWin
->m_nLock
;
178 catch ( css::lang::DisposedException
& )
181 catch ( const css::uno::RuntimeException
& )
185 catch ( css::uno::Exception
& )
193 void SAL_CALL
LayoutManagerListener::addEventListener(
194 const css::uno::Reference
< css::lang::XEventListener
>& )
196 // do nothing, only internal class
199 void SAL_CALL
LayoutManagerListener::removeEventListener(
200 const css::uno::Reference
< css::lang::XEventListener
>& )
202 // do nothing, only internal class
205 void SAL_CALL
LayoutManagerListener::dispose()
207 SolarMutexGuard aGuard
;
212 css::uno::Reference
< css::frame::XFrame
> xFrame( m_xFrame
.get(), css::uno::UNO_QUERY
);
219 css::uno::Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, css::uno::UNO_QUERY
);
220 css::uno::Reference
< css::frame::XLayoutManagerEventBroadcaster
> xLayoutManager
;
221 if ( !xPropSet
.is() )
226 css::uno::Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
227 aValue
>>= xLayoutManager
;
229 // remove as listener from layout manager
230 if ( xLayoutManager
.is() )
231 xLayoutManager
->removeLayoutManagerEventListener(
232 css::uno::Reference
< css::frame::XLayoutManagerListener
>(
233 static_cast< OWeakObject
* >( this ), css::uno::UNO_QUERY
));
235 catch ( css::lang::DisposedException
& )
238 catch ( const css::uno::RuntimeException
& )
242 catch ( css::uno::Exception
& )
250 void SAL_CALL
LayoutManagerListener::disposing(
251 const css::lang::EventObject
& )
253 SolarMutexGuard aGuard
;
260 // XLayoutManagerEventListener
262 void SAL_CALL
LayoutManagerListener::layoutEvent(
263 const css::lang::EventObject
&,
264 ::sal_Int16 eLayoutEvent
,
265 const css::uno::Any
& )
267 SolarMutexGuard aGuard
;
271 if ( eLayoutEvent
== css::frame::LayoutManagerEvents::VISIBLE
)
273 m_pWrkWin
->MakeVisible_Impl( true );
274 m_pWrkWin
->ShowChildren_Impl();
275 m_pWrkWin
->ArrangeChildren_Impl();
277 else if ( eLayoutEvent
== css::frame::LayoutManagerEvents::INVISIBLE
)
279 m_pWrkWin
->MakeVisible_Impl( false );
280 m_pWrkWin
->HideChildren_Impl();
281 m_pWrkWin
->ArrangeChildren_Impl();
283 else if ( eLayoutEvent
== css::frame::LayoutManagerEvents::LOCK
)
285 m_pWrkWin
->Lock_Impl( true );
287 else if ( eLayoutEvent
== css::frame::LayoutManagerEvents::UNLOCK
)
289 m_pWrkWin
->Lock_Impl( false );
297 size_t operator()(ToolbarId t
) const
299 typedef std::underlying_type
<ToolbarId
>::type underlying_type
;
300 return std::hash
<underlying_type
>()(static_cast<underlying_type
>(t
));
304 class FilledToolBarResIdToResourceURLMap
307 typedef std::unordered_map
<ToolbarId
, OUString
, ToolbarIdHash
> ToolBarResIdToResourceURLMap
;
308 ToolBarResIdToResourceURLMap m_aResIdToResourceURLMap
;
310 FilledToolBarResIdToResourceURLMap()
312 sal_Int32
nIndex( 0 );
313 while (pToolBarResToName
[nIndex
].eId
!= ToolbarId::None
)
315 OUString
aResourceURL( OUString::createFromAscii( pToolBarResToName
[nIndex
].pName
));
316 m_aResIdToResourceURLMap
.emplace(pToolBarResToName
[nIndex
].eId
, aResourceURL
);
321 OUString
findURL(ToolbarId eId
) const
323 ToolBarResIdToResourceURLMap::const_iterator aIter
= m_aResIdToResourceURLMap
.find(eId
);
324 if ( aIter
!= m_aResIdToResourceURLMap
.end() )
325 return aIter
->second
;
330 class theFilledToolBarResIdToResourceURLMap
331 : public rtl::Static
<FilledToolBarResIdToResourceURLMap
,
332 theFilledToolBarResIdToResourceURLMap
>
337 static OUString
GetResourceURLFromToolbarId(ToolbarId eId
)
339 return theFilledToolBarResIdToResourceURLMap::get().findURL(eId
);
342 static sal_uInt16
TbxMatch( sal_uInt16 nPos
)
346 case SFX_OBJECTBAR_APPLICATION
:
348 case SFX_OBJECTBAR_OPTIONS
:
350 case SFX_OBJECTBAR_MACRO
:
352 case SFX_OBJECTBAR_OBJECT
:
354 case SFX_OBJECTBAR_TOOLS
:
356 case SFX_OBJECTBAR_FULLSCREEN
:
357 case SFX_OBJECTBAR_COMMONTASK
:
358 case SFX_OBJECTBAR_RECORDING
:
365 static sal_uInt16
ChildAlignValue(SfxChildAlignment eAlign
)
371 case SfxChildAlignment::HIGHESTTOP
:
374 case SfxChildAlignment::LOWESTBOTTOM
:
377 case SfxChildAlignment::FIRSTLEFT
:
380 case SfxChildAlignment::LASTRIGHT
:
383 case SfxChildAlignment::LEFT
:
386 case SfxChildAlignment::RIGHT
:
389 case SfxChildAlignment::FIRSTRIGHT
:
392 case SfxChildAlignment::LASTLEFT
:
395 case SfxChildAlignment::TOP
:
398 case SfxChildAlignment::BOTTOM
:
401 case SfxChildAlignment::TOOLBOXTOP
:
404 case SfxChildAlignment::TOOLBOXBOTTOM
:
407 case SfxChildAlignment::LOWESTTOP
:
410 case SfxChildAlignment::HIGHESTBOTTOM
:
413 case SfxChildAlignment::TOOLBOXLEFT
:
416 case SfxChildAlignment::TOOLBOXRIGHT
:
419 case SfxChildAlignment::NOALIGNMENT
:
420 break; // -Wall not handled...
426 void SfxWorkWindow::Sort_Impl()
429 for (size_t i
= 0; i
< aChildren
.size(); ++i
)
431 SfxChild_Impl
*pCli
= aChildren
[i
].get();
434 decltype(aSortedList
)::size_type k
;
435 for (k
=0; k
<aSortedList
.size(); k
++)
436 if (ChildAlignValue( aChildren
[aSortedList
[k
]]->eAlign
) >
437 ChildAlignValue(pCli
->eAlign
))
439 aSortedList
.insert( aSortedList
.begin() + k
, i
);
446 constexpr OUStringLiteral
g_aStatusBarResName( u
"private:resource/statusbar/statusbar" );
447 constexpr OUStringLiteral
g_aTbxTypeName( u
"private:resource/toolbar/" );
448 constexpr OUStringLiteral
g_aProgressBarResName( u
"private:resource/progressbar/progressbar" );
450 // constructor for workwin of a Frame
452 SfxWorkWindow::SfxWorkWindow( vcl::Window
*pWin
, SfxFrame
*pFrm
, SfxFrame
* pMaster
) :
453 pBindings(&pFrm
->GetCurrentViewFrame()->GetBindings()),
455 pActiveChild( nullptr ),
456 nUpdateMode(SfxVisibilityFlags::Standard
),
458 nOrigMode( SfxVisibilityFlags::Invisible
),
460 bDockingAllowed(true),
461 bInternalDockingAllowed(true),
462 bAllChildrenVisible(true),
463 #if !defined(ANDROID) || HAVE_FEATURE_ANDROID_LOK
464 bIsFullScreen( false ),
465 #else // Fennec-based Android Viewer
466 bIsFullScreen( true ),
468 #if HAVE_FEATURE_DESKTOP
469 bShowStatusBar( true ),
471 bShowStatusBar( sal_False
),
474 pMasterFrame( pMaster
),
477 DBG_ASSERT (pBindings
, "No Bindings!");
479 pBindings
->SetWorkWindow_Impl( std::unique_ptr
<SfxWorkWindow
>(this) );
481 // For the ObjectBars an integral place in the Childlist is reserved,
482 // so that they always come in a defined order.
483 for (int i
=0; i
<SFX_OBJECTBAR_MAX
; ++i
)
484 aChildren
.push_back( nullptr );
486 // create and initialize layout manager listener
487 Reference
< css::frame::XFrame
> xFrame
= GetFrameInterface();
488 LayoutManagerListener
* pLayoutManagerListener
= new LayoutManagerListener( this );
489 m_xLayoutManagerListener
.set( static_cast< cppu::OWeakObject
* >( pLayoutManagerListener
),
490 css::uno::UNO_QUERY
);
491 pLayoutManagerListener
->setFrame( xFrame
);
493 SfxShell
* pConfigShell
= pFrm
->GetCurrentViewFrame();
494 if ( pConfigShell
&& pConfigShell
->GetObjectShell() )
496 bShowStatusBar
= ( !pConfigShell
->GetObjectShell()->IsInPlaceActive() );
497 bDockingAllowed
= true;
498 bInternalDockingAllowed
= true;
501 // The required split windows (one for each side) can be created
502 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
504 // The SplitWindows excludes direct ChildWindows of the WorkWindows
505 // and receives the docked window.
507 SfxChildAlignment eAlign
=
508 ( n
== SFX_SPLITWINDOWS_LEFT
? SfxChildAlignment::LEFT
:
509 n
== SFX_SPLITWINDOWS_RIGHT
? SfxChildAlignment::RIGHT
:
510 n
== SFX_SPLITWINDOWS_TOP
? SfxChildAlignment::TOP
:
511 SfxChildAlignment::BOTTOM
);
512 VclPtr
<SfxSplitWindow
> pSplitWin
= VclPtr
<SfxSplitWindow
>::Create(pWorkWin
, eAlign
, this, true );
513 pSplit
[n
] = pSplitWin
;
516 nOrigMode
= SfxVisibilityFlags::Standard
;
517 nUpdateMode
= SfxVisibilityFlags::Standard
;
523 SfxWorkWindow::~SfxWorkWindow()
526 // Delete SplitWindows
527 for (VclPtr
<SfxSplitWindow
> & p
: pSplit
)
529 if (p
->GetWindowCount())
530 ReleaseChild_Impl(*p
);
534 // Delete help structure for Child-Windows
535 DBG_ASSERT( aChildren
.empty(), "dangling children" );
537 if ( m_xLayoutManagerListener
.is() )
538 m_xLayoutManagerListener
->dispose();
541 void SfxWorkWindow::Lock_Impl( bool bLock
)
549 OSL_FAIL("Lock count underflow!");
550 assert(m_nLock
>= 0);
555 ArrangeChildren_Impl();
559 // Helper method to release the child lists. Should the destructor not be
560 // called after this, instead work continues, then space for the object bars
561 // and split windows has to be reserved in the same way as in the constructor
564 void SfxWorkWindow::DeleteControllers_Impl()
567 // Lock SplitWindows (which means suppressing the Resize-Reaction of the
569 for (size_t n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
571 VclPtr
<SfxSplitWindow
> const &p
= pSplit
[n
];
572 if (p
->GetWindowCount())
576 // Delete Child-Windows
577 while(!aChildWins
.empty())
579 std::unique_ptr
<SfxChildWin_Impl
> pCW
= std::move(*aChildWins
.begin());
580 aChildWins
.erase(aChildWins
.begin());
581 SfxChildWindow
*pChild
= pCW
->pWin
;
584 if (comphelper::LibreOfficeKit::isActive())
586 vcl::Window
* pWindow
= pChild
->GetWindow();
589 pWindow
->ReleaseLOKNotifier();
594 // If the child window is a direct child window and not in a
595 // SplitWindow, cancel it at the workwindow.
596 // After TH a cancellation on the SplitWindow is not necessary
597 // since this window is also destroyed (see below).
600 if (pChild
->GetController())
601 ReleaseChild_Impl(*pChild
->GetController());
603 ReleaseChild_Impl(*pChild
->GetWindow());
607 pWorkWin
->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChild
->GetWindow() );
611 // ATTENTION: The array itself is cleared after this loop!!
612 // Therefore we have to set every array entry to zero as it could be
613 // accessed by calling pChild->Destroy().
614 // Window::NotifyAllChildren() calls SfxWorkWindow::DataChanged_Impl for
615 // 8-bit displays (WM_QUERYPALETTECHANGED message due to focus change)!!
618 Reference
< css::frame::XFrame
> xFrame
= GetFrameInterface();
619 Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
620 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
625 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
626 aValue
>>= xLayoutManager
;
633 if ( xLayoutManager
.is() )
635 xLayoutManager
->reset();
638 ResetStatusBar_Impl();
640 // Delete ObjectBars (this is done last, so that aChildren does not
641 // receive dead Pointers)
642 for (SfxObjectBar_Impl
& i
: aObjBarList
)
644 // Not every position must be occupied
645 ToolbarId eId
= i
.eId
;
646 if (eId
!= ToolbarId::None
)
647 i
.eId
= ToolbarId::None
;
651 // ObjectBars are all released at once, since they occupy a
652 // fixed contiguous area in the array pChild
660 // for placing the child window.
662 void SfxWorkWindow::ArrangeChildren_Impl( bool bForce
)
664 if ( pFrame
->IsClosing_Impl() || ( m_nLock
&& !bForce
))
667 SfxInPlaceClient
*pClient
= nullptr;
668 SfxViewFrame
*pF
= pFrame
->GetCurrentViewFrame();
669 if ( pF
&& pF
->GetViewShell() )
670 pClient
= pF
->GetViewShell()->GetIPClient();
675 aClientArea
= GetTopRect_Impl();
676 if ( aClientArea
.IsEmpty() )
680 if ( nChildren
&& IsVisible_Impl() )
681 aBorder
= Arrange_Impl();
682 // If the current application document contains an IPClient, then the
683 // object through SetTopToolFramePixel has to be assigned the available
684 // space. The object will then point to its UITools and sets the app border
685 // (-> SfxInPlaceEnv_Impl:: ArrangeChildren_Impl ()). Otherwise the
686 // app border is set here directly to possibly overwrite the Border that
687 // was set by an object from another document. The object does not set
688 // the SetAppBorder when it removes its UI tools so that no-dithering
690 // (->SfxInPlaceEnv_Impl::ArrangeChildren_Impl())
692 pMasterFrame
->SetToolSpaceBorderPixel_Impl( aBorder
);
694 ArrangeAutoHideWindows( nullptr );
697 void SfxWorkWindow::FlushPendingChildSizes()
699 // tdf#116865, if any windows are being resized, i.e. their
700 // resize timer is active, then calling GetSizePixel on
701 // them forces the timer to fire and sets the final
702 // size to which they are getting resized towards.
703 for (size_t i
= 0; i
< aChildren
.size(); ++i
)
705 SfxChild_Impl
*pCli
= aChildren
[i
].get();
706 if (!pCli
|| !pCli
->pWin
)
708 (void)pCli
->pWin
->GetSizePixel();
712 SvBorder
SfxWorkWindow::Arrange_Impl()
716 This method organizes all visible child windows so that the docked window
717 sorted in order from the outside to the inside are placed after one
718 another. If a visible window does not fit anymore into the free
719 ClientArea, it is set to "not visible".
722 //tdf#116865 trigger pending sizing timers now so we arrange
723 //with the final size of the client area.
725 //Otherwise calling GetSizePixel in the following loop will trigger the
726 //timers, causing reentry into Arrange_Impl again where the inner
727 //Arrange_Impl arranges with the final size, and then returns to this outer
728 //Arrange_Impl which would rearrange with the old client area size
729 FlushPendingChildSizes();
730 aClientArea
= GetTopRect_Impl();
731 aUpperClientArea
= aClientArea
;
742 tools::Rectangle
aTmp( aClientArea
);
744 for (sal_uInt16 n
: aSortedList
)
746 SfxChild_Impl
* pCli
= aChildren
[n
].get();
750 // First, we assume that there is room for the window.
751 pCli
->nVisible
|= SfxChildVisibility::FITS_IN
;
753 // Skip invisible windows
754 if (pCli
->nVisible
!= SfxChildVisibility::VISIBLE
)
760 aSize
= pCli
->pWin
->GetSizePixel();
762 SvBorder aTemp
= aBorder
;
763 bool bAllowHiding
= true;
764 switch ( pCli
->eAlign
)
766 case SfxChildAlignment::HIGHESTTOP
:
767 case SfxChildAlignment::TOP
:
768 case SfxChildAlignment::TOOLBOXTOP
:
769 case SfxChildAlignment::LOWESTTOP
:
770 aSize
.setWidth( aTmp
.GetWidth() );
771 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
772 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
773 bAllowHiding
= false;
774 aBorder
.Top() += aSize
.Height();
775 aPos
= aTmp
.TopLeft();
776 aTmp
.AdjustTop(aSize
.Height() );
777 if ( pCli
->eAlign
== SfxChildAlignment::HIGHESTTOP
)
778 aUpperClientArea
.AdjustTop(aSize
.Height() );
781 case SfxChildAlignment::LOWESTBOTTOM
:
782 case SfxChildAlignment::BOTTOM
:
783 case SfxChildAlignment::TOOLBOXBOTTOM
:
784 case SfxChildAlignment::HIGHESTBOTTOM
:
785 aSize
.setWidth( aTmp
.GetWidth() );
786 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
787 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
788 aBorder
.Bottom() += aSize
.Height();
789 aPos
= aTmp
.BottomLeft();
790 aPos
.AdjustY( -(aSize
.Height()-1) );
791 aTmp
.AdjustBottom( -(aSize
.Height()) );
792 if ( pCli
->eAlign
== SfxChildAlignment::LOWESTBOTTOM
)
793 aUpperClientArea
.AdjustBottom( -(aSize
.Height()) );
796 case SfxChildAlignment::FIRSTLEFT
:
797 case SfxChildAlignment::LEFT
:
798 case SfxChildAlignment::LASTLEFT
:
799 case SfxChildAlignment::TOOLBOXLEFT
:
800 aSize
.setHeight( aTmp
.GetHeight() );
801 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
802 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
803 bAllowHiding
= false;
804 aBorder
.Left() += aSize
.Width();
805 aPos
= aTmp
.TopLeft();
806 aTmp
.AdjustLeft(aSize
.Width() );
807 if ( pCli
->eAlign
!= SfxChildAlignment::TOOLBOXLEFT
)
808 aUpperClientArea
.AdjustLeft(aSize
.Width() );
811 case SfxChildAlignment::FIRSTRIGHT
:
812 case SfxChildAlignment::RIGHT
:
813 case SfxChildAlignment::LASTRIGHT
:
814 case SfxChildAlignment::TOOLBOXRIGHT
:
815 aSize
.setHeight( aTmp
.GetHeight() );
816 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
817 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
818 aBorder
.Right() += aSize
.Width();
819 aPos
= aTmp
.TopRight();
820 aPos
.AdjustX( -(aSize
.Width()-1) );
821 aTmp
.AdjustRight( -(aSize
.Width()) );
822 if ( pCli
->eAlign
!= SfxChildAlignment::TOOLBOXRIGHT
)
823 aUpperClientArea
.AdjustRight( -(aSize
.Width()) );
827 pCli
->aSize
= pCli
->pWin
->GetSizePixel();
828 pCli
->bResize
= false;
832 pCli
->pWin
->SetPosSizePixel( aPos
, aSize
);
833 pCli
->bResize
= false;
835 if( bAllowHiding
&& !RequestTopToolSpacePixel_Impl( aBorder
) )
837 pCli
->nVisible
^= SfxChildVisibility::FITS_IN
;
842 if ( aClientArea
.GetWidth() >= aBorder
.Left() + aBorder
.Right() )
844 aClientArea
.AdjustLeft(aBorder
.Left() );
845 aClientArea
.AdjustRight( -(aBorder
.Right()) );
849 aBorder
.Left() = aClientArea
.Left();
850 aBorder
.Right() = aClientArea
.Right();
851 aClientArea
.SetRight( aTmp
.Left() );
852 aClientArea
.SetLeft( aTmp
.Left() );
855 if ( aClientArea
.GetHeight() >= aBorder
.Top() + aBorder
.Bottom() )
857 aClientArea
.AdjustTop(aBorder
.Top() );
858 aClientArea
.AdjustBottom( -(aBorder
.Bottom()) );
862 aBorder
.Top() = aClientArea
.Top();
863 aBorder
.Bottom() = aClientArea
.Bottom();
864 aClientArea
.SetTop(aTmp
.Top());
865 aClientArea
.SetBottom(aTmp
.Top());
868 return IsDockingAllowed() ? aBorder
: SvBorder();
871 bool SfxWorkWindow::PrepareClose_Impl()
873 for (const std::unique_ptr
<SfxChildWin_Impl
> &pCW
: aChildWins
)
875 SfxChildWindow
*pChild
= pCW
->pWin
;
876 if ( pChild
&& !pChild
->QueryClose() )
883 SfxChild_Impl
* SfxWorkWindow::RegisterChild_Impl( vcl::Window
& rWindow
,
884 SfxChildAlignment eAlign
)
886 DBG_ASSERT( aChildren
.size() < 255, "too many children" );
887 DBG_ASSERT( SfxChildAlignValid(eAlign
), "invalid align" );
888 DBG_ASSERT( !FindChild_Impl(&rWindow
), "child registered more than once" );
891 if ( rWindow
.GetParent() != pWorkWin
)
892 rWindow
.SetParent( pWorkWin
);
894 auto pChild
= std::make_unique
<SfxChild_Impl
>(rWindow
, rWindow
.GetSizePixel(),
895 eAlign
, rWindow
.IsVisible());
897 aChildren
.push_back(std::move(pChild
));
900 return aChildren
.back().get();
903 SfxChild_Impl
* SfxWorkWindow::RegisterChild_Impl(std::shared_ptr
<SfxDialogController
>& rController
,
904 SfxChildAlignment eAlign
)
906 DBG_ASSERT( aChildren
.size() < 255, "too many children" );
907 DBG_ASSERT( SfxChildAlignValid(eAlign
), "invalid align" );
909 auto pChild
= std::make_unique
<SfxChild_Impl
>(rController
, eAlign
);
911 aChildren
.push_back(std::move(pChild
));
914 return aChildren
.back().get();
917 void SfxWorkWindow::ReleaseChild_Impl( vcl::Window
& rWindow
)
920 SfxChild_Impl
*pChild
= nullptr;
921 decltype(aChildren
)::size_type nPos
;
922 for ( nPos
= 0; nPos
< aChildren
.size(); ++nPos
)
924 pChild
= aChildren
[nPos
].get();
925 if ( pChild
&& pChild
->pWin
== &rWindow
)
929 aChildren
.erase(aChildren
.begin() + nPos
);
933 OSL_FAIL( "releasing unregistered child" );
936 void SfxWorkWindow::ReleaseChild_Impl(SfxDialogController
& rController
)
939 SfxChild_Impl
*pChild
= nullptr;
940 decltype(aChildren
)::size_type nPos
;
941 for ( nPos
= 0; nPos
< aChildren
.size(); ++nPos
)
943 pChild
= aChildren
[nPos
].get();
944 if (pChild
&& pChild
->xController
.get() == &rController
)
948 aChildren
.erase(aChildren
.begin() + nPos
);
952 OSL_FAIL( "releasing unregistered child" );
955 SfxChild_Impl
* SfxWorkWindow::FindChild_Impl( const vcl::Window
* rWindow
) const
958 sal_uInt16 nCount
= aChildren
.size();
959 for ( sal_uInt16 nPos
= 0; nPos
< nCount
; ++nPos
)
961 SfxChild_Impl
*pChild
= aChildren
[nPos
].get();
962 if ( pChild
&& pChild
->pWin
== rWindow
)
969 void SfxWorkWindow::ShowChildren_Impl()
971 bool bInvisible
= ( !IsVisible_Impl() || ( !pWorkWin
->IsReallyVisible() && !pWorkWin
->IsReallyShown() ));
973 for (std::unique_ptr
<SfxChild_Impl
>& pCli
: aChildren
)
977 SfxChildWin_Impl
* pCW
= nullptr;
978 if (pCli
->pWin
|| pCli
->xController
)
980 // We have to find the SfxChildWin_Impl to retrieve the
981 // SFX_CHILDWIN flags that can influence visibility.
982 for (const std::unique_ptr
<SfxChildWin_Impl
>& pCWin
: aChildWins
)
984 SfxChild_Impl
* pChild
= pCWin
->pCli
;
985 if ( pChild
== pCli
.get() )
992 bool bVisible( !bInvisible
);
995 // Check flag SFX_CHILDWIN_NEVERHIDE that forces us to show
996 // the child window even in situations where no child window is
998 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
999 bVisible
= !bInvisible
|| ( nFlags
& SfxChildWindowFlags::NEVERHIDE
);
1002 if ( SfxChildVisibility::VISIBLE
== (pCli
->nVisible
& SfxChildVisibility::VISIBLE
) && bVisible
)
1004 ShowFlags nFlags
= pCli
->bSetFocus
? ShowFlags::NONE
: ShowFlags::NoFocusChange
| ShowFlags::NoActivate
;
1005 if (pCli
->xController
)
1007 if (!pCli
->xController
->getDialog()->get_visible())
1009 auto xController
= pCli
->xController
;
1010 weld::DialogController::runAsync(xController
,
1011 [=](sal_Int32
/*nResult*/){ xController
->Close(); });
1015 pCli
->pWin
->Show(true, nFlags
);
1016 pCli
->bSetFocus
= false;
1020 if (pCli
->xController
)
1022 if (pCli
->xController
->getDialog()->get_visible())
1023 pCli
->xController
->response(RET_CLOSE
);
1033 void SfxWorkWindow::HideChildren_Impl()
1035 for ( sal_uInt16 nPos
= aChildren
.size(); nPos
> 0; --nPos
)
1037 SfxChild_Impl
*pChild
= aChildren
[nPos
-1].get();
1040 if (pChild
->xController
)
1041 pChild
->xController
->response(RET_CLOSE
);
1042 else if (pChild
->pWin
)
1043 pChild
->pWin
->Hide();
1047 void SfxWorkWindow::ResetObjectBars_Impl()
1049 for ( auto & n
: aObjBarList
)
1052 for ( auto & n
: aChildWins
)
1056 void SfxWorkWindow::SetObjectBar_Impl(sal_uInt16 nPos
, SfxVisibilityFlags nFlags
, ToolbarId eId
)
1058 DBG_ASSERT( nPos
< SFX_OBJECTBAR_MAX
, "object bar position overflow" );
1060 SfxObjectBar_Impl aObjBar
;
1062 aObjBar
.nMode
= nFlags
;
1064 for (SfxObjectBar_Impl
& rBar
: aObjBarList
)
1066 if ( rBar
.eId
== aObjBar
.eId
)
1073 aObjBarList
.push_back( aObjBar
);
1076 bool SfxWorkWindow::IsVisible_Impl( SfxVisibilityFlags nMode
) const
1078 switch( nUpdateMode
)
1080 case SfxVisibilityFlags::Standard
:
1082 case SfxVisibilityFlags::Invisible
:
1084 case SfxVisibilityFlags::Client
:
1085 case SfxVisibilityFlags::Server
:
1086 return bool(nMode
& nUpdateMode
);
1088 return (nMode
& nOrigMode
) ||
1089 nOrigMode
== SfxVisibilityFlags::Standard
;
1093 void SfxWorkWindow::UpdateObjectBars_Impl()
1095 if ( pFrame
->IsClosing_Impl() )
1098 UpdateObjectBars_Impl2();
1101 ArrangeChildren_Impl( false );
1103 ShowChildren_Impl();
1106 ShowChildren_Impl();
1109 Reference
< css::task::XStatusIndicator
> SfxWorkWindow::GetStatusIndicator()
1111 Reference
< css::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
1112 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1113 Reference
< css::task::XStatusIndicator
> xStatusIndicator
;
1115 if ( xPropSet
.is() )
1117 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
1118 aValue
>>= xLayoutManager
;
1119 if ( xLayoutManager
.is() )
1121 xLayoutManager
->createElement( g_aProgressBarResName
);
1122 xLayoutManager
->showElement( g_aProgressBarResName
);
1124 Reference
< css::ui::XUIElement
> xProgressBar
=
1125 xLayoutManager
->getElement( g_aProgressBarResName
);
1126 if ( xProgressBar
.is() )
1128 xStatusIndicator
.set( xProgressBar
->getRealInterface(), UNO_QUERY
);
1133 return xStatusIndicator
;
1137 bool SfxWorkWindow::IsPluginMode( SfxObjectShell
const * pObjShell
)
1139 if ( pObjShell
&& pObjShell
->GetMedium() )
1141 const SfxBoolItem
* pViewOnlyItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pObjShell
->GetMedium()->GetItemSet(), SID_VIEWONLY
, false);
1142 if ( pViewOnlyItem
&& pViewOnlyItem
->GetValue() )
1150 css::uno::Reference
< css::frame::XFrame
> SfxWorkWindow::GetFrameInterface()
1152 css::uno::Reference
< css::frame::XFrame
> xFrame
;
1154 SfxDispatcher
* pDispatcher( GetBindings().GetDispatcher() );
1157 SfxViewFrame
* pViewFrame
= pDispatcher
->GetFrame();
1159 xFrame
= pViewFrame
->GetFrame().GetFrameInterface();
1166 void SfxWorkWindow::UpdateObjectBars_Impl2()
1168 // Lock SplitWindows (which means suppressing the Resize-Reaction of the
1170 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
1172 VclPtr
<SfxSplitWindow
> const & p
= pSplit
[n
];
1173 if (p
->GetWindowCount())
1177 Reference
< css::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
1178 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1180 if ( xPropSet
.is() )
1182 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
1183 aValue
>>= xLayoutManager
;
1186 if ( !xLayoutManager
.is() )
1189 bool bPluginMode( false );
1190 SfxDispatcher
* pDispatcher( GetBindings().GetDispatcher() );
1194 SfxViewFrame
* pViewFrame
= pDispatcher
->GetFrame();
1196 bPluginMode
= IsPluginMode( pViewFrame
->GetObjectShell() );
1199 // Iterate over all Toolboxes
1200 xLayoutManager
->lock();
1201 for ( auto const & n
: aObjBarList
)
1203 ToolbarId eId
= n
.eId
;
1204 bool bDestroy
= n
.bDestroy
;
1206 // Determine the valid mode for the ToolBox
1207 SfxVisibilityFlags nTbxMode
= n
.nMode
;
1208 bool bFullScreenTbx( nTbxMode
& SfxVisibilityFlags::FullScreen
);
1209 nTbxMode
&= ~SfxVisibilityFlags::FullScreen
;
1210 nTbxMode
&= ~SfxVisibilityFlags::Viewer
;
1212 // Is a ToolBox required in this context ?
1213 bool bModesMatching
= (nUpdateMode
!= SfxVisibilityFlags::Invisible
) && ((nTbxMode
& nUpdateMode
) == nUpdateMode
);
1214 if ( bDestroy
|| sfx2::SfxNotebookBar::IsActive())
1216 OUString aTbxId
= g_aTbxTypeName
+ GetResourceURLFromToolbarId(eId
);
1217 xLayoutManager
->destroyElement( aTbxId
);
1219 else if ( eId
!= ToolbarId::None
&& ( ( bModesMatching
&& !bIsFullScreen
) ||
1220 ( bIsFullScreen
&& bFullScreenTbx
) ) )
1222 OUString aTbxId
= g_aTbxTypeName
+ GetResourceURLFromToolbarId(eId
);
1223 if ( !IsDockingAllowed() && !xLayoutManager
->isElementFloating( aTbxId
))
1224 xLayoutManager
->destroyElement( aTbxId
);
1227 xLayoutManager
->requestElement( aTbxId
);
1229 xLayoutManager
->lockWindow( aTbxId
);
1232 else if ( eId
!= ToolbarId::None
)
1234 // Delete the Toolbox at this Position if possible
1235 OUString aTbxId
= g_aTbxTypeName
+ GetResourceURLFromToolbarId(eId
);
1236 xLayoutManager
->destroyElement( aTbxId
);
1240 UpdateStatusBar_Impl();
1242 // unlocking automatically forces Layout
1243 xLayoutManager
->unlock();
1245 UpdateChildWindows_Impl();
1247 // Unlock the SplitWindows again
1248 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
1250 VclPtr
<SfxSplitWindow
> const & p
= pSplit
[n
];
1251 if (p
->GetWindowCount())
1256 void SfxWorkWindow::UpdateChildWindows_Impl()
1258 // tdf#100870, tdf#101320: don't use range-based for loop when
1259 // container is modified
1260 for ( size_t n
=0; n
<aChildWins
.size(); n
++ )
1262 // any current or in the context available Childwindows
1263 SfxChildWin_Impl
*pCW
= aChildWins
[n
].get();
1264 SfxChildWindow
*pChildWin
= pCW
->pWin
;
1265 bool bCreate
= false;
1266 if ( pCW
->nId
&& (pCW
->aInfo
.nFlags
& SfxChildWindowFlags::ALWAYSAVAILABLE
|| IsVisible_Impl( pCW
->nVisibility
) ) )
1268 // In the context is an appropriate ChildWindow allowed;
1269 // it is also turned on?
1270 if ( pChildWin
== nullptr && pCW
->bCreate
)
1272 // Internal docking is only used for embedding into another
1273 // container. We force the floating state of all floatable
1275 if ( !bInternalDockingAllowed
)
1277 // Special case for all non-floatable child windows. We have
1278 // to prevent the creation here!
1279 bCreate
= !( pCW
->aInfo
.nFlags
& SfxChildWindowFlags::FORCEDOCK
);
1281 else if ( !IsDockingAllowed() || bIsFullScreen
) // || !bInternalDocking )
1283 // In Presentation mode or FullScreen only FloatingWindows
1284 SfxChildAlignment eAlign
;
1285 if ( pCW
->aInfo
.GetExtraData_Impl( &eAlign
) )
1286 bCreate
= ( eAlign
== SfxChildAlignment::NOALIGNMENT
);
1291 if (pCW
->aInfo
.nFlags
& SfxChildWindowFlags::NEVERCLONE
)
1292 pCW
->bCreate
= bCreate
= false; // Don't create and remember that we haven't created.
1294 // Currently, no window here, but it is enabled; windows
1295 // Create window and if possible theContext
1297 CreateChildWin_Impl( pCW
, false );
1299 if ( !bAllChildrenVisible
&& pCW
->pCli
)
1300 pCW
->pCli
->nVisible
&= ~SfxChildVisibility::ACTIVE
;
1302 else if ( pChildWin
)
1304 // Window already exists, it should also be visible?
1305 if ( ( !bIsFullScreen
|| pChildWin
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
) && bAllChildrenVisible
)
1307 // Update Mode is compatible; definitely enable it
1311 // The window is a direct Child
1312 if ((IsDockingAllowed() && bInternalDockingAllowed
)
1313 || pCW
->pCli
->eAlign
== SfxChildAlignment::NOALIGNMENT
)
1314 pCW
->pCli
->nVisible
|= SfxChildVisibility::NOT_HIDDEN
;
1318 if ( pCW
->bCreate
&& IsDockingAllowed() && bInternalDockingAllowed
)
1319 // The window ia within a SplitWindow
1320 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Reappear_Impl();
1323 if ( pCW
->nInterfaceId
!= pChildWin
->GetContextId() )
1324 pChildWin
->CreateContext( pCW
->nInterfaceId
, GetBindings() );
1329 if ( pChildWin
&& !bCreate
)
1331 if ( !pChildWin
->QueryClose() || pChildWin
->IsHideNotDelete() || Application::IsUICaptured() )
1335 if ( pCW
->pCli
->nVisible
& SfxChildVisibility::NOT_HIDDEN
)
1336 pCW
->pCli
->nVisible
^= SfxChildVisibility::NOT_HIDDEN
;
1339 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Disappear_Impl();
1342 RemoveChildWin_Impl( pCW
);
1347 void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl
*pCW
, bool bSetFocus
)
1349 pCW
->aInfo
.bVisible
= true;
1351 SfxChildWindow
*pChildWin
= SfxChildWindow::CreateChildWindow( pCW
->nId
, pWorkWin
, &GetBindings(), pCW
->aInfo
).release();
1356 bSetFocus
= pChildWin
->WantsFocus();
1357 pChildWin
->SetWorkWindow_Impl( this );
1359 // At least the extra string is changed during the evaluation,
1360 // also get it anewed
1361 SfxChildWinInfo aInfo
= pChildWin
->GetInfo();
1362 pCW
->aInfo
.aExtraString
= aInfo
.aExtraString
;
1363 pCW
->aInfo
.bVisible
= aInfo
.bVisible
;
1364 pCW
->aInfo
.nFlags
|= aInfo
.nFlags
;
1366 // The creation was successful
1367 GetBindings().Invalidate(pCW
->nId
);
1369 sal_uInt16 nPos
= pChildWin
->GetPosition();
1370 if (nPos
!= CHILDWIN_NOPOS
)
1372 DBG_ASSERT(nPos
< SFX_OBJECTBAR_MAX
, "Illegal objectbar position!");
1373 if ( aChildren
[TbxMatch(nPos
)] )// &&
1375 // ChildWindow replaces ObjectBar
1376 aChildren
[TbxMatch(nPos
)]->nVisible
^= SfxChildVisibility::NOT_HIDDEN
;
1380 // make childwin keyboard accessible
1381 pWorkWin
->GetSystemWindow()->GetTaskPaneList()->AddWindow( pChildWin
->GetWindow() );
1383 pCW
->pWin
= pChildWin
;
1385 if ( pChildWin
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
|| pChildWin
->GetWindow()->GetParent() == pWorkWin
)
1387 // The window is not docked or docked outside of one split windows
1388 // and must therefore be registered explicitly as a Child
1389 if (pChildWin
->GetController())
1390 pCW
->pCli
= RegisterChild_Impl(pChildWin
->GetController(), pChildWin
->GetAlignment());
1392 pCW
->pCli
= RegisterChild_Impl(*(pChildWin
->GetWindow()), pChildWin
->GetAlignment());
1393 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
;
1394 if ( pChildWin
->GetAlignment() != SfxChildAlignment::NOALIGNMENT
&& bIsFullScreen
)
1395 pCW
->pCli
->nVisible
^= SfxChildVisibility::ACTIVE
;
1396 pCW
->pCli
->bSetFocus
= bSetFocus
;
1400 // A docked window which parent is not a WorkingWindow, must lie
1401 // in a SplitWindow and thus not be explicitly registered.
1402 // This happens already in the initialization of SfxDockingWindows!
1405 if ( pCW
->nInterfaceId
!= pChildWin
->GetContextId() )
1406 pChildWin
->CreateContext( pCW
->nInterfaceId
, GetBindings() );
1408 // Save the information in the INI file
1409 SaveStatus_Impl(pChildWin
, pCW
->aInfo
);
1412 void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl
*pCW
)
1414 sal_uInt16 nId
= pCW
->nSaveId
;
1415 SfxChildWindow
*pChildWin
= pCW
->pWin
;
1417 // Save the information in the INI file
1418 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
1419 pCW
->aInfo
= pChildWin
->GetInfo();
1420 pCW
->aInfo
.nFlags
|= nFlags
;
1421 SaveStatus_Impl(pChildWin
, pCW
->aInfo
);
1427 // Child window is a direct child window and must therefore unregister
1428 // itself from the WorkWindow
1429 pCW
->pCli
= nullptr;
1430 if (pChildWin
->GetController())
1431 ReleaseChild_Impl(*pChildWin
->GetController());
1433 ReleaseChild_Impl(*pChildWin
->GetWindow());
1437 // ChildWindow is within a SplitWindow and unregister itself in
1441 pWorkWin
->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChildWin
->GetWindow() );
1442 pCW
->pWin
= nullptr;
1443 pChildWin
->Destroy();
1445 GetBindings().Invalidate( nId
);
1448 void SfxWorkWindow::ResetStatusBar_Impl()
1450 aStatBar
.eId
= StatusBarId::None
;
1453 void SfxWorkWindow::SetStatusBar_Impl(StatusBarId eId
)
1455 if (eId
!= StatusBarId::None
&& bShowStatusBar
&& IsVisible_Impl())
1459 void SfxWorkWindow::UpdateStatusBar_Impl()
1461 Reference
< css::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
1462 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1464 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
1465 aValue
>>= xLayoutManager
;
1467 // No status bar, if no ID is required or when in FullScreenView or
1469 if (aStatBar
.eId
!= StatusBarId::None
&& IsDockingAllowed() && bInternalDockingAllowed
&& bShowStatusBar
&&
1472 // Id has changed, thus create a suitable Statusbarmanager, this takes
1473 // over the current status bar;
1474 if ( xLayoutManager
.is() )
1475 xLayoutManager
->requestElement( g_aStatusBarResName
);
1479 // Destroy the current StatusBar
1480 // The Manager only creates the Status bar, does not destroy it.
1481 if ( xLayoutManager
.is() )
1482 xLayoutManager
->destroyElement( g_aStatusBarResName
);
1486 void SfxWorkWindow::MakeVisible_Impl( bool bVis
)
1489 nOrigMode
= SfxVisibilityFlags::Standard
;
1491 nOrigMode
= SfxVisibilityFlags::Invisible
;
1493 if ( nOrigMode
!= nUpdateMode
)
1494 nUpdateMode
= nOrigMode
;
1497 bool SfxWorkWindow::IsVisible_Impl() const
1499 return nOrigMode
!= SfxVisibilityFlags::Invisible
;
1503 void SfxWorkWindow::HidePopups_Impl(bool bHide
, sal_uInt16 nId
)
1505 if (comphelper::LibreOfficeKit::isActive() && bHide
)
1508 for (const std::unique_ptr
<SfxChildWin_Impl
>& i
: aChildWins
)
1510 SfxChildWindow
*pCW
= i
->pWin
;
1511 if (pCW
&& pCW
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
&& pCW
->GetType() != nId
)
1513 vcl::Window
*pWin
= pCW
->GetWindow();
1514 SfxChild_Impl
*pChild
= FindChild_Impl(pWin
);
1517 SAL_WARN("sfx.appl", "missing SfxChild_Impl child!");
1522 pChild
->nVisible
&= ~SfxChildVisibility::ACTIVE
;
1525 else if ( !comphelper::LibreOfficeKit::isActive() ||
1526 SfxChildVisibility::ACTIVE
!= (pChild
->nVisible
& SfxChildVisibility::ACTIVE
) )
1528 pChild
->nVisible
|= SfxChildVisibility::ACTIVE
;
1529 if ( SfxChildVisibility::VISIBLE
== (pChild
->nVisible
& SfxChildVisibility::VISIBLE
) )
1530 pCW
->Show( ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
1537 void SfxWorkWindow::ConfigChild_Impl(SfxChildIdentifier eChild
,
1538 SfxDockingConfig eConfig
, sal_uInt16 nId
)
1540 SfxDockingWindow
* pDockWin
=nullptr;
1541 sal_uInt16 nPos
= USHRT_MAX
;
1542 vcl::Window
*pWin
=nullptr;
1543 SfxChildWin_Impl
*pCW
= nullptr;
1545 // configure direct childwindow
1546 for (const std::unique_ptr
<SfxChildWin_Impl
>& i
: aChildWins
)
1549 SfxChildWindow
*pChild
= pCW
->pWin
;
1550 if ( pChild
&& (pChild
->GetType() == nId
))
1552 if (SfxDockingWindow
* pSfxDockingWindow
= dynamic_cast<SfxDockingWindow
*>(pChild
->GetWindow()))
1554 // it's a DockingWindow
1555 pDockWin
= pSfxDockingWindow
;
1559 // FloatingWindow or ModelessDialog
1560 pWin
= pChild
->GetWindow();
1568 if ( eChild
== SfxChildIdentifier::DOCKINGWINDOW
|| pDockWin
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
)
1570 if ( eChild
== SfxChildIdentifier::SPLITWINDOW
&& eConfig
== SfxDockingConfig::TOGGLEFLOATMODE
)
1572 // DockingWindow was dragged out of a SplitWindow
1573 pCW
->pCli
= RegisterChild_Impl(*pDockWin
, pDockWin
->GetAlignment());
1574 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
;
1581 SfxSplitWindow
*pSplitWin
= GetSplitWindow_Impl(pDockWin
->GetAlignment());
1583 // configure DockingWindow inside a SplitWindow
1584 if ( eConfig
== SfxDockingConfig::TOGGLEFLOATMODE
)
1586 // DockingWindow was dragged into a SplitWindow
1587 pCW
->pCli
= nullptr;
1588 ReleaseChild_Impl(*pDockWin
);
1591 pWin
= pSplitWin
->GetSplitWindow();
1592 if ( pSplitWin
->GetWindowCount() == 1 )
1593 static_cast<SplitWindow
*>(pWin
)->Show( true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
1597 DBG_ASSERT( pCW
, "Unknown window!" );
1600 // windows may have been registered and released without an update until now
1603 decltype(aSortedList
)::size_type n
;
1604 for ( n
=0; n
<aSortedList
.size(); ++n
)
1606 SfxChild_Impl
*pChild
= aChildren
[aSortedList
[n
]].get();
1607 if ( pChild
&& pChild
->pWin
== pWin
)
1611 if ( n
< aSortedList
.size() )
1612 // sometimes called while toggling float mode
1613 nPos
= aSortedList
[n
];
1617 case SfxDockingConfig::SETDOCKINGRECTS
:
1619 if (nPos
== USHRT_MAX
|| !pDockWin
)
1622 tools::Rectangle
aOuterRect( GetTopRect_Impl() );
1623 aOuterRect
.SetPos( pWorkWin
->OutputToScreenPixel( aOuterRect
.TopLeft() ));
1624 tools::Rectangle
aInnerRect( aOuterRect
);
1626 // The current affected window is included in the calculation of
1627 // the inner rectangle!
1628 for (sal_uInt16 i
: aSortedList
)
1630 SfxChild_Impl
* pCli
= aChildren
[i
].get();
1632 if ( pCli
&& pCli
->nVisible
== SfxChildVisibility::VISIBLE
&& pCli
->pWin
)
1634 switch ( pCli
->eAlign
)
1636 case SfxChildAlignment::TOP
:
1637 // Object-Toolboxes come always last
1638 aInnerRect
.AdjustTop(pCli
->aSize
.Height() );
1641 case SfxChildAlignment::HIGHESTTOP
:
1642 // Always performed first
1643 aInnerRect
.AdjustTop(pCli
->aSize
.Height() );
1646 case SfxChildAlignment::LOWESTTOP
:
1647 // Is only counted if it is the current window
1649 aInnerRect
.AdjustTop(pCli
->aSize
.Height() );
1652 case SfxChildAlignment::BOTTOM
:
1653 // Object-Toolboxes come always last
1654 aInnerRect
.AdjustBottom( -(pCli
->aSize
.Height()) );
1657 case SfxChildAlignment::LOWESTBOTTOM
:
1658 // Always performed first
1659 aInnerRect
.AdjustBottom( -(pCli
->aSize
.Height()) );
1662 case SfxChildAlignment::HIGHESTBOTTOM
:
1663 // Is only counted if it is the current window
1665 aInnerRect
.AdjustBottom( -(pCli
->aSize
.Height()) );
1668 case SfxChildAlignment::LEFT
:
1669 // Toolboxes come always last
1670 aInnerRect
.AdjustLeft(pCli
->aSize
.Width() );
1673 case SfxChildAlignment::FIRSTLEFT
:
1674 // Always performed first
1675 aInnerRect
.AdjustLeft(pCli
->aSize
.Width() );
1678 case SfxChildAlignment::LASTLEFT
:
1679 // Is only counted if it is the current window
1681 aInnerRect
.AdjustLeft(pCli
->aSize
.Width() );
1684 case SfxChildAlignment::RIGHT
:
1685 // Toolboxes come always last
1686 aInnerRect
.AdjustRight( -(pCli
->aSize
.Width()) );
1689 case SfxChildAlignment::FIRSTRIGHT
:
1690 // Is only counted if it is the current window
1692 aInnerRect
.AdjustRight( -(pCli
->aSize
.Width()) );
1695 case SfxChildAlignment::LASTRIGHT
:
1696 // Always performed first
1697 aInnerRect
.AdjustRight( -(pCli
->aSize
.Width()) );
1706 pDockWin
->SetDockingRects(aOuterRect
, aInnerRect
);
1710 case SfxDockingConfig::ALIGNDOCKINGWINDOW
:
1711 case SfxDockingConfig::TOGGLEFLOATMODE
:
1713 if ( nPos
== USHRT_MAX
&& !pCW
)
1716 SfxChildAlignment eAlign
= SfxChildAlignment::NOALIGNMENT
;
1717 SfxChild_Impl
*pCli
= ( nPos
!= USHRT_MAX
) ? aChildren
[nPos
].get() : nullptr;
1718 if ( pCli
&& pDockWin
)
1720 eAlign
= pDockWin
->GetAlignment();
1721 if ( eChild
== SfxChildIdentifier::DOCKINGWINDOW
|| eAlign
== SfxChildAlignment::NOALIGNMENT
)
1723 // configuration inside the SplitWindow, no change for the SplitWindows' configuration
1724 pCli
->bResize
= true;
1725 pCli
->aSize
= pDockWin
->GetSizePixel();
1731 if( pCli
->eAlign
!= eAlign
)
1734 pCli
->eAlign
= eAlign
;
1737 ArrangeChildren_Impl();
1738 ShowChildren_Impl();
1741 if ( pCW
&& pCW
->pWin
)
1743 // store changed configuration
1744 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
1745 pCW
->aInfo
= pCW
->pWin
->GetInfo();
1746 pCW
->aInfo
.nFlags
|= nFlags
;
1747 SaveStatus_Impl( pCW
->pWin
, pCW
->aInfo
);
1756 void SfxWorkWindow::SetChildWindowVisible_Impl( sal_uInt32 lId
, bool bEnabled
, SfxVisibilityFlags nMode
)
1758 sal_uInt16 nInter
= static_cast<sal_uInt16
>( lId
>> 16 );
1759 sal_uInt16 nId
= static_cast<sal_uInt16
>( lId
& 0xFFFF );
1761 SfxChildWin_Impl
*pCW
=nullptr;
1765 // If no Parent or the Parent us still unknown, then search here
1766 sal_uInt16 nCount
= aChildWins
.size();
1767 for (sal_uInt16 n
=0; n
<nCount
; n
++)
1768 if (aChildWins
[n
]->nSaveId
== nId
)
1770 pCW
= aChildWins
[n
].get();
1777 // If new, then initialize, add this here depending on the flag or
1779 pCW
= new SfxChildWin_Impl( lId
);
1781 InitializeChild_Impl( pCW
);
1782 aChildWins
.push_back( std::unique_ptr
<SfxChildWin_Impl
>(pCW
) );
1787 pCW
->nInterfaceId
= nInter
;
1788 pCW
->nVisibility
= nMode
;
1789 pCW
->bEnable
= bEnabled
;
1793 // The on/off status of a ChildWindow is switched
1795 void SfxWorkWindow::ToggleChildWindow_Impl(sal_uInt16 nId
, bool bSetFocus
)
1797 sal_uInt16 nCount
= aChildWins
.size();
1799 for (n
=0; n
<nCount
; n
++)
1800 if (aChildWins
[n
]->nId
== nId
)
1805 // The Window is already known
1806 SfxChildWin_Impl
*pCW
= aChildWins
[n
].get();
1807 SfxChildWindow
*pChild
= pCW
->pWin
;
1809 bool bCreationAllowed( true );
1810 if ( !bInternalDockingAllowed
)
1812 // Special case for all non-floatable child windows. We have
1813 // to prevent the creation here!
1814 bCreationAllowed
= !( pCW
->aInfo
.nFlags
& SfxChildWindowFlags::FORCEDOCK
);
1817 if ( bCreationAllowed
)
1823 if ( pChild
->QueryClose() )
1825 pCW
->bCreate
= false;
1826 // The Window should be switched off
1827 pChild
->SetVisible_Impl( false );
1828 RemoveChildWin_Impl( pCW
);
1833 // no actual Window exists, yet => just remember the "switched off" state
1834 pCW
->bCreate
= false;
1839 pCW
->bCreate
= true;
1842 ShowChildWindow_Impl( nId
, true, bSetFocus
);
1846 // create actual Window
1847 CreateChildWin_Impl( pCW
, bSetFocus
);
1850 pCW
->bCreate
= false;
1855 ArrangeChildren_Impl();
1856 ShowChildren_Impl();
1858 if ( pCW
->bCreate
&& bCreationAllowed
)
1862 SfxDockingWindow
*pDock
=
1863 static_cast<SfxDockingWindow
*>( pCW
->pWin
->GetWindow() );
1864 if ( pDock
->IsAutoHide_Impl() )
1865 pDock
->AutoShow_Impl();
1873 nCount
= aChildWins
.size();
1874 for (n
=0; n
<nCount
; n
++)
1875 if (aChildWins
[n
]->nSaveId
== nId
)
1880 OSL_FAIL("The ChildWindow is not in context!");
1884 OSL_FAIL("The ChildWindow is not registered!");
1890 bool SfxWorkWindow::HasChildWindow_Impl(sal_uInt16 nId
)
1892 sal_uInt16 nCount
= aChildWins
.size();
1894 for (n
=0; n
<nCount
; n
++)
1895 if (aChildWins
[n
]->nSaveId
== nId
)
1900 SfxChildWin_Impl
*pCW
= aChildWins
[n
].get();
1901 SfxChildWindow
*pChild
= pCW
->pWin
;
1902 return ( pChild
&& pCW
->bCreate
);
1908 bool SfxWorkWindow::IsFloating( sal_uInt16 nId
)
1910 SfxChildWin_Impl
*pCW
=nullptr;
1914 // If no Parent or the Parent us still unknown, then search here
1915 sal_uInt16 nCount
= aChildWins
.size();
1916 for (sal_uInt16 n
=0; n
<nCount
; n
++)
1917 if (aChildWins
[n
]->nSaveId
== nId
)
1919 pCW
= aChildWins
[n
].get();
1926 // If new, then initialize, add this here depending on the flag or
1928 pCW
= new SfxChildWin_Impl( nId
);
1929 pCW
->bEnable
= false;
1931 pCW
->nVisibility
= SfxVisibilityFlags::Invisible
;
1932 InitializeChild_Impl( pCW
);
1933 aChildWins
.push_back( std::unique_ptr
<SfxChildWin_Impl
>(pCW
) );
1936 SfxChildAlignment eAlign
;
1937 if ( pCW
->aInfo
.GetExtraData_Impl( &eAlign
) )
1938 return( eAlign
== SfxChildAlignment::NOALIGNMENT
);
1944 bool SfxWorkWindow::KnowsChildWindow_Impl(sal_uInt16 nId
)
1946 SfxChildWin_Impl
*pCW
=nullptr;
1947 sal_uInt16 nCount
= aChildWins
.size();
1949 for (n
=0; n
<nCount
; n
++)
1951 pCW
= aChildWins
[n
].get();
1952 if ( pCW
->nSaveId
== nId
)
1958 if ( !(pCW
->aInfo
.nFlags
& SfxChildWindowFlags::ALWAYSAVAILABLE
) && !IsVisible_Impl( pCW
->nVisibility
) )
1960 return pCW
->bEnable
;
1967 void SfxWorkWindow::SetChildWindow_Impl(sal_uInt16 nId
, bool bOn
, bool bSetFocus
)
1969 SfxChildWin_Impl
*pCW
=nullptr;
1970 SfxWorkWindow
*pWork
= nullptr;
1974 // If no Parent or the Parent us still unknown, then search here
1975 sal_uInt16 nCount
= aChildWins
.size();
1976 for (sal_uInt16 n
=0; n
<nCount
; n
++)
1977 if (aChildWins
[n
]->nSaveId
== nId
)
1979 pCW
= aChildWins
[n
].get();
1987 // If new, then initialize, add this here depending on the flag or
1989 pCW
= new SfxChildWin_Impl( nId
);
1990 InitializeChild_Impl( pCW
);
1991 if ( !pWork
|| pCW
->aInfo
.nFlags
& SfxChildWindowFlags::TASK
)
1993 pWork
->aChildWins
.push_back( std::unique_ptr
<SfxChildWin_Impl
>(pCW
) );
1996 if ( pCW
->bCreate
!= bOn
)
1997 pWork
->ToggleChildWindow_Impl(nId
,bSetFocus
);
2001 void SfxWorkWindow::ShowChildWindow_Impl(sal_uInt16 nId
, bool bVisible
, bool bSetFocus
)
2003 sal_uInt16 nCount
= aChildWins
.size();
2004 SfxChildWin_Impl
* pCW
=nullptr;
2006 for (n
=0; n
<nCount
; n
++)
2008 pCW
= aChildWins
[n
].get();
2009 if (pCW
->nId
== nId
)
2015 SfxChildWindow
*pChildWin
= pCW
->pWin
;
2022 pCW
->pCli
->bSetFocus
= bSetFocus
;
2023 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
;
2024 pChildWin
->Show( bSetFocus
&& pChildWin
->WantsFocus() ? ShowFlags::NONE
: ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
2027 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Reappear_Impl();
2034 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
^ SfxChildVisibility::NOT_HIDDEN
;
2038 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Disappear_Impl();
2042 ArrangeChildren_Impl();
2043 ShowChildren_Impl();
2045 else if ( bVisible
)
2047 SetChildWindow_Impl( nId
, true, bSetFocus
);
2048 pChildWin
= pCW
->pWin
;
2053 pChildWin
->SetVisible_Impl( bVisible
);
2054 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
2055 pCW
->aInfo
= pChildWin
->GetInfo();
2056 pCW
->aInfo
.nFlags
|= nFlags
;
2057 if ( !pCW
->bCreate
)
2058 SaveStatus_Impl( pChildWin
, pCW
->aInfo
);
2065 nCount
= aChildWins
.size();
2066 for (n
=0; n
<nCount
; n
++)
2067 if (aChildWins
[n
]->nSaveId
== nId
)
2072 OSL_FAIL("The ChildWindow is not in context!");
2076 OSL_FAIL("The ChildWindow is not registered");
2082 SfxChildWindow
* SfxWorkWindow::GetChildWindow_Impl(sal_uInt16 nId
)
2084 sal_uInt16 nCount
= aChildWins
.size();
2086 for (n
=0; n
<nCount
; n
++)
2087 if (aChildWins
[n
]->nSaveId
== nId
)
2091 return aChildWins
[n
]->pWin
;
2096 void SfxWorkWindow::ResetChildWindows_Impl()
2098 for (std::unique_ptr
<SfxChildWin_Impl
>& pChildWin
: aChildWins
)
2101 pChildWin
->bEnable
= false;
2105 // returns the size of the area (client area) of the
2106 // parent windows, in which the ChildWindow can be fitted.
2108 tools::Rectangle
SfxWorkWindow::GetTopRect_Impl() const
2110 return pMasterFrame
->GetTopOuterRectPixel_Impl();
2114 // Virtual method to find out if there is room for a ChildWindow in the
2115 // client area of the parent.
2117 bool SfxWorkWindow::RequestTopToolSpacePixel_Impl( SvBorder aBorder
)
2119 return !(!IsDockingAllowed() ||
2120 aClientArea
.GetWidth() < aBorder
.Left() + aBorder
.Right() ||
2121 aClientArea
.GetHeight() < aBorder
.Top() + aBorder
.Bottom());
2124 void SfxWorkWindow::SaveStatus_Impl(SfxChildWindow
*pChild
, const SfxChildWinInfo
&rInfo
)
2126 // The Status of the Presentation mode is not saved
2127 if ( IsDockingAllowed() && bInternalDockingAllowed
)
2128 pChild
->SaveStatus(rInfo
);
2131 void SfxWorkWindow::InitializeChild_Impl(SfxChildWin_Impl
*pCW
)
2133 SfxDispatcher
*pDisp
= pBindings
->GetDispatcher_Impl();
2134 SfxViewFrame
*pViewFrame
= pDisp
? pDisp
->GetFrame() :nullptr;
2135 SfxModule
*pMod
= pViewFrame
? SfxModule::GetActiveModule(pViewFrame
) :nullptr;
2142 uno::Reference
< frame::XModuleManager2
> xModuleManager(
2143 frame::ModuleManager::create(::comphelper::getProcessComponentContext()));
2144 sModule
= xModuleManager
->identify(pViewFrame
->GetFrame().GetFrameInterface());
2145 SvtModuleOptions::EFactory eFac
= SvtModuleOptions::ClassifyFactoryByServiceName(sModule
);
2146 sModule
= SvtModuleOptions::GetFactoryShortName(eFac
);
2153 SfxChildWinFactory
* pFact
=nullptr;
2154 SfxApplication
*pApp
= SfxGetpApp();
2156 SfxChildWinFactArr_Impl
&rFactories
= pApp
->GetChildWinFactories_Impl();
2157 for ( size_t nFactory
= 0; nFactory
< rFactories
.size(); ++nFactory
)
2159 pFact
= &rFactories
[nFactory
];
2160 if ( pFact
->nId
== pCW
->nSaveId
)
2162 pCW
->aInfo
= pFact
->aInfo
;
2163 pCW
->aInfo
.aModule
= sModule
;
2164 SfxChildWindow::InitializeChildWinFactory_Impl(
2165 pCW
->nSaveId
, pCW
->aInfo
);
2166 pCW
->bCreate
= pCW
->aInfo
.bVisible
;
2167 SfxChildWindowFlags nFlags
= pFact
->aInfo
.nFlags
;
2168 if ( nFlags
& SfxChildWindowFlags::TASK
)
2169 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::TASK
;
2170 if ( nFlags
& SfxChildWindowFlags::CANTGETFOCUS
)
2171 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::CANTGETFOCUS
;
2172 if ( nFlags
& SfxChildWindowFlags::FORCEDOCK
)
2173 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::FORCEDOCK
;
2174 pFact
->aInfo
= pCW
->aInfo
;
2183 SfxChildWinFactArr_Impl
*pFactories
= pMod
->GetChildWinFactories_Impl();
2187 SfxChildWinFactArr_Impl
&rFactories
= *pFactories
;
2188 for ( size_t nFactory
= 0; nFactory
< rFactories
.size(); ++nFactory
)
2190 pFact
= &rFactories
[nFactory
];
2191 if ( pFact
->nId
== pCW
->nSaveId
)
2193 pCW
->aInfo
= pFact
->aInfo
;
2194 pCW
->aInfo
.aModule
= sModule
;
2195 SfxChildWindow::InitializeChildWinFactory_Impl(
2196 pCW
->nSaveId
, pCW
->aInfo
);
2197 pCW
->bCreate
= pCW
->aInfo
.bVisible
;
2198 SfxChildWindowFlags nFlags
= pFact
->aInfo
.nFlags
;
2199 if ( nFlags
& SfxChildWindowFlags::TASK
)
2200 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::TASK
;
2201 if ( nFlags
& SfxChildWindowFlags::CANTGETFOCUS
)
2202 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::CANTGETFOCUS
;
2203 if ( nFlags
& SfxChildWindowFlags::FORCEDOCK
)
2204 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::FORCEDOCK
;
2205 if ( nFlags
& SfxChildWindowFlags::ALWAYSAVAILABLE
)
2206 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::ALWAYSAVAILABLE
;
2207 pFact
->aInfo
= pCW
->aInfo
;
2213 SfxSplitWindow
* SfxWorkWindow::GetSplitWindow_Impl( SfxChildAlignment eAlign
)
2217 case SfxChildAlignment::TOP
:
2220 case SfxChildAlignment::BOTTOM
:
2223 case SfxChildAlignment::LEFT
:
2226 case SfxChildAlignment::RIGHT
:
2234 void SfxWorkWindow::MakeChildrenVisible_Impl( bool bVis
)
2236 bAllChildrenVisible
= bVis
;
2241 for (sal_uInt16 n
: aSortedList
)
2243 SfxChild_Impl
* pCli
= aChildren
[n
].get();
2244 if ( (pCli
->eAlign
== SfxChildAlignment::NOALIGNMENT
) || (IsDockingAllowed() && bInternalDockingAllowed
) )
2245 pCli
->nVisible
|= SfxChildVisibility::ACTIVE
;
2252 for (sal_uInt16 n
: aSortedList
)
2254 SfxChild_Impl
* pCli
= aChildren
[n
].get();
2255 pCli
->nVisible
&= ~SfxChildVisibility::ACTIVE
;
2260 bool SfxWorkWindow::IsAutoHideMode( const SfxSplitWindow
*pSplitWin
)
2262 for (const VclPtr
<SfxSplitWindow
> & pWin
: pSplit
)
2264 if ( pWin
.get() != pSplitWin
&& pWin
->IsAutoHide( true ) )
2271 void SfxWorkWindow::EndAutoShow_Impl( Point aPos
)
2273 for (VclPtr
<SfxSplitWindow
> & p
: pSplit
)
2275 if ( p
&& p
->IsAutoHide(false) )
2277 Point aLocalPos
= p
->ScreenToOutputPixel( aPos
);
2278 tools::Rectangle
aRect( Point(), p
->GetSizePixel() );
2279 if ( !aRect
.IsInside( aLocalPos
) )
2285 void SfxWorkWindow::ArrangeAutoHideWindows( SfxSplitWindow
*pActSplitWin
)
2290 tools::Rectangle
aArea( aUpperClientArea
);
2291 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
2293 // Either dummy window or window in the auto-show-mode are processed
2294 // (not pinned, FadeIn).
2295 // Only the abandoned window may be invisible, because perhaps its
2296 // size is just being calculated before it is displayed.
2297 VclPtr
<SfxSplitWindow
> const & pSplitWin
= pSplit
[n
];
2298 bool bDummyWindow
= !pSplitWin
->IsFadeIn();
2299 vcl::Window
*pDummy
= pSplitWin
->GetSplitWindow();
2300 vcl::Window
*pWin
= bDummyWindow
? pDummy
: pSplitWin
;
2301 if ( (pSplitWin
->IsPinned() && !bDummyWindow
) || (!pWin
->IsVisible() && pActSplitWin
!= pSplitWin
) )
2304 // Width and position of the dummy window as a starting point
2305 Size aSize
= pDummy
->GetSizePixel();
2306 Point aPos
= pDummy
->GetPosPixel();
2313 // Get the width of the Window yourself, if no DummyWindow
2314 if ( !bDummyWindow
)
2315 aSize
.setWidth( pSplitWin
->GetSizePixel().Width() );
2317 // If a Window is visible to the left, then the free region
2318 // starts to the right from it, for example at the Client area
2319 tools::Long nLeft
= aPos
.X() + aSize
.Width();
2320 if ( nLeft
> aArea
.Left() )
2321 aArea
.SetLeft( nLeft
);
2326 // Right SplitWindow
2327 // Position to correct the difference of the widths
2328 aPos
.AdjustX(aSize
.Width() );
2330 // Get the width of the Window yourself, if no DummyWindow
2331 if ( !bDummyWindow
)
2332 aSize
.setWidth( pSplitWin
->GetSizePixel().Width() );
2334 aPos
.AdjustX( -(aSize
.Width()) );
2336 // If already a window is opened at the left side, then the
2337 // right is not allowed to overlap this one.
2338 if ( aPos
.X() < aArea
.Left() )
2340 aPos
.setX( aArea
.Left() );
2341 aSize
.setWidth( aArea
.GetWidth() );
2344 // If a Window is visible to the right, then the free region
2345 // starts to the left from it, for example at the Client area
2346 tools::Long nRight
= aPos
.X();
2347 if ( !aArea
.IsWidthEmpty() && nRight
< aArea
.Right() )
2348 aArea
.SetRight( nRight
);
2354 // Get the height of the Window yourself, if no DummyWindow
2355 if ( !bDummyWindow
)
2356 aSize
.setHeight( pSplitWin
->GetSizePixel().Height() );
2359 // Adjust width with regard to if a Window is already open
2360 // to the left or right
2361 aPos
.setX( aArea
.Left() );
2362 aSize
.setWidth( aArea
.GetWidth() );
2364 // If a Window is visible at the top, then the free region
2365 // starts beneath it, for example at the Client area
2366 tools::Long nTop
= aPos
.Y() + aSize
.Height();
2367 if ( nTop
> aArea
.Top() )
2368 aArea
.SetTop( nTop
);
2373 // The bottom SplitWindow
2374 // Position to correct the difference of the heights
2375 aPos
.AdjustY(aSize
.Height() );
2377 // Get the height of the Window yourself, if no DummyWindow
2378 if ( !bDummyWindow
)
2379 aSize
.setHeight( pSplitWin
->GetSizePixel().Height() );
2381 aPos
.AdjustY( -(aSize
.Height()) );
2383 // Adjust width with regard to if a Window is already open
2384 // to the left or right.
2385 aPos
.setX( aArea
.Left() );
2386 aSize
.setWidth( aArea
.GetWidth() );
2388 // If already a window is opened at the top, then the
2389 // bottom one is not allowed to overlap this one.
2390 if ( aPos
.Y() < aArea
.Top() )
2392 aPos
.setY( aArea
.Top() );
2393 aSize
.setHeight( aArea
.GetHeight() );
2400 if ( !bDummyWindow
)
2401 // the FadeIn-Window is a Floating window, which coordinates are
2402 // set in Screen coordinates.
2403 pSplitWin
->SetPosSizePixel( pWorkWin
->OutputToScreenPixel(aPos
), aSize
);
2405 // the docked DummyWindow
2406 pDummy
->SetPosSizePixel( aPos
, aSize
);
2410 tools::Rectangle
SfxWorkWindow::GetFreeArea( bool bAutoHide
) const
2414 tools::Rectangle
aArea( aClientArea
);
2415 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
2417 if ( pSplit
[n
]->IsPinned() || !pSplit
[n
]->IsVisible() )
2420 Size aSize
= pSplit
[n
]->GetSizePixel();
2424 aArea
.AdjustLeft(aSize
.Width() );
2427 aArea
.AdjustRight( -(aSize
.Width()) );
2430 aArea
.AdjustTop(aSize
.Height() );
2433 aArea
.AdjustBottom( -(aSize
.Height()) );
2444 void SfxWorkWindow::SetActiveChild_Impl( vcl::Window
*pChild
)
2446 pActiveChild
= pChild
;
2449 void SfxWorkWindow::DataChanged_Impl()
2451 ArrangeChildren_Impl();
2454 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */