Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/dialog/dockwin.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <svl/eitem.hxx>
21
#include <svl/solar.hrc>
22
#include <vcl/event.hxx>
23
#include <vcl/settings.hxx>
24
25
#include <vcl/svapp.hxx>
26
#include <vcl/timer.hxx>
27
#include <vcl/idle.hxx>
28
#include <vcl/weld/Builder.hxx>
29
#include <o3tl/safeint.hxx>
30
#include <o3tl/string_view.hxx>
31
#include <osl/diagnose.h>
32
#include <toolkit/helper/vclunohelper.hxx>
33
#include <tools/debug.hxx>
34
#include <comphelper/processfactory.hxx>
35
#include <comphelper/propertysequence.hxx>
36
#include <svl/itemset.hxx>
37
38
#include <sfx2/chalign.hxx>
39
#include <sfx2/dockwin.hxx>
40
#include <sfx2/bindings.hxx>
41
#include <sfx2/viewfrm.hxx>
42
#include <sfx2/dispatch.hxx>
43
#include <workwin.hxx>
44
#include <splitwin.hxx>
45
#include <sfx2/viewsh.hxx>
46
47
#include <com/sun/star/beans/UnknownPropertyException.hpp>
48
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
49
#include <com/sun/star/awt/XWindow.hpp>
50
#include <com/sun/star/uno/XComponentContext.hpp>
51
#include <com/sun/star/frame/ModuleManager.hpp>
52
#include <com/sun/star/container/XNameAccess.hpp>
53
#include <com/sun/star/ui/theWindowStateConfiguration.hpp>
54
#include <com/sun/star/ui/theWindowContentFactoryManager.hpp>
55
56
0
#define MAX_TOGGLEAREA_WIDTH        20
57
0
#define MAX_TOGGLEAREA_HEIGHT       20
58
59
using namespace ::com::sun::star;
60
61
// If you want to change the number you also have to:
62
// - Add new slot ids to sfxsids.hrc
63
// - Add new slots to frmslots.sdi
64
// - Add new slot definitions to sfx.sdi
65
const int NUM_OF_DOCKINGWINDOWS = 10;
66
67
namespace {
68
69
class SfxTitleDockingWindow : public SfxDockingWindow
70
{
71
    VclPtr<vcl::Window>   m_pWrappedWindow;
72
73
public:
74
    SfxTitleDockingWindow(SfxBindings& rBindings, SfxChildWindow* pChildWin, vcl::Window* pParent,
75
                          WinBits nBits);
76
    virtual             ~SfxTitleDockingWindow() override;
77
    virtual void        dispose() override;
78
79
0
    vcl::Window*        GetWrappedWindow() const { return m_pWrappedWindow; }
80
    void                SetWrappedWindow(vcl::Window* const pWindow);
81
82
    virtual void        StateChanged( StateChangedType nType ) override;
83
    virtual void        Resize() override;
84
    virtual void        Resizing( Size& rSize ) override;
85
};
86
87
    struct WindowState
88
    {
89
        OUString sTitle;
90
    };
91
}
92
93
static bool lcl_getWindowState( const uno::Reference< container::XNameAccess >& xWindowStateMgr, const OUString& rResourceURL, WindowState& rWindowState )
94
0
{
95
0
    bool bResult = false;
96
97
0
    try
98
0
    {
99
0
        uno::Any a;
100
0
        uno::Sequence< beans::PropertyValue > aWindowState;
101
0
        a = xWindowStateMgr->getByName( rResourceURL );
102
0
        if ( a >>= aWindowState )
103
0
        {
104
0
            for (const auto& rProp : aWindowState)
105
0
            {
106
0
                if ( rProp.Name == "UIName" )
107
0
                {
108
0
                    rProp.Value >>= rWindowState.sTitle;
109
0
                }
110
0
            }
111
0
        }
112
113
0
        bResult = true;
114
0
    }
115
0
    catch ( container::NoSuchElementException& )
116
0
    {
117
0
        bResult = false;
118
0
    }
119
120
0
    return bResult;
121
0
}
122
123
SfxDockingWrapper::SfxDockingWrapper(vcl::Window* pParentWnd, sal_uInt16 nId,
124
                                     SfxBindings& rBindings, SfxChildWinInfo& rInfo)
125
0
    : SfxChildWindow(pParentWnd, nId)
126
0
{
127
0
    const uno::Reference< uno::XComponentContext >& xContext = ::comphelper::getProcessComponentContext();
128
129
0
    VclPtr<SfxTitleDockingWindow> pTitleDockWindow = VclPtr<SfxTitleDockingWindow>::Create(
130
0
        rBindings, this, pParentWnd, WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK);
131
0
    SetWindow( pTitleDockWindow );
132
133
    // Use factory manager to retrieve XWindow factory. That can be used to instantiate
134
    // the real window factory.
135
0
    uno::Reference< lang::XSingleComponentFactory > xFactoryMgr = ui::theWindowContentFactoryManager::get(xContext);
136
137
0
    SfxDispatcher* pDispatcher = rBindings.GetDispatcher();
138
0
    uno::Reference< frame::XFrame > xFrame = pDispatcher->GetFrame()->GetFrame().GetFrameInterface();
139
    // create a resource URL from the nId provided by the sfx2
140
0
    OUString aResourceURL =  "private:resource/dockingwindow/" + OUString::number(nId);
141
0
    uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
142
0
    {
143
0
        {"Frame", uno::Any(xFrame)},
144
0
        {"ResourceURL", uno::Any(aResourceURL)},
145
0
    }));
146
147
0
    uno::Reference< awt::XWindow > xWindow;
148
0
    try
149
0
    {
150
0
        xWindow.set(
151
0
            xFactoryMgr->createInstanceWithArgumentsAndContext( aArgs, xContext ),
152
0
            uno::UNO_QUERY );
153
154
0
        static uno::WeakReference< frame::XModuleManager2 >  s_xModuleManager;
155
156
0
        uno::Reference< frame::XModuleManager2 > xModuleManager( s_xModuleManager );
157
0
        if ( !xModuleManager.is() )
158
0
        {
159
0
            xModuleManager = frame::ModuleManager::create(xContext);
160
0
            s_xModuleManager = xModuleManager;
161
0
        }
162
163
0
        static uno::WeakReference< container::XNameAccess > s_xWindowStateConfiguration;
164
165
0
        uno::Reference< container::XNameAccess > xWindowStateConfiguration( s_xWindowStateConfiguration );
166
0
        if ( !xWindowStateConfiguration.is() )
167
0
        {
168
0
            xWindowStateConfiguration = ui::theWindowStateConfiguration::get( xContext );
169
0
            s_xWindowStateConfiguration = xWindowStateConfiguration;
170
0
        }
171
172
0
        OUString sModuleIdentifier = xModuleManager->identify( xFrame );
173
174
0
        uno::Reference< container::XNameAccess > xModuleWindowState(
175
0
                                                    xWindowStateConfiguration->getByName( sModuleIdentifier ),
176
0
                                                    uno::UNO_QUERY );
177
0
        if ( xModuleWindowState.is() )
178
0
        {
179
0
            WindowState aDockWinState;
180
0
            if ( lcl_getWindowState( xModuleWindowState, aResourceURL, aDockWinState ))
181
0
                pTitleDockWindow->SetText( aDockWinState.sTitle );
182
0
        }
183
0
    }
184
0
    catch ( beans::UnknownPropertyException& )
185
0
    {
186
0
    }
187
0
    catch ( uno::RuntimeException& )
188
0
    {
189
0
    }
190
0
    catch ( uno::Exception& )
191
0
    {
192
0
    }
193
194
0
    VclPtr<vcl::Window> pContentWindow = VCLUnoHelper::GetWindow(xWindow);
195
0
    if ( pContentWindow )
196
0
        pContentWindow->SetStyle( pContentWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
197
0
    pTitleDockWindow->SetWrappedWindow(pContentWindow);
198
199
0
    GetWindow()->SetOutputSizePixel( Size( 270, 240 ) );
200
201
0
    static_cast<SfxDockingWindow*>(GetWindow())->Initialize(rInfo);
202
0
    SetHideNotDelete( true );
203
0
}
204
205
std::unique_ptr<SfxChildWindow> SfxDockingWrapper::CreateImpl(vcl::Window* pParent, sal_uInt16 nId,
206
                                                              SfxBindings& rBindings,
207
                                                              SfxChildWinInfo& rInfo)
208
0
{
209
0
    return std::make_unique<SfxDockingWrapper>(pParent, nId, rBindings, rInfo);
210
0
}
211
212
void SfxDockingWrapper::RegisterChildWindow (bool bVis, SfxModule *pMod, SfxChildWindowFlags nFlags)
213
25
{
214
    // pre-register a couple of docking windows
215
275
    for (int i=0; i < NUM_OF_DOCKINGWINDOWS; i++ )
216
250
    {
217
250
        sal_uInt16 nID = sal_uInt16(SID_DOCKWIN_START+i);
218
250
        SfxChildWinFactory aFact( SfxDockingWrapper::CreateImpl, nID, 0xffff );
219
250
        aFact.aInfo.nFlags |= nFlags;
220
250
        aFact.aInfo.bVisible = bVis;
221
250
        SfxChildWindow::RegisterChildWindow(pMod, aFact);
222
250
    }
223
25
}
224
225
SfxChildWinInfo  SfxDockingWrapper::GetInfo() const
226
0
{
227
0
    SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
228
0
    static_cast<SfxDockingWindow*>(GetWindow())->FillInfo( aInfo );
229
0
    return aInfo;
230
0
};
231
232
SfxTitleDockingWindow::SfxTitleDockingWindow(SfxBindings& rBindings, SfxChildWindow* pChildWin,
233
                                             vcl::Window* pParent, WinBits nBits)
234
0
    : SfxDockingWindow(rBindings, pChildWin, pParent, nBits)
235
0
    , m_pWrappedWindow(nullptr)
236
0
{
237
0
}
238
239
SfxTitleDockingWindow::~SfxTitleDockingWindow()
240
0
{
241
0
    disposeOnce();
242
0
}
243
244
void SfxTitleDockingWindow::dispose()
245
0
{
246
0
    m_pWrappedWindow.disposeAndClear();
247
0
    SfxDockingWindow::dispose();
248
0
}
249
250
void SfxTitleDockingWindow::SetWrappedWindow( vcl::Window* const pWindow )
251
0
{
252
0
    m_pWrappedWindow = pWindow;
253
0
    if (m_pWrappedWindow)
254
0
    {
255
0
        m_pWrappedWindow->SetParent(this);
256
0
        m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
257
0
        m_pWrappedWindow->Show();
258
0
    }
259
0
}
260
261
void SfxTitleDockingWindow::StateChanged( StateChangedType nType )
262
0
{
263
0
    if ( nType == StateChangedType::InitShow )
264
0
    {
265
0
        vcl::Window* pWindow = GetWrappedWindow();
266
0
        if ( pWindow )
267
0
        {
268
0
            pWindow->SetSizePixel( GetOutputSizePixel() );
269
0
            pWindow->Show();
270
0
        }
271
0
    }
272
273
0
    SfxDockingWindow::StateChanged(nType);
274
0
}
275
276
void SfxTitleDockingWindow::Resize()
277
0
{
278
0
    SfxDockingWindow::Resize();
279
0
    if (m_pWrappedWindow)
280
0
        m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
281
0
}
282
283
void SfxTitleDockingWindow::Resizing( Size &rSize )
284
0
{
285
0
    SfxDockingWindow::Resizing( rSize );
286
0
    if (m_pWrappedWindow)
287
0
        m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
288
0
}
289
290
static bool lcl_checkDockingWindowID( sal_uInt16 nID )
291
0
{
292
0
    return nID >= SID_DOCKWIN_START && nID < o3tl::make_unsigned(SID_DOCKWIN_START+NUM_OF_DOCKINGWINDOWS);
293
0
}
294
295
static SfxWorkWindow* lcl_getWorkWindowFromXFrame( const uno::Reference< frame::XFrame >& rFrame )
296
0
{
297
    // We need to find the corresponding SfxFrame of our XFrame
298
0
    SfxFrame* pFrame  = SfxFrame::GetFirst();
299
0
    SfxFrame* pXFrame = nullptr;
300
0
    while ( pFrame )
301
0
    {
302
0
        uno::Reference< frame::XFrame > xViewShellFrame( pFrame->GetFrameInterface() );
303
0
        if ( xViewShellFrame == rFrame )
304
0
        {
305
0
            pXFrame = pFrame;
306
0
            break;
307
0
        }
308
0
        else
309
0
            pFrame = SfxFrame::GetNext( *pFrame );
310
0
    }
311
312
    // If we have a SfxFrame we can retrieve the work window (Sfx layout manager for docking windows)
313
0
    if ( pXFrame )
314
0
        return pXFrame->GetWorkWindow_Impl();
315
0
    else
316
0
        return nullptr;
317
0
}
318
319
/** Factory function used by the framework layout manager to "create" a docking window with a special name.
320
    The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot range located
321
    in sfxsids.hrc (currently SID_DOCKWIN_START = 9800).
322
*/
323
void SfxDockingWindowFactory( const uno::Reference< frame::XFrame >& rFrame, std::u16string_view rDockingWindowName )
324
0
{
325
0
    SolarMutexGuard aGuard;
326
0
    sal_uInt16 nID = sal_uInt16(o3tl::toInt32(rDockingWindowName));
327
328
    // Check the range of the provided ID otherwise nothing will happen
329
0
    if ( !lcl_checkDockingWindowID( nID ))
330
0
        return;
331
332
0
    SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame );
333
0
    if ( pWorkWindow )
334
0
    {
335
0
        SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID);
336
0
        if ( !pChildWindow )
337
0
        {
338
            // Register window at the workwindow child window list
339
0
            pWorkWindow->SetChildWindow_Impl( nID, true, false );
340
0
        }
341
0
    }
342
0
}
343
344
/** Function used by the framework layout manager to determine the visibility state of a docking window with
345
    a special name. The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot
346
    range located in sfxsids.hrc (currently SID_DOCKWIN_START = 9800).
347
*/
348
bool IsDockingWindowVisible( const uno::Reference< frame::XFrame >& rFrame, std::u16string_view rDockingWindowName )
349
0
{
350
0
    SolarMutexGuard aGuard;
351
352
0
    sal_uInt16 nID = sal_uInt16(o3tl::toInt32(rDockingWindowName));
353
354
    // Check the range of the provided ID otherwise nothing will happen
355
0
    if ( lcl_checkDockingWindowID( nID ))
356
0
    {
357
0
        SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame );
358
0
        if ( pWorkWindow )
359
0
        {
360
0
            SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID);
361
0
            if ( pChildWindow )
362
0
                return true;
363
0
        }
364
0
    }
365
366
0
    return false;
367
0
}
368
369
class SfxDockingWindow_Impl
370
{
371
friend class SfxDockingWindow;
372
373
    SfxChildAlignment   eLastAlignment;
374
    SfxChildAlignment   eDockAlignment;
375
    bool                bConstructed;
376
    Size                aMinSize;
377
    VclPtr<SfxSplitWindow>  pSplitWin;
378
    Idle                aMoveIdle;
379
380
    // The following members are only valid in the time from startDocking to
381
    // EndDocking:
382
    Size                aSplitSize;
383
    tools::Long                nHorizontalSize;
384
    tools::Long                nVerticalSize;
385
    sal_uInt16          nLine;
386
    sal_uInt16          nPos;
387
    sal_uInt16          nDockLine;
388
    sal_uInt16          nDockPos;
389
    bool                bNewLine;
390
    bool                bDockingPrevented;
391
    vcl::WindowData aWinState;
392
393
    explicit            SfxDockingWindow_Impl(SfxDockingWindow *pBase);
394
    SfxChildAlignment   GetLastAlignment() const
395
0
                        { return eLastAlignment; }
396
    void                SetLastAlignment(SfxChildAlignment eAlign)
397
0
                        { eLastAlignment = eAlign; }
398
    SfxChildAlignment   GetDockAlignment() const
399
0
                        { return eDockAlignment; }
400
    void                SetDockAlignment(SfxChildAlignment eAlign)
401
0
                        { eDockAlignment = eAlign; }
402
};
403
404
SfxDockingWindow_Impl::SfxDockingWindow_Impl(SfxDockingWindow* pBase)
405
0
    :eLastAlignment(SfxChildAlignment::NOALIGNMENT)
406
0
    ,eDockAlignment(SfxChildAlignment::NOALIGNMENT)
407
0
    ,bConstructed(false)
408
0
    ,pSplitWin(nullptr)
409
0
    ,aMoveIdle( "sfx::SfxDockingWindow_Impl aMoveIdle" )
410
0
    ,nHorizontalSize(0)
411
0
    ,nVerticalSize(0)
412
0
    ,nLine(0)
413
0
    ,nPos(0)
414
0
    ,nDockLine(0)
415
0
    ,nDockPos(0)
416
0
    ,bNewLine(false)
417
0
    ,bDockingPrevented(false)
418
0
{
419
0
    aMoveIdle.SetPriority(TaskPriority::RESIZE);
420
0
    aMoveIdle.SetInvokeHandler(LINK(pBase,SfxDockingWindow,TimerHdl));
421
0
}
422
423
/*  [Description]
424
425
    This virtual method of the class FloatingWindow keeps track of changes in
426
    FloatingSize. If this method is overridden by a derived class,
427
    then the FloatingWindow: Resize() must also be called.
428
*/
429
void SfxDockingWindow::Resize()
430
0
{
431
0
    ResizableDockingWindow::Resize();
432
0
    Invalidate();
433
0
    if (!m_pImpl || !m_pImpl->bConstructed || !m_pMgr)
434
0
        return;
435
436
0
    if ( IsFloatingMode() )
437
0
    {
438
        // start timer for saving window status information
439
0
        m_pImpl->aMoveIdle.Start();
440
0
    }
441
0
    else
442
0
    {
443
0
        Size aSize( GetSizePixel() );
444
0
        switch (m_pImpl->GetDockAlignment())
445
0
        {
446
0
            case SfxChildAlignment::LEFT:
447
0
            case SfxChildAlignment::FIRSTLEFT:
448
0
            case SfxChildAlignment::LASTLEFT:
449
0
            case SfxChildAlignment::RIGHT:
450
0
            case SfxChildAlignment::FIRSTRIGHT:
451
0
            case SfxChildAlignment::LASTRIGHT:
452
0
                m_pImpl->nHorizontalSize = aSize.Width();
453
0
                m_pImpl->aSplitSize = aSize;
454
0
                break;
455
0
            case SfxChildAlignment::TOP:
456
0
            case SfxChildAlignment::LOWESTTOP:
457
0
            case SfxChildAlignment::HIGHESTTOP:
458
0
            case SfxChildAlignment::BOTTOM:
459
0
            case SfxChildAlignment::HIGHESTBOTTOM:
460
0
            case SfxChildAlignment::LOWESTBOTTOM:
461
0
                m_pImpl->nVerticalSize = aSize.Height();
462
0
                m_pImpl->aSplitSize = aSize;
463
0
                break;
464
0
            default:
465
0
                break;
466
0
        }
467
0
    }
468
0
}
469
470
/*  [Description]
471
472
    This virtual method of the class DockingWindow makes it possible to
473
    intervene in the switching of the floating mode.
474
    If this method is overridden by a derived class,
475
    then the SfxDockingWindow::PrepareToggleFloatingMode() must be called
476
    afterwards, if not FALSE is returned.
477
*/
478
bool SfxDockingWindow::PrepareToggleFloatingMode()
479
0
{
480
0
    if (!m_pImpl || !m_pImpl->bConstructed)
481
0
        return true;
482
483
0
    if ((Application::IsInModalMode() && IsFloatingMode()) || !m_pMgr)
484
0
        return false;
485
486
0
    if (m_pImpl->bDockingPrevented)
487
0
        return false;
488
489
0
    if (!IsFloatingMode())
490
0
    {
491
        // Test, if FloatingMode is permitted.
492
0
        if ( CheckAlignment(GetAlignment(),SfxChildAlignment::NOALIGNMENT) != SfxChildAlignment::NOALIGNMENT )
493
0
            return false;
494
495
0
        if (m_pImpl->pSplitWin)
496
0
        {
497
            // The DockingWindow is inside a SplitWindow and will be teared of.
498
0
            m_pImpl->pSplitWin->RemoveWindow(this /*, sal_False*/);
499
0
            m_pImpl->pSplitWin = nullptr;
500
0
        }
501
0
    }
502
0
    else if (m_pMgr)
503
0
    {
504
0
        m_pImpl->aWinState = GetFloatingWindow()->GetWindowState();
505
506
        // Test if it is allowed to dock,
507
0
        if (CheckAlignment(GetAlignment(), m_pImpl->GetLastAlignment())
508
0
            == SfxChildAlignment::NOALIGNMENT)
509
0
            return false;
510
511
        // Test, if the Workwindow allows for docking at the moment.
512
0
        SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
513
0
        if ( !pWorkWin->IsDockingAllowed() || !pWorkWin->IsInternalDockingAllowed() )
514
0
            return false;
515
0
    }
516
517
0
    return true;
518
0
}
519
520
/*  [Description]
521
522
    This virtual method of the DockingWindow class sets the internal data of
523
    the SfxDockingWindow and ensures the correct alignment on the parent window.
524
    Through PrepareToggleFloatMode and Initialize it is ensured that
525
    m_pImpl-> GetLastAlignment() always delivers an allowed alignment. If this
526
    method is overridden by a derived class, then first the
527
    SfxDockingWindow::ToggleFloatingMode() must be called.
528
*/
529
void SfxDockingWindow::ToggleFloatingMode()
530
0
{
531
0
    if (!m_pImpl || !m_pImpl->bConstructed || !m_pMgr)
532
0
        return;                                 // No Handler call
533
534
    // Remember old alignment and then switch.
535
    // SV has already switched, but the alignment SfxDockingWindow is still
536
    // the old one. What I was before?
537
0
    SfxChildAlignment eLastAlign = GetAlignment();
538
539
0
    SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
540
541
0
    if (IsFloatingMode())
542
0
    {
543
0
        SetAlignment(SfxChildAlignment::NOALIGNMENT);
544
0
        if (m_pImpl->aWinState.mask() != vcl::WindowDataMask::NONE)
545
0
            GetFloatingWindow()->SetWindowState(m_pImpl->aWinState);
546
0
        else
547
0
            GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
548
0
    }
549
0
    else
550
0
    {
551
0
        if (m_pImpl->GetDockAlignment() == eLastAlign)
552
0
        {
553
            // If ToggleFloatingMode was called, but the DockAlignment still
554
            // is unchanged, then this means that it must have been a toggling
555
            // through DClick, so use last alignment
556
0
            SetAlignment(m_pImpl->GetLastAlignment());
557
0
        }
558
0
        else
559
0
        {
560
561
            // Toggling was triggered by dragging
562
0
            m_pImpl->nLine = m_pImpl->nDockLine;
563
0
            m_pImpl->nPos = m_pImpl->nDockPos;
564
0
            SetAlignment(m_pImpl->GetDockAlignment());
565
0
        }
566
567
        // The DockingWindow is now in a SplitWindow
568
0
        m_pImpl->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
569
570
        // The LastAlignment is still the last docked
571
0
        SfxSplitWindow* pSplit = pWorkWin->GetSplitWindow_Impl(m_pImpl->GetLastAlignment());
572
573
0
        DBG_ASSERT( pSplit, "LastAlignment is not correct!" );
574
0
        if (pSplit && pSplit != m_pImpl->pSplitWin)
575
0
            pSplit->ReleaseWindow_Impl(this);
576
0
        if (m_pImpl->GetDockAlignment() == eLastAlign)
577
0
            m_pImpl->pSplitWin->InsertWindow(this, m_pImpl->aSplitSize);
578
0
        else
579
0
            m_pImpl->pSplitWin->InsertWindow(this, m_pImpl->aSplitSize, m_pImpl->nLine,
580
0
                                             m_pImpl->nPos, m_pImpl->bNewLine);
581
0
        if (!m_pImpl->pSplitWin->IsFadeIn())
582
0
            m_pImpl->pSplitWin->FadeIn();
583
0
    }
584
585
    // Keep the old alignment for the next toggle; set it only now due to the
586
    // unregister SplitWindow!
587
0
    m_pImpl->SetLastAlignment(eLastAlign);
588
589
    // Reset DockAlignment, if EndDocking is still called
590
0
    m_pImpl->SetDockAlignment(GetAlignment());
591
592
    // Dock or undock SfxChildWindow correctly.
593
0
    pWorkWin->ConfigChild_Impl(SfxChildIdentifier::SPLITWINDOW, SfxDockingConfig::TOGGLEFLOATMODE,
594
0
                               m_pMgr->GetType());
595
0
}
596
597
/*  [Description]
598
599
    This virtual method of the DockingWindow class takes the inner and outer
600
    docking rectangle from the parent window. If this method is overridden by
601
    a derived class, then SfxDockingWindow:StartDocking() has to be called at
602
    the end.
603
*/
604
void SfxDockingWindow::StartDocking()
605
0
{
606
0
    if (!m_pImpl || !m_pImpl->bConstructed || !m_pMgr)
607
0
        return;
608
0
    SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
609
0
    pWorkWin->ConfigChild_Impl(SfxChildIdentifier::SPLITWINDOW, SfxDockingConfig::SETDOCKINGRECTS,
610
0
                               m_pMgr->GetType());
611
0
    m_pImpl->SetDockAlignment(GetAlignment());
612
613
0
    if (m_pImpl->pSplitWin)
614
0
    {
615
        // Get the current docking data
616
0
        m_pImpl->pSplitWin->GetWindowPos(this, m_pImpl->nLine, m_pImpl->nPos);
617
0
        m_pImpl->nDockLine = m_pImpl->nLine;
618
0
        m_pImpl->nDockPos = m_pImpl->nPos;
619
0
        m_pImpl->bNewLine = false;
620
0
    }
621
0
}
622
623
/*  [Description]
624
625
    This virtual method of the DockingWindow class calculates the current
626
    tracking rectangle. For this purpose the method CalcAlignment(RPOs, rRect)
627
    is used, the behavior can be influenced by the derived classes (see below).
628
    This method should if possible not be overwritten.
629
*/
630
bool SfxDockingWindow::Docking( const Point& rPos, tools::Rectangle& rRect )
631
0
{
632
0
    if ( Application::IsInModalMode() )
633
0
        return true;
634
635
0
    if (!m_pImpl || !m_pImpl->bConstructed || !m_pMgr)
636
0
    {
637
0
        rRect.SetSize( Size() );
638
0
        return IsFloatingMode();
639
0
    }
640
641
0
    SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
642
0
    if (m_pImpl->bDockingPrevented || !pWorkWin->IsInternalDockingAllowed())
643
0
        return false;
644
645
0
    bool bFloatMode = false;
646
647
0
    if ( GetOuterRect().Contains( rPos ) )
648
0
    {
649
        // Mouse within OuterRect: calculate Alignment and Rectangle
650
0
        SfxChildAlignment eAlign = CalcAlignment(rPos, rRect);
651
0
        if (eAlign == SfxChildAlignment::NOALIGNMENT)
652
0
            bFloatMode = true;
653
0
        m_pImpl->SetDockAlignment(eAlign);
654
0
    }
655
0
    else
656
0
    {
657
        // Mouse is not within OuterRect: must be FloatingWindow
658
        // Is this allowed?
659
0
        if (CheckAlignment(m_pImpl->GetDockAlignment(), SfxChildAlignment::NOALIGNMENT)
660
0
            != SfxChildAlignment::NOALIGNMENT)
661
0
            return false;
662
0
        bFloatMode = true;
663
0
        if (SfxChildAlignment::NOALIGNMENT != m_pImpl->GetDockAlignment())
664
0
        {
665
            // Due to a bug the rRect may only be changed when the
666
            // alignment is changed!
667
0
            m_pImpl->SetDockAlignment(SfxChildAlignment::NOALIGNMENT);
668
0
            rRect.SetSize(CalcDockingSize(SfxChildAlignment::NOALIGNMENT));
669
0
        }
670
0
    }
671
672
0
    return bFloatMode;
673
0
}
674
675
/** Virtual method of the DockingWindow class ensures the correct alignment on
676
    the parent window. If this method is overridden by a derived class, then
677
    SfxDockingWindow::EndDocking() must be called first.
678
*/
679
void SfxDockingWindow::EndDocking( const tools::Rectangle& rRect, bool bFloatMode )
680
0
{
681
0
    if (!m_pImpl || !m_pImpl->bConstructed || IsDockingCanceled() || !m_pMgr)
682
0
        return;
683
684
0
    SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
685
686
    // If the alignment changes and the window is in a docked state in a
687
    // SplitWindow, then it must be re-registered. If it is docked again,
688
    // PrepareToggleFloatingMode() and ToggleFloatingMode() perform the
689
    // re-registered
690
0
    bool bReArrange = !bFloatMode;
691
692
0
    if ( bReArrange )
693
0
    {
694
0
        if (GetAlignment() != m_pImpl->GetDockAlignment())
695
0
        {
696
            // before Show() is called must the reassignment have been made,
697
            // therefore the base class can not be called
698
0
            if ( IsFloatingMode() )
699
0
                Show( false, ShowFlags::NoFocusChange );
700
701
            // Set the size for toggling.
702
0
            m_pImpl->aSplitSize = rRect.GetSize();
703
0
            if ( IsFloatingMode() )
704
0
            {
705
0
                SetFloatingMode( bFloatMode );
706
0
                if ( IsFloatingMode() )
707
0
                    Show( true, ShowFlags::NoFocusChange );
708
0
            }
709
0
            else
710
0
            {
711
0
                m_pImpl->pSplitWin->RemoveWindow(this, false);
712
0
                m_pImpl->nLine = m_pImpl->nDockLine;
713
0
                m_pImpl->nPos = m_pImpl->nDockPos;
714
0
                m_pImpl->pSplitWin->ReleaseWindow_Impl(this);
715
0
                m_pImpl->pSplitWin = pWorkWin->GetSplitWindow_Impl(m_pImpl->GetDockAlignment());
716
0
                m_pImpl->pSplitWin->InsertWindow(this, m_pImpl->aSplitSize, m_pImpl->nDockLine,
717
0
                                                 m_pImpl->nDockPos, m_pImpl->bNewLine);
718
0
                if (!m_pImpl->pSplitWin->IsFadeIn())
719
0
                    m_pImpl->pSplitWin->FadeIn();
720
0
            }
721
0
        }
722
0
        else if (m_pImpl->nLine != m_pImpl->nDockLine || m_pImpl->nPos != m_pImpl->nDockPos
723
0
                 || m_pImpl->bNewLine)
724
0
        {
725
            // Moved within Splitwindows
726
0
            if (m_pImpl->nLine != m_pImpl->nDockLine)
727
0
                m_pImpl->aSplitSize = rRect.GetSize();
728
0
            m_pImpl->pSplitWin->MoveWindow(this, m_pImpl->aSplitSize, m_pImpl->nDockLine,
729
0
                                           m_pImpl->nDockPos, m_pImpl->bNewLine);
730
0
        }
731
0
    }
732
0
    else
733
0
    {
734
0
        ResizableDockingWindow::EndDocking(rRect, bFloatMode);
735
0
    }
736
737
0
    SetAlignment(IsFloatingMode() ? SfxChildAlignment::NOALIGNMENT : m_pImpl->GetDockAlignment());
738
0
}
739
740
/*  [Description]
741
742
    Virtual method of the DockingWindow class. Here, the interactive resize in
743
    FloatingMode can be influenced, for example by only allowing for discrete
744
    values for width and / or height. The base implementation prevents that the
745
    output size is smaller than one set with SetMinOutputSizePixel().
746
*/
747
void SfxDockingWindow::Resizing( Size& /*rSize*/ )
748
0
{
749
750
0
}
751
752
/*  [Description]
753
754
    Constructor for the SfxDockingWindow class. A SfxChildWindow will be
755
    required because the docking is implemented in Sfx through SfxChildWindows.
756
*/
757
SfxDockingWindow::SfxDockingWindow(SfxBindings& rBindings, SfxChildWindow* pCW,
758
                                   vcl::Window* pParent, WinBits nWinBits)
