Update ooo320-m1
[ooovba.git] / sfx2 / source / dialog / splitwin.cxx
blobe35859a946a656f99c518bdc732ae878a3394ddc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: splitwin.cxx,v $
10 * $Revision: 1.20 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #ifdef SOLARIS
35 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
36 #include <ctime>
37 #endif
39 #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
41 #ifndef _WRKWIN_HXX //autogen
42 #include <vcl/wrkwin.hxx>
43 #endif
44 #include <svtools/viewoptions.hxx>
45 #ifndef GCC
46 #endif
48 #include <vcl/timer.hxx>
50 #include "splitwin.hxx"
51 #include "workwin.hxx"
52 #include <sfx2/dockwin.hxx>
53 #include <sfx2/app.hxx>
54 #include "dialog.hrc"
55 #include "sfxresid.hxx"
56 #include <sfx2/mnumgr.hxx>
57 #include "virtmenu.hxx"
58 #include <sfx2/msgpool.hxx>
59 #include <sfx2/viewfrm.hxx>
61 using namespace ::com::sun::star::uno;
62 using namespace ::rtl;
64 #define VERSION 1
65 #define nPixel 30L
66 #define USERITEM_NAME OUString::createFromAscii( "UserItem" )
68 struct SfxDock_Impl
70 USHORT nType;
71 SfxDockingWindow* pWin; // SplitWindow hat dieses Fenster
72 BOOL bNewLine;
73 BOOL bHide; // SplitWindow hatte dieses Fenster
74 long nSize;
77 typedef SfxDock_Impl* SfxDockPtr;
78 SV_DECL_PTRARR_DEL( SfxDockArr_Impl, SfxDockPtr, 4, 4)
79 SV_IMPL_PTRARR( SfxDockArr_Impl, SfxDockPtr);
81 class SfxEmptySplitWin_Impl : public SplitWindow
83 /* [Beschreibung]
85 Das SfxEmptySplitWin_Impldow ist ein leeres SplitWindow, das das SfxSplitWindow
86 im AutoHide-Modus ersetzt. Es dient nur als Platzhalter, um MouseMoves
87 zu empfangen und ggf. das eigentlichte SplitWindow einzublenden
89 friend class SfxSplitWindow;
91 SfxSplitWindow* pOwner;
92 BOOL bFadeIn;
93 BOOL bAutoHide;
94 BOOL bSplit;
95 BOOL bEndAutoHide;
96 Timer aTimer;
97 Point aLastPos;
98 USHORT nState;
100 SfxEmptySplitWin_Impl( SfxSplitWindow *pParent )
101 : SplitWindow( pParent->GetParent(), WinBits( WB_BORDER | WB_3DLOOK ) )
102 , pOwner( pParent )
103 , bFadeIn( FALSE )
104 , bAutoHide( FALSE )
105 , bSplit( FALSE )
106 , bEndAutoHide( FALSE )
107 , nState( 1 )
109 aTimer.SetTimeoutHdl(
110 LINK(pOwner, SfxSplitWindow, TimerHdl ) );
111 aTimer.SetTimeout( 200 );
112 // EnableDrop( TRUE );
113 SetAlign( pOwner->GetAlign() );
114 Actualize();
115 ShowAutoHideButton( pOwner->IsAutoHideButtonVisible() );
116 ShowFadeInHideButton( TRUE );
119 ~SfxEmptySplitWin_Impl()
121 aTimer.Stop();
124 virtual void MouseMove( const MouseEvent& );
125 virtual void AutoHide();
126 virtual void FadeIn();
127 void Actualize();
130 void SfxEmptySplitWin_Impl::Actualize()
132 Size aSize( pOwner->GetSizePixel() );
133 switch ( pOwner->GetAlign() )
135 case WINDOWALIGN_LEFT:
136 case WINDOWALIGN_RIGHT:
137 aSize.Width() = GetFadeInSize();
138 break;
139 case WINDOWALIGN_TOP:
140 case WINDOWALIGN_BOTTOM:
141 aSize.Height() = GetFadeInSize();
142 break;
145 SetSizePixel( aSize );
148 void SfxEmptySplitWin_Impl::AutoHide()
150 pOwner->SetPinned_Impl( !pOwner->bPinned );
151 pOwner->SaveConfig_Impl();
152 bAutoHide = TRUE;
153 FadeIn();
156 void SfxEmptySplitWin_Impl::FadeIn()
158 if (!bAutoHide )
159 bAutoHide = IsFadeNoButtonMode();
160 pOwner->SetFadeIn_Impl( TRUE );
161 pOwner->Show_Impl();
162 if ( bAutoHide )
164 // Timer zum Schlie\sen aufsetzen; der Aufrufer mu\s selbst sicherstellen,
165 // da\s das Window nicht gleich wieder zu geht ( z.B. durch Setzen des
166 // Focus oder einen modal mode )
167 aLastPos = GetPointerPosPixel();
168 aTimer.Start();
170 else
171 pOwner->SaveConfig_Impl();
174 //-------------------------------------------------------------------------
176 void SfxSplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
178 if ( rMEvt.GetClicks() != 2 )
179 SplitWindow::MouseButtonDown( rMEvt );
182 void SfxEmptySplitWin_Impl::MouseMove( const MouseEvent& rMEvt )
184 SplitWindow::MouseMove( rMEvt );
187 //-------------------------------------------------------------------------
189 SfxSplitWindow::SfxSplitWindow( Window* pParent, SfxChildAlignment eAl,
190 SfxWorkWindow *pW, BOOL bWithButtons, WinBits nBits )
192 /* [Beschreibung]
194 Ein SfxSplitWindow verbirgt die rekursive Struktur des SV-Splitwindows
195 nach au\sen, indem es einen tabellenartigen Aufbau mit Zeilen und Spalten
196 ( also maximale Rekursionstiefe 2 ) simuliert.
197 Au\erdem sichert es die Persistenz der Anordnung der SfxDockingWindows.
200 : SplitWindow ( pParent, nBits | WB_HIDE ),
201 eAlign(eAl),
202 pWorkWin(pW),
203 pDockArr( new SfxDockArr_Impl ),
204 bLocked(FALSE),
205 bPinned(TRUE),
206 pEmptyWin(NULL),
207 pActive(NULL)
209 if ( bWithButtons )
211 ShowAutoHideButton( FALSE ); // no autohide button (pin) anymore
212 ShowFadeOutButton( TRUE );
215 // SV-Alignment setzen
216 WindowAlign eTbxAlign;
217 switch ( eAlign )
219 case SFX_ALIGN_LEFT:
220 eTbxAlign = WINDOWALIGN_LEFT;
221 break;
222 case SFX_ALIGN_RIGHT:
223 eTbxAlign = WINDOWALIGN_RIGHT;
224 break;
225 case SFX_ALIGN_TOP:
226 eTbxAlign = WINDOWALIGN_TOP;
227 break;
228 case SFX_ALIGN_BOTTOM:
229 eTbxAlign = WINDOWALIGN_BOTTOM;
230 bPinned = TRUE;
231 break;
232 default:
233 eTbxAlign = WINDOWALIGN_TOP; // some sort of default...
234 break; // -Wall lots not handled..
237 SetAlign (eTbxAlign);
238 pEmptyWin = new SfxEmptySplitWin_Impl( this );
239 if ( bPinned )
241 pEmptyWin->bFadeIn = TRUE;
242 pEmptyWin->nState = 2;
245 if ( bWithButtons )
247 // Konfiguration einlesen
248 String aWindowId = String::CreateFromAscii("SplitWindow");
249 aWindowId += String::CreateFromInt32( (sal_Int32) eTbxAlign );
250 SvtViewOptions aWinOpt( E_WINDOW, aWindowId );
251 String aWinData;
252 Any aUserItem = aWinOpt.GetUserItem( USERITEM_NAME );
253 OUString aTemp;
254 if ( aUserItem >>= aTemp )
255 aWinData = String( aTemp );
256 if ( aWinData.Len() && aWinData.GetChar( (USHORT) 0 ) == 'V' )
258 pEmptyWin->nState = (USHORT) aWinData.GetToken( 1, ',' ).ToInt32();
259 if ( pEmptyWin->nState & 2 )
260 pEmptyWin->bFadeIn = TRUE;
261 //bPinned = !( pEmptyWin->nState & 1 );
262 bPinned = TRUE; // always assume pinned - floating mode not used anymore
264 USHORT i=2;
265 USHORT nCount = (USHORT) aWinData.GetToken(i++, ',').ToInt32();
266 for ( USHORT n=0; n<nCount; n++ )
268 SfxDock_Impl *pDock = new SfxDock_Impl;
269 pDock->pWin = 0;
270 pDock->bNewLine = FALSE;
271 pDock->bHide = TRUE;
272 pDock->nType = (USHORT) aWinData.GetToken(i++, ',').ToInt32();
273 if ( !pDock->nType )
275 // K"onnte NewLine bedeuten
276 pDock->nType = (USHORT) aWinData.GetToken(i++, ',').ToInt32();
277 if ( !pDock->nType )
279 // Lesefehler
280 delete pDock;
281 break;
283 else
284 pDock->bNewLine = TRUE;
287 pDockArr->Insert(pDock,n);
291 else
293 bPinned = TRUE;
294 pEmptyWin->bFadeIn = TRUE;
295 pEmptyWin->nState = 2;
298 SetAutoHideState( !bPinned );
299 pEmptyWin->SetAutoHideState( !bPinned );
302 //-------------------------------------------------------------------------
304 SfxSplitWindow::~SfxSplitWindow()
306 if ( !pWorkWin->GetParent_Impl() )
307 SaveConfig_Impl();
309 if ( pEmptyWin )
311 // pOwner auf NULL setzen, sonst versucht pEmptyWin, nochmal zu
312 // l"oschen; es wird n"amlich von au\sen immer das Fenster deleted,
313 // das gerade angedockt ist
314 pEmptyWin->pOwner = NULL;
315 delete pEmptyWin;
318 delete pDockArr;
321 void SfxSplitWindow::SaveConfig_Impl()
323 // Konfiguration abspeichern
324 String aWinData('V');
325 aWinData += String::CreateFromInt32( VERSION );
326 aWinData += ',';
327 aWinData += String::CreateFromInt32( pEmptyWin->nState );
328 aWinData += ',';
330 USHORT nCount = 0;
331 USHORT n;
332 for ( n=0; n<pDockArr->Count(); n++ )
334 SfxDock_Impl *pDock = (*pDockArr)[n];
335 if ( pDock->bHide || pDock->pWin )
336 nCount++;
339 aWinData += String::CreateFromInt32( nCount );
341 for ( n=0; n<pDockArr->Count(); n++ )
343 SfxDock_Impl *pDock = (*pDockArr)[n];
344 if ( !pDock->bHide && !pDock->pWin )
345 continue;
346 if ( pDock->bNewLine )
347 aWinData += DEFINE_CONST_UNICODE(",0");
348 aWinData += ',';
349 aWinData += String::CreateFromInt32( pDock->nType);
352 String aWindowId = String::CreateFromAscii("SplitWindow");
353 aWindowId += String::CreateFromInt32( (sal_Int32) GetAlign() );
354 SvtViewOptions aWinOpt( E_WINDOW, aWindowId );
355 aWinOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aWinData ) ) );
358 //-------------------------------------------------------------------------
360 void SfxSplitWindow::StartSplit()
362 long nSize = 0;
363 Size aSize = GetSizePixel();
365 if ( pEmptyWin )
367 pEmptyWin->bFadeIn = TRUE;
368 pEmptyWin->bSplit = TRUE;
371 Rectangle aRect = pWorkWin->GetFreeArea( !bPinned );
372 switch ( GetAlign() )
374 case WINDOWALIGN_LEFT:
375 case WINDOWALIGN_RIGHT:
376 nSize = aSize.Width() + aRect.GetWidth();
377 break;
378 case WINDOWALIGN_TOP:
379 case WINDOWALIGN_BOTTOM:
380 nSize = aSize.Height() + aRect.GetHeight();
381 break;
384 SetMaxSizePixel( nSize );
387 //-------------------------------------------------------------------------
389 void SfxSplitWindow::SplitResize()
391 if ( bPinned )
393 pWorkWin->ArrangeChilds_Impl();
394 pWorkWin->ShowChilds_Impl();
396 else
397 pWorkWin->ArrangeAutoHideWindows( this );
400 //-------------------------------------------------------------------------
402 void SfxSplitWindow::Split()
404 if ( pEmptyWin )
405 pEmptyWin->bSplit = FALSE;
407 SplitWindow::Split();
409 USHORT nCount = pDockArr->Count();
410 for ( USHORT n=0; n<nCount; n++ )
412 SfxDock_Impl *pD = (*pDockArr)[n];
413 if ( pD->pWin )
415 USHORT nId = pD->nType;
416 long nSize = GetItemSize( nId, SWIB_FIXED );
417 long nSetSize = GetItemSize( GetSet( nId ) );
418 Size aSize;
420 if ( IsHorizontal() )
422 aSize.Width() = nSize;
423 aSize.Height() = nSetSize;
425 else
427 aSize.Width() = nSetSize;
428 aSize.Height() = nSize;
431 pD->pWin->SetItemSize_Impl( aSize );
435 SaveConfig_Impl();
438 //-------------------------------------------------------------------------
440 void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize)
442 /* [Beschreibung]
444 Zum Einf"ugen von SfxDockingWindows kann auch keine Position "ubergeben
445 werden. Das SfxSplitWindow sucht dann die zuletzt gemerkte zu dem
446 "ubergebenen SfxDockingWindow heraus oder h"angt es als letztes neu an.
450 short nLine = -1; // damit erstes Fenster nLine auf 0 hochsetzen kann
451 USHORT nL;
452 USHORT nPos = 0;
453 BOOL bNewLine = TRUE;
454 BOOL bSaveConfig = FALSE;
455 SfxDock_Impl *pFoundDock=0;
456 USHORT nCount = pDockArr->Count();
457 for ( USHORT n=0; n<nCount; n++ )
459 SfxDock_Impl *pDock = (*pDockArr)[n];
460 if ( pDock->bNewLine )
462 // Das Fenster er"offnet eine neue Zeile
463 if ( pFoundDock )
464 // Aber hinter dem gerade eingef"ugten Fenster
465 break;
467 // Neue Zeile
468 nPos = 0;
469 bNewLine = TRUE;
472 if ( pDock->pWin )
474 // Es gibt an dieser Stelle gerade ein Fenster
475 if ( bNewLine && !pFoundDock )
477 // Bisher ist nicht bekannt, in welcher realen Zeile es liegt
478 GetWindowPos( pDock->pWin, nL, nPos );
479 nLine = (short) nL;
482 if ( !pFoundDock )
484 // Fenster liegt vor dem eingef"ugten
485 nPos++;
488 // Zeile ist schon er"offnet
489 bNewLine = FALSE;
490 if ( pFoundDock )
491 break;
494 if ( pDock->nType == pDockWin->GetType() )
496 DBG_ASSERT( !pFoundDock && !pDock->pWin, "Fenster ist schon vorhanden!");
497 pFoundDock = pDock;
498 if ( !bNewLine )
499 break;
500 else
502 // Es wurde zuletzt eine neue Reihe gestartet, aber noch kein
503 // darin liegendes Fenster gefunden; daher weitersuchen, ob noch
504 // ein Fenster in dieser Zeile folgt, um bNewLine korrekt zu setzen.
505 // Dabei darf aber nLine oder nPos nicht mehr ver"andert werden!
506 nLine++;
511 if ( !pFoundDock )
513 // Nicht gefunden, am Ende einf"ugen
514 pFoundDock = new SfxDock_Impl;
515 pFoundDock->bHide = TRUE;
516 pDockArr->Insert( pFoundDock, nCount );
517 pFoundDock->nType = pDockWin->GetType();
518 nLine++;
519 nPos = 0;
520 bNewLine = TRUE;
521 pFoundDock->bNewLine = bNewLine;
522 bSaveConfig = TRUE;
525 pFoundDock->pWin = pDockWin;
526 pFoundDock->bHide = FALSE;
527 InsertWindow_Impl( pFoundDock, rSize, nLine, nPos, bNewLine );
528 if ( bSaveConfig )
529 SaveConfig_Impl();
532 //-------------------------------------------------------------------------
534 void SfxSplitWindow::ReleaseWindow_Impl(SfxDockingWindow *pDockWin, BOOL bSave)
536 /* [Beschreibung]
538 Das DockingWindow wird nicht mehr in den internen Daten gespeichert.
542 SfxDock_Impl *pDock=0;
543 USHORT nCount = pDockArr->Count();
544 BOOL bFound = FALSE;
545 for ( USHORT n=0; n<nCount; n++ )
547 pDock = (*pDockArr)[n];
548 if ( pDock->nType == pDockWin->GetType() )
550 if ( pDock->bNewLine && n<nCount-1 )
551 (*pDockArr)[n+1]->bNewLine = TRUE;
553 // Fenster hat schon eine Position, die vergessen wir
554 bFound = TRUE;
555 pDockArr->Remove(n);
556 break;
560 if ( bFound )
561 delete pDock;
563 if ( bSave )
564 SaveConfig_Impl();
567 //-------------------------------------------------------------------------
569 void SfxSplitWindow::MoveWindow( SfxDockingWindow* pDockWin, const Size& rSize,
570 USHORT nLine, USHORT nPos, BOOL bNewLine)
572 /* [Beschreibung]
574 Das DockingWindow wird innerhalb des Splitwindows verschoben.
579 USHORT nL, nP;
580 GetWindowPos( pDockWin, nL, nP );
582 if ( nLine > nL && GetItemCount( GetItemId( nL, 0 ) ) == 1 )
584 // Wenn das letzte Fenster aus seiner Zeile entfernt wird, rutscht
585 // alles eine Zeile nach vorne!
586 nLine--;
589 else if ( nLine == nL && nPos > nP )
591 nPos--;
594 RemoveWindow( pDockWin );
595 InsertWindow( pDockWin, rSize, nLine, nPos, bNewLine );
598 //-------------------------------------------------------------------------
600 void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize,
601 USHORT nLine, USHORT nPos, BOOL bNewLine)
603 /* [Beschreibung]
605 Das DockingWindow wird in dieses Splitwindow geschoben und soll die
606 "ubergebene Position und Gr"o\se haben.
610 ReleaseWindow_Impl( pDockWin, FALSE );
611 SfxDock_Impl *pDock = new SfxDock_Impl;
612 pDock->bHide = FALSE;
613 pDock->nType = pDockWin->GetType();
614 pDock->bNewLine = bNewLine;
615 pDock->pWin = pDockWin;
617 DBG_ASSERT( nPos==0 || !bNewLine, "Falsche Paramenter!");
618 if ( bNewLine )
619 nPos = 0;
621 // Das Fenster mu\s vor dem ersten Fenster eingef"ugt werden, das die
622 // gleiche oder eine gr"o\sere Position hat als pDockWin.
623 USHORT nCount = pDockArr->Count();
625 // Wenn gar kein Fenster gefunden wird, wird als erstes eingef"ugt
626 USHORT nInsertPos = 0;
627 for ( USHORT n=0; n<nCount; n++ )
629 SfxDock_Impl *pD = (*pDockArr)[n];
631 if (pD->pWin)
633 // Ein angedocktes Fenster wurde gefunden
634 // Wenn kein geeignetes Fenster hinter der gew"unschten Einf"ugeposition
635 // gefunden wird, wird am Ende eingef"ugt
636 nInsertPos = nCount;
637 USHORT nL=0, nP=0;
638 GetWindowPos( pD->pWin, nL, nP );
640 if ( (nL == nLine && nP == nPos) || nL > nLine )
642 DBG_ASSERT( nL == nLine || bNewLine || nPos > 0, "Falsche Parameter!" );
643 if ( nL == nLine && nPos == 0 && !bNewLine )
645 DBG_ASSERT(pD->bNewLine, "Keine neue Zeile?");
647 // Das Fenster wird auf nPos==0 eingeschoben
648 pD->bNewLine = FALSE;
649 pDock->bNewLine = TRUE;
652 nInsertPos = n;
653 break;
658 pDockArr->Insert(pDock, nInsertPos);
659 InsertWindow_Impl( pDock, rSize, nLine, nPos, bNewLine );
660 SaveConfig_Impl();
663 //-------------------------------------------------------------------------
665 void SfxSplitWindow::InsertWindow_Impl( SfxDock_Impl* pDock,
666 const Size& rSize,
667 USHORT nLine, USHORT nPos, BOOL bNewLine)
669 /* [Beschreibung]
671 F"ugt ein DockingWindow ein und veranla\st die Neuberechnung der Gr"o\se
672 des Splitwindows.
676 SfxDockingWindow* pDockWin = pDock->pWin;
678 USHORT nItemBits = pDockWin->GetWinBits_Impl();
680 long nWinSize, nSetSize;
681 if ( IsHorizontal() )
683 nWinSize = rSize.Width();
684 nSetSize = rSize.Height();
686 else
688 nSetSize = rSize.Width();
689 nWinSize = rSize.Height();
692 pDock->nSize = nWinSize;
694 BOOL bUpdateMode = IsUpdateMode();
695 if ( bUpdateMode )
696 SetUpdateMode( FALSE );
698 if ( bNewLine || nLine == GetItemCount( 0 ) )
700 // Es soll nicht in eine vorhandene Zeile eingef"ugt werden, sondern
701 // eine neue erzeugt werden
703 USHORT nId = 1;
704 for ( USHORT n=0; n<GetItemCount(0); n++ )
706 if ( GetItemId(n) >= nId )
707 nId = GetItemId(n)+1;
710 // Eine neue nLine-te Zeile erzeugen
711 USHORT nBits = nItemBits;
712 if ( GetAlign() == WINDOWALIGN_TOP || GetAlign() == WINDOWALIGN_BOTTOM )
713 nBits |= SWIB_COLSET;
714 InsertItem( nId, nSetSize, nLine, 0, nBits );
717 // In Zeile mit Position nLine das Fenster einf"ugen
718 // ItemWindowSize auf "Prozentual" setzen, da SV dann das Umgr"o\sern
719 // so macht, wie man erwartet; "Pixel" macht eigentlich nur Sinn, wenn
720 // auch Items mit prozentualen oder relativen Gr"o\sen dabei sind.
721 nItemBits |= SWIB_PERCENTSIZE;
722 bLocked = TRUE;
723 USHORT nSet = GetItemId( nLine );
724 InsertItem( pDockWin->GetType(), pDockWin, nWinSize, nPos, nSet, nItemBits );
726 // Splitwindows werden im SFX einmal angelegt und beim Einf"ugen des ersten
727 // DockingWindows sichtbar gemacht.
728 if ( GetItemCount( 0 ) == 1 && GetItemCount( 1 ) == 1 )
730 // Das Neuarrangieren am WorkWindow und ein Show() auf das SplitWindow
731 // wird vom SfxDockingwindow veranla\st (->SfxWorkWindow::ConfigChild_Impl)
732 if ( !bPinned && !IsFloatingMode() )
734 bPinned = TRUE;
735 BOOL bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
736 pEmptyWin->bFadeIn = FALSE;
737 SetPinned_Impl( FALSE );
738 pEmptyWin->Actualize();
739 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
740 pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, TRUE )->nVisible = CHILD_VISIBLE;
741 pWorkWin->ArrangeChilds_Impl();
742 if ( bFadeIn )
743 FadeIn();
745 else
747 BOOL bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
748 pEmptyWin->bFadeIn = FALSE;
749 pEmptyWin->Actualize();
750 #ifdef DBG_UTIL
751 if ( !bPinned || !pEmptyWin->bFadeIn )
753 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
755 else
757 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering real Splitwindow" );
759 #endif
760 pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, TRUE )->nVisible = CHILD_VISIBLE;
761 pWorkWin->ArrangeChilds_Impl();
762 if ( bFadeIn )
763 FadeIn();
766 pWorkWin->ShowChilds_Impl();
769 if ( bUpdateMode )
770 SetUpdateMode( TRUE );
771 bLocked = FALSE;
774 //-------------------------------------------------------------------------
776 void SfxSplitWindow::RemoveWindow( SfxDockingWindow* pDockWin, BOOL bHide )
778 /* [Beschreibung]
780 Entfernt ein DockingWindow. Wenn es das letzte war, wird das SplitWindow
781 gehidet.
784 USHORT nSet = GetSet( pDockWin->GetType() );
786 // Splitwindows werden im SFX einmal angelegt und nach dem Entfernen
787 // des letzten DockingWindows unsichtbar gemacht.
788 if ( GetItemCount( nSet ) == 1 && GetItemCount( 0 ) == 1 )
790 // Das Neuarrangieren am WorkWindow wird vom SfxDockingwindow
791 // veranla\st!
792 Hide();
793 pEmptyWin->aTimer.Stop();
794 USHORT nRealState = pEmptyWin->nState;
795 FadeOut_Impl();
796 pEmptyWin->Hide();
797 #ifdef DBG_UTIL
798 if ( !bPinned || !pEmptyWin->bFadeIn )
800 DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing empty Splitwindow" );
802 else
804 DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing real Splitwindow" );
806 #endif
807 pWorkWin->ReleaseChild_Impl( *GetSplitWindow() );
808 pEmptyWin->nState = nRealState;
809 pWorkWin->ArrangeAutoHideWindows( this );
812 SfxDock_Impl *pDock=0;
813 USHORT nCount = pDockArr->Count();
814 for ( USHORT n=0; n<nCount; n++ )
816 pDock = (*pDockArr)[n];
817 if ( pDock->nType == pDockWin->GetType() )
819 pDock->pWin = 0;
820 pDock->bHide = bHide;
821 break;
825 // Fenster removen, und wenn es das letzte der Zeile war, auch die Zeile
826 // ( Zeile = ItemSet )
827 BOOL bUpdateMode = IsUpdateMode();
828 if ( bUpdateMode )
829 SetUpdateMode( FALSE );
830 bLocked = TRUE;
832 RemoveItem( pDockWin->GetType() );
834 if ( nSet && !GetItemCount( nSet ) )
835 RemoveItem( nSet );
837 if ( bUpdateMode )
838 SetUpdateMode( TRUE );
839 bLocked = FALSE;
842 //-------------------------------------------------------------------------
844 BOOL SfxSplitWindow::GetWindowPos( const SfxDockingWindow* pWindow,
845 USHORT& rLine, USHORT& rPos ) const
846 /* [Beschreibung]
848 Liefert die Id des Itemsets und die des Items f"ur das "ubergebene
849 DockingWindow in der alten Zeilen/Spalten-Bezeichnung zur"uck.
853 USHORT nSet = GetSet ( pWindow->GetType() );
854 if ( nSet == SPLITWINDOW_ITEM_NOTFOUND )
855 return FALSE;
857 rPos = GetItemPos( pWindow->GetType(), nSet );
858 rLine = GetItemPos( nSet );
859 return TRUE;
862 //-------------------------------------------------------------------------
864 BOOL SfxSplitWindow::GetWindowPos( const Point& rTestPos,
865 USHORT& rLine, USHORT& rPos ) const
866 /* [Beschreibung]
868 Liefert die Id des Itemsets und die des Items f"ur das DockingWindow
869 an der "ubergebenen Position in der alten Zeilen/Spalten-Bezeichnung
870 zur"uck.
874 USHORT nId = GetItemId( rTestPos );
875 if ( nId == 0 )
876 return FALSE;
878 USHORT nSet = GetSet ( nId );
879 rPos = GetItemPos( nId, nSet );
880 rLine = GetItemPos( nSet );
881 return TRUE;
884 //-------------------------------------------------------------------------
886 USHORT SfxSplitWindow::GetLineCount() const
888 /* [Beschreibung]
890 Liefert die Zeilenzahl = Zahl der Sub-Itemsets im Root-Set.
893 return GetItemCount( 0 );
896 //-------------------------------------------------------------------------
898 long SfxSplitWindow::GetLineSize( USHORT nLine ) const
900 /* [Beschreibung]
902 Liefert die "Zeilenh"ohe" des nLine-ten Itemsets.
905 USHORT nId = GetItemId( nLine );
906 return GetItemSize( nId );
909 //-------------------------------------------------------------------------
911 USHORT SfxSplitWindow::GetWindowCount( USHORT nLine ) const
913 /* [Beschreibung]
915 Liefert die
918 USHORT nId = GetItemId( nLine );
919 return GetItemCount( nId );
922 //-------------------------------------------------------------------------
924 USHORT SfxSplitWindow::GetWindowCount() const
926 /* [Beschreibung]
928 Liefert die Gesamtzahl aller Fenstert
931 return GetItemCount( 0 );
934 //-------------------------------------------------------------------------
936 void SfxSplitWindow::Command( const CommandEvent& rCEvt )
938 SplitWindow::Command( rCEvt );
941 //-------------------------------------------------------------------------
943 IMPL_LINK( SfxSplitWindow, TimerHdl, Timer*, pTimer)
945 if ( pTimer )
946 pTimer->Stop();
948 if ( CursorIsOverRect( FALSE ) || !pTimer )
950 // Wenn der Mauszeiger innerhalb des Fensters liegt, SplitWindow anzeigen
951 // und Timer zum Schlie\sen aufsetzen
952 pEmptyWin->bAutoHide = TRUE;
953 if ( !IsVisible() )
954 pEmptyWin->FadeIn();
956 pEmptyWin->aLastPos = GetPointerPosPixel();
957 pEmptyWin->aTimer.Start();
959 else if ( pEmptyWin->bAutoHide )
961 if ( GetPointerPosPixel() != pEmptyWin->aLastPos )
963 // Die Maus wurd innerhalb der Timerlaugzeit bewegt, also erst einmal
964 // nichts tun
965 pEmptyWin->aLastPos = GetPointerPosPixel();
966 pEmptyWin->aTimer.Start();
967 return 0L;
970 // Speziell f"ur TF_AUTOSHOW_ON_MOUSEMOVE :
971 // Wenn das Fenster nicht sichtbar ist, gibt es nichts zu tun
972 // (Benutzer ist einfach mit der Maus "uber pEmptyWin gefahren)
973 if ( IsVisible() )
975 pEmptyWin->bEndAutoHide = FALSE;
976 if ( !Application::IsInModalMode() &&
977 !PopupMenu::IsInExecute() &&
978 !pEmptyWin->bSplit && !HasChildPathFocus( TRUE ) )
980 // W"ahrend ein modaler Dialog oder ein Popupmenu offen sind
981 // oder w"ahrend des Splittens auf keinen Fall zumachen; auch
982 // solange eines der Children den Focus hat, bleibt das
983 // das Fenster offen
984 pEmptyWin->bEndAutoHide = TRUE;
987 if ( pEmptyWin->bEndAutoHide )
989 // Von mir aus kann Schlu\s sein mit AutoShow
990 // Aber vielleicht will noch ein anderes SfxSplitWindow offen bleiben,
991 // dann bleiben auch alle anderen offen
992 if ( !pWorkWin->IsAutoHideMode( this ) )
994 FadeOut_Impl();
995 pWorkWin->ArrangeAutoHideWindows( this );
997 else
999 pEmptyWin->aLastPos = GetPointerPosPixel();
1000 pEmptyWin->aTimer.Start();
1003 else
1005 pEmptyWin->aLastPos = GetPointerPosPixel();
1006 pEmptyWin->aTimer.Start();
1011 return 0L;
1014 //-------------------------------------------------------------------------
1016 BOOL SfxSplitWindow::CursorIsOverRect( BOOL bForceAdding ) const
1018 BOOL bVisible = IsVisible();
1020 // Auch das kollabierte SplitWindow ber"ucksichtigen
1021 Point aPos = pEmptyWin->GetParent()->OutputToScreenPixel( pEmptyWin->GetPosPixel() );
1022 Size aSize = pEmptyWin->GetSizePixel();
1024 if ( bForceAdding )
1026 // Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
1027 aPos.X() -= nPixel;
1028 aPos.Y() -= nPixel;
1029 aSize.Width() += 2 * nPixel;
1030 aSize.Height() += 2 * nPixel;
1033 Rectangle aRect( aPos, aSize );
1035 if ( bVisible )
1037 Point aVisPos = GetPosPixel();
1038 Size aVisSize = GetSizePixel();
1040 // Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
1041 aVisPos.X() -= nPixel;
1042 aVisPos.Y() -= nPixel;
1043 aVisSize.Width() += 2 * nPixel;
1044 aVisSize.Height() += 2 * nPixel;
1046 Rectangle aVisRect( aVisPos, aVisSize );
1047 aRect = aRect.GetUnion( aVisRect );
1050 if ( aRect.IsInside( OutputToScreenPixel( ((Window*)this)->GetPointerPosPixel() ) ) )
1051 return TRUE;
1052 return FALSE;
1055 //-------------------------------------------------------------------------
1057 SplitWindow* SfxSplitWindow::GetSplitWindow()
1059 if ( !bPinned || !pEmptyWin->bFadeIn )
1060 return pEmptyWin;
1061 return this;
1064 //-------------------------------------------------------------------------
1065 BOOL SfxSplitWindow::IsFadeIn() const
1067 return pEmptyWin->bFadeIn;
1070 BOOL SfxSplitWindow::IsAutoHide( BOOL bSelf ) const
1072 return bSelf ? pEmptyWin->bAutoHide && !pEmptyWin->bEndAutoHide : pEmptyWin->bAutoHide;
1075 //-------------------------------------------------------------------------
1077 void SfxSplitWindow::SetPinned_Impl( BOOL bOn )
1079 if ( bPinned == bOn )
1080 return;
1082 bPinned = bOn;
1083 if ( GetItemCount( 0 ) == 0 )
1084 return;
1086 if ( !bOn )
1088 pEmptyWin->nState |= 1;
1089 if ( pEmptyWin->bFadeIn )
1091 // Ersatzfenster anmelden
1092 DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing real Splitwindow" );
1093 pWorkWin->ReleaseChild_Impl( *this );
1094 Hide();
1095 pEmptyWin->Actualize();
1096 DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering empty Splitwindow" );
1097 pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, TRUE )->nVisible = CHILD_VISIBLE;
1100 Point aPos( GetPosPixel() );
1101 aPos = GetParent()->OutputToScreenPixel( aPos );
1102 SetFloatingPos( aPos );
1103 SetFloatingMode( TRUE );
1104 GetFloatingWindow()->SetOutputSizePixel( GetOutputSizePixel() );
1106 if ( pEmptyWin->bFadeIn )
1107 Show();
1109 else
1111 pEmptyWin->nState &= ~1;
1112 SetOutputSizePixel( GetFloatingWindow()->GetOutputSizePixel() );
1113 SetFloatingMode( FALSE );
1115 if ( pEmptyWin->bFadeIn )
1117 // Ersatzfenster abmelden
1118 DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing empty Splitwindow" );
1119 pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1120 pEmptyWin->Hide();
1121 DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering real Splitwindow" );
1122 pWorkWin->RegisterChild_Impl( *this, eAlign, TRUE )->nVisible = CHILD_VISIBLE;
1126 SetAutoHideState( !bPinned );
1127 pEmptyWin->SetAutoHideState( !bPinned );
1130 //-------------------------------------------------------------------------
1132 void SfxSplitWindow::SetFadeIn_Impl( BOOL bOn )
1134 if ( bOn == pEmptyWin->bFadeIn )
1135 return;
1137 if ( GetItemCount( 0 ) == 0 )
1138 return;
1140 pEmptyWin->bFadeIn = bOn;
1141 if ( bOn )
1143 pEmptyWin->nState |= 2;
1144 if ( IsFloatingMode() )
1146 // FloatingWindow ist nicht sichtbar, also anzeigen
1147 pWorkWin->ArrangeAutoHideWindows( this );
1148 Show();
1150 else
1152 DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing empty Splitwindow" );
1153 pWorkWin->ReleaseChild_Impl( *pEmptyWin );
1154 pEmptyWin->Hide();
1155 DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering real Splitwindow" );
1156 pWorkWin->RegisterChild_Impl( *this, eAlign, TRUE )->nVisible = CHILD_VISIBLE;
1157 pWorkWin->ArrangeChilds_Impl();
1158 pWorkWin->ShowChilds_Impl();
1161 else
1163 pEmptyWin->bAutoHide = FALSE;
1164 pEmptyWin->nState &= ~2;
1165 if ( !IsFloatingMode() )
1167 // Das Fenster "schwebt" nicht, soll aber ausgeblendet werden,
1168 DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing real Splitwindow" );
1169 pWorkWin->ReleaseChild_Impl( *this );
1170 Hide();
1171 pEmptyWin->Actualize();
1172 DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering empty Splitwindow" );
1173 pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, TRUE )->nVisible = CHILD_VISIBLE;
1174 pWorkWin->ArrangeChilds_Impl();
1175 pWorkWin->ShowChilds_Impl();
1176 pWorkWin->ArrangeAutoHideWindows( this );
1178 else
1180 Hide();
1181 pWorkWin->ArrangeAutoHideWindows( this );
1186 void SfxSplitWindow::AutoHide()
1188 // Wenn dieser Handler am "echten" SplitWindow aufgerufen wird, ist es
1189 // entweder angedockt und soll "schwebend" angezeigt werden oder umgekehrt
1190 if ( !bPinned )
1192 // Es "schwebt", also wieder andocken
1193 SetPinned_Impl( TRUE );
1194 pWorkWin->ArrangeChilds_Impl();
1196 else
1198 // In den "Schwebezustand" bringen
1199 SetPinned_Impl( FALSE );
1200 pWorkWin->ArrangeChilds_Impl();
1201 pWorkWin->ArrangeAutoHideWindows( this );
1204 pWorkWin->ShowChilds_Impl();
1205 SaveConfig_Impl();
1208 void SfxSplitWindow::FadeOut_Impl()
1210 if ( pEmptyWin->aTimer.IsActive() )
1212 pEmptyWin->bAutoHide = FALSE;
1213 pEmptyWin->aTimer.Stop();
1216 SetFadeIn_Impl( FALSE );
1217 Show_Impl();
1220 void SfxSplitWindow::FadeOut()
1222 FadeOut_Impl();
1223 SaveConfig_Impl();
1226 void SfxSplitWindow::FadeIn()
1228 SetFadeIn_Impl( TRUE );
1229 Show_Impl();
1232 void SfxSplitWindow::Show_Impl()
1234 USHORT nCount = pDockArr->Count();
1235 for ( USHORT n=0; n<nCount; n++ )
1237 SfxDock_Impl *pDock = (*pDockArr)[n];
1238 if ( pDock->pWin )
1239 pDock->pWin->FadeIn( pEmptyWin->bFadeIn );
1243 void SfxSplitWindow::Pin_Impl( BOOL bPin )
1245 if ( bPinned != bPin )
1246 AutoHide();
1249 BOOL SfxSplitWindow::ActivateNextChild_Impl( BOOL bForward )
1251 // Wenn kein pActive, auf erstes bzw. letztes Fenster gehen ( bei !bForward wird erst in der loop dekrementiert )
1252 USHORT nCount = pDockArr->Count();
1253 USHORT n = bForward ? 0 : nCount;
1255 // Wenn Focus innerhalb, dann ein Fenster vor oder zur"uck, wenn m"oglich
1256 if ( pActive )
1258 // Aktives Fenster ermitteln
1259 for ( n=0; n<nCount; n++ )
1261 SfxDock_Impl *pD = (*pDockArr)[n];
1262 if ( pD->pWin && pD->pWin->HasChildPathFocus() )
1263 break;
1266 if ( bForward )
1267 // ein Fenster weiter ( wenn dann n>nCount, wird die Schleife unten gar nicht durchlaufen )
1268 n++;
1271 if ( bForward )
1273 // N"achstes Fenster suchen
1274 for ( USHORT nNext=n; nNext<nCount; nNext++ )
1276 SfxDock_Impl *pD = (*pDockArr)[nNext];
1277 if ( pD->pWin )
1279 pD->pWin->GrabFocus();
1280 return TRUE;
1284 else
1286 // Vorheriges Fenster suchen
1287 for ( USHORT nNext=n; nNext--; )
1289 SfxDock_Impl *pD = (*pDockArr)[nNext];
1290 if ( pD->pWin )
1292 pD->pWin->GrabFocus();
1293 return TRUE;
1298 return FALSE;
1301 void SfxSplitWindow::SetActiveWindow_Impl( SfxDockingWindow* pWin )
1303 pActive = pWin;
1304 pWorkWin->SetActiveChild_Impl( this );