1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
36 #include <vcl/wrkwin.hxx>
37 #include <unotools/viewoptions.hxx>
39 #include <vcl/timer.hxx>
41 #include "splitwin.hxx"
42 #include "workwin.hxx"
43 #include <sfx2/dockwin.hxx>
44 #include <sfx2/app.hxx>
46 #include "sfx2/sfxresid.hxx"
47 #include <sfx2/mnumgr.hxx>
48 #include "virtmenu.hxx"
49 #include <sfx2/msgpool.hxx>
50 #include <sfx2/viewfrm.hxx>
52 using namespace ::com::sun::star::uno
;
53 using namespace ::rtl
;
57 #define USERITEM_NAME OUString("UserItem")
62 SfxDockingWindow
* pWin
; // SplitWindow has this window
64 sal_Bool bHide
; // SplitWindow had this window
68 typedef SfxDock_Impl
* SfxDockPtr
;
69 SV_DECL_PTRARR_DEL( SfxDockArr_Impl
, SfxDockPtr
, 4 )
70 SV_IMPL_PTRARR( SfxDockArr_Impl
, SfxDockPtr
);
72 class SfxEmptySplitWin_Impl
: public SplitWindow
76 The SfxEmptySplitWin_Impldow is an empty SplitWindow, that replaces the
77 SfxSplitWindow AutoHide mode. It only serves as a placeholder to receive
78 mouse moves and if possible blend in the true SplitWindow display.
80 friend class SfxSplitWindow
;
82 SfxSplitWindow
* pOwner
;
86 sal_Bool bEndAutoHide
;
91 SfxEmptySplitWin_Impl( SfxSplitWindow
*pParent
)
92 : SplitWindow( pParent
->GetParent(), WinBits( WB_BORDER
| WB_3DLOOK
) )
94 , bFadeIn( sal_False
)
95 , bAutoHide( sal_False
)
97 , bEndAutoHide( sal_False
)
100 aTimer
.SetTimeoutHdl(
101 LINK(pOwner
, SfxSplitWindow
, TimerHdl
) );
102 aTimer
.SetTimeout( 200 );
103 SetAlign( pOwner
->GetAlign() );
105 ShowAutoHideButton( pOwner
->IsAutoHideButtonVisible() );
106 ShowFadeInHideButton( sal_True
);
109 ~SfxEmptySplitWin_Impl()
114 virtual void MouseMove( const MouseEvent
& );
115 virtual void AutoHide();
116 virtual void FadeIn();
120 void SfxEmptySplitWin_Impl::Actualize()
122 Size
aSize( pOwner
->GetSizePixel() );
123 switch ( pOwner
->GetAlign() )
125 case WINDOWALIGN_LEFT
:
126 case WINDOWALIGN_RIGHT
:
127 aSize
.Width() = GetFadeInSize();
129 case WINDOWALIGN_TOP
:
130 case WINDOWALIGN_BOTTOM
:
131 aSize
.Height() = GetFadeInSize();
135 SetSizePixel( aSize
);
138 void SfxEmptySplitWin_Impl::AutoHide()
140 pOwner
->SetPinned_Impl( !pOwner
->bPinned
);
141 pOwner
->SaveConfig_Impl();
142 bAutoHide
= sal_True
;
146 void SfxEmptySplitWin_Impl::FadeIn()
149 bAutoHide
= IsFadeNoButtonMode();
150 pOwner
->SetFadeIn_Impl( sal_True
);
154 // Set Timer to close; the caller has to ensure themselves that the
155 // Window is not closed instantly (eg by setting the focus or a modal
157 aLastPos
= GetPointerPosPixel();
161 pOwner
->SaveConfig_Impl();
164 //-------------------------------------------------------------------------
166 void SfxSplitWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
168 if ( rMEvt
.GetClicks() != 2 )
169 SplitWindow::MouseButtonDown( rMEvt
);
172 void SfxEmptySplitWin_Impl::MouseMove( const MouseEvent
& rMEvt
)
174 SplitWindow::MouseMove( rMEvt
);
177 //-------------------------------------------------------------------------
179 SfxSplitWindow::SfxSplitWindow( Window
* pParent
, SfxChildAlignment eAl
,
180 SfxWorkWindow
*pW
, sal_Bool bWithButtons
, WinBits nBits
)
184 A SfxSplitWindow brings the recursive structure of the SV-SplitWindows to
185 the outside by simulating a table-like structure with rows and columns
186 (maximum recursion depth 2). Furthermore, it ensures the persistence of
187 the arrangement of the SfxDockingWindows.
190 : SplitWindow ( pParent
, nBits
| WB_HIDE
),
193 pDockArr( new SfxDockArr_Impl
),
201 ShowAutoHideButton( sal_False
); // no autohide button (pin) anymore
202 ShowFadeOutButton( sal_True
);
206 WindowAlign eTbxAlign
;
210 eTbxAlign
= WINDOWALIGN_LEFT
;
212 case SFX_ALIGN_RIGHT
:
213 eTbxAlign
= WINDOWALIGN_RIGHT
;
216 eTbxAlign
= WINDOWALIGN_TOP
;
218 case SFX_ALIGN_BOTTOM
:
219 eTbxAlign
= WINDOWALIGN_BOTTOM
;
223 eTbxAlign
= WINDOWALIGN_TOP
; // some sort of default...
224 break; // -Wall lots not handled..
227 SetAlign (eTbxAlign
);
228 pEmptyWin
= new SfxEmptySplitWin_Impl( this );
231 pEmptyWin
->bFadeIn
= sal_True
;
232 pEmptyWin
->nState
= 2;
237 // Read Configuration
238 String aWindowId
= String::CreateFromAscii("SplitWindow");
239 aWindowId
+= String::CreateFromInt32( (sal_Int32
) eTbxAlign
);
240 SvtViewOptions
aWinOpt( E_WINDOW
, aWindowId
);
242 Any aUserItem
= aWinOpt
.GetUserItem( USERITEM_NAME
);
244 if ( aUserItem
>>= aTemp
)
245 aWinData
= String( aTemp
);
246 if ( aWinData
.Len() && aWinData
.GetChar( (sal_uInt16
) 0 ) == 'V' )
248 pEmptyWin
->nState
= (sal_uInt16
) aWinData
.GetToken( 1, ',' ).ToInt32();
249 if ( pEmptyWin
->nState
& 2 )
250 pEmptyWin
->bFadeIn
= sal_True
;
251 bPinned
= sal_True
; // always assume pinned - floating mode not used anymore
254 sal_uInt16 nCount
= (sal_uInt16
) aWinData
.GetToken(i
++, ',').ToInt32();
255 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
257 SfxDock_Impl
*pDock
= new SfxDock_Impl
;
259 pDock
->bNewLine
= sal_False
;
260 pDock
->bHide
= sal_True
;
261 pDock
->nType
= (sal_uInt16
) aWinData
.GetToken(i
++, ',').ToInt32();
264 // could mean NewLine
265 pDock
->nType
= (sal_uInt16
) aWinData
.GetToken(i
++, ',').ToInt32();
273 pDock
->bNewLine
= sal_True
;
276 pDockArr
->Insert(pDock
,n
);
283 pEmptyWin
->bFadeIn
= sal_True
;
284 pEmptyWin
->nState
= 2;
287 SetAutoHideState( !bPinned
);
288 pEmptyWin
->SetAutoHideState( !bPinned
);
291 //-------------------------------------------------------------------------
293 SfxSplitWindow::~SfxSplitWindow()
295 if ( !pWorkWin
->GetParent_Impl() )
300 // Set pOwner to NULL, otherwise try to delete pEmptyWin once more. The
301 // window that is just beeing docked is always deleted from the outside.
302 pEmptyWin
->pOwner
= NULL
;
309 void SfxSplitWindow::SaveConfig_Impl()
311 // Save configuration
312 String
aWinData('V');
313 aWinData
+= String::CreateFromInt32( VERSION
);
315 aWinData
+= String::CreateFromInt32( pEmptyWin
->nState
);
318 sal_uInt16 nCount
= 0;
320 for ( n
=0; n
<pDockArr
->Count(); n
++ )
322 SfxDock_Impl
*pDock
= (*pDockArr
)[n
];
323 if ( pDock
->bHide
|| pDock
->pWin
)
327 aWinData
+= String::CreateFromInt32( nCount
);
329 for ( n
=0; n
<pDockArr
->Count(); n
++ )
331 SfxDock_Impl
*pDock
= (*pDockArr
)[n
];
332 if ( !pDock
->bHide
&& !pDock
->pWin
)
334 if ( pDock
->bNewLine
)
335 aWinData
+= DEFINE_CONST_UNICODE(",0");
337 aWinData
+= String::CreateFromInt32( pDock
->nType
);
340 String aWindowId
= String::CreateFromAscii("SplitWindow");
341 aWindowId
+= String::CreateFromInt32( (sal_Int32
) GetAlign() );
342 SvtViewOptions
aWinOpt( E_WINDOW
, aWindowId
);
343 aWinOpt
.SetUserItem( USERITEM_NAME
, makeAny( OUString( aWinData
) ) );
346 //-------------------------------------------------------------------------
348 void SfxSplitWindow::StartSplit()
351 Size aSize
= GetSizePixel();
355 pEmptyWin
->bFadeIn
= sal_True
;
356 pEmptyWin
->bSplit
= sal_True
;
359 Rectangle aRect
= pWorkWin
->GetFreeArea( !bPinned
);
360 switch ( GetAlign() )
362 case WINDOWALIGN_LEFT
:
363 case WINDOWALIGN_RIGHT
:
364 nSize
= aSize
.Width() + aRect
.GetWidth();
366 case WINDOWALIGN_TOP
:
367 case WINDOWALIGN_BOTTOM
:
368 nSize
= aSize
.Height() + aRect
.GetHeight();
372 SetMaxSizePixel( nSize
);
375 //-------------------------------------------------------------------------
377 void SfxSplitWindow::SplitResize()
381 pWorkWin
->ArrangeChildren_Impl();
382 pWorkWin
->ShowChildren_Impl();
385 pWorkWin
->ArrangeAutoHideWindows( this );
388 //-------------------------------------------------------------------------
390 void SfxSplitWindow::Split()
393 pEmptyWin
->bSplit
= sal_False
;
395 SplitWindow::Split();
397 sal_uInt16 nCount
= pDockArr
->Count();
398 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
400 SfxDock_Impl
*pD
= (*pDockArr
)[n
];
403 sal_uInt16 nId
= pD
->nType
;
404 long nSize
= GetItemSize( nId
, SWIB_FIXED
);
405 long nSetSize
= GetItemSize( GetSet( nId
) );
408 if ( IsHorizontal() )
410 aSize
.Width() = nSize
;
411 aSize
.Height() = nSetSize
;
415 aSize
.Width() = nSetSize
;
416 aSize
.Height() = nSize
;
419 pD
->pWin
->SetItemSize_Impl( aSize
);
426 //-------------------------------------------------------------------------
428 void SfxSplitWindow::InsertWindow( SfxDockingWindow
* pDockWin
, const Size
& rSize
)
432 To insert SfxDockingWindows can no position be passed. The SfxSplitWindow
433 searches the last marked one to the passed SfxDockingWindow or appends a
437 short nLine
= -1; // so that the first window cab set nline to 0
440 sal_Bool bNewLine
= sal_True
;
441 sal_Bool bSaveConfig
= sal_False
;
442 SfxDock_Impl
*pFoundDock
=0;
443 sal_uInt16 nCount
= pDockArr
->Count();
444 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
446 SfxDock_Impl
*pDock
= (*pDockArr
)[n
];
447 if ( pDock
->bNewLine
)
449 // The window opens a new line
451 // But after the just inserted window
461 // Does there exist a window now at this position
462 if ( bNewLine
&& !pFoundDock
)
464 // Not known until now in which real line it is located
465 GetWindowPos( pDock
->pWin
, nL
, nPos
);
471 // The window is located before the inserted one
476 bNewLine
= sal_False
;
481 if ( pDock
->nType
== pDockWin
->GetType() )
483 DBG_ASSERT( !pFoundDock
&& !pDock
->pWin
, "Window does already exist!");
489 // A new line has been created but no window was fond there;
490 // continue searching for a window in this line in-order to set
491 // bNewLine correctly. While doing so nline or nPos are not
500 // Not found, insert at end
501 pFoundDock
= new SfxDock_Impl
;
502 pFoundDock
->bHide
= sal_True
;
503 pDockArr
->Insert( pFoundDock
, nCount
);
504 pFoundDock
->nType
= pDockWin
->GetType();
508 pFoundDock
->bNewLine
= bNewLine
;
509 bSaveConfig
= sal_True
;
512 pFoundDock
->pWin
= pDockWin
;
513 pFoundDock
->bHide
= sal_False
;
514 InsertWindow_Impl( pFoundDock
, rSize
, nLine
, nPos
, bNewLine
);
519 //-------------------------------------------------------------------------
521 void SfxSplitWindow::ReleaseWindow_Impl(SfxDockingWindow
*pDockWin
, sal_Bool bSave
)
525 The docking window is no longer stored in the internal data.
529 SfxDock_Impl
*pDock
=0;
530 sal_uInt16 nCount
= pDockArr
->Count();
531 sal_Bool bFound
= sal_False
;
532 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
534 pDock
= (*pDockArr
)[n
];
535 if ( pDock
->nType
== pDockWin
->GetType() )
537 if ( pDock
->bNewLine
&& n
<nCount
-1 )
538 (*pDockArr
)[n
+1]->bNewLine
= sal_True
;
540 // Window has a position, this we forget
554 //-------------------------------------------------------------------------
556 void SfxSplitWindow::MoveWindow( SfxDockingWindow
* pDockWin
, const Size
& rSize
,
557 sal_uInt16 nLine
, sal_uInt16 nPos
, sal_Bool bNewLine
)
561 The docking window is moved within the SplitWindows.
566 GetWindowPos( pDockWin
, nL
, nP
);
568 if ( nLine
> nL
&& GetItemCount( GetItemId( nL
, 0 ) ) == 1 )
570 // If the last window is removed from its line, then everything slips
571 // one line to the front!
574 RemoveWindow( pDockWin
);
575 InsertWindow( pDockWin
, rSize
, nLine
, nPos
, bNewLine
);
578 //-------------------------------------------------------------------------
580 void SfxSplitWindow::InsertWindow( SfxDockingWindow
* pDockWin
, const Size
& rSize
,
581 sal_uInt16 nLine
, sal_uInt16 nPos
, sal_Bool bNewLine
)
585 The DockingWindow that is pushed on this SplitWindow and shall hold the
586 given position and size.
589 ReleaseWindow_Impl( pDockWin
, sal_False
);
590 SfxDock_Impl
*pDock
= new SfxDock_Impl
;
591 pDock
->bHide
= sal_False
;
592 pDock
->nType
= pDockWin
->GetType();
593 pDock
->bNewLine
= bNewLine
;
594 pDock
->pWin
= pDockWin
;
596 DBG_ASSERT( nPos
==0 || !bNewLine
, "Wrong Paramenter!");
600 // The window must be inserted before the first window so that it has the
601 // same or a greater position than pDockWin.
602 sal_uInt16 nCount
= pDockArr
->Count();
603 sal_uInt16
nLastWindowIdx(0);
605 // If no window is found, a first window is inserted
606 sal_uInt16 nInsertPos
= 0;
607 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
609 SfxDock_Impl
*pD
= (*pDockArr
)[n
];
613 // A docked window has been found. If no suitable window behind the
614 // the desired insertion point s found, then insertion is done at
618 sal_uInt16 nL
=0, nP
=0;
619 GetWindowPos( pD
->pWin
, nL
, nP
);
621 if ( (nL
== nLine
&& nP
== nPos
) || nL
> nLine
)
623 DBG_ASSERT( nL
== nLine
|| bNewLine
|| nPos
> 0, "Wrong Parameter!" );
624 if ( nL
== nLine
&& nPos
== 0 && !bNewLine
)
626 DBG_ASSERT(pD
->bNewLine
, "No new line?");
628 // The posption is pushed to nPos==0
629 pD
->bNewLine
= sal_False
;
630 pDock
->bNewLine
= sal_True
;
633 nInsertPos
= n
!= 0 ? nLastWindowIdx
+ 1 : 0; // ignore all non-windows after the last window
638 if (nCount
!= 0 && nInsertPos
== nCount
&& nLastWindowIdx
!= nCount
- 1)
640 nInsertPos
= nLastWindowIdx
+ 1; // ignore all non-windows after the last window
643 pDockArr
->Insert(pDock
, nInsertPos
);
644 InsertWindow_Impl( pDock
, rSize
, nLine
, nPos
, bNewLine
);
648 //-------------------------------------------------------------------------
650 void SfxSplitWindow::InsertWindow_Impl( SfxDock_Impl
* pDock
,
652 sal_uInt16 nLine
, sal_uInt16 nPos
, sal_Bool bNewLine
)
656 Adds a DockingWindow, and causes the recalculation of the size of
661 SfxDockingWindow
* pDockWin
= pDock
->pWin
;
663 sal_uInt16 nItemBits
= pDockWin
->GetWinBits_Impl();
665 long nWinSize
, nSetSize
;
666 if ( IsHorizontal() )
668 nWinSize
= rSize
.Width();
669 nSetSize
= rSize
.Height();
673 nSetSize
= rSize
.Width();
674 nWinSize
= rSize
.Height();
677 pDock
->nSize
= nWinSize
;
679 sal_Bool bUpdateMode
= IsUpdateMode();
681 SetUpdateMode( sal_False
);
683 if ( bNewLine
|| nLine
== GetItemCount( 0 ) )
685 // An existing row should not be inserted, instead a new one
689 for ( sal_uInt16 n
=0; n
<GetItemCount(0); n
++ )
691 if ( GetItemId(n
) >= nId
)
692 nId
= GetItemId(n
)+1;
695 // Create a new nLine:th line
696 sal_uInt16 nBits
= nItemBits
;
697 if ( GetAlign() == WINDOWALIGN_TOP
|| GetAlign() == WINDOWALIGN_BOTTOM
)
698 nBits
|= SWIB_COLSET
;
699 InsertItem( nId
, nSetSize
, nLine
, 0, nBits
);
702 // Insert the window at line with the position nline. ItemWindowSize set to
703 // "percentage" share since the SV then does the re-sizing as expected,
704 // "pixel" actually only makes sense if also items with percentage or
705 // relative sizes are present.
706 nItemBits
|= SWIB_PERCENTSIZE
;
708 sal_uInt16 nSet
= GetItemId( nLine
);
709 InsertItem( pDockWin
->GetType(), pDockWin
, nWinSize
, nPos
, nSet
, nItemBits
);
711 // SplitWindows are once created in SFX and when inserting the first
712 // DockingWindows is made visable.
713 if ( GetItemCount( 0 ) == 1 && GetItemCount( 1 ) == 1 )
715 // The Rearranging in WorkWindow and a Show() on the SplitWindow is
716 // caues by SfxDockingwindow (->SfxWorkWindow::ConfigChild_Impl)
717 if ( !bPinned
&& !IsFloatingMode() )
720 sal_Bool bFadeIn
= ( pEmptyWin
->nState
& 2 ) != 0;
721 pEmptyWin
->bFadeIn
= sal_False
;
722 SetPinned_Impl( sal_False
);
723 pEmptyWin
->Actualize();
724 OSL_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
725 pWorkWin
->RegisterChild_Impl( *GetSplitWindow(), eAlign
, sal_True
)->nVisible
= CHILD_VISIBLE
;
726 pWorkWin
->ArrangeChildren_Impl();
732 sal_Bool bFadeIn
= ( pEmptyWin
->nState
& 2 ) != 0;
733 pEmptyWin
->bFadeIn
= sal_False
;
734 pEmptyWin
->Actualize();
736 if ( !bPinned
|| !pEmptyWin
->bFadeIn
)
738 OSL_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
742 OSL_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering real Splitwindow" );
745 pWorkWin
->RegisterChild_Impl( *GetSplitWindow(), eAlign
, sal_True
)->nVisible
= CHILD_VISIBLE
;
746 pWorkWin
->ArrangeChildren_Impl();
751 pWorkWin
->ShowChildren_Impl();
755 SetUpdateMode( sal_True
);
759 //-------------------------------------------------------------------------
761 void SfxSplitWindow::RemoveWindow( SfxDockingWindow
* pDockWin
, sal_Bool bHide
)
765 Removes a DockingWindow. If it was the last one, then the SplitWindow is
769 sal_uInt16 nSet
= GetSet( pDockWin
->GetType() );
771 // SplitWindows are once created in SFX and is made invisible after
772 // removing the last DockingWindows.
773 if ( GetItemCount( nSet
) == 1 && GetItemCount( 0 ) == 1 )
775 // The Rearranging in WorkWindow is caues by SfxDockingwindow
777 pEmptyWin
->aTimer
.Stop();
778 sal_uInt16 nRealState
= pEmptyWin
->nState
;
782 if ( !bPinned
|| !pEmptyWin
->bFadeIn
)
784 OSL_TRACE( "SfxSplitWindow::RemoveWindow - releasing empty Splitwindow" );
788 OSL_TRACE( "SfxSplitWindow::RemoveWindow - releasing real Splitwindow" );
791 pWorkWin
->ReleaseChild_Impl( *GetSplitWindow() );
792 pEmptyWin
->nState
= nRealState
;
793 pWorkWin
->ArrangeAutoHideWindows( this );
796 SfxDock_Impl
*pDock
=0;
797 sal_uInt16 nCount
= pDockArr
->Count();
798 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
800 pDock
= (*pDockArr
)[n
];
801 if ( pDock
->nType
== pDockWin
->GetType() )
804 pDock
->bHide
= bHide
;
809 // Remove Windows, and if it was the last of the line, then also remove
810 // the line (line = itemset)
811 sal_Bool bUpdateMode
= IsUpdateMode();
813 SetUpdateMode( sal_False
);
816 RemoveItem( pDockWin
->GetType() );
818 if ( nSet
&& !GetItemCount( nSet
) )
822 SetUpdateMode( sal_True
);
826 //-------------------------------------------------------------------------
828 sal_Bool
SfxSplitWindow::GetWindowPos( const SfxDockingWindow
* pWindow
,
829 sal_uInt16
& rLine
, sal_uInt16
& rPos
) const
832 Returns the ID of the item sets and items for the DockingWindow in
833 the position passed on the old row / column-name.
837 sal_uInt16 nSet
= GetSet ( pWindow
->GetType() );
838 if ( nSet
== SPLITWINDOW_ITEM_NOTFOUND
)
841 rPos
= GetItemPos( pWindow
->GetType(), nSet
);
842 rLine
= GetItemPos( nSet
);
846 //-------------------------------------------------------------------------
848 sal_Bool
SfxSplitWindow::GetWindowPos( const Point
& rTestPos
,
849 sal_uInt16
& rLine
, sal_uInt16
& rPos
) const
852 Returns the ID of the item sets and items for the DockingWindow in
853 the position passed on the old row / column-name.
857 sal_uInt16 nId
= GetItemId( rTestPos
);
861 sal_uInt16 nSet
= GetSet ( nId
);
862 rPos
= GetItemPos( nId
, nSet
);
863 rLine
= GetItemPos( nSet
);
867 //-------------------------------------------------------------------------
869 sal_uInt16
SfxSplitWindow::GetLineCount() const
873 Returns the number of rows = number of sub-itemsets in the root set.
876 return GetItemCount( 0 );
879 //-------------------------------------------------------------------------
881 long SfxSplitWindow::GetLineSize( sal_uInt16 nLine
) const
885 Returns the Row Height of nline itemset.
888 sal_uInt16 nId
= GetItemId( nLine
);
889 return GetItemSize( nId
);
892 //-------------------------------------------------------------------------
894 sal_uInt16
SfxSplitWindow::GetWindowCount( sal_uInt16 nLine
) const
898 Returns the total number of windows
901 sal_uInt16 nId
= GetItemId( nLine
);
902 return GetItemCount( nId
);
905 //-------------------------------------------------------------------------
907 sal_uInt16
SfxSplitWindow::GetWindowCount() const
911 Returns the total number of windows
914 return GetItemCount( 0 );
917 //-------------------------------------------------------------------------
919 void SfxSplitWindow::Command( const CommandEvent
& rCEvt
)
921 SplitWindow::Command( rCEvt
);
924 //-------------------------------------------------------------------------
926 IMPL_LINK( SfxSplitWindow
, TimerHdl
, Timer
*, pTimer
)
931 if ( CursorIsOverRect( sal_False
) || !pTimer
)
933 // If the cursor is within the window, display the SplitWindow and set
934 // up the timer for close
935 pEmptyWin
->bAutoHide
= sal_True
;
939 pEmptyWin
->aLastPos
= GetPointerPosPixel();
940 pEmptyWin
->aTimer
.Start();
942 else if ( pEmptyWin
->bAutoHide
)
944 if ( GetPointerPosPixel() != pEmptyWin
->aLastPos
)
946 // The mouse has moved within the running time of the timer, thus
948 pEmptyWin
->aLastPos
= GetPointerPosPixel();
949 pEmptyWin
->aTimer
.Start();
953 // Especially for TF_AUTOSHOW_ON_MOUSEMOVE :
954 // If the window is not visible, there is nothing to do
955 // (user has simply moved the mouse over pEmptyWin)
958 pEmptyWin
->bEndAutoHide
= sal_False
;
959 if ( !Application::IsInModalMode() &&
960 !PopupMenu::IsInExecute() &&
961 !pEmptyWin
->bSplit
&& !HasChildPathFocus( sal_True
) )
963 // While a modal dialog or a popup menu is open or while the
964 // Splitting is done, in any case, do not close. Even as long
965 // as one of the Children has the focus, the window remains
967 pEmptyWin
->bEndAutoHide
= sal_True
;
970 if ( pEmptyWin
->bEndAutoHide
)
972 // As far as I am concered this can be the end of AutoShow
973 // But maybe some other SfxSplitWindow will remain open,
974 // then all others remain open too.
975 if ( !pWorkWin
->IsAutoHideMode( this ) )
978 pWorkWin
->ArrangeAutoHideWindows( this );
982 pEmptyWin
->aLastPos
= GetPointerPosPixel();
983 pEmptyWin
->aTimer
.Start();
988 pEmptyWin
->aLastPos
= GetPointerPosPixel();
989 pEmptyWin
->aTimer
.Start();
997 //-------------------------------------------------------------------------
999 sal_Bool
SfxSplitWindow::CursorIsOverRect( sal_Bool bForceAdding
) const
1001 sal_Bool bVisible
= IsVisible();
1003 // Also, take the collapsed SplitWindow into account
1004 Point aPos
= pEmptyWin
->GetParent()->OutputToScreenPixel( pEmptyWin
->GetPosPixel() );
1005 Size aSize
= pEmptyWin
->GetSizePixel();
1009 // Extend with +/- a few pixels, otherwise it is too nervous
1012 aSize
.Width() += 2 * nPixel
;
1013 aSize
.Height() += 2 * nPixel
;
1016 Rectangle
aRect( aPos
, aSize
);
1020 Point aVisPos
= GetPosPixel();
1021 Size aVisSize
= GetSizePixel();
1023 // Extend with +/- a few pixels, otherwise it is too nervous
1024 aVisPos
.X() -= nPixel
;
1025 aVisPos
.Y() -= nPixel
;
1026 aVisSize
.Width() += 2 * nPixel
;
1027 aVisSize
.Height() += 2 * nPixel
;
1029 Rectangle
aVisRect( aVisPos
, aVisSize
);
1030 aRect
= aRect
.GetUnion( aVisRect
);
1033 if ( aRect
.IsInside( OutputToScreenPixel( ((Window
*)this)->GetPointerPosPixel() ) ) )
1038 //-------------------------------------------------------------------------
1040 SplitWindow
* SfxSplitWindow::GetSplitWindow()
1042 if ( !bPinned
|| !pEmptyWin
->bFadeIn
)
1047 //-------------------------------------------------------------------------
1048 sal_Bool
SfxSplitWindow::IsFadeIn() const
1050 return pEmptyWin
->bFadeIn
;
1053 sal_Bool
SfxSplitWindow::IsAutoHide( sal_Bool bSelf
) const
1055 return bSelf
? pEmptyWin
->bAutoHide
&& !pEmptyWin
->bEndAutoHide
: pEmptyWin
->bAutoHide
;
1058 //-------------------------------------------------------------------------
1060 void SfxSplitWindow::SetPinned_Impl( sal_Bool bOn
)
1062 if ( bPinned
== bOn
)
1066 if ( GetItemCount( 0 ) == 0 )
1071 pEmptyWin
->nState
|= 1;
1072 if ( pEmptyWin
->bFadeIn
)
1074 // Unregister replacement windows
1075 OSL_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing real Splitwindow" );
1076 pWorkWin
->ReleaseChild_Impl( *this );
1078 pEmptyWin
->Actualize();
1079 OSL_TRACE( "SfxSplitWindow::SetPinned_Impl - registering empty Splitwindow" );
1080 pWorkWin
->RegisterChild_Impl( *pEmptyWin
, eAlign
, sal_True
)->nVisible
= CHILD_VISIBLE
;
1083 Point
aPos( GetPosPixel() );
1084 aPos
= GetParent()->OutputToScreenPixel( aPos
);
1085 SetFloatingPos( aPos
);
1086 SetFloatingMode( sal_True
);
1087 GetFloatingWindow()->SetOutputSizePixel( GetOutputSizePixel() );
1089 if ( pEmptyWin
->bFadeIn
)
1094 pEmptyWin
->nState
&= ~1;
1095 SetOutputSizePixel( GetFloatingWindow()->GetOutputSizePixel() );
1096 SetFloatingMode( sal_False
);
1098 if ( pEmptyWin
->bFadeIn
)
1100 // Unregister replacement windows
1101 OSL_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing empty Splitwindow" );
1102 pWorkWin
->ReleaseChild_Impl( *pEmptyWin
);
1104 OSL_TRACE( "SfxSplitWindow::SetPinned_Impl - registering real Splitwindow" );
1105 pWorkWin
->RegisterChild_Impl( *this, eAlign
, sal_True
)->nVisible
= CHILD_VISIBLE
;
1109 SetAutoHideState( !bPinned
);
1110 pEmptyWin
->SetAutoHideState( !bPinned
);
1113 //-------------------------------------------------------------------------
1115 void SfxSplitWindow::SetFadeIn_Impl( sal_Bool bOn
)
1117 if ( bOn
== pEmptyWin
->bFadeIn
)
1120 if ( GetItemCount( 0 ) == 0 )
1123 pEmptyWin
->bFadeIn
= bOn
;
1126 pEmptyWin
->nState
|= 2;
1127 if ( IsFloatingMode() )
1129 // FloatingWindow is not visable, thus display it
1130 pWorkWin
->ArrangeAutoHideWindows( this );
1135 OSL_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing empty Splitwindow" );
1136 pWorkWin
->ReleaseChild_Impl( *pEmptyWin
);
1138 OSL_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering real Splitwindow" );
1139 pWorkWin
->RegisterChild_Impl( *this, eAlign
, sal_True
)->nVisible
= CHILD_VISIBLE
;
1140 pWorkWin
->ArrangeChildren_Impl();
1141 pWorkWin
->ShowChildren_Impl();
1146 pEmptyWin
->bAutoHide
= sal_False
;
1147 pEmptyWin
->nState
&= ~2;
1148 if ( !IsFloatingMode() )
1150 // The window is not "floating", should be hidden
1151 OSL_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing real Splitwindow" );
1152 pWorkWin
->ReleaseChild_Impl( *this );
1154 pEmptyWin
->Actualize();
1155 OSL_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering empty Splitwindow" );
1156 pWorkWin
->RegisterChild_Impl( *pEmptyWin
, eAlign
, sal_True
)->nVisible
= CHILD_VISIBLE
;
1157 pWorkWin
->ArrangeChildren_Impl();
1158 pWorkWin
->ShowChildren_Impl();
1159 pWorkWin
->ArrangeAutoHideWindows( this );
1164 pWorkWin
->ArrangeAutoHideWindows( this );
1169 void SfxSplitWindow::AutoHide()
1171 // If this handler is called in the "real" SplitWindow, it is
1172 // either docked and should be displayed as floating, or vice versa
1175 // It "floats", thus dock it again
1176 SetPinned_Impl( sal_True
);
1177 pWorkWin
->ArrangeChildren_Impl();
1182 SetPinned_Impl( sal_False
);
1183 pWorkWin
->ArrangeChildren_Impl();
1184 pWorkWin
->ArrangeAutoHideWindows( this );
1187 pWorkWin
->ShowChildren_Impl();
1191 void SfxSplitWindow::FadeOut_Impl()
1193 if ( pEmptyWin
->aTimer
.IsActive() )
1195 pEmptyWin
->bAutoHide
= sal_False
;
1196 pEmptyWin
->aTimer
.Stop();
1199 SetFadeIn_Impl( sal_False
);
1203 void SfxSplitWindow::FadeOut()
1209 void SfxSplitWindow::FadeIn()
1211 SetFadeIn_Impl( sal_True
);
1215 void SfxSplitWindow::Show_Impl()
1217 sal_uInt16 nCount
= pDockArr
->Count();
1218 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
1220 SfxDock_Impl
*pDock
= (*pDockArr
)[n
];
1222 pDock
->pWin
->FadeIn( pEmptyWin
->bFadeIn
);
1226 sal_Bool
SfxSplitWindow::ActivateNextChild_Impl( sal_Bool bForward
)
1228 // If no pActive, go to first and last window (!bForward is first
1229 // decremented in the loop)
1230 sal_uInt16 nCount
= pDockArr
->Count();
1231 sal_uInt16 n
= bForward
? 0 : nCount
;
1233 // if Focus is within, then move to a window forward or backwards
1237 // Determine the active window
1238 for ( n
=0; n
<nCount
; n
++ )
1240 SfxDock_Impl
*pD
= (*pDockArr
)[n
];
1241 if ( pD
->pWin
&& pD
->pWin
->HasChildPathFocus() )
1246 // up window counter (then when n>nCount, the loop below is
1253 // Search for next window
1254 for ( sal_uInt16 nNext
=n
; nNext
<nCount
; nNext
++ )
1256 SfxDock_Impl
*pD
= (*pDockArr
)[nNext
];
1259 pD
->pWin
->GrabFocus();
1266 // Search for previous window
1267 for ( sal_uInt16 nNext
=n
; nNext
--; )
1269 SfxDock_Impl
*pD
= (*pDockArr
)[nNext
];
1272 pD
->pWin
->GrabFocus();
1281 void SfxSplitWindow::SetActiveWindow_Impl( SfxDockingWindow
* pWin
)
1284 pWorkWin
->SetActiveChild_Impl( this );
1288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */