xref: /aoo42x/main/sfx2/source/dialog/splitwin.cxx (revision cdf0e10c)
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, "Falsche Paramenter!");
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 nCount = pDockArr->Count();
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 			sal_uInt16 nL=0, nP=0;
635 			GetWindowPos( pD->pWin, nL, nP );
636 
637 			if ( (nL == nLine && nP == nPos) || nL > nLine )
638 			{
639 				DBG_ASSERT( nL == nLine || bNewLine || nPos > 0, "Falsche Parameter!" );
640 				if ( nL == nLine && nPos == 0 && !bNewLine )
641 				{
642 					DBG_ASSERT(pD->bNewLine, "Keine neue Zeile?");
643 
644 					// Das Fenster wird auf nPos==0 eingeschoben
645 					pD->bNewLine = sal_False;
646 					pDock->bNewLine = sal_True;
647 				}
648 
649 				nInsertPos = n;
650 				break;
651 			}
652 		}
653 	}
654 
655 	pDockArr->Insert(pDock, nInsertPos);
656 	InsertWindow_Impl( pDock, rSize, nLine, nPos, bNewLine );
657 	SaveConfig_Impl();
658 }
659 
660 //-------------------------------------------------------------------------
661 
662 void SfxSplitWindow::InsertWindow_Impl( SfxDock_Impl* pDock,
663 						const Size& rSize,
664 						sal_uInt16 nLine, sal_uInt16 nPos, sal_Bool bNewLine)
665 
666 /*  [Beschreibung]
667 
668 	F"ugt ein DockingWindow ein und veranla\st die Neuberechnung der Gr"o\se
669 	des Splitwindows.
670 */
671 
672 {
673 	SfxDockingWindow* pDockWin = pDock->pWin;
674 
675 	sal_uInt16 nItemBits = pDockWin->GetWinBits_Impl();
676 
677 	long nWinSize, nSetSize;
678 	if ( IsHorizontal() )
679 	{
680 		nWinSize = rSize.Width();
681 		nSetSize = rSize.Height();
682 	}
683 	else
684 	{
685 		nSetSize = rSize.Width();
686 		nWinSize = rSize.Height();
687 	}
688 
689 	pDock->nSize = nWinSize;
690 
691 	sal_Bool bUpdateMode = IsUpdateMode();
692 	if ( bUpdateMode )
693 		SetUpdateMode( sal_False );
694 
695 	if ( bNewLine || nLine == GetItemCount( 0 ) )
696 	{
697 		// Es soll nicht in eine vorhandene Zeile eingef"ugt werden, sondern
698 		// eine neue erzeugt werden
699 
700 		sal_uInt16 nId = 1;
701 		for ( sal_uInt16 n=0; n<GetItemCount(0); n++ )
702 		{
703 			if ( GetItemId(n) >= nId )
704 				nId = GetItemId(n)+1;
705 		}
706 
707 		// Eine neue nLine-te Zeile erzeugen
708 		sal_uInt16 nBits = nItemBits;
709 		if ( GetAlign() == WINDOWALIGN_TOP || GetAlign() == WINDOWALIGN_BOTTOM )
710 			nBits |= SWIB_COLSET;
711 		InsertItem( nId, nSetSize, nLine, 0, nBits );
712 	}
713 
714 	// In Zeile mit Position nLine das Fenster einf"ugen
715 	// ItemWindowSize auf "Prozentual" setzen, da SV dann das Umgr"o\sern
716 	// so macht, wie man erwartet; "Pixel" macht eigentlich nur Sinn, wenn
717 	// auch Items mit prozentualen oder relativen Gr"o\sen dabei sind.
718 	nItemBits |= SWIB_PERCENTSIZE;
719 	bLocked = sal_True;
720 	sal_uInt16 nSet = GetItemId( nLine );
721 	InsertItem( pDockWin->GetType(), pDockWin, nWinSize, nPos, nSet, nItemBits );
722 
723 	// Splitwindows werden im SFX einmal angelegt und beim Einf"ugen des ersten
724 	// DockingWindows sichtbar gemacht.
725 	if ( GetItemCount( 0 ) == 1 && GetItemCount( 1 ) == 1 )
726 	{
727 		// Das Neuarrangieren am WorkWindow und ein Show() auf das SplitWindow
728 		// wird vom SfxDockingwindow veranla\st (->SfxWorkWindow::ConfigChild_Impl)
729 		if ( !bPinned && !IsFloatingMode() )
730 		{
731 			bPinned = sal_True;
732 			sal_Bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
733 			pEmptyWin->bFadeIn = sal_False;
734 			SetPinned_Impl( sal_False );
735 			pEmptyWin->Actualize();
736             DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
737 			pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, sal_True )->nVisible = CHILD_VISIBLE;
738 			pWorkWin->ArrangeChilds_Impl();
739 			if ( bFadeIn )
740 				FadeIn();
741 		}
742 		else
743 		{
744 			sal_Bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
745 			pEmptyWin->bFadeIn = sal_False;
746 			pEmptyWin->Actualize();
747 #ifdef DBG_UTIL
748             if ( !bPinned || !pEmptyWin->bFadeIn )
749             {
750                 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
751             }
752             else
753             {
754                 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering real Splitwindow" );
755             }
756 #endif
757 			pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, sal_True )->nVisible = CHILD_VISIBLE;
758 			pWorkWin->ArrangeChilds_Impl();
759 			if ( bFadeIn )
760 				FadeIn();
761 		}
762 
763 		pWorkWin->ShowChilds_Impl();
764 	}
765 
766 	if ( bUpdateMode )
767 		SetUpdateMode( sal_True );
768 	bLocked = sal_False;
769 }
770 
771 //-------------------------------------------------------------------------
772 
773 void SfxSplitWindow::RemoveWindow( SfxDockingWindow* pDockWin, sal_Bool bHide )
774 
775 /*  [Beschreibung]
776 
777 	Entfernt ein DockingWindow. Wenn es das letzte war, wird das SplitWindow
778 	gehidet.
779 */
780 {
781 	sal_uInt16 nSet = GetSet( pDockWin->GetType() );
782 
783 	// Splitwindows werden im SFX einmal angelegt und nach dem Entfernen
784 	// des letzten DockingWindows unsichtbar gemacht.
785 	if ( GetItemCount( nSet ) == 1 && GetItemCount( 0 ) == 1 )
786 	{
787 		// Das Neuarrangieren am WorkWindow wird vom SfxDockingwindow
788 		// veranla\st!
789 		Hide();
790 		pEmptyWin->aTimer.Stop();
791         sal_uInt16 nRealState = pEmptyWin->nState;
792 		FadeOut_Impl();
793 		pEmptyWin->Hide();
794 #ifdef DBG_UTIL
795         if ( !bPinned || !pEmptyWin->bFadeIn )
796         {
797             DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing empty Splitwindow" );
798         }
799         else
800         {
801             DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing real Splitwindow" );
802         }
803 #endif
804 		pWorkWin->ReleaseChild_Impl( *GetSplitWindow() );
805 		pEmptyWin->nState = nRealState;
806 		pWorkWin->ArrangeAutoHideWindows( this );
807 	}
808 
809 	SfxDock_Impl *pDock=0;
810 	sal_uInt16 nCount = pDockArr->Count();
811 	for ( sal_uInt16 n=0; n<nCount; n++ )
812 	{
813 		pDock = (*pDockArr)[n];
814 		if ( pDock->nType == pDockWin->GetType() )
815 		{
816 			pDock->pWin = 0;
817 			pDock->bHide = bHide;
818 			break;
819 		}
820 	}
821 
822 	// Fenster removen, und wenn es das letzte der Zeile war, auch die Zeile
823 	// ( Zeile = ItemSet )
824 	sal_Bool bUpdateMode = IsUpdateMode();
825 	if ( bUpdateMode )
826 		SetUpdateMode( sal_False );
827 	bLocked = sal_True;
828 
829 	RemoveItem( pDockWin->GetType() );
830 
831 	if ( nSet && !GetItemCount( nSet ) )
832 		RemoveItem( nSet );
833 
834 	if ( bUpdateMode )
835 		SetUpdateMode( sal_True );
836 	bLocked = sal_False;
837 };
838 
839 //-------------------------------------------------------------------------
840 
841 sal_Bool SfxSplitWindow::GetWindowPos( const SfxDockingWindow* pWindow,
842 										sal_uInt16& rLine, sal_uInt16& rPos ) const
843 /*  [Beschreibung]
844 
845 	Liefert die Id des Itemsets und die des Items f"ur das "ubergebene
846 	DockingWindow in der alten Zeilen/Spalten-Bezeichnung zur"uck.
847 */
848 
849 {
850 	sal_uInt16 nSet = GetSet ( pWindow->GetType() );
851 	if ( nSet == SPLITWINDOW_ITEM_NOTFOUND )
852 		return sal_False;
853 
854 	rPos  = GetItemPos( pWindow->GetType(), nSet );
855 	rLine = GetItemPos( nSet );
856 	return sal_True;
857 }
858 
859 //-------------------------------------------------------------------------
860 
861 sal_Bool SfxSplitWindow::GetWindowPos( const Point& rTestPos,
862 									  sal_uInt16& rLine, sal_uInt16& rPos ) const
863 /*  [Beschreibung]
864 
865 	Liefert die Id des Itemsets und die des Items f"ur das DockingWindow
866 	an der "ubergebenen Position in der alten Zeilen/Spalten-Bezeichnung
867 	zur"uck.
868 */
869 
870 {
871 	sal_uInt16 nId = GetItemId( rTestPos );
872 	if ( nId == 0 )
873 		return sal_False;
874 
875 	sal_uInt16 nSet = GetSet ( nId );
876 	rPos  = GetItemPos( nId, nSet );
877 	rLine = GetItemPos( nSet );
878 	return sal_True;
879 }
880 
881 //-------------------------------------------------------------------------
882 
883 sal_uInt16 SfxSplitWindow::GetLineCount() const
884 
885 /*  [Beschreibung]
886 
887 	Liefert die Zeilenzahl = Zahl der Sub-Itemsets im Root-Set.
888 */
889 {
890 	return GetItemCount( 0 );
891 }
892 
893 //-------------------------------------------------------------------------
894 
895 long SfxSplitWindow::GetLineSize( sal_uInt16 nLine ) const
896 
897 /*  [Beschreibung]
898 
899 	Liefert die "Zeilenh"ohe" des nLine-ten Itemsets.
900 */
901 {
902 	sal_uInt16 nId = GetItemId( nLine );
903 	return GetItemSize( nId );
904 }
905 
906 //-------------------------------------------------------------------------
907 
908 sal_uInt16 SfxSplitWindow::GetWindowCount( sal_uInt16 nLine ) const
909 
910 /*  [Beschreibung]
911 
912 	Liefert die
913 */
914 {
915 	sal_uInt16 nId = GetItemId( nLine );
916 	return GetItemCount( nId );
917 }
918 
919 //-------------------------------------------------------------------------
920 
921 sal_uInt16 SfxSplitWindow::GetWindowCount() const
922 
923 /*  [Beschreibung]
924 
925 	Liefert die Gesamtzahl aller Fenstert
926 */
927 {
928 	return GetItemCount( 0 );
929 }
930 
931 //-------------------------------------------------------------------------
932 
933 void SfxSplitWindow::Command( const CommandEvent& rCEvt )
934 {
935 	SplitWindow::Command( rCEvt );
936 }
937 
938 //-------------------------------------------------------------------------
939 
940 IMPL_LINK( SfxSplitWindow, TimerHdl, Timer*, pTimer)
941 {
942 	if ( pTimer )
943 		pTimer->Stop();
944 
945 	if ( CursorIsOverRect( sal_False ) || !pTimer )
946 	{
947 		// Wenn der Mauszeiger innerhalb des Fensters liegt, SplitWindow anzeigen
948 		// und Timer zum Schlie\sen aufsetzen
949 		pEmptyWin->bAutoHide = sal_True;
950 		if ( !IsVisible() )
951 			pEmptyWin->FadeIn();
952 
953 		pEmptyWin->aLastPos = GetPointerPosPixel();
954 		pEmptyWin->aTimer.Start();
955 	}
956 	else if ( pEmptyWin->bAutoHide )
957 	{
958 		if ( GetPointerPosPixel() != pEmptyWin->aLastPos )
959 		{
960 			// Die Maus wurd innerhalb der Timerlaugzeit bewegt, also erst einmal
961 			// nichts tun
962 			pEmptyWin->aLastPos = GetPointerPosPixel();
963 			pEmptyWin->aTimer.Start();
964 			return 0L;
965 		}
966 
967 		// Speziell f"ur TF_AUTOSHOW_ON_MOUSEMOVE :
968 		// Wenn das Fenster nicht sichtbar ist, gibt es nichts zu tun
969 		// (Benutzer ist einfach mit der Maus "uber pEmptyWin gefahren)
970 		if ( IsVisible() )
971 		{
972 			pEmptyWin->bEndAutoHide = sal_False;
973 			if ( !Application::IsInModalMode() &&
974 				  !PopupMenu::IsInExecute() &&
975 				  !pEmptyWin->bSplit && !HasChildPathFocus( sal_True ) )
976 			{
977 				// W"ahrend ein modaler Dialog oder ein Popupmenu offen sind
978 				// oder w"ahrend des Splittens auf keinen Fall zumachen; auch
979 				// solange eines der Children den Focus hat, bleibt das
980 				// das Fenster offen
981 				pEmptyWin->bEndAutoHide = sal_True;
982 			}
983 
984 			if ( pEmptyWin->bEndAutoHide )
985 			{
986 				// Von mir aus kann Schlu\s sein mit AutoShow
987 				// Aber vielleicht will noch ein anderes SfxSplitWindow offen bleiben,
988 				// dann bleiben auch alle anderen offen
989 				if ( !pWorkWin->IsAutoHideMode( this ) )
990 				{
991 					FadeOut_Impl();
992 					pWorkWin->ArrangeAutoHideWindows( this );
993 				}
994 				else
995 				{
996 					pEmptyWin->aLastPos = GetPointerPosPixel();
997 					pEmptyWin->aTimer.Start();
998 				}
999 			}
1000 			else
1001 			{
1002 				pEmptyWin->aLastPos = GetPointerPosPixel();
1003 				pEmptyWin->aTimer.Start();
1004 			}
1005 		}
1006 	}
1007 
1008 	return 0L;
1009 }
1010 
1011 //-------------------------------------------------------------------------
1012 
1013 sal_Bool SfxSplitWindow::CursorIsOverRect( sal_Bool bForceAdding ) const
1014 {
1015 	sal_Bool bVisible = IsVisible();
1016 
1017 	// Auch das kollabierte SplitWindow ber"ucksichtigen
1018 	Point aPos = pEmptyWin->GetParent()->OutputToScreenPixel( pEmptyWin->GetPosPixel() );
1019 	Size aSize = pEmptyWin->GetSizePixel();
1020 
1021 	if ( bForceAdding )
1022 	{
1023 		// Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
1024 		aPos.X() -= nPixel;
1025 		aPos.Y() -= nPixel;
1026 		aSize.Width() += 2 * nPixel;
1027 		aSize.Height() += 2 * nPixel;
1028 	}
1029 
1030 	Rectangle aRect( aPos, aSize );
1031 
1032 	if ( bVisible )
1033 	{
1034 		Point aVisPos = GetPosPixel();
1035 		Size aVisSize = GetSizePixel();
1036 
1037 		// Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
1038 		aVisPos.X() -= nPixel;
1039 		aVisPos.Y() -= nPixel;
1040 		aVisSize.Width() += 2 * nPixel;
1041 		aVisSize.Height() += 2 * nPixel;
1042 
1043 		Rectangle aVisRect( aVisPos, aVisSize );
1044 		aRect = aRect.GetUnion( aVisRect );
1045 	}
1046 
1047 	if ( aRect.IsInside( OutputToScreenPixel( ((Window*)this)->GetPointerPosPixel() ) ) )
1048 		return sal_True;
1049 	return sal_False;
1050 }
1051 
1052 //-------------------------------------------------------------------------
1053 
1054 SplitWindow* SfxSplitWindow::GetSplitWindow()
1055 {
1056 	if ( !bPinned || !pEmptyWin->bFadeIn )
1057 		return pEmptyWin;
1058 	return this;
1059 }
1060 
1061 //-------------------------------------------------------------------------
1062 sal_Bool SfxSplitWindow::IsFadeIn() const
1063 {
1064 	return pEmptyWin->bFadeIn;
1065 }
1066 
1067 sal_Bool SfxSplitWindow::IsAutoHide( sal_Bool bSelf ) const
1068 {
1069 	return bSelf ? pEmptyWin->bAutoHide && !pEmptyWin->bEndAutoHide : pEmptyWin->bAutoHide;
1070 }
1071 
1072 //-------------------------------------------------------------------------
1073 
1074 void SfxSplitWindow::SetPinned_Impl( sal_Bool bOn )
1075 {
1076 	if ( bPinned == bOn )
1077 		return;
1078 
1079 	bPinned = bOn;
1080 	if ( GetItemCount( 0 ) == 0 )
1081 		return;
1082 
1083 	if ( !bOn )
1084 	{
1085 		pEmptyWin->nState |= 1;
1086 		if ( pEmptyWin->bFadeIn )
1087 		{
1088 			// Ersatzfenster anmelden
1089             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing real Splitwindow" );
1090 			pWorkWin->ReleaseChild_Impl( *this );
1091 			Hide();
1092 			pEmptyWin->Actualize();
1093             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering empty Splitwindow" );
1094 			pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1095 		}
1096 
1097 		Point aPos( GetPosPixel() );
1098 		aPos = GetParent()->OutputToScreenPixel( aPos );
1099 		SetFloatingPos( aPos );
1100 		SetFloatingMode( sal_True );
1101 		GetFloatingWindow()->SetOutputSizePixel( GetOutputSizePixel() );
1102 
1103 		if ( pEmptyWin->bFadeIn )
1104 			Show();
1105 	}
1106 	else
1107 	{
1108 		pEmptyWin->nState &= ~1;
1109 		SetOutputSizePixel( GetFloatingWindow()->GetOutputSizePixel() );
1110 		SetFloatingMode( sal_False );
1111 
1112 		if ( pEmptyWin->bFadeIn )
1113 		{
1114 			// Ersatzfenster abmelden
1115             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing empty Splitwindow" );
1116 			pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1117 			pEmptyWin->Hide();
1118             DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering real Splitwindow" );
1119 			pWorkWin->RegisterChild_Impl( *this, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1120 		}
1121 	}
1122 
1123 	SetAutoHideState( !bPinned );
1124 	pEmptyWin->SetAutoHideState( !bPinned );
1125 }
1126 
1127 //-------------------------------------------------------------------------
1128 
1129 void SfxSplitWindow::SetFadeIn_Impl( sal_Bool bOn )
1130 {
1131 	if ( bOn == pEmptyWin->bFadeIn )
1132 		return;
1133 
1134 	if ( GetItemCount( 0 ) == 0 )
1135 		return;
1136 
1137 	pEmptyWin->bFadeIn = bOn;
1138 	if ( bOn )
1139 	{
1140 		pEmptyWin->nState |= 2;
1141 		if ( IsFloatingMode() )
1142 		{
1143 			// FloatingWindow ist nicht sichtbar, also anzeigen
1144 			pWorkWin->ArrangeAutoHideWindows( this );
1145 			Show();
1146 		}
1147 		else
1148 		{
1149             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing empty Splitwindow" );
1150 			pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1151 			pEmptyWin->Hide();
1152             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering real Splitwindow" );
1153 			pWorkWin->RegisterChild_Impl( *this, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1154 			pWorkWin->ArrangeChilds_Impl();
1155 			pWorkWin->ShowChilds_Impl();
1156 		}
1157 	}
1158 	else
1159 	{
1160 		pEmptyWin->bAutoHide = sal_False;
1161 		pEmptyWin->nState &= ~2;
1162 		if ( !IsFloatingMode() )
1163 		{
1164 			// Das Fenster "schwebt" nicht, soll aber ausgeblendet werden,
1165             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing real Splitwindow" );
1166 			pWorkWin->ReleaseChild_Impl( *this );
1167 			Hide();
1168 			pEmptyWin->Actualize();
1169             DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering empty Splitwindow" );
1170 			pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
1171 			pWorkWin->ArrangeChilds_Impl();
1172 			pWorkWin->ShowChilds_Impl();
1173 			pWorkWin->ArrangeAutoHideWindows( this );
1174 		}
1175 		else
1176 		{
1177 			Hide();
1178 			pWorkWin->ArrangeAutoHideWindows( this );
1179 		}
1180 	}
1181 }
1182 
1183 void SfxSplitWindow::AutoHide()
1184 {
1185 	// Wenn dieser Handler am "echten" SplitWindow aufgerufen wird, ist es
1186 	// entweder angedockt und soll "schwebend" angezeigt werden oder umgekehrt
1187 	if ( !bPinned )
1188 	{
1189 		// Es "schwebt", also wieder andocken
1190 		SetPinned_Impl( sal_True );
1191 		pWorkWin->ArrangeChilds_Impl();
1192 	}
1193 	else
1194 	{
1195 		// In den "Schwebezustand" bringen
1196 		SetPinned_Impl( sal_False );
1197 		pWorkWin->ArrangeChilds_Impl();
1198 		pWorkWin->ArrangeAutoHideWindows( this );
1199 	}
1200 
1201 	pWorkWin->ShowChilds_Impl();
1202 	SaveConfig_Impl();
1203 }
1204 
1205 void SfxSplitWindow::FadeOut_Impl()
1206 {
1207     if ( pEmptyWin->aTimer.IsActive() )
1208     {
1209         pEmptyWin->bAutoHide = sal_False;
1210         pEmptyWin->aTimer.Stop();
1211     }
1212 
1213 	SetFadeIn_Impl( sal_False );
1214 	Show_Impl();
1215 }
1216 
1217 void SfxSplitWindow::FadeOut()
1218 {
1219 	FadeOut_Impl();
1220 	SaveConfig_Impl();
1221 }
1222 
1223 void SfxSplitWindow::FadeIn()
1224 {
1225 	SetFadeIn_Impl( sal_True );
1226 	Show_Impl();
1227 }
1228 
1229 void SfxSplitWindow::Show_Impl()
1230 {
1231 	sal_uInt16 nCount = pDockArr->Count();
1232 	for ( sal_uInt16 n=0; n<nCount; n++ )
1233 	{
1234 		SfxDock_Impl *pDock = (*pDockArr)[n];
1235 		if ( pDock->pWin )
1236 			pDock->pWin->FadeIn( pEmptyWin->bFadeIn );
1237 	}
1238 }
1239 /*
1240 void SfxSplitWindow::Pin_Impl( sal_Bool bPin )
1241 {
1242 	if ( bPinned != bPin )
1243 		AutoHide();
1244 }
1245 */
1246 sal_Bool SfxSplitWindow::ActivateNextChild_Impl( sal_Bool bForward )
1247 {
1248 	// Wenn kein pActive, auf erstes bzw. letztes Fenster gehen ( bei !bForward wird erst in der loop dekrementiert )
1249 	sal_uInt16 nCount = pDockArr->Count();
1250 	sal_uInt16 n = bForward ? 0 : nCount;
1251 
1252 	// Wenn Focus innerhalb, dann ein Fenster vor oder zur"uck, wenn m"oglich
1253 	if ( pActive )
1254 	{
1255 		// Aktives Fenster ermitteln
1256 		for ( n=0; n<nCount; n++ )
1257 		{
1258 			SfxDock_Impl *pD = (*pDockArr)[n];
1259 			if ( pD->pWin && pD->pWin->HasChildPathFocus() )
1260 				break;
1261 		}
1262 
1263 		if ( bForward )
1264 			// ein Fenster weiter ( wenn dann n>nCount, wird die Schleife unten gar nicht durchlaufen )
1265 			n++;
1266 	}
1267 
1268 	if ( bForward )
1269 	{
1270 		// N"achstes Fenster suchen
1271 		for ( sal_uInt16 nNext=n; nNext<nCount; nNext++ )
1272 		{
1273 			SfxDock_Impl *pD = (*pDockArr)[nNext];
1274 			if ( pD->pWin )
1275 			{
1276 				pD->pWin->GrabFocus();
1277 				return sal_True;
1278 			}
1279 		}
1280 	}
1281 	else
1282 	{
1283 		// Vorheriges Fenster suchen
1284 		for ( sal_uInt16 nNext=n; nNext--; )
1285 		{
1286 			SfxDock_Impl *pD = (*pDockArr)[nNext];
1287 			if ( pD->pWin )
1288 			{
1289 				pD->pWin->GrabFocus();
1290 				return sal_True;
1291 			}
1292 		}
1293 	}
1294 
1295 	return sal_False;
1296 }
1297 
1298 void SfxSplitWindow::SetActiveWindow_Impl( SfxDockingWindow* pWin )
1299 {
1300 	pActive = pWin;
1301 	pWorkWin->SetActiveChild_Impl( this );
1302 }
1303 
1304 
1305