Bug Summary

File:home/maarten/src/libreoffice/core/sfx2/source/dialog/splitwin.cxx
Warning:line 459, column 23
Assigned value is garbage or undefined

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name splitwin.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sfx2/source/dialog/splitwin.cxx

/home/maarten/src/libreoffice/core/sfx2/source/dialog/splitwin.cxx

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

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
7
Assuming the condition is true
8
Returning the value 1, which participates in a condition later
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */