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 <sfx2/sfxsids.hrc>
38 #include <sfx2/toolbarids.hxx>
39 #include <vcl/taskpanelist.hxx>
40 #include <vcl/svapp.hxx>
41 #include <svl/eitem.hxx>
42 #include <tools/svborder.hxx>
43 #include <tools/debug.hxx>
44 #include <unotools/moduleoptions.hxx>
45 #include <com/sun/star/ui/XUIElement.hpp>
46 #include <com/sun/star/frame/LayoutManagerEvents.hpp>
47 #include <com/sun/star/frame/ModuleManager.hpp>
48 #include <com/sun/star/frame/XLayoutManager.hpp>
49 #include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/lang/DisposedException.hpp>
52 #include <type_traits>
53 #include <unordered_map>
54 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
56 using namespace ::com::sun::star
;
57 using namespace ::com::sun::star::uno
;
69 const ResIdToResName pToolBarResToName
[] =
71 { ToolbarId::FullScreenToolbox
, "fullscreenbar" },
72 { ToolbarId::EnvToolbox
, "standardbar", },
73 { ToolbarId::SvxTbx_Form_Navigation
, "formsnavigationbar" },
74 { ToolbarId::SvxTbx_Form_Filter
, "formsfilterbar" },
75 { ToolbarId::SvxTbx_Text_Control_Attributes
, "formtextobjectbar" },
76 { ToolbarId::SvxTbx_Controls
, "formcontrols" },
77 { ToolbarId::SvxTbx_FormDesign
, "formdesign" },
78 { ToolbarId::Math_Toolbox
, "toolbar" }, //math
79 { ToolbarId::Text_Toolbox_Sc
, "textobjectbar" }, //calc
80 { ToolbarId::Draw_Objectbar
, "drawobjectbar" },
81 { ToolbarId::Graphic_Objectbar
, "graphicobjectbar" },
82 { ToolbarId::Objectbar_Format
, "formatobjectbar" },
83 { ToolbarId::Objectbar_Preview
, "previewbar" },
84 { ToolbarId::Objectbar_Tools
, "toolbar" }, //calc
85 { ToolbarId::Bezier_Toolbox_Sd
, "bezierobjectbar" }, //draw/impress
86 { ToolbarId::Gluepoints_Toolbox
, "gluepointsobjectbar" },
87 { ToolbarId::Draw_Graf_Toolbox
, "graphicobjectbar" },
88 { ToolbarId::Draw_Obj_Toolbox
, "drawingobjectbar" }, //impress
89 { ToolbarId::Draw_Text_Toolbox_Sd
, "textobjectbar" }, //impress
90 { ToolbarId::Draw_Toolbox_Sd
, "toolbar" }, //impress
91 { ToolbarId::Draw_Options_Toolbox
, "optionsbar" },
92 { ToolbarId::Draw_CommonTask_Toolbox
, "commontaskbar" },
93 { ToolbarId::Graphic_Obj_Toolbox
, "drawingobjectbar" }, //draw
94 { ToolbarId::Outline_Toolbox
, "outlinetoolbar" }, //impress
95 { ToolbarId::Slide_Toolbox
, "slideviewtoolbar" },
96 { ToolbarId::Slide_Obj_Toolbox
, "slideviewobjectbar" },
97 { ToolbarId::Bezier_Toolbox_Sw
, "bezierobjectbar" },
98 { ToolbarId::Draw_Toolbox_Sw
, "drawingobjectbar" },
99 { ToolbarId::Draw_Text_Toolbox_Sw
, "drawtextobjectbar" },
100 { ToolbarId::Frame_Toolbox
, "frameobjectbar" },
101 { ToolbarId::Grafik_Toolbox
, "graphicobjectbar" },
102 { ToolbarId::Num_Toolbox
, "numobjectbar" },
103 { ToolbarId::Ole_Toolbox
, "oleobjectbar" },
104 { ToolbarId::Table_Toolbox
, "tableobjectbar" },
105 { ToolbarId::Text_Toolbox_Sw
, "textobjectbar" },
106 { ToolbarId::PView_Toolbox
, "previewobjectbar" }, //writer
107 { ToolbarId::Webtools_Toolbox
, "toolbar" }, //web
108 { ToolbarId::Webtext_Toolbox
, "textobjectbar" },
109 { ToolbarId::Tools_Toolbox
, "toolbar" }, //writer
110 { ToolbarId::Webframe_Toolbox
, "frameobjectbar" }, //web
111 { ToolbarId::Webgraphic_Toolbox
, "graphicobjectbar" },
112 { ToolbarId::Webole_Toolbox
, "oleobjectbar" },
113 { ToolbarId::Basicide_Objectbar
, "macrobar" },
114 { ToolbarId::Svx_Fontwork_Bar
, "fontworkobjectbar" }, //global
115 { ToolbarId::Svx_Extrusion_Bar
, "extrusionobjectbar" },
116 { ToolbarId::FormLayer_Toolbox
, "formsobjectbar" },
117 { ToolbarId::Module_Toolbox
, "viewerbar" }, //writer (plugin)
118 { ToolbarId::Objectbar_App
, "viewerbar" }, //calc (plugin)
119 { ToolbarId::Draw_Viewer_Toolbox
, "viewerbar" }, //impress(plugin)
120 { ToolbarId::Draw_Media_Toolbox
, "mediaobjectbar" }, //draw/impress
121 { ToolbarId::Media_Objectbar
, "mediaobjectbar" }, //calc
122 { ToolbarId::Media_Toolbox
, "mediaobjectbar" }, //writer
123 { ToolbarId::None
, "" }
126 // Sort the Children according their alignment
127 // The order corresponds to the enum SfxChildAlignment (->CHILDWIN.HXX).
129 constexpr OUStringLiteral g_aLayoutManagerPropName
= u
"LayoutManager";
131 // Help to make changes to the alignment compatible!
132 LayoutManagerListener::LayoutManagerListener(
133 SfxWorkWindow
* pWrkWin
) :
134 m_bHasFrame( false ),
139 LayoutManagerListener::~LayoutManagerListener()
143 void LayoutManagerListener::setFrame( const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
145 SolarMutexGuard aGuard
;
146 if ( !m_pWrkWin
|| m_bHasFrame
)
155 css::uno::Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
156 css::uno::Reference
< css::frame::XLayoutManagerEventBroadcaster
> xLayoutManager
;
157 if ( !xPropSet
.is() )
162 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
163 aValue
>>= xLayoutManager
;
165 if ( xLayoutManager
.is() )
166 xLayoutManager
->addLayoutManagerEventListener(
167 css::uno::Reference
< css::frame::XLayoutManagerListener
>(this) );
169 xPropSet
.set( xLayoutManager
, UNO_QUERY
);
172 aValue
= xPropSet
->getPropertyValue( "LockCount" );
173 aValue
>>= m_pWrkWin
->m_nLock
;
176 catch ( css::lang::DisposedException
& )
179 catch ( const css::uno::RuntimeException
& )
183 catch ( css::uno::Exception
& )
191 void SAL_CALL
LayoutManagerListener::addEventListener(
192 const css::uno::Reference
< css::lang::XEventListener
>& )
194 // do nothing, only internal class
197 void SAL_CALL
LayoutManagerListener::removeEventListener(
198 const css::uno::Reference
< css::lang::XEventListener
>& )
200 // do nothing, only internal class
203 void SAL_CALL
LayoutManagerListener::dispose()
205 SolarMutexGuard aGuard
;
210 css::uno::Reference
< css::frame::XFrame
> xFrame( m_xFrame
.get(), css::uno::UNO_QUERY
);
217 css::uno::Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, css::uno::UNO_QUERY
);
218 css::uno::Reference
< css::frame::XLayoutManagerEventBroadcaster
> xLayoutManager
;
219 if ( !xPropSet
.is() )
224 css::uno::Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
225 aValue
>>= xLayoutManager
;
227 // remove as listener from layout manager
228 if ( xLayoutManager
.is() )
229 xLayoutManager
->removeLayoutManagerEventListener(
230 css::uno::Reference
< css::frame::XLayoutManagerListener
>(this) );
232 catch ( css::lang::DisposedException
& )
235 catch ( const css::uno::RuntimeException
& )
239 catch ( css::uno::Exception
& )
247 void SAL_CALL
LayoutManagerListener::disposing(
248 const css::lang::EventObject
& )
250 SolarMutexGuard aGuard
;
257 // XLayoutManagerEventListener
259 void SAL_CALL
LayoutManagerListener::layoutEvent(
260 const css::lang::EventObject
&,
261 ::sal_Int16 eLayoutEvent
,
262 const css::uno::Any
& )
264 SolarMutexGuard aGuard
;
268 if ( eLayoutEvent
== css::frame::LayoutManagerEvents::VISIBLE
)
270 m_pWrkWin
->MakeVisible_Impl( true );
271 m_pWrkWin
->ShowChildren_Impl();
272 m_pWrkWin
->ArrangeChildren_Impl();
274 else if ( eLayoutEvent
== css::frame::LayoutManagerEvents::INVISIBLE
)
276 m_pWrkWin
->MakeVisible_Impl( false );
277 m_pWrkWin
->HideChildren_Impl();
278 m_pWrkWin
->ArrangeChildren_Impl();
280 else if ( eLayoutEvent
== css::frame::LayoutManagerEvents::LOCK
)
282 m_pWrkWin
->Lock_Impl( true );
284 else if ( eLayoutEvent
== css::frame::LayoutManagerEvents::UNLOCK
)
286 m_pWrkWin
->Lock_Impl( false );
294 size_t operator()(ToolbarId t
) const
296 typedef std::underlying_type
<ToolbarId
>::type underlying_type
;
297 return std::hash
<underlying_type
>()(static_cast<underlying_type
>(t
));
301 class FilledToolBarResIdToResourceURLMap
304 typedef std::unordered_map
<ToolbarId
, OUString
, ToolbarIdHash
> ToolBarResIdToResourceURLMap
;
305 ToolBarResIdToResourceURLMap m_aResIdToResourceURLMap
;
307 FilledToolBarResIdToResourceURLMap()
309 sal_Int32
nIndex( 0 );
310 while (pToolBarResToName
[nIndex
].eId
!= ToolbarId::None
)
312 OUString
aResourceURL( OUString::createFromAscii( pToolBarResToName
[nIndex
].pName
));
313 m_aResIdToResourceURLMap
.emplace(pToolBarResToName
[nIndex
].eId
, aResourceURL
);
318 OUString
findURL(ToolbarId eId
) const
320 ToolBarResIdToResourceURLMap::const_iterator aIter
= m_aResIdToResourceURLMap
.find(eId
);
321 if ( aIter
!= m_aResIdToResourceURLMap
.end() )
322 return aIter
->second
;
328 static OUString
GetResourceURLFromToolbarId(ToolbarId eId
)
330 static FilledToolBarResIdToResourceURLMap theFilledToolBarResIdToResourceURLMap
;
331 return theFilledToolBarResIdToResourceURLMap
.findURL(eId
);
334 static sal_uInt16
TbxMatch( sal_uInt16 nPos
)
338 case SFX_OBJECTBAR_APPLICATION
:
340 case SFX_OBJECTBAR_OPTIONS
:
342 case SFX_OBJECTBAR_MACRO
:
344 case SFX_OBJECTBAR_OBJECT
:
346 case SFX_OBJECTBAR_TOOLS
:
348 case SFX_OBJECTBAR_FULLSCREEN
:
349 case SFX_OBJECTBAR_COMMONTASK
:
350 case SFX_OBJECTBAR_RECORDING
:
357 static sal_uInt16
ChildAlignValue(SfxChildAlignment eAlign
)
363 case SfxChildAlignment::HIGHESTTOP
:
366 case SfxChildAlignment::LOWESTBOTTOM
:
369 case SfxChildAlignment::FIRSTLEFT
:
372 case SfxChildAlignment::LASTRIGHT
:
375 case SfxChildAlignment::LEFT
:
378 case SfxChildAlignment::RIGHT
:
381 case SfxChildAlignment::FIRSTRIGHT
:
384 case SfxChildAlignment::LASTLEFT
:
387 case SfxChildAlignment::TOP
:
390 case SfxChildAlignment::BOTTOM
:
393 case SfxChildAlignment::TOOLBOXTOP
:
396 case SfxChildAlignment::TOOLBOXBOTTOM
:
399 case SfxChildAlignment::LOWESTTOP
:
402 case SfxChildAlignment::HIGHESTBOTTOM
:
405 case SfxChildAlignment::TOOLBOXLEFT
:
408 case SfxChildAlignment::TOOLBOXRIGHT
:
411 case SfxChildAlignment::NOALIGNMENT
:
412 break; // -Wall not handled...
418 void SfxWorkWindow::Sort_Impl()
421 for (size_t i
= 0; i
< aChildren
.size(); ++i
)
423 SfxChild_Impl
*pCli
= aChildren
[i
].get();
426 decltype(aSortedList
)::size_type k
;
427 for (k
=0; k
<aSortedList
.size(); k
++)
428 if (ChildAlignValue( aChildren
[aSortedList
[k
]]->eAlign
) >
429 ChildAlignValue(pCli
->eAlign
))
431 aSortedList
.insert( aSortedList
.begin() + k
, i
);
438 constexpr OUStringLiteral
g_aStatusBarResName( u
"private:resource/statusbar/statusbar" );
439 constexpr OUStringLiteral
g_aTbxTypeName( u
"private:resource/toolbar/" );
440 constexpr OUStringLiteral
g_aProgressBarResName( u
"private:resource/progressbar/progressbar" );
442 // constructor for workwin of a Frame
444 SfxWorkWindow::SfxWorkWindow( vcl::Window
*pWin
, SfxFrame
*pFrm
, SfxFrame
* pMaster
) :
445 pBindings(&pFrm
->GetCurrentViewFrame()->GetBindings()),
447 pActiveChild( nullptr ),
448 nUpdateMode(SfxVisibilityFlags::Standard
),
450 nOrigMode( SfxVisibilityFlags::Invisible
),
452 bDockingAllowed(true),
453 bInternalDockingAllowed(true),
454 bAllChildrenVisible(true),
455 #if !defined(ANDROID) || HAVE_FEATURE_ANDROID_LOK
456 bIsFullScreen( false ),
457 #else // Fennec-based Android Viewer
458 bIsFullScreen( true ),
460 #if HAVE_FEATURE_DESKTOP
461 bShowStatusBar( true ),
463 bShowStatusBar( sal_False
),
466 pMasterFrame( pMaster
),
469 DBG_ASSERT (pBindings
, "No Bindings!");
471 pBindings
->SetWorkWindow_Impl( std::unique_ptr
<SfxWorkWindow
>(this) );
473 // For the ObjectBars an integral place in the Childlist is reserved,
474 // so that they always come in a defined order.
475 for (int i
=0; i
<SFX_OBJECTBAR_MAX
; ++i
)
476 aChildren
.push_back( nullptr );
478 // create and initialize layout manager listener
479 Reference
< css::frame::XFrame
> xFrame
= GetFrameInterface();
480 rtl::Reference
<LayoutManagerListener
> pLayoutManagerListener
= new LayoutManagerListener( this );
481 m_xLayoutManagerListener
= pLayoutManagerListener
;
482 pLayoutManagerListener
->setFrame( xFrame
);
484 SfxShell
* pConfigShell
= pFrm
->GetCurrentViewFrame();
485 if ( pConfigShell
&& pConfigShell
->GetObjectShell() )
487 bShowStatusBar
= ( !pConfigShell
->GetObjectShell()->IsInPlaceActive() );
488 bDockingAllowed
= true;
489 bInternalDockingAllowed
= true;
492 // The required split windows (one for each side) can be created
493 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
495 // The SplitWindows excludes direct ChildWindows of the WorkWindows
496 // and receives the docked window.
498 SfxChildAlignment eAlign
=
499 ( n
== SFX_SPLITWINDOWS_LEFT
? SfxChildAlignment::LEFT
:
500 n
== SFX_SPLITWINDOWS_RIGHT
? SfxChildAlignment::RIGHT
:
501 n
== SFX_SPLITWINDOWS_TOP
? SfxChildAlignment::TOP
:
502 SfxChildAlignment::BOTTOM
);
503 VclPtr
<SfxSplitWindow
> pSplitWin
= VclPtr
<SfxSplitWindow
>::Create(pWorkWin
, eAlign
, this, true );
504 pSplit
[n
] = pSplitWin
;
507 nOrigMode
= SfxVisibilityFlags::Standard
;
508 nUpdateMode
= SfxVisibilityFlags::Standard
;
514 SfxWorkWindow::~SfxWorkWindow()
517 // Delete SplitWindows
518 for (VclPtr
<SfxSplitWindow
> & p
: pSplit
)
520 if (p
->GetWindowCount())
521 ReleaseChild_Impl(*p
);
525 // Delete help structure for Child-Windows
526 DBG_ASSERT( aChildren
.empty(), "dangling children" );
528 if ( m_xLayoutManagerListener
.is() )
529 m_xLayoutManagerListener
->dispose();
532 void SfxWorkWindow::Lock_Impl( bool bLock
)
540 OSL_FAIL("Lock count underflow!");
541 assert(m_nLock
>= 0);
546 ArrangeChildren_Impl();
550 // Helper method to release the child lists. Should the destructor not be
551 // called after this, instead work continues, then space for the object bars
552 // and split windows has to be reserved in the same way as in the constructor
555 void SfxWorkWindow::DeleteControllers_Impl()
558 // Lock SplitWindows (which means suppressing the Resize-Reaction of the
560 for (size_t n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
562 VclPtr
<SfxSplitWindow
> const &p
= pSplit
[n
];
563 if (p
->GetWindowCount())
567 // Delete Child-Windows
568 while(!aChildWins
.empty())
570 std::unique_ptr
<SfxChildWin_Impl
> pCW
= std::move(*aChildWins
.begin());
571 aChildWins
.erase(aChildWins
.begin());
572 SfxChildWindow
*pChild
= pCW
->pWin
;
575 if (comphelper::LibreOfficeKit::isActive())
577 vcl::Window
* pWindow
= pChild
->GetWindow();
580 pWindow
->ReleaseLOKNotifier();
585 // If the child window is a direct child window and not in a
586 // SplitWindow, cancel it at the workwindow.
587 // After TH a cancellation on the SplitWindow is not necessary
588 // since this window is also destroyed (see below).
591 if (pChild
->GetController())
592 ReleaseChild_Impl(*pChild
->GetController());
594 ReleaseChild_Impl(*pChild
->GetWindow());
598 pWorkWin
->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChild
->GetWindow() );
602 // ATTENTION: The array itself is cleared after this loop!!
603 // Therefore we have to set every array entry to zero as it could be
604 // accessed by calling pChild->Destroy().
605 // Window::NotifyAllChildren() calls SfxWorkWindow::DataChanged_Impl for
606 // 8-bit displays (WM_QUERYPALETTECHANGED message due to focus change)!!
609 Reference
< css::frame::XFrame
> xFrame
= GetFrameInterface();
610 Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
611 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
616 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
617 aValue
>>= xLayoutManager
;
624 if ( xLayoutManager
.is() )
626 xLayoutManager
->reset();
629 ResetStatusBar_Impl();
631 // Delete ObjectBars (this is done last, so that aChildren does not
632 // receive dead Pointers)
633 for (SfxObjectBar_Impl
& i
: aObjBarList
)
635 // Not every position must be occupied
636 ToolbarId eId
= i
.eId
;
637 if (eId
!= ToolbarId::None
)
638 i
.eId
= ToolbarId::None
;
642 // ObjectBars are all released at once, since they occupy a
643 // fixed contiguous area in the array pChild
651 // for placing the child window.
653 void SfxWorkWindow::ArrangeChildren_Impl( bool bForce
)
655 if ( pFrame
->IsClosing_Impl() || ( m_nLock
&& !bForce
))
658 SfxInPlaceClient
*pClient
= nullptr;
659 SfxViewFrame
*pF
= pFrame
->GetCurrentViewFrame();
660 if ( pF
&& pF
->GetViewShell() )
661 pClient
= pF
->GetViewShell()->GetIPClient();
666 aClientArea
= GetTopRect_Impl();
667 if ( aClientArea
.IsEmpty() )
671 if ( nChildren
&& IsVisible_Impl() )
672 aBorder
= Arrange_Impl();
673 // If the current application document contains an IPClient, then the
674 // object through SetTopToolFramePixel has to be assigned the available
675 // space. The object will then point to its UITools and sets the app border
676 // (-> SfxInPlaceEnv_Impl:: ArrangeChildren_Impl ()). Otherwise the
677 // app border is set here directly to possibly overwrite the Border that
678 // was set by an object from another document. The object does not set
679 // the SetAppBorder when it removes its UI tools so that no-dithering
681 // (->SfxInPlaceEnv_Impl::ArrangeChildren_Impl())
683 pMasterFrame
->SetToolSpaceBorderPixel_Impl( aBorder
);
685 ArrangeAutoHideWindows( nullptr );
688 void SfxWorkWindow::FlushPendingChildSizes()
690 // tdf#116865, if any windows are being resized, i.e. their
691 // resize timer is active, then calling GetSizePixel on
692 // them forces the timer to fire and sets the final
693 // size to which they are getting resized towards.
694 for (size_t i
= 0; i
< aChildren
.size(); ++i
)
696 SfxChild_Impl
*pCli
= aChildren
[i
].get();
697 if (!pCli
|| !pCli
->pWin
)
699 (void)pCli
->pWin
->GetSizePixel();
703 SvBorder
SfxWorkWindow::Arrange_Impl()
707 This method organizes all visible child windows so that the docked window
708 sorted in order from the outside to the inside are placed after one
709 another. If a visible window does not fit anymore into the free
710 ClientArea, it is set to "not visible".
713 //tdf#116865 trigger pending sizing timers now so we arrange
714 //with the final size of the client area.
716 //Otherwise calling GetSizePixel in the following loop will trigger the
717 //timers, causing reentry into Arrange_Impl again where the inner
718 //Arrange_Impl arranges with the final size, and then returns to this outer
719 //Arrange_Impl which would rearrange with the old client area size
720 FlushPendingChildSizes();
721 aClientArea
= GetTopRect_Impl();
722 aUpperClientArea
= aClientArea
;
733 tools::Rectangle
aTmp( aClientArea
);
735 for (sal_uInt16 n
: aSortedList
)
737 SfxChild_Impl
* pCli
= aChildren
[n
].get();
741 // First, we assume that there is room for the window.
742 pCli
->nVisible
|= SfxChildVisibility::FITS_IN
;
744 // Skip invisible windows
745 if (pCli
->nVisible
!= SfxChildVisibility::VISIBLE
)
751 aSize
= pCli
->pWin
->GetSizePixel();
753 SvBorder aTemp
= aBorder
;
754 bool bAllowHiding
= true;
755 switch ( pCli
->eAlign
)
757 case SfxChildAlignment::HIGHESTTOP
:
758 case SfxChildAlignment::TOP
:
759 case SfxChildAlignment::TOOLBOXTOP
:
760 case SfxChildAlignment::LOWESTTOP
:
761 aSize
.setWidth( aTmp
.GetWidth() );
762 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
763 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
764 bAllowHiding
= false;
765 aBorder
.Top() += aSize
.Height();
766 aPos
= aTmp
.TopLeft();
767 aTmp
.AdjustTop(aSize
.Height() );
768 if ( pCli
->eAlign
== SfxChildAlignment::HIGHESTTOP
)
769 aUpperClientArea
.AdjustTop(aSize
.Height() );
772 case SfxChildAlignment::LOWESTBOTTOM
:
773 case SfxChildAlignment::BOTTOM
:
774 case SfxChildAlignment::TOOLBOXBOTTOM
:
775 case SfxChildAlignment::HIGHESTBOTTOM
:
776 aSize
.setWidth( aTmp
.GetWidth() );
777 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
778 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
779 aBorder
.Bottom() += aSize
.Height();
780 aPos
= aTmp
.BottomLeft();
781 aPos
.AdjustY( -(aSize
.Height()-1) );
782 aTmp
.AdjustBottom( -(aSize
.Height()) );
783 if ( pCli
->eAlign
== SfxChildAlignment::LOWESTBOTTOM
)
784 aUpperClientArea
.AdjustBottom( -(aSize
.Height()) );
787 case SfxChildAlignment::FIRSTLEFT
:
788 case SfxChildAlignment::LEFT
:
789 case SfxChildAlignment::LASTLEFT
:
790 case SfxChildAlignment::TOOLBOXLEFT
:
791 aSize
.setHeight( aTmp
.GetHeight() );
792 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
793 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
794 bAllowHiding
= false;
795 aBorder
.Left() += aSize
.Width();
796 aPos
= aTmp
.TopLeft();
797 aTmp
.AdjustLeft(aSize
.Width() );
798 if ( pCli
->eAlign
!= SfxChildAlignment::TOOLBOXLEFT
)
799 aUpperClientArea
.AdjustLeft(aSize
.Width() );
802 case SfxChildAlignment::FIRSTRIGHT
:
803 case SfxChildAlignment::RIGHT
:
804 case SfxChildAlignment::LASTRIGHT
:
805 case SfxChildAlignment::TOOLBOXRIGHT
:
806 aSize
.setHeight( aTmp
.GetHeight() );
807 if ( pCli
->pWin
->GetType() == WindowType::SPLITWINDOW
)
808 aSize
= static_cast<SplitWindow
*>(pCli
->pWin
.get())->CalcLayoutSizePixel( aSize
);
809 aBorder
.Right() += aSize
.Width();
810 aPos
= aTmp
.TopRight();
811 aPos
.AdjustX( -(aSize
.Width()-1) );
812 aTmp
.AdjustRight( -(aSize
.Width()) );
813 if ( pCli
->eAlign
!= SfxChildAlignment::TOOLBOXRIGHT
)
814 aUpperClientArea
.AdjustRight( -(aSize
.Width()) );
818 pCli
->aSize
= pCli
->pWin
->GetSizePixel();
819 pCli
->bResize
= false;
823 pCli
->pWin
->SetPosSizePixel( aPos
, aSize
);
824 pCli
->bResize
= false;
826 if( bAllowHiding
&& !RequestTopToolSpacePixel_Impl( aBorder
) )
828 pCli
->nVisible
^= SfxChildVisibility::FITS_IN
;
833 if ( aClientArea
.GetWidth() >= aBorder
.Left() + aBorder
.Right() )
835 aClientArea
.AdjustLeft(aBorder
.Left() );
836 aClientArea
.AdjustRight( -(aBorder
.Right()) );
840 aBorder
.Left() = aClientArea
.Left();
841 aBorder
.Right() = aClientArea
.Right();
842 aClientArea
.SetRight( aTmp
.Left() );
843 aClientArea
.SetLeft( aTmp
.Left() );
846 if ( aClientArea
.GetHeight() >= aBorder
.Top() + aBorder
.Bottom() )
848 aClientArea
.AdjustTop(aBorder
.Top() );
849 aClientArea
.AdjustBottom( -(aBorder
.Bottom()) );
853 aBorder
.Top() = aClientArea
.Top();
854 aBorder
.Bottom() = aClientArea
.Bottom();
855 aClientArea
.SetTop(aTmp
.Top());
856 aClientArea
.SetBottom(aTmp
.Top());
859 return IsDockingAllowed() ? aBorder
: SvBorder();
862 bool SfxWorkWindow::PrepareClose_Impl()
864 for (const std::unique_ptr
<SfxChildWin_Impl
> &pCW
: aChildWins
)
866 SfxChildWindow
*pChild
= pCW
->pWin
;
867 if ( pChild
&& !pChild
->QueryClose() )
874 SfxChild_Impl
* SfxWorkWindow::RegisterChild_Impl( vcl::Window
& rWindow
,
875 SfxChildAlignment eAlign
)
877 DBG_ASSERT( aChildren
.size() < 255, "too many children" );
878 DBG_ASSERT( SfxChildAlignValid(eAlign
), "invalid align" );
879 DBG_ASSERT( !FindChild_Impl(&rWindow
), "child registered more than once" );
882 if ( rWindow
.GetParent() != pWorkWin
)
883 rWindow
.SetParent( pWorkWin
);
885 auto pChild
= std::make_unique
<SfxChild_Impl
>(rWindow
, rWindow
.GetSizePixel(),
886 eAlign
, rWindow
.IsVisible());
888 aChildren
.push_back(std::move(pChild
));
891 return aChildren
.back().get();
894 SfxChild_Impl
* SfxWorkWindow::RegisterChild_Impl(std::shared_ptr
<SfxDialogController
>& rController
,
895 SfxChildAlignment eAlign
)
897 DBG_ASSERT( aChildren
.size() < 255, "too many children" );
898 DBG_ASSERT( SfxChildAlignValid(eAlign
), "invalid align" );
900 auto pChild
= std::make_unique
<SfxChild_Impl
>(rController
, eAlign
);
902 aChildren
.push_back(std::move(pChild
));
905 return aChildren
.back().get();
908 void SfxWorkWindow::ReleaseChild_Impl( vcl::Window
& rWindow
)
911 SfxChild_Impl
*pChild
= nullptr;
912 decltype(aChildren
)::size_type nPos
;
913 for ( nPos
= 0; nPos
< aChildren
.size(); ++nPos
)
915 pChild
= aChildren
[nPos
].get();
916 if ( pChild
&& pChild
->pWin
== &rWindow
)
920 aChildren
.erase(aChildren
.begin() + nPos
);
924 OSL_FAIL( "releasing unregistered child" );
927 void SfxWorkWindow::ReleaseChild_Impl(const SfxDialogController
& rController
)
930 SfxChild_Impl
*pChild
= nullptr;
931 decltype(aChildren
)::size_type nPos
;
932 for ( nPos
= 0; nPos
< aChildren
.size(); ++nPos
)
934 pChild
= aChildren
[nPos
].get();
935 if (pChild
&& pChild
->xController
.get() == &rController
)
939 aChildren
.erase(aChildren
.begin() + nPos
);
943 OSL_FAIL( "releasing unregistered child" );
946 SfxChild_Impl
* SfxWorkWindow::FindChild_Impl( const vcl::Window
* rWindow
) const
949 sal_uInt16 nCount
= aChildren
.size();
950 for ( sal_uInt16 nPos
= 0; nPos
< nCount
; ++nPos
)
952 SfxChild_Impl
*pChild
= aChildren
[nPos
].get();
953 if ( pChild
&& pChild
->pWin
== rWindow
)
960 void SfxWorkWindow::ShowChildren_Impl()
962 bool bInvisible
= ( !IsVisible_Impl() || ( !pWorkWin
->IsReallyVisible() && !pWorkWin
->IsReallyShown() ));
964 for (std::unique_ptr
<SfxChild_Impl
>& pCli
: aChildren
)
968 SfxChildWin_Impl
* pCW
= nullptr;
969 if (pCli
->pWin
|| pCli
->xController
)
971 // We have to find the SfxChildWin_Impl to retrieve the
972 // SFX_CHILDWIN flags that can influence visibility.
973 for (const std::unique_ptr
<SfxChildWin_Impl
>& pCWin
: aChildWins
)
975 SfxChild_Impl
* pChild
= pCWin
->pCli
;
976 if ( pChild
== pCli
.get() )
983 bool bVisible( !bInvisible
);
986 // Check flag SFX_CHILDWIN_NEVERHIDE that forces us to show
987 // the child window even in situations where no child window is
989 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
990 bVisible
= !bInvisible
|| ( nFlags
& SfxChildWindowFlags::NEVERHIDE
);
993 if ( SfxChildVisibility::VISIBLE
== (pCli
->nVisible
& SfxChildVisibility::VISIBLE
) && bVisible
)
995 ShowFlags nFlags
= pCli
->bSetFocus
? ShowFlags::NONE
: ShowFlags::NoFocusChange
| ShowFlags::NoActivate
;
996 if (pCli
->xController
)
998 if (!pCli
->xController
->getDialog()->get_visible())
1000 auto xController
= pCli
->xController
;
1001 weld::DialogController::runAsync(xController
,
1002 [=](sal_Int32
/*nResult*/){ xController
->Close(); });
1006 pCli
->pWin
->Show(true, nFlags
);
1007 pCli
->bSetFocus
= false;
1011 if (pCli
->xController
)
1013 if (pCli
->xController
->getDialog()->get_visible())
1014 pCli
->xController
->response(RET_CLOSE
);
1024 void SfxWorkWindow::HideChildren_Impl()
1026 for ( sal_uInt16 nPos
= aChildren
.size(); nPos
> 0; --nPos
)
1028 SfxChild_Impl
*pChild
= aChildren
[nPos
-1].get();
1031 if (pChild
->xController
)
1032 pChild
->xController
->response(RET_CLOSE
);
1033 else if (pChild
->pWin
)
1034 pChild
->pWin
->Hide();
1038 void SfxWorkWindow::ResetObjectBars_Impl()
1040 for ( auto & n
: aObjBarList
)
1043 for ( auto & n
: aChildWins
)
1047 void SfxWorkWindow::SetObjectBar_Impl(sal_uInt16 nPos
, SfxVisibilityFlags nFlags
, ToolbarId eId
)
1049 DBG_ASSERT( nPos
< SFX_OBJECTBAR_MAX
, "object bar position overflow" );
1051 SfxObjectBar_Impl aObjBar
;
1053 aObjBar
.nMode
= nFlags
;
1055 for (SfxObjectBar_Impl
& rBar
: aObjBarList
)
1057 if ( rBar
.eId
== aObjBar
.eId
)
1064 aObjBarList
.push_back( aObjBar
);
1067 bool SfxWorkWindow::IsVisible_Impl( SfxVisibilityFlags nMode
) const
1069 switch( nUpdateMode
)
1071 case SfxVisibilityFlags::Standard
:
1073 case SfxVisibilityFlags::Invisible
:
1075 case SfxVisibilityFlags::Client
:
1076 case SfxVisibilityFlags::Server
:
1077 return bool(nMode
& nUpdateMode
);
1079 return (nMode
& nOrigMode
) ||
1080 nOrigMode
== SfxVisibilityFlags::Standard
;
1084 void SfxWorkWindow::UpdateObjectBars_Impl()
1086 if ( pFrame
->IsClosing_Impl() )
1089 UpdateObjectBars_Impl2();
1092 ArrangeChildren_Impl( false );
1094 ShowChildren_Impl();
1097 ShowChildren_Impl();
1100 Reference
< css::task::XStatusIndicator
> SfxWorkWindow::GetStatusIndicator()
1102 Reference
< css::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
1103 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1104 Reference
< css::task::XStatusIndicator
> xStatusIndicator
;
1106 if ( xPropSet
.is() )
1108 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
1109 aValue
>>= xLayoutManager
;
1110 if ( xLayoutManager
.is() )
1112 xLayoutManager
->createElement( g_aProgressBarResName
);
1113 xLayoutManager
->showElement( g_aProgressBarResName
);
1115 Reference
< css::ui::XUIElement
> xProgressBar
=
1116 xLayoutManager
->getElement( g_aProgressBarResName
);
1117 if ( xProgressBar
.is() )
1119 xStatusIndicator
.set( xProgressBar
->getRealInterface(), UNO_QUERY
);
1124 return xStatusIndicator
;
1128 bool SfxWorkWindow::IsPluginMode( SfxObjectShell
const * pObjShell
)
1130 if ( pObjShell
&& pObjShell
->GetMedium() )
1132 const SfxBoolItem
* pViewOnlyItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pObjShell
->GetMedium()->GetItemSet(), SID_VIEWONLY
, false);
1133 if ( pViewOnlyItem
&& pViewOnlyItem
->GetValue() )
1141 css::uno::Reference
< css::frame::XFrame
> SfxWorkWindow::GetFrameInterface()
1143 css::uno::Reference
< css::frame::XFrame
> xFrame
;
1145 SfxDispatcher
* pDispatcher( GetBindings().GetDispatcher() );
1148 SfxViewFrame
* pViewFrame
= pDispatcher
->GetFrame();
1150 xFrame
= pViewFrame
->GetFrame().GetFrameInterface();
1157 void SfxWorkWindow::UpdateObjectBars_Impl2()
1159 // Lock SplitWindows (which means suppressing the Resize-Reaction of the
1161 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
1163 VclPtr
<SfxSplitWindow
> const & p
= pSplit
[n
];
1164 if (p
->GetWindowCount())
1168 Reference
< css::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
1169 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1171 if ( xPropSet
.is() )
1173 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
1174 aValue
>>= xLayoutManager
;
1177 if ( !xLayoutManager
.is() )
1180 bool bPluginMode( false );
1181 SfxDispatcher
* pDispatcher( GetBindings().GetDispatcher() );
1185 SfxViewFrame
* pViewFrame
= pDispatcher
->GetFrame();
1187 bPluginMode
= IsPluginMode( pViewFrame
->GetObjectShell() );
1190 // Iterate over all Toolboxes
1191 xLayoutManager
->lock();
1192 const bool isNotebookBarActive
= sfx2::SfxNotebookBar::IsActive();
1193 for ( auto const & n
: aObjBarList
)
1195 ToolbarId eId
= n
.eId
;
1196 bool bDestroy
= n
.bDestroy
;
1198 // Determine the valid mode for the ToolBox
1199 SfxVisibilityFlags nTbxMode
= n
.nMode
;
1200 bool bFullScreenTbx( nTbxMode
& SfxVisibilityFlags::FullScreen
);
1201 nTbxMode
&= ~SfxVisibilityFlags::FullScreen
;
1202 nTbxMode
&= ~SfxVisibilityFlags::Viewer
;
1204 // Is a ToolBox required in this context ?
1205 bool bModesMatching
= (nUpdateMode
!= SfxVisibilityFlags::Invisible
) && ((nTbxMode
& nUpdateMode
) == nUpdateMode
);
1206 if ( bDestroy
|| isNotebookBarActive
)
1208 OUString aTbxId
= g_aTbxTypeName
+ GetResourceURLFromToolbarId(eId
);
1209 xLayoutManager
->destroyElement( aTbxId
);
1211 else if ( eId
!= ToolbarId::None
&& ( ( bModesMatching
&& !bIsFullScreen
) ||
1212 ( bIsFullScreen
&& bFullScreenTbx
) ) )
1214 OUString aTbxId
= g_aTbxTypeName
+ GetResourceURLFromToolbarId(eId
);
1215 if ( !IsDockingAllowed() && !xLayoutManager
->isElementFloating( aTbxId
))
1216 xLayoutManager
->destroyElement( aTbxId
);
1219 xLayoutManager
->requestElement( aTbxId
);
1221 xLayoutManager
->lockWindow( aTbxId
);
1224 else if ( eId
!= ToolbarId::None
)
1226 // Delete the Toolbox at this Position if possible
1227 OUString aTbxId
= g_aTbxTypeName
+ GetResourceURLFromToolbarId(eId
);
1228 xLayoutManager
->destroyElement( aTbxId
);
1232 UpdateStatusBar_Impl();
1234 // unlocking automatically forces Layout
1235 xLayoutManager
->unlock();
1237 UpdateChildWindows_Impl();
1239 // Unlock the SplitWindows again
1240 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
1242 VclPtr
<SfxSplitWindow
> const & p
= pSplit
[n
];
1243 if (p
->GetWindowCount())
1248 void SfxWorkWindow::UpdateChildWindows_Impl()
1250 // tdf#100870, tdf#101320: don't use range-based for loop when
1251 // container is modified
1252 for ( size_t n
=0; n
<aChildWins
.size(); n
++ )
1254 // any current or in the context available Childwindows
1255 SfxChildWin_Impl
*pCW
= aChildWins
[n
].get();
1256 SfxChildWindow
*pChildWin
= pCW
->pWin
;
1257 bool bCreate
= false;
1258 if ( pCW
->nId
&& (pCW
->aInfo
.nFlags
& SfxChildWindowFlags::ALWAYSAVAILABLE
|| IsVisible_Impl( pCW
->nVisibility
) ) )
1260 // In the context is an appropriate ChildWindow allowed;
1261 // it is also turned on?
1262 if ( pChildWin
== nullptr && pCW
->bCreate
)
1264 // Internal docking is only used for embedding into another
1265 // container. We force the floating state of all floatable
1267 if ( !bInternalDockingAllowed
)
1269 // Special case for all non-floatable child windows. We have
1270 // to prevent the creation here!
1271 bCreate
= !( pCW
->aInfo
.nFlags
& SfxChildWindowFlags::FORCEDOCK
);
1273 else if ( !IsDockingAllowed() || bIsFullScreen
) // || !bInternalDocking )
1275 // In Presentation mode or FullScreen only FloatingWindows
1276 SfxChildAlignment eAlign
;
1277 if ( pCW
->aInfo
.GetExtraData_Impl( &eAlign
) )
1278 bCreate
= ( eAlign
== SfxChildAlignment::NOALIGNMENT
);
1283 if (pCW
->aInfo
.nFlags
& SfxChildWindowFlags::NEVERCLONE
)
1284 pCW
->bCreate
= bCreate
= false; // Don't create and remember that we haven't created.
1286 // Currently, no window here, but it is enabled; windows
1287 // Create window and if possible theContext
1289 CreateChildWin_Impl( pCW
, false );
1291 if ( !bAllChildrenVisible
&& pCW
->pCli
)
1292 pCW
->pCli
->nVisible
&= ~SfxChildVisibility::ACTIVE
;
1294 else if ( pChildWin
)
1296 // Window already exists, it should also be visible?
1297 if ( ( !bIsFullScreen
|| pChildWin
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
) && bAllChildrenVisible
)
1299 // Update Mode is compatible; definitely enable it
1303 // The window is a direct Child
1304 if ((IsDockingAllowed() && bInternalDockingAllowed
)
1305 || pCW
->pCli
->eAlign
== SfxChildAlignment::NOALIGNMENT
)
1306 pCW
->pCli
->nVisible
|= SfxChildVisibility::NOT_HIDDEN
;
1310 if ( pCW
->bCreate
&& IsDockingAllowed() && bInternalDockingAllowed
)
1311 // The window ia within a SplitWindow
1312 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Reappear_Impl();
1318 if ( pChildWin
&& !bCreate
)
1320 if ( !pChildWin
->QueryClose() || pChildWin
->IsHideNotDelete() || Application::IsUICaptured() )
1324 if ( pCW
->pCli
->nVisible
& SfxChildVisibility::NOT_HIDDEN
)
1325 pCW
->pCli
->nVisible
^= SfxChildVisibility::NOT_HIDDEN
;
1328 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Disappear_Impl();
1331 RemoveChildWin_Impl( pCW
);
1336 void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl
*pCW
, bool bSetFocus
)
1338 pCW
->aInfo
.bVisible
= true;
1340 SfxChildWindow
*pChildWin
= SfxChildWindow::CreateChildWindow( pCW
->nId
, pWorkWin
, &GetBindings(), pCW
->aInfo
).release();
1345 bSetFocus
= pChildWin
->WantsFocus();
1346 pChildWin
->SetWorkWindow_Impl( this );
1348 // At least the extra string is changed during the evaluation,
1349 // also get it anewed
1350 SfxChildWinInfo aInfo
= pChildWin
->GetInfo();
1351 pCW
->aInfo
.aExtraString
= aInfo
.aExtraString
;
1352 pCW
->aInfo
.bVisible
= aInfo
.bVisible
;
1353 pCW
->aInfo
.nFlags
|= aInfo
.nFlags
;
1355 // The creation was successful
1356 GetBindings().Invalidate(pCW
->nId
);
1358 sal_uInt16 nPos
= pChildWin
->GetPosition();
1359 if (nPos
!= CHILDWIN_NOPOS
)
1361 DBG_ASSERT(nPos
< SFX_OBJECTBAR_MAX
, "Illegal objectbar position!");
1362 if ( aChildren
[TbxMatch(nPos
)] )// &&
1364 // ChildWindow replaces ObjectBar
1365 aChildren
[TbxMatch(nPos
)]->nVisible
^= SfxChildVisibility::NOT_HIDDEN
;
1369 // make childwin keyboard accessible
1370 pWorkWin
->GetSystemWindow()->GetTaskPaneList()->AddWindow( pChildWin
->GetWindow() );
1372 pCW
->pWin
= pChildWin
;
1374 if ( pChildWin
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
|| pChildWin
->GetWindow()->GetParent() == pWorkWin
)
1376 // The window is not docked or docked outside of one split windows
1377 // and must therefore be registered explicitly as a Child
1378 if (pChildWin
->GetController())
1379 pCW
->pCli
= RegisterChild_Impl(pChildWin
->GetController(), pChildWin
->GetAlignment());
1381 pCW
->pCli
= RegisterChild_Impl(*(pChildWin
->GetWindow()), pChildWin
->GetAlignment());
1382 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
;
1383 if ( pChildWin
->GetAlignment() != SfxChildAlignment::NOALIGNMENT
&& bIsFullScreen
)
1384 pCW
->pCli
->nVisible
^= SfxChildVisibility::ACTIVE
;
1385 pCW
->pCli
->bSetFocus
= bSetFocus
;
1389 // A docked window which parent is not a WorkingWindow, must lie
1390 // in a SplitWindow and thus not be explicitly registered.
1391 // This happens already in the initialization of SfxDockingWindows!
1394 // Save the information in the INI file
1395 SaveStatus_Impl(pChildWin
, pCW
->aInfo
);
1398 void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl
*pCW
)
1400 sal_uInt16 nId
= pCW
->nSaveId
;
1401 SfxChildWindow
*pChildWin
= pCW
->pWin
;
1403 // Save the information in the INI file
1404 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
1405 pCW
->aInfo
= pChildWin
->GetInfo();
1406 pCW
->aInfo
.nFlags
|= nFlags
;
1407 SaveStatus_Impl(pChildWin
, pCW
->aInfo
);
1413 // Child window is a direct child window and must therefore unregister
1414 // itself from the WorkWindow
1415 pCW
->pCli
= nullptr;
1416 if (pChildWin
->GetController())
1417 ReleaseChild_Impl(*pChildWin
->GetController());
1419 ReleaseChild_Impl(*pChildWin
->GetWindow());
1423 // ChildWindow is within a SplitWindow and unregister itself in
1427 pWorkWin
->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChildWin
->GetWindow() );
1428 pCW
->pWin
= nullptr;
1429 pChildWin
->Destroy();
1431 GetBindings().Invalidate( nId
);
1434 void SfxWorkWindow::ResetStatusBar_Impl()
1436 aStatBar
.eId
= StatusBarId::None
;
1439 void SfxWorkWindow::SetStatusBar_Impl(StatusBarId eId
)
1441 if (eId
!= StatusBarId::None
&& bShowStatusBar
&& IsVisible_Impl())
1445 void SfxWorkWindow::UpdateStatusBar_Impl()
1447 Reference
< css::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
1448 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1450 Any aValue
= xPropSet
->getPropertyValue( g_aLayoutManagerPropName
);
1451 aValue
>>= xLayoutManager
;
1453 // No status bar, if no ID is required or when in FullScreenView or
1455 if (aStatBar
.eId
!= StatusBarId::None
&& IsDockingAllowed() && bInternalDockingAllowed
&& bShowStatusBar
&&
1458 // Id has changed, thus create a suitable Statusbarmanager, this takes
1459 // over the current status bar;
1460 if ( xLayoutManager
.is() )
1461 xLayoutManager
->requestElement( g_aStatusBarResName
);
1465 // Destroy the current StatusBar
1466 // The Manager only creates the Status bar, does not destroy it.
1467 if ( xLayoutManager
.is() )
1468 xLayoutManager
->destroyElement( g_aStatusBarResName
);
1472 void SfxWorkWindow::MakeVisible_Impl( bool bVis
)
1475 nOrigMode
= SfxVisibilityFlags::Standard
;
1477 nOrigMode
= SfxVisibilityFlags::Invisible
;
1479 if ( nOrigMode
!= nUpdateMode
)
1480 nUpdateMode
= nOrigMode
;
1483 bool SfxWorkWindow::IsVisible_Impl() const
1485 return nOrigMode
!= SfxVisibilityFlags::Invisible
;
1489 void SfxWorkWindow::HidePopups_Impl(bool bHide
, sal_uInt16 nId
)
1491 if (comphelper::LibreOfficeKit::isActive() && bHide
)
1494 for (const std::unique_ptr
<SfxChildWin_Impl
>& i
: aChildWins
)
1496 SfxChildWindow
*pCW
= i
->pWin
;
1497 if (pCW
&& pCW
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
&& pCW
->GetType() != nId
)
1499 vcl::Window
*pWin
= pCW
->GetWindow();
1500 SfxChild_Impl
*pChild
= FindChild_Impl(pWin
);
1503 SAL_WARN("sfx.appl", "missing SfxChild_Impl child!");
1508 pChild
->nVisible
&= ~SfxChildVisibility::ACTIVE
;
1511 else if ( !comphelper::LibreOfficeKit::isActive() ||
1512 SfxChildVisibility::ACTIVE
!= (pChild
->nVisible
& SfxChildVisibility::ACTIVE
) )
1514 pChild
->nVisible
|= SfxChildVisibility::ACTIVE
;
1515 if ( SfxChildVisibility::VISIBLE
== (pChild
->nVisible
& SfxChildVisibility::VISIBLE
) )
1516 pCW
->Show( ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
1523 void SfxWorkWindow::ConfigChild_Impl(SfxChildIdentifier eChild
,
1524 SfxDockingConfig eConfig
, sal_uInt16 nId
)
1526 SfxDockingWindow
* pDockWin
=nullptr;
1527 sal_uInt16 nPos
= USHRT_MAX
;
1528 vcl::Window
*pWin
=nullptr;
1529 SfxChildWin_Impl
*pCW
= nullptr;
1531 // configure direct childwindow
1532 for (const std::unique_ptr
<SfxChildWin_Impl
>& i
: aChildWins
)
1535 SfxChildWindow
*pChild
= pCW
->pWin
;
1536 if ( pChild
&& (pChild
->GetType() == nId
))
1538 if (SfxDockingWindow
* pSfxDockingWindow
= dynamic_cast<SfxDockingWindow
*>(pChild
->GetWindow()))
1540 // it's a DockingWindow
1541 pDockWin
= pSfxDockingWindow
;
1545 // FloatingWindow or ModelessDialog
1546 pWin
= pChild
->GetWindow();
1554 if ( eChild
== SfxChildIdentifier::DOCKINGWINDOW
|| pDockWin
->GetAlignment() == SfxChildAlignment::NOALIGNMENT
)
1556 if ( eChild
== SfxChildIdentifier::SPLITWINDOW
&& eConfig
== SfxDockingConfig::TOGGLEFLOATMODE
)
1558 // DockingWindow was dragged out of a SplitWindow
1559 pCW
->pCli
= RegisterChild_Impl(*pDockWin
, pDockWin
->GetAlignment());
1560 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
;
1567 SfxSplitWindow
*pSplitWin
= GetSplitWindow_Impl(pDockWin
->GetAlignment());
1569 // configure DockingWindow inside a SplitWindow
1570 if ( eConfig
== SfxDockingConfig::TOGGLEFLOATMODE
)
1572 // DockingWindow was dragged into a SplitWindow
1573 pCW
->pCli
= nullptr;
1574 ReleaseChild_Impl(*pDockWin
);
1577 pWin
= pSplitWin
->GetSplitWindow();
1578 if ( pSplitWin
->GetWindowCount() == 1 )
1579 static_cast<SplitWindow
*>(pWin
)->Show( true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
1583 DBG_ASSERT( pCW
, "Unknown window!" );
1586 // windows may have been registered and released without an update until now
1589 decltype(aSortedList
)::size_type n
;
1590 for ( n
=0; n
<aSortedList
.size(); ++n
)
1592 SfxChild_Impl
*pChild
= aChildren
[aSortedList
[n
]].get();
1593 if ( pChild
&& pChild
->pWin
== pWin
)
1597 if ( n
< aSortedList
.size() )
1598 // sometimes called while toggling float mode
1599 nPos
= aSortedList
[n
];
1603 case SfxDockingConfig::SETDOCKINGRECTS
:
1605 if (nPos
== USHRT_MAX
|| !pDockWin
)
1608 tools::Rectangle
aOuterRect( GetTopRect_Impl() );
1609 aOuterRect
.SetPos( pWorkWin
->OutputToScreenPixel( aOuterRect
.TopLeft() ));
1610 tools::Rectangle
aInnerRect( aOuterRect
);
1612 // The current affected window is included in the calculation of
1613 // the inner rectangle!
1614 for (sal_uInt16 i
: aSortedList
)
1616 SfxChild_Impl
* pCli
= aChildren
[i
].get();
1618 if ( pCli
&& pCli
->nVisible
== SfxChildVisibility::VISIBLE
&& pCli
->pWin
)
1620 switch ( pCli
->eAlign
)
1622 case SfxChildAlignment::TOP
:
1623 // Object-Toolboxes come always last
1624 aInnerRect
.AdjustTop(pCli
->aSize
.Height() );
1627 case SfxChildAlignment::HIGHESTTOP
:
1628 // Always performed first
1629 aInnerRect
.AdjustTop(pCli
->aSize
.Height() );
1632 case SfxChildAlignment::LOWESTTOP
:
1633 // Is only counted if it is the current window
1635 aInnerRect
.AdjustTop(pCli
->aSize
.Height() );
1638 case SfxChildAlignment::BOTTOM
:
1639 // Object-Toolboxes come always last
1640 aInnerRect
.AdjustBottom( -(pCli
->aSize
.Height()) );
1643 case SfxChildAlignment::LOWESTBOTTOM
:
1644 // Always performed first
1645 aInnerRect
.AdjustBottom( -(pCli
->aSize
.Height()) );
1648 case SfxChildAlignment::HIGHESTBOTTOM
:
1649 // Is only counted if it is the current window
1651 aInnerRect
.AdjustBottom( -(pCli
->aSize
.Height()) );
1654 case SfxChildAlignment::LEFT
:
1655 // Toolboxes come always last
1656 aInnerRect
.AdjustLeft(pCli
->aSize
.Width() );
1659 case SfxChildAlignment::FIRSTLEFT
:
1660 // Always performed first
1661 aInnerRect
.AdjustLeft(pCli
->aSize
.Width() );
1664 case SfxChildAlignment::LASTLEFT
:
1665 // Is only counted if it is the current window
1667 aInnerRect
.AdjustLeft(pCli
->aSize
.Width() );
1670 case SfxChildAlignment::RIGHT
:
1671 // Toolboxes come always last
1672 aInnerRect
.AdjustRight( -(pCli
->aSize
.Width()) );
1675 case SfxChildAlignment::FIRSTRIGHT
:
1676 // Is only counted if it is the current window
1678 aInnerRect
.AdjustRight( -(pCli
->aSize
.Width()) );
1681 case SfxChildAlignment::LASTRIGHT
:
1682 // Always performed first
1683 aInnerRect
.AdjustRight( -(pCli
->aSize
.Width()) );
1692 pDockWin
->SetDockingRects(aOuterRect
, aInnerRect
);
1696 case SfxDockingConfig::ALIGNDOCKINGWINDOW
:
1697 case SfxDockingConfig::TOGGLEFLOATMODE
:
1699 if ( nPos
== USHRT_MAX
&& !pCW
)
1702 SfxChildAlignment eAlign
= SfxChildAlignment::NOALIGNMENT
;
1703 SfxChild_Impl
*pCli
= ( nPos
!= USHRT_MAX
) ? aChildren
[nPos
].get() : nullptr;
1704 if ( pCli
&& pDockWin
)
1706 eAlign
= pDockWin
->GetAlignment();
1707 if ( eChild
== SfxChildIdentifier::DOCKINGWINDOW
|| eAlign
== SfxChildAlignment::NOALIGNMENT
)
1709 // configuration inside the SplitWindow, no change for the SplitWindows' configuration
1710 pCli
->bResize
= true;
1711 pCli
->aSize
= pDockWin
->GetSizePixel();
1717 if( pCli
->eAlign
!= eAlign
)
1720 pCli
->eAlign
= eAlign
;
1723 ArrangeChildren_Impl();
1724 ShowChildren_Impl();
1727 if ( pCW
&& pCW
->pWin
)
1729 // store changed configuration
1730 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
1731 pCW
->aInfo
= pCW
->pWin
->GetInfo();
1732 pCW
->aInfo
.nFlags
|= nFlags
;
1733 SaveStatus_Impl( pCW
->pWin
, pCW
->aInfo
);
1742 void SfxWorkWindow::SetChildWindowVisible_Impl( sal_uInt32 lId
, bool bEnabled
, SfxVisibilityFlags nMode
)
1744 sal_uInt16 nId
= static_cast<sal_uInt16
>( lId
& 0xFFFF );
1746 SfxChildWin_Impl
*pCW
=nullptr;
1750 // If no Parent or the Parent us still unknown, then search here
1751 sal_uInt16 nCount
= aChildWins
.size();
1752 for (sal_uInt16 n
=0; n
<nCount
; n
++)
1753 if (aChildWins
[n
]->nSaveId
== nId
)
1755 pCW
= aChildWins
[n
].get();
1762 // If new, then initialize, add this here depending on the flag or
1764 pCW
= new SfxChildWin_Impl( lId
);
1766 InitializeChild_Impl( pCW
);
1767 aChildWins
.push_back( std::unique_ptr
<SfxChildWin_Impl
>(pCW
) );
1771 pCW
->nVisibility
= nMode
;
1772 pCW
->bEnable
= bEnabled
;
1776 // The on/off status of a ChildWindow is switched
1778 void SfxWorkWindow::ToggleChildWindow_Impl(sal_uInt16 nId
, bool bSetFocus
)
1780 sal_uInt16 nCount
= aChildWins
.size();
1782 for (n
=0; n
<nCount
; n
++)
1783 if (aChildWins
[n
]->nId
== nId
)
1788 // The Window is already known
1789 SfxChildWin_Impl
*pCW
= aChildWins
[n
].get();
1790 SfxChildWindow
*pChild
= pCW
->pWin
;
1792 bool bCreationAllowed( true );
1793 if ( !bInternalDockingAllowed
)
1795 // Special case for all non-floatable child windows. We have
1796 // to prevent the creation here!
1797 bCreationAllowed
= !( pCW
->aInfo
.nFlags
& SfxChildWindowFlags::FORCEDOCK
);
1800 if ( bCreationAllowed
)
1806 if ( pChild
->QueryClose() )
1808 pCW
->bCreate
= false;
1809 // The Window should be switched off
1810 pChild
->SetVisible_Impl( false );
1811 RemoveChildWin_Impl( pCW
);
1816 // no actual Window exists, yet => just remember the "switched off" state
1817 pCW
->bCreate
= false;
1822 pCW
->bCreate
= true;
1825 ShowChildWindow_Impl( nId
, true, bSetFocus
);
1829 // create actual Window
1830 CreateChildWin_Impl( pCW
, bSetFocus
);
1833 pCW
->bCreate
= false;
1838 ArrangeChildren_Impl();
1839 ShowChildren_Impl();
1841 if ( pCW
->bCreate
&& bCreationAllowed
)
1845 SfxDockingWindow
*pDock
=
1846 static_cast<SfxDockingWindow
*>( pCW
->pWin
->GetWindow() );
1847 if ( pDock
->IsAutoHide_Impl() )
1848 pDock
->AutoShow_Impl();
1856 nCount
= aChildWins
.size();
1857 for (n
=0; n
<nCount
; n
++)
1858 if (aChildWins
[n
]->nSaveId
== nId
)
1863 OSL_FAIL("The ChildWindow is not in context!");
1867 OSL_FAIL("The ChildWindow is not registered!");
1873 bool SfxWorkWindow::HasChildWindow_Impl(sal_uInt16 nId
)
1875 sal_uInt16 nCount
= aChildWins
.size();
1877 for (n
=0; n
<nCount
; n
++)
1878 if (aChildWins
[n
]->nSaveId
== nId
)
1883 SfxChildWin_Impl
*pCW
= aChildWins
[n
].get();
1884 SfxChildWindow
*pChild
= pCW
->pWin
;
1885 return ( pChild
&& pCW
->bCreate
);
1891 bool SfxWorkWindow::IsFloating( sal_uInt16 nId
)
1893 SfxChildWin_Impl
*pCW
=nullptr;
1897 // If no Parent or the Parent us still unknown, then search here
1898 sal_uInt16 nCount
= aChildWins
.size();
1899 for (sal_uInt16 n
=0; n
<nCount
; n
++)
1900 if (aChildWins
[n
]->nSaveId
== nId
)
1902 pCW
= aChildWins
[n
].get();
1909 // If new, then initialize, add this here depending on the flag or
1911 pCW
= new SfxChildWin_Impl( nId
);
1912 pCW
->bEnable
= false;
1914 pCW
->nVisibility
= SfxVisibilityFlags::Invisible
;
1915 InitializeChild_Impl( pCW
);
1916 aChildWins
.push_back( std::unique_ptr
<SfxChildWin_Impl
>(pCW
) );
1919 SfxChildAlignment eAlign
;
1920 if ( pCW
->aInfo
.GetExtraData_Impl( &eAlign
) )
1921 return( eAlign
== SfxChildAlignment::NOALIGNMENT
);
1927 bool SfxWorkWindow::KnowsChildWindow_Impl(sal_uInt16 nId
)
1929 SfxChildWin_Impl
*pCW
=nullptr;
1930 sal_uInt16 nCount
= aChildWins
.size();
1932 for (n
=0; n
<nCount
; n
++)
1934 pCW
= aChildWins
[n
].get();
1935 if ( pCW
->nSaveId
== nId
)
1941 if ( !(pCW
->aInfo
.nFlags
& SfxChildWindowFlags::ALWAYSAVAILABLE
) && !IsVisible_Impl( pCW
->nVisibility
) )
1943 return pCW
->bEnable
;
1950 void SfxWorkWindow::SetChildWindow_Impl(sal_uInt16 nId
, bool bOn
, bool bSetFocus
)
1952 SfxChildWin_Impl
*pCW
=nullptr;
1953 SfxWorkWindow
*pWork
= nullptr;
1957 // If no Parent or the Parent us still unknown, then search here
1958 sal_uInt16 nCount
= aChildWins
.size();
1959 for (sal_uInt16 n
=0; n
<nCount
; n
++)
1960 if (aChildWins
[n
]->nSaveId
== nId
)
1962 pCW
= aChildWins
[n
].get();
1970 // If new, then initialize, add this here depending on the flag or
1972 pCW
= new SfxChildWin_Impl( nId
);
1973 InitializeChild_Impl( pCW
);
1974 if ( !pWork
|| pCW
->aInfo
.nFlags
& SfxChildWindowFlags::TASK
)
1976 pWork
->aChildWins
.push_back( std::unique_ptr
<SfxChildWin_Impl
>(pCW
) );
1979 if ( pCW
->bCreate
!= bOn
)
1980 pWork
->ToggleChildWindow_Impl(nId
,bSetFocus
);
1984 void SfxWorkWindow::ShowChildWindow_Impl(sal_uInt16 nId
, bool bVisible
, bool bSetFocus
)
1986 sal_uInt16 nCount
= aChildWins
.size();
1987 SfxChildWin_Impl
* pCW
=nullptr;
1989 for (n
=0; n
<nCount
; n
++)
1991 pCW
= aChildWins
[n
].get();
1992 if (pCW
->nId
== nId
)
1998 SfxChildWindow
*pChildWin
= pCW
->pWin
;
2005 pCW
->pCli
->bSetFocus
= bSetFocus
;
2006 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
;
2007 pChildWin
->Show( bSetFocus
&& pChildWin
->WantsFocus() ? ShowFlags::NONE
: ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
2010 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Reappear_Impl();
2017 pCW
->pCli
->nVisible
= SfxChildVisibility::VISIBLE
^ SfxChildVisibility::NOT_HIDDEN
;
2021 static_cast<SfxDockingWindow
*>(pChildWin
->GetWindow())->Disappear_Impl();
2025 ArrangeChildren_Impl();
2026 ShowChildren_Impl();
2028 else if ( bVisible
)
2030 SetChildWindow_Impl( nId
, true, bSetFocus
);
2031 pChildWin
= pCW
->pWin
;
2036 pChildWin
->SetVisible_Impl( bVisible
);
2037 SfxChildWindowFlags nFlags
= pCW
->aInfo
.nFlags
;
2038 pCW
->aInfo
= pChildWin
->GetInfo();
2039 pCW
->aInfo
.nFlags
|= nFlags
;
2040 if ( !pCW
->bCreate
)
2041 SaveStatus_Impl( pChildWin
, pCW
->aInfo
);
2048 nCount
= aChildWins
.size();
2049 for (n
=0; n
<nCount
; n
++)
2050 if (aChildWins
[n
]->nSaveId
== nId
)
2055 OSL_FAIL("The ChildWindow is not in context!");
2059 OSL_FAIL("The ChildWindow is not registered");
2065 SfxChildWindow
* SfxWorkWindow::GetChildWindow_Impl(sal_uInt16 nId
)
2067 sal_uInt16 nCount
= aChildWins
.size();
2069 for (n
=0; n
<nCount
; n
++)
2070 if (aChildWins
[n
]->nSaveId
== nId
)
2074 return aChildWins
[n
]->pWin
;
2079 void SfxWorkWindow::ResetChildWindows_Impl()
2081 for (std::unique_ptr
<SfxChildWin_Impl
>& pChildWin
: aChildWins
)
2084 pChildWin
->bEnable
= false;
2088 // returns the size of the area (client area) of the
2089 // parent windows, in which the ChildWindow can be fitted.
2091 tools::Rectangle
SfxWorkWindow::GetTopRect_Impl() const
2093 return pMasterFrame
->GetTopOuterRectPixel_Impl();
2097 // Virtual method to find out if there is room for a ChildWindow in the
2098 // client area of the parent.
2100 bool SfxWorkWindow::RequestTopToolSpacePixel_Impl( SvBorder aBorder
)
2102 return !(!IsDockingAllowed() ||
2103 aClientArea
.GetWidth() < aBorder
.Left() + aBorder
.Right() ||
2104 aClientArea
.GetHeight() < aBorder
.Top() + aBorder
.Bottom());
2107 void SfxWorkWindow::SaveStatus_Impl(SfxChildWindow
*pChild
, const SfxChildWinInfo
&rInfo
)
2109 // The Status of the Presentation mode is not saved
2110 if ( IsDockingAllowed() && bInternalDockingAllowed
)
2111 pChild
->SaveStatus(rInfo
);
2114 void SfxWorkWindow::InitializeChild_Impl(SfxChildWin_Impl
*pCW
)
2116 SfxDispatcher
*pDisp
= pBindings
->GetDispatcher_Impl();
2117 SfxViewFrame
*pViewFrame
= pDisp
? pDisp
->GetFrame() :nullptr;
2118 SfxModule
*pMod
= pViewFrame
? SfxModule::GetActiveModule(pViewFrame
) :nullptr;
2125 uno::Reference
< frame::XModuleManager2
> xModuleManager(
2126 frame::ModuleManager::create(::comphelper::getProcessComponentContext()));
2127 sModule
= xModuleManager
->identify(pViewFrame
->GetFrame().GetFrameInterface());
2128 SvtModuleOptions::EFactory eFac
= SvtModuleOptions::ClassifyFactoryByServiceName(sModule
);
2129 sModule
= SvtModuleOptions::GetFactoryShortName(eFac
);
2136 SfxChildWinFactory
* pFact
=nullptr;
2137 SfxApplication
*pApp
= SfxGetpApp();
2139 pFact
= pApp
->GetChildWinFactoryById(pCW
->nSaveId
);
2142 pCW
->aInfo
= pFact
->aInfo
;
2143 pCW
->aInfo
.aModule
= sModule
;
2144 SfxChildWindow::InitializeChildWinFactory_Impl(
2145 pCW
->nSaveId
, pCW
->aInfo
);
2146 pCW
->bCreate
= pCW
->aInfo
.bVisible
;
2147 SfxChildWindowFlags nFlags
= pFact
->aInfo
.nFlags
;
2148 if ( nFlags
& SfxChildWindowFlags::TASK
)
2149 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::TASK
;
2150 if ( nFlags
& SfxChildWindowFlags::CANTGETFOCUS
)
2151 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::CANTGETFOCUS
;
2152 if ( nFlags
& SfxChildWindowFlags::FORCEDOCK
)
2153 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::FORCEDOCK
;
2154 pFact
->aInfo
= pCW
->aInfo
;
2162 pFact
= pMod
->GetChildWinFactoryById(pCW
->nSaveId
);
2166 pCW
->aInfo
= pFact
->aInfo
;
2167 pCW
->aInfo
.aModule
= sModule
;
2168 SfxChildWindow::InitializeChildWinFactory_Impl(
2169 pCW
->nSaveId
, pCW
->aInfo
);
2170 pCW
->bCreate
= pCW
->aInfo
.bVisible
;
2171 SfxChildWindowFlags nFlags
= pFact
->aInfo
.nFlags
;
2172 if ( nFlags
& SfxChildWindowFlags::TASK
)
2173 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::TASK
;
2174 if ( nFlags
& SfxChildWindowFlags::CANTGETFOCUS
)
2175 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::CANTGETFOCUS
;
2176 if ( nFlags
& SfxChildWindowFlags::FORCEDOCK
)
2177 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::FORCEDOCK
;
2178 if ( nFlags
& SfxChildWindowFlags::ALWAYSAVAILABLE
)
2179 pCW
->aInfo
.nFlags
|= SfxChildWindowFlags::ALWAYSAVAILABLE
;
2180 pFact
->aInfo
= pCW
->aInfo
;
2183 SfxSplitWindow
* SfxWorkWindow::GetSplitWindow_Impl( SfxChildAlignment eAlign
)
2187 case SfxChildAlignment::TOP
:
2190 case SfxChildAlignment::BOTTOM
:
2193 case SfxChildAlignment::LEFT
:
2196 case SfxChildAlignment::RIGHT
:
2204 void SfxWorkWindow::MakeChildrenVisible_Impl( bool bVis
)
2206 bAllChildrenVisible
= bVis
;
2211 for (sal_uInt16 n
: aSortedList
)
2213 SfxChild_Impl
* pCli
= aChildren
[n
].get();
2214 if ( (pCli
->eAlign
== SfxChildAlignment::NOALIGNMENT
) || (IsDockingAllowed() && bInternalDockingAllowed
) )
2215 pCli
->nVisible
|= SfxChildVisibility::ACTIVE
;
2222 for (sal_uInt16 n
: aSortedList
)
2224 SfxChild_Impl
* pCli
= aChildren
[n
].get();
2225 pCli
->nVisible
&= ~SfxChildVisibility::ACTIVE
;
2230 bool SfxWorkWindow::IsAutoHideMode( const SfxSplitWindow
*pSplitWin
)
2232 for (const VclPtr
<SfxSplitWindow
> & pWin
: pSplit
)
2234 if ( pWin
.get() != pSplitWin
&& pWin
->IsAutoHide( true ) )
2241 void SfxWorkWindow::EndAutoShow_Impl( Point aPos
)
2243 for (VclPtr
<SfxSplitWindow
> & p
: pSplit
)
2245 if ( p
&& p
->IsAutoHide(false) )
2247 Point aLocalPos
= p
->ScreenToOutputPixel( aPos
);
2248 tools::Rectangle
aRect( Point(), p
->GetSizePixel() );
2249 if ( !aRect
.Contains( aLocalPos
) )
2255 void SfxWorkWindow::ArrangeAutoHideWindows( SfxSplitWindow
*pActSplitWin
)
2260 tools::Rectangle
aArea( aUpperClientArea
);
2261 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
2263 // Either dummy window or window in the auto-show-mode are processed
2264 // (not pinned, FadeIn).
2265 // Only the abandoned window may be invisible, because perhaps its
2266 // size is just being calculated before it is displayed.
2267 VclPtr
<SfxSplitWindow
> const & pSplitWin
= pSplit
[n
];
2268 bool bDummyWindow
= !pSplitWin
->IsFadeIn();
2269 vcl::Window
*pDummy
= pSplitWin
->GetSplitWindow();
2270 vcl::Window
*pWin
= bDummyWindow
? pDummy
: pSplitWin
;
2271 if ( (pSplitWin
->IsPinned() && !bDummyWindow
) || (!pWin
->IsVisible() && pActSplitWin
!= pSplitWin
) )
2274 // Width and position of the dummy window as a starting point
2275 Size aSize
= pDummy
->GetSizePixel();
2276 Point aPos
= pDummy
->GetPosPixel();
2283 // Get the width of the Window yourself, if no DummyWindow
2284 if ( !bDummyWindow
)
2285 aSize
.setWidth( pSplitWin
->GetSizePixel().Width() );
2287 // If a Window is visible to the left, then the free region
2288 // starts to the right from it, for example at the Client area
2289 tools::Long nLeft
= aPos
.X() + aSize
.Width();
2290 if ( nLeft
> aArea
.Left() )
2291 aArea
.SetLeft( nLeft
);
2296 // Right SplitWindow
2297 // Position to correct the difference of the widths
2298 aPos
.AdjustX(aSize
.Width() );
2300 // Get the width of the Window yourself, if no DummyWindow
2301 if ( !bDummyWindow
)
2302 aSize
.setWidth( pSplitWin
->GetSizePixel().Width() );
2304 aPos
.AdjustX( -(aSize
.Width()) );
2306 // If already a window is opened at the left side, then the
2307 // right is not allowed to overlap this one.
2308 if ( aPos
.X() < aArea
.Left() )
2310 aPos
.setX( aArea
.Left() );
2311 aSize
.setWidth( aArea
.GetWidth() );
2314 // If a Window is visible to the right, then the free region
2315 // starts to the left from it, for example at the Client area
2316 tools::Long nRight
= aPos
.X();
2317 if ( !aArea
.IsWidthEmpty() && nRight
< aArea
.Right() )
2318 aArea
.SetRight( nRight
);
2324 // Get the height of the Window yourself, if no DummyWindow
2325 if ( !bDummyWindow
)
2326 aSize
.setHeight( pSplitWin
->GetSizePixel().Height() );
2329 // Adjust width with regard to if a Window is already open
2330 // to the left or right
2331 aPos
.setX( aArea
.Left() );
2332 aSize
.setWidth( aArea
.GetWidth() );
2334 // If a Window is visible at the top, then the free region
2335 // starts beneath it, for example at the Client area
2336 tools::Long nTop
= aPos
.Y() + aSize
.Height();
2337 if ( nTop
> aArea
.Top() )
2338 aArea
.SetTop( nTop
);
2343 // The bottom SplitWindow
2344 // Position to correct the difference of the heights
2345 aPos
.AdjustY(aSize
.Height() );
2347 // Get the height of the Window yourself, if no DummyWindow
2348 if ( !bDummyWindow
)
2349 aSize
.setHeight( pSplitWin
->GetSizePixel().Height() );
2351 aPos
.AdjustY( -(aSize
.Height()) );
2353 // Adjust width with regard to if a Window is already open
2354 // to the left or right.
2355 aPos
.setX( aArea
.Left() );
2356 aSize
.setWidth( aArea
.GetWidth() );
2358 // If already a window is opened at the top, then the
2359 // bottom one is not allowed to overlap this one.
2360 if ( aPos
.Y() < aArea
.Top() )
2362 aPos
.setY( aArea
.Top() );
2363 aSize
.setHeight( aArea
.GetHeight() );
2370 if ( !bDummyWindow
)
2371 // the FadeIn-Window is a Floating window, which coordinates are
2372 // set in Screen coordinates.
2373 pSplitWin
->SetPosSizePixel( pWorkWin
->OutputToScreenPixel(aPos
), aSize
);
2375 // the docked DummyWindow
2376 pDummy
->SetPosSizePixel( aPos
, aSize
);
2380 tools::Rectangle
SfxWorkWindow::GetFreeArea( bool bAutoHide
) const
2384 tools::Rectangle
aArea( aClientArea
);
2385 for ( sal_uInt16 n
=0; n
<SFX_SPLITWINDOWS_MAX
; n
++ )
2387 if ( pSplit
[n
]->IsPinned() || !pSplit
[n
]->IsVisible() )
2390 Size aSize
= pSplit
[n
]->GetSizePixel();
2394 aArea
.AdjustLeft(aSize
.Width() );
2397 aArea
.AdjustRight( -(aSize
.Width()) );
2400 aArea
.AdjustTop(aSize
.Height() );
2403 aArea
.AdjustBottom( -(aSize
.Height()) );
2414 void SfxWorkWindow::SetActiveChild_Impl( vcl::Window
*pChild
)
2416 pActiveChild
= pChild
;
2419 void SfxWorkWindow::DataChanged_Impl()
2421 ArrangeChildren_Impl();
2424 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */