xref: /aoo41x/main/sfx2/source/dialog/splitwin.cxx (revision abd9d880)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 
31 #ifdef SOLARIS
32 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
33 #include <ctime>
34 #endif
35 
36 #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
37 
38 #ifndef _WRKWIN_HXX //autogen
39 #include <vcl/wrkwin.hxx>
40 #endif
41 #include <unotools/viewoptions.hxx>
42 #ifndef GCC
43 #endif
44 
45 #include <vcl/timer.hxx>
46 
47 #include "splitwin.hxx"
48 #include "workwin.hxx"
49 #include <sfx2/dockwin.hxx>
50 #include <sfx2/app.hxx>
51 #include "dialog.hrc"
52 #include "sfx2/sfxresid.hxx"
53 #include <sfx2/mnumgr.hxx>
54 #include "virtmenu.hxx"
55 #include <sfx2/msgpool.hxx>
56 #include <sfx2/viewfrm.hxx>
57 
58 using namespace ::com::sun::star::uno;
59 using namespace ::rtl;
60 
61 #define VERSION	1
62 #define nPixel	30L
63 #define USERITEM_NAME			OUString::createFromAscii( "UserItem" )
64 
65 struct SfxDock_Impl
66 {
67 	sal_uInt16 				nType;
68 	SfxDockingWindow*	pWin;			// SplitWindow hat dieses Fenster
69 	sal_Bool				bNewLine;
70 	sal_Bool				bHide;			// SplitWindow hatte dieses Fenster
71 	long				nSize;
72 };
73 
74 typedef SfxDock_Impl* SfxDockPtr;
75 SV_DECL_PTRARR_DEL( SfxDockArr_Impl, SfxDockPtr, 4, 4)
76 SV_IMPL_PTRARR( SfxDockArr_Impl, SfxDockPtr);
77 
78 class SfxEmptySplitWin_Impl : public SplitWindow
79 {
80 /*  [Beschreibung]
81 
82 	Das SfxEmptySplitWin_Impldow ist ein leeres SplitWindow, das das SfxSplitWindow
83 	im AutoHide-Modus ersetzt. Es dient nur als Platzhalter, um MouseMoves
84 	zu empfangen und ggf. das eigentlichte SplitWindow einzublenden
85 */
86 friend class SfxSplitWindow;
87 
88 	SfxSplitWindow* 	pOwner;
89 	sal_Bool				bFadeIn;
90 	sal_Bool				bAutoHide;
91 	sal_Bool				bSplit;
92 	sal_Bool				bEndAutoHide;
93 	Timer				aTimer;
94 	Point				aLastPos;
95 	sal_uInt16				nState;
96 
97 						SfxEmptySplitWin_Impl( SfxSplitWindow *pParent )
98 							: SplitWindow( pParent->GetParent(), WinBits( WB_BORDER | WB_3DLOOK ) )
99 							, pOwner( pParent )
100 							, bFadeIn( sal_False )
101 							, bAutoHide( sal_False )
102 							, bSplit( sal_False )
103 							, bEndAutoHide( sal_False )
104 							, nState( 1 )
105 						{
106 							aTimer.SetTimeoutHdl(
107 								LINK(pOwner, SfxSplitWindow, TimerHdl ) );
108 							aTimer.SetTimeout( 200 );
109 //                            EnableDrop( sal_True );
110 							SetAlign( pOwner->GetAlign() );
111 							Actualize();
112 							ShowAutoHideButton( pOwner->IsAutoHideButtonVisible() );
113 							ShowFadeInHideButton( sal_True );
114 						}
115 
116 						~SfxEmptySplitWin_Impl()
117 						{
118 							aTimer.Stop();
119 						}
120 
121 	virtual void		MouseMove( const MouseEvent& );
122 	virtual void		AutoHide();
123 	virtual void		FadeIn();
124 	void				Actualize();
125 };
126 
127 void SfxEmptySplitWin_Impl::Actualize()
128 {
129 	Size aSize( pOwner->GetSizePixel() );
130 	switch ( pOwner->GetAlign() )
131 	{
132 		case WINDOWALIGN_LEFT:
133 		case WINDOWALIGN_RIGHT:
134 			aSize.Width() = GetFadeInSize();
135 			break;
136 		case WINDOWALIGN_TOP:
137 		case WINDOWALIGN_BOTTOM:
138 			aSize.Height() = GetFadeInSize();
139 			break;
140 	}
141 
142 	SetSizePixel( aSize );
143 }
144 
145 void SfxEmptySplitWin_Impl::AutoHide()
146 {
147 	pOwner->SetPinned_Impl( !pOwner->bPinned );
148 	pOwner->SaveConfig_Impl();
149 	bAutoHide = sal_True;
150 	FadeIn();
151 }
152 
153 void SfxEmptySplitWin_Impl::FadeIn()
154 {
155 	if (!bAutoHide )
156 		bAutoHide = IsFadeNoButtonMode();
157 	pOwner->SetFadeIn_Impl( sal_True );
158 	pOwner->Show_Impl();
159 	if ( bAutoHide )
160 	{
161 		// Timer zum Schlie\sen aufsetzen; der Aufrufer mu\s selbst sicherstellen,
162 		// da\s das Window nicht gleich wieder zu geht ( z.B. durch Setzen des
163 		// Focus oder einen modal mode )
164 		aLastPos = GetPointerPosPixel();
165 		aTimer.Start();
166 	}
167 	else
168 		pOwner->SaveConfig_Impl();
169 }
170 
171 //-------------------------------------------------------------------------
172 
173 void SfxSplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
174 {
175 	if ( rMEvt.GetClicks() != 2 )
176 		SplitWindow::MouseButtonDown( rMEvt );
177 }
178 
179 void SfxEmptySplitWin_Impl::MouseMove( const MouseEvent& rMEvt )
180 {
181 	SplitWindow::MouseMove( rMEvt );
182 }
183 
184 //-------------------------------------------------------------------------
185 
186 SfxSplitWindow::SfxSplitWindow( Window* pParent, SfxChildAlignment eAl,
187 		SfxWorkWindow *pW, sal_Bool bWithButtons, WinBits nBits )
188 
189 /*  [Beschreibung]
190 
191 	Ein SfxSplitWindow verbirgt die rekursive Struktur des SV-Splitwindows
192 	nach au\sen, indem es einen tabellenartigen Aufbau mit Zeilen und Spalten
193 	( also maximale Rekursionstiefe 2 ) simuliert.
194 	Au\erdem sichert es die Persistenz der Anordnung der SfxDockingWindows.
195 */
196 
197 :	SplitWindow ( pParent, nBits | WB_HIDE ),
198 	eAlign(eAl),
199 	pWorkWin(pW),
200 	pDockArr( new SfxDockArr_Impl ),
201 	bLocked(sal_False),
202 	bPinned(sal_True),
203 	pEmptyWin(NULL),
204 	pActive(NULL)
205 {
206 	if ( bWithButtons )
207 	{
208 		ShowAutoHideButton( sal_False );    // no autohide button (pin) anymore
209 		ShowFadeOutButton( sal_True );
210 	}
211 
212 	// SV-Alignment setzen
213 	WindowAlign eTbxAlign;
214 	switch ( eAlign )
215 	{
216 		case SFX_ALIGN_LEFT:
217 			eTbxAlign = WINDOWALIGN_LEFT;
218 			break;
219 		case SFX_ALIGN_RIGHT:
220 			eTbxAlign = WINDOWALIGN_RIGHT;
221 			break;
222 		case SFX_ALIGN_TOP:
223 			eTbxAlign = WINDOWALIGN_TOP;
224 			break;
225 		case SFX_ALIGN_BOTTOM:
226 			eTbxAlign = WINDOWALIGN_BOTTOM;
227 			bPinned = sal_True;
228 			break;
229 		default:
230 			eTbxAlign = WINDOWALIGN_TOP;  // some sort of default...
231 			break;  // -Wall lots not handled..
232 	}
233 
234 	SetAlign (eTbxAlign);
235 	pEmptyWin = new SfxEmptySplitWin_Impl( this );
236 	if ( bPinned )
237 	{
238 		pEmptyWin->bFadeIn = sal_True;
239 		pEmptyWin->nState = 2;
240 	}
241 
242 	if ( bWithButtons )
243 	{
244 		// Konfiguration einlesen
245         String aWindowId = String::CreateFromAscii("SplitWindow");
246         aWindowId += String::CreateFromInt32( (sal_Int32) eTbxAlign );
247         SvtViewOptions aWinOpt( E_WINDOW, aWindowId );
248         String aWinData;
249 		Any aUserItem = aWinOpt.GetUserItem( USERITEM_NAME );
250 		OUString aTemp;
251 		if ( aUserItem >>= aTemp )
252 			aWinData = String( aTemp );
253         if ( aWinData.Len() && aWinData.GetChar( (sal_uInt16) 0 ) == 'V' )
254         {
255             pEmptyWin->nState = (sal_uInt16) aWinData.GetToken( 1, ',' ).ToInt32();
256             if ( pEmptyWin->nState & 2 )
257                 pEmptyWin->bFadeIn = sal_True;
258             //bPinned = !( pEmptyWin->nState & 1 );
259             bPinned = sal_True; // always assume pinned - floating mode not used anymore
260 
261             sal_uInt16 i=2;
262             sal_uInt16 nCount = (sal_uInt16) aWinData.GetToken(i++, ',').ToInt32();
263             for ( sal_uInt16 n=0; n<nCount; n++ )
264             {
265                 SfxDock_Impl *pDock = new SfxDock_Impl;
266                 pDock->pWin = 0;
267                 pDock->bNewLine = sal_False;
268                 pDock->bHide = sal_True;
269                 pDock->nType = (sal_uInt16) aWinData.GetToken(i++, ',').ToInt32();
270                 if ( !pDock->nType )
271                 {
272                     // K"onnte NewLine bedeuten
273                     pDock->nType = (sal_uInt16) aWinData.GetToken(i++, ',').ToInt32();
274                     if ( !pDock->nType )
275                     {
276                         // Lesefehler
277                         delete pDock;
278                         break;
279                     }
280                     else
281                         pDock->bNewLine = sal_True;
282                 }
283 
284                 pDockArr->Insert(pDock,n);
285             }
286         }
287 	}
288 	else
289 	{
290 		bPinned = sal_True;
291 		pEmptyWin->bFadeIn = sal_True;
292 		pEmptyWin->nState = 2;
293 	}
294 
295 	SetAutoHideState( !bPinned );
296 	pEmptyWin->SetAutoHideState( !bPinned );
297 }
298 
299 //-------------------------------------------------------------------------
300 
301 SfxSplitWindow::~SfxSplitWindow()
302 {
303 	if ( !pWorkWin->GetParent_Impl() )
304 		SaveConfig_Impl();
305 
306 	if ( pEmptyWin )
307 	{
308 		// pOwner auf NULL setzen, sonst versucht pEmptyWin, nochmal zu
309 		// l"oschen; es wird n"amlich von au\sen immer das Fenster deleted,
310 		// das gerade angedockt ist
311 		pEmptyWin->pOwner = NULL;
312 		delete pEmptyWin;
313 	}
314 
315 	delete pDockArr;
316 }
317 
318 void SfxSplitWindow::SaveConfig_Impl()
319 {
320 	// Konfiguration abspeichern
321 	String aWinData('V');
322     aWinData += String::CreateFromInt32( VERSION );
323 	aWinData += ',';
324     aWinData += String::CreateFromInt32( pEmptyWin->nState );
325 	aWinData += ',';
326 
327 	sal_uInt16 nCount = 0;
328 	sal_uInt16 n;
329 	for ( n=0; n<pDockArr->Count(); n++ )
330 	{
331 		SfxDock_Impl *pDock = (*pDockArr)[n];
332 		if ( pDock->bHide || pDock->pWin )
333 			nCount++;
334 	}
335 
336     aWinData += String::CreateFromInt32( nCount );
337 
338 	for ( n=0; n<pDockArr->Count(); n++ )
339 	{
340 		SfxDock_Impl *pDock = (*pDockArr)[n];
341 		if ( !pDock->bHide && !pDock->pWin )
342 			continue;
343 		if ( pDock->bNewLine )
344 			aWinData += DEFINE_CONST_UNICODE(",0");
345 		aWinData += ',';
346         aWinData += String::CreateFromInt32( pDock->nType);
347 	}
348 
349     String aWindowId = String::CreateFromAscii("SplitWindow");
350     aWindowId += String::CreateFromInt32( (sal_Int32) GetAlign() );
351     SvtViewOptions aWinOpt( E_WINDOW, aWindowId );
352 	aWinOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aWinData ) ) );
353 }
354 
355 //-------------------------------------------------------------------------
356 
357 void SfxSplitWindow::StartSplit()
358 {
359 	long nSize = 0;
360 	Size aSize = GetSizePixel();
361 
362 	if ( pEmptyWin )
363 	{
364 		pEmptyWin->bFadeIn = sal_True;
365 		pEmptyWin->bSplit = sal_True;
366 	}
367 
368 	Rectangle aRect = pWorkWin->GetFreeArea( !bPinned );
369 	switch ( GetAlign() )
370 	{
371 		case WINDOWALIGN_LEFT:
372 		case WINDOWALIGN_RIGHT:
373 			nSize = aSize.Width() + aRect.GetWidth();
374 			break;
375 		case WINDOWALIGN_TOP:
376 		case WINDOWALIGN_BOTTOM:
377 			nSize = aSize.Height() + aRect.GetHeight();
378 			break;
379 	}
380 
381 	SetMaxSizePixel( nSize );
382 }
383 
384 //-------------------------------------------------------------------------
385 
386 void SfxSplitWindow::SplitResize()
387 {
388 	if ( bPinned )
389 	{
390 		pWorkWin->ArrangeChilds_Impl();
391 		pWorkWin->ShowChilds_Impl();
392 	}
393 	else
394 		pWorkWin->ArrangeAutoHideWindows( this );
395 }
396 
397 //-------------------------------------------------------------------------
398 
399 void SfxSplitWindow::Split()
400 {
401 	if ( pEmptyWin )
402 		pEmptyWin->bSplit = sal_False;
403 
404 	SplitWindow::Split();
405 
406 	sal_uInt16 nCount = pDockArr->Count();
407 	for ( sal_uInt16 n=0; n<nCount; n++ )
408 	{
409 		SfxDock_Impl *pD = (*pDockArr)[n];
410 		if ( pD->pWin )
411 		{
412 			sal_uInt16 nId = pD->nType;
413 			long nSize    = GetItemSize( nId, SWIB_FIXED );
414 			long nSetSize = GetItemSize( GetSet( nId ) );
415 			Size aSize;
416 
417 			if ( IsHorizontal() )
418 			{
419 				aSize.Width()  = nSize;
420 				aSize.Height() = nSetSize;
421 			}
422 			else
423 			{
424 				aSize.Width()  = nSetSize;
425 				aSize.Height() = nSize;
426 			}
427 
428 			pD->pWin->SetItemSize_Impl( aSize );
429 		}
430 	}
431 
432 	SaveConfig_Impl();
433 }
434 
435 //-------------------------------------------------------------------------
436 
437 void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize)
438 
439 /*  [Beschreibung]
440 
441 	Zum Einf"ugen von SfxDockingWindows kann auch keine Position "ubergeben
442 	werden. Das SfxSplitWindow sucht dann die zuletzt gemerkte zu dem
443 	"ubergebenen SfxDockingWindow heraus oder h"angt es als letztes neu an.
444 
445 */
446 {
447 	short nLine = -1;    	// damit erstes Fenster nLine auf 0 hochsetzen kann
448 	sal_uInt16 nL;
449 	sal_uInt16 nPos = 0;
450 	sal_Bool bNewLine = sal_True;
451 	sal_Bool bSaveConfig = sal_False;
452 	SfxDock_Impl *pFoundDock=0;
453 	sal_uInt16 nCount = pDockArr->Count();
454 	for ( sal_uInt16 n=0; n<nCount; n++ )
455 	{
456 		SfxDock_Impl *pDock = (*pDockArr)[n];
457 		if ( pDock->bNewLine )
458 		{
459 			// Das Fenster er"offnet eine neue Zeile
460 			if ( pFoundDock )
461 				// Aber hinter dem gerade eingef"ugten Fenster
462 				break;
463 
464 			// Neue Zeile
465 			nPos = 0;
466 			bNewLine = sal_True;
467 		}
468 
469 		if ( pDock->pWin )
470 		{
471 			// Es gibt an dieser Stelle gerade ein Fenster
472 			if ( bNewLine && !pFoundDock )
473 			{
474 				// Bisher ist nicht bekannt, in welcher realen Zeile es liegt
475 				GetWindowPos( pDock->pWin, nL, nPos );
476 				nLine = (short) nL;
477 			}
478 
479 			if ( !pFoundDock )
480 			{
481 				// Fenster liegt vor dem eingef"ugten
482 				nPos++;
483 			}
484 
485 			// Zeile ist schon er"offnet
486 			bNewLine = sal_False;
487 			if ( pFoundDock )
488 				break;
489 		}
490 
491 		if ( pDock->nType == pDockWin->GetType() )
492 		{
493 			DBG_ASSERT( !pFoundDock && !pDock->pWin, "Fenster ist schon vorhanden!");
494 			pFoundDock = pDock;
495 			if ( !bNewLine )
496 				break;
497 			else
498 			{
499 				// Es wurde zuletzt eine neue Reihe gestartet, aber noch kein
500 				// darin liegendes Fenster gefunden; daher weitersuchen, ob noch
501 				// ein Fenster in dieser Zeile folgt, um bNewLine korrekt zu setzen.
502 				// Dabei darf aber nLine oder nPos nicht mehr ver"andert werden!
503 				nLine++;
504 			}
505 		}
506 	}
507 
508 	if ( !pFoundDock )
509 	{
510 		// Nicht gefunden, am Ende einf"ugen
511 		pFoundDock = new SfxDock_Impl;
512 		pFoundDock->bHide = sal_True;
513 		pDockArr->Insert( pFoundDock, nCount );
514 		pFoundDock->nType = pDockWin->GetType();
515 		nLine++;
516 		nPos = 0;
517 		bNewLine = sal_True;
518 		pFoundDock->bNewLine = bNewLine;
519 		bSaveConfig = sal_True;
520 	}
521 
522 	pFoundDock->pWin = pDockWin;
523 	pFoundDock->bHide = sal_False;
524 	InsertWindow_Impl( pFoundDock, rSize, nLine, nPos, bNewLine );
525 	if ( bSaveConfig )
526 		SaveConfig_Impl();
527 }
528 
529 //-------------------------------------------------------------------------
530 
531 void SfxSplitWindow::ReleaseWindow_Impl(SfxDockingWindow *pDockWin, sal_Bool bSave)
532 
533 /*  [Beschreibung]
534 
535 	Das DockingWindow wird nicht mehr in den internen Daten gespeichert.
536 */
537 
538 {
539 	SfxDock_Impl *pDock=0;
540 	sal_uInt16 nCount = pDockArr->Count();
541 	sal_Bool bFound = sal_False;
542 	for ( sal_uInt16 n=0; n<nCount; n++ )
543 	{
544 		pDock = (*pDockArr)[n];
545 		if ( pDock->nType == pDockWin->GetType() )
546 		{
547 			if ( pDock->bNewLine && n<nCount-1 )
548 				(*pDockArr)[n+1]->bNewLine = sal_True;
549 
550 			// Fenster hat schon eine Position, die vergessen wir
551 			bFound = sal_True;
552 			pDockArr->Remove(n);
553 			break;
554 		}
555 	}
556 
557 	if ( bFound )
558 		delete pDock;
559 
560 	if ( bSave )
561 		SaveConfig_Impl();
562 }
563 
564 //-------------------------------------------------------------------------
565 
566 void SfxSplitWindow::MoveWindow( SfxDockingWindow* pDockWin, const Size& rSize,
567 						sal_uInt16 nLine, sal_uInt16 nPos, sal_Bool bNewLine)
568 
569 /*  [Beschreibung]
570 
571 	Das DockingWindow wird innerhalb des Splitwindows verschoben.
572 
573 */
574 
575 {
576 	sal_uInt16 nL, nP;
577 	GetWindowPos( pDockWin, nL, nP );
578 
579 	if ( nLine > nL && GetItemCount( GetItemId( nL, 0 ) ) == 1 )
580 	{
581 		// Wenn das letzte Fenster aus seiner Zeile entfernt wird, rutscht
582 		// alles eine Zeile nach vorne!
583 		nLine--;
584 	}
585 /*
586 	else if ( nLine == nL && nPos > nP )
587 	{
588 		nPos--;
589 	}
590 */
591 	RemoveWindow( pDockWin );
592 	InsertWindow( pDockWin, rSize, nLine, nPos, bNewLine );
593 }
594 
595 //-------------------------------------------------------------------------
596 
597 void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize,
598 						sal_uInt16 nLine, sal_uInt16 nPos, sal_Bool bNewLine)
599 
600 /*  [Beschreibung]
601 
602 	Das DockingWindow wird in dieses Splitwindow geschoben und soll die
603 	"ubergebene Position und Gr"o\se haben.
604 
605 */
606 {
607 	ReleaseWindow_Impl( pDockWin, sal_False );
608 	SfxDock_Impl *pDock = new SfxDock_Impl;
609 	pDock->bHide = sal_False;
610 	pDock->nType = pDockWin->GetType();
611 	pDock->bNewLine = bNewLine;
612 	pDock->pWin = pDockWin;
613 
614 	DBG_ASSERT( nPos==0 || !bNewLine, "Wrong Parameter!");
615 	if ( bNewLine )
616 		nPos = 0;
617 
618 	// Das Fenster mu\s vor dem ersten Fenster eingef"ugt werden, das die
619 	// gleiche oder eine gr"o\sere Position hat als pDockWin.
620 	sal_uInt16 nLastWindowIdx(0);
621 
622 	// Wenn gar kein Fenster gefunden wird, wird als erstes eingef"ugt
623 	sal_uInt16 nInsertPos = 0;
624 	for ( sal_uInt16 n=0; n<nCount; n++ )
625 	{
626 		SfxDock_Impl *pD = (*pDockArr)[n];
627 
628 		if (pD->pWin)
629 		{
630 			// Ein angedocktes Fenster wurde gefunden
631 			// Wenn kein geeignetes Fenster hinter der gew"unschten Einf"ugeposition
632 			// gefunden wird, wird am Ende eingef"ugt
633 			nInsertPos = nCount;
634 			nLastWindowIdx = n;
635 			sal_uInt16 nL=0, nP=0;
636 			GetWindowPos( pD->pWin, nL, nP );
637 
638 			if ( (nL == nLine && nP == nPos) || nL > nLine )
639 			{
640 				DBG_ASSERT( nL == nLine || bNewLine || nPos > 0, "Wrong Parameter!" );
641 				if ( nL == nLine && nPos == 0 && !bNewLine )
642 				{
643 					DBG_ASSERT(pD->bNewLine, "No new line?");
644 
645 					// Das Fenster wird auf nPos==0 eingeschoben
646 					pD->bNewLine = sal_False;
647 					pDock->bNewLine = sal_True;
648 				}
649 
650 				nInsertPos = n != 0 ? nLastWindowIdx + 1 : 0;    // ignore all non-windows after the last window
651 				break;
652 			}
653 		}
654 	}
655     if (nInsertPos == nCount && nLastWindowIdx != nCount - 1)
656     {
657         nInsertPos = nLastWindowIdx + 1;    // ignore all non-windows after the last window
658     }
659 
660 	pDockArr->Insert(pDock, nInsertPos);
661 	InsertWindow_Impl( pDock, rSize, nLine, nPos, bNewLine );
662 	SaveConfig_Impl();
663 }
664 
665 //-------------------------------------------------------------------------
666 
667 void SfxSplitWindow::InsertWindow_Impl( SfxDock_Impl* pDock,
668 						const Size& rSize,
669 						sal_uInt16 nLine, sal_uInt16 nPos, sal_Bool bNewLine)
670 
671 /*  [Beschreibung]
672 
673 	F"ugt ein DockingWindow ein und veranla\st die Neuberechnung der Gr"o\se
674 	des Splitwindows.
675 */
676 
677 {
678 	SfxDockingWindow* pDockWin = pDock->pWin;
679 
680 	sal_uInt16 nItemBits = pDockWin->GetWinBits_Impl();
681 
682 	long nWinSize, nSetSize;
683 	if ( IsHorizontal() )
684 	{
685 		nWinSize = rSize.Width();
686 		nSetSize = rSize.Height();
687 	}
688 	else
689 	{
690 		nSetSize = rSize.Width();
691 		nWinSize = rSize.Height();
692 	}
693 
694 	pDock->nSize = nWinSize;
695 
696 	sal_Bool bUpdateMode = IsUpdateMode();
697 	if ( bUpdateMode )
698 		SetUpdateMode( sal_False );
699 
700 	if ( bNewLine || nLine == GetItemCount( 0 ) )
701 	{
702 		// Es soll nicht in eine vorhandene Zeile eingef"ugt werden, sondern
703 		// eine neue erzeugt werden
704 
705 		sal_uInt16 nId = 1;
706 		for ( sal_uInt16 n=0; n<GetItemCount(0); n++ )
707 		{
708 			if ( GetItemId(n) >= nId )
709 				nId = GetItemId(n)+1;
710 		}
711 
712 		// Eine neue nLine-te Zeile erzeugen
713 		sal_uInt16 nBits = nItemBits;
714 		if ( GetAlign() == WINDOWALIGN_TOP || GetAlign() == WINDOWALIGN_BOTTOM )
715 			nBits |= SWIB_COLSET;
716 		InsertItem( nId, nSetSize, nLine, 0, nBits );
717 	}
718 
719 	// In Zeile mit Position nLine das Fenster einf"ugen
720 	// ItemWindowSize auf "Prozentual" setzen, da SV dann das Umgr"o\sern
721 	// so macht, wie man erwartet; "Pixel" macht eigentlich nur Sinn, wenn
722 	// auch Items mit prozentualen oder relativen Gr"o\sen dabei sind.
723 	nItemBits |= SWIB_PERCENTSIZE;
724 	bLocked = sal_True;
725 	sal_uInt16 nSet = GetItemId( nLine );
726 	InsertItem( pDockWin->GetType(), pDockWin, nWinSize, nPos, nSet, nItemBits );
727 
728 	// Splitwindows werden im SFX einmal angelegt und beim Einf"ugen des ersten
729 	// DockingWindows sichtbar gemacht.
730 	if ( GetItemCount( 0 ) == 1 && GetItemCount( 1 ) == 1 )
731 	{
732 		// Das Neuarrangieren am WorkWindow und ein Show() auf das SplitWindow
733 		// wird vom SfxDockingwindow veranla\st (->SfxWorkWindow::ConfigChild_Impl)
734 		if ( !bPinned && !IsFloatingMode() )
735 		{
736 			bPinned = sal_True;
737 			sal_Bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
738 			pEmptyWin->bFadeIn = sal_False;
739 			SetPinned_Impl( sal_False );
740 			pEmptyWin->Actualize();
741             DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
742 			pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, sal_True )->nVisible = CHILD_VISIBLE;
743 			pWorkWin->ArrangeChilds_Impl();
744 			if ( bFadeIn )
745 				FadeIn();
746 		}
747 		else
748 		{
749 			sal_Bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
750 			pEmptyWin->bFadeIn = sal_False;
751 			pEmptyWin->Actualize();
752 #ifdef DBG_UTIL
753             if ( !bPinned || !pEmptyWin->bFadeIn )
754             {
755                 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
756             }
757             else
758             {
759                 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering real Splitwindow" );
760             }
761 #endif
762 			pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, sal_True )->nVisible = CHILD_VISIBLE;
763 			pWorkWin->ArrangeChilds_Impl();
764 			if ( bFadeIn )
765 				FadeIn();
766 		}
767 
768 		pWorkWin->ShowChilds_Impl();
769 	}
770 
771 	if ( bUpdateMode )
772 		SetUpdateMode( sal_True );
773 	bLocked = sal_False;
774 }
775 
776 //-------------------------------------------------------------------------
777 
778 void SfxSplitWindow::RemoveWindow( SfxDockingWindow* pDockWin, sal_Bool bHide )
779 
780 /*  [Beschreibung]
781 
782 	Entfernt ein DockingWindow. Wenn es das letzte war, wird das SplitWindow
783 	gehidet.
784 */
785 {
786 	sal_uInt16 nSet = GetSet( pDockWin->GetType() );
787 
788 	// Splitwindows werden im SFX einmal angelegt und nach dem Entfernen
789 	// des letzten DockingWindows unsichtbar gemacht.
790 	if ( GetItemCount( nSet ) == 1 && GetItemCount( 0 ) == 1 )
791 	{
792 		// Das Neuarrangieren am WorkWindow wird vom SfxDockingwindow
793 		// veranla\st!
794 		Hide();
795 		pEmptyWin->aTimer.Stop();
796         sal_uInt16 nRealState = pEmptyWin->nState;
797 		FadeOut_Impl();
798 		pEmptyWin->Hide();
799 #ifdef DBG_UTIL
800         if ( !bPinned || !pEmptyWin->bFadeIn )
801         {
802             DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing empty Splitwindow" );
803         }
804         else
805         {
806             DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing real Splitwindow" );
807         }
808 #endif
809 		pWorkWin->ReleaseChild_Impl( *GetSplitWindow() );
810 		pEmptyWin->nState = nRealState;
811 		pWorkWin->ArrangeAutoHideWindows( this );
812 	}
813 
814 	SfxDock_Impl *pDock=0;
815 	sal_uInt16 nCount = pDockArr->Count();
816 	for ( sal_uInt16 n=0; n<nCount; n++ )
817 	{
818 		pDock = (*pDockArr)[n];
819 		if ( pDock->nType == pDockWin->GetType() )
820 		{
821 			pDock->pWin = 0;
822 			pDock->bHide = bHide;
823 			break;
824 		}
825 	}
826 
827 	// Fenster removen, und wenn es das letzte der Zeile war, auch die Zeile
828 	// ( Zeile = ItemSet )
829 	sal_Bool bUpdateMode = IsUpdateMode();
830 	if ( bUpdateMode )
831 		SetUpdateMode( sal_False );
832 	bLocked = sal_True;
833 
834 	RemoveItem( pDockWin->GetType() );
835 
836 	if ( nSet && !GetItemCount( nSet ) )
837 		RemoveItem( nSet );
838 
839 	if ( bUpdateMode )
840 		SetUpdateMode( sal_True );
841 	bLocked = sal_False;
842 };
843 
844 //-------------------------------------------------------------------------
845 
846 sal_Bool SfxSplitWindow::GetWindowPos( const SfxDockingWindow* pWindow,
847 										sal_uInt16& rLine, sal_uInt16& rPos ) const
848 /*  [Beschreibung]
849 
850 	Liefert die Id des Itemsets und die des Items f"ur das "ubergebene
851 	DockingWindow in der alten Zeilen/Spalten-Bezeichnung zur"uck.
852 */
853 
854 {
855 	sal_uInt16 nSet = GetSet ( pWindow->GetType() );
856 	if ( nSet == SPLITWINDOW_ITEM_NOTFOUND )
857 		return sal_False;
858 
859 	rPos  = GetItemPos( pWindow->GetType(), nSet );
860 	rLine = GetItemPos( nSet );
861 	return sal_True;
862 }
863 
864 //-------------------------------------------------------------------------
865 
866 sal_Bool SfxSplitWindow::GetWindowPos( const Point& rTestPos,
867 									  sal_uInt16& rLine, sal_uInt16& rPos ) const
868 /*  [Beschreibung]
869 
870 	Liefert die Id des Itemsets und die des Items f"ur das DockingWindow
871 	an der "ubergebenen Position in der alten Zeilen/Spalten-Bezeichnung
872 	zur"uck.
873 */
874 
875 {
876 	sal_uInt16 nId = GetItemId( rTestPos );
877 	if ( nId == 0 )
878 		return sal_False;
879 
880 	sal_uInt16 nSet = GetSet ( nId );
881 	rPos  = GetItemPos( nId, nSet );
882 	rLine = GetItemPos( nSet );
883 	return sal_True;
884 }
885 
886 //-------------------------------------------------------------------------
887 
888 sal_uInt16 SfxSplitWindow::GetLineCount() const
889 
890 /*  [Beschreibung]
891 
892 	Liefert die Zeilenzahl = Zahl der Sub-Itemsets im Root-Set.
893 */
894 {
895 	return GetItemCount( 0 );
896 }
897 
898 //-------------------------------------------------------------------------
899 
900 long SfxSplitWindow::GetLineSize( sal_uInt16 nLine ) const
901 
902 /*  [Beschreibung]
903 
904 	Liefert die "Zeilenh"ohe" des nLine-ten Itemsets.
905 */
906 {
907 	sal_uInt16 nId = GetItemId( nLine );
908 	return GetItemSize( nId );
909 }
910 
911 //-------------------------------------------------------------------------
912 
913 sal_uInt16 SfxSplitWindow::GetWindowCount( sal_uInt16 nLine ) const
914 
915 /*  [Beschreibung]
916 
917 	Liefert die
918 */
919 {
920 	sal_uInt16 nId = GetItemId( nLine );
921 	return GetItemCount( nId );
922 }
923 
924 //-------------------------------------------------------------------------
925 
926 sal_uInt16 SfxSplitWindow::GetWindowCount() const
927 
928 /*  [Beschreibung]
929 
930 	Liefert die Gesamtzahl aller Fenstert
931 */
932 {
933 	return GetItemCount( 0 );
934 }
935 
936 //-------------------------------------------------------------------------
937 
938 void SfxSplitWindow::Command( const CommandEvent& rCEvt )
939 {
940 	SplitWindow::Command( rCEvt );
941 }
942 
943 //-------------------------------------------------------------------------
944 
945 IMPL_LINK( SfxSplitWindow, TimerHdl, Timer*, pTimer)
946 {
947 	if ( pTimer )
948 		pTimer->Stop();
949 
950 	if ( CursorIsOverRect( sal_False ) || !pTimer )
951 	{
952 		// Wenn der Mauszeiger innerhalb des Fensters liegt, SplitWindow anzeigen
953 		// und Timer zum Schlie\sen aufsetzen
954 		pEmptyWin->bAutoHide = sal_True;
955 		if ( !IsVisible() )
956 			pEmptyWin->FadeIn();
957 
958 		pEmptyWin->aLastPos = GetPointerPosPixel();
959 		pEmptyWin->aTimer.Start();
960 	}
961 	else if ( pEmptyWin->bAutoHide )
962 	{
963 		if ( GetPointerPosPixel() != pEmptyWin->aLastPos )
964 		{
965 			// Die Maus wurd innerhalb der Timerlaugzeit bewegt, also erst einmal
966 			// nichts tun
967 			pEmptyWin->aLastPos = GetPointerPosPixel();
968 			pEmptyWin->aTimer.Start();
969 			return 0L;
970 		}
971 
972 		// Speziell f"ur TF_AUTOSHOW_ON_MOUSEMOVE :
973 		// Wenn das Fenster nicht sichtbar ist, gibt es nichts zu tun
974 		// (Benutzer ist einfach mit der Maus "uber pEmptyWin gefahren)
975 		if ( IsVisible() )
976 		{
977 			pEmptyWin->bEndAutoHide = sal_False;
978 			if ( !Application::IsInModalMode() &&
979 				  !PopupMenu::IsInExecute() &&
980 				  !pEmptyWin->bSplit && !HasChildPathFocus( sal_True ) )
981 			{
982 				// W"ahrend ein modaler Dialog oder ein Popupmenu offen sind
983 				// oder w"ahrend des Splittens auf keinen Fall zumachen; auch
984 				// solange eines der Children den Focus hat, bleibt das
985 				// das Fenster offen
986 				pEmptyWin->bEndAutoHide = sal_True;
987 			}
988 
989 			if ( pEmptyWin->bEndAutoHide )
990 			{
991 				// Von mir aus kann Schlu\s sein mit AutoShow
992 				// Aber vielleicht will noch ein anderes SfxSplitWindow offen bleiben,
993 				// dann bleiben auch alle anderen offen
994 				if ( !pWorkWin->IsAutoHideMode( this ) )
995 				{
996 					FadeOut_Impl();
997 					pWorkWin->ArrangeAutoHideWindows( this );
998 				}
999 				else
1000 				{
1001 					pEmptyWin->aLastPos = GetPointerPosPixel();
1002 					pEmptyWin->aTimer.Start();
1003 				}
1004 			}
1005 			else
1006 			{
1007 				pEmptyWin->aLastPos = GetPointerPosPixel();
1008 				pEmptyWin->aTimer.Start();
1009 			}
1010 		}
1011 	}
1012 
1013 	return 0L;
1014 }
1015 
1016 //-------------------------------------------------------------------------
1017 
1018 sal_Bool SfxSplitWindow::CursorIsOverRect( sal_Bool bForceAdding ) const
1019 {
1020 	sal_Bool bVisible = IsVisible();
1021 
1022 	// Auch das kollabierte SplitWindow ber"ucksichtigen
1023 	Point aPos = pEmptyWin->GetParent()->OutputToScreenPixel( pEmptyWin->GetPosPixel() );
1024 	Size aSize = pEmptyWin->GetSizePixel();
1025 
1026 	if ( bForceAdding )
1027 	{
1028 		// Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
1029 		aPos.X() -= nPixel;
1030 		aPos.Y() -= nPixel;
1031 		aSize.Width() += 2 * nPixel;
1032 		aSize.Height() += 2 * nPixel;
1033 	}
1034 
1035 	Rectangle aRect( aPos, aSize );
1036 
1037 	if ( bVisible )
1038 	{
1039 		Point aVisPos = GetPosPixel();
1040 		Size aVisSize = GetSizePixel();
1041 
1042 		// Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
1043 		aVisPos.X() -= nPixel;
1044 		aVisPos.Y() -= nPixel;
1045 		aVisSize.Width() += 2 * nPixel;
1046 		aVisSize.Height() += 2 * nPixel;
1047 
1048 		Rectangle aVisRect( aVisPos, aVisSize );
1049 		aRect = aRect.GetUnion( aVisRect );
1050 	}
1051 
1052 	if ( aRect.IsInside( OutputToScreenPixel( ((Window*)this)->GetPointerPosPixel() ) ) )
1053 		return sal_True;
1054 	return sal_False;
1055 }
1056 
1057 //-------------------------------------------------------------------------
1058 
1059 SplitWindow* SfxSplitWindow::GetSplitWindow()
1060 {
1061 	if ( !bPinned || !pEmptyWin->bFadeIn )
1062 		return pEmptyWin;
1063 	return this;
1064 }
1065 
1066 //-------------------------------------------------------------------------
1067 sal_Bool SfxSplitWindow::IsFadeIn() const
1068 {
1069 	return pEmptyWin->bFadeIn;
1070 }
1071 
1072 sal_Bool SfxSplitWindow::IsAutoHide( sal_Bool bSelf ) const
1073 {
1074 	return bSelf ? pEmptyWin->bAutoHide && !pEmptyWin->bEndAutoHide : pEmptyWin->bAutoHide;
1075 }
1076 
1077 //-------------------------------------------------------------------------
1078 
1079 void SfxSplitWindow::SetPinned_Impl( sal_Bool bOn )
1080 {
1081 	if ( bPinned == bOn )
1082 		return;
1083 
1084 	bPinned = bOn;
1085 	if ( GetItemCount( 0 ) == 0 )
1086 		return;
1087 
1088 	if ( !bOn )
1089 	{
1090 		pEmptyWin->nState |= 1;
1091 		if ( pEmptyWin->bFadeIn )
1092 		{
1093 			// Ersatzfenster anmelden
1094             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing real Splitwindow" );
1095 			pWorkWin->ReleaseChild_Impl( *this );
1096 			Hide();
1097 			pEmptyWin->Actualize();
1098             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering empty Splitwindow" );
1099 			pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1100 		}
1101 
1102 		Point aPos( GetPosPixel() );
1103 		aPos = GetParent()->OutputToScreenPixel( aPos );
1104 		SetFloatingPos( aPos );
1105 		SetFloatingMode( sal_True );
1106 		GetFloatingWindow()->SetOutputSizePixel( GetOutputSizePixel() );
1107 
1108 		if ( pEmptyWin->bFadeIn )
1109 			Show();
1110 	}
1111 	else
1112 	{
1113 		pEmptyWin->nState &= ~1;
1114 		SetOutputSizePixel( GetFloatingWindow()->GetOutputSizePixel() );
1115 		SetFloatingMode( sal_False );
1116 
1117 		if ( pEmptyWin->bFadeIn )
1118 		{
1119 			// Ersatzfenster abmelden
1120             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing empty Splitwindow" );
1121 			pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1122 			pEmptyWin->Hide();
1123             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering real Splitwindow" );
1124 			pWorkWin->RegisterChild_Impl( *this, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1125 		}
1126 	}
1127 
1128 	SetAutoHideState( !bPinned );
1129 	pEmptyWin->SetAutoHideState( !bPinned );
1130 }
1131 
1132 //-------------------------------------------------------------------------
1133 
1134 void SfxSplitWindow::SetFadeIn_Impl( sal_Bool bOn )
1135 {
1136 	if ( bOn == pEmptyWin->bFadeIn )
1137 		return;
1138 
1139 	if ( GetItemCount( 0 ) == 0 )
1140 		return;
1141 
1142 	pEmptyWin->bFadeIn = bOn;
1143 	if ( bOn )
1144 	{
1145 		pEmptyWin->nState |= 2;
1146 		if ( IsFloatingMode() )
1147 		{
1148 			// FloatingWindow ist nicht sichtbar, also anzeigen
1149 			pWorkWin->ArrangeAutoHideWindows( this );
1150 			Show();
1151 		}
1152 		else
1153 		{
1154             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing empty Splitwindow" );
1155 			pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1156 			pEmptyWin->Hide();
1157             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering real Splitwindow" );
1158 			pWorkWin->RegisterChild_Impl( *this, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1159 			pWorkWin->ArrangeChilds_Impl();
1160 			pWorkWin->ShowChilds_Impl();
1161 		}
1162 	}
1163 	else
1164 	{
1165 		pEmptyWin->bAutoHide = sal_False;
1166 		pEmptyWin->nState &= ~2;
1167 		if ( !IsFloatingMode() )
1168 		{
1169 			// Das Fenster "schwebt" nicht, soll aber ausgeblendet werden,
1170             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing real Splitwindow" );
1171 			pWorkWin->ReleaseChild_Impl( *this );
1172 			Hide();
1173 			pEmptyWin->Actualize();
1174             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering empty Splitwindow" );
1175 			pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1176 			pWorkWin->ArrangeChilds_Impl();
1177 			pWorkWin->ShowChilds_Impl();
1178 			pWorkWin->ArrangeAutoHideWindows( this );
1179 		}
1180 		else
1181 		{
1182 			Hide();
1183 			pWorkWin->ArrangeAutoHideWindows( this );
1184 		}
1185 	}
1186 }
1187 
1188 void SfxSplitWindow::AutoHide()
1189 {
1190 	// Wenn dieser Handler am "echten" SplitWindow aufgerufen wird, ist es
1191 	// entweder angedockt und soll "schwebend" angezeigt werden oder umgekehrt
1192 	if ( !bPinned )
1193 	{
1194 		// Es "schwebt", also wieder andocken
1195 		SetPinned_Impl( sal_True );
1196 		pWorkWin->ArrangeChilds_Impl();
1197 	}
1198 	else
1199 	{
1200 		// In den "Schwebezustand" bringen
1201 		SetPinned_Impl( sal_False );
1202 		pWorkWin->ArrangeChilds_Impl();
1203 		pWorkWin->ArrangeAutoHideWindows( this );
1204 	}
1205 
1206 	pWorkWin->ShowChilds_Impl();
1207 	SaveConfig_Impl();
1208 }
1209 
1210 void SfxSplitWindow::FadeOut_Impl()
1211 {
1212     if ( pEmptyWin->aTimer.IsActive() )
1213     {
1214         pEmptyWin->bAutoHide = sal_False;
1215         pEmptyWin->aTimer.Stop();
1216     }
1217 
1218 	SetFadeIn_Impl( sal_False );
1219 	Show_Impl();
1220 }
1221 
1222 void SfxSplitWindow::FadeOut()
1223 {
1224 	FadeOut_Impl();
1225 	SaveConfig_Impl();
1226 }
1227 
1228 void SfxSplitWindow::FadeIn()
1229 {
1230 	SetFadeIn_Impl( sal_True );
1231 	Show_Impl();
1232 }
1233 
1234 void SfxSplitWindow::Show_Impl()
1235 {
1236 	sal_uInt16 nCount = pDockArr->Count();
1237 	for ( sal_uInt16 n=0; n<nCount; n++ )
1238 	{
1239 		SfxDock_Impl *pDock = (*pDockArr)[n];
1240 		if ( pDock->pWin )
1241 			pDock->pWin->FadeIn( pEmptyWin->bFadeIn );
1242 	}
1243 }
1244 /*
1245 void SfxSplitWindow::Pin_Impl( sal_Bool bPin )
1246 {
1247 	if ( bPinned != bPin )
1248 		AutoHide();
1249 }
1250 */
1251 sal_Bool SfxSplitWindow::ActivateNextChild_Impl( sal_Bool bForward )
1252 {
1253 	// Wenn kein pActive, auf erstes bzw. letztes Fenster gehen ( bei !bForward wird erst in der loop dekrementiert )
1254 	sal_uInt16 nCount = pDockArr->Count();
1255 	sal_uInt16 n = bForward ? 0 : nCount;
1256 
1257 	// Wenn Focus innerhalb, dann ein Fenster vor oder zur"uck, wenn m"oglich
1258 	if ( pActive )
1259 	{
1260 		// Aktives Fenster ermitteln
1261 		for ( n=0; n<nCount; n++ )
1262 		{
1263 			SfxDock_Impl *pD = (*pDockArr)[n];
1264 			if ( pD->pWin && pD->pWin->HasChildPathFocus() )
1265 				break;
1266 		}
1267 
1268 		if ( bForward )
1269 			// ein Fenster weiter ( wenn dann n>nCount, wird die Schleife unten gar nicht durchlaufen )
1270 			n++;
1271 	}
1272 
1273 	if ( bForward )
1274 	{
1275 		// N"achstes Fenster suchen
1276 		for ( sal_uInt16 nNext=n; nNext<nCount; nNext++ )
1277 		{
1278 			SfxDock_Impl *pD = (*pDockArr)[nNext];
1279 			if ( pD->pWin )
1280 			{
1281 				pD->pWin->GrabFocus();
1282 				return sal_True;
1283 			}
1284 		}
1285 	}
1286 	else
1287 	{
1288 		// Vorheriges Fenster suchen
1289 		for ( sal_uInt16 nNext=n; nNext--; )
1290 		{
1291 			SfxDock_Impl *pD = (*pDockArr)[nNext];
1292 			if ( pD->pWin )
1293 			{
1294 				pD->pWin->GrabFocus();
1295 				return sal_True;
1296 			}
1297 		}
1298 	}
1299 
1300 	return sal_False;
1301 }
1302 
1303 void SfxSplitWindow::SetActiveWindow_Impl( SfxDockingWindow* pWin )
1304 {
1305 	pActive = pWin;
1306 	pWorkWin->SetActiveChild_Impl( this );
1307 }
1308 
1309 
1310