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