2355 lines
76 KiB
C++
2355 lines
76 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <config_features.h>
|
|
#include <config_feature_desktop.h>
|
|
#include <comphelper/configuration.hxx>
|
|
#include <comphelper/lok.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <sal/log.hxx>
|
|
#include <sfx2/docfile.hxx>
|
|
#include <sfx2/objface.hxx>
|
|
#include <sfx2/objsh.hxx>
|
|
#include <sfx2/app.hxx>
|
|
#include <workwin.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <sfx2/module.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/dockwin.hxx>
|
|
#include <sfx2/viewsh.hxx>
|
|
#include <splitwin.hxx>
|
|
#include <sfx2/sfxsids.hrc>
|
|
#include <sfx2/toolbarids.hxx>
|
|
#include <vcl/taskpanelist.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <svl/eitem.hxx>
|
|
#include <tools/svborder.hxx>
|
|
#include <tools/debug.hxx>
|
|
#include <unotools/configmgr.hxx>
|
|
#include <unotools/moduleoptions.hxx>
|
|
#include <com/sun/star/ui/XUIElement.hpp>
|
|
#include <com/sun/star/frame/LayoutManagerEvents.hpp>
|
|
#include <com/sun/star/frame/ModuleManager.hpp>
|
|
#include <com/sun/star/frame/XLayoutManager.hpp>
|
|
#include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/lang/DisposedException.hpp>
|
|
#include <type_traits>
|
|
#include <unordered_map>
|
|
#include <sfx2/notebookbar/SfxNotebookBar.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
namespace {
|
|
|
|
struct ResIdToResName
|
|
{
|
|
ToolbarId eId;
|
|
OUString pName;
|
|
};
|
|
|
|
}
|
|
|
|
constexpr ResIdToResName pToolBarResToName[] =
|
|
{
|
|
{ ToolbarId::FullScreenToolbox, u"fullscreenbar"_ustr },
|
|
{ ToolbarId::EnvToolbox, u"standardbar"_ustr, },
|
|
{ ToolbarId::SvxTbx_Form_Navigation, u"formsnavigationbar"_ustr },
|
|
{ ToolbarId::SvxTbx_Form_Filter, u"formsfilterbar"_ustr },
|
|
{ ToolbarId::SvxTbx_Text_Control_Attributes, u"formtextobjectbar"_ustr },
|
|
{ ToolbarId::SvxTbx_Controls, u"formcontrols"_ustr },
|
|
{ ToolbarId::SvxTbx_FormDesign, u"formdesign"_ustr },
|
|
{ ToolbarId::Math_Toolbox, u"toolbar"_ustr }, //math
|
|
{ ToolbarId::Text_Toolbox_Sc, u"textobjectbar"_ustr }, //calc
|
|
{ ToolbarId::Draw_Objectbar, u"drawobjectbar"_ustr },
|
|
{ ToolbarId::Graphic_Objectbar, u"graphicobjectbar"_ustr },
|
|
{ ToolbarId::Objectbar_Format, u"formatobjectbar"_ustr },
|
|
{ ToolbarId::Objectbar_Preview, u"previewbar"_ustr },
|
|
{ ToolbarId::Objectbar_Tools, u"toolbar"_ustr }, //calc
|
|
{ ToolbarId::Bezier_Toolbox_Sd, u"bezierobjectbar"_ustr }, //draw/impress
|
|
{ ToolbarId::Gluepoints_Toolbox, u"gluepointsobjectbar"_ustr },
|
|
{ ToolbarId::Draw_Graf_Toolbox, u"graphicobjectbar"_ustr },
|
|
{ ToolbarId::Draw_Obj_Toolbox, u"drawingobjectbar"_ustr }, //impress
|
|
{ ToolbarId::Draw_Text_Toolbox_Sd, u"textobjectbar"_ustr }, //impress
|
|
{ ToolbarId::Draw_Toolbox_Sd, u"toolbar"_ustr }, //impress
|
|
{ ToolbarId::Draw_Options_Toolbox, u"optionsbar"_ustr },
|
|
{ ToolbarId::Draw_CommonTask_Toolbox, u"commontaskbar"_ustr },
|
|
{ ToolbarId::Graphic_Obj_Toolbox, u"drawingobjectbar"_ustr }, //draw
|
|
{ ToolbarId::Outline_Toolbox, u"outlinetoolbar"_ustr }, //impress
|
|
{ ToolbarId::Slide_Toolbox, u"slideviewtoolbar"_ustr },
|
|
{ ToolbarId::Slide_Obj_Toolbox, u"slideviewobjectbar"_ustr },
|
|
{ ToolbarId::Bezier_Toolbox_Sw, u"bezierobjectbar"_ustr },
|
|
{ ToolbarId::Draw_Toolbox_Sw, u"drawingobjectbar"_ustr },
|
|
{ ToolbarId::Draw_Text_Toolbox_Sw, u"drawtextobjectbar"_ustr },
|
|
{ ToolbarId::Frame_Toolbox, u"frameobjectbar"_ustr },
|
|
{ ToolbarId::Grafik_Toolbox, u"graphicobjectbar"_ustr },
|
|
{ ToolbarId::Num_Toolbox, u"numobjectbar"_ustr },
|
|
{ ToolbarId::Ole_Toolbox, u"oleobjectbar"_ustr },
|
|
{ ToolbarId::Table_Toolbox, u"tableobjectbar"_ustr },
|
|
{ ToolbarId::Text_Toolbox_Sw, u"textobjectbar"_ustr },
|
|
{ ToolbarId::PView_Toolbox, u"previewobjectbar"_ustr }, //writer
|
|
{ ToolbarId::Webtools_Toolbox, u"toolbar"_ustr }, //web
|
|
{ ToolbarId::Webtext_Toolbox, u"textobjectbar"_ustr },
|
|
{ ToolbarId::Tools_Toolbox, u"toolbar"_ustr }, //writer
|
|
{ ToolbarId::Webframe_Toolbox, u"frameobjectbar"_ustr }, //web
|
|
{ ToolbarId::Webgraphic_Toolbox, u"graphicobjectbar"_ustr },
|
|
{ ToolbarId::Webole_Toolbox, u"oleobjectbar"_ustr },
|
|
{ ToolbarId::Basicide_Objectbar, u"macrobar"_ustr },
|
|
{ ToolbarId::Svx_Fontwork_Bar, u"fontworkobjectbar"_ustr }, //global
|
|
{ ToolbarId::Svx_Extrusion_Bar, u"extrusionobjectbar"_ustr },
|
|
{ ToolbarId::FormLayer_Toolbox, u"formsobjectbar"_ustr },
|
|
{ ToolbarId::Module_Toolbox, u"viewerbar"_ustr }, //writer (plugin)
|
|
{ ToolbarId::Objectbar_App, u"viewerbar"_ustr }, //calc (plugin)
|
|
{ ToolbarId::Draw_Viewer_Toolbox, u"viewerbar"_ustr }, //impress(plugin)
|
|
{ ToolbarId::Draw_Media_Toolbox, u"mediaobjectbar"_ustr }, //draw/impress
|
|
{ ToolbarId::Media_Objectbar, u"mediaobjectbar"_ustr }, //calc
|
|
{ ToolbarId::Media_Toolbox, u"mediaobjectbar"_ustr }, //writer
|
|
{ ToolbarId::None, u""_ustr }
|
|
};
|
|
|
|
// Sort the Children according their alignment
|
|
// The order corresponds to the enum SfxChildAlignment (->CHILDWIN.HXX).
|
|
|
|
constexpr OUString g_aLayoutManagerPropName = u"LayoutManager"_ustr;
|
|
|
|
// Help to make changes to the alignment compatible!
|
|
LayoutManagerListener::LayoutManagerListener(
|
|
SfxWorkWindow* pWrkWin ) :
|
|
m_bHasFrame( false ),
|
|
m_pWrkWin( pWrkWin )
|
|
{
|
|
}
|
|
|
|
LayoutManagerListener::~LayoutManagerListener()
|
|
{
|
|
}
|
|
|
|
void LayoutManagerListener::setFrame( const css::uno::Reference< css::frame::XFrame >& xFrame )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if ( !m_pWrkWin || m_bHasFrame )
|
|
return;
|
|
|
|
m_xFrame = xFrame;
|
|
m_bHasFrame = true;
|
|
|
|
if ( !xFrame.is() )
|
|
return;
|
|
|
|
css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
|
|
css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager;
|
|
if ( !xPropSet.is() )
|
|
return;
|
|
|
|
try
|
|
{
|
|
Any aValue = xPropSet->getPropertyValue( g_aLayoutManagerPropName );
|
|
aValue >>= xLayoutManager;
|
|
|
|
if ( xLayoutManager.is() )
|
|
xLayoutManager->addLayoutManagerEventListener(
|
|
css::uno::Reference< css::frame::XLayoutManagerListener >(this) );
|
|
|
|
xPropSet.set( xLayoutManager, UNO_QUERY );
|
|
if ( xPropSet.is() )
|
|
{
|
|
aValue = xPropSet->getPropertyValue( u"LockCount"_ustr );
|
|
aValue >>= m_pWrkWin->m_nLock;
|
|
}
|
|
}
|
|
catch ( css::lang::DisposedException& )
|
|
{
|
|
}
|
|
catch ( const css::uno::RuntimeException& )
|
|
{
|
|
throw;
|
|
}
|
|
catch ( css::uno::Exception& )
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
// XComponent
|
|
|
|
void SAL_CALL LayoutManagerListener::addEventListener(
|
|
const css::uno::Reference< css::lang::XEventListener >& )
|
|
{
|
|
// do nothing, only internal class
|
|
}
|
|
|
|
void SAL_CALL LayoutManagerListener::removeEventListener(
|
|
const css::uno::Reference< css::lang::XEventListener >& )
|
|
{
|
|
// do nothing, only internal class
|
|
}
|
|
|
|
void SAL_CALL LayoutManagerListener::dispose()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
// reset member
|
|
m_pWrkWin = nullptr;
|
|
|
|
css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame.get(), css::uno::UNO_QUERY );
|
|
if ( !xFrame.is() )
|
|
return;
|
|
|
|
m_xFrame.clear();
|
|
m_bHasFrame = false;
|
|
|
|
css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
|
|
css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager;
|
|
if ( !xPropSet.is() )
|
|
return;
|
|
|
|
try
|
|
{
|
|
css::uno::Any aValue = xPropSet->getPropertyValue( g_aLayoutManagerPropName );
|
|
aValue >>= xLayoutManager;
|
|
|
|
// remove as listener from layout manager
|
|
if ( xLayoutManager.is() )
|
|
xLayoutManager->removeLayoutManagerEventListener(
|
|
css::uno::Reference< css::frame::XLayoutManagerListener >(this) );
|
|
}
|
|
catch ( css::lang::DisposedException& )
|
|
{
|
|
}
|
|
catch ( const css::uno::RuntimeException& )
|
|
{
|
|
throw;
|
|
}
|
|
catch ( css::uno::Exception& )
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
// XEventListener
|
|
|
|
void SAL_CALL LayoutManagerListener::disposing(
|
|
const css::lang::EventObject& )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
m_pWrkWin = nullptr;
|
|
m_bHasFrame = false;
|
|
m_xFrame.clear();
|
|
}
|
|
|
|
|
|
// XLayoutManagerEventListener
|
|
|
|
void SAL_CALL LayoutManagerListener::layoutEvent(
|
|
const css::lang::EventObject&,
|
|
::sal_Int16 eLayoutEvent,
|
|
const css::uno::Any& )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if ( !m_pWrkWin )
|
|
return;
|
|
|
|
if ( eLayoutEvent == css::frame::LayoutManagerEvents::VISIBLE )
|
|
{
|
|
m_pWrkWin->MakeVisible_Impl( true );
|
|
m_pWrkWin->ShowChildren_Impl();
|
|
m_pWrkWin->ArrangeChildren_Impl();
|
|
}
|
|
else if ( eLayoutEvent == css::frame::LayoutManagerEvents::INVISIBLE )
|
|
{
|
|
m_pWrkWin->MakeVisible_Impl( false );
|
|
m_pWrkWin->HideChildren_Impl();
|
|
m_pWrkWin->ArrangeChildren_Impl();
|
|
}
|
|
else if ( eLayoutEvent == css::frame::LayoutManagerEvents::LOCK )
|
|
{
|
|
m_pWrkWin->Lock_Impl( true );
|
|
}
|
|
else if ( eLayoutEvent == css::frame::LayoutManagerEvents::UNLOCK )
|
|
{
|
|
m_pWrkWin->Lock_Impl( false );
|
|
}
|
|
}
|
|
|
|
namespace
|
|
{
|
|
struct ToolbarIdHash
|
|
{
|
|
size_t operator()(ToolbarId t) const
|
|
{
|
|
typedef std::underlying_type<ToolbarId>::type underlying_type;
|
|
return std::hash<underlying_type>()(static_cast<underlying_type>(t));
|
|
}
|
|
};
|
|
|
|
class FilledToolBarResIdToResourceURLMap
|
|
{
|
|
private:
|
|
typedef std::unordered_map<ToolbarId, OUString, ToolbarIdHash> ToolBarResIdToResourceURLMap;
|
|
ToolBarResIdToResourceURLMap m_aResIdToResourceURLMap;
|
|
public:
|
|
FilledToolBarResIdToResourceURLMap()
|
|
{
|
|
sal_Int32 nIndex( 0 );
|
|
while (pToolBarResToName[nIndex].eId != ToolbarId::None)
|
|
{
|
|
OUString aResourceURL( pToolBarResToName[nIndex].pName );
|
|
m_aResIdToResourceURLMap.emplace(pToolBarResToName[nIndex].eId, aResourceURL);
|
|
++nIndex;
|
|
}
|
|
}
|
|
|
|
OUString findURL(ToolbarId eId) const
|
|
{
|
|
ToolBarResIdToResourceURLMap::const_iterator aIter = m_aResIdToResourceURLMap.find(eId);
|
|
if ( aIter != m_aResIdToResourceURLMap.end() )
|
|
return aIter->second;
|
|
return OUString();
|
|
}
|
|
};
|
|
}
|
|
|
|
static OUString GetResourceURLFromToolbarId(ToolbarId eId)
|
|
{
|
|
static FilledToolBarResIdToResourceURLMap theFilledToolBarResIdToResourceURLMap;
|
|
return theFilledToolBarResIdToResourceURLMap.findURL(eId);
|
|
}
|
|
|
|
static sal_uInt16 TbxMatch( sal_uInt16 nPos )
|
|
{
|
|
switch ( nPos )
|
|
{
|
|
case SFX_OBJECTBAR_APPLICATION :
|
|
return 0;
|
|
case SFX_OBJECTBAR_OPTIONS:
|
|
return 1;
|
|
case SFX_OBJECTBAR_MACRO:
|
|
return 2;
|
|
case SFX_OBJECTBAR_OBJECT:
|
|
return 3;
|
|
case SFX_OBJECTBAR_TOOLS:
|
|
return 4;
|
|
case SFX_OBJECTBAR_FULLSCREEN:
|
|
case SFX_OBJECTBAR_COMMONTASK:
|
|
case SFX_OBJECTBAR_RECORDING:
|
|
return nPos+1;
|
|
default:
|
|
return nPos;
|
|
}
|
|
}
|
|
|
|
static sal_uInt16 ChildAlignValue(SfxChildAlignment eAlign)
|
|
{
|
|
sal_uInt16 ret = 17;
|
|
|
|
switch (eAlign)
|
|
{
|
|
case SfxChildAlignment::HIGHESTTOP:
|
|
ret = 1;
|
|
break;
|
|
case SfxChildAlignment::LOWESTBOTTOM:
|
|
ret = 2;
|
|
break;
|
|
case SfxChildAlignment::FIRSTLEFT:
|
|
ret = 3;
|
|
break;
|
|
case SfxChildAlignment::LASTRIGHT:
|
|
ret = 4;
|
|
break;
|
|
case SfxChildAlignment::LEFT:
|
|
ret = 5;
|
|
break;
|
|
case SfxChildAlignment::RIGHT:
|
|
ret = 6;
|
|
break;
|
|
case SfxChildAlignment::FIRSTRIGHT:
|
|
ret = 7;
|
|
break;
|
|
case SfxChildAlignment::LASTLEFT:
|
|
ret = 8;
|
|
break;
|
|
case SfxChildAlignment::TOP:
|
|
ret = 9;
|
|
break;
|
|
case SfxChildAlignment::BOTTOM:
|
|
ret = 10;
|
|
break;
|
|
case SfxChildAlignment::TOOLBOXTOP:
|
|
ret = 11;
|
|
break;
|
|
case SfxChildAlignment::TOOLBOXBOTTOM:
|
|
ret = 12;
|
|
break;
|
|
case SfxChildAlignment::LOWESTTOP:
|
|
ret = 13;
|
|
break;
|
|
case SfxChildAlignment::HIGHESTBOTTOM:
|
|
ret = 14;
|
|
break;
|
|
case SfxChildAlignment::TOOLBOXLEFT:
|
|
ret = 15;
|
|
break;
|
|
case SfxChildAlignment::TOOLBOXRIGHT:
|
|
ret = 16;
|
|
break;
|
|
case SfxChildAlignment::NOALIGNMENT:
|
|
break; // -Wall not handled...
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void SfxWorkWindow::Sort_Impl()
|
|
{
|
|
aSortedList.clear();
|
|
for (size_t i = 0; i < aChildren.size(); ++i)
|
|
{
|
|
SfxChild_Impl *pCli = aChildren[i].get();
|
|
if (pCli)
|
|
{
|
|
decltype(aSortedList)::size_type k;
|
|
for (k=0; k<aSortedList.size(); k++)
|
|
if (ChildAlignValue( aChildren[aSortedList[k]]->eAlign ) >
|
|
ChildAlignValue(pCli->eAlign))
|
|
break;
|
|
aSortedList.insert( aSortedList.begin() + k, i );
|
|
}
|
|
}
|
|
|
|
bSorted = true;
|
|
}
|
|
|
|
constexpr OUString g_aStatusBarResName( u"private:resource/statusbar/statusbar"_ustr );
|
|
constexpr OUString g_aTbxTypeName( u"private:resource/toolbar/"_ustr );
|
|
constexpr OUString g_aProgressBarResName( u"private:resource/progressbar/progressbar"_ustr );
|
|
|
|
// constructor for workwin of a Frame
|
|
|
|
SfxWorkWindow::SfxWorkWindow( vcl::Window *pWin, SfxFrame *pFrm, SfxFrame* pMaster ) :
|
|
pBindings(&pFrm->GetCurrentViewFrame()->GetBindings()),
|
|
pWorkWin (pWin),
|
|
pActiveChild( nullptr ),
|
|
nUpdateMode(SfxVisibilityFlags::Standard),
|
|
nChildren( 0 ),
|
|
nOrigMode( SfxVisibilityFlags::Invisible ),
|
|
bSorted( true ),
|
|
bDockingAllowed(true),
|
|
bInternalDockingAllowed(true),
|
|
bAllChildrenVisible(true),
|
|
#if !defined(ANDROID) || HAVE_FEATURE_ANDROID_LOK
|
|
bIsFullScreen( false ),
|
|
#else // Fennec-based Android Viewer
|
|
bIsFullScreen( true ),
|
|
#endif
|
|
#if HAVE_FEATURE_DESKTOP
|
|
bShowStatusBar( true ),
|
|
#else
|
|
bShowStatusBar( sal_False ),
|
|
#endif
|
|
m_nLock( 0 ),
|
|
pMasterFrame( pMaster ),
|
|
pFrame( pFrm )
|
|
{
|
|
DBG_ASSERT (pBindings, "No Bindings!");
|
|
|
|
pBindings->SetWorkWindow_Impl( std::unique_ptr<SfxWorkWindow>(this) );
|
|
|
|
// For the ObjectBars an integral place in the Childlist is reserved,
|
|
// so that they always come in a defined order.
|
|
for (int i=0; i<SFX_OBJECTBAR_MAX; ++i)
|
|
aChildren.push_back( nullptr );
|
|
|
|
// create and initialize layout manager listener
|
|
Reference< css::frame::XFrame > xFrame = GetFrameInterface();
|
|
m_xLayoutManagerListener = new LayoutManagerListener( this );
|
|
m_xLayoutManagerListener->setFrame( xFrame );
|
|
|
|
SfxShell* pConfigShell = pFrm->GetCurrentViewFrame();
|
|
if ( pConfigShell && pConfigShell->GetObjectShell() )
|
|
{
|
|
bShowStatusBar = ( !pConfigShell->GetObjectShell()->IsInPlaceActive() );
|
|
bDockingAllowed = true;
|
|
bInternalDockingAllowed = true;
|
|
}
|
|
|
|
// The required split windows (one for each side) can be created
|
|
for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
|
|
{
|
|
// The SplitWindows excludes direct ChildWindows of the WorkWindows
|
|
// and receives the docked window.
|
|
|
|
SfxChildAlignment eAlign =
|
|
( n == SFX_SPLITWINDOWS_LEFT ? SfxChildAlignment::LEFT :
|
|
n == SFX_SPLITWINDOWS_RIGHT ? SfxChildAlignment::RIGHT :
|
|
n == SFX_SPLITWINDOWS_TOP ? SfxChildAlignment::TOP :
|
|
SfxChildAlignment::BOTTOM );
|
|
pSplit[n] = VclPtr<SfxSplitWindow>::Create(pWorkWin, eAlign, this, true );
|
|
}
|
|
|
|
nOrigMode = SfxVisibilityFlags::Standard;
|
|
nUpdateMode = SfxVisibilityFlags::Standard;
|
|
}
|
|
|
|
|
|
// Destructor
|
|
|
|
SfxWorkWindow::~SfxWorkWindow()
|
|
{
|
|
|
|
// Delete SplitWindows
|
|
for (VclPtr<SfxSplitWindow> & p : pSplit)
|
|
{
|
|
if (p->GetWindowCount())
|
|
ReleaseChild_Impl(*p);
|
|
p.disposeAndClear();
|
|
}
|
|
|
|
// Delete help structure for Child-Windows
|
|
DBG_ASSERT( aChildren.empty(), "dangling children" );
|
|
|
|
if ( m_xLayoutManagerListener.is() )
|
|
m_xLayoutManagerListener->dispose();
|
|
}
|
|
|
|
void SfxWorkWindow::Lock_Impl( bool bLock )
|
|
{
|
|
if ( bLock )
|
|
m_nLock++;
|
|
else
|
|
--m_nLock;
|
|
if ( m_nLock<0 )
|
|
{
|
|
OSL_FAIL("Lock count underflow!");
|
|
assert(m_nLock >= 0);
|
|
m_nLock = 0;
|
|
}
|
|
|
|
if ( !m_nLock )
|
|
ArrangeChildren_Impl();
|
|
}
|
|
|
|
|
|
// Helper method to release the child lists. Should the destructor not be
|
|
// called after this, instead work continues, then space for the object bars
|
|
// and split windows has to be reserved in the same way as in the constructor
|
|
// of SfxWorkWindow.
|
|
|
|
void SfxWorkWindow::DeleteControllers_Impl()
|
|
{
|
|
|
|
// Lock SplitWindows (which means suppressing the Resize-Reaction of the
|
|
// DockingWindows)
|
|
for (size_t n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
|
|
{
|
|
VclPtr<SfxSplitWindow> const &p = pSplit[n];
|
|
if (p->GetWindowCount())
|
|
p->Lock();
|
|
}
|
|
|
|
// Delete Child-Windows
|
|
while(!aChildWins.empty())
|
|
{
|
|
std::unique_ptr<SfxChildWin_Impl> pCW = std::move(*aChildWins.begin());
|
|
aChildWins.erase(aChildWins.begin());
|
|
SfxChildWindow *pChild = pCW->pWin;
|
|
if (pChild)
|
|
{
|
|
if (comphelper::LibreOfficeKit::isActive())
|
|
{
|
|
vcl::Window* pWindow = pChild->GetWindow();
|
|
if (pWindow)
|
|
{
|
|
pWindow->ReleaseLOKNotifier();
|
|
}
|
|
}
|
|
pChild->Hide();
|
|
|
|
// If the child window is a direct child window and not in a
|
|
// SplitWindow, cancel it at the workwindow.
|
|
// After TH a cancellation on the SplitWindow is not necessary
|
|
// since this window is also destroyed (see below).
|
|
if (pCW->pCli)
|
|
{
|
|
if (pChild->GetController())
|
|
ReleaseChild_Impl(*pChild->GetController());
|
|
else
|
|
ReleaseChild_Impl(*pChild->GetWindow());
|
|
}
|
|
|
|
pCW->pWin = nullptr;
|
|
pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChild->GetWindow() );
|
|
pChild->Destroy();
|
|
}
|
|
|
|
// ATTENTION: The array itself is cleared after this loop!!
|
|
// Therefore we have to set every array entry to zero as it could be
|
|
// accessed by calling pChild->Destroy().
|
|
// Window::NotifyAllChildren() calls SfxWorkWindow::DataChanged_Impl for
|
|
// 8-bit displays (WM_QUERYPALETTECHANGED message due to focus change)!!
|
|
}
|
|
|
|
Reference< css::frame::XFrame > xFrame = GetFrameInterface();
|
|
Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
|
|
Reference< css::frame::XLayoutManager > xLayoutManager;
|
|
if ( xPropSet.is() )
|
|
{
|
|
try
|
|
{
|
|
Any aValue = xPropSet->getPropertyValue( g_aLayoutManagerPropName );
|
|
aValue >>= xLayoutManager;
|
|
}
|
|
catch ( Exception& )
|
|
{
|
|
}
|
|
}
|
|
|
|
if ( xLayoutManager.is() )
|
|
{
|
|
xLayoutManager->reset();
|
|
|
|
// Delete StatusBar
|
|
ResetStatusBar_Impl();
|
|
|
|
// Delete ObjectBars (this is done last, so that aChildren does not
|
|
// receive dead Pointers)
|
|
for (SfxObjectBar_Impl & i : aObjBarList)
|
|
{
|
|
// Not every position must be occupied
|
|
ToolbarId eId = i.eId;
|
|
if (eId != ToolbarId::None)
|
|
i.eId = ToolbarId::None;
|
|
}
|
|
}
|
|
|
|
// ObjectBars are all released at once, since they occupy a
|
|
// fixed contiguous area in the array pChild
|
|
aChildren.clear();
|
|
bSorted = false;
|
|
|
|
nChildren = 0;
|
|
}
|
|
|
|
|
|
// for placing the child window.
|
|
|
|
void SfxWorkWindow::ArrangeChildren_Impl( bool bForce )
|
|
{
|
|
if ( pFrame->IsClosing_Impl() || ( m_nLock && !bForce ))
|
|
return;
|
|
|
|
SfxInPlaceClient *pClient = nullptr;
|
|
SfxViewFrame *pF = pFrame->GetCurrentViewFrame();
|
|
if ( pF && pF->GetViewShell() )
|
|
pClient = pF->GetViewShell()->GetIPClient();
|
|
|
|
if ( pClient )
|
|
return;
|
|
|
|
aClientArea = GetTopRect_Impl();
|
|
if ( aClientArea.IsEmpty() )
|
|
return;
|
|
|
|
SvBorder aBorder;
|
|
if ( nChildren && IsVisible_Impl() )
|
|
aBorder = Arrange_Impl();
|
|
// If the current application document contains an IPClient, then the
|
|
// object through SetTopToolFramePixel has to be assigned the available
|
|
// space. The object will then point to its UITools and sets the app border
|
|
// (-> SfxInPlaceEnv_Impl:: ArrangeChildren_Impl ()). Otherwise the
|
|
// app border is set here directly to possibly overwrite the Border that
|
|
// was set by an object from another document. The object does not set
|
|
// the SetAppBorder when it removes its UI tools so that no-dithering
|
|
// ObjectBar arises.
|
|
// (->SfxInPlaceEnv_Impl::ArrangeChildren_Impl())
|
|
|
|
pMasterFrame->SetToolSpaceBorderPixel_Impl( aBorder );
|
|
|
|
ArrangeAutoHideWindows( nullptr );
|
|
}
|
|
|
|
void SfxWorkWindow::FlushPendingChildSizes()
|
|
{
|
|
// tdf#116865, if any windows are being resized, i.e. their
|
|
// resize timer is active, then calling GetSizePixel on
|
|
// them forces the timer to fire and sets the final
|
|
// size to which they are getting resized towards.
|
|
for (size_t i = 0; i < aChildren.size(); ++i)
|
|
{
|
|
SfxChild_Impl *pCli = aChildren[i].get();
|
|
if (!pCli || !pCli->pWin)
|
|
continue;
|
|
(void)pCli->pWin->GetSizePixel();
|
|
}
|
|
}
|
|
|
|
SvBorder SfxWorkWindow::Arrange_Impl()
|
|
|
|
/* [Description]
|
|
|
|
This method organizes all visible child windows so that the docked window
|
|
sorted in order from the outside to the inside are placed after one
|
|
another. If a visible window does not fit anymore into the free
|
|
ClientArea, it is set to "not visible".
|
|
*/
|
|
{
|
|
//tdf#116865 trigger pending sizing timers now so we arrange
|
|
//with the final size of the client area.
|
|
//
|
|
//Otherwise calling GetSizePixel in the following loop will trigger the
|
|
//timers, causing reentry into Arrange_Impl again where the inner
|
|
//Arrange_Impl arranges with the final size, and then returns to this outer
|
|
//Arrange_Impl which would rearrange with the old client area size
|
|
FlushPendingChildSizes();
|
|
aClientArea = GetTopRect_Impl();
|
|
aUpperClientArea = aClientArea;
|
|
|
|
SvBorder aBorder;
|
|
if ( !nChildren )
|
|
return aBorder;
|
|
|
|
if (!bSorted)
|
|
Sort_Impl();
|
|
|
|
Point aPos;
|
|
Size aSize;
|
|
tools::Rectangle aTmp( aClientArea );
|
|
|
|
for (sal_uInt16 n : aSortedList)
|
|
{
|
|
SfxChild_Impl* pCli = aChildren[n].get();
|
|
if ( !pCli->pWin )
|
|
continue;
|
|
|
|
// First, we assume that there is room for the window.
|
|
pCli->nVisible |= SfxChildVisibility::FITS_IN;
|
|
|
|
// Skip invisible windows
|
|
if (pCli->nVisible != SfxChildVisibility::VISIBLE)
|
|
continue;
|
|
|
|
if ( pCli->bResize )
|
|
aSize = pCli->aSize;
|
|
else
|
|
aSize = pCli->pWin->GetSizePixel();
|
|
|
|
SvBorder aTemp = aBorder;
|
|
bool bAllowHiding = true;
|
|
switch ( pCli->eAlign )
|
|
{
|
|
case SfxChildAlignment::HIGHESTTOP:
|
|
case SfxChildAlignment::TOP:
|
|
case SfxChildAlignment::TOOLBOXTOP:
|
|
case SfxChildAlignment::LOWESTTOP:
|
|
aSize.setWidth( aTmp.GetWidth() );
|
|
if ( pCli->pWin->GetType() == WindowType::SPLITWINDOW )
|
|
aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
|
|
bAllowHiding = false;
|
|
aBorder.Top() += aSize.Height();
|
|
aPos = aTmp.TopLeft();
|
|
aTmp.AdjustTop(aSize.Height() );
|
|
if ( pCli->eAlign == SfxChildAlignment::HIGHESTTOP )
|
|
aUpperClientArea.AdjustTop(aSize.Height() );
|
|
break;
|
|
|
|
case SfxChildAlignment::LOWESTBOTTOM:
|
|
case SfxChildAlignment::BOTTOM:
|
|
case SfxChildAlignment::TOOLBOXBOTTOM:
|
|
case SfxChildAlignment::HIGHESTBOTTOM:
|
|
aSize.setWidth( aTmp.GetWidth() );
|
|
if ( pCli->pWin->GetType() == WindowType::SPLITWINDOW )
|
|
aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
|
|
aBorder.Bottom() += aSize.Height();
|
|
aPos = aTmp.BottomLeft();
|
|
aPos.AdjustY( -(aSize.Height()-1) );
|
|
aTmp.AdjustBottom( -(aSize.Height()) );
|
|
if ( pCli->eAlign == SfxChildAlignment::LOWESTBOTTOM )
|
|
aUpperClientArea.AdjustBottom( -(aSize.Height()) );
|
|
break;
|
|
|
|
case SfxChildAlignment::FIRSTLEFT:
|
|
case SfxChildAlignment::LEFT:
|
|
case SfxChildAlignment::LASTLEFT:
|
|
case SfxChildAlignment::TOOLBOXLEFT:
|
|
aSize.setHeight( aTmp.GetHeight() );
|
|
if ( pCli->pWin->GetType() == WindowType::SPLITWINDOW )
|
|
aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
|
|
bAllowHiding = false;
|
|
aBorder.Left() += aSize.Width();
|
|
aPos = aTmp.TopLeft();
|
|
aTmp.AdjustLeft(aSize.Width() );
|
|
if ( pCli->eAlign != SfxChildAlignment::TOOLBOXLEFT )
|
|
aUpperClientArea.AdjustLeft(aSize.Width() );
|
|
break;
|
|
|
|
case SfxChildAlignment::FIRSTRIGHT:
|
|
case SfxChildAlignment::RIGHT:
|
|
case SfxChildAlignment::LASTRIGHT:
|
|
case SfxChildAlignment::TOOLBOXRIGHT:
|
|
aSize.setHeight( aTmp.GetHeight() );
|
|
if ( pCli->pWin->GetType() == WindowType::SPLITWINDOW )
|
|
aSize = static_cast<SplitWindow *>(pCli->pWin.get())->CalcLayoutSizePixel( aSize );
|
|
aBorder.Right() += aSize.Width();
|
|
aPos = aTmp.TopRight();
|
|
aPos.AdjustX( -(aSize.Width()-1) );
|
|
aTmp.AdjustRight( -(aSize.Width()) );
|
|
if ( pCli->eAlign != SfxChildAlignment::TOOLBOXRIGHT )
|
|
aUpperClientArea.AdjustRight( -(aSize.Width()) );
|
|
break;
|
|
|
|
default:
|
|
pCli->aSize = pCli->pWin->GetSizePixel();
|
|
pCli->bResize = false;
|
|
continue;
|
|
}
|
|
|
|
pCli->pWin->SetPosSizePixel( aPos, aSize );
|
|
pCli->bResize = false;
|
|
pCli->aSize = aSize;
|
|
if( bAllowHiding && !RequestTopToolSpacePixel_Impl( aBorder ) )
|
|
{
|
|
pCli->nVisible ^= SfxChildVisibility::FITS_IN;
|
|
aBorder = aTemp;
|
|
}
|
|
}
|
|
|
|
if ( aClientArea.GetWidth() >= aBorder.Left() + aBorder.Right() )
|
|
{
|
|
aClientArea.AdjustLeft(aBorder.Left() );
|
|
aClientArea.AdjustRight( -(aBorder.Right()) );
|
|
}
|
|
else
|
|
{
|
|
aBorder.Left() = aClientArea.Left();
|
|
aBorder.Right() = aClientArea.Right();
|
|
aClientArea.SetRight( aTmp.Left() );
|
|
aClientArea.SetLeft( aTmp.Left() );
|
|
}
|
|
|
|
if ( aClientArea.GetHeight() >= aBorder.Top() + aBorder.Bottom() )
|
|
{
|
|
aClientArea.AdjustTop(aBorder.Top() );
|
|
aClientArea.AdjustBottom( -(aBorder.Bottom()) );
|
|
}
|
|
else
|
|
{
|
|
aBorder.Top() = aClientArea.Top();
|
|
aBorder.Bottom() = aClientArea.Bottom();
|
|
aClientArea.SetTop(aTmp.Top());
|
|
aClientArea.SetBottom(aTmp.Top());
|
|
}
|
|
|
|
return IsDockingAllowed() ? aBorder : SvBorder();
|
|
}
|
|
|
|
bool SfxWorkWindow::PrepareClose_Impl()
|
|
{
|
|
for (const std::unique_ptr<SfxChildWin_Impl> &pCW : aChildWins)
|
|
{
|
|
SfxChildWindow *pChild = pCW->pWin;
|
|
if ( pChild && !pChild->QueryClose() )
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( vcl::Window& rWindow,
|
|
SfxChildAlignment eAlign )
|
|
{
|
|
DBG_ASSERT( aChildren.size() < 255, "too many children" );
|
|
DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" );
|
|
DBG_ASSERT( !FindChild_Impl(&rWindow), "child registered more than once" );
|
|
|
|
|
|
if ( rWindow.GetParent() != pWorkWin )
|
|
rWindow.SetParent( pWorkWin );
|
|
|
|
auto pChild = std::make_unique<SfxChild_Impl>(rWindow, rWindow.GetSizePixel(),
|
|
eAlign, rWindow.IsVisible());
|
|
|
|
aChildren.push_back(std::move(pChild));
|
|
bSorted = false;
|
|
nChildren++;
|
|
return aChildren.back().get();
|
|
}
|
|
|
|
SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl(std::shared_ptr<SfxDialogController>& rController,
|
|
SfxChildAlignment eAlign )
|
|
{
|
|
DBG_ASSERT( aChildren.size() < 255, "too many children" );
|
|
DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" );
|
|
|
|
auto pChild = std::make_unique<SfxChild_Impl>(rController, eAlign);
|
|
|
|
aChildren.push_back(std::move(pChild));
|
|
bSorted = false;
|
|
nChildren++;
|
|
return aChildren.back().get();
|
|
}
|
|
|
|
void SfxWorkWindow::ReleaseChild_Impl( vcl::Window& rWindow )
|
|
{
|
|
|
|
SfxChild_Impl *pChild = nullptr;
|
|
decltype(aChildren)::size_type nPos;
|
|
for ( nPos = 0; nPos < aChildren.size(); ++nPos )
|
|
{
|
|
pChild = aChildren[nPos].get();
|
|
if ( pChild && pChild->pWin == &rWindow )
|
|
{
|
|
bSorted = false;
|
|
nChildren--;
|
|
aChildren.erase(aChildren.begin() + nPos);
|
|
return;
|
|
}
|
|
}
|
|
OSL_FAIL( "releasing unregistered child" );
|
|
}
|
|
|
|
void SfxWorkWindow::ReleaseChild_Impl(const SfxDialogController& rController)
|
|
{
|
|
|
|
SfxChild_Impl *pChild = nullptr;
|
|
decltype(aChildren)::size_type nPos;
|
|
for ( nPos = 0; nPos < aChildren.size(); ++nPos )
|
|
{
|
|
pChild = aChildren[nPos].get();
|
|
if (pChild && pChild->xController.get() == &rController)
|
|
{
|
|
bSorted = false;
|
|
nChildren--;
|
|
aChildren.erase(aChildren.begin() + nPos);
|
|
return;
|
|
}
|
|
}
|
|
OSL_FAIL( "releasing unregistered child" );
|
|
}
|
|
|
|
SfxChild_Impl* SfxWorkWindow::FindChild_Impl( const vcl::Window* rWindow ) const
|
|
{
|
|
|
|
sal_uInt16 nCount = aChildren.size();
|
|
for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
|
|
{
|
|
SfxChild_Impl *pChild = aChildren[nPos].get();
|
|
if ( pChild && pChild->pWin == rWindow )
|
|
return pChild;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void SfxWorkWindow::ShowChildren_Impl()
|
|
{
|
|
bool bInvisible = ( !IsVisible_Impl() || ( !pWorkWin->IsReallyVisible() && !pWorkWin->IsReallyShown() ));
|
|
|
|
for (std::unique_ptr<SfxChild_Impl>& pCli : aChildren)
|
|
{
|
|
if (!pCli)
|
|
continue;
|
|
SfxChildWin_Impl* pCW = nullptr;
|
|
if (pCli->pWin || pCli->xController)
|
|
{
|
|
// We have to find the SfxChildWin_Impl to retrieve the
|
|
// SFX_CHILDWIN flags that can influence visibility.
|
|
for (const std::unique_ptr<SfxChildWin_Impl>& pCWin : aChildWins)
|
|
{
|
|
SfxChild_Impl* pChild = pCWin->pCli;
|
|
if ( pChild == pCli.get() )
|
|
{
|
|
pCW = pCWin.get();
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool bVisible( !bInvisible );
|
|
if ( pCW )
|
|
{
|
|
// Check flag SFX_CHILDWIN_NEVERHIDE that forces us to show
|
|
// the child window even in situations where no child window is
|
|
// visible.
|
|
SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
|
|
bVisible = !bInvisible || ( nFlags & SfxChildWindowFlags::NEVERHIDE );
|
|
}
|
|
|
|
if ( SfxChildVisibility::VISIBLE == (pCli->nVisible & SfxChildVisibility::VISIBLE) && bVisible )
|
|
{
|
|
if (pCli->xController)
|
|
{
|
|
if (!pCli->xController->getDialog()->get_visible())
|
|
{
|
|
auto xController = pCli->xController;
|
|
weld::DialogController::runAsync(xController,
|
|
[=](sal_Int32 nResult){
|
|
if (nResult == nCloseResponseToJustHide)
|
|
return;
|
|
xController->Close();
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ShowFlags nFlags = pCli->bSetFocus ? ShowFlags::NONE : ShowFlags::NoFocusChange | ShowFlags::NoActivate;
|
|
pCli->pWin->Show(true, nFlags);
|
|
}
|
|
pCli->bSetFocus = false;
|
|
}
|
|
else
|
|
{
|
|
if (pCli->xController)
|
|
{
|
|
if (pCli->xController->getDialog()->get_visible())
|
|
pCli->xController->response(RET_CLOSE);
|
|
}
|
|
else
|
|
pCli->pWin->Hide();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::HideChildren_Impl()
|
|
{
|
|
for ( sal_uInt16 nPos = aChildren.size(); nPos > 0; --nPos )
|
|
{
|
|
SfxChild_Impl *pChild = aChildren[nPos-1].get();
|
|
if (!pChild)
|
|
continue;
|
|
if (pChild->xController)
|
|
pChild->xController->response(RET_CLOSE);
|
|
else if (pChild->pWin)
|
|
pChild->pWin->Hide();
|
|
}
|
|
}
|
|
|
|
void SfxWorkWindow::ResetObjectBars_Impl()
|
|
{
|
|
for ( auto & n: aObjBarList )
|
|
n.bDestroy = true;
|
|
|
|
for ( auto & n: aChildWins )
|
|
n->nId = 0;
|
|
}
|
|
|
|
void SfxWorkWindow::SetObjectBar_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId)
|
|
{
|
|
DBG_ASSERT( nPos < SFX_OBJECTBAR_MAX, "object bar position overflow" );
|
|
|
|
SfxObjectBar_Impl aObjBar;
|
|
aObjBar.eId = eId;
|
|
aObjBar.nMode = nFlags;
|
|
|
|
for (SfxObjectBar_Impl & rBar : aObjBarList)
|
|
{
|
|
if ( rBar.eId == aObjBar.eId )
|
|
{
|
|
rBar = aObjBar;
|
|
return;
|
|
}
|
|
}
|
|
|
|
aObjBarList.push_back( aObjBar );
|
|
}
|
|
|
|
bool SfxWorkWindow::IsVisible_Impl( SfxVisibilityFlags nMode ) const
|
|
{
|
|
switch( nUpdateMode )
|
|
{
|
|
case SfxVisibilityFlags::Standard:
|
|
return true;
|
|
case SfxVisibilityFlags::Invisible:
|
|
return false;
|
|
case SfxVisibilityFlags::Client:
|
|
case SfxVisibilityFlags::Server:
|
|
return bool(nMode & nUpdateMode);
|
|
default:
|
|
return (nMode & nOrigMode ) ||
|
|
nOrigMode == SfxVisibilityFlags::Standard;
|
|
}
|
|
}
|
|
|
|
void SfxWorkWindow::UpdateObjectBars_Impl()
|
|
{
|
|
if ( pFrame->IsClosing_Impl() )
|
|
return;
|
|
|
|
UpdateObjectBars_Impl2();
|
|
|
|
{
|
|
ArrangeChildren_Impl( false );
|
|
|
|
ShowChildren_Impl();
|
|
}
|
|
|
|
ShowChildren_Impl();
|
|
}
|
|
|
|
Reference< css::task::XStatusIndicator > SfxWorkWindow::GetStatusIndicator()
|
|
{
|
|
Reference< css::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
|
|
Reference< css::frame::XLayoutManager > xLayoutManager;
|
|
Reference< css::task::XStatusIndicator > xStatusIndicator;
|
|
|
|
if ( xPropSet.is() )
|
|
{
|
|
Any aValue = xPropSet->getPropertyValue( g_aLayoutManagerPropName );
|
|
aValue >>= xLayoutManager;
|
|
if ( xLayoutManager.is() )
|
|
{
|
|
xLayoutManager->createElement( g_aProgressBarResName );
|
|
xLayoutManager->showElement( g_aProgressBarResName );
|
|
|
|
Reference< css::ui::XUIElement > xProgressBar =
|
|
xLayoutManager->getElement( g_aProgressBarResName );
|
|
if ( xProgressBar.is() )
|
|
{
|
|
xStatusIndicator.set( xProgressBar->getRealInterface(), UNO_QUERY );
|
|
}
|
|
}
|
|
}
|
|
|
|
return xStatusIndicator;
|
|
}
|
|
|
|
|
|
bool SfxWorkWindow::IsPluginMode( SfxObjectShell const * pObjShell )
|
|
{
|
|
if ( pObjShell && pObjShell->GetMedium() )
|
|
{
|
|
const SfxBoolItem* pViewOnlyItem = pObjShell->GetMedium()->GetItemSet().GetItem(SID_VIEWONLY, false);
|
|
if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
css::uno::Reference< css::frame::XFrame > SfxWorkWindow::GetFrameInterface()
|
|
{
|
|
css::uno::Reference< css::frame::XFrame > xFrame;
|
|
|
|
SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() );
|
|
if ( pDispatcher )
|
|
{
|
|
SfxViewFrame* pViewFrame = pDispatcher->GetFrame();
|
|
if ( pViewFrame )
|
|
xFrame = pViewFrame->GetFrame().GetFrameInterface();
|
|
}
|
|
|
|
return xFrame;
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::UpdateObjectBars_Impl2()
|
|
{
|
|
if (comphelper::IsFuzzing())
|
|
return;
|
|
|
|
// Lock SplitWindows (which means suppressing the Resize-Reaction of the
|
|
// DockingWindows)
|
|
for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
|
|
{
|
|
VclPtr<SfxSplitWindow> const & p = pSplit[n];
|
|
if (p->GetWindowCount())
|
|
p->Lock();
|
|
}
|
|
|
|
Reference< css::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
|
|
Reference< css::frame::XLayoutManager > xLayoutManager;
|
|
|
|
if ( xPropSet.is() )
|
|
{
|
|
Any aValue = xPropSet->getPropertyValue( g_aLayoutManagerPropName );
|
|
aValue >>= xLayoutManager;
|
|
}
|
|
|
|
if ( !xLayoutManager.is() )
|
|
return;
|
|
|
|
bool bPluginMode( false );
|
|
SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() );
|
|
|
|
if ( pDispatcher )
|
|
{
|
|
SfxViewFrame* pViewFrame = pDispatcher->GetFrame();
|
|
if ( pViewFrame )
|
|
bPluginMode = IsPluginMode( pViewFrame->GetObjectShell() );
|
|
}
|
|
|
|
// Iterate over all Toolboxes
|
|
xLayoutManager->lock();
|
|
const bool bForceDestroyToolbars =
|
|
comphelper::LibreOfficeKit::isActive() ? false : sfx2::SfxNotebookBar::IsActive(true);
|
|
for ( auto const & n: aObjBarList )
|
|
{
|
|
ToolbarId eId = n.eId;
|
|
bool bDestroy = n.bDestroy;
|
|
|
|
// Determine the valid mode for the ToolBox
|
|
SfxVisibilityFlags nTbxMode = n.nMode;
|
|
bool bFullScreenTbx( nTbxMode & SfxVisibilityFlags::FullScreen );
|
|
nTbxMode &= ~SfxVisibilityFlags::FullScreen;
|
|
nTbxMode &= ~SfxVisibilityFlags::Viewer;
|
|
|
|
// Is a ToolBox required in this context ?
|
|
bool bModesMatching = (nUpdateMode != SfxVisibilityFlags::Invisible) && ((nTbxMode & nUpdateMode) == nUpdateMode);
|
|
if ( bDestroy || bForceDestroyToolbars)
|
|
{
|
|
OUString aTbxId = g_aTbxTypeName + GetResourceURLFromToolbarId(eId);
|
|
xLayoutManager->destroyElement( aTbxId );
|
|
}
|
|
else if ( eId != ToolbarId::None && ( ( bModesMatching && !bIsFullScreen ) ||
|
|
( bIsFullScreen && bFullScreenTbx ) ) )
|
|
{
|
|
OUString aTbxId = g_aTbxTypeName + GetResourceURLFromToolbarId(eId);
|
|
if ( !IsDockingAllowed() && !xLayoutManager->isElementFloating( aTbxId ))
|
|
xLayoutManager->destroyElement( aTbxId );
|
|
else
|
|
{
|
|
xLayoutManager->requestElement( aTbxId );
|
|
if ( bPluginMode )
|
|
xLayoutManager->lockWindow( aTbxId );
|
|
}
|
|
}
|
|
else if ( eId != ToolbarId::None )
|
|
{
|
|
// Delete the Toolbox at this Position if possible
|
|
OUString aTbxId = g_aTbxTypeName + GetResourceURLFromToolbarId(eId);
|
|
xLayoutManager->destroyElement( aTbxId );
|
|
}
|
|
}
|
|
|
|
UpdateStatusBar_Impl();
|
|
|
|
// unlocking automatically forces Layout
|
|
xLayoutManager->unlock();
|
|
|
|
UpdateChildWindows_Impl();
|
|
|
|
// Unlock the SplitWindows again
|
|
for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
|
|
{
|
|
VclPtr<SfxSplitWindow> const & p = pSplit[n];
|
|
if (p->GetWindowCount())
|
|
p->Lock(false);
|
|
}
|
|
}
|
|
|
|
void SfxWorkWindow::UpdateChildWindows_Impl()
|
|
{
|
|
// tdf#100870, tdf#101320: don't use range-based for loop when
|
|
// container is modified
|
|
for ( size_t n=0; n<aChildWins.size(); n++ )
|
|
{
|
|
// any current or in the context available Childwindows
|
|
SfxChildWin_Impl *pCW = aChildWins[n].get();
|
|
SfxChildWindow *pChildWin = pCW->pWin;
|
|
bool bCreate = false;
|
|
if ( pCW->nId && (pCW->aInfo.nFlags & SfxChildWindowFlags::ALWAYSAVAILABLE || IsVisible_Impl( pCW->nVisibility ) ) )
|
|
{
|
|
// In the context is an appropriate ChildWindow allowed;
|
|
// it is also turned on?
|
|
if ( pChildWin == nullptr && pCW->bCreate )
|
|
{
|
|
// Internal docking is only used for embedding into another
|
|
// container. We force the floating state of all floatable
|
|
// child windows.
|
|
if ( !bInternalDockingAllowed )
|
|
{
|
|
// Special case for all non-floatable child windows. We have
|
|
// to prevent the creation here!
|
|
bCreate = !( pCW->aInfo.nFlags & SfxChildWindowFlags::FORCEDOCK );
|
|
}
|
|
else if ( !IsDockingAllowed() || bIsFullScreen ) // || !bInternalDocking )
|
|
{
|
|
// In Presentation mode or FullScreen only FloatingWindows
|
|
SfxChildAlignment eAlign;
|
|
if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) )
|
|
bCreate = ( eAlign == SfxChildAlignment::NOALIGNMENT );
|
|
}
|
|
else
|
|
bCreate = true;
|
|
|
|
if (pCW->aInfo.nFlags & SfxChildWindowFlags::NEVERCLONE)
|
|
pCW->bCreate = bCreate = false; // Don't create and remember that we haven't created.
|
|
|
|
// Currently, no window here, but it is enabled; windows
|
|
// Create window and if possible theContext
|
|
if ( bCreate )
|
|
CreateChildWin_Impl( pCW, false );
|
|
|
|
if ( !bAllChildrenVisible && pCW->pCli )
|
|
pCW->pCli->nVisible &= ~SfxChildVisibility::ACTIVE;
|
|
}
|
|
else if ( pChildWin )
|
|
{
|
|
// Window already exists, it should also be visible?
|
|
if ( ( !bIsFullScreen || pChildWin->GetAlignment() == SfxChildAlignment::NOALIGNMENT ) && bAllChildrenVisible )
|
|
{
|
|
// Update Mode is compatible; definitely enable it
|
|
bCreate = true;
|
|
if ( pCW->pCli )
|
|
{
|
|
// The window is a direct Child
|
|
if ((IsDockingAllowed() && bInternalDockingAllowed)
|
|
|| pCW->pCli->eAlign == SfxChildAlignment::NOALIGNMENT)
|
|
pCW->pCli->nVisible |= SfxChildVisibility::NOT_HIDDEN;
|
|
}
|
|
else
|
|
{
|
|
if ( pCW->bCreate && IsDockingAllowed() && bInternalDockingAllowed )
|
|
// The window ia within a SplitWindow
|
|
static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Reappear_Impl();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( pChildWin && !bCreate )
|
|
{
|
|
if ( !pChildWin->QueryClose() || pChildWin->IsHideNotDelete() || Application::IsUICaptured() )
|
|
{
|
|
if ( pCW->pCli )
|
|
{
|
|
if ( pCW->pCli->nVisible & SfxChildVisibility::NOT_HIDDEN )
|
|
pCW->pCli->nVisible ^= SfxChildVisibility::NOT_HIDDEN;
|
|
}
|
|
else
|
|
static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Disappear_Impl();
|
|
}
|
|
else
|
|
RemoveChildWin_Impl( pCW );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl *pCW, bool bSetFocus )
|
|
{
|
|
pCW->aInfo.bVisible = true;
|
|
|
|
SfxChildWindow *pChildWin = SfxChildWindow::CreateChildWindow( pCW->nId, pWorkWin, &GetBindings(), pCW->aInfo).release();
|
|
if (!pChildWin)
|
|
return;
|
|
|
|
if ( bSetFocus )
|
|
bSetFocus = pChildWin->WantsFocus();
|
|
pChildWin->SetWorkWindow_Impl( this );
|
|
|
|
// At least the extra string is changed during the evaluation,
|
|
// also get it anewed
|
|
SfxChildWinInfo aInfo = pChildWin->GetInfo();
|
|
pCW->aInfo.aExtraString = aInfo.aExtraString;
|
|
pCW->aInfo.bVisible = aInfo.bVisible;
|
|
pCW->aInfo.nFlags |= aInfo.nFlags;
|
|
|
|
// The creation was successful
|
|
GetBindings().Invalidate(pCW->nId);
|
|
|
|
sal_uInt16 nPos = pChildWin->GetPosition();
|
|
if (nPos != CHILDWIN_NOPOS)
|
|
{
|
|
DBG_ASSERT(nPos < SFX_OBJECTBAR_MAX, "Illegal objectbar position!");
|
|
if ( aChildren[TbxMatch(nPos)] )// &&
|
|
{
|
|
// ChildWindow replaces ObjectBar
|
|
aChildren[TbxMatch(nPos)]->nVisible ^= SfxChildVisibility::NOT_HIDDEN;
|
|
}
|
|
}
|
|
|
|
// make childwin keyboard accessible
|
|
pWorkWin->GetSystemWindow()->GetTaskPaneList()->AddWindow( pChildWin->GetWindow() );
|
|
|
|
pCW->pWin = pChildWin;
|
|
|
|
if ( pChildWin->GetAlignment() == SfxChildAlignment::NOALIGNMENT || pChildWin->GetWindow()->GetParent() == pWorkWin)
|
|
{
|
|
// The window is not docked or docked outside of one split windows
|
|
// and must therefore be registered explicitly as a Child
|
|
if (pChildWin->GetController())
|
|
pCW->pCli = RegisterChild_Impl(pChildWin->GetController(), pChildWin->GetAlignment());
|
|
else
|
|
pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment());
|
|
pCW->pCli->nVisible = SfxChildVisibility::VISIBLE;
|
|
if ( pChildWin->GetAlignment() != SfxChildAlignment::NOALIGNMENT && bIsFullScreen )
|
|
pCW->pCli->nVisible ^= SfxChildVisibility::ACTIVE;
|
|
pCW->pCli->bSetFocus = bSetFocus;
|
|
}
|
|
else
|
|
{
|
|
// A docked window which parent is not a WorkingWindow, must lie
|
|
// in a SplitWindow and thus not be explicitly registered.
|
|
// This happens already in the initialization of SfxDockingWindows!
|
|
}
|
|
|
|
// Save the information in the INI file
|
|
SaveStatus_Impl(pChildWin, pCW->aInfo);
|
|
}
|
|
|
|
void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl *pCW )
|
|
{
|
|
sal_uInt16 nId = pCW->nSaveId;
|
|
SfxChildWindow *pChildWin = pCW->pWin;
|
|
|
|
// Save the information in the INI file
|
|
SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
|
|
pCW->aInfo = pChildWin->GetInfo();
|
|
pCW->aInfo.nFlags |= nFlags;
|
|
SaveStatus_Impl(pChildWin, pCW->aInfo);
|
|
|
|
pChildWin->Hide();
|
|
|
|
if ( pCW->pCli )
|
|
{
|
|
// Child window is a direct child window and must therefore unregister
|
|
// itself from the WorkWindow
|
|
pCW->pCli = nullptr;
|
|
if (pChildWin->GetController())
|
|
ReleaseChild_Impl(*pChildWin->GetController());
|
|
else
|
|
ReleaseChild_Impl(*pChildWin->GetWindow());
|
|
}
|
|
else
|
|
{
|
|
// ChildWindow is within a SplitWindow and unregister itself in
|
|
// the destructor.
|
|
}
|
|
|
|
pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChildWin->GetWindow() );
|
|
pCW->pWin = nullptr;
|
|
pChildWin->Destroy();
|
|
|
|
GetBindings().Invalidate( nId );
|
|
}
|
|
|
|
void SfxWorkWindow::ResetStatusBar_Impl()
|
|
{
|
|
aStatBar.eId = StatusBarId::None;
|
|
}
|
|
|
|
void SfxWorkWindow::SetStatusBar_Impl(StatusBarId eId)
|
|
{
|
|
if (eId != StatusBarId::None && bShowStatusBar && IsVisible_Impl())
|
|
aStatBar.eId = eId;
|
|
}
|
|
|
|
void SfxWorkWindow::UpdateStatusBar_Impl()
|
|
{
|
|
Reference< css::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
|
|
Reference< css::frame::XLayoutManager > xLayoutManager;
|
|
|
|
Any aValue = xPropSet->getPropertyValue( g_aLayoutManagerPropName );
|
|
aValue >>= xLayoutManager;
|
|
|
|
// No status bar, if no ID is required or when in FullScreenView or
|
|
// if disabled
|
|
if (aStatBar.eId != StatusBarId::None && IsDockingAllowed() && bInternalDockingAllowed && bShowStatusBar &&
|
|
!bIsFullScreen)
|
|
{
|
|
// Id has changed, thus create a suitable Statusbarmanager, this takes
|
|
// over the current status bar;
|
|
if ( xLayoutManager.is() )
|
|
xLayoutManager->requestElement( g_aStatusBarResName );
|
|
}
|
|
else
|
|
{
|
|
// Destroy the current StatusBar
|
|
// The Manager only creates the Status bar, does not destroy it.
|
|
if ( xLayoutManager.is() )
|
|
xLayoutManager->destroyElement( g_aStatusBarResName );
|
|
}
|
|
}
|
|
|
|
void SfxWorkWindow::MakeVisible_Impl( bool bVis )
|
|
{
|
|
if ( bVis )
|
|
nOrigMode = SfxVisibilityFlags::Standard;
|
|
else
|
|
nOrigMode = SfxVisibilityFlags::Invisible;
|
|
|
|
if ( nOrigMode != nUpdateMode)
|
|
nUpdateMode = nOrigMode;
|
|
}
|
|
|
|
bool SfxWorkWindow::IsVisible_Impl() const
|
|
{
|
|
return nOrigMode != SfxVisibilityFlags::Invisible;
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::HidePopups_Impl(bool bHide, sal_uInt16 nId )
|
|
{
|
|
if (comphelper::LibreOfficeKit::isActive() && bHide)
|
|
return;
|
|
|
|
for (const std::unique_ptr<SfxChildWin_Impl>& i : aChildWins)
|
|
{
|
|
SfxChildWindow *pCW = i->pWin;
|
|
if (pCW && pCW->GetAlignment() == SfxChildAlignment::NOALIGNMENT && pCW->GetType() != nId)
|
|
{
|
|
vcl::Window *pWin = pCW->GetWindow();
|
|
SfxChild_Impl *pChild = FindChild_Impl(pWin);
|
|
if (!pChild)
|
|
{
|
|
SAL_WARN("sfx.appl", "missing SfxChild_Impl child!");
|
|
continue;
|
|
}
|
|
if (bHide)
|
|
{
|
|
pChild->nVisible &= ~SfxChildVisibility::ACTIVE;
|
|
pCW->Hide();
|
|
}
|
|
else if ( !comphelper::LibreOfficeKit::isActive() ||
|
|
SfxChildVisibility::ACTIVE != (pChild->nVisible & SfxChildVisibility::ACTIVE) )
|
|
{
|
|
pChild->nVisible |= SfxChildVisibility::ACTIVE;
|
|
if ( SfxChildVisibility::VISIBLE == (pChild->nVisible & SfxChildVisibility::VISIBLE) )
|
|
pCW->Show( ShowFlags::NoFocusChange | ShowFlags::NoActivate );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::ConfigChild_Impl(SfxChildIdentifier eChild,
|
|
SfxDockingConfig eConfig, sal_uInt16 nId)
|
|
{
|
|
SfxDockingWindow* pDockWin=nullptr;
|
|
sal_uInt16 nPos = USHRT_MAX;
|
|
vcl::Window *pWin=nullptr;
|
|
SfxChildWin_Impl *pCW = nullptr;
|
|
|
|
// configure direct childwindow
|
|
for (const std::unique_ptr<SfxChildWin_Impl>& i : aChildWins)
|
|
{
|
|
pCW = i.get();
|
|
SfxChildWindow *pChild = pCW->pWin;
|
|
if ( pChild && (pChild->GetType() == nId ))
|
|
{
|
|
if (SfxDockingWindow* pSfxDockingWindow = dynamic_cast<SfxDockingWindow*>(pChild->GetWindow()))
|
|
{
|
|
// it's a DockingWindow
|
|
pDockWin = pSfxDockingWindow;
|
|
}
|
|
else
|
|
{
|
|
// FloatingWindow or ModelessDialog
|
|
pWin = pChild->GetWindow();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( pDockWin )
|
|
{
|
|
if ( eChild == SfxChildIdentifier::DOCKINGWINDOW || pDockWin->GetAlignment() == SfxChildAlignment::NOALIGNMENT )
|
|
{
|
|
if ( eChild == SfxChildIdentifier::SPLITWINDOW && eConfig == SfxDockingConfig::TOGGLEFLOATMODE)
|
|
{
|
|
// DockingWindow was dragged out of a SplitWindow
|
|
pCW->pCli = RegisterChild_Impl(*pDockWin, pDockWin->GetAlignment());
|
|
pCW->pCli->nVisible = SfxChildVisibility::VISIBLE;
|
|
}
|
|
|
|
pWin = pDockWin;
|
|
}
|
|
else
|
|
{
|
|
SfxSplitWindow *pSplitWin = GetSplitWindow_Impl(pDockWin->GetAlignment());
|
|
|
|
// configure DockingWindow inside a SplitWindow
|
|
if ( eConfig == SfxDockingConfig::TOGGLEFLOATMODE)
|
|
{
|
|
// DockingWindow was dragged into a SplitWindow
|
|
pCW->pCli = nullptr;
|
|
ReleaseChild_Impl(*pDockWin);
|
|
}
|
|
|
|
pWin = pSplitWin->GetSplitWindow();
|
|
if ( pSplitWin->GetWindowCount() == 1 )
|
|
static_cast<SplitWindow*>(pWin)->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
|
|
}
|
|
}
|
|
|
|
DBG_ASSERT( pCW, "Unknown window!" );
|
|
|
|
if ( !bSorted )
|
|
// windows may have been registered and released without an update until now
|
|
Sort_Impl();
|
|
|
|
decltype(aSortedList)::size_type n;
|
|
for ( n=0; n<aSortedList.size(); ++n )
|
|
{
|
|
SfxChild_Impl *pChild = aChildren[aSortedList[n]].get();
|
|
if ( pChild && pChild->pWin == pWin )
|
|
break;
|
|
}
|
|
|
|
if ( n < aSortedList.size() )
|
|
// sometimes called while toggling float mode
|
|
nPos = aSortedList[n];
|
|
|
|
switch ( eConfig )
|
|
{
|
|
case SfxDockingConfig::SETDOCKINGRECTS :
|
|
{
|
|
if (nPos == USHRT_MAX || !pDockWin)
|
|
return;
|
|
|
|
tools::Rectangle aOuterRect( GetTopRect_Impl() );
|
|
aOuterRect.SetPos( pWorkWin->OutputToScreenPixel( aOuterRect.TopLeft() ));
|
|
tools::Rectangle aInnerRect( aOuterRect );
|
|
|
|
// The current affected window is included in the calculation of
|
|
// the inner rectangle!
|
|
for (sal_uInt16 i : aSortedList)
|
|
{
|
|
SfxChild_Impl* pCli = aChildren[i].get();
|
|
|
|
if ( pCli && pCli->nVisible == SfxChildVisibility::VISIBLE && pCli->pWin )
|
|
{
|
|
switch ( pCli->eAlign )
|
|
{
|
|
case SfxChildAlignment::TOP:
|
|
// Object-Toolboxes come always last
|
|
aInnerRect.AdjustTop(pCli->aSize.Height() );
|
|
break;
|
|
|
|
case SfxChildAlignment::HIGHESTTOP:
|
|
// Always performed first
|
|
aInnerRect.AdjustTop(pCli->aSize.Height() );
|
|
break;
|
|
|
|
case SfxChildAlignment::LOWESTTOP:
|
|
// Is only counted if it is the current window
|
|
if ( i == nPos )
|
|
aInnerRect.AdjustTop(pCli->aSize.Height() );
|
|
break;
|
|
|
|
case SfxChildAlignment::BOTTOM:
|
|
// Object-Toolboxes come always last
|
|
aInnerRect.AdjustBottom( -(pCli->aSize.Height()) );
|
|
break;
|
|
|
|
case SfxChildAlignment::LOWESTBOTTOM:
|
|
// Always performed first
|
|
aInnerRect.AdjustBottom( -(pCli->aSize.Height()) );
|
|
break;
|
|
|
|
case SfxChildAlignment::HIGHESTBOTTOM:
|
|
// Is only counted if it is the current window
|
|
if ( i == nPos )
|
|
aInnerRect.AdjustBottom( -(pCli->aSize.Height()) );
|
|
break;
|
|
|
|
case SfxChildAlignment::LEFT:
|
|
// Toolboxes come always last
|
|
aInnerRect.AdjustLeft(pCli->aSize.Width() );
|
|
break;
|
|
|
|
case SfxChildAlignment::FIRSTLEFT:
|
|
// Always performed first
|
|
aInnerRect.AdjustLeft(pCli->aSize.Width() );
|
|
break;
|
|
|
|
case SfxChildAlignment::LASTLEFT:
|
|
// Is only counted if it is the current window
|
|
if (i == nPos)
|
|
aInnerRect.AdjustLeft(pCli->aSize.Width() );
|
|
break;
|
|
|
|
case SfxChildAlignment::RIGHT:
|
|
// Toolboxes come always last
|
|
aInnerRect.AdjustRight( -(pCli->aSize.Width()) );
|
|
break;
|
|
|
|
case SfxChildAlignment::FIRSTRIGHT:
|
|
// Is only counted if it is the current window
|
|
if (i == nPos)
|
|
aInnerRect.AdjustRight( -(pCli->aSize.Width()) );
|
|
break;
|
|
|
|
case SfxChildAlignment::LASTRIGHT:
|
|
// Always performed first
|
|
aInnerRect.AdjustRight( -(pCli->aSize.Width()) );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
pDockWin->SetDockingRects(aOuterRect, aInnerRect);
|
|
break;
|
|
}
|
|
|
|
case SfxDockingConfig::ALIGNDOCKINGWINDOW :
|
|
case SfxDockingConfig::TOGGLEFLOATMODE:
|
|
{
|
|
if ( nPos == USHRT_MAX && !pCW )
|
|
return;
|
|
|
|
SfxChildAlignment eAlign = SfxChildAlignment::NOALIGNMENT;
|
|
SfxChild_Impl *pCli = ( nPos != USHRT_MAX ) ? aChildren[nPos].get() : nullptr;
|
|
if ( pCli && pDockWin )
|
|
{
|
|
eAlign = pDockWin->GetAlignment();
|
|
if ( eChild == SfxChildIdentifier::DOCKINGWINDOW || eAlign == SfxChildAlignment::NOALIGNMENT)
|
|
{
|
|
// configuration inside the SplitWindow, no change for the SplitWindows' configuration
|
|
pCli->bResize = true;
|
|
pCli->aSize = pDockWin->GetSizePixel();
|
|
}
|
|
}
|
|
|
|
if ( pCli )
|
|
{
|
|
if( pCli->eAlign != eAlign )
|
|
{
|
|
bSorted = false;
|
|
pCli->eAlign = eAlign;
|
|
}
|
|
|
|
ArrangeChildren_Impl();
|
|
ShowChildren_Impl();
|
|
}
|
|
|
|
if ( pCW && pCW->pWin )
|
|
{
|
|
// store changed configuration
|
|
SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
|
|
pCW->aInfo = pCW->pWin->GetInfo();
|
|
pCW->aInfo.nFlags |= nFlags;
|
|
SaveStatus_Impl( pCW->pWin, pCW->aInfo);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace
|
|
{
|
|
template <sal_uInt16 SfxChildWin_Impl::*Member>
|
|
SfxChildWin_Impl* Get_Impl(const std::vector<std::unique_ptr<SfxChildWin_Impl>>& rChildWins,
|
|
sal_uInt16 nId)
|
|
{
|
|
for (auto& pChildWin : rChildWins)
|
|
if (pChildWin.get()->*Member == nId)
|
|
return pChildWin.get();
|
|
return nullptr;
|
|
}
|
|
auto Get_ById = Get_Impl<&SfxChildWin_Impl::nId>;
|
|
auto Get_BySaveId = Get_Impl<&SfxChildWin_Impl::nSaveId>;
|
|
}
|
|
|
|
void SfxWorkWindow::SetChildWindowVisible_Impl( sal_uInt32 lId, bool bEnabled, SfxVisibilityFlags nMode )
|
|
{
|
|
sal_uInt16 nId = static_cast<sal_uInt16>( lId & 0xFFFF );
|
|
|
|
SfxChildWin_Impl* pCW = Get_BySaveId(aChildWins, nId);
|
|
|
|
if ( !pCW )
|
|
{
|
|
// If new, then initialize, add this here depending on the flag or
|
|
// the Parent
|
|
pCW = new SfxChildWin_Impl( lId );
|
|
pCW->nId = nId;
|
|
InitializeChild_Impl( pCW );
|
|
aChildWins.push_back( std::unique_ptr<SfxChildWin_Impl>(pCW) );
|
|
}
|
|
|
|
pCW->nId = nId;
|
|
pCW->nVisibility = nMode;
|
|
pCW->bEnable = bEnabled;
|
|
}
|
|
|
|
|
|
// The on/off status of a ChildWindow is switched
|
|
|
|
void SfxWorkWindow::ToggleChildWindow_Impl(sal_uInt16 nId, bool bSetFocus)
|
|
{
|
|
if (SfxChildWin_Impl* pCW = Get_ById(aChildWins, nId))
|
|
{
|
|
// The Window is already known
|
|
SfxChildWindow *pChild = pCW->pWin;
|
|
|
|
bool bCreationAllowed( true );
|
|
if ( !bInternalDockingAllowed )
|
|
{
|
|
// Special case for all non-floatable child windows. We have
|
|
// to prevent the creation here!
|
|
bCreationAllowed = !( pCW->aInfo.nFlags & SfxChildWindowFlags::FORCEDOCK );
|
|
}
|
|
|
|
if ( bCreationAllowed )
|
|
{
|
|
if ( pCW->bCreate )
|
|
{
|
|
if ( pChild )
|
|
{
|
|
if ( pChild->QueryClose() )
|
|
{
|
|
pCW->bCreate = false;
|
|
// The Window should be switched off
|
|
pChild->SetVisible_Impl( false );
|
|
RemoveChildWin_Impl( pCW );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no actual Window exists, yet => just remember the "switched off" state
|
|
pCW->bCreate = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pCW->bCreate = true;
|
|
if ( pChild )
|
|
{
|
|
ShowChildWindow_Impl( nId, true, bSetFocus );
|
|
}
|
|
else
|
|
{
|
|
// create actual Window
|
|
CreateChildWin_Impl( pCW, bSetFocus );
|
|
if ( !pCW->pWin )
|
|
// no success
|
|
pCW->bCreate = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
ArrangeChildren_Impl();
|
|
ShowChildren_Impl();
|
|
|
|
if ( pCW->bCreate && bCreationAllowed )
|
|
{
|
|
if ( !pCW->pCli )
|
|
{
|
|
SfxDockingWindow *pDock =
|
|
static_cast<SfxDockingWindow*>( pCW->pWin->GetWindow() );
|
|
if ( pDock->IsAutoHide_Impl() )
|
|
pDock->AutoShow_Impl();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#ifdef DBG_UTIL
|
|
if (Get_BySaveId(aChildWins, nId))
|
|
{
|
|
OSL_FAIL("The ChildWindow is not in context!");
|
|
}
|
|
else
|
|
{
|
|
OSL_FAIL("The ChildWindow is not registered!");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
bool SfxWorkWindow::HasChildWindow_Impl(sal_uInt16 nId)
|
|
{
|
|
if (const SfxChildWin_Impl* pCW = Get_BySaveId(aChildWins, nId))
|
|
return ( pCW->pWin && pCW->bCreate );
|
|
|
|
return false;
|
|
}
|
|
|
|
bool SfxWorkWindow::IsFloating( sal_uInt16 nId )
|
|
{
|
|
SfxChildWin_Impl* pCW = Get_BySaveId(aChildWins, nId);
|
|
|
|
if ( !pCW )
|
|
{
|
|
// If new, then initialize, add this here depending on the flag or
|
|
// the Parent
|
|
pCW = new SfxChildWin_Impl( nId );
|
|
pCW->bEnable = false;
|
|
pCW->nId = 0;
|
|
pCW->nVisibility = SfxVisibilityFlags::Invisible;
|
|
InitializeChild_Impl( pCW );
|
|
aChildWins.push_back( std::unique_ptr<SfxChildWin_Impl>(pCW) );
|
|
}
|
|
|
|
SfxChildAlignment eAlign;
|
|
if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) )
|
|
return( eAlign == SfxChildAlignment::NOALIGNMENT );
|
|
else
|
|
return true;
|
|
}
|
|
|
|
|
|
bool SfxWorkWindow::KnowsChildWindow_Impl(sal_uInt16 nId)
|
|
{
|
|
if (SfxChildWin_Impl* pCW = Get_BySaveId(aChildWins, nId))
|
|
{
|
|
if ( !(pCW->aInfo.nFlags & SfxChildWindowFlags::ALWAYSAVAILABLE) && !IsVisible_Impl( pCW->nVisibility ) )
|
|
return false;
|
|
return pCW->bEnable;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::SetChildWindow_Impl(sal_uInt16 nId, bool bOn, bool bSetFocus)
|
|
{
|
|
SfxChildWin_Impl* pCW = Get_BySaveId(aChildWins, nId);
|
|
|
|
if ( !pCW )
|
|
{
|
|
// If new, then initialize, add this here depending on the flag or
|
|
// the Parent
|
|
pCW = new SfxChildWin_Impl( nId );
|
|
InitializeChild_Impl( pCW );
|
|
aChildWins.push_back( std::unique_ptr<SfxChildWin_Impl>(pCW) );
|
|
}
|
|
|
|
if ( pCW->bCreate != bOn )
|
|
ToggleChildWindow_Impl(nId,bSetFocus);
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::ShowChildWindow_Impl(sal_uInt16 nId, bool bVisible, bool bSetFocus)
|
|
{
|
|
if (SfxChildWin_Impl* pCW = Get_ById(aChildWins, nId))
|
|
{
|
|
SfxChildWindow *pChildWin = pCW->pWin;
|
|
if ( pChildWin )
|
|
{
|
|
if ( bVisible )
|
|
{
|
|
if ( pCW->pCli )
|
|
{
|
|
pCW->pCli->bSetFocus = bSetFocus;
|
|
pCW->pCli->nVisible = SfxChildVisibility::VISIBLE;
|
|
pChildWin->Show( bSetFocus && pChildWin->WantsFocus() ? ShowFlags::NONE : ShowFlags::NoFocusChange | ShowFlags::NoActivate );
|
|
}
|
|
else
|
|
static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Reappear_Impl();
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( pCW->pCli )
|
|
{
|
|
pCW->pCli->nVisible = SfxChildVisibility::VISIBLE ^ SfxChildVisibility::NOT_HIDDEN;
|
|
pCW->pWin->Hide();
|
|
}
|
|
else
|
|
static_cast<SfxDockingWindow*>(pChildWin->GetWindow())->Disappear_Impl();
|
|
|
|
}
|
|
|
|
ArrangeChildren_Impl();
|
|
ShowChildren_Impl();
|
|
}
|
|
else if ( bVisible )
|
|
{
|
|
SetChildWindow_Impl( nId, true, bSetFocus );
|
|
pChildWin = pCW->pWin;
|
|
}
|
|
|
|
if ( pChildWin )
|
|
{
|
|
pChildWin->SetVisible_Impl( bVisible );
|
|
SfxChildWindowFlags nFlags = pCW->aInfo.nFlags;
|
|
pCW->aInfo = pChildWin->GetInfo();
|
|
pCW->aInfo.nFlags |= nFlags;
|
|
if ( !pCW->bCreate )
|
|
SaveStatus_Impl( pChildWin, pCW->aInfo );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#ifdef DBG_UTIL
|
|
if (Get_BySaveId(aChildWins, nId))
|
|
{
|
|
OSL_FAIL("The ChildWindow is not in context!");
|
|
}
|
|
else
|
|
{
|
|
OSL_FAIL("The ChildWindow is not registered");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
SfxChildWindow* SfxWorkWindow::GetChildWindow_Impl(sal_uInt16 nId)
|
|
{
|
|
if (SfxChildWin_Impl* pCW = Get_BySaveId(aChildWins, nId))
|
|
return pCW->pWin;
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::ResetChildWindows_Impl()
|
|
{
|
|
for (std::unique_ptr<SfxChildWin_Impl>& pChildWin : aChildWins)
|
|
{
|
|
pChildWin->nId = 0;
|
|
pChildWin->bEnable = false;
|
|
}
|
|
}
|
|
|
|
// returns the size of the area (client area) of the
|
|
// parent windows, in which the ChildWindow can be fitted.
|
|
|
|
tools::Rectangle SfxWorkWindow::GetTopRect_Impl() const
|
|
{
|
|
return pMasterFrame->GetTopOuterRectPixel_Impl();
|
|
}
|
|
|
|
|
|
// Virtual method to find out if there is room for a ChildWindow in the
|
|
// client area of the parent.
|
|
|
|
bool SfxWorkWindow::RequestTopToolSpacePixel_Impl( SvBorder aBorder )
|
|
{
|
|
return !(!IsDockingAllowed() ||
|
|
aClientArea.GetWidth() < aBorder.Left() + aBorder.Right() ||
|
|
aClientArea.GetHeight() < aBorder.Top() + aBorder.Bottom());
|
|
}
|
|
|
|
void SfxWorkWindow::SaveStatus_Impl(SfxChildWindow *pChild, const SfxChildWinInfo &rInfo)
|
|
{
|
|
// The Status of the Presentation mode is not saved
|
|
if ( IsDockingAllowed() && bInternalDockingAllowed )
|
|
pChild->SaveStatus(rInfo);
|
|
}
|
|
|
|
void SfxWorkWindow::InitializeChild_Impl(SfxChildWin_Impl *pCW)
|
|
{
|
|
SfxDispatcher *pDisp = pBindings->GetDispatcher_Impl();
|
|
SfxViewFrame *pViewFrame = pDisp ? pDisp->GetFrame() :nullptr;
|
|
SfxModule *pMod = pViewFrame ? SfxModule::GetActiveModule(pViewFrame) :nullptr;
|
|
|
|
OUString sModule;
|
|
if (pViewFrame)
|
|
{
|
|
try
|
|
{
|
|
uno::Reference< frame::XModuleManager2 > xModuleManager(
|
|
frame::ModuleManager::create(::comphelper::getProcessComponentContext()));
|
|
sModule = xModuleManager->identify(pViewFrame->GetFrame().GetFrameInterface());
|
|
SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(sModule);
|
|
sModule = SvtModuleOptions::GetFactoryShortName(eFac);
|
|
}
|
|
catch (...)
|
|
{
|
|
}
|
|
}
|
|
|
|
SfxChildWinFactory* pFact=nullptr;
|
|
SfxApplication *pApp = SfxGetpApp();
|
|
{
|
|
pFact = pApp->GetChildWinFactoryById(pCW->nSaveId);
|
|
if ( pFact )
|
|
{
|
|
pCW->aInfo = pFact->aInfo;
|
|
pCW->aInfo.aModule = sModule;
|
|
SfxChildWindow::InitializeChildWinFactory_Impl(
|
|
pCW->nSaveId, pCW->aInfo);
|
|
pCW->bCreate = pCW->aInfo.bVisible;
|
|
SfxChildWindowFlags nFlags = pFact->aInfo.nFlags;
|
|
if ( nFlags & SfxChildWindowFlags::TASK )
|
|
pCW->aInfo.nFlags |= SfxChildWindowFlags::TASK;
|
|
if ( nFlags & SfxChildWindowFlags::CANTGETFOCUS )
|
|
pCW->aInfo.nFlags |= SfxChildWindowFlags::CANTGETFOCUS;
|
|
if ( nFlags & SfxChildWindowFlags::FORCEDOCK )
|
|
pCW->aInfo.nFlags |= SfxChildWindowFlags::FORCEDOCK;
|
|
pFact->aInfo = pCW->aInfo;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( !pMod )
|
|
return;
|
|
|
|
pFact = pMod->GetChildWinFactoryById(pCW->nSaveId);
|
|
if ( !pFact )
|
|
return;
|
|
|
|
pCW->aInfo = pFact->aInfo;
|
|
pCW->aInfo.aModule = sModule;
|
|
SfxChildWindow::InitializeChildWinFactory_Impl(
|
|
pCW->nSaveId, pCW->aInfo);
|
|
pCW->bCreate = pCW->aInfo.bVisible;
|
|
SfxChildWindowFlags nFlags = pFact->aInfo.nFlags;
|
|
if ( nFlags & SfxChildWindowFlags::TASK )
|
|
pCW->aInfo.nFlags |= SfxChildWindowFlags::TASK;
|
|
if ( nFlags & SfxChildWindowFlags::CANTGETFOCUS )
|
|
pCW->aInfo.nFlags |= SfxChildWindowFlags::CANTGETFOCUS;
|
|
if ( nFlags & SfxChildWindowFlags::FORCEDOCK )
|
|
pCW->aInfo.nFlags |= SfxChildWindowFlags::FORCEDOCK;
|
|
if ( nFlags & SfxChildWindowFlags::ALWAYSAVAILABLE )
|
|
pCW->aInfo.nFlags |= SfxChildWindowFlags::ALWAYSAVAILABLE;
|
|
pFact->aInfo = pCW->aInfo;
|
|
}
|
|
|
|
SfxSplitWindow* SfxWorkWindow::GetSplitWindow_Impl( SfxChildAlignment eAlign )
|
|
{
|
|
switch ( eAlign )
|
|
{
|
|
case SfxChildAlignment::TOP:
|
|
return pSplit[2];
|
|
|
|
case SfxChildAlignment::BOTTOM:
|
|
return pSplit[3];
|
|
|
|
case SfxChildAlignment::LEFT:
|
|
return pSplit[0];
|
|
|
|
case SfxChildAlignment::RIGHT:
|
|
return pSplit[1];
|
|
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
void SfxWorkWindow::MakeChildrenVisible_Impl( bool bVis )
|
|
{
|
|
bAllChildrenVisible = bVis;
|
|
if ( bVis )
|
|
{
|
|
if ( !bSorted )
|
|
Sort_Impl();
|
|
for (sal_uInt16 n : aSortedList)
|
|
{
|
|
SfxChild_Impl* pCli = aChildren[n].get();
|
|
if ( (pCli->eAlign == SfxChildAlignment::NOALIGNMENT) || (IsDockingAllowed() && bInternalDockingAllowed) )
|
|
pCli->nVisible |= SfxChildVisibility::ACTIVE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !bSorted )
|
|
Sort_Impl();
|
|
for (sal_uInt16 n : aSortedList)
|
|
{
|
|
SfxChild_Impl* pCli = aChildren[n].get();
|
|
pCli->nVisible &= ~SfxChildVisibility::ACTIVE;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SfxWorkWindow::IsAutoHideMode( const SfxSplitWindow *pSplitWin )
|
|
{
|
|
for (const VclPtr<SfxSplitWindow> & pWin : pSplit)
|
|
{
|
|
if ( pWin.get() != pSplitWin && pWin->IsAutoHide( true ) )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void SfxWorkWindow::EndAutoShow_Impl( Point aPos )
|
|
{
|
|
for (VclPtr<SfxSplitWindow> & p : pSplit)
|
|
{
|
|
if ( p && p->IsAutoHide(false) )
|
|
{
|
|
Point aLocalPos = p->ScreenToOutputPixel( aPos );
|
|
tools::Rectangle aRect( Point(), p->GetSizePixel() );
|
|
if ( !aRect.Contains( aLocalPos ) )
|
|
p->FadeOut();
|
|
}
|
|
}
|
|
}
|
|
|
|
void SfxWorkWindow::ArrangeAutoHideWindows( SfxSplitWindow *pActSplitWin )
|
|
{
|
|
if ( m_nLock )
|
|
return;
|
|
|
|
tools::Rectangle aArea( aUpperClientArea );
|
|
for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
|
|
{
|
|
// Either dummy window or window in the auto-show-mode are processed
|
|
// (not pinned, FadeIn).
|
|
// Only the abandoned window may be invisible, because perhaps its
|
|
// size is just being calculated before it is displayed.
|
|
VclPtr<SfxSplitWindow> const & pSplitWin = pSplit[n];
|
|
bool bDummyWindow = !pSplitWin->IsFadeIn();
|
|
vcl::Window *pDummy = pSplitWin->GetSplitWindow();
|
|
vcl::Window *pWin = bDummyWindow ? pDummy : pSplitWin;
|
|
if ( (pSplitWin->IsPinned() && !bDummyWindow) || (!pWin->IsVisible() && pActSplitWin != pSplitWin) )
|
|
continue;
|
|
|
|
// Width and position of the dummy window as a starting point
|
|
Size aSize = pDummy->GetSizePixel();
|
|
Point aPos = pDummy->GetPosPixel();
|
|
|
|
switch ( n )
|
|
{
|
|
case 0 :
|
|
{
|
|
// Left SplitWindow
|
|
// Get the width of the Window yourself, if no DummyWindow
|
|
if ( !bDummyWindow )
|
|
aSize.setWidth( pSplitWin->GetSizePixel().Width() );
|
|
|
|
// If a Window is visible to the left, then the free region
|
|
// starts to the right from it, for example at the Client area
|
|
tools::Long nLeft = aPos.X() + aSize.Width();
|
|
if ( nLeft > aArea.Left() )
|
|
aArea.SetLeft( nLeft );
|
|
break;
|
|
}
|
|
case 1 :
|
|
{
|
|
// Right SplitWindow
|
|
// Position to correct the difference of the widths
|
|
aPos.AdjustX(aSize.Width() );
|
|
|
|
// Get the width of the Window yourself, if no DummyWindow
|
|
if ( !bDummyWindow )
|
|
aSize.setWidth( pSplitWin->GetSizePixel().Width() );
|
|
|
|
aPos.AdjustX( -(aSize.Width()) );
|
|
|
|
// If already a window is opened at the left side, then the
|
|
// right is not allowed to overlap this one.
|
|
if ( aPos.X() < aArea.Left() )
|
|
{
|
|
aPos.setX( aArea.Left() );
|
|
aSize.setWidth( aArea.GetWidth() );
|
|
}
|
|
|
|
// If a Window is visible to the right, then the free region
|
|
// starts to the left from it, for example at the Client area
|
|
tools::Long nRight = aPos.X();
|
|
if ( !aArea.IsWidthEmpty() && nRight < aArea.Right() )
|
|
aArea.SetRight( nRight );
|
|
break;
|
|
}
|
|
case 2 :
|
|
{
|
|
// Top SplitWindow
|
|
// Get the height of the Window yourself, if no DummyWindow
|
|
if ( !bDummyWindow )
|
|
aSize.setHeight( pSplitWin->GetSizePixel().Height() );
|
|
|
|
|
|
// Adjust width with regard to if a Window is already open
|
|
// to the left or right
|
|
aPos.setX( aArea.Left() );
|
|
aSize.setWidth( aArea.GetWidth() );
|
|
|
|
// If a Window is visible at the top, then the free region
|
|
// starts beneath it, for example at the Client area
|
|
tools::Long nTop = aPos.Y() + aSize.Height();
|
|
if ( nTop > aArea.Top() )
|
|
aArea.SetTop( nTop );
|
|
break;
|
|
}
|
|
case 3 :
|
|
{
|
|
// The bottom SplitWindow
|
|
// Position to correct the difference of the heights
|
|
aPos.AdjustY(aSize.Height() );
|
|
|
|
// Get the height of the Window yourself, if no DummyWindow
|
|
if ( !bDummyWindow )
|
|
aSize.setHeight( pSplitWin->GetSizePixel().Height() );
|
|
|
|
aPos.AdjustY( -(aSize.Height()) );
|
|
|
|
// Adjust width with regard to if a Window is already open
|
|
// to the left or right.
|
|
aPos.setX( aArea.Left() );
|
|
aSize.setWidth( aArea.GetWidth() );
|
|
|
|
// If already a window is opened at the top, then the
|
|
// bottom one is not allowed to overlap this one.
|
|
if ( aPos.Y() < aArea.Top() )
|
|
{
|
|
aPos.setY( aArea.Top() );
|
|
aSize.setHeight( aArea.GetHeight() );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !bDummyWindow )
|
|
// the FadeIn-Window is a Floating window, which coordinates are
|
|
// set in Screen coordinates.
|
|
pSplitWin->SetPosSizePixel( pWorkWin->OutputToScreenPixel(aPos), aSize );
|
|
else
|
|
// the docked DummyWindow
|
|
pDummy->SetPosSizePixel( aPos, aSize );
|
|
}
|
|
}
|
|
|
|
tools::Rectangle SfxWorkWindow::GetFreeArea( bool bAutoHide ) const
|
|
{
|
|
if ( bAutoHide )
|
|
{
|
|
tools::Rectangle aArea( aClientArea );
|
|
for ( sal_uInt16 n=0; n<SFX_SPLITWINDOWS_MAX; n++ )
|
|
{
|
|
if ( pSplit[n]->IsPinned() || !pSplit[n]->IsVisible() )
|
|
continue;
|
|
|
|
Size aSize = pSplit[n]->GetSizePixel();
|
|
switch ( n )
|
|
{
|
|
case 0 :
|
|
aArea.AdjustLeft(aSize.Width() );
|
|
break;
|
|
case 1 :
|
|
aArea.AdjustRight( -(aSize.Width()) );
|
|
break;
|
|
case 2 :
|
|
aArea.AdjustTop(aSize.Height() );
|
|
break;
|
|
case 3 :
|
|
aArea.AdjustBottom( -(aSize.Height()) );
|
|
break;
|
|
}
|
|
}
|
|
|
|
return aArea;
|
|
}
|
|
else
|
|
return aClientArea;
|
|
}
|
|
|
|
void SfxWorkWindow::SetActiveChild_Impl( vcl::Window *pChild )
|
|
{
|
|
pActiveChild = pChild;
|
|
}
|
|
|
|
void SfxWorkWindow::DataChanged_Impl()
|
|
{
|
|
ArrangeChildren_Impl();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|