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