Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/dialog/splitwin.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
#ifdef __sun
21
#include <ctime>
22
#endif
23
24
#include <rtl/ustrbuf.hxx>
25
#include <sal/log.hxx>
26
#include <svtools/viewoptions.hxx>
27
#include <tools/debug.hxx>
28
29
#include <vcl/dialoghelper.hxx>
30
#include <vcl/event.hxx>
31
#include <vcl/timer.hxx>
32
#include <vcl/svapp.hxx>
33
34
#include <splitwin.hxx>
35
#include <workwin.hxx>
36
#include <sfx2/chalign.hxx>
37
#include <sfx2/dockwin.hxx>
38
#include <o3tl/string_view.hxx>
39
40
#include <cassert>
41
#include <memory>
42
#include <vector>
43
#include <utility>
44
45
using namespace ::com::sun::star::uno;
46
47
24.8k
#define VERSION 1
48
0
#define nPixel  30L
49
constexpr OUString USERITEM_NAME = u"UserItem"_ustr;
50
51
namespace {
52
    // helper class to deactivate UpdateMode, if needed, for the life time of an instance
53
    class DeactivateUpdateMode
54
    {
55
    public:
56
        explicit DeactivateUpdateMode( SfxSplitWindow& rSplitWindow )
57
0
            : mrSplitWindow( rSplitWindow )
58
0
            , mbUpdateMode( rSplitWindow.IsUpdateMode() )
59
0
        {
60
0
            if ( mbUpdateMode )
61
0
            {
62
0
                mrSplitWindow.SetUpdateMode( false );
63
0
            }
64
0
        }
65
66
        ~DeactivateUpdateMode()
67
0
        {
68
0
            if ( mbUpdateMode )
69
0
            {
70
0
                mrSplitWindow.SetUpdateMode( true );
71
0
            }
72
0
        }
73
74
    private:
75
        SfxSplitWindow& mrSplitWindow;
76
        const bool mbUpdateMode;
77
    };
78
}
79
80
class SfxEmptySplitWin_Impl : public SplitWindow
81
{
82
/*  [Description]
83
84
    The SfxEmptySplitWin_Impldow is an empty SplitWindow, that replaces the
85
    SfxSplitWindow AutoHide mode. It only serves as a placeholder to receive
86
    mouse moves and if possible blend in the true SplitWindow display.
87
*/
88
friend class SfxSplitWindow;
89
90
    VclPtr<SfxSplitWindow>  pOwner;
91
    bool                    bFadeIn;
92
    bool                    bAutoHide;
93
    bool                    bSplit;
94
    bool                    bEndAutoHide;
95
    Timer                   aTimer;
96
    Point                   aLastPos;
97
    sal_uInt16              nState;
98
99
public:
100
   explicit             SfxEmptySplitWin_Impl( SfxSplitWindow *pParent )
101
24.8k
                            : SplitWindow( pParent->GetParent(), WinBits( WB_BORDER | WB_3DLOOK ) )
102
24.8k
                            , pOwner( pParent )
103
24.8k
                            , bFadeIn( false )
104
24.8k
                            , bAutoHide( false )
105
24.8k
                            , bSplit( false )
106
24.8k
                            , bEndAutoHide( false )
107
24.8k
                            , aTimer("sfx2 SfxEmptySplitWin_Impl aTimer")
108
24.8k
                            , nState( 1 )
109
24.8k
                        {
110
24.8k
                            aTimer.SetInvokeHandler(
111
24.8k
                                LINK(pOwner, SfxSplitWindow, TimerHdl ) );
112
24.8k
                            aTimer.SetTimeout( 200 );
113
24.8k
                            SetAlign( pOwner->GetAlign() );
114
24.8k
                            Actualize();
115
24.8k
                            ShowFadeInHideButton();
116
24.8k
                        }
117
118
                        virtual ~SfxEmptySplitWin_Impl() override
119
24.8k
                        { disposeOnce(); }
120
   virtual void         dispose() override
121
24.8k
                        {
122
24.8k
                            aTimer.Stop();
123
24.8k
                            pOwner.reset();
124
24.8k
                            SplitWindow::dispose();
125
24.8k
                        }
126
127
    virtual void        FadeIn() override;
128
    void                Actualize();
129
};
130
131
void SfxEmptySplitWin_Impl::Actualize()
132
24.8k
{
133
24.8k
    Size aSize( pOwner->GetSizePixel() );
134
24.8k
    switch ( pOwner->GetAlign() )
135
24.8k
    {
136
6.21k
        case WindowAlign::Left:
137
12.4k
        case WindowAlign::Right:
138
12.4k
            aSize.setWidth( GetFadeInSize() );
139
12.4k
            break;
140
6.21k
        case WindowAlign::Top:
141
12.4k
        case WindowAlign::Bottom:
142
12.4k
            aSize.setHeight( GetFadeInSize() );
143
12.4k
            break;
144
24.8k
    }
145
146
24.8k
    SetSizePixel( aSize );
147
24.8k
}
148
149
void SfxEmptySplitWin_Impl::FadeIn()
150
0
{
151
0
    if (!bAutoHide )
152
0
        bAutoHide = IsFadeNoButtonMode();
153
0
    pOwner->SetFadeIn_Impl( true );
154
0
    if ( bAutoHide )
155
0
    {
156
        // Set Timer to close; the caller has to ensure themselves that the
157
        // Window is not closed instantly (eg by setting the focus or a modal
158
        // mode.
159
0
        aLastPos = GetPointerPosPixel();
160
0
        aTimer.Start();
161
0
    }
162
0
    else
163
0
        pOwner->SaveConfig_Impl();
164
0
}
165
166
167
void SfxSplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
168
0
{
169
0
    if ( rMEvt.GetClicks() != 2 )
170
0
        SplitWindow::MouseButtonDown( rMEvt );
171
0
}
172
173
SfxSplitWindow::SfxSplitWindow( vcl::Window* pParent, SfxChildAlignment eAl,
174
        SfxWorkWindow *pW, bool bWithButtons )
175
176
/*  [Description]
177
178
    A SfxSplitWindow brings the recursive structure of the SV-SplitWindows to
179
    the outside by simulating a table-like structure with rows and columns
180
    (maximum recursion depth 2). Furthermore, it ensures the persistence of
181
    the arrangement of the SfxDockingWindows.
182
*/
183
184
24.8k
:   SplitWindow ( pParent, WB_BORDER | WB_SIZEABLE | WB_3DLOOK | WB_HIDE ),
185
24.8k
    eAlign(eAl),
186
24.8k
    pWorkWin(pW),
187
24.8k
    bPinned(true),
188
24.8k
    pEmptyWin(nullptr),
189
24.8k
    pActive(nullptr)
190
24.8k
{
191
24.8k
    if (bWithButtons)
192
24.8k
    {
193
24.8k
        ShowFadeOutButton();
194
24.8k
    }
195
196
    // Set SV-Alignment
197
24.8k
    WindowAlign eTbxAlign;
198
24.8k
    switch ( eAlign )
199
24.8k
    {
200
6.21k
        case SfxChildAlignment::LEFT:
201
6.21k
            eTbxAlign = WindowAlign::Left;
202
6.21k
            break;
203
6.21k
        case SfxChildAlignment::RIGHT:
204
6.21k
            eTbxAlign = WindowAlign::Right;
205
6.21k
            break;
206
6.21k
        case SfxChildAlignment::TOP:
207
6.21k
            eTbxAlign = WindowAlign::Top;
208
6.21k
            break;
209
6.21k
        case SfxChildAlignment::BOTTOM:
210
6.21k
            eTbxAlign = WindowAlign::Bottom;
211
6.21k
            bPinned = true;
212
6.21k
            break;
213
0
        default:
214
0
            eTbxAlign = WindowAlign::Top;  // some sort of default...
215
0
            break;  // -Wall lots not handled...
216
24.8k
    }
217
218
24.8k
    SetAlign (eTbxAlign);
219
24.8k
    pEmptyWin = VclPtr<SfxEmptySplitWin_Impl>::Create( this );
220
24.8k
    if ( bPinned )
221
24.8k
    {
222
24.8k
        pEmptyWin->bFadeIn = true;
223
24.8k
        pEmptyWin->nState = 2;
224
24.8k
    }
225
226
24.8k
    if ( bWithButtons )
227
24.8k
    {
228
        //  Read Configuration
229
24.8k
        const OUString aWindowId{ "SplitWindow" + OUString::number(static_cast<sal_Int32>(eTbxAlign)) };
230
24.8k
        SvtViewOptions aWinOpt( EViewType::Window, aWindowId );
231
24.8k
        OUString aWinData;
232
24.8k
        Any aUserItem = aWinOpt.GetUserItem( USERITEM_NAME );
233
24.8k
        OUString aTemp;
234
24.8k
        if ( aUserItem >>= aTemp )
235
0
            aWinData = aTemp;
236
24.8k
        if ( aWinData.startsWith("V") )
237
0
        {
238
0
            sal_Int32 nIdx{ 0 };
239
0
            pEmptyWin->nState = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aWinData, 1, ',', nIdx )));
240
0
            if ( pEmptyWin->nState & 2 )
241
0
                pEmptyWin->bFadeIn = true;
242
0
            bPinned = true; // always assume pinned - floating mode not used anymore
243
244
0
            const sal_Int32 nCount{ o3tl::toInt32(o3tl::getToken(aWinData, 0, ',', nIdx)) };
245
0
            for ( sal_Int32 n=0; n<nCount; ++n )
246
0
            {
247
0
                std::unique_ptr<SfxDock_Impl> pDock(new SfxDock_Impl);
248
0
                pDock->pWin = nullptr;
249
0
                pDock->bNewLine = false;
250
0
                pDock->bHide = true;
251
0
                pDock->nType = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aWinData, 0, ',', nIdx)));
252
0
                if ( !pDock->nType )
253
0
                {
254
                    // could mean NewLine
255
0
                    pDock->nType = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aWinData, 0, ',', nIdx)));
256
0
                    if ( !pDock->nType )
257
0
                    {
258
                        // Read error
259
0
                        break;
260
0
                    }
261
0
                    else
262
0
                        pDock->bNewLine = true;
263
0
                }
264
265
0
                maDockArr.insert(maDockArr.begin() + n, std::move(pDock));
266
0
            }
267
0
        }
268
24.8k
    }
269
0
    else
270
0
    {
271
0
        bPinned = true;
272
0
        pEmptyWin->bFadeIn = true;
273
0
        pEmptyWin->nState = 2;
274
0
    }
275
24.8k
}
Unexecuted instantiation: SfxSplitWindow::SfxSplitWindow(vcl::Window*, SfxChildAlignment, SfxWorkWindow*, bool)
SfxSplitWindow::SfxSplitWindow(vcl::Window*, SfxChildAlignment, SfxWorkWindow*, bool)
Line
Count
Source
184
24.8k
:   SplitWindow ( pParent, WB_BORDER | WB_SIZEABLE | WB_3DLOOK | WB_HIDE ),
185
24.8k
    eAlign(eAl),
186
24.8k
    pWorkWin(pW),
187
24.8k
    bPinned(true),
188
24.8k
    pEmptyWin(nullptr),
189
24.8k
    pActive(nullptr)
190
24.8k
{
191
24.8k
    if (bWithButtons)
192
24.8k
    {
193
24.8k
        ShowFadeOutButton();
194
24.8k
    }
195
196
    // Set SV-Alignment
197
24.8k
    WindowAlign eTbxAlign;
198
24.8k
    switch ( eAlign )
199
24.8k
    {
200
6.21k
        case SfxChildAlignment::LEFT:
201
6.21k
            eTbxAlign = WindowAlign::Left;
202
6.21k
            break;
203
6.21k
        case SfxChildAlignment::RIGHT:
204
6.21k
            eTbxAlign = WindowAlign::Right;
205
6.21k
            break;
206
6.21k
        case SfxChildAlignment::TOP:
207
6.21k
            eTbxAlign = WindowAlign::Top;
208
6.21k
            break;
209
6.21k
        case SfxChildAlignment::BOTTOM:
210
6.21k
            eTbxAlign = WindowAlign::Bottom;
211
6.21k
            bPinned = true;
212
6.21k
            break;
213
0
        default:
214
0
            eTbxAlign = WindowAlign::Top;  // some sort of default...
215
0
            break;  // -Wall lots not handled...
216
24.8k
    }
217
218
24.8k
    SetAlign (eTbxAlign);
219
24.8k
    pEmptyWin = VclPtr<SfxEmptySplitWin_Impl>::Create( this );
220
24.8k
    if ( bPinned )
221
24.8k
    {
222
24.8k
        pEmptyWin->bFadeIn = true;
223
24.8k
        pEmptyWin->nState = 2;
224
24.8k
    }
225
226
24.8k
    if ( bWithButtons )
227
24.8k
    {
228
        //  Read Configuration
229
24.8k
        const OUString aWindowId{ "SplitWindow" + OUString::number(static_cast<sal_Int32>(eTbxAlign)) };
230
24.8k
        SvtViewOptions aWinOpt( EViewType::Window, aWindowId );
231
24.8k
        OUString aWinData;
232
24.8k
        Any aUserItem = aWinOpt.GetUserItem( USERITEM_NAME );
233
24.8k
        OUString aTemp;
234
24.8k
        if ( aUserItem >>= aTemp )
235
0
            aWinData = aTemp;
236
24.8k
        if ( aWinData.startsWith("V") )
237
0
        {
238
0
            sal_Int32 nIdx{ 0 };
239
0
            pEmptyWin->nState = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aWinData, 1, ',', nIdx )));
240
0
            if ( pEmptyWin->nState & 2 )
241
0
                pEmptyWin->bFadeIn = true;
242
0
            bPinned = true; // always assume pinned - floating mode not used anymore
243
244
0
            const sal_Int32 nCount{ o3tl::toInt32(o3tl::getToken(aWinData, 0, ',', nIdx)) };
245
0
            for ( sal_Int32 n=0; n<nCount; ++n )
246
0
            {
247
0
                std::unique_ptr<SfxDock_Impl> pDock(new SfxDock_Impl);
248
0
                pDock->pWin = nullptr;
249
0
                pDock->bNewLine = false;
250
0
                pDock->bHide = true;
251
0
                pDock->nType = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aWinData, 0, ',', nIdx)));
252
0
                if ( !pDock->nType )
253
0
                {
254
                    // could mean NewLine
255
0
                    pDock->nType = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aWinData, 0, ',', nIdx)));
256
0
                    if ( !pDock->nType )
257
0
                    {
258
                        // Read error
259
0
                        break;
260
0
                    }
261
0
                    else
262
0
                        pDock->bNewLine = true;
263
0
                }
264
265
0
                maDockArr.insert(maDockArr.begin() + n, std::move(pDock));
266
0
            }
267
0
        }
268
24.8k
    }
269
0
    else
270
0
    {
271
0
        bPinned = true;
272
0
        pEmptyWin->bFadeIn = true;
273
0
        pEmptyWin->nState = 2;
274
0
    }
275
24.8k
}
276
277
278
SfxSplitWindow::~SfxSplitWindow()
279
24.8k
{
280
24.8k
    disposeOnce();
281
24.8k
}
282
283
void SfxSplitWindow::dispose()
284
24.8k
{
285
24.8k
    SaveConfig_Impl();
286
287
24.8k
    if ( pEmptyWin )
288
24.8k
    {
289
        // Set pOwner to NULL, otherwise try to delete pEmptyWin once more. The
290
        // window that is just being docked is always deleted from the outside.
291
24.8k
        pEmptyWin->pOwner = nullptr;
292
24.8k
    }
293
24.8k
    pEmptyWin.disposeAndClear();
294
295
24.8k
    maDockArr.clear();
296
24.8k
    pActive.reset();
297
24.8k
    SplitWindow::dispose();
298
24.8k
}
299
300
void SfxSplitWindow::SaveConfig_Impl()
301
24.8k
{
302
    // Save configuration
303
24.8k
    OUStringBuffer aWinData =
304
24.8k
        "V"
305
24.8k
        + OUString::number(static_cast<sal_Int32>(VERSION))
306
24.8k
        + ","
307
24.8k
        + OUString::number(static_cast<sal_Int32>(pEmptyWin->nState))
308
24.8k
        + ",";
309
310
24.8k
    sal_uInt16 nCount = 0;
311
24.8k
    for ( auto const & rDock: maDockArr )
312
0
    {
313
0
        if ( rDock->bHide || rDock->pWin )
314
0
            nCount++;
315
0
    }
316
317
24.8k
    aWinData.append(static_cast<sal_Int32>(nCount));
318
319
24.8k
    for ( auto const & rDock: maDockArr )
320
0
    {
321
0
        if ( !rDock->bHide && !rDock->pWin )
322
0
            continue;
323
0
        if ( rDock->bNewLine )
324
0
            aWinData.append(",0");
325
0
        aWinData.append("," + OUString::number(static_cast<sal_Int32>(rDock->nType)));
326
0
    }
327
328
24.8k
    const OUString aWindowId{ "SplitWindow" + OUString::number(static_cast<sal_Int32>(GetAlign())) };
329
24.8k
    SvtViewOptions aWinOpt( EViewType::Window, aWindowId );
330
24.8k
    aWinOpt.SetUserItem( USERITEM_NAME, Any( aWinData.makeStringAndClear() ) );
331
24.8k
}
332
333
334
void SfxSplitWindow::StartSplit()
335
0
{
336
0
    tools::Long nSize = 0;
337
0
    Size aSize = GetSizePixel();
338
339
0
    if ( pEmptyWin )
340
0
    {
341
0
        pEmptyWin->bFadeIn = true;
342
0
        pEmptyWin->bSplit = true;
343
0
    }
344
345
0
    tools::Rectangle aRect = pWorkWin->GetFreeArea( !bPinned );
346
0
    switch ( GetAlign() )
347
0
    {
348
0
        case WindowAlign::Left:
349
0
        case WindowAlign::Right:
350
0
            nSize = aSize.Width() + aRect.GetWidth();
351
0
            break;
352
0
        case WindowAlign::Top:
353
0
        case WindowAlign::Bottom:
354
0
            nSize = aSize.Height() + aRect.GetHeight();
355
0
            break;
356
0
    }
357
358
0
    SetMaxSizePixel( nSize );
359
0
}
360
361
362
void SfxSplitWindow::SplitResize()
363
0
{
364
0
    if ( bPinned )
365
0
    {
366
0
        pWorkWin->ArrangeChildren_Impl();
367
0
        pWorkWin->ShowChildren_Impl();
368
0
    }
369
0
    else
370
0
        pWorkWin->ArrangeAutoHideWindows( this );
371
0
}
372
373
374
void SfxSplitWindow::Split()
375
0
{
376
0
    if ( pEmptyWin )
377
0
        pEmptyWin->bSplit = false;
378
379
0
    SplitWindow::Split();
380
381
0
    std::vector< std::pair< sal_uInt16, tools::Long > > aNewOrgSizes;
382
383
0
    sal_uInt16 nCount = maDockArr.size();
384
0
    for ( sal_uInt16 n=0; n<nCount; n++ )
385
0
    {
386
0
        const SfxDock_Impl& rD = *maDockArr[n];
387
0
        if ( rD.pWin )
388
0
        {
389
0
            const sal_uInt16 nId = rD.nType;
390
0
            const tools::Long nSize    = GetItemSize( nId, SplitWindowItemFlags::Fixed );
391
0
            const tools::Long nSetSize = GetItemSize( GetSet( nId ) );
392
0
            Size aSize;
393
394
0
            if ( IsHorizontal() )
395
0
            {
396
0
                aSize.setWidth( nSize );
397
0
                aSize.setHeight( nSetSize );
398
0
            }
399
0
            else
400
0
            {
401
0
                aSize.setWidth( nSetSize );
402
0
                aSize.setHeight( nSize );
403
0
            }
404
405
0
            rD.pWin->SetItemSize_Impl( aSize );
406
407
0
            aNewOrgSizes.emplace_back( nId, nSize );
408
0
        }
409
0
    }
410
411
    // workaround insufficiency of <SplitWindow> regarding dock layouting:
412
    // apply FIXED item size as 'original' item size to improve layouting of undock-dock-cycle of a window
413
0
    {
414
0
        DeactivateUpdateMode aDeactivateUpdateMode( *this );
415
0
        for (const std::pair< sal_uInt16, tools::Long > & rNewOrgSize : aNewOrgSizes)
416
0
        {
417
0
            SetItemSize( rNewOrgSize.first, rNewOrgSize.second );
418
0
        }
419
0
    }
420
421
0
    SaveConfig_Impl();
422
0
}
423
424
425
void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize)
426
427
/*
428
    To insert SfxDockingWindows just pass no position. The SfxSplitWindow
429
    searches the last marked one to the passed SfxDockingWindow or appends a
430
    new one at the end.
431
*/
432
0
{
433
0
    short nLine = -1;  // so that the first window cab set nline to 0
434
0
    sal_uInt16 nPos = 0;
435
0
    bool bNewLine = true;
436
0
    bool bSaveConfig = false;
437
0
    SfxDock_Impl *pFoundDock=nullptr;
438
0
    sal_uInt16 nCount = maDockArr.size();
439
0
    for ( sal_uInt16 n=0; n<nCount; n++ )
440
0
    {
441
0
        SfxDock_Impl& rDock = *maDockArr[n];
442
0
        if ( rDock.bNewLine )
443
0
        {
444
            // The window opens a new line
445
0
            if ( pFoundDock )
446
                // But after the just inserted window
447
0
                break;
448
449
            // New line
450
0
            nPos = 0;
451
0
            bNewLine = true;
452
0
        }
453
454
0
        if ( rDock.pWin )
455
0
        {
456
            // Does there exist a window now at this position
457
0
            if ( bNewLine && !pFoundDock )
458
0
            {
459
                // Not known until now in which real line it is located
460
0
                sal_uInt16 nL = 0;
461
0
                [[maybe_unused]] auto const ok = GetWindowPos( rDock.pWin, nL, nPos );
462
0
                assert(ok);
463
0
                nLine = static_cast<short>(nL);
464
0
            }
465
466
0
            if ( !pFoundDock )
467
0
            {
468
                // The window is located before the inserted one
469
0
                nPos++;
470
0
            }
471
472
            // Line is opened
473
0
            bNewLine = false;
474
0
            if ( pFoundDock )
475
0
                break;
476
0
        }
477
478
0
        if ( rDock.nType == pDockWin->GetType() )
479
0
        {
480
0
            DBG_ASSERT( !pFoundDock && !rDock.pWin, "Window already exists!");
481
0
            pFoundDock = &rDock;
482
0
            if ( !bNewLine )
483
0
                break;
484
0
            else
485
0
            {
486
                // A new line has been created but no window was found there;
487
                // continue searching for a window in this line in-order to set
488
                // bNewLine correctly. While doing so nline or nPos are not
489
                // to be changed!
490
0
                nLine++;
491
0
            }
492
0
        }
493
0
    }
494
495
0
    if ( !pFoundDock )
496
0
    {
497
        // Not found, insert at end
498
0
        pFoundDock = new SfxDock_Impl;
499
0
        pFoundDock->bHide = true;
500
0
        maDockArr.push_back( std::unique_ptr<SfxDock_Impl>(pFoundDock) );
501
0
        pFoundDock->nType = pDockWin->GetType();
502
0
        nLine++;
503
0
        nPos = 0;
504
0
        bNewLine = true;
505
0
        pFoundDock->bNewLine = bNewLine;
506
0
        bSaveConfig = true;
507
0
    }
508
509
0
    pFoundDock->pWin = pDockWin;
510
0
    pFoundDock->bHide = false;
511
0
    InsertWindow_Impl( pFoundDock, rSize, nLine, nPos, bNewLine );
512
0
    if ( bSaveConfig )
513
0
        SaveConfig_Impl();
514
0
}
515
516
517
void SfxSplitWindow::ReleaseWindow_Impl(SfxDockingWindow const *pDockWin, bool bSave)
518
0
{
519
//  The docking window is no longer stored in the internal data.
520
0
    sal_uInt16 nCount = maDockArr.size();
521
0
    for ( sal_uInt16 n=0; n<nCount; n++ )
522
0
    {
523
0
        const SfxDock_Impl& rDock = *maDockArr[n];
524
0
        if ( rDock.nType == pDockWin->GetType() )
525
0
        {
526
0
            if ( rDock.bNewLine && n<nCount-1 )
527
0
                maDockArr[n+1]->bNewLine = true;
528
529
            // Window has a position, this we forget
530
0
            maDockArr.erase(maDockArr.begin() + n);
531
0
            break;
532
0
        }
533
0
    }
534
535
0
    if ( bSave )
536
0
        SaveConfig_Impl();
537
0
}
538
539
540
void SfxSplitWindow::MoveWindow( SfxDockingWindow* pDockWin, const Size& rSize,
541
                        sal_uInt16 nLine, sal_uInt16 nPos, bool bNewLine)
542
543
/*  [Description]
544
545
    The docking window is moved within the SplitWindows.
546
*/
547
548
0
{
549
0
    sal_uInt16 nL = 0;
550
0
    sal_uInt16 nP = 0;
551
0
    [[maybe_unused]] auto const ok = GetWindowPos( pDockWin, nL, nP );
552
0
    assert(ok);
553
554
0
    if ( nLine > nL && GetItemCount( GetItemId( nL ) ) == 1 )
555
0
    {
556
        // If the last window is removed from its line, then everything slips
557
        // one line to the front!
558
0
        nLine--;
559
0
    }
560
0
    RemoveWindow( pDockWin );
561
0
    InsertWindow( pDockWin, rSize, nLine, nPos, bNewLine );
562
0
}
563
564
565
void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize,
566
                        sal_uInt16 nLine, sal_uInt16 nPos, bool bNewLine)
567
568
/*  [Description]
569
570
    The DockingWindow that is pushed on this SplitWindow and shall hold the
571
    given position and size.
572
*/
573
0
{
574
0
    ReleaseWindow_Impl( pDockWin, false );
575
0
    SfxDock_Impl *pDock = new SfxDock_Impl;
576
0
    pDock->bHide = false;
577
0
    pDock->nType = pDockWin->GetType();
578
0
    pDock->bNewLine = bNewLine;
579
0
    pDock->pWin = pDockWin;
580
581
0
    DBG_ASSERT( nPos==0 || !bNewLine, "Wrong Parameter!");
582
0
    if ( bNewLine )
583
0
        nPos = 0;
584
585
    // The window must be inserted before the first window so that it has the
586
    // same or a greater position than pDockWin.
587
0
    sal_uInt16 nCount = maDockArr.size();
588
0
    sal_uInt16 nLastWindowIdx(0);
589
590
    // If no window is found, a first window is inserted
591
0
    sal_uInt16 nInsertPos = 0;
592
0
    for ( sal_uInt16 n=0; n<nCount; n++ )
593
0
    {
594
0
        SfxDock_Impl& rD = *maDockArr[n];
595
596
0
        if (rD.pWin)
597
0
        {
598
            // A docked window has been found. If no suitable window behind
599
            // the desired insertion point s found, then insertion is done at
600
            // the end.
601
0
            nInsertPos = nCount;
602
0
            nLastWindowIdx = n;
603
0
            sal_uInt16 nL=0, nP=0;
604
0
            GetWindowPos( rD.pWin, nL, nP );
605
606
0
            if ( (nL == nLine && nP == nPos) || nL > nLine )
607
0
            {
608
0
                DBG_ASSERT( nL == nLine || bNewLine || nPos > 0, "Wrong Parameter!" );
609
0
                if ( nL == nLine && nPos == 0 && !bNewLine )
610
0
                {
611
0
                    DBG_ASSERT(rD.bNewLine, "No new line?");
612
613
                    // The position is pushed to nPos==0
614
0
                    rD.bNewLine = false;
615
0
                    pDock->bNewLine = true;
616
0
                }
617
618
0
                nInsertPos = n != 0 ? nLastWindowIdx + 1 : 0;    // ignore all non-windows after the last window
619
0
                break;
620
0
            }
621
0
        }
622
0
    }
623
0
    if (nCount != 0 && nInsertPos == nCount && nLastWindowIdx != nCount - 1)
624
0
    {
625
0
        nInsertPos = nLastWindowIdx + 1;    // ignore all non-windows after the last window
626
0
    }
627
628
0
    maDockArr.insert(maDockArr.begin() + nInsertPos, std::unique_ptr<SfxDock_Impl>(pDock));
629
0
    InsertWindow_Impl( pDock, rSize, nLine, nPos, bNewLine );
630
0
    SaveConfig_Impl();
631
0
}
632
633
634
void SfxSplitWindow::InsertWindow_Impl( SfxDock_Impl const * pDock,
635
                        const Size& rSize,
636
                        sal_uInt16 nLine, sal_uInt16 nPos, bool bNewLine)
637
638
/*  [Description]
639
640
    Adds a DockingWindow, and causes the recalculation of the size of
641
    the SplitWindows.
642
*/
643
644
0
{
645
0
    SfxDockingWindow* pDockWin = pDock->pWin;
646
647
0
    SplitWindowItemFlags nItemBits = SplitWindowItemFlags::NONE;
648
649
0
    tools::Long nWinSize, nSetSize;
650
0
    if ( IsHorizontal() )
651
0
    {
652
0
        nWinSize = rSize.Width();
653
0
        nSetSize = rSize.Height();
654
0
    }
655
0
    else
656
0
    {
657
0
        nSetSize = rSize.Width();
658
0
        nWinSize = rSize.Height();
659
0
    }
660
661
0
    std::unique_ptr<DeactivateUpdateMode> pDeactivateUpdateMode(new DeactivateUpdateMode( *this ));
662
663
0
    if ( bNewLine || nLine == GetItemCount() )
664
0
    {
665
        // An existing row should not be inserted, instead a new one
666
        // will be created
667
668
0
        sal_uInt16 nId = 1;
669
0
        for ( sal_uInt16 n=0; n<GetItemCount(); n++ )
670
0
        {
671
0
            if ( GetItemId(n) >= nId )
672
0
                nId = GetItemId(n)+1;
673
0
        }
674
675
        // Create a new nLine:th line
676
0
        SplitWindowItemFlags nBits = nItemBits;
677
0
        if ( GetAlign() == WindowAlign::Top || GetAlign() == WindowAlign::Bottom )
678
0
            nBits |= SplitWindowItemFlags::ColSet;
679
0
        InsertItem( nId, nSetSize, nLine, 0, nBits );
680
0
    }
681
682
    // Insert the window at line with the position nline. ItemWindowSize set to
683
    // "percentage" share since the SV then does the re-sizing as expected,
684
    // "pixel" actually only makes sense if also items with percentage or
685
    // relative sizes are present.
686
0
    nItemBits |= SplitWindowItemFlags::PercentSize;
687
0
    sal_uInt16 nSet = GetItemId( nLine );
688
0
    InsertItem( pDockWin->GetType(), pDockWin, nWinSize, nPos, nSet, nItemBits );
689
690
    // SplitWindows are once created in SFX and when inserting the first
691
    // DockingWindows is made visible.
692
0
    if ( GetItemCount() == 1 && GetItemCount( 1 ) == 1 )
693
0
    {
694
        // The Rearranging in WorkWindow and a Show() on the SplitWindow is
695
        // caused by SfxDockingwindow (->SfxWorkWindow::ConfigChild_Impl)
696
0
        if ( !bPinned && !IsFloatingMode() )
697
0
        {
698
0
            bPinned = true;
699
0
            bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
700
0
            pEmptyWin->bFadeIn = false;
701
0
            SetPinned_Impl( false );
702
0
            pEmptyWin->Actualize();
703
0
            SAL_INFO("sfx", "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
704
0
            pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign )->nVisible = SfxChildVisibility::VISIBLE;
705
            // tdf#113539 FadeIn will call ArrangeChildren_Impl() for us, and avoiding extra calls to that
706
            // can make a different to load times because it avoids extra accessibility calcs
707
0
            if ( bFadeIn )
708
0
                FadeIn();
709
0
            else
710
0
                pWorkWin->ArrangeChildren_Impl();
711
0
        }
712
0
        else
713
0
        {
714
0
            bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
715
0
            pEmptyWin->bFadeIn = false;
716
0
            pEmptyWin->Actualize();
717
0
            if ( !bPinned || !pEmptyWin->bFadeIn )
718
0
            {
719
0
                SAL_INFO("sfx", "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
720
0
            }
721
0
            else
722
0
            {
723
0
                SAL_INFO("sfx", "SfxSplitWindow::InsertWindow_Impl - registering real Splitwindow" );
724
0
            }
725
0
            pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign )->nVisible = SfxChildVisibility::VISIBLE;
726
            // tdf#113539 FadeIn will call ArrangeChildren_Impl() for us, and avoiding extra calls to that
727
            // can make a different to load times because it avoids extra accessibility calcs
728
0
            if ( bFadeIn )
729
0
                FadeIn();
730
0
            else
731
0
                pWorkWin->ArrangeChildren_Impl();
732
0
        }
733
734
0
        pWorkWin->ShowChildren_Impl();
735
0
    }
736
737
0
    pDeactivateUpdateMode.reset();
738
739
    // workaround insufficiency of <SplitWindow> regarding dock layouting:
740
    // apply FIXED item size as 'original' item size to improve layouting of undock-dock-cycle of a window
741
0
    {
742
0
        std::vector< std::pair< sal_uInt16, tools::Long > > aNewOrgSizes;
743
        // get FIXED item sizes
744
0
        sal_uInt16 nCount = maDockArr.size();
745
0
        for ( sal_uInt16 n=0; n<nCount; ++n )
746
0
        {
747
0
            const SfxDock_Impl& rD = *maDockArr[n];
748
0
            if ( rD.pWin )
749
0
            {
750
0
                const sal_uInt16 nId = rD.nType;
751
0
                const tools::Long nSize    = GetItemSize( nId, SplitWindowItemFlags::Fixed );
752
0
                aNewOrgSizes.emplace_back( nId, nSize );
753
0
            }
754
0
        }
755
        // apply new item sizes
756
0
        DeactivateUpdateMode aDeactivateUpdateMode( *this );
757
0
        for (const std::pair< sal_uInt16, tools::Long > & rNewOrgSize : aNewOrgSizes)
758
0
        {
759
0
            SetItemSize( rNewOrgSize.first, rNewOrgSize.second );
760
0
        }
761
0
    }
762
0
}
763
764
765
void SfxSplitWindow::RemoveWindow( SfxDockingWindow const * pDockWin, bool bHide )
766
767
/*  [Description]
768
769
    Removes a DockingWindow. If it was the last one, then the SplitWindow is
770
    being hidden.
771
*/
772
0
{
773
0
    sal_uInt16 nSet = GetSet( pDockWin->GetType() );
774
775
    // SplitWindows are once created in SFX and is made invisible after
776
    // removing the last DockingWindows.
777
0
    if ( GetItemCount( nSet ) == 1 && GetItemCount() == 1 )
778
0
    {
779
        // The Rearranging in WorkWindow is caused by SfxDockingwindow
780
0
        Hide();
781
0
        pEmptyWin->aTimer.Stop();
782
0
        sal_uInt16 nRealState = pEmptyWin->nState;
783
0
        FadeOut_Impl();
784
0
        pEmptyWin->Hide();
785
#ifdef DBG_UTIL
786
        if ( !bPinned || !pEmptyWin->bFadeIn )
787
        {
788
            SAL_INFO("sfx", "SfxSplitWindow::RemoveWindow - releasing empty Splitwindow" );
789
        }
790
        else
791
        {
792
            SAL_INFO("sfx", "SfxSplitWindow::RemoveWindow - releasing real Splitwindow" );
793
        }
794
#endif
795
0
        pWorkWin->ReleaseChild_Impl( *GetSplitWindow() );
796
0
        pEmptyWin->nState = nRealState;
797
0
        pWorkWin->ArrangeAutoHideWindows( this );
798
0
    }
799
800
0
    sal_uInt16 nCount = maDockArr.size();
801
0
    for ( sal_uInt16 n=0; n<nCount; n++ )
802
0
    {
803
0
        SfxDock_Impl& rDock = *maDockArr[n];
804
0
        if ( rDock.nType == pDockWin->GetType() )
805
0
        {
806
0
            rDock.pWin = nullptr;
807
0
            rDock.bHide = bHide;
808
0
            break;
809
0
        }
810
0
    }
811
812
    // Remove Windows, and if it was the last of the line, then also remove
813
    // the line (line = itemset)
814
0
    DeactivateUpdateMode aDeactivateUpdateMode( *this );
815
816
0
    RemoveItem( pDockWin->GetType() );
817
818
0
    if ( nSet && !GetItemCount( nSet ) )
819
0
        RemoveItem( nSet );
820
0
};
821
822
823
bool SfxSplitWindow::GetWindowPos( const SfxDockingWindow* pWindow,
824
                                        sal_uInt16& rLine, sal_uInt16& rPos ) const
825
/*  [Description]
826
827
    Returns the ID of the item sets and items for the DockingWindow in
828
    the position passed on the old row / column-name.
829
*/
830
831
0
{
832
0
    sal_uInt16 nSet = GetSet ( pWindow->GetType() );
833
0
    if ( nSet == SPLITWINDOW_ITEM_NOTFOUND )
834
0
        return false;
835
836
0
    rPos  = GetItemPos( pWindow->GetType(), nSet );
837
0
    rLine = GetItemPos( nSet );
838
0
    return true;
839
0
}
840
841
842
bool SfxSplitWindow::GetWindowPos( const Point& rTestPos,
843
                                      sal_uInt16& rLine, sal_uInt16& rPos ) const
844
/*  [Description]
845
846
    Returns the ID of the item sets and items for the DockingWindow in
847
    the position passed on the old row / column-name.
848
*/
849
850
0
{
851
0
    sal_uInt16 nId = GetItemId( rTestPos );
852
0
    if ( nId == 0 )
853
0
        return false;
854
855
0
    sal_uInt16 nSet = GetSet ( nId );
856
0
    rPos  = GetItemPos( nId, nSet );
857
0
    rLine = GetItemPos( nSet );
858
0
    return true;
859
0
}
860
861
862
sal_uInt16 SfxSplitWindow::GetLineCount() const
863
864
/*  [Description]
865
866
    Returns the number of rows = number of sub-itemsets in the root set.
867
*/
868
0
{
869
0
    return GetItemCount();
870
0
}
871
872
873
tools::Long SfxSplitWindow::GetLineSize( sal_uInt16 nLine ) const
874
875
/*  [Description]
876
877
    Returns the Row Height of nline itemset.
878
*/
879
0
{
880
0
    sal_uInt16 nId = GetItemId( nLine );
881
0
    return GetItemSize( nId );
882
0
}
883
884
885
sal_uInt16 SfxSplitWindow::GetWindowCount( sal_uInt16 nLine ) const
886
887
/*  [Description]
888
889
    Returns the total number of windows
890
*/
891
0
{
892
0
    sal_uInt16 nId = GetItemId( nLine );
893
0
    return GetItemCount( nId );
894
0
}
895
896
897
sal_uInt16 SfxSplitWindow::GetWindowCount() const
898
899
/*  [Description]
900
901
    Returns the total number of windows
902
*/
903
49.7k
{
904
49.7k
    return GetItemCount();
905
49.7k
}
906
907
908
IMPL_LINK( SfxSplitWindow, TimerHdl, Timer*, pTimer, void)
909
0
{
910
0
    if ( pTimer )
911
0
        pTimer->Stop();
912
913
0
    if ( CursorIsOverRect() || !pTimer )
914
0
    {
915
        // If the cursor is within the window, display the SplitWindow and set
916
        // up the timer for close
917
0
        pEmptyWin->bAutoHide = true;
918
0
        if ( !IsVisible() )
919
0
            pEmptyWin->FadeIn();
920
921
0
        pEmptyWin->aLastPos = GetPointerPosPixel();
922
0
        pEmptyWin->aTimer.Start();
923
0
    }
924
0
    else if ( pEmptyWin->bAutoHide )
925
0
    {
926
0
        if ( GetPointerPosPixel() != pEmptyWin->aLastPos )
927
0
        {
928
            // The mouse has moved within the running time of the timer, thus
929
            // do nothing
930
0
            pEmptyWin->aLastPos = GetPointerPosPixel();
931
0
            pEmptyWin->aTimer.Start();
932
0
            return;
933
0
        }
934
935
        // Especially for TF_AUTOSHOW_ON_MOUSEMOVE :
936
        // If the window is not visible, there is nothing to do
937
        // (user has simply moved the mouse over pEmptyWin)
938
0
        if ( IsVisible() )
939
0
        {
940
0
            pEmptyWin->bEndAutoHide = false;
941
0
            if ( !Application::IsInModalMode() &&
942
0
                  !vcl::IsInPopupMenuExecute() &&
943
0
                  !pEmptyWin->bSplit && !HasChildPathFocus( true ) )
944
0
            {
945
                // While a modal dialog or a popup menu is open or while the
946
                // Splitting is done, in any case, do not close. Even as long
947
                // as one of the Children has the focus, the window remains
948
                // open.
949
0
                pEmptyWin->bEndAutoHide = true;
950
0
            }
951
952
0
            if ( pEmptyWin->bEndAutoHide )
953
0
            {
954
               // As far as I am concerned this can be the end of AutoShow
955
               // But maybe some other SfxSplitWindow will remain open,
956
               // then all others remain open too.
957
0
                if ( !pWorkWin->IsAutoHideMode( this ) )
958
0
                {
959
0
                    FadeOut_Impl();
960
0
                    pWorkWin->ArrangeAutoHideWindows( this );
961
0
                }
962
0
                else
963
0
                {
964
0
                    pEmptyWin->aLastPos = GetPointerPosPixel();
965
0
                    pEmptyWin->aTimer.Start();
966
0
                }
967
0
            }
968
0
            else
969
0
            {
970
0
                pEmptyWin->aLastPos = GetPointerPosPixel();
971
0
                pEmptyWin->aTimer.Start();
972
0
            }
973
0
        }
974
0
    }
975
0
}
976
977
978
bool SfxSplitWindow::CursorIsOverRect() const
979
0
{
980
0
    bool bVisible = IsVisible();
981
982
    // Also, take the collapsed SplitWindow into account
983
0
    Point aPos = pEmptyWin->GetParent()->OutputToScreenPixel( pEmptyWin->GetPosPixel() );
984
0
    Size aSize = pEmptyWin->GetSizePixel();
985
986
0
    tools::Rectangle aRect( aPos, aSize );
987
988
0
    if ( bVisible )
989
0
    {
990
0
        Point aVisPos = GetPosPixel();
991
0
        Size aVisSize = GetSizePixel();
992
993
        // Extend with +/- a few pixels, otherwise it is too nervous
994
0
        aVisPos.AdjustX( -(nPixel) );
995
0
        aVisPos.AdjustY( -(nPixel) );
996
0
        aVisSize.AdjustWidth(2 * nPixel );
997
0
        aVisSize.AdjustHeight(2 * nPixel );
998
999
0
        tools::Rectangle aVisRect( aVisPos, aVisSize );
1000
0
        aRect = aRect.GetUnion( aVisRect );
1001
0
    }
1002
1003
0
    return aRect.Contains( OutputToScreenPixel( static_cast<vcl::Window*>(const_cast<SfxSplitWindow *>(this))->GetPointerPosPixel() ) );
1004
0
}
1005
1006
1007
SplitWindow* SfxSplitWindow::GetSplitWindow()
1008
0
{
1009
0
    if ( !bPinned || !pEmptyWin->bFadeIn )
1010
0
        return pEmptyWin;
1011
0
    return this;
1012
0
}
1013
1014
1015
bool SfxSplitWindow::IsFadeIn() const
1016
0
{
1017
0
    return pEmptyWin->bFadeIn;
1018
0
}
1019
1020
bool SfxSplitWindow::IsAutoHide( bool bSelf ) const
1021
0
{
1022
0
    return bSelf ? pEmptyWin->bAutoHide && !pEmptyWin->bEndAutoHide : pEmptyWin->bAutoHide;
1023
0
}
1024
1025
1026
void SfxSplitWindow::SetPinned_Impl( bool bOn )
1027
0
{
1028
0
    if ( bPinned == bOn )
1029
0
        return;
1030
1031
0
    bPinned = bOn;
1032
0
    if ( GetItemCount() == 0 )
1033
0
        return;
1034
1035
0
    if ( !bOn )
1036
0
    {
1037
0
        pEmptyWin->nState |= 1;
1038
0
        if ( pEmptyWin->bFadeIn )
1039
0
        {
1040
            // Unregister replacement windows
1041
0
            SAL_INFO("sfx", "SfxSplitWindow::SetPinned_Impl - releasing real Splitwindow" );
1042
0
            pWorkWin->ReleaseChild_Impl( *this );
1043
0
            Hide();
1044
0
            pEmptyWin->Actualize();
1045
0
            SAL_INFO("sfx", "SfxSplitWindow::SetPinned_Impl - registering empty Splitwindow" );
1046
0
            pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign )->nVisible = SfxChildVisibility::VISIBLE;
1047
0
        }
1048
1049
0
        Point aPos( GetPosPixel() );
1050
0
        aPos = GetParent()->OutputToScreenPixel( aPos );
1051
0
        SetFloatingPos( aPos );
1052
0
        SetFloatingMode( true );
1053
0
        GetFloatingWindow()->SetOutputSizePixel( GetOutputSizePixel() );
1054
1055
0
        if ( pEmptyWin->bFadeIn )
1056
0
            Show();
1057
0
    }
1058
0
    else
1059
0
    {
1060
0
        pEmptyWin->nState &= ~1;
1061
0
        SetOutputSizePixel( GetFloatingWindow()->GetOutputSizePixel() );
1062
0
        SetFloatingMode(false);
1063
1064
0
        if ( pEmptyWin->bFadeIn )
1065
0
        {
1066
            // Unregister replacement windows
1067
0
            SAL_INFO("sfx", "SfxSplitWindow::SetPinned_Impl - releasing empty Splitwindow" );
1068
0
            pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1069
0
            pEmptyWin->Hide();
1070
0
            SAL_INFO("sfx", "SfxSplitWindow::SetPinned_Impl - registering real Splitwindow" );
1071
0
            pWorkWin->RegisterChild_Impl( *this, eAlign )->nVisible = SfxChildVisibility::VISIBLE;
1072
0
        }
1073
0
    }
1074
0
}
1075
1076
void SfxSplitWindow::SetFadeIn_Impl( bool bOn )
1077
0
{
1078
0
    if ( bOn == pEmptyWin->bFadeIn )
1079
0
        return;
1080
1081
0
    if ( GetItemCount() == 0 )
1082
0
        return;
1083
1084
0
    pEmptyWin->bFadeIn = bOn;
1085
0
    if ( bOn )
1086
0
    {
1087
0
        pEmptyWin->nState |= 2;
1088
0
        if ( IsFloatingMode() )
1089
0
        {
1090
            // FloatingWindow is not visible, thus display it
1091
0
            pWorkWin->ArrangeAutoHideWindows( this );
1092
0
            Show();
1093
0
        }
1094
0
        else
1095
0
        {
1096
0
            SAL_INFO("sfx", "SfxSplitWindow::SetFadeIn_Impl - releasing empty Splitwindow" );
1097
0
            pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1098
0
            pEmptyWin->Hide();
1099
0
            SAL_INFO("sfx", "SfxSplitWindow::SetFadeIn_Impl - registering real Splitwindow" );
1100
0
            pWorkWin->RegisterChild_Impl( *this, eAlign )->nVisible = SfxChildVisibility::VISIBLE;
1101
0
            pWorkWin->ArrangeChildren_Impl();
1102
0
            pWorkWin->ShowChildren_Impl();
1103
0
        }
1104
0
    }
1105
0
    else
1106
0
    {
1107
0
        pEmptyWin->bAutoHide = false;
1108
0
        pEmptyWin->nState &= ~2;
1109
0
        if ( !IsFloatingMode() )
1110
0
        {
1111
            // The window is not "floating", should be hidden
1112
0
            SAL_INFO("sfx", "SfxSplitWindow::SetFadeIn_Impl - releasing real Splitwindow" );
1113
0
            pWorkWin->ReleaseChild_Impl( *this );
1114
0
            Hide();
1115
0
            pEmptyWin->Actualize();
1116
0
            SAL_INFO("sfx", "SfxSplitWindow::SetFadeIn_Impl - registering empty Splitwindow" );
1117
0
            pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign )->nVisible = SfxChildVisibility::VISIBLE;
1118
0
            pWorkWin->ArrangeChildren_Impl();
1119
0
            pWorkWin->ShowChildren_Impl();
1120
0
            pWorkWin->ArrangeAutoHideWindows( this );
1121
0
        }
1122
0
        else
1123
0
        {
1124
0
            Hide();
1125
0
            pWorkWin->ArrangeAutoHideWindows( this );
1126
0
        }
1127
0
    }
1128
0
}
1129
1130
void SfxSplitWindow::FadeOut_Impl()
1131
0
{
1132
0
    if ( pEmptyWin->aTimer.IsActive() )
1133
0
    {
1134
0
        pEmptyWin->bAutoHide = false;
1135
0
        pEmptyWin->aTimer.Stop();
1136
0
    }
1137
1138
0
    SetFadeIn_Impl( false );
1139
0
}
1140
1141
void SfxSplitWindow::FadeOut()
1142
0
{
1143
0
    FadeOut_Impl();
1144
0
    SaveConfig_Impl();
1145
0
}
1146
1147
void SfxSplitWindow::FadeIn()
1148
0
{
1149
0
    SetFadeIn_Impl( true );
1150
0
}
1151
1152
void SfxSplitWindow::SetActiveWindow_Impl( SfxDockingWindow* pWin )
1153
0
{
1154
0
    pActive = pWin;
1155
0
    pWorkWin->SetActiveChild_Impl( this );
1156
0
}
1157
1158
1159
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */