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