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