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