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