1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: splitwin.cxx,v $
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"
35 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
39 #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
41 #ifndef _WRKWIN_HXX //autogen
42 #include <vcl/wrkwin.hxx>
44 #include <svtools/viewoptions.hxx>
48 #include <vcl/timer.hxx>
50 #include "splitwin.hxx"
51 #include "workwin.hxx"
52 #include <sfx2/dockwin.hxx>
53 #include <sfx2/app.hxx>
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
;
66 #define USERITEM_NAME OUString::createFromAscii( "UserItem" )
71 SfxDockingWindow
* pWin
; // SplitWindow hat dieses Fenster
73 BOOL bHide
; // SplitWindow hatte dieses Fenster
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
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
;
100 SfxEmptySplitWin_Impl( SfxSplitWindow
*pParent
)
101 : SplitWindow( pParent
->GetParent(), WinBits( WB_BORDER
| WB_3DLOOK
) )
106 , bEndAutoHide( FALSE
)
109 aTimer
.SetTimeoutHdl(
110 LINK(pOwner
, SfxSplitWindow
, TimerHdl
) );
111 aTimer
.SetTimeout( 200 );
112 // EnableDrop( TRUE );
113 SetAlign( pOwner
->GetAlign() );
115 ShowAutoHideButton( pOwner
->IsAutoHideButtonVisible() );
116 ShowFadeInHideButton( TRUE
);
119 ~SfxEmptySplitWin_Impl()
124 virtual void MouseMove( const MouseEvent
& );
125 virtual void AutoHide();
126 virtual void FadeIn();
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();
139 case WINDOWALIGN_TOP
:
140 case WINDOWALIGN_BOTTOM
:
141 aSize
.Height() = GetFadeInSize();
145 SetSizePixel( aSize
);
148 void SfxEmptySplitWin_Impl::AutoHide()
150 pOwner
->SetPinned_Impl( !pOwner
->bPinned
);
151 pOwner
->SaveConfig_Impl();
156 void SfxEmptySplitWin_Impl::FadeIn()
159 bAutoHide
= IsFadeNoButtonMode();
160 pOwner
->SetFadeIn_Impl( TRUE
);
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();
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
)
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
),
203 pDockArr( new SfxDockArr_Impl
),
211 ShowAutoHideButton( FALSE
); // no autohide button (pin) anymore
212 ShowFadeOutButton( TRUE
);
215 // SV-Alignment setzen
216 WindowAlign eTbxAlign
;
220 eTbxAlign
= WINDOWALIGN_LEFT
;
222 case SFX_ALIGN_RIGHT
:
223 eTbxAlign
= WINDOWALIGN_RIGHT
;
226 eTbxAlign
= WINDOWALIGN_TOP
;
228 case SFX_ALIGN_BOTTOM
:
229 eTbxAlign
= WINDOWALIGN_BOTTOM
;
233 eTbxAlign
= WINDOWALIGN_TOP
; // some sort of default...
234 break; // -Wall lots not handled..
237 SetAlign (eTbxAlign
);
238 pEmptyWin
= new SfxEmptySplitWin_Impl( this );
241 pEmptyWin
->bFadeIn
= TRUE
;
242 pEmptyWin
->nState
= 2;
247 // Konfiguration einlesen
248 String aWindowId
= String::CreateFromAscii("SplitWindow");
249 aWindowId
+= String::CreateFromInt32( (sal_Int32
) eTbxAlign
);
250 SvtViewOptions
aWinOpt( E_WINDOW
, aWindowId
);
252 Any aUserItem
= aWinOpt
.GetUserItem( USERITEM_NAME
);
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
265 USHORT nCount
= (USHORT
) aWinData
.GetToken(i
++, ',').ToInt32();
266 for ( USHORT n
=0; n
<nCount
; n
++ )
268 SfxDock_Impl
*pDock
= new SfxDock_Impl
;
270 pDock
->bNewLine
= FALSE
;
272 pDock
->nType
= (USHORT
) aWinData
.GetToken(i
++, ',').ToInt32();
275 // K"onnte NewLine bedeuten
276 pDock
->nType
= (USHORT
) aWinData
.GetToken(i
++, ',').ToInt32();
284 pDock
->bNewLine
= TRUE
;
287 pDockArr
->Insert(pDock
,n
);
294 pEmptyWin
->bFadeIn
= TRUE
;
295 pEmptyWin
->nState
= 2;
298 SetAutoHideState( !bPinned
);
299 pEmptyWin
->SetAutoHideState( !bPinned
);
302 //-------------------------------------------------------------------------
304 SfxSplitWindow::~SfxSplitWindow()
306 if ( !pWorkWin
->GetParent_Impl() )
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
;
321 void SfxSplitWindow::SaveConfig_Impl()
323 // Konfiguration abspeichern
324 String
aWinData('V');
325 aWinData
+= String::CreateFromInt32( VERSION
);
327 aWinData
+= String::CreateFromInt32( pEmptyWin
->nState
);
332 for ( n
=0; n
<pDockArr
->Count(); n
++ )
334 SfxDock_Impl
*pDock
= (*pDockArr
)[n
];
335 if ( pDock
->bHide
|| pDock
->pWin
)
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
)
346 if ( pDock
->bNewLine
)
347 aWinData
+= DEFINE_CONST_UNICODE(",0");
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()
363 Size aSize
= GetSizePixel();
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();
378 case WINDOWALIGN_TOP
:
379 case WINDOWALIGN_BOTTOM
:
380 nSize
= aSize
.Height() + aRect
.GetHeight();
384 SetMaxSizePixel( nSize
);
387 //-------------------------------------------------------------------------
389 void SfxSplitWindow::SplitResize()
393 pWorkWin
->ArrangeChilds_Impl();
394 pWorkWin
->ShowChilds_Impl();
397 pWorkWin
->ArrangeAutoHideWindows( this );
400 //-------------------------------------------------------------------------
402 void SfxSplitWindow::Split()
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
];
415 USHORT nId
= pD
->nType
;
416 long nSize
= GetItemSize( nId
, SWIB_FIXED
);
417 long nSetSize
= GetItemSize( GetSet( nId
) );
420 if ( IsHorizontal() )
422 aSize
.Width() = nSize
;
423 aSize
.Height() = nSetSize
;
427 aSize
.Width() = nSetSize
;
428 aSize
.Height() = nSize
;
431 pD
->pWin
->SetItemSize_Impl( aSize
);
438 //-------------------------------------------------------------------------
440 void SfxSplitWindow::InsertWindow( SfxDockingWindow
* pDockWin
, const Size
& rSize
)
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
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
464 // Aber hinter dem gerade eingef"ugten Fenster
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
);
484 // Fenster liegt vor dem eingef"ugten
488 // Zeile ist schon er"offnet
494 if ( pDock
->nType
== pDockWin
->GetType() )
496 DBG_ASSERT( !pFoundDock
&& !pDock
->pWin
, "Fenster ist schon vorhanden!");
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!
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();
521 pFoundDock
->bNewLine
= bNewLine
;
525 pFoundDock
->pWin
= pDockWin
;
526 pFoundDock
->bHide
= FALSE
;
527 InsertWindow_Impl( pFoundDock
, rSize
, nLine
, nPos
, bNewLine
);
532 //-------------------------------------------------------------------------
534 void SfxSplitWindow::ReleaseWindow_Impl(SfxDockingWindow
*pDockWin
, BOOL bSave
)
538 Das DockingWindow wird nicht mehr in den internen Daten gespeichert.
542 SfxDock_Impl
*pDock
=0;
543 USHORT nCount
= pDockArr
->Count();
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
567 //-------------------------------------------------------------------------
569 void SfxSplitWindow::MoveWindow( SfxDockingWindow
* pDockWin
, const Size
& rSize
,
570 USHORT nLine
, USHORT nPos
, BOOL bNewLine
)
574 Das DockingWindow wird innerhalb des Splitwindows verschoben.
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!
589 else if ( nLine == nL && nPos > nP )
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
)
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!");
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
];
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
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
;
658 pDockArr
->Insert(pDock
, nInsertPos
);
659 InsertWindow_Impl( pDock
, rSize
, nLine
, nPos
, bNewLine
);
663 //-------------------------------------------------------------------------
665 void SfxSplitWindow::InsertWindow_Impl( SfxDock_Impl
* pDock
,
667 USHORT nLine
, USHORT nPos
, BOOL bNewLine
)
671 F"ugt ein DockingWindow ein und veranla\st die Neuberechnung der Gr"o\se
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();
688 nSetSize
= rSize
.Width();
689 nWinSize
= rSize
.Height();
692 pDock
->nSize
= nWinSize
;
694 BOOL bUpdateMode
= IsUpdateMode();
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
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
;
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() )
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();
747 BOOL bFadeIn
= ( pEmptyWin
->nState
& 2 ) != 0;
748 pEmptyWin
->bFadeIn
= FALSE
;
749 pEmptyWin
->Actualize();
751 if ( !bPinned
|| !pEmptyWin
->bFadeIn
)
753 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
757 DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering real Splitwindow" );
760 pWorkWin
->RegisterChild_Impl( *GetSplitWindow(), eAlign
, TRUE
)->nVisible
= CHILD_VISIBLE
;
761 pWorkWin
->ArrangeChilds_Impl();
766 pWorkWin
->ShowChilds_Impl();
770 SetUpdateMode( TRUE
);
774 //-------------------------------------------------------------------------
776 void SfxSplitWindow::RemoveWindow( SfxDockingWindow
* pDockWin
, BOOL bHide
)
780 Entfernt ein DockingWindow. Wenn es das letzte war, wird das SplitWindow
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
793 pEmptyWin
->aTimer
.Stop();
794 USHORT nRealState
= pEmptyWin
->nState
;
798 if ( !bPinned
|| !pEmptyWin
->bFadeIn
)
800 DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing empty Splitwindow" );
804 DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing real Splitwindow" );
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() )
820 pDock
->bHide
= bHide
;
825 // Fenster removen, und wenn es das letzte der Zeile war, auch die Zeile
826 // ( Zeile = ItemSet )
827 BOOL bUpdateMode
= IsUpdateMode();
829 SetUpdateMode( FALSE
);
832 RemoveItem( pDockWin
->GetType() );
834 if ( nSet
&& !GetItemCount( nSet
) )
838 SetUpdateMode( TRUE
);
842 //-------------------------------------------------------------------------
844 BOOL
SfxSplitWindow::GetWindowPos( const SfxDockingWindow
* pWindow
,
845 USHORT
& rLine
, USHORT
& rPos
) const
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
)
857 rPos
= GetItemPos( pWindow
->GetType(), nSet
);
858 rLine
= GetItemPos( nSet
);
862 //-------------------------------------------------------------------------
864 BOOL
SfxSplitWindow::GetWindowPos( const Point
& rTestPos
,
865 USHORT
& rLine
, USHORT
& rPos
) const
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
874 USHORT nId
= GetItemId( rTestPos
);
878 USHORT nSet
= GetSet ( nId
);
879 rPos
= GetItemPos( nId
, nSet
);
880 rLine
= GetItemPos( nSet
);
884 //-------------------------------------------------------------------------
886 USHORT
SfxSplitWindow::GetLineCount() const
890 Liefert die Zeilenzahl = Zahl der Sub-Itemsets im Root-Set.
893 return GetItemCount( 0 );
896 //-------------------------------------------------------------------------
898 long SfxSplitWindow::GetLineSize( USHORT nLine
) const
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
918 USHORT nId
= GetItemId( nLine
);
919 return GetItemCount( nId
);
922 //-------------------------------------------------------------------------
924 USHORT
SfxSplitWindow::GetWindowCount() const
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
)
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
;
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
965 pEmptyWin
->aLastPos
= GetPointerPosPixel();
966 pEmptyWin
->aTimer
.Start();
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)
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
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 ) )
995 pWorkWin
->ArrangeAutoHideWindows( this );
999 pEmptyWin
->aLastPos
= GetPointerPosPixel();
1000 pEmptyWin
->aTimer
.Start();
1005 pEmptyWin
->aLastPos
= GetPointerPosPixel();
1006 pEmptyWin
->aTimer
.Start();
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();
1026 // Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
1029 aSize
.Width() += 2 * nPixel
;
1030 aSize
.Height() += 2 * nPixel
;
1033 Rectangle
aRect( aPos
, aSize
);
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() ) ) )
1055 //-------------------------------------------------------------------------
1057 SplitWindow
* SfxSplitWindow::GetSplitWindow()
1059 if ( !bPinned
|| !pEmptyWin
->bFadeIn
)
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
)
1083 if ( GetItemCount( 0 ) == 0 )
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 );
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
)
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
);
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
)
1137 if ( GetItemCount( 0 ) == 0 )
1140 pEmptyWin
->bFadeIn
= bOn
;
1143 pEmptyWin
->nState
|= 2;
1144 if ( IsFloatingMode() )
1146 // FloatingWindow ist nicht sichtbar, also anzeigen
1147 pWorkWin
->ArrangeAutoHideWindows( this );
1152 DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing empty Splitwindow" );
1153 pWorkWin
->ReleaseChild_Impl( *pEmptyWin
);
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();
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 );
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 );
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
1192 // Es "schwebt", also wieder andocken
1193 SetPinned_Impl( TRUE
);
1194 pWorkWin
->ArrangeChilds_Impl();
1198 // In den "Schwebezustand" bringen
1199 SetPinned_Impl( FALSE
);
1200 pWorkWin
->ArrangeChilds_Impl();
1201 pWorkWin
->ArrangeAutoHideWindows( this );
1204 pWorkWin
->ShowChilds_Impl();
1208 void SfxSplitWindow::FadeOut_Impl()
1210 if ( pEmptyWin
->aTimer
.IsActive() )
1212 pEmptyWin
->bAutoHide
= FALSE
;
1213 pEmptyWin
->aTimer
.Stop();
1216 SetFadeIn_Impl( FALSE
);
1220 void SfxSplitWindow::FadeOut()
1226 void SfxSplitWindow::FadeIn()
1228 SetFadeIn_Impl( TRUE
);
1232 void SfxSplitWindow::Show_Impl()
1234 USHORT nCount
= pDockArr
->Count();
1235 for ( USHORT n
=0; n
<nCount
; n
++ )
1237 SfxDock_Impl
*pDock
= (*pDockArr
)[n
];
1239 pDock
->pWin
->FadeIn( pEmptyWin
->bFadeIn
);
1243 void SfxSplitWindow::Pin_Impl( BOOL bPin )
1245 if ( bPinned != bPin )
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
1258 // Aktives Fenster ermitteln
1259 for ( n
=0; n
<nCount
; n
++ )
1261 SfxDock_Impl
*pD
= (*pDockArr
)[n
];
1262 if ( pD
->pWin
&& pD
->pWin
->HasChildPathFocus() )
1267 // ein Fenster weiter ( wenn dann n>nCount, wird die Schleife unten gar nicht durchlaufen )
1273 // N"achstes Fenster suchen
1274 for ( USHORT nNext
=n
; nNext
<nCount
; nNext
++ )
1276 SfxDock_Impl
*pD
= (*pDockArr
)[nNext
];
1279 pD
->pWin
->GrabFocus();
1286 // Vorheriges Fenster suchen
1287 for ( USHORT nNext
=n
; nNext
--; )
1289 SfxDock_Impl
*pD
= (*pDockArr
)[nNext
];
1292 pD
->pWin
->GrabFocus();
1301 void SfxSplitWindow::SetActiveWindow_Impl( SfxDockingWindow
* pWin
)
1304 pWorkWin
->SetActiveChild_Impl( this );