xref: /AOO41X/main/sfx2/source/dialog/splitwin.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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