759
0
    : ResizableDockingWindow(pParent, nWinBits)
760
0
    , m_rBindings(rBindings)
761
0
    , m_pMgr(pCW)
762
0
{
763
0
    m_pImpl.reset(new SfxDockingWindow_Impl(this));
764
0
}
Unexecuted instantiation: SfxDockingWindow::SfxDockingWindow(SfxBindings&, SfxChildWindow*, vcl::Window*, long)
Unexecuted instantiation: SfxDockingWindow::SfxDockingWindow(SfxBindings&, SfxChildWindow*, vcl::Window*, long)
765
766
/** Constructor for the SfxDockingWindow class. A SfxChildWindow will be
767
    required because the docking is implemented in Sfx through SfxChildWindows.
768
*/
769
SfxDockingWindow::SfxDockingWindow(SfxBindings& rBindings, SfxChildWindow* pCW,
770
                                   vcl::Window* pParent, const OUString& rID,
771
                                   const OUString& rUIXMLDescription)
772
0
    : ResizableDockingWindow(pParent)
773
0
    , m_rBindings(rBindings)
774
0
    , m_pMgr(pCW)
775
0
{
776
0
    m_xBuilder = Application::CreateInterimBuilder(m_xBox, rUIXMLDescription, true);
777
0
    m_xContainer = m_xBuilder->weld_box(rID);
778
779
0
    m_pImpl.reset(new SfxDockingWindow_Impl(this));
780
0
}
Unexecuted instantiation: SfxDockingWindow::SfxDockingWindow(SfxBindings&, SfxChildWindow*, vcl::Window*, rtl::OUString const&, rtl::OUString const&)
Unexecuted instantiation: SfxDockingWindow::SfxDockingWindow(SfxBindings&, SfxChildWindow*, vcl::Window*, rtl::OUString const&, rtl::OUString const&)
781
782
/** Initialization of the SfxDockingDialog class via a SfxChildWinInfo.
783
    The initialization is done only in a 2nd step after the constructor, this
784
    constructor should be called from the derived class or from the
785
    SfxChildWindows.
786
*/
787
void SfxDockingWindow::Initialize(SfxChildWinInfo& rInfo)
788
0
{
789
0
    if (!m_pMgr)
790
0
    {
791
0
        m_pImpl->SetDockAlignment(SfxChildAlignment::NOALIGNMENT);
792
0
        m_pImpl->bConstructed = true;
793
0
        return;
794
0
    }
795
796
0
    if (rInfo.nFlags & SfxChildWindowFlags::FORCEDOCK)
797
0
        m_pImpl->bDockingPrevented = true;
798
799
0
    m_pImpl->aSplitSize = GetOutputSizePixel();
800
0
    if ( !GetFloatingSize().Width() )
801
0
    {
802
0
        Size aMinSize( GetMinOutputSizePixel() );
803
0
        SetFloatingSize(m_pImpl->aSplitSize);
804
0
        if (m_pImpl->aSplitSize.Width() < aMinSize.Width())
805
0
            m_pImpl->aSplitSize.setWidth(aMinSize.Width());
806
0
        if (m_pImpl->aSplitSize.Height() < aMinSize.Height())
807
0
            m_pImpl->aSplitSize.setHeight(aMinSize.Height());
808
0
    }
809
810
0
    bool bVertHorzRead( false );
811
0
    if (!rInfo.aExtraString.isEmpty())
812
0
    {
813
        // get information about alignment, split size and position in SplitWindow
814
0
        OUString aStr;
815
0
        sal_Int32 nPos = rInfo.aExtraString.indexOf("AL:");
816
0
        if ( nPos != -1 )
817
0
        {
818
            // alignment information
819
0
            sal_Int32 n1 = rInfo.aExtraString.indexOf('(', nPos);
820
0
            if ( n1 != -1 )
821
0
            {
822
0
                sal_Int32 n2 = rInfo.aExtraString.indexOf(')', n1);
823
0
                if ( n2 != -1 )
824
0
                {
825
                    // extract alignment information from extrastring
826
0
                    aStr = rInfo.aExtraString.copy(nPos, n2 - nPos + 1);
827
0
                    rInfo.aExtraString = rInfo.aExtraString.replaceAt(nPos, n2 - nPos + 1, u"");
828
0
                    aStr = aStr.replaceAt(nPos, n1-nPos+1, u"");
829
0
                }
830
0
            }
831
0
        }
832
833
0
        if ( !aStr.isEmpty() )
834
0
        {
835
            // accept window state only if alignment is also set
836
0
            m_pImpl->aWinState = rInfo.aWinState;
837
838
            // check for valid alignment
839
0
            SfxChildAlignment eLocalAlignment = static_cast<SfxChildAlignment>(static_cast<sal_uInt16>(aStr.toInt32()));
840
0
            bool bIgnoreFloatConfig = (eLocalAlignment == SfxChildAlignment::NOALIGNMENT &&
841
0
                                       !StyleSettings::GetDockingFloatsSupported());
842
0
            if (m_pImpl->bDockingPrevented || bIgnoreFloatConfig)
843
                // docking prevented, ignore old configuration and take alignment from default
844
0
                aStr.clear();
845
0
            else
846
0
                SetAlignment( eLocalAlignment );
847
848
0
            SfxChildAlignment eAlign = CheckAlignment(GetAlignment(),GetAlignment());
849
0
            if ( eAlign != GetAlignment() )
850
0
            {
851
0
                OSL_FAIL("Invalid Alignment!");
852
0
                SetAlignment( eAlign );
853
0
                aStr.clear();
854
0
            }
855
856
            // get last alignment (for toggling)
857
0
            nPos = aStr.indexOf(',');
858
0
            if ( nPos != -1 )
859
0
            {
860
0
                aStr = aStr.copy(nPos+1);
861
0
                m_pImpl->SetLastAlignment(
862
0
                    static_cast<SfxChildAlignment>(static_cast<sal_uInt16>(aStr.toInt32())));
863
0
            }
864
865
0
            nPos = aStr.indexOf(',');
866
0
            if ( nPos != -1 )
867
0
            {
868
                // get split size and position in SplitWindow
869
0
                Point aPos;
870
0
                aStr = aStr.copy(nPos+1);
871
0
                if (GetPosSizeFromString(aStr, aPos, m_pImpl->aSplitSize))
872
0
                {
873
0
                    m_pImpl->nLine = m_pImpl->nDockLine = static_cast<sal_uInt16>(aPos.X());
874
0
                    m_pImpl->nPos = m_pImpl->nDockPos = static_cast<sal_uInt16>(aPos.Y());
875
0
                    m_pImpl->nVerticalSize = m_pImpl->aSplitSize.Height();
876
0
                    m_pImpl->nHorizontalSize = m_pImpl->aSplitSize.Width();
877
0
                    if (GetSplitSizeFromString(aStr, m_pImpl->aSplitSize))
878
0
                        bVertHorzRead = true;
879
0
                }
880
0
            }
881
0
        }
882
0
        else {
883
0
            OSL_FAIL( "Information is missing!" );
884
0
        }
885
0
    }
886
887
0
    if ( !bVertHorzRead )
888
0
    {
889
0
        m_pImpl->nVerticalSize = m_pImpl->aSplitSize.Height();
890
0
        m_pImpl->nHorizontalSize = m_pImpl->aSplitSize.Width();
891
0
    }
892
893
0
    SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
894
0
    if ( GetAlignment() != SfxChildAlignment::NOALIGNMENT )
895
0
    {
896
        // check if SfxWorkWindow is able to allow docking at its border
897
0
        if (
898
0
            !pWorkWin->IsDockingAllowed() ||
899
0
            !pWorkWin->IsInternalDockingAllowed() ||
900
0
            ( (GetFloatStyle() & WB_STANDALONE) && Application::IsInModalMode()) )
901
0
        {
902
0
            SetAlignment( SfxChildAlignment::NOALIGNMENT );
903
0
        }
904
0
    }
905
906
    // detect floating mode
907
    // toggling mode will not execute code in handlers, because pImpl->bConstructed is not set yet
908
0
    bool bFloatMode = IsFloatingMode();
909
0
    if ( bFloatMode != (GetAlignment() == SfxChildAlignment::NOALIGNMENT) )
910
0
    {
911
0
        bFloatMode = !bFloatMode;
912
0
        SetFloatingMode( bFloatMode );
913
0
        if ( bFloatMode )
914
0
        {
915
0
            if (m_pImpl->aWinState.mask() != vcl::WindowDataMask::NONE)
916
0
                GetFloatingWindow()->SetWindowState(m_pImpl->aWinState);
917
0
            else
918
0
                GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
919
0
        }
920
0
    }
921
922
0
    if ( IsFloatingMode() )
923
0
    {
924
        // validate last alignment
925
0
        SfxChildAlignment eLastAlign = m_pImpl->GetLastAlignment();
926
0
        if ( eLastAlign == SfxChildAlignment::NOALIGNMENT)
927
0
            eLastAlign = CheckAlignment(eLastAlign, SfxChildAlignment::LEFT);
928
0
        if ( eLastAlign == SfxChildAlignment::NOALIGNMENT)
929
0
            eLastAlign = CheckAlignment(eLastAlign, SfxChildAlignment::RIGHT);
930
0
        if ( eLastAlign == SfxChildAlignment::NOALIGNMENT)
931
0
            eLastAlign = CheckAlignment(eLastAlign, SfxChildAlignment::TOP);
932
0
        if ( eLastAlign == SfxChildAlignment::NOALIGNMENT)
933
0
            eLastAlign = CheckAlignment(eLastAlign, SfxChildAlignment::BOTTOM);
934
0
        m_pImpl->SetLastAlignment(eLastAlign);
935
0
    }
936
0
    else
937
0
    {
938
        // docked window must have NOALIGNMENT as last alignment
939
0
        m_pImpl->SetLastAlignment(SfxChildAlignment::NOALIGNMENT);
940
941
0
        m_pImpl->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
942
0
        m_pImpl->pSplitWin->InsertWindow(this, m_pImpl->aSplitSize);
943
0
    }
944
945
    // save alignment
946
0
    m_pImpl->SetDockAlignment(GetAlignment());
947
0
}
948
949
void SfxDockingWindow::Initialize_Impl()
950
0
{
951
0
    if (!m_pMgr)
952
0
    {
953
0
        m_pImpl->bConstructed = true;
954
0
        return;
955
0
    }
956
957
0
    SystemWindow* pFloatWin = GetFloatingWindow();
958
0
    bool bSet = false;
959
0
    if ( pFloatWin )
960
0
    {
961
0
        bSet = !pFloatWin->IsDefaultPos();
962
0
    }
963
0
    else
964
0
    {
965
0
        Point aPos = GetFloatingPos();
966
0
        if ( aPos != Point() )
967
0
            bSet = true;
968
0
    }
969
970
0
    if ( !bSet)
971
0
    {
972
0
        SfxViewFrame* pFrame = m_rBindings.GetDispatcher_Impl()->GetFrame();
973
0
        vcl::Window* pEditWin = pFrame->GetViewShell()->GetWindow();
974
0
        Point aPos = pEditWin->OutputToScreenPixel( pEditWin->GetPosPixel() );
975
0
        aPos = GetParent()->ScreenToOutputPixel( aPos );
976
0
        SetFloatingPos( aPos );
977
0
    }
978
979
0
    if ( pFloatWin )
980
0
    {
981
        // initialize floating window
982
0
        if (m_pImpl->aWinState.mask() == vcl::WindowDataMask::NONE)
983
            // window state never set before, get if from defaults
984
0
            m_pImpl->aWinState = pFloatWin->GetWindowState();
985
986
        // trick: use VCL method SetWindowState to adjust position and size
987
0
        pFloatWin->SetWindowState(m_pImpl->aWinState);
988
0
        Size aSize(pFloatWin->GetSizePixel());
989
990
        // remember floating size for calculating alignment and tracking rectangle
991
0
        SetFloatingSize(aSize);
992
993
0
    }
994
995
    // allow calling of docking handlers
996
0
    m_pImpl->bConstructed = true;
997
0
}
998
999
/** Fills a SfxChildWinInfo with specific data from SfxDockingWindow,
1000
    so that it can be written in the INI file. It is assumed that rinfo
1001
    receives all other possible relevant data in the ChildWindow class.
1002
    Insertions are marked with size and the ZoomIn flag.
1003
    If this method is overridden, the base implementation must be called first.
1004
*/
1005
void SfxDockingWindow::FillInfo(SfxChildWinInfo& rInfo) const
1006
0
{
1007
0
    if (!m_pMgr || !m_pImpl)
1008
0
        return;
1009
1010
0
    if (GetFloatingWindow() && m_pImpl->bConstructed)
1011
0
        m_pImpl->aWinState = GetFloatingWindow()->GetWindowState();
1012
1013
0
    rInfo.aWinState = m_pImpl->aWinState;
1014
0
    rInfo.aExtraString = "AL:(";
1015
0
    rInfo.aExtraString += OUString::number(static_cast<sal_uInt16>(GetAlignment()));
1016
0
    rInfo.aExtraString += ",";
1017
0
    rInfo.aExtraString += OUString::number(static_cast<sal_uInt16>(m_pImpl->GetLastAlignment()));
1018
1019
0
    Point aPos(m_pImpl->nLine, m_pImpl->nPos);
1020
0
    rInfo.aExtraString += ",";
1021
0
    rInfo.aExtraString += OUString::number( aPos.X() );
1022
0
    rInfo.aExtraString += "/";
1023
0
    rInfo.aExtraString += OUString::number( aPos.Y() );
1024
0
    rInfo.aExtraString += "/";
1025
0
    rInfo.aExtraString += OUString::number(m_pImpl->nHorizontalSize);
1026
0
    rInfo.aExtraString += "/";
1027
0
    rInfo.aExtraString += OUString::number(m_pImpl->nVerticalSize);
1028
0
    rInfo.aExtraString += ",";
1029
0
    rInfo.aExtraString += OUString::number(m_pImpl->aSplitSize.Width());
1030
0
    rInfo.aExtraString += ";";
1031
0
    rInfo.aExtraString += OUString::number(m_pImpl->aSplitSize.Height());
1032
1033
0
    rInfo.aExtraString += ")";
1034
0
}
1035
1036
SfxDockingWindow::~SfxDockingWindow()
1037
0
{
1038
0
    disposeOnce();
1039
0
}
1040
1041
void SfxDockingWindow::dispose()
1042
0
{
1043
0
    ReleaseChildWindow_Impl();
1044
0
    m_pImpl.reset();
1045
0
    m_xContainer.reset();
1046
0
    m_xBuilder.reset();
1047
0
    ResizableDockingWindow::dispose();
1048
0
}
1049
1050
void SfxDockingWindow::ReleaseChildWindow_Impl()
1051
0
{
1052
0
    if (m_pMgr && m_pMgr->GetFrame() == m_rBindings.GetActiveFrame())
1053
0
        m_rBindings.SetActiveFrame(nullptr);
1054
1055
0
    if (m_pMgr && m_pImpl->pSplitWin && m_pImpl->pSplitWin->IsItemValid(GetType()))
1056
0
        m_pImpl->pSplitWin->RemoveWindow(this);
1057
1058
0
    m_pMgr = nullptr;
1059
0
}
1060
1061
/** This method calculates a resulting alignment for the given mouse position
1062
    and tracking rectangle. When changing the alignment it can also be that
1063
    the tracking rectangle is changed, so that an altered rectangle is
1064
    returned. The user of this class can influence behaviour of this method,
1065
    and thus the behavior of his DockinWindow class when docking where the
1066
    called virtual method:
1067
1068
    SfxDockingWindow::CalcDockingSize (SfxChildAlignment eAlign)
1069
1070
    is overridden (see below).
1071
*/
1072
SfxChildAlignment SfxDockingWindow::CalcAlignment(const Point& rPos, tools::Rectangle& rRect)
1073
0
{
1074
    // calculate hypothetical sizes for different modes
1075
0
    Size aFloatingSize(CalcDockingSize(SfxChildAlignment::NOALIGNMENT));
1076
1077
    // check if docking is permitted
1078
0
    SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
1079
0
    if ( !pWorkWin->IsDockingAllowed() )
1080
0
    {
1081
0
        rRect.SetSize( aFloatingSize );
1082
0
        return m_pImpl->GetDockAlignment();
1083
0
    }
1084
1085
    // calculate borders to shrink inner area before checking for intersection with tracking rectangle
1086
0
    tools::Long nLRBorder, nTBBorder;
1087
1088
    // take the smaller size of docked and floating mode
1089
0
    Size aBorderTmp = m_pImpl->aSplitSize;
1090
0
    if ( GetFloatingSize().Height() < aBorderTmp.Height() )
1091
0
        aBorderTmp.setHeight( GetFloatingSize().Height() );
1092
0
    if ( GetFloatingSize().Width() < aBorderTmp.Width() )
1093
0
        aBorderTmp.setWidth( GetFloatingSize().Width() );
1094
1095
0
    nLRBorder = aBorderTmp.Width();
1096
0
    nTBBorder = aBorderTmp.Height();
1097
1098
    // limit border to predefined constant values
1099
0
    if ( nLRBorder > MAX_TOGGLEAREA_WIDTH )
1100
0
        nLRBorder = MAX_TOGGLEAREA_WIDTH;
1101
0
    if ( nTBBorder > MAX_TOGGLEAREA_WIDTH )
1102
0
        nTBBorder = MAX_TOGGLEAREA_WIDTH;
1103
1104
    // shrink area for floating mode if possible
1105
0
    tools::Rectangle aInRect = GetInnerRect();
1106
0
    if ( aInRect.GetWidth() > nLRBorder )
1107
0
        aInRect.AdjustLeft(nLRBorder/2 );
1108
0
    if ( aInRect.GetWidth() > nLRBorder )
1109
0
        aInRect.AdjustRight( -(nLRBorder/2) );
1110
0
    if ( aInRect.GetHeight() > nTBBorder )
1111
0
        aInRect.AdjustTop(nTBBorder/2 );
1112
0
    if ( aInRect.GetHeight() > nTBBorder )
1113
0
        aInRect.AdjustBottom( -(nTBBorder/2) );
1114
1115
    // calculate alignment resulting from docking rectangle
1116
0
    bool bBecomesFloating = false;
1117
0
    SfxChildAlignment eDockAlign = m_pImpl->GetDockAlignment();
1118
0
    tools::Rectangle aDockingRect( rRect );
1119
0
    if ( !IsFloatingMode() )
1120
0
    {
1121
        // don't use tracking rectangle for alignment check, because it will be too large
1122
        // to get a floating mode as result - switch to floating size
1123
        // so the calculation only depends on the position of the rectangle, not the current
1124
        // docking state of the window
1125
0
        aDockingRect.SetSize( GetFloatingSize() );
1126
1127
        // in this mode docking is never done by keyboard, so it's OK to use the mouse position
1128
0
        aDockingRect.SetPos( pWorkWin->GetWindow()->OutputToScreenPixel( pWorkWin->GetWindow()->GetPointerPosPixel() ) );
1129
0
    }
1130
1131
0
    Point aPos = aDockingRect.TopLeft();
1132
0
    tools::Rectangle aIntersect = GetOuterRect().GetIntersection( aDockingRect );
1133
0
    if ( aIntersect.IsEmpty() )
1134
        // docking rectangle completely outside docking area -> floating mode
1135
0
        bBecomesFloating = true;
1136
0
    else
1137
0
    {
1138
        // create a small test rect around the mouse position and use this one
1139
        // instead of the passed rRect to not dock too easily or by accident
1140
0
        tools::Rectangle aSmallDockingRect;
1141
0
        aSmallDockingRect.SetSize( Size( MAX_TOGGLEAREA_WIDTH, MAX_TOGGLEAREA_HEIGHT ) );
1142
0
        Point aNewPos(rPos);
1143
0
        aNewPos.AdjustX( -(aSmallDockingRect.GetWidth()/2) );
1144
0
        aNewPos.AdjustY( -(aSmallDockingRect.GetHeight()/2) );
1145
0
        aSmallDockingRect.SetPos(aNewPos);
1146
0
        tools::Rectangle aIntersectRect = aInRect.GetIntersection( aSmallDockingRect );
1147
0
        if ( aIntersectRect == aSmallDockingRect )
1148
            // docking rectangle completely inside (shrunk) inner area -> floating mode
1149
0
            bBecomesFloating = true;
1150
0
    }
1151
1152
0
    if ( bBecomesFloating )
1153
0
    {
1154
0
        eDockAlign = CheckAlignment(m_pImpl->GetDockAlignment(), SfxChildAlignment::NOALIGNMENT);
1155
0
    }
1156
0
    else
1157
0
    {
1158
        // docking rectangle is in the "sensible area"
1159
0
        Point aInPosTL( aPos.X()-aInRect.Left(), aPos.Y()-aInRect.Top() );
1160
0
        Point aInPosBR( aPos.X()-aInRect.Left() + aDockingRect.GetWidth(), aPos.Y()-aInRect.Top() + aDockingRect.GetHeight() );
1161
0
        Size  aInSize = aInRect.GetSize();
1162
0
        bool  bNoChange = false;
1163
1164
        // check if alignment is still unchanged
1165
0
        switch ( GetAlignment() )
1166
0
        {
1167
0
            case SfxChildAlignment::LEFT:
1168
0
            case SfxChildAlignment::FIRSTLEFT:
1169
0
            case SfxChildAlignment::LASTLEFT:
1170
0
                if (aInPosTL.X() <= 0)
1171
0
                {
1172
0
                    eDockAlign = GetAlignment();
1173
0
                    bNoChange = true;
1174
0
                }
1175
0
                break;
1176
0
            case SfxChildAlignment::TOP:
1177
0
            case SfxChildAlignment::LOWESTTOP:
1178
0
            case SfxChildAlignment::HIGHESTTOP:
1179
0
                if ( aInPosTL.Y() <= 0)
1180
0
                {
1181
0
                    eDockAlign = GetAlignment();
1182
0
                    bNoChange = true;
1183
0
                }
1184
0
                break;
1185
0
            case SfxChildAlignment::RIGHT:
1186
0
            case SfxChildAlignment::FIRSTRIGHT:
1187
0
            case SfxChildAlignment::LASTRIGHT:
1188
0
                if ( aInPosBR.X() >= aInSize.Width())
1189
0
                {
1190
0
                    eDockAlign = GetAlignment();
1191
0
                    bNoChange = true;
1192
0
                }
1193
0
                break;
1194
0
            case SfxChildAlignment::BOTTOM:
1195
0
            case SfxChildAlignment::LOWESTBOTTOM:
1196
0
            case SfxChildAlignment::HIGHESTBOTTOM:
1197
0
                if ( aInPosBR.Y() >= aInSize.Height())
1198
0
                {
1199
0
                    eDockAlign = GetAlignment();
1200
0
                    bNoChange = true;
1201
0
                }
1202
0
                break;
1203
0
            default:
1204
0
                break;
1205
0
        }
1206
1207
0
        if ( !bNoChange )
1208
0
        {
1209
            // alignment will change, test alignment according to distance of the docking rectangles edges
1210
0
            bool bForbidden = true;
1211
0
            if ( aInPosTL.X() <= 0)
1212
0
            {
1213
0
                eDockAlign = CheckAlignment(m_pImpl->GetDockAlignment(), SfxChildAlignment::LEFT);
1214
0
                bForbidden = ( eDockAlign != SfxChildAlignment::LEFT &&
1215
0
                               eDockAlign != SfxChildAlignment::FIRSTLEFT &&
1216
0
                               eDockAlign != SfxChildAlignment::LASTLEFT );
1217
0
            }
1218
1219
0
            if ( bForbidden && aInPosTL.Y() <= 0)
1220
0
            {
1221
0
                eDockAlign = CheckAlignment(m_pImpl->GetDockAlignment(), SfxChildAlignment::TOP);
1222
0
                bForbidden = ( eDockAlign != SfxChildAlignment::TOP &&
1223
0
                               eDockAlign != SfxChildAlignment::HIGHESTTOP &&
1224
0
                               eDockAlign != SfxChildAlignment::LOWESTTOP );
1225
0
            }
1226
1227
0
            if ( bForbidden && aInPosBR.X() >= aInSize.Width())
1228
0
            {
1229
0
                eDockAlign = CheckAlignment(m_pImpl->GetDockAlignment(), SfxChildAlignment::RIGHT);
1230
0
                bForbidden = ( eDockAlign != SfxChildAlignment::RIGHT &&
1231
0
                               eDockAlign != SfxChildAlignment::FIRSTRIGHT &&
1232
0
                               eDockAlign != SfxChildAlignment::LASTRIGHT );
1233
0
            }
1234
1235
0
            if ( bForbidden && aInPosBR.Y() >= aInSize.Height())
1236
0
            {
1237
0
                eDockAlign = CheckAlignment(m_pImpl->GetDockAlignment(), SfxChildAlignment::BOTTOM);
1238
0
                bForbidden = ( eDockAlign != SfxChildAlignment::BOTTOM &&
1239
0
                               eDockAlign != SfxChildAlignment::HIGHESTBOTTOM &&
1240
0
                               eDockAlign != SfxChildAlignment::LOWESTBOTTOM );
1241
0
            }
1242
1243
            // the calculated alignment was rejected by the window -> take floating mode
1244
0
            if ( bForbidden )
1245
0
                eDockAlign
1246
0
                    = CheckAlignment(m_pImpl->GetDockAlignment(), SfxChildAlignment::NOALIGNMENT);
1247
0
        }
1248
0
    }
1249
1250
0
    if ( eDockAlign == SfxChildAlignment::NOALIGNMENT )
1251
0
    {
1252
        // In the FloatingMode the tracking rectangle will get the floating
1253
        // size. Due to a bug the rRect may only be changed when the
1254
        // alignment is changed!
1255
0
        if (eDockAlign != m_pImpl->GetDockAlignment())
1256
0
            aDockingRect.SetSize( aFloatingSize );
1257
0
    }
1258
0
    else
1259
0
    {
1260
0
        sal_uInt16 nLine, nPos;
1261
0
        SfxSplitWindow *pSplitWin = pWorkWin->GetSplitWindow_Impl(eDockAlign);
1262
0
        aPos = pSplitWin->ScreenToOutputPixel( aPos );
1263
0
        if ( pSplitWin->GetWindowPos( aPos, nLine, nPos ) )
1264
0
        {
1265
            // mouse over splitwindow, get line and position
1266
0
            m_pImpl->nDockLine = nLine;
1267
0
            m_pImpl->nDockPos = nPos;
1268
0
            m_pImpl->bNewLine = false;
1269
0
        }
1270
0
        else
1271
0
        {
1272
            // mouse touches inner border -> create new line
1273
0
            if (eDockAlign == GetAlignment() && m_pImpl->pSplitWin
1274
0
                && m_pImpl->nLine == m_pImpl->pSplitWin->GetLineCount() - 1
1275
0
                && m_pImpl->pSplitWin->GetWindowCount(m_pImpl->nLine) == 1)
1276
0
            {
1277
                // if this window is the only one in the last line, it can't be docked as new line in the same splitwindow
1278
0
                m_pImpl->nDockLine = m_pImpl->nLine;
1279
0
                m_pImpl->nDockPos = m_pImpl->nPos;
1280
0
                m_pImpl->bNewLine = false;
1281
0
            }
1282
0
            else
1283
0
            {
1284
                // create new line
1285
0
                m_pImpl->nDockLine = pSplitWin->GetLineCount();
1286
0
                m_pImpl->nDockPos = 0;
1287
0
                m_pImpl->bNewLine = true;
1288
0
            }
1289
0
        }
1290
1291
0
        bool bChanged = m_pImpl->nLine != m_pImpl->nDockLine || m_pImpl->nPos != m_pImpl->nDockPos
1292
0
                        || eDockAlign != GetAlignment();
1293
0
        if ( !bChanged && !IsFloatingMode() )
1294
0
        {
1295
            // window only slightly moved, no change of any property
1296
0
            rRect.SetSize(m_pImpl->aSplitSize);
1297
0
            rRect.SetPos( aDockingRect.TopLeft() );
1298
0
            return eDockAlign;
1299
0
        }
1300
1301
        // calculate new size and position
1302
0
        Size aSize;
1303
0
        Point aPoint = aDockingRect.TopLeft();
1304
0
        Size aInnerSize = GetInnerRect().GetSize();
1305
0
        if ( eDockAlign == SfxChildAlignment::LEFT || eDockAlign == SfxChildAlignment::RIGHT )
1306
0
        {
1307
0
            if (m_pImpl->bNewLine)
1308
0
            {
1309
                // set height to height of free area
1310
0
                aSize.setHeight( aInnerSize.Height() );
1311
0
                aSize.setWidth(m_pImpl->nHorizontalSize);
1312
0
                if ( eDockAlign == SfxChildAlignment::LEFT )
1313
0
                {
1314
0
                    aPoint = m_aInnerRect.TopLeft();
1315
0
                }
1316
0
                else
1317
0
                {
1318
0
                    aPoint = m_aInnerRect.TopRight();
1319
0
                    aPoint.AdjustX( -(aSize.Width()) );
1320
0
                }
1321
0
            }
1322
0
            else
1323
0
            {
1324
                // get width from splitwindow
1325
0
                aSize.setWidth( pSplitWin->GetLineSize(nLine) );
1326
0
                aSize.setHeight(m_pImpl->aSplitSize.Height());
1327
0
            }
1328
0
        }
1329
0
        else
1330
0
        {
1331
0
            if (m_pImpl->bNewLine)
1332
0
            {
1333
                // set width to width of free area
1334
0
                aSize.setWidth( aInnerSize.Width() );
1335
0
                aSize.setHeight(m_pImpl->nVerticalSize);
1336
0
                if ( eDockAlign == SfxChildAlignment::TOP )
1337
0
                {
1338
0
                    aPoint = m_aInnerRect.TopLeft();
1339
0
                }
1340
0
                else
1341
0
                {
1342
0
                    aPoint = m_aInnerRect.BottomLeft();
1343
0
                    aPoint.AdjustY( -(aSize.Height()) );
1344
0
                }
1345
0
            }
1346
0
            else
1347
0
            {
1348
                // get height from splitwindow
1349
0
                aSize.setHeight( pSplitWin->GetLineSize(nLine) );
1350
0
                aSize.setWidth(m_pImpl->aSplitSize.Width());
1351
0
            }
1352
0
        }
1353
1354
0
        aDockingRect.SetSize( aSize );
1355
0
        aDockingRect.SetPos( aPoint );
1356
0
    }
1357
1358
0
    rRect = aDockingRect;
1359
0
    return eDockAlign;
1360
0
}
1361
1362
/** Virtual method of the SfxDockingWindow class. This method determines how
1363
    the size of the DockingWindows changes depending on the alignment. The base
1364
    implementation uses the floating mode, the size of the marked Floating
1365
    Size. For horizontal alignment, the width will be the width of the outer
1366
    DockingRectangle, with vertical alignment the height will be the height of
1367
    the inner DockingRectangle (resulting from the order in which the SFX child
1368
    windows are displayed). The other size is set to the current floating-size,
1369
    this could changed by a to intervening derived class. The docking size must
1370
    be the same for Left/Right and Top/Bottom.
1371
*/
1372
Size SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign)
1373
0
{
1374
    // Note: if the resizing is also possible in the docked state, then the
1375
    // Floating-size does also have to be adjusted?
1376
1377
0
    Size aSize = GetFloatingSize();
1378
0
    switch (eAlign)
1379
0
    {
1380
0
        case SfxChildAlignment::TOP:
1381
0
        case SfxChildAlignment::BOTTOM:
1382
0
        case SfxChildAlignment::LOWESTTOP:
1383
0
        case SfxChildAlignment::HIGHESTTOP:
1384
0
        case SfxChildAlignment::LOWESTBOTTOM:
1385
0
        case SfxChildAlignment::HIGHESTBOTTOM:
1386
0
            aSize.setWidth(m_aOuterRect.Right() - m_aOuterRect.Left());
1387
0
            break;
1388
0
        case SfxChildAlignment::LEFT:
1389
0
        case SfxChildAlignment::RIGHT:
1390
0
        case SfxChildAlignment::FIRSTLEFT:
1391
0
        case SfxChildAlignment::LASTLEFT:
1392
0
        case SfxChildAlignment::FIRSTRIGHT:
1393
0
        case SfxChildAlignment::LASTRIGHT:
1394
0
            aSize.setHeight(m_aInnerRect.Bottom() - m_aInnerRect.Top());
1395
0
            break;
1396
0
        case SfxChildAlignment::NOALIGNMENT:
1397
0
            break;
1398
0
              default:
1399
0
                  break;
1400
0
    }
1401
1402
0
    return aSize;
1403
0
}
1404
1405
/** Virtual method of the SfxDockingWindow class. Here a derived class can
1406
    disallow certain alignments. The base implementation does not
1407
    prohibit alignment.
1408
*/
1409
SfxChildAlignment SfxDockingWindow::CheckAlignment(SfxChildAlignment,
1410
    SfxChildAlignment eAlign)
1411
0
{
1412
0
    return eAlign;
1413
0
}
1414
1415
/** The window is closed when the ChildWindow is destroyed by running the
1416
    ChildWindow-slots. If this is method is overridden by a derived class
1417
    method, then the SfxDockingDialogWindow: Close() must be called afterwards
1418
    if the Close() was not cancelled with "return sal_False".
1419
*/
1420
bool SfxDockingWindow::Close()
1421
0
{
1422
    // Execute with Parameters, since Toggle is ignored by some ChildWindows.
1423
0
    if (!m_pMgr)
1424
0
        return true;
1425
1426
0
    SfxBoolItem aValue(m_pMgr->GetType(), false);
1427
0
    m_rBindings.GetDispatcher_Impl()->ExecuteList(
1428
0
        m_pMgr->GetType(), SfxCallMode::RECORD | SfxCallMode::ASYNCHRON, { &aValue });
1429
0
    return true;
1430
0
}
1431
1432
void SfxDockingWindow::Paint(vcl::RenderContext&, const tools::Rectangle& /*rRect*/)
1433
0
{
1434
0
}
1435
1436
/** With this method, a minimal OutputSize be can set, that is queried in
1437
    the Resizing()-Handler.
1438
*/
1439
void SfxDockingWindow::SetMinOutputSizePixel( const Size& rSize )
1440
0
{
1441
0
    m_pImpl->aMinSize = rSize;
1442
0
    ResizableDockingWindow::SetMinOutputSizePixel( rSize );
1443
0
}
1444
1445
/** Set the minimum size which is returned.*/
1446
0
const Size& SfxDockingWindow::GetMinOutputSizePixel() const { return m_pImpl->aMinSize; }
1447
1448
bool SfxDockingWindow::EventNotify( NotifyEvent& rEvt )
1449
0
{
1450
0
    if (!m_pImpl)
1451
0
        return ResizableDockingWindow::EventNotify( rEvt );
1452
1453
0
    if ( rEvt.GetType() == NotifyEventType::GETFOCUS )
1454
0
    {
1455
0
        if (m_pMgr != nullptr)
1456
0
            m_rBindings.SetActiveFrame(m_pMgr->GetFrame());
1457
1458
0
        if (m_pImpl->pSplitWin)
1459
0
            m_pImpl->pSplitWin->SetActiveWindow_Impl(this);
1460
0
        else if (m_pMgr != nullptr)
1461
0
            m_pMgr->Activate_Impl();
1462
1463
        // In VCL EventNotify goes first to the window itself, also call the
1464
        // base class, otherwise the parent learns nothing
1465
        // if ( rEvt.GetWindow() == this )  PB: #i74693# not necessary any longer
1466
0
        ResizableDockingWindow::EventNotify( rEvt );
1467
        // tdf#151112 move focus into container widget hierarchy if not already there
1468
0
        if (m_xContainer && !m_xContainer->has_child_focus())
1469
0
            m_xContainer->child_grab_focus();
1470
0
        return true;
1471
0
    }
1472
0
    else if( rEvt.GetType() == NotifyEventType::KEYINPUT )
1473
0
    {
1474
        // First, allow KeyInput for Dialog functions
1475
0
        if (!DockingWindow::EventNotify(rEvt) && SfxViewShell::Current())
1476
0
        {
1477
            // then also for valid global accelerators.
1478
0
            return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
1479
0
        }
1480
0
        return true;
1481
0
    }
1482
0
    else if ( rEvt.GetType() == NotifyEventType::LOSEFOCUS && !HasChildPathFocus() )
1483
0
    {
1484
0
        m_rBindings.SetActiveFrame(nullptr);
1485
0
    }
1486
1487
0
    return ResizableDockingWindow::EventNotify( rEvt );
1488
0
}
1489
1490
void SfxDockingWindow::SetItemSize_Impl( const Size& rSize )
1491
0
{
1492
0
    m_pImpl->aSplitSize = rSize;
1493
1494
0
    SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
1495
0
    pWorkWin->ConfigChild_Impl(SfxChildIdentifier::SPLITWINDOW,
1496
0
                               SfxDockingConfig::ALIGNDOCKINGWINDOW, m_pMgr->GetType());
1497
0
}
1498
1499
void SfxDockingWindow::Disappear_Impl()
1500
0
{
1501
0
    if (m_pImpl->pSplitWin && m_pImpl->pSplitWin->IsItemValid(GetType()))
1502
0
        m_pImpl->pSplitWin->RemoveWindow(this);
1503
0
}
1504
1505
void SfxDockingWindow::Reappear_Impl()
1506
0
{
1507
0
    if (m_pImpl->pSplitWin && !m_pImpl->pSplitWin->IsItemValid(GetType()))
1508
0
    {
1509
0
        m_pImpl->pSplitWin->InsertWindow(this, m_pImpl->aSplitSize);
1510
0
    }
1511
0
}
1512
1513
bool SfxDockingWindow::IsAutoHide_Impl() const
1514
0
{
1515
0
    if (m_pImpl->pSplitWin)
1516
0
        return !m_pImpl->pSplitWin->IsFadeIn();
1517
0
    else
1518
0
        return false;
1519
0
}
1520
1521
void SfxDockingWindow::AutoShow_Impl()
1522
0
{
1523
0
    if (m_pImpl->pSplitWin)
1524
0
    {
1525
0
        m_pImpl->pSplitWin->FadeIn();
1526
0
    }
1527
0
}
1528
1529
void SfxDockingWindow::StateChanged( StateChangedType nStateChange )
1530
0
{
1531
0
    if ( nStateChange == StateChangedType::InitShow )
1532
0
        Initialize_Impl();
1533
1534
0
    ResizableDockingWindow::StateChanged( nStateChange );
1535
0
}
1536
1537
void SfxDockingWindow::Move()
1538
0
{
1539
0
    if (m_pImpl)
1540
0
        m_pImpl->aMoveIdle.Start();
1541
0
}
1542
1543
IMPL_LINK_NOARG(SfxDockingWindow, TimerHdl, Timer *, void)
1544
0
{
1545
0
    m_pImpl->aMoveIdle.Stop();
1546
0
    if ( IsReallyVisible() && IsFloatingMode() )
1547
0
    {
1548
0
        SetFloatingSize( GetOutputSizePixel() );
1549
0
        m_pImpl->aWinState = GetFloatingWindow()->GetWindowState();
1550
0
        SfxWorkWindow* pWorkWin = m_rBindings.GetWorkWindow_Impl();
1551
0
        pWorkWin->ConfigChild_Impl(SfxChildIdentifier::SPLITWINDOW,
1552
0
                                   SfxDockingConfig::ALIGNDOCKINGWINDOW, m_pMgr->GetType());
1553
0
    }
1554
0
}
1555
1556
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */