xref: /trunk/main/vcl/source/window/splitwin.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <string.h>
32 
33 #include <tools/list.hxx>
34 #include <tools/debug.hxx>
35 #include <tools/rcid.h>
36 
37 #include <vcl/event.hxx>
38 #include <vcl/wall.hxx>
39 #include <vcl/bitmap.hxx>
40 #include <vcl/decoview.hxx>
41 #include <vcl/symbol.hxx>
42 #include <vcl/image.hxx>
43 #include <vcl/help.hxx>
44 #include <vcl/splitwin.hxx>
45 
46 #include <svdata.hxx>
47 #include <svids.hrc>
48 
49 
50 // =======================================================================
51 
52 // Attention: Must not contain non-PODs because array is enlarged/copied
53 // with the use of memmove/memcpy.
54 struct ImplSplitItem
55 {
56     long                mnSize;
57     long                mnPixSize;
58     long                mnLeft;
59     long                mnTop;
60     long                mnWidth;
61     long                mnHeight;
62     long                mnSplitPos;
63     long                mnSplitSize;
64     long                mnOldSplitPos;
65     long                mnOldSplitSize;
66     long                mnOldWidth;
67     long                mnOldHeight;
68     ImplSplitSet*       mpSet;
69     Window*             mpWindow;
70     Window*             mpOrgParent;
71     sal_uInt16              mnId;
72     SplitWindowItemBits mnBits;
73     sal_Bool                mbFixed;
74     sal_Bool                mbSubSize;
75     /// Minimal width or height of the item.  -1 means no restriction.
76     long                mnMinSize;
77     /// Maximal width or height of the item.  -1 means no restriction.
78     long                mnMaxSize;
79 };
80 
81 struct ImplSplitSet
82 {
83     ImplSplitItem*      mpItems;
84     Wallpaper*          mpWallpaper;
85     Bitmap*             mpBitmap;
86     long                mnLastSize;
87     long                mnSplitSize;
88     sal_uInt16              mnItems;
89     sal_uInt16              mnId;
90     sal_Bool                mbCalcPix;
91 };
92 
93 
94 
95 /** Check whether the given size is inside the valid range defined by
96     [rItem.mnMinSize,rItem.mnMaxSize].  When it is not inside it then return
97     the upper or lower bound, respectively. Otherwise return the given size
98     unmodified.
99     Note that either mnMinSize and/or mnMaxSize can be -1 in which case the
100     size has not lower or upper bound.
101 */
102 namespace {
103     long ValidateSize (const long nSize, const ImplSplitItem rItem)
104     {
105         if (rItem.mnMinSize>=0 && nSize<rItem.mnMinSize)
106             return rItem.mnMinSize;
107         else if (rItem.mnMaxSize>0 && nSize>rItem.mnMaxSize)
108             return rItem.mnMaxSize;
109         else
110             return nSize;
111     }
112 }
113 
114 
115 #define SPLITWIN_SPLITSIZE              3
116 #define SPLITWIN_SPLITSIZEEX            4
117 #define SPLITWIN_SPLITSIZEEXLN          6
118 #define SPLITWIN_SPLITSIZEAUTOHIDE      36
119 #define SPLITWIN_SPLITSIZEFADE          36
120 
121 #define SPLIT_HORZ              ((sal_uInt16)0x0001)
122 #define SPLIT_VERT              ((sal_uInt16)0x0002)
123 #define SPLIT_WINDOW            ((sal_uInt16)0x0004)
124 #define SPLIT_NOSPLIT           ((sal_uInt16)0x8000)
125 
126 // -----------------------------------------------------------------------
127 
128 DECLARE_LIST( ImplSplitList, SplitWindow* )
129 
130 // =======================================================================
131 
132 static void ImplCalcBorder( WindowAlign eAlign, sal_Bool bNoAlign,
133                             long& rLeft, long& rTop,
134                             long& rRight, long& rBottom )
135 {
136     if ( bNoAlign )
137     {
138         rLeft   = 2;
139         rTop    = 2;
140         rRight  = 2;
141         rBottom = 2;
142     }
143     else
144     {
145         if ( eAlign == WINDOWALIGN_TOP )
146         {
147             rLeft   = 2;
148             rTop    = 2;
149             rRight  = 2;
150             rBottom = 0;
151         }
152         else if ( eAlign == WINDOWALIGN_LEFT )
153         {
154             rLeft   = 2;
155             rTop    = 2;
156             rRight  = 0;
157             rBottom = 2;
158         }
159         else if ( eAlign == WINDOWALIGN_BOTTOM )
160         {
161             rLeft   = 2;
162             rTop    = 0;
163             rRight  = 2;
164             rBottom = 2;
165         }
166         else
167         {
168             rLeft   = 0;
169             rTop    = 2;
170             rRight  = 2;
171             rBottom = 2;
172         }
173     }
174 }
175 
176 // -----------------------------------------------------------------------
177 
178 void SplitWindow::ImplDrawBorder( SplitWindow* pWin )
179 {
180     const StyleSettings&    rStyleSettings = pWin->GetSettings().GetStyleSettings();
181     long                    nDX = pWin->mnDX;
182     long                    nDY = pWin->mnDY;
183 
184     if ( pWin->mbNoAlign )
185     {
186         DecorationView  aDecoView( pWin );
187         Point           aTmpPoint;
188         Rectangle       aRect( aTmpPoint, Size( nDX, nDY ) );
189         aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
190     }
191     else
192     {/*
193         if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
194         {
195             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
196             pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
197             pWin->SetLineColor( rStyleSettings.GetLightColor() );
198             pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
199         }
200         else
201         {
202             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
203             pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
204             pWin->SetLineColor( rStyleSettings.GetLightColor() );
205             pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
206             if ( (pWin->meAlign == WINDOWALIGN_LEFT) || (pWin->meAlign == WINDOWALIGN_RIGHT) )
207             {
208                 if ( pWin->meAlign == WINDOWALIGN_LEFT )
209                 {
210                     pWin->SetLineColor( rStyleSettings.GetShadowColor() );
211                     pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
212                     pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
213                     pWin->SetLineColor( rStyleSettings.GetLightColor() );
214                     pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
215                     pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
216                 }
217                 else
218                 {
219                     pWin->SetLineColor( rStyleSettings.GetShadowColor() );
220                     pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
221                     pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
222                     pWin->SetLineColor( rStyleSettings.GetLightColor() );
223                     pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
224                     pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
225                 }
226             }
227         }*/
228         if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
229         {
230             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
231             pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
232             pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
233             pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
234 
235             pWin->SetLineColor( rStyleSettings.GetLightColor() );
236             pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
237             pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
238             pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
239         }
240         else if ( pWin->meAlign == WINDOWALIGN_TOP )
241         {
242             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
243             pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
244             pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
245             pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
246 
247             pWin->SetLineColor( rStyleSettings.GetLightColor() );
248             pWin->DrawLine( Point( 1, 1 ), Point( nDX-3, 1 ) );
249             pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-1 ) );
250             pWin->DrawLine( Point( nDX-1, 1 ), Point( nDX-1, nDY-1 ) );
251         }
252         else if ( pWin->meAlign == WINDOWALIGN_LEFT )
253         {
254             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
255             pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
256             pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
257             pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
258 
259             pWin->SetLineColor( rStyleSettings.GetLightColor() );
260             pWin->DrawLine( Point( 1, 1 ), Point( nDX-1, 1 ) );
261             pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
262             pWin->DrawLine( Point( 1, nDY-1 ), Point( nDX-1, nDY-1 ) );
263         }
264         else
265         {
266             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
267             pWin->DrawLine( Point( 0, 0 ), Point( nDX-2, 0 ) );
268             pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
269             pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
270 
271             pWin->SetLineColor( rStyleSettings.GetLightColor() );
272             pWin->DrawLine( Point( 0, 1 ), Point( nDX-3, 1 ) );
273             pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
274             pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
275         }
276     }
277 }
278 
279 // -----------------------------------------------------------------------
280 
281 void SplitWindow::ImplDrawBorderLine( SplitWindow* pWin )
282 {
283     if ( pWin->mbFadeOut || pWin->mbAutoHide )
284     {
285         const StyleSettings&    rStyleSettings = pWin->GetSettings().GetStyleSettings();
286         long                    nDX = pWin->mnDX;
287         long                    nDY = pWin->mnDY;
288 
289         if ( pWin->meAlign == WINDOWALIGN_LEFT )
290         {
291             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
292             pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, nDY-3 ) );
293             pWin->SetLineColor( rStyleSettings.GetLightColor() );
294             pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN, nDY-4 ) );
295         }
296         else if ( pWin->meAlign == WINDOWALIGN_RIGHT )
297         {
298             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
299             pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( SPLITWIN_SPLITSIZEEXLN-1, nDY-3 ) );
300             pWin->SetLineColor( rStyleSettings.GetLightColor() );
301             pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN, 1 ), Point( SPLITWIN_SPLITSIZEEXLN, nDY-4 ) );
302         }
303         else if ( pWin->meAlign == WINDOWALIGN_TOP )
304         {
305             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
306             pWin->DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-3, nDY-SPLITWIN_SPLITSIZEEXLN-1 ) );
307             pWin->SetLineColor( rStyleSettings.GetLightColor() );
308             pWin->DrawLine( Point( 1, nDY-SPLITWIN_SPLITSIZEEXLN ), Point( nDX-4, nDY-SPLITWIN_SPLITSIZEEXLN ) );
309         }
310         else if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
311         {
312             pWin->SetLineColor( rStyleSettings.GetShadowColor() );
313             pWin->DrawLine( Point( 0, SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-3, SPLITWIN_SPLITSIZEEXLN-1 ) );
314             pWin->SetLineColor( rStyleSettings.GetLightColor() );
315             pWin->DrawLine( Point( 1, SPLITWIN_SPLITSIZEEXLN ), Point( nDX-4, SPLITWIN_SPLITSIZEEXLN ) );
316         }
317     }
318 }
319 
320 // -----------------------------------------------------------------------
321 
322 static ImplSplitSet* ImplFindSet( ImplSplitSet* pSet, sal_uInt16 nId )
323 {
324     if ( pSet->mnId == nId )
325         return pSet;
326 
327     sal_uInt16          i;
328     sal_uInt16          nItems = pSet->mnItems;
329     ImplSplitItem*  pItems = pSet->mpItems;
330 
331     for ( i = 0; i < nItems; i++ )
332     {
333         if ( pItems[i].mnId == nId )
334             return pItems[i].mpSet;
335     }
336 
337     for ( i = 0; i < nItems; i++ )
338     {
339         if ( pItems[i].mpSet )
340         {
341             ImplSplitSet* pFindSet = ImplFindSet( pItems[i].mpSet, nId );
342             if ( pFindSet )
343                 return pFindSet;
344         }
345     }
346 
347     return NULL;
348 }
349 
350 // -----------------------------------------------------------------------
351 
352 static ImplSplitSet* ImplFindItem( ImplSplitSet* pSet, sal_uInt16 nId, sal_uInt16& rPos )
353 {
354     sal_uInt16          i;
355     sal_uInt16          nItems = pSet->mnItems;
356     ImplSplitItem*  pItems = pSet->mpItems;
357 
358     for ( i = 0; i < nItems; i++ )
359     {
360         if ( pItems[i].mnId == nId )
361         {
362             rPos = i;
363             return pSet;
364         }
365     }
366 
367     for ( i = 0; i < nItems; i++ )
368     {
369         if ( pItems[i].mpSet )
370         {
371             ImplSplitSet* pFindSet = ImplFindItem( pItems[i].mpSet, nId, rPos );
372             if ( pFindSet )
373                 return pFindSet;
374         }
375     }
376 
377     return NULL;
378 }
379 
380 // -----------------------------------------------------------------------
381 
382 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, Window* pWindow )
383 {
384     sal_uInt16          i;
385     sal_uInt16          nItems = pSet->mnItems;
386     ImplSplitItem*  pItems = pSet->mpItems;
387 
388     for ( i = 0; i < nItems; i++ )
389     {
390         if ( pItems[i].mpWindow == pWindow )
391             return pItems[i].mnId;
392         else
393         {
394             if ( pItems[i].mpSet )
395             {
396                 sal_uInt16 nId = ImplFindItem( pItems[i].mpSet, pWindow );
397                 if ( nId )
398                     return nId;
399             }
400         }
401     }
402 
403     return 0;
404 }
405 
406 // -----------------------------------------------------------------------
407 
408 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, const Point& rPos,
409                             sal_Bool bRows, sal_Bool bDown = sal_True )
410 {
411     sal_uInt16          i;
412     sal_uInt16          nItems = pSet->mnItems;
413     ImplSplitItem*  pItems = pSet->mpItems;
414 
415     for ( i = 0; i < nItems; i++ )
416     {
417         if ( pItems[i].mnWidth && pItems[i].mnHeight )
418         {
419             // Wegen ICC auftrennen
420             Point       aPoint( pItems[i].mnLeft, pItems[i].mnTop );
421             Size        aSize( pItems[i].mnWidth, pItems[i].mnHeight );
422             Rectangle   aRect( aPoint, aSize );
423             if ( bRows )
424             {
425                 if ( bDown )
426                     aRect.Bottom() += pSet->mnSplitSize;
427                 else
428                     aRect.Top() -= pSet->mnSplitSize;
429             }
430             else
431             {
432                 if ( bDown )
433                     aRect.Right() += pSet->mnSplitSize;
434                 else
435                     aRect.Left() -= pSet->mnSplitSize;
436             }
437 
438             if ( aRect.IsInside( rPos ) )
439             {
440                 if ( pItems[i].mpSet && pItems[i].mpSet->mpItems )
441                 {
442                     return ImplFindItem( pItems[i].mpSet, rPos,
443                                         ((pItems[i].mnBits & SWIB_COLSET) == 0) );
444                 }
445                 else
446                     return pItems[i].mnId;
447             }
448         }
449     }
450 
451     return 0;
452 }
453 
454 // -----------------------------------------------------------------------
455 
456 static void ImplDeleteSet( ImplSplitSet* pSet )
457 {
458     sal_uInt16          i;
459     sal_uInt16          nItems = pSet->mnItems;
460     ImplSplitItem*  pItems = pSet->mpItems;
461 
462     for ( i = 0; i < nItems; i++ )
463     {
464         if ( pItems[i].mpSet )
465             ImplDeleteSet( pItems[i].mpSet );
466     }
467 
468     if ( pSet->mpWallpaper )
469         delete pSet->mpWallpaper;
470 
471     if ( pSet->mpBitmap )
472         delete pSet->mpBitmap;
473 
474     delete [] pItems;
475     delete pSet;
476 }
477 
478 // -----------------------------------------------------------------------
479 
480 static void ImplSetSplitSize( ImplSplitSet* pSet, long nNewSize )
481 {
482     pSet->mnSplitSize = nNewSize;
483     for ( sal_uInt16 i = 0; i < pSet->mnItems; i++ )
484     {
485         if ( pSet->mpItems[i].mpSet )
486             ImplSetSplitSize( pSet->mpItems[i].mpSet, nNewSize );
487     }
488 }
489 
490 // -----------------------------------------------------------------------
491 
492 static void ImplCalcSet( ImplSplitSet* pSet,
493                          long nSetLeft, long nSetTop,
494                          long nSetWidth, long nSetHeight,
495                          sal_Bool bRows, sal_Bool bDown = sal_True )
496 {
497     if ( !pSet->mpItems )
498         return;
499 
500     sal_uInt16              i;
501     sal_uInt16              j;
502     sal_uInt16              nMins;
503     sal_uInt16              nCalcItems;
504     sal_uInt16              nItems = pSet->mnItems;
505     sal_uInt16              nVisItems;
506     sal_uInt16              nAbsItems;
507     long                nCalcSize;
508     long                nSizeDelta;
509     long                nCurSize;
510     long                nSizeWinSize;
511     long                nNewSizeWinSize;
512     long                nTemp;
513     long                nTempErr;
514     long                nErrorSum;
515     long                nCurSizeDelta;
516     long                nPos;
517     long                nMaxPos;
518     long*               pSize;
519     ImplSplitItem*      pItems = pSet->mpItems;
520     sal_Bool                bEmpty;
521 
522     // Anzahl sichtbarer Items ermitteln
523     nVisItems = 0;
524     for ( i = 0; i < nItems; i++ )
525     {
526         if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
527             nVisItems++;
528     }
529 
530     // Groessen berechnen
531     if ( bRows )
532         nCalcSize = nSetHeight;
533     else
534         nCalcSize = nSetWidth;
535     nCalcSize -= (nVisItems-1)*pSet->mnSplitSize;
536     nCurSize   = 0;
537     if ( pSet->mbCalcPix || (pSet->mnLastSize != nCalcSize) )
538     {
539         long nPercentFactor = 10;
540         long nRelCount      = 0;
541         long nPercent       = 0;
542         long nRelPercent    = 0;
543         long nAbsSize       = 0;
544         for ( i = 0; i < nItems; i++ )
545         {
546             if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
547             {
548                 if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
549                     nRelCount += pItems[i].mnSize;
550                 else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
551                     nPercent += pItems[i].mnSize;
552                 else
553                     nAbsSize += pItems[i].mnSize;
554             }
555         }
556         // Relative-Werte auf prozentual mappen (Percent bei uns 10tel Prozent)
557         nPercent *= nPercentFactor;
558         if ( nRelCount )
559         {
560             long nRelPercentBase = 1000;
561             while ( (nRelCount > nRelPercentBase) && (nPercentFactor < 100000) )
562             {
563                 nRelPercentBase *= 10;
564                 nPercentFactor *= 10;
565             }
566             if ( nPercent < nRelPercentBase )
567             {
568                 nRelPercent = (nRelPercentBase-nPercent)/nRelCount;
569                 nPercent += nRelPercent*nRelCount;
570             }
571             else
572                 nRelPercent = 0;
573         }
574         if ( !nPercent )
575             nPercent = 1;
576         nSizeDelta = nCalcSize-nAbsSize;
577         for ( i = 0; i < nItems; i++ )
578         {
579             if ( pItems[i].mnBits & SWIB_INVISIBLE )
580                 pItems[i].mnPixSize = 0;
581             else if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
582             {
583                 if ( nSizeDelta <= 0 )
584                     pItems[i].mnPixSize = 0;
585                 else
586                     pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nRelPercent)/nPercent;
587             }
588             else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
589             {
590                 if ( nSizeDelta <= 0 )
591                     pItems[i].mnPixSize = 0;
592                 else
593                     pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nPercentFactor)/nPercent;
594             }
595             else
596                 pItems[i].mnPixSize = pItems[i].mnSize;
597             nCurSize += pItems[i].mnPixSize;
598         }
599 
600         pSet->mbCalcPix  = sal_False;
601         pSet->mnLastSize = nCalcSize;
602 
603         // Fenster einpassen
604         nSizeDelta  = nCalcSize-nCurSize;
605         if ( nSizeDelta )
606         {
607             nAbsItems       = 0;
608             nSizeWinSize    = 0;
609             nNewSizeWinSize = 0;
610 
611             // Zuerst die absoluten Items relativ resizen
612             for ( i = 0; i < nItems; i++ )
613             {
614                 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
615                 {
616                     if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
617                     {
618                         nAbsItems++;
619                         nSizeWinSize += pItems[i].mnPixSize;
620                     }
621                 }
622             }
623             // Rundungsfehler werden hier nicht ausgelichen
624             if ( (nAbsItems < (sal_uInt16)(Abs( nSizeDelta ))) && nSizeWinSize )
625             {
626                 for ( i = 0; i < nItems; i++ )
627                 {
628                     if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
629                     {
630                         if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
631                         {
632                             pItems[i].mnPixSize += (nSizeDelta*pItems[i].mnPixSize)/nSizeWinSize;
633                             nNewSizeWinSize += pItems[i].mnPixSize;
634                         }
635                     }
636                 }
637                 nSizeDelta -= nNewSizeWinSize-nSizeWinSize;
638             }
639 
640             // Jetzt die Rundunsfehler ausgleichen
641             j           = 0;
642             nMins       = 0;
643             while ( nSizeDelta && (nItems != nMins) )
644             {
645                 // Feststellen, welche Items berechnet werden duerfen
646                 nCalcItems = 0;
647                 while ( !nCalcItems )
648                 {
649                     for ( i = 0; i < nItems; i++ )
650                     {
651                         pItems[i].mbSubSize = sal_False;
652 
653                         if ( j >= 2 )
654                             pItems[i].mbSubSize = sal_True;
655                         else
656                         {
657                             if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
658                             {
659                                 if ( (nSizeDelta > 0) || pItems[i].mnPixSize )
660                                 {
661                                     if ( j >= 1 )
662                                         pItems[i].mbSubSize = sal_True;
663                                     else
664                                     {
665                                         if ( (j == 0) && (pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
666                                             pItems[i].mbSubSize = sal_True;
667                                     }
668                                 }
669                             }
670                         }
671 
672                         if ( pItems[i].mbSubSize )
673                             nCalcItems++;
674                     }
675 
676                     j++;
677                 }
678 
679                 // Groessen von den einzelnen Items abziehen
680                 nErrorSum       = nSizeDelta % nCalcItems;
681                 nCurSizeDelta   = nSizeDelta / nCalcItems;
682                 nMins           = 0;
683                 for ( i = 0; i < nItems; i++ )
684                 {
685                     if ( pItems[i].mnBits & SWIB_INVISIBLE )
686                         nMins++;
687                     else if ( pItems[i].mbSubSize )
688                     {
689                         pSize = &(pItems[i].mnPixSize);
690 
691                         if ( nErrorSum )
692                         {
693                             if ( nErrorSum < 0 )
694                                 nTempErr = -1;
695                             else
696                                 nTempErr = 1;
697                         }
698                         else
699                             nTempErr = 0;
700 
701                         if ( (*pSize+nCurSizeDelta+nTempErr) <= 0 )
702                         {
703                             nTemp = *pSize;
704                             if ( nTemp )
705                             {
706                                 *pSize -= nTemp;
707                                 nSizeDelta += nTemp;
708                             }
709                             nMins++;
710                         }
711                         else
712                         {
713                             *pSize += nCurSizeDelta;
714                             nSizeDelta -= nCurSizeDelta;
715                             if ( nTempErr && (*pSize || (nTempErr > 0)) )
716                             {
717                                 *pSize += nTempErr;
718                                 nSizeDelta -= nTempErr;
719                                 nErrorSum -= nTempErr;
720                             }
721                         }
722                     }
723                 }
724             }
725         }
726     }
727     else
728     {
729         for ( i = 0; i < nItems; i++ )
730         {
731             if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
732                 nCurSize += pItems[i].mnPixSize;
733         }
734     }
735 
736     // Maximale Groesse berechnen
737     if ( bRows )
738     {
739         nPos = nSetTop;
740         if ( !bDown )
741             nMaxPos = nSetTop-nSetHeight;
742         else
743             nMaxPos = nSetTop+nSetHeight;
744     }
745     else
746     {
747         nPos = nSetLeft;
748         if ( !bDown )
749             nMaxPos = nSetLeft-nSetWidth;
750         else
751             nMaxPos = nSetLeft+nSetWidth;
752     }
753 
754     // Fenster anordnen und Werte anpassen
755     for ( i = 0; i < nItems; i++ )
756     {
757         pItems[i].mnOldSplitPos    = pItems[i].mnSplitPos;
758         pItems[i].mnOldSplitSize   = pItems[i].mnSplitSize;
759         pItems[i].mnOldWidth       = pItems[i].mnWidth;
760         pItems[i].mnOldHeight      = pItems[i].mnHeight;
761 
762         if ( pItems[i].mnBits & SWIB_INVISIBLE )
763             bEmpty = sal_True;
764         else
765         {
766             bEmpty = sal_False;
767             if ( bDown )
768             {
769                 if ( nPos+pItems[i].mnPixSize > nMaxPos )
770                     bEmpty = sal_True;
771             }
772             else
773             {
774                 nPos -= pItems[i].mnPixSize;
775                 if ( nPos < nMaxPos )
776                     bEmpty = sal_True;
777             }
778         }
779 
780         if ( bEmpty )
781         {
782             pItems[i].mnWidth     = 0;
783             pItems[i].mnHeight    = 0;
784             pItems[i].mnSplitSize = 0;
785         }
786         else
787         {
788             if ( bRows )
789             {
790                 pItems[i].mnLeft   = nSetLeft;
791                 pItems[i].mnTop    = nPos;
792                 pItems[i].mnWidth  = nSetWidth;
793                 pItems[i].mnHeight = pItems[i].mnPixSize;
794             }
795             else
796             {
797                 pItems[i].mnLeft   = nPos;
798                 pItems[i].mnTop    = nSetTop;
799                 pItems[i].mnWidth  = pItems[i].mnPixSize;
800                 pItems[i].mnHeight = nSetHeight;
801             }
802 
803             if ( i > nItems-1 )
804                 pItems[i].mnSplitSize = 0;
805             else
806             {
807                 pItems[i].mnSplitSize = pSet->mnSplitSize;
808                 if ( bDown )
809                 {
810                     pItems[i].mnSplitPos  = nPos+pItems[i].mnPixSize;
811                     if ( pItems[i].mnSplitPos+pItems[i].mnSplitSize > nMaxPos )
812                         pItems[i].mnSplitSize = nMaxPos-pItems[i].mnSplitPos;
813                 }
814                 else
815                 {
816                     pItems[i].mnSplitPos = nPos-pSet->mnSplitSize;
817                     if ( pItems[i].mnSplitPos < nMaxPos )
818                         pItems[i].mnSplitSize = pItems[i].mnSplitPos+pSet->mnSplitSize-nMaxPos;
819                 }
820             }
821         }
822 
823         if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
824         {
825             if ( !bDown )
826                 nPos -= pSet->mnSplitSize;
827             else
828                 nPos += pItems[i].mnPixSize+pSet->mnSplitSize;
829         }
830     }
831 
832     // Sub-Set's berechnen
833     for ( i = 0; i < nItems; i++ )
834     {
835         if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
836         {
837             ImplCalcSet( pItems[i].mpSet,
838                          pItems[i].mnLeft, pItems[i].mnTop,
839                          pItems[i].mnWidth, pItems[i].mnHeight,
840                          ((pItems[i].mnBits & SWIB_COLSET) == 0) );
841         }
842     }
843 
844     // Fixed setzen
845     for ( i = 0; i < nItems; i++ )
846     {
847         pItems[i].mbFixed = sal_False;
848         if ( pItems[i].mnBits & SWIB_FIXED )
849             pItems[i].mbFixed = sal_True;
850         else
851         {
852             // Wenn Child-Set vorhanden, ist dieses Item auch Fixed, wenn
853             // ein Child fixed ist
854             if ( pItems[i].mpSet )
855             {
856                 for ( j = 0; j < pItems[i].mpSet->mnItems; j++ )
857                 {
858                     if ( pItems[i].mpSet->mpItems[j].mbFixed )
859                     {
860                         pItems[i].mbFixed = sal_True;
861                         break;
862                     }
863                 }
864             }
865         }
866     }
867 }
868 
869 // -----------------------------------------------------------------------
870 
871 void SplitWindow::ImplCalcSet2( SplitWindow* pWindow, ImplSplitSet* pSet, sal_Bool bHide,
872                                 sal_Bool bRows, sal_Bool /*bDown*/ )
873 {
874     sal_uInt16          i;
875     sal_uInt16          nItems = pSet->mnItems;
876     ImplSplitItem*  pItems = pSet->mpItems;
877 
878     if ( pWindow->IsReallyVisible() && pWindow->IsUpdateMode() && pWindow->mbInvalidate )
879     {
880         for ( i = 0; i < nItems; i++ )
881         {
882             if ( pItems[i].mnSplitSize )
883             {
884                 // Evt. alles invalidieren oder nur einen kleinen Teil
885                 if ( (pItems[i].mnOldSplitPos  != pItems[i].mnSplitPos)  ||
886                      (pItems[i].mnOldSplitSize != pItems[i].mnSplitSize) ||
887                      (pItems[i].mnOldWidth     != pItems[i].mnWidth)     ||
888                      (pItems[i].mnOldHeight    != pItems[i].mnHeight) )
889                 {
890                     Rectangle aRect;
891 
892                     // Old Rect invalidieren
893                     if ( bRows )
894                     {
895                         aRect.Left()    = pItems[i].mnLeft;
896                         aRect.Right()   = pItems[i].mnLeft+pItems[i].mnOldWidth-1;
897                         aRect.Top()     = pItems[i].mnOldSplitPos;
898                         aRect.Bottom()  = aRect.Top() + pItems[i].mnOldSplitSize;
899                     }
900                     else
901                     {
902                         aRect.Top()     = pItems[i].mnTop;
903                         aRect.Bottom()  = pItems[i].mnTop+pItems[i].mnOldHeight-1;
904                         aRect.Left()    = pItems[i].mnOldSplitPos;
905                         aRect.Right()   = aRect.Left() + pItems[i].mnOldSplitSize;
906                     }
907                     pWindow->Invalidate( aRect );
908                     // New Rect invalidieren
909                     if ( bRows )
910                     {
911                         aRect.Left()    = pItems[i].mnLeft;
912                         aRect.Right()   = pItems[i].mnLeft+pItems[i].mnWidth-1;
913                         aRect.Top()     = pItems[i].mnSplitPos;
914                         aRect.Bottom()  = aRect.Top() + pItems[i].mnSplitSize;
915                     }
916                     else
917                     {
918                         aRect.Top()     = pItems[i].mnTop;
919                         aRect.Bottom()  = pItems[i].mnTop+pItems[i].mnHeight-1;
920                         aRect.Left()    = pItems[i].mnSplitPos;
921                         aRect.Right()   = aRect.Left() + pItems[i].mnSplitSize;
922                     }
923                     pWindow->Invalidate( aRect );
924 
925                     // Leere Sets komplett invalidieren, da diese Flaechen
926                     // nicht von Fenstern ueberladen werden
927                     if ( pItems[i].mpSet && !pItems[i].mpSet->mpItems )
928                     {
929                         aRect.Left()    = pItems[i].mnLeft;
930                         aRect.Top()     = pItems[i].mnTop;
931                         aRect.Right()   = pItems[i].mnLeft+pItems[i].mnWidth-1;
932                         aRect.Bottom()  = pItems[i].mnTop+pItems[i].mnHeight-1;
933                         pWindow->Invalidate( aRect );
934                     }
935                 }
936             }
937         }
938     }
939 
940     // Fenster positionieren
941     for ( i = 0; i < nItems; i++ )
942     {
943         if ( pItems[i].mpSet )
944         {
945             sal_Bool bTempHide = bHide;
946             if ( !pItems[i].mnWidth || !pItems[i].mnHeight )
947                 bTempHide = sal_True;
948             ImplCalcSet2( pWindow, pItems[i].mpSet, bTempHide,
949                           ((pItems[i].mnBits & SWIB_COLSET) == 0) );
950         }
951         else
952         {
953             if ( pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
954             {
955                 Point aPos( pItems[i].mnLeft, pItems[i].mnTop );
956                 Size  aSize( pItems[i].mnWidth, pItems[i].mnHeight );
957                 pItems[i].mpWindow->SetPosSizePixel( aPos, aSize );
958             }
959             else
960                 pItems[i].mpWindow->Hide();
961         }
962     }
963 
964     // Fenster anzeigen und Flag zuruecksetzen
965     for ( i = 0; i < nItems; i++ )
966     {
967         if ( pItems[i].mpWindow && pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
968             pItems[i].mpWindow->Show();
969     }
970 }
971 
972 // -----------------------------------------------------------------------
973 
974 static void ImplCalcLogSize( ImplSplitItem* pItems, sal_uInt16 nItems )
975 {
976     // Original-Groessen updaten
977     sal_uInt16  i;
978     long    nRelSize = 0;
979     long    nPerSize = 0;
980     for ( i = 0; i < nItems; i++ )
981     {
982         if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
983             nRelSize += pItems[i].mnPixSize;
984         else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
985             nPerSize += pItems[i].mnPixSize;
986     }
987     nPerSize += nRelSize;
988     for ( i = 0; i < nItems; i++ )
989     {
990         if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
991         {
992             if ( nRelSize )
993                 pItems[i].mnSize = (pItems[i].mnPixSize+(nRelSize/2))/nRelSize;
994             else
995                 pItems[i].mnSize = 1;
996         }
997         else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
998         {
999             if ( nPerSize )
1000                 pItems[i].mnSize = (pItems[i].mnPixSize*100)/nPerSize;
1001             else
1002                 pItems[i].mnSize = 1;
1003         }
1004         else
1005             pItems[i].mnSize = pItems[i].mnPixSize;
1006     }
1007 }
1008 
1009 // -----------------------------------------------------------------------
1010 
1011 void SplitWindow::ImplDrawBack( SplitWindow* pWindow, const Rectangle& rRect,
1012                                 const Wallpaper* pWall, const Bitmap* pBitmap )
1013 {
1014     if ( pBitmap )
1015     {
1016         Point   aPos = rRect.TopLeft();
1017         Size    aBmpSize = pBitmap->GetSizePixel();
1018         pWindow->Push( PUSH_CLIPREGION );
1019         pWindow->IntersectClipRegion( rRect );
1020         do
1021         {
1022             aPos.X() = rRect.Left();
1023             do
1024             {
1025                 pWindow->DrawBitmap( aPos, *pBitmap );
1026                 aPos.X() += aBmpSize.Width();
1027             }
1028             while ( aPos.X() < rRect.Right() );
1029             aPos.Y() += aBmpSize.Height();
1030         }
1031         while ( aPos.Y() < rRect.Bottom() );
1032         pWindow->Pop();
1033     }
1034     else
1035         pWindow->DrawWallpaper( rRect, *pWall );
1036 }
1037 
1038 // -----------------------------------------------------------------------
1039 
1040 void SplitWindow::ImplDrawBack( SplitWindow* pWindow, ImplSplitSet* pSet )
1041 {
1042     sal_uInt16          i;
1043     sal_uInt16          nItems = pSet->mnItems;
1044     ImplSplitItem*  pItems = pSet->mpItems;
1045 
1046     // Beim Mainset auch den Hintergrund zeichnen
1047     if ( pSet->mnId == 0 )
1048     {
1049         if ( pSet->mpBitmap )
1050         {
1051             Rectangle aRect( pWindow->mnLeftBorder,
1052                              pWindow->mnTopBorder,
1053                              pWindow->mnDX-pWindow->mnRightBorder-1,
1054                              pWindow->mnDY-pWindow->mnBottomBorder-1 );
1055             ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
1056         }
1057     }
1058 
1059     for ( i = 0; i < nItems; i++ )
1060     {
1061         pSet = pItems[i].mpSet;
1062         if ( pSet )
1063         {
1064             if ( pSet->mpBitmap || pSet->mpWallpaper )
1065             {
1066                 // Wegen ICC auftrennen
1067                 Point       aPoint( pItems[i].mnLeft, pItems[i].mnTop );
1068                 Size        aSize( pItems[i].mnWidth, pItems[i].mnHeight );
1069                 Rectangle   aRect( aPoint, aSize );
1070                 ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
1071             }
1072         }
1073     }
1074 
1075     for ( i = 0; i < nItems; i++ )
1076     {
1077         if ( pItems[i].mpSet )
1078             ImplDrawBack( pWindow, pItems[i].mpSet );
1079     }
1080 }
1081 
1082 // -----------------------------------------------------------------------
1083 
1084 static void ImplDrawSplit( SplitWindow* pWindow, ImplSplitSet* pSet,
1085                            sal_Bool bRows, sal_Bool bDown = sal_True )
1086 {
1087     if ( !pSet->mpItems )
1088         return;
1089 
1090     sal_uInt16                  i;
1091     sal_uInt16                  nItems = pSet->mnItems;
1092     long                    nPos;
1093     long                    nTop;
1094     long                    nBottom;
1095     ImplSplitItem*          pItems = pSet->mpItems;
1096     const StyleSettings&    rStyleSettings = pWindow->GetSettings().GetStyleSettings();
1097 
1098     sal_Bool bFlat = (pWindow->GetStyle() & WB_FLATSPLITDRAW) == WB_FLATSPLITDRAW;
1099 
1100     for ( i = 0; i < nItems-1; i++ )
1101     {
1102         if ( pItems[i].mnSplitSize )
1103         {
1104             nPos = pItems[i].mnSplitPos;
1105 
1106             long nItemSplitSize = pItems[i].mnSplitSize;
1107             long nSplitSize = pSet->mnSplitSize;
1108             if ( bRows )
1109             {
1110                 nTop    = pItems[i].mnLeft;
1111                 nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
1112 
1113                 if ( bFlat ) nPos--;
1114 
1115                 if ( bDown || (nItemSplitSize >= nSplitSize) )
1116                 {
1117                     pWindow->SetLineColor( rStyleSettings.GetLightColor() );
1118                     pWindow->DrawLine( Point( nTop, nPos+1 ), Point( nBottom, nPos+1 ) );
1119                 }
1120                 nPos += nSplitSize-2;
1121                 if ( bFlat ) nPos+=2;
1122                 if ( (!bDown && (nItemSplitSize >= 2)) ||
1123                      (bDown  && (nItemSplitSize >= nSplitSize-1)) )
1124                 {
1125                     pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
1126                     pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
1127                 }
1128                 if ( !bFlat )
1129                 {
1130                     nPos++;
1131                     if ( !bDown || (nItemSplitSize >= nSplitSize) )
1132                     {
1133                         pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
1134                         pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
1135                     }
1136                 }
1137             }
1138             else
1139             {
1140                 nTop    = pItems[i].mnTop;
1141                 nBottom = pItems[i].mnTop+pSet->mpItems[i].mnHeight-1;
1142 
1143                 if ( bFlat ) nPos--;
1144                 if ( bDown || (nItemSplitSize >= nSplitSize) )
1145                 {
1146                     pWindow->SetLineColor( rStyleSettings.GetLightColor() );
1147                     pWindow->DrawLine( Point( nPos+1, nTop ), Point( nPos+1, nBottom ) );
1148                 }
1149                 nPos += pSet->mnSplitSize-2;
1150                 if ( bFlat ) nPos+=2;
1151                 if ( (!bDown && (nItemSplitSize >= 2)) ||
1152                      (bDown  && (nItemSplitSize >= nSplitSize-1)) )
1153                 {
1154                     pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
1155                     pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
1156                 }
1157                 if( !bFlat )
1158                 {
1159                     nPos++;
1160                     if ( !bDown || (nItemSplitSize >= nSplitSize) )
1161                     {
1162                         pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
1163                         pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
1164                     }
1165                 }
1166             }
1167         }
1168     }
1169 
1170     for ( i = 0; i < nItems; i++ )
1171     {
1172         if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
1173             ImplDrawSplit( pWindow, pItems[i].mpSet, ((pItems[i].mnBits & SWIB_COLSET) == 0) );
1174     }
1175 }
1176 
1177 // -----------------------------------------------------------------------
1178 
1179 sal_uInt16 SplitWindow::ImplTestSplit( ImplSplitSet* pSet, const Point& rPos,
1180                                    long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos,
1181                                    sal_Bool bRows, sal_Bool /*bDown*/ )
1182 {
1183     if ( !pSet->mpItems )
1184         return 0;
1185 
1186     sal_uInt16          i;
1187     sal_uInt16          nSplitTest;
1188     sal_uInt16          nItems = pSet->mnItems;
1189     long            nMPos1;
1190     long            nMPos2;
1191     long            nPos;
1192     long            nTop;
1193     long            nBottom;
1194     ImplSplitItem*   pItems = pSet->mpItems;
1195 
1196     if ( bRows )
1197     {
1198         nMPos1 = rPos.X();
1199         nMPos2 = rPos.Y();
1200     }
1201     else
1202     {
1203         nMPos1 = rPos.Y();
1204         nMPos2 = rPos.X();
1205     }
1206 
1207     for ( i = 0; i < nItems-1; i++ )
1208     {
1209         if ( pItems[i].mnSplitSize )
1210         {
1211             if ( bRows )
1212             {
1213                 nTop    = pItems[i].mnLeft;
1214                 nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
1215             }
1216             else
1217             {
1218                 nTop    = pItems[i].mnTop;
1219                 nBottom = pItems[i].mnTop+pItems[i].mnHeight-1;
1220             }
1221             nPos = pItems[i].mnSplitPos;
1222 
1223             if ( (nMPos1 >= nTop) && (nMPos1 <= nBottom) &&
1224                  (nMPos2 >= nPos) && (nMPos2 <= nPos+pItems[i].mnSplitSize) )
1225             {
1226                 if ( !pItems[i].mbFixed && !pItems[i+1].mbFixed )
1227                 {
1228                     rMouseOff = nMPos2-nPos;
1229                     *ppFoundSet = pSet;
1230                     rFoundPos = i;
1231                     if ( bRows )
1232                         return SPLIT_VERT;
1233                     else
1234                         return SPLIT_HORZ;
1235                 }
1236                 else
1237                     return SPLIT_NOSPLIT;
1238             }
1239         }
1240     }
1241 
1242     for ( i = 0; i < nItems; i++ )
1243     {
1244         if ( pItems[i].mpSet )
1245         {
1246             nSplitTest = ImplTestSplit( pItems[i].mpSet, rPos,
1247                                        rMouseOff, ppFoundSet, rFoundPos,
1248                                        ((pItems[i].mnBits & SWIB_COLSET) == 0) );
1249             if ( nSplitTest )
1250                 return nSplitTest;
1251         }
1252     }
1253 
1254     return 0;
1255 }
1256 
1257 // -----------------------------------------------------------------------
1258 
1259 sal_uInt16 SplitWindow::ImplTestSplit( SplitWindow* pWindow, const Point& rPos,
1260                                    long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos )
1261 {
1262     // Resizeable SplitWindow muss anders behandelt werden
1263     if ( pWindow->mnWinStyle & WB_SIZEABLE )
1264     {
1265         long    nTPos;
1266         long    nPos;
1267         long    nBorder;
1268 
1269         if ( pWindow->mbHorz )
1270         {
1271             if ( pWindow->mbBottomRight )
1272             {
1273                 nBorder = pWindow->mnBottomBorder;
1274                 nPos = 0;
1275             }
1276             else
1277             {
1278                 nBorder = pWindow->mnTopBorder;
1279                 nPos = pWindow->mnDY-nBorder;
1280             }
1281             nTPos = rPos.Y();
1282         }
1283         else
1284         {
1285             if ( pWindow->mbBottomRight )
1286             {
1287                 nBorder = pWindow->mnRightBorder;
1288                 nPos = 0;
1289             }
1290             else
1291             {
1292                 nBorder = pWindow->mnLeftBorder;
1293                 nPos = pWindow->mnDX-nBorder;
1294             }
1295             nTPos = rPos.X();
1296         }
1297         long nSplitSize = pWindow->mpMainSet->mnSplitSize-2;
1298         if ( pWindow->mbAutoHide || pWindow->mbFadeOut )
1299             nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1300         if ( !pWindow->mbBottomRight )
1301             nPos -= nSplitSize;
1302         if ( (nTPos >= nPos) && (nTPos <= nPos+nSplitSize+nBorder) )
1303         {
1304             rMouseOff = nTPos-nPos;
1305             *ppFoundSet = pWindow->mpMainSet;
1306             if ( pWindow->mpMainSet->mpItems )
1307                 rFoundPos = pWindow->mpMainSet->mnItems-1;
1308             else
1309                 rFoundPos = 0;
1310             if ( pWindow->mbHorz )
1311                 return SPLIT_VERT | SPLIT_WINDOW;
1312             else
1313                 return SPLIT_HORZ | SPLIT_WINDOW;
1314         }
1315     }
1316 
1317     return ImplTestSplit( pWindow->mpMainSet, rPos, rMouseOff, ppFoundSet, rFoundPos,
1318                          pWindow->mbHorz, !pWindow->mbBottomRight );
1319 }
1320 
1321 // -----------------------------------------------------------------------
1322 
1323 void SplitWindow::ImplDrawSplitTracking( SplitWindow* pThis, const Point& rPos )
1324 {
1325     Rectangle aRect;
1326 
1327     if ( pThis->mnSplitTest & SPLIT_HORZ )
1328     {
1329         aRect.Top()    = pThis->maDragRect.Top();
1330         aRect.Bottom() = pThis->maDragRect.Bottom();
1331         aRect.Left()   = rPos.X();
1332         aRect.Right()  = aRect.Left()+pThis->mpSplitSet->mnSplitSize-1;
1333         if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
1334             aRect.Right()--;
1335         if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
1336              (pThis->mbAutoHide || pThis->mbFadeOut) )
1337         {
1338             aRect.Left()  += SPLITWIN_SPLITSIZEEXLN;
1339             aRect.Right() += SPLITWIN_SPLITSIZEEXLN;
1340         }
1341     }
1342     else
1343     {
1344         aRect.Left()    = pThis->maDragRect.Left();
1345         aRect.Right()   = pThis->maDragRect.Right();
1346         aRect.Top()     = rPos.Y();
1347         aRect.Bottom()  = aRect.Top()+pThis->mpSplitSet->mnSplitSize-1;
1348         if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
1349             aRect.Bottom()--;
1350         if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
1351              (pThis->mbAutoHide || pThis->mbFadeOut) )
1352         {
1353             aRect.Top()    += SPLITWIN_SPLITSIZEEXLN;
1354             aRect.Bottom() += SPLITWIN_SPLITSIZEEXLN;
1355         }
1356     }
1357     pThis->ShowTracking( aRect, SHOWTRACK_SPLIT );
1358 }
1359 
1360 // -----------------------------------------------------------------------
1361 
1362 void SplitWindow::ImplInit( Window* pParent, WinBits nStyle )
1363 {
1364     ImplSplitSet* pNewSet   = new ImplSplitSet;
1365     pNewSet->mpItems        = NULL;
1366     pNewSet->mpWallpaper    = NULL;
1367     pNewSet->mpBitmap       = NULL;
1368     pNewSet->mnLastSize     = 0;
1369     pNewSet->mnItems        = 0;
1370     pNewSet->mnId           = 0;
1371     pNewSet->mnSplitSize    = SPLITWIN_SPLITSIZE;
1372     pNewSet->mbCalcPix      = sal_True;
1373 
1374     mpMainSet               = pNewSet;
1375     mpBaseSet               = pNewSet;
1376     mpSplitSet              = NULL;
1377     mpLastSizes             = NULL;
1378     mnDX                    = 0;
1379     mnDY                    = 0;
1380     mnLeftBorder            = 0;
1381     mnTopBorder             = 0;
1382     mnRightBorder           = 0;
1383     mnBottomBorder          = 0;
1384     mnMaxSize               = 0;
1385     mnMouseOff              = 0;
1386     meAlign                 = WINDOWALIGN_TOP;
1387     mnWinStyle              = nStyle;
1388     mnSplitTest             = 0;
1389     mnSplitPos              = 0;
1390     mnMouseModifier         = 0;
1391     mnMStartPos             = 0;
1392     mnMSplitPos             = 0;
1393     mbDragFull              = sal_False;
1394     mbHorz                  = sal_True;
1395     mbBottomRight           = sal_False;
1396     mbCalc                  = sal_False;
1397     mbRecalc                = sal_True;
1398     mbInvalidate            = sal_True;
1399     mbAutoHide              = sal_False;
1400     mbFadeIn                = sal_False;
1401     mbFadeOut               = sal_False;
1402     mbAutoHideIn            = sal_False;
1403     mbAutoHideDown          = sal_False;
1404     mbFadeInDown            = sal_False;
1405     mbFadeOutDown           = sal_False;
1406     mbAutoHidePressed       = sal_False;
1407     mbFadeInPressed         = sal_False;
1408     mbFadeOutPressed        = sal_False;
1409     mbFadeNoButtonMode      = sal_False;
1410     mbNoAlign               = sal_False;
1411 
1412     if ( nStyle & WB_NOSPLITDRAW )
1413     {
1414         pNewSet->mnSplitSize -= 2;
1415         mbInvalidate = sal_False;
1416     }
1417 
1418     if ( nStyle & WB_BORDER )
1419     {
1420         ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
1421                         mnRightBorder, mnBottomBorder );
1422     }
1423     else
1424     {
1425         mnLeftBorder   = 0;
1426         mnTopBorder    = 0;
1427         mnRightBorder  = 0;
1428         mnBottomBorder = 0;
1429     }
1430 
1431     DockingWindow::ImplInit( pParent, (nStyle | WB_CLIPCHILDREN) & ~(WB_BORDER | WB_SIZEABLE) );
1432 
1433     ImplInitSettings();
1434 }
1435 
1436 // -----------------------------------------------------------------------
1437 
1438 void SplitWindow::ImplInitSettings()
1439 {
1440     // Wenn fuer das MainSet eine Bitmap gesetzt wird, dann
1441     // brauchen wir nicht mehr den Hintergrund loeschen
1442     // Wenn MainSet Wallpaper hat, dann ist das der Hintergrund, ansonsten
1443     // sind es die Standard-Farben
1444     if ( mpMainSet->mpBitmap )
1445         SetBackground();
1446     else if ( mpMainSet->mpWallpaper )
1447         SetBackground( *mpMainSet->mpWallpaper );
1448     else
1449     {
1450         const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1451 
1452         Color aColor;
1453         if ( IsControlBackground() )
1454             aColor = GetControlBackground();
1455         else if ( Window::GetStyle() & WB_3DLOOK )
1456             aColor = rStyleSettings.GetFaceColor();
1457         else
1458             aColor = rStyleSettings.GetWindowColor();
1459         SetBackground( aColor );
1460     }
1461 }
1462 
1463 // =======================================================================
1464 
1465 SplitWindow::SplitWindow( Window* pParent, WinBits nStyle ) :
1466     DockingWindow( WINDOW_SPLITWINDOW )
1467 {
1468     ImplInit( pParent, nStyle );
1469 }
1470 
1471 // -----------------------------------------------------------------------
1472 
1473 SplitWindow::SplitWindow( Window* pParent, const ResId& rResId ) :
1474     DockingWindow( WINDOW_SPLITWINDOW )
1475 {
1476     rResId.SetRT( RSC_SPLITWINDOW );
1477     WinBits nStyle = ImplInitRes( rResId );
1478     ImplInit( pParent, nStyle );
1479     ImplLoadRes( rResId );
1480 
1481     if ( !(nStyle & WB_HIDE) )
1482         Show();
1483 }
1484 
1485 // -----------------------------------------------------------------------
1486 
1487 SplitWindow::~SplitWindow()
1488 {
1489     // Sets loeschen
1490     ImplDeleteSet( mpMainSet );
1491 }
1492 
1493 // -----------------------------------------------------------------------
1494 
1495 void SplitWindow::ImplSetWindowSize( long nDelta )
1496 {
1497     if ( !nDelta )
1498         return;
1499 
1500     Size aSize = GetSizePixel();
1501     if ( meAlign == WINDOWALIGN_TOP )
1502     {
1503         aSize.Height() += nDelta;
1504         SetSizePixel( aSize );
1505     }
1506     else if ( meAlign == WINDOWALIGN_BOTTOM )
1507     {
1508         maDragRect.Top() += nDelta;
1509         Point aPos = GetPosPixel();
1510         aPos.Y() -= nDelta;
1511         aSize.Height() += nDelta;
1512         SetPosSizePixel( aPos, aSize );
1513     }
1514     else if ( meAlign == WINDOWALIGN_LEFT )
1515     {
1516         aSize.Width() += nDelta;
1517         SetSizePixel( aSize );
1518     }
1519     else // meAlign == WINDOWALIGN_RIGHT
1520     {
1521         maDragRect.Left() += nDelta;
1522         Point aPos = GetPosPixel();
1523         aPos.X() -= nDelta;
1524         aSize.Width() += nDelta;
1525         SetPosSizePixel( aPos, aSize );
1526     }
1527 
1528     SplitResize();
1529 }
1530 
1531 // -----------------------------------------------------------------------
1532 
1533 Size SplitWindow::CalcLayoutSizePixel( const Size& aNewSize )
1534 {
1535     Size aSize( aNewSize );
1536     long nSplitSize = mpMainSet->mnSplitSize-2;
1537 
1538     if ( mbAutoHide || mbFadeOut )
1539         nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1540 
1541     // Wenn Fenster sizeable ist, wird die groesse automatisch nach
1542     // dem MainSet festgelegt, wenn kein relatives Fenster enthalten
1543     // ist
1544     if ( mnWinStyle & WB_SIZEABLE )
1545     {
1546         long    nCurSize;
1547         long    nCalcSize = 0;
1548         sal_uInt16  i;
1549 
1550         for ( i = 0; i < mpMainSet->mnItems; i++ )
1551         {
1552             if ( mpMainSet->mpItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE) )
1553                 break;
1554             else
1555                 nCalcSize += mpMainSet->mpItems[i].mnSize;
1556         }
1557 
1558         if ( i == mpMainSet->mnItems )
1559         {
1560             long    nDelta = 0;
1561             Point   aPos = GetPosPixel();
1562 
1563             if ( mbHorz )
1564                 nCurSize = aNewSize.Height()-mnTopBorder-mnBottomBorder;
1565             else
1566                 nCurSize = aNewSize.Width()-mnLeftBorder-mnRightBorder;
1567             nCurSize -= nSplitSize;
1568             nCurSize -= (mpMainSet->mnItems-1)*mpMainSet->mnSplitSize;
1569 
1570             nDelta = nCalcSize-nCurSize;
1571             if ( !nDelta )
1572                 return aSize;
1573 
1574             if ( meAlign == WINDOWALIGN_TOP )
1575             {
1576                 aSize.Height() += nDelta;
1577             }
1578             else if ( meAlign == WINDOWALIGN_BOTTOM )
1579             {
1580                 aPos.Y() -= nDelta;
1581                 aSize.Height() += nDelta;
1582             }
1583             else if ( meAlign == WINDOWALIGN_LEFT )
1584             {
1585                 aSize.Width() += nDelta;
1586             }
1587             else // meAlign == WINDOWALIGN_RIGHT
1588             {
1589                 aPos.X() -= nDelta;
1590                 aSize.Width() += nDelta;
1591             }
1592         }
1593     }
1594 
1595     return aSize;
1596 }
1597 
1598 // -----------------------------------------------------------------------
1599 
1600 void SplitWindow::ImplCalcLayout()
1601 {
1602     if ( !mbCalc || !mbRecalc || !mpMainSet->mpItems )
1603         return;
1604 
1605     long nSplitSize = mpMainSet->mnSplitSize-2;
1606     if ( mbAutoHide || mbFadeOut )
1607         nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1608 
1609     // Wenn Fenster sizeable ist, wird die groesse automatisch nach
1610     // dem MainSet festgelegt, wenn kein relatives Fenster enthalten
1611     // ist
1612     if ( mnWinStyle & WB_SIZEABLE )
1613     {
1614         long    nCurSize;
1615         long    nCalcSize = 0;
1616         sal_uInt16  i;
1617 
1618         for ( i = 0; i < mpMainSet->mnItems; i++ )
1619         {
1620             if ( mpMainSet->mpItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE) )
1621                 break;
1622             else
1623                 nCalcSize += mpMainSet->mpItems[i].mnSize;
1624         }
1625 
1626         if ( i == mpMainSet->mnItems )
1627         {
1628             if ( mbHorz )
1629                 nCurSize = mnDY-mnTopBorder-mnBottomBorder;
1630             else
1631                 nCurSize = mnDX-mnLeftBorder-mnRightBorder;
1632             nCurSize -= nSplitSize;
1633             nCurSize -= (mpMainSet->mnItems-1)*mpMainSet->mnSplitSize;
1634 
1635             mbRecalc = sal_False;
1636             ImplSetWindowSize( nCalcSize-nCurSize );
1637             mbRecalc = sal_True;
1638         }
1639     }
1640 
1641     if ( (mnDX <= 0) || (mnDY <= 0) )
1642         return;
1643 
1644     // Groessen/Position vorberechnen
1645     long    nL;
1646     long    nT;
1647     long    nW;
1648     long    nH;
1649 
1650     if ( mbHorz )
1651     {
1652         if ( mbBottomRight )
1653             nT = mnDY-mnBottomBorder;
1654         else
1655             nT = mnTopBorder;
1656         nL = mnLeftBorder;
1657     }
1658     else
1659     {
1660         if ( mbBottomRight )
1661             nL = mnDX-mnRightBorder;
1662         else
1663             nL = mnLeftBorder;
1664         nT = mnTopBorder;
1665     }
1666     nW = mnDX-mnLeftBorder-mnRightBorder;
1667     nH = mnDY-mnTopBorder-mnBottomBorder;
1668     if ( mnWinStyle & WB_SIZEABLE )
1669     {
1670         if ( mbHorz )
1671             nH -= nSplitSize;
1672         else
1673             nW -= nSplitSize;
1674     }
1675 
1676     // Sets rekursiv berechnen
1677     ImplCalcSet( mpMainSet, nL, nT, nW, nH, mbHorz, !mbBottomRight );
1678     ImplCalcSet2( this, mpMainSet, sal_False, mbHorz, !mbBottomRight );
1679     mbCalc = sal_False;
1680 }
1681 
1682 // -----------------------------------------------------------------------
1683 
1684 void SplitWindow::ImplUpdate()
1685 {
1686     mbCalc = sal_True;
1687 
1688     if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
1689     {
1690         if ( mpMainSet->mpItems )
1691             ImplCalcLayout();
1692         else
1693             Invalidate();
1694     }
1695 }
1696 
1697 // -----------------------------------------------------------------------
1698 
1699 void SplitWindow::ImplUpdateSet( ImplSplitSet* pSet )
1700 {
1701     if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
1702     {
1703         // Wenn wir noch berechnen muessen, dann alles invalidieren.
1704         if ( mbCalc )
1705         {
1706             // Wenn nicht NOSPLITDRAW gesetzt ist, koennen wir uns das
1707             // invalidieren sparen, da bei ImplCalcSet2() die freien flaechen
1708             // sowieso invalidiert werden
1709             if ( !mpMainSet->mpItems || (mnWinStyle & WB_NOSPLITDRAW) )
1710                 pSet = mpMainSet;
1711             else
1712                 return;
1713         }
1714 
1715         Rectangle aRect;
1716         if ( pSet == mpMainSet )
1717         {
1718             aRect.Left()    = mnLeftBorder;
1719             aRect.Top()     = mnTopBorder;
1720             aRect.Right()   = mnDX-mnRightBorder-1;
1721             aRect.Bottom()  = mnDY-mnBottomBorder-1;
1722         }
1723         else
1724         {
1725             ImplSplitItem*  pItem;
1726             sal_uInt16          nPos;
1727 
1728             pSet = ImplFindItem( mpMainSet, pSet->mnId, nPos );
1729             pItem = &(pSet->mpItems[nPos]);
1730             aRect.Left()    = pItem->mnLeft;
1731             aRect.Top()     = pItem->mnTop;
1732             aRect.Right()   = aRect.Left()+pItem->mnWidth;
1733             aRect.Bottom()  = aRect.Top()+pItem->mnHeight;
1734         }
1735         Invalidate( aRect );
1736     }
1737 }
1738 
1739 // -----------------------------------------------------------------------
1740 
1741 void SplitWindow::ImplSplitMousePos( Point& rMousePos )
1742 {
1743     if ( mnSplitTest & SPLIT_HORZ )
1744     {
1745         rMousePos.X() -= mnMouseOff;
1746         if ( rMousePos.X() < maDragRect.Left() )
1747             rMousePos.X() = maDragRect.Left();
1748         else if ( rMousePos.X()+mpSplitSet->mnSplitSize+1 > maDragRect.Right() )
1749             rMousePos.X() = maDragRect.Right()-mpSplitSet->mnSplitSize+1;
1750         // Wegen FullDrag in Screen-Koordinaaten merken
1751         mnMSplitPos = OutputToScreenPixel( rMousePos ).X();
1752     }
1753     else
1754     {
1755         rMousePos.Y() -= mnMouseOff;
1756         if ( rMousePos.Y() < maDragRect.Top() )
1757             rMousePos.Y() = maDragRect.Top();
1758         else if ( rMousePos.Y()+mpSplitSet->mnSplitSize+1 > maDragRect.Bottom() )
1759             rMousePos.Y() = maDragRect.Bottom()-mpSplitSet->mnSplitSize+1;
1760         mnMSplitPos = OutputToScreenPixel( rMousePos ).Y();
1761     }
1762 }
1763 
1764 // -----------------------------------------------------------------------
1765 
1766 void SplitWindow::ImplGetButtonRect( Rectangle& rRect, long nEx, sal_Bool bTest ) const
1767 {
1768     long nSplitSize = mpMainSet->mnSplitSize-2;
1769     if ( mbAutoHide || mbFadeOut || mbFadeIn )
1770         nSplitSize += SPLITWIN_SPLITSIZEEX;
1771 
1772     long nButtonSize = 0;
1773     if ( mbFadeIn )
1774         nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1775     if ( mbFadeOut )
1776         nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1777     if ( mbAutoHide )
1778         nButtonSize += SPLITWIN_SPLITSIZEAUTOHIDE+1;
1779     long nCenterEx = 0;
1780     if ( mbHorz )
1781         nCenterEx += ((mnDX-mnLeftBorder-mnRightBorder)-nButtonSize)/2;
1782     else
1783         nCenterEx += ((mnDY-mnTopBorder-mnBottomBorder)-nButtonSize)/2;
1784     if ( nCenterEx > 0 )
1785         nEx += nCenterEx;
1786 
1787     if ( meAlign == WINDOWALIGN_TOP )
1788     {
1789         rRect.Left()    = mnLeftBorder+nEx;
1790         rRect.Top()     = mnDY-mnBottomBorder-nSplitSize;
1791         rRect.Right()   = rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
1792         rRect.Bottom()  = mnDY-mnBottomBorder-1;
1793         if ( bTest )
1794         {
1795             rRect.Top()     -= mnTopBorder;
1796             rRect.Bottom()  += mnBottomBorder;
1797         }
1798     }
1799     else if ( meAlign == WINDOWALIGN_BOTTOM )
1800     {
1801         rRect.Left()    = mnLeftBorder+nEx;
1802         rRect.Top()     = mnTopBorder;
1803         rRect.Right()   = rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
1804         rRect.Bottom()  = mnTopBorder+nSplitSize-1;
1805         if ( bTest )
1806         {
1807             rRect.Top()     -= mnTopBorder;
1808             rRect.Bottom()  += mnBottomBorder;
1809         }
1810     }
1811     else if ( meAlign == WINDOWALIGN_LEFT )
1812     {
1813         rRect.Left()    = mnDX-mnRightBorder-nSplitSize;
1814         rRect.Top()     = mnTopBorder+nEx;
1815         rRect.Right()   = mnDX-mnRightBorder-1;
1816         rRect.Bottom()  = rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
1817         if ( bTest )
1818         {
1819             rRect.Left()    -= mnLeftBorder;
1820             rRect.Right()   += mnRightBorder;
1821         }
1822     }
1823     else if ( meAlign == WINDOWALIGN_RIGHT )
1824     {
1825         rRect.Left()    = mnLeftBorder;
1826         rRect.Top()     = mnTopBorder+nEx;
1827         rRect.Right()   = mnLeftBorder+nSplitSize-1;
1828         rRect.Bottom()  = rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
1829         if ( bTest )
1830         {
1831             rRect.Left()    -= mnLeftBorder;
1832             rRect.Right()   += mnRightBorder;
1833         }
1834     }
1835 }
1836 
1837 // -----------------------------------------------------------------------
1838 
1839 void SplitWindow::ImplGetAutoHideRect( Rectangle& rRect, sal_Bool bTest ) const
1840 {
1841     Rectangle aRect;
1842 
1843     if ( mbAutoHide )
1844     {
1845         long nEx = 0;
1846         if ( mbFadeIn || mbFadeOut )
1847             nEx = SPLITWIN_SPLITSIZEFADE+1;
1848         ImplGetButtonRect( aRect, nEx, bTest && mbFadeIn );
1849     }
1850 
1851     rRect = aRect;
1852 }
1853 
1854 // -----------------------------------------------------------------------
1855 
1856 void SplitWindow::ImplGetFadeInRect( Rectangle& rRect, sal_Bool bTest ) const
1857 {
1858     Rectangle aRect;
1859 
1860     if ( mbFadeIn )
1861         ImplGetButtonRect( aRect, 0, bTest );
1862 
1863     rRect = aRect;
1864 }
1865 
1866 // -----------------------------------------------------------------------
1867 
1868 void SplitWindow::ImplGetFadeOutRect( Rectangle& rRect, sal_Bool ) const
1869 {
1870     Rectangle aRect;
1871 
1872     if ( mbFadeOut )
1873         ImplGetButtonRect( aRect, 0, sal_False );
1874 
1875     rRect = aRect;
1876 }
1877 
1878 // -----------------------------------------------------------------------
1879 
1880 void SplitWindow::ImplDrawButtonRect( const Rectangle& rRect, long nSize )
1881 {
1882     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1883 
1884     if ( mbHorz )
1885     {
1886         long nLeft = rRect.Left();
1887         long nRight = rRect.Right();
1888         long nCenter = rRect.Center().Y();
1889         long nEx1 = nLeft+((rRect.GetWidth()-nSize)/2)-2;
1890         long nEx2 = nEx1+nSize+3;
1891         SetLineColor( rStyleSettings.GetLightColor() );
1892         DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
1893         DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
1894         SetLineColor( rStyleSettings.GetShadowColor() );
1895         DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
1896         DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
1897         long i = nLeft+2;
1898         while ( i < nRight-3 )
1899         {
1900             if ( (i < nEx1) || (i > nEx2 ) )
1901             {
1902                 DrawPixel( Point( i, nCenter-2 ), rStyleSettings.GetLightColor() );
1903                 DrawPixel( Point( i+1, nCenter-2+1 ), rStyleSettings.GetShadowColor() );
1904             }
1905             i++;
1906             if ( (i < nEx1) || ((i > nEx2 ) && (i < nRight-3)) )
1907             {
1908                 DrawPixel( Point( i, nCenter+2 ), rStyleSettings.GetLightColor() );
1909                 DrawPixel( Point( i+1, nCenter+2+1 ), rStyleSettings.GetShadowColor() );
1910             }
1911             i += 2;
1912         }
1913     }
1914     else
1915     {
1916         long nTop = rRect.Top();
1917         long nBottom = rRect.Bottom();
1918         long nCenter = rRect.Center().X();
1919         long nEx1 = nTop+((rRect.GetHeight()-nSize)/2)-2;
1920         long nEx2 = nEx1+nSize+3;
1921         SetLineColor( rStyleSettings.GetLightColor() );
1922         DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
1923         DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
1924         SetLineColor( rStyleSettings.GetShadowColor() );
1925         DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
1926         DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
1927         long i = nTop+2;
1928         while ( i < nBottom-3 )
1929         {
1930             if ( (i < nEx1) || (i > nEx2 ) )
1931             {
1932                 DrawPixel( Point( nCenter-2, i ), rStyleSettings.GetLightColor() );
1933                 DrawPixel( Point( nCenter-2+1, i+1 ), rStyleSettings.GetShadowColor() );
1934             }
1935             i++;
1936             if ( (i < nEx1) || ((i > nEx2 ) && (i < nBottom-3)) )
1937             {
1938                 DrawPixel( Point( nCenter+2, i ), rStyleSettings.GetLightColor() );
1939                 DrawPixel( Point( nCenter+2+1, i+1 ), rStyleSettings.GetShadowColor() );
1940             }
1941             i += 2;
1942         }
1943     }
1944 }
1945 
1946 // -----------------------------------------------------------------------
1947 
1948 void SplitWindow::ImplDrawAutoHide( sal_Bool bInPaint )
1949 {
1950     if ( mbAutoHide )
1951     {
1952         Rectangle aTempRect;
1953         ImplGetAutoHideRect( aTempRect );
1954 
1955         if ( !bInPaint )
1956             Erase( aTempRect );
1957 
1958         // ImageListe laden, wenn noch nicht vorhanden
1959         ImplSVData* pSVData = ImplGetSVData();
1960         ImageList*  pImageList;
1961         if ( mbHorz )
1962         {
1963             if ( !pSVData->maCtrlData.mpSplitHPinImgList )
1964             {
1965                 ResMgr* pResMgr = ImplGetResMgr();
1966                 if( pResMgr )
1967                 {
1968                     Color aNonAlphaMask( 0x00, 0x00, 0xFF );
1969                     pSVData->maCtrlData.mpSplitHPinImgList = new ImageList(4);
1970                     pSVData->maCtrlData.mpSplitHPinImgList->InsertFromHorizontalBitmap
1971                         ( ResId( SV_RESID_BITMAP_SPLITHPIN, *pResMgr ), 4, &aNonAlphaMask );
1972                 }
1973                 }
1974             pImageList = pSVData->maCtrlData.mpSplitHPinImgList;
1975         }
1976         else
1977         {
1978             if ( !pSVData->maCtrlData.mpSplitVPinImgList )
1979             {
1980                 ResMgr* pResMgr = ImplGetResMgr();
1981                 pSVData->maCtrlData.mpSplitVPinImgList = new ImageList(4);
1982                 if( pResMgr )
1983                 {
1984                     Color aNonAlphaMask( 0x00, 0x00, 0xFF );
1985                     pSVData->maCtrlData.mpSplitVPinImgList->InsertFromHorizontalBitmap
1986                         ( ResId( SV_RESID_BITMAP_SPLITVPIN, *pResMgr ), 4, &aNonAlphaMask );
1987                 }
1988             }
1989             pImageList = pSVData->maCtrlData.mpSplitVPinImgList;
1990                 }
1991 
1992         // Image ermitteln und zurueckgeben
1993         sal_uInt16 nId;
1994         if ( mbAutoHidePressed )
1995         {
1996             if ( mbAutoHideIn )
1997                 nId = 3;
1998             else
1999                 nId = 4;
2000         }
2001         else
2002         {
2003             if ( mbAutoHideIn )
2004                 nId = 1;
2005             else
2006                 nId = 2;
2007         }
2008 
2009         Image   aImage = pImageList->GetImage( nId );
2010         Size    aImageSize = aImage.GetSizePixel();
2011         Point   aPos( aTempRect.Left()+((aTempRect.GetWidth()-aImageSize.Width())/2),
2012                       aTempRect.Top()+((aTempRect.GetHeight()-aImageSize.Height())/2) );
2013         long    nSize;
2014         if ( mbHorz )
2015             nSize = aImageSize.Width();
2016         else
2017             nSize = aImageSize.Height();
2018         ImplDrawButtonRect( aTempRect, nSize );
2019         DrawImage( aPos, aImage );
2020     }
2021 }
2022 
2023 // -----------------------------------------------------------------------
2024 
2025 void SplitWindow::ImplDrawFadeArrow( const Point& rPt, sal_Bool bHorz, sal_Bool bLeft )
2026 {
2027     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2028 
2029     int x( rPt.X() );
2030     int y( rPt.Y() );
2031 
2032     Color aCol;
2033     if( !bHorz )
2034     {
2035         int dx = 1;
2036         if( bLeft )
2037         {
2038             x ++;
2039             dx = -1;
2040         }
2041 
2042         x++; y++;
2043         aCol = Color( COL_WHITE );
2044         DrawPixel( Point(x, y), aCol );
2045         DrawPixel( Point(x, y+1), aCol );
2046         DrawPixel( Point(x, y+2), aCol );
2047         DrawPixel( Point(x+dx, y+1), aCol );
2048 
2049         x--; y--;
2050         aCol = rStyleSettings.GetDarkShadowColor();
2051         DrawPixel( Point(x, y), rStyleSettings.GetDarkShadowColor() );
2052         DrawPixel( Point(x, y+1), rStyleSettings.GetDarkShadowColor() );
2053         DrawPixel( Point(x, y+2), rStyleSettings.GetDarkShadowColor() );
2054         DrawPixel( Point(x+dx, y+1), rStyleSettings.GetDarkShadowColor() );
2055     }
2056     else
2057     {
2058         int dy = 1;
2059         if( bLeft )
2060         {
2061             y ++;
2062             dy = -1;
2063         }
2064 
2065         x++; y++;
2066         aCol = Color( COL_WHITE );
2067         DrawPixel( Point(x, y), aCol );
2068         DrawPixel( Point(x+1, y), aCol );
2069         DrawPixel( Point(x+2, y), aCol );
2070         DrawPixel( Point(x+1, y+dy), aCol );
2071 
2072         x--; y--;
2073         aCol = rStyleSettings.GetDarkShadowColor();
2074         DrawPixel( Point(x, y), aCol );
2075         DrawPixel( Point(x+1, y), aCol );
2076         DrawPixel( Point(x+2, y), aCol );
2077         DrawPixel( Point(x+1, y+dy), aCol );
2078     }
2079 }
2080 
2081 void SplitWindow::ImplDrawGrip( const Rectangle& rRect, sal_Bool bHorz, sal_Bool bLeft )
2082 {
2083     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2084 
2085     if( rRect.IsInside( GetPointerPosPixel() ) )
2086     {
2087         DrawWallpaper( rRect, Wallpaper( Color( COL_WHITE ) ) );
2088         DrawSelectionBackground( rRect, 2, sal_False, sal_False, sal_False );
2089     }
2090 
2091     if( bHorz )
2092     {
2093         int width = (int) (0.5 * rRect.getWidth() + 0.5);
2094         int i = rRect.nLeft + (rRect.getWidth() - width) / 2;
2095         width += i;
2096         const int y = rRect.nTop + 1;
2097         ImplDrawFadeArrow( Point( i-8, y), bHorz, bLeft );
2098         while( i <= width )
2099         {
2100 
2101             DrawPixel( Point(i, y), rStyleSettings.GetDarkShadowColor() );
2102             DrawPixel( Point(i+1, y), rStyleSettings.GetShadowColor() );
2103 
2104             DrawPixel( Point(i, y+1), rStyleSettings.GetShadowColor() );
2105             DrawPixel( Point(i+1, y+1), rStyleSettings.GetFaceColor() );
2106             DrawPixel( Point(i+2, y+1), Color(COL_WHITE) );
2107 
2108             DrawPixel( Point(i+1, y+2), Color(COL_WHITE) );
2109             DrawPixel( Point(i+2, y+2), Color(COL_WHITE) );
2110             i+=4;
2111         }
2112         ImplDrawFadeArrow( Point( i+3, y), bHorz, bLeft );
2113     }
2114     else
2115     {
2116         int height = (int) (0.5 * rRect.getHeight() + 0.5);
2117         int i = rRect.nTop + (rRect.getHeight() - height) / 2;
2118         height += i;
2119         const int x = rRect.nLeft + 1;
2120         ImplDrawFadeArrow( Point( x, i-8), bHorz, bLeft );
2121         while( i <= height )
2122         {
2123 
2124             DrawPixel( Point(x, i), rStyleSettings.GetDarkShadowColor() );
2125             DrawPixel( Point(x+1, i), rStyleSettings.GetShadowColor() );
2126 
2127             DrawPixel( Point(x, i+1), rStyleSettings.GetShadowColor() );
2128             DrawPixel( Point(x+1, i+1), rStyleSettings.GetFaceColor() );
2129             DrawPixel( Point(x+2, i+1), Color(COL_WHITE) );
2130 
2131             DrawPixel( Point(x+1, i+2), Color(COL_WHITE) );
2132             DrawPixel( Point(x+2, i+2), Color(COL_WHITE) );
2133             i+=4;
2134         }
2135         ImplDrawFadeArrow( Point( x, i+3), bHorz, bLeft );
2136     }
2137 }
2138 
2139 void SplitWindow::ImplDrawFadeIn( sal_Bool bInPaint )
2140 {
2141     if ( mbFadeIn )
2142     {
2143         Rectangle       aTempRect;
2144         Image           aImage;
2145         ImplGetFadeInRect( aTempRect );
2146 
2147         sal_Bool bLeft;
2148         if ( meAlign == WINDOWALIGN_TOP )
2149             bLeft   = sal_False;
2150         else if ( meAlign == WINDOWALIGN_BOTTOM )
2151             bLeft   = sal_True;
2152         else if ( meAlign == WINDOWALIGN_LEFT )
2153             bLeft   = sal_False;
2154         else if ( meAlign == WINDOWALIGN_RIGHT )
2155             bLeft   = sal_True;
2156         else
2157             bLeft   = sal_True;
2158 
2159         if ( !bInPaint )
2160             Erase( aTempRect );
2161 
2162         ImplDrawGrip( aTempRect, (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM), bLeft );
2163     }
2164 }
2165 
2166 // -----------------------------------------------------------------------
2167 
2168 void SplitWindow::ImplDrawFadeOut( sal_Bool bInPaint )
2169 {
2170     if ( mbFadeOut )
2171     {
2172         Rectangle       aTempRect;
2173         Image           aImage;
2174         ImplGetFadeOutRect( aTempRect );
2175 
2176         sal_Bool bLeft;
2177         if ( meAlign == WINDOWALIGN_TOP )
2178             bLeft   = sal_True;
2179         else if ( meAlign == WINDOWALIGN_BOTTOM )
2180             bLeft   = sal_False;
2181         else if ( meAlign == WINDOWALIGN_LEFT )
2182             bLeft   = sal_True;
2183         else if ( meAlign == WINDOWALIGN_RIGHT )
2184             bLeft   = sal_False;
2185         else
2186             bLeft   = sal_True;
2187 
2188         if ( !bInPaint )
2189             Erase( aTempRect );
2190 
2191         ImplDrawGrip( aTempRect, (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM), bLeft );
2192     }
2193 }
2194 
2195 // -----------------------------------------------------------------------
2196 void SplitWindow::ImplStartSplit( const MouseEvent& rMEvt )
2197 {
2198     Point aMousePosPixel = rMEvt.GetPosPixel();
2199     mnSplitTest = ImplTestSplit( this, aMousePosPixel, mnMouseOff, &mpSplitSet, mnSplitPos );
2200 
2201     if ( mnSplitTest && !(mnSplitTest & SPLIT_NOSPLIT) )
2202     {
2203         ImplSplitItem*  pSplitItem;
2204         long            nCurMaxSize;
2205         sal_uInt16          nTemp;
2206         sal_Bool            bDown;
2207         sal_Bool            bPropSmaller;
2208 
2209         mnMouseModifier = rMEvt.GetModifier();
2210         if ( !(mnMouseModifier & KEY_SHIFT) || (mnSplitPos+1 >= mpSplitSet->mnItems) )
2211             bPropSmaller = sal_False;
2212         else
2213             bPropSmaller = sal_True;
2214 
2215         // Hier kann noch die maximale Groesse gesetzt werden
2216         StartSplit();
2217 
2218         if ( mnMaxSize )
2219             nCurMaxSize = mnMaxSize;
2220         else
2221         {
2222             Size aSize = GetParent()->GetOutputSizePixel();
2223             if ( mbHorz )
2224                 nCurMaxSize = aSize.Height();
2225             else
2226                 nCurMaxSize = aSize.Width();
2227         }
2228 
2229         if ( mpSplitSet->mpItems )
2230         {
2231             bDown = sal_True;
2232             if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2233                 bDown = sal_False;
2234 
2235             pSplitItem          = &(mpSplitSet->mpItems[mnSplitPos]);
2236             maDragRect.Left()   = pSplitItem->mnLeft;
2237             maDragRect.Top()    = pSplitItem->mnTop;
2238             maDragRect.Right()  = pSplitItem->mnLeft+pSplitItem->mnWidth-1;
2239             maDragRect.Bottom() = pSplitItem->mnTop+pSplitItem->mnHeight-1;
2240 
2241             if ( mnSplitTest & SPLIT_HORZ )
2242             {
2243                 if ( bDown )
2244                     maDragRect.Right() += mpSplitSet->mnSplitSize;
2245                 else
2246                     maDragRect.Left() -= mpSplitSet->mnSplitSize;
2247             }
2248             else
2249             {
2250                 if ( bDown )
2251                     maDragRect.Bottom() += mpSplitSet->mnSplitSize;
2252                 else
2253                     maDragRect.Top() -= mpSplitSet->mnSplitSize;
2254             }
2255 
2256             if ( mnSplitPos )
2257             {
2258                 nTemp = mnSplitPos;
2259                 while ( nTemp )
2260                 {
2261                     pSplitItem = &(mpSplitSet->mpItems[nTemp-1]);
2262                     if ( pSplitItem->mbFixed )
2263                         break;
2264                     else
2265                     {
2266                         if ( mnSplitTest & SPLIT_HORZ )
2267                         {
2268                             if ( bDown )
2269                                 maDragRect.Left() -= pSplitItem->mnPixSize;
2270                             else
2271                                 maDragRect.Right() += pSplitItem->mnPixSize;
2272                         }
2273                         else
2274                         {
2275                             if ( bDown )
2276                                 maDragRect.Top() -= pSplitItem->mnPixSize;
2277                             else
2278                                 maDragRect.Bottom() += pSplitItem->mnPixSize;
2279                         }
2280                     }
2281                     nTemp--;
2282                 }
2283             }
2284 
2285             if ( (mpSplitSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) && !bPropSmaller )
2286             {
2287                 if ( bDown )
2288                 {
2289                     if ( mbHorz )
2290                         maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
2291                     else
2292                         maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
2293                 }
2294                 else
2295                 {
2296                     if ( mbHorz )
2297                         maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
2298                     else
2299                         maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
2300                 }
2301             }
2302             else
2303             {
2304                 nTemp = mnSplitPos+1;
2305                 while ( nTemp < mpSplitSet->mnItems )
2306                 {
2307                     pSplitItem = &(mpSplitSet->mpItems[nTemp]);
2308                     if ( pSplitItem->mbFixed )
2309                         break;
2310                     else
2311                     {
2312                         if ( mnSplitTest & SPLIT_HORZ )
2313                         {
2314                             if ( bDown )
2315                                 maDragRect.Right() += pSplitItem->mnPixSize;
2316                             else
2317                                 maDragRect.Left() -= pSplitItem->mnPixSize;
2318                         }
2319                         else
2320                         {
2321                             if ( bDown )
2322                                 maDragRect.Bottom() += pSplitItem->mnPixSize;
2323                             else
2324                                 maDragRect.Top() -= pSplitItem->mnPixSize;
2325                         }
2326                     }
2327                     nTemp++;
2328                 }
2329             }
2330         }
2331         else
2332         {
2333             maDragRect.Left()   = mnLeftBorder;
2334             maDragRect.Top()    = mnTopBorder;
2335             maDragRect.Right()  = mnDX-mnRightBorder-1;
2336             maDragRect.Bottom() = mnDY-mnBottomBorder-1;
2337             if ( mbHorz )
2338             {
2339                 if ( mbBottomRight )
2340                     maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
2341                 else
2342                     maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
2343             }
2344             else
2345             {
2346                 if ( mbBottomRight )
2347                     maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
2348                 else
2349                     maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
2350             }
2351         }
2352 
2353         StartTracking();
2354 
2355         mbDragFull = (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0;
2356 
2357         ImplSplitMousePos( aMousePosPixel );
2358 
2359         if ( !mbDragFull )
2360             ImplDrawSplitTracking( this, aMousePosPixel );
2361         else
2362         {
2363             ImplSplitItem*  pItems = mpSplitSet->mpItems;
2364             sal_uInt16          nItems = mpSplitSet->mnItems;
2365             mpLastSizes = new long[nItems*2];
2366             for ( sal_uInt16 i = 0; i < nItems; i++ )
2367             {
2368                 mpLastSizes[i*2]   = pItems[i].mnSize;
2369                 mpLastSizes[i*2+1] = pItems[i].mnPixSize;
2370             }
2371         }
2372         mnMStartPos = mnMSplitPos;
2373 
2374         PointerStyle eStyle = POINTER_ARROW;
2375         if ( mnSplitTest & SPLIT_HORZ )
2376             eStyle = POINTER_HSPLIT;
2377         else if ( mnSplitTest & SPLIT_VERT )
2378             eStyle = POINTER_VSPLIT;
2379 
2380         Pointer aPtr( eStyle );
2381         SetPointer( aPtr );
2382     }
2383 }
2384 
2385 
2386 // -----------------------------------------------------------------------
2387 
2388 void SplitWindow::StartSplit()
2389 {
2390     maStartSplitHdl.Call( this );
2391 }
2392 
2393 // -----------------------------------------------------------------------
2394 
2395 void SplitWindow::Split()
2396 {
2397     maSplitHdl.Call( this );
2398 }
2399 
2400 // -----------------------------------------------------------------------
2401 
2402 void SplitWindow::SplitResize()
2403 {
2404     maSplitResizeHdl.Call( this );
2405 }
2406 
2407 // -----------------------------------------------------------------------
2408 
2409 void SplitWindow::AutoHide()
2410 {
2411     maAutoHideHdl.Call( this );
2412 }
2413 
2414 // -----------------------------------------------------------------------
2415 
2416 void SplitWindow::FadeIn()
2417 {
2418     maFadeInHdl.Call( this );
2419 }
2420 
2421 // -----------------------------------------------------------------------
2422 
2423 void SplitWindow::FadeOut()
2424 {
2425     maFadeOutHdl.Call( this );
2426 }
2427 
2428 // -----------------------------------------------------------------------
2429 
2430 void SplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
2431 {
2432     if ( !rMEvt.IsLeft() || rMEvt.IsMod2() )
2433     {
2434         DockingWindow::MouseButtonDown( rMEvt );
2435         return;
2436     }
2437 
2438     Point           aMousePosPixel = rMEvt.GetPosPixel();
2439     Rectangle       aTestRect;
2440 
2441     mbFadeNoButtonMode = sal_False;
2442     ImplGetAutoHideRect( aTestRect, sal_True );
2443     if ( aTestRect.IsInside( aMousePosPixel ) )
2444     {
2445         mbAutoHideDown = sal_True;
2446         mbAutoHidePressed = sal_True;
2447         ImplDrawAutoHide( sal_False );
2448     }
2449     else
2450     {
2451         ImplGetFadeOutRect( aTestRect, sal_True );
2452         if ( aTestRect.IsInside( aMousePosPixel ) )
2453         {
2454             mbFadeOutDown = sal_True;
2455             mbFadeOutPressed = sal_True;
2456             ImplDrawFadeOut( sal_False );
2457         }
2458         else
2459         {
2460             ImplGetFadeInRect( aTestRect, sal_True );
2461             if ( aTestRect.IsInside( aMousePosPixel ) )
2462             {
2463                 mbFadeInDown = sal_True;
2464                 mbFadeInPressed = sal_True;
2465                 ImplDrawFadeIn( sal_False );
2466             }
2467             else if ( !aTestRect.IsEmpty() && !(mnWinStyle & WB_SIZEABLE) )
2468             {
2469                 mbFadeNoButtonMode = sal_True;
2470                 FadeIn();
2471                 return;
2472             }
2473         }
2474     }
2475 
2476     if ( mbAutoHideDown || mbFadeInDown || mbFadeOutDown )
2477         StartTracking();
2478     else
2479         ImplStartSplit( rMEvt );
2480 }
2481 
2482 // -----------------------------------------------------------------------
2483 
2484 void SplitWindow::MouseMove( const MouseEvent& rMEvt )
2485 {
2486     if ( !IsTracking() )
2487     {
2488         Point           aPos = rMEvt.GetPosPixel();
2489         long            nTemp;
2490         ImplSplitSet*   pTempSplitSet;
2491         sal_uInt16          nTempSplitPos;
2492         sal_uInt16          nSplitTest = ImplTestSplit( this, aPos, nTemp, &pTempSplitSet, nTempSplitPos );
2493         PointerStyle    eStyle = POINTER_ARROW;
2494         Rectangle       aAutoHideRect;
2495         Rectangle       aFadeInRect;
2496         Rectangle       aFadeOutRect;
2497 
2498         ImplGetAutoHideRect( aAutoHideRect );
2499         ImplGetFadeInRect( aFadeInRect );
2500         ImplGetFadeOutRect( aFadeOutRect );
2501         if ( !aAutoHideRect.IsInside( aPos ) &&
2502              !aFadeInRect.IsInside( aPos ) &&
2503              !aFadeOutRect.IsInside( aPos ) )
2504         {
2505             if ( nSplitTest && !(nSplitTest & SPLIT_NOSPLIT) )
2506             {
2507                 if ( nSplitTest & SPLIT_HORZ )
2508                     eStyle = POINTER_HSPLIT;
2509                 else if ( nSplitTest & SPLIT_VERT )
2510                     eStyle = POINTER_VSPLIT;
2511             }
2512         }
2513 
2514         Pointer aPtr( eStyle );
2515         SetPointer( aPtr );
2516     }
2517 }
2518 
2519 // -----------------------------------------------------------------------
2520 
2521 void SplitWindow::Tracking( const TrackingEvent& rTEvt )
2522 {
2523     Point aMousePosPixel = rTEvt.GetMouseEvent().GetPosPixel();
2524 
2525     if ( mbAutoHideDown )
2526     {
2527         if ( rTEvt.IsTrackingEnded() )
2528         {
2529             mbAutoHideDown = sal_False;
2530             if ( mbAutoHidePressed )
2531             {
2532                 mbAutoHidePressed = sal_False;
2533 
2534                 if ( !rTEvt.IsTrackingCanceled() )
2535                 {
2536                     mbAutoHideIn = !mbAutoHideIn;
2537                     ImplDrawAutoHide( sal_False );
2538                     AutoHide();
2539                 }
2540                 else
2541                     ImplDrawAutoHide( sal_False );
2542             }
2543         }
2544         else
2545         {
2546             Rectangle aTestRect;
2547             ImplGetAutoHideRect( aTestRect, sal_True );
2548             sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2549             if ( bNewPressed != mbAutoHidePressed )
2550             {
2551                 mbAutoHidePressed = bNewPressed;
2552                 ImplDrawAutoHide( sal_False );
2553             }
2554         }
2555     }
2556     else if ( mbFadeInDown )
2557     {
2558         if ( rTEvt.IsTrackingEnded() )
2559         {
2560             mbFadeInDown = sal_False;
2561             if ( mbFadeInPressed )
2562             {
2563                 mbFadeInPressed = sal_False;
2564                 ImplDrawFadeIn( sal_False );
2565 
2566                 if ( !rTEvt.IsTrackingCanceled() )
2567                     FadeIn();
2568             }
2569         }
2570         else
2571         {
2572             Rectangle aTestRect;
2573             ImplGetFadeInRect( aTestRect, sal_True );
2574             sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2575             if ( bNewPressed != mbFadeInPressed )
2576             {
2577                 mbFadeInPressed = bNewPressed;
2578                 ImplDrawFadeIn( sal_False );
2579             }
2580         }
2581     }
2582     else if ( mbFadeOutDown )
2583     {
2584         if ( rTEvt.IsTrackingEnded() )
2585         {
2586             mbFadeOutDown = sal_False;
2587             if ( mbFadeOutPressed )
2588             {
2589                 mbFadeOutPressed = sal_False;
2590                 ImplDrawFadeOut( sal_False );
2591 
2592                 if ( !rTEvt.IsTrackingCanceled() )
2593                     FadeOut();
2594             }
2595         }
2596         else
2597         {
2598             Rectangle aTestRect;
2599             ImplGetFadeOutRect( aTestRect, sal_True );
2600             sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2601             if ( bNewPressed == sal_False )
2602             {
2603                 mbFadeOutPressed = bNewPressed;
2604                 ImplDrawFadeOut( sal_False );
2605 
2606                 // We need a mouseevent with a position inside the button for the
2607                 // ImplStartSplit function!
2608                 MouseEvent aOrgMEvt = rTEvt.GetMouseEvent();
2609                 MouseEvent aNewMEvt = MouseEvent( aTestRect.Center(), aOrgMEvt.GetClicks(),
2610                                                   aOrgMEvt.GetMode(), aOrgMEvt.GetButtons(),
2611                                                   aOrgMEvt.GetModifier() );
2612 
2613                 ImplStartSplit( aNewMEvt );
2614                 mbFadeOutDown = sal_False;
2615             }
2616         }
2617     }
2618     else
2619     {
2620         ImplSplitMousePos( aMousePosPixel );
2621         sal_Bool bSplit = sal_True;
2622         if ( mbDragFull )
2623         {
2624             if ( rTEvt.IsTrackingEnded() )
2625             {
2626                 if ( rTEvt.IsTrackingCanceled() )
2627                 {
2628                     ImplSplitItem*  pItems = mpSplitSet->mpItems;
2629                     sal_uInt16          nItems = mpSplitSet->mnItems;
2630                     for ( sal_uInt16 i = 0; i < nItems; i++ )
2631                     {
2632                         pItems[i].mnSize     = mpLastSizes[i*2];
2633                         pItems[i].mnPixSize  = mpLastSizes[i*2+1];
2634                     }
2635                     ImplUpdate();
2636                     Split();
2637                 }
2638                 bSplit = sal_False;
2639             }
2640         }
2641         else
2642         {
2643             if ( rTEvt.IsTrackingEnded() )
2644             {
2645                 HideTracking();
2646                 bSplit = !rTEvt.IsTrackingCanceled();
2647             }
2648             else
2649             {
2650                 ImplDrawSplitTracking( this, aMousePosPixel );
2651                 bSplit = sal_False;
2652             }
2653         }
2654 
2655         if ( bSplit )
2656         {
2657             sal_Bool    bPropSmaller = (mnMouseModifier & KEY_SHIFT) ? sal_True : sal_False;
2658             sal_Bool    bPropGreater = (mnMouseModifier & KEY_MOD1) ? sal_True : sal_False;
2659             long    nDelta = mnMSplitPos-mnMStartPos;
2660 
2661             if ( (mnSplitTest & SPLIT_WINDOW) && !mpMainSet->mpItems )
2662             {
2663                 if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2664                     nDelta *= -1;
2665                 ImplSetWindowSize( nDelta );
2666             }
2667             else
2668             {
2669                 long nNewSize = mpSplitSet->mpItems[mnSplitPos].mnPixSize;
2670                 if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2671                     nNewSize -= nDelta;
2672                 else
2673                     nNewSize += nDelta;
2674                 SplitItem( mpSplitSet->mpItems[mnSplitPos].mnId, nNewSize,
2675                            bPropSmaller, bPropGreater );
2676             }
2677 
2678             Split();
2679 
2680             if ( mbDragFull )
2681             {
2682                 Update();
2683                 mnMStartPos = mnMSplitPos;
2684             }
2685         }
2686 
2687         if ( rTEvt.IsTrackingEnded() )
2688         {
2689             if ( mpLastSizes )
2690                 delete mpLastSizes;
2691             mpLastSizes     = NULL;
2692             mpSplitSet      = NULL;
2693             mnMouseOff      = 0;
2694             mnMStartPos     = 0;
2695             mnMSplitPos     = 0;
2696             mnMouseModifier = 0;
2697             mnSplitTest     = 0;
2698             mnSplitPos      = 0;
2699         }
2700     }
2701 }
2702 
2703 // -----------------------------------------------------------------------
2704 
2705 long SplitWindow::PreNotify( NotifyEvent& rNEvt )
2706 {
2707     const MouseEvent* pMouseEvt = NULL;
2708 
2709     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
2710     {
2711         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2712         {
2713             // trigger redraw if mouse over state has changed
2714             Rectangle aFadeInRect;
2715             Rectangle aFadeOutRect;
2716             ImplGetFadeInRect( aFadeInRect );
2717             ImplGetFadeOutRect( aFadeOutRect );
2718 
2719             if ( aFadeInRect.IsInside( GetPointerPosPixel() ) != aFadeInRect.IsInside( GetLastPointerPosPixel() ) )
2720                 Invalidate( aFadeInRect );
2721             if ( aFadeOutRect.IsInside( GetPointerPosPixel() ) != aFadeOutRect.IsInside( GetLastPointerPosPixel() ) )
2722                 Invalidate( aFadeOutRect );
2723 
2724             if( pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
2725             {
2726                 Invalidate( aFadeInRect );
2727                 Invalidate( aFadeOutRect );
2728             }
2729         }
2730     }
2731     return Window::PreNotify( rNEvt );
2732 }
2733 
2734 // -----------------------------------------------------------------------
2735 
2736 void SplitWindow::Paint( const Rectangle& )
2737 {
2738     if ( mnWinStyle & WB_BORDER )
2739         ImplDrawBorder( this );
2740 
2741     ImplDrawBorderLine( this );
2742     ImplDrawFadeOut( sal_True );
2743     ImplDrawFadeIn( sal_True );
2744     ImplDrawAutoHide( sal_True );
2745 
2746     // FrameSet-Hintergruende zeichnen
2747     ImplDrawBack( this, mpMainSet );
2748 
2749     // Splitter zeichnen
2750     if ( !(mnWinStyle & WB_NOSPLITDRAW) )
2751         ImplDrawSplit( this, mpMainSet, mbHorz, !mbBottomRight );
2752 }
2753 
2754 // -----------------------------------------------------------------------
2755 
2756 void SplitWindow::Move()
2757 {
2758     DockingWindow::Move();
2759 }
2760 
2761 // -----------------------------------------------------------------------
2762 
2763 void SplitWindow::Resize()
2764 {
2765     Size aSize = GetOutputSizePixel();
2766     mnDX = aSize.Width();
2767     mnDY = aSize.Height();
2768 
2769     ImplUpdate();
2770     Invalidate();
2771 }
2772 
2773 // -----------------------------------------------------------------------
2774 
2775 void SplitWindow::RequestHelp( const HelpEvent& rHEvt )
2776 {
2777     // no keyboard help for splitwin
2778     if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) && !rHEvt.KeyboardActivated() )
2779     {
2780         Point       aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
2781         Rectangle   aHelpRect;
2782         sal_uInt16      nHelpResId = 0;
2783 
2784         ImplGetAutoHideRect( aHelpRect, sal_True );
2785         if ( aHelpRect.IsInside( aMousePosPixel ) )
2786         {
2787             if ( mbAutoHideIn )
2788                 nHelpResId = SV_HELPTEXT_SPLITFIXED;
2789             else
2790                 nHelpResId = SV_HELPTEXT_SPLITFLOATING;
2791         }
2792         else
2793         {
2794             ImplGetFadeInRect( aHelpRect, sal_True );
2795             if ( aHelpRect.IsInside( aMousePosPixel ) )
2796                 nHelpResId = SV_HELPTEXT_FADEIN;
2797             else
2798             {
2799                 ImplGetFadeOutRect( aHelpRect, sal_True );
2800                 if ( aHelpRect.IsInside( aMousePosPixel ) )
2801                     nHelpResId = SV_HELPTEXT_FADEOUT;
2802             }
2803         }
2804 
2805         // Rechteck ermitteln
2806         if ( nHelpResId )
2807         {
2808             Point aPt = OutputToScreenPixel( aHelpRect.TopLeft() );
2809             aHelpRect.Left()   = aPt.X();
2810             aHelpRect.Top()    = aPt.Y();
2811             aPt = OutputToScreenPixel( aHelpRect.BottomRight() );
2812             aHelpRect.Right()  = aPt.X();
2813             aHelpRect.Bottom() = aPt.Y();
2814 
2815             // Text ermitteln und anzeigen
2816             XubString aStr;
2817             ResMgr* pResMgr = ImplGetResMgr();
2818             if( pResMgr )
2819                 aStr = XubString( ResId( nHelpResId, *pResMgr ) );
2820             if ( rHEvt.GetMode() & HELPMODE_BALLOON )
2821                 Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aStr );
2822             else
2823                 Help::ShowQuickHelp( this, aHelpRect, aStr );
2824             return;
2825         }
2826     }
2827 
2828     DockingWindow::RequestHelp( rHEvt );
2829 }
2830 
2831 // -----------------------------------------------------------------------
2832 
2833 void SplitWindow::StateChanged( StateChangedType nType )
2834 {
2835     if ( nType == STATE_CHANGE_INITSHOW )
2836     {
2837         if ( IsUpdateMode() )
2838             ImplCalcLayout();
2839     }
2840     else if ( nType == STATE_CHANGE_UPDATEMODE )
2841     {
2842         if ( IsUpdateMode() && IsReallyShown() )
2843             ImplCalcLayout();
2844     }
2845     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2846     {
2847         ImplInitSettings();
2848         Invalidate();
2849     }
2850 
2851     DockingWindow::StateChanged( nType );
2852 }
2853 
2854 // -----------------------------------------------------------------------
2855 
2856 void SplitWindow::DataChanged( const DataChangedEvent& rDCEvt )
2857 {
2858     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2859          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2860     {
2861         ImplInitSettings();
2862         Invalidate();
2863     }
2864     else
2865         DockingWindow::DataChanged( rDCEvt );
2866 }
2867 
2868 // -----------------------------------------------------------------------
2869 
2870 void SplitWindow::InsertItem( sal_uInt16 nId, Window* pWindow, long nSize,
2871                               sal_uInt16 nPos, sal_uInt16 nSetId,
2872                               SplitWindowItemBits nBits )
2873 {
2874 #ifdef DBG_UTIL
2875     sal_uInt16 nDbgDummy;
2876     DBG_ASSERT( ImplFindSet( mpMainSet, nSetId ), "SplitWindow::InsertItem() - Set not exists" );
2877     DBG_ASSERT( !ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::InsertItem() - Id already exists" );
2878 #endif
2879 
2880     // Size has to be at least 1.
2881     if ( nSize < 1 )
2882         nSize = 1;
2883 
2884     ImplSplitSet* pSet       = ImplFindSet( mpMainSet, nSetId );
2885     ImplSplitSet* pNewSet;
2886     ImplSplitItem* pItem;
2887 
2888     // Make room for the new item.
2889     if ( nPos > pSet->mnItems )
2890         nPos = pSet->mnItems;
2891     ImplSplitItem* pNewItems = new ImplSplitItem[pSet->mnItems+1];
2892     if ( nPos )
2893         memcpy( pNewItems, pSet->mpItems, sizeof( ImplSplitItem )*nPos );
2894     if ( nPos < pSet->mnItems )
2895         memcpy( pNewItems+nPos+1, pSet->mpItems+nPos, sizeof( ImplSplitItem )*(pSet->mnItems-nPos) );
2896     delete[] pSet->mpItems;
2897     pSet->mpItems = pNewItems;
2898     pSet->mnItems++;
2899     pSet->mbCalcPix = sal_True;
2900 
2901     // Create and initialize item.
2902     pItem           = &(pSet->mpItems[nPos]);
2903     memset( pItem, 0, sizeof( ImplSplitItem ) );
2904     pItem->mnSize   = nSize;
2905     pItem->mnId     = nId;
2906     pItem->mnBits   = nBits;
2907     pItem->mnMinSize=-1;
2908     pItem->mnMaxSize=-1;
2909 
2910     if ( pWindow )
2911     {
2912         pItem->mpWindow         = pWindow;
2913         pItem->mpOrgParent      = pWindow->GetParent();
2914 
2915         // Attach window to SplitWindow.
2916         pWindow->Hide();
2917         pWindow->SetParent( this );
2918     }
2919     else
2920     {
2921         pNewSet                 = new ImplSplitSet;
2922         pNewSet->mpItems        = NULL;
2923         pNewSet->mpWallpaper    = NULL;
2924         pNewSet->mpBitmap       = NULL;
2925         pNewSet->mnLastSize     = 0;
2926         pNewSet->mnItems        = 0;
2927         pNewSet->mnId           = nId;
2928         pNewSet->mnSplitSize    = pSet->mnSplitSize;
2929         pNewSet->mbCalcPix      = sal_True;
2930 
2931         pItem->mpSet            = pNewSet;
2932     }
2933 
2934     ImplUpdate();
2935 }
2936 
2937 // -----------------------------------------------------------------------
2938 
2939 void SplitWindow::InsertItem( sal_uInt16 nId, long nSize,
2940                               sal_uInt16 nPos, sal_uInt16 nSetId,
2941                               SplitWindowItemBits nBits )
2942 {
2943     InsertItem( nId, NULL, nSize, nPos, nSetId, nBits );
2944 }
2945 
2946 // -----------------------------------------------------------------------
2947 
2948 void SplitWindow::MoveItem( sal_uInt16 nId, sal_uInt16 nNewPos, sal_uInt16 nNewSetId )
2949 {
2950 #ifdef DBG_UTIL
2951     sal_uInt16 nDbgDummy;
2952     DBG_ASSERT( ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::MoveItem() - Id not found" );
2953     DBG_ASSERT( ImplFindSet( mpMainSet, nNewSetId ), "SplitWindow::MoveItem() - Set not exists" );
2954 #endif
2955 
2956     sal_uInt16          nPos;
2957     ImplSplitSet*    pNewSet = ImplFindSet( mpMainSet, nNewSetId );
2958     ImplSplitSet*    pSet    = ImplFindItem( mpMainSet, nId, nPos );
2959     ImplSplitItem    aTempItem;
2960 
2961     if ( pNewSet == pSet )
2962     {
2963         if ( nNewPos >= pNewSet->mnItems )
2964             nNewPos = pNewSet->mnItems-1;
2965         if ( nPos != nNewPos )
2966         {
2967             memcpy( &aTempItem, &(pSet->mpItems[nPos]), sizeof( aTempItem ) );
2968             if ( nPos < nNewPos )
2969             {
2970                 memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
2971                          (nNewPos-nPos)*sizeof( ImplSplitItem ) );
2972             }
2973             else
2974             {
2975                 memmove( pSet->mpItems+nNewPos+1, pSet->mpItems+nNewPos,
2976                          (nPos-nNewPos)*sizeof( ImplSplitItem ) );
2977             }
2978             memcpy( &(pSet->mpItems[nNewPos]), &aTempItem, sizeof( aTempItem ) );
2979 
2980             ImplUpdate();
2981         }
2982     }
2983     else
2984     {
2985         if ( nNewPos >= pNewSet->mnItems )
2986             nNewPos = pNewSet->mnItems;
2987         memcpy( &aTempItem, &(pSet->mpItems[nPos]), sizeof( aTempItem ) );
2988         pSet->mnItems--;
2989         pSet->mbCalcPix = sal_True;
2990         if ( pSet->mnItems )
2991         {
2992             memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
2993                      (pSet->mnItems-nPos)*sizeof( ImplSplitItem ) );
2994         }
2995         else
2996         {
2997             delete[] pSet->mpItems;
2998             pSet->mpItems = NULL;
2999         }
3000         ImplSplitItem* pNewItems = new ImplSplitItem[pNewSet->mnItems+1];
3001         if ( nNewPos )
3002             memcpy( pNewItems, pNewSet->mpItems, sizeof( ImplSplitItem )*nNewPos );
3003         if ( nNewPos < pNewSet->mnItems )
3004         {
3005             memcpy( pNewItems+nNewPos+1, pNewSet->mpItems+nNewPos,
3006                     sizeof( ImplSplitItem )*(pNewSet->mnItems-nNewPos) );
3007         }
3008         delete[] pNewSet->mpItems;
3009         pNewSet->mpItems = pNewItems;
3010         pNewSet->mnItems++;
3011         pNewSet->mbCalcPix = sal_True;
3012         memcpy( &(pNewSet->mpItems[nNewPos]), &aTempItem, sizeof( aTempItem ) );
3013         ImplUpdate();
3014     }
3015 }
3016 
3017 // -----------------------------------------------------------------------
3018 
3019 void SplitWindow::RemoveItem( sal_uInt16 nId, sal_Bool bHide )
3020 {
3021 #ifdef DBG_UTIL
3022     sal_uInt16 nDbgDummy;
3023     DBG_ASSERT( ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::RemoveItem() - Id not found" );
3024 #endif
3025 
3026     // Set suchen
3027     sal_uInt16          nPos;
3028     ImplSplitSet*    pSet    = ImplFindItem( mpMainSet, nId, nPos );
3029     ImplSplitItem*   pItem   = &(pSet->mpItems[nPos]);
3030     Window*         pWindow = pItem->mpWindow;
3031     Window*         pOrgParent = pItem->mpOrgParent;
3032 
3033     // Evt. Set loeschen
3034     if ( !pWindow )
3035         ImplDeleteSet( pItem->mpSet );
3036 
3037     // Item entfernen
3038     pSet->mnItems--;
3039     pSet->mbCalcPix = sal_True;
3040     if ( pSet->mnItems )
3041     {
3042         memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
3043                  (pSet->mnItems-nPos)*sizeof( ImplSplitItem ) );
3044     }
3045     else
3046     {
3047         delete[] pSet->mpItems;
3048         pSet->mpItems = NULL;
3049     }
3050 
3051     ImplUpdate();
3052 
3053     // Window erst hier loeschen, um weniger Paints zu haben
3054     if ( pWindow )
3055     {
3056         // Fenster wieder herstellen
3057         if ( bHide || (pOrgParent != this) )
3058         {
3059             pWindow->Hide();
3060             pWindow->SetParent( pOrgParent );
3061         }
3062     }
3063 }
3064 
3065 // -----------------------------------------------------------------------
3066 
3067 void SplitWindow::Clear()
3068 {
3069     // Alle Sets loeschen
3070     ImplDeleteSet( mpMainSet );
3071 
3072     // Main-Set wieder anlegen
3073     mpMainSet                   = new ImplSplitSet;
3074     mpMainSet->mpItems          = NULL;
3075     mpMainSet->mpWallpaper      = NULL;
3076     mpMainSet->mpBitmap         = NULL;
3077     mpMainSet->mnLastSize       = 0;
3078     mpMainSet->mnItems          = 0;
3079     mpMainSet->mnId             = 0;
3080     mpMainSet->mnSplitSize      = SPLITWIN_SPLITSIZE;
3081     mpMainSet->mbCalcPix        = sal_True;
3082     if ( mnWinStyle & WB_NOSPLITDRAW )
3083         mpMainSet->mnSplitSize -= 2;
3084     mpBaseSet                   = mpMainSet;
3085 
3086     // Und neu invalidieren
3087     ImplUpdate();
3088 }
3089 
3090 // -----------------------------------------------------------------------
3091 
3092 void SplitWindow::SetBaseSet( sal_uInt16 nSetId )
3093 {
3094     mpBaseSet = ImplFindSet( mpMainSet, nSetId );
3095 }
3096 
3097 // -----------------------------------------------------------------------
3098 
3099 sal_uInt16 SplitWindow::GetBaseSet() const
3100 {
3101     return mpBaseSet->mnId;
3102 }
3103 
3104 // -----------------------------------------------------------------------
3105 
3106 void SplitWindow::SetSplitSize( sal_uInt16 nSetId, long nSplitSize,
3107                                 sal_Bool bWithChilds )
3108 {
3109     ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3110     if ( pSet )
3111     {
3112         if ( bWithChilds )
3113             ImplSetSplitSize( pSet, nSplitSize );
3114         else
3115             pSet->mnSplitSize = nSplitSize;
3116     }
3117     ImplUpdate();
3118 }
3119 
3120 // -----------------------------------------------------------------------
3121 
3122 long SplitWindow::GetSplitSize( sal_uInt16 nSetId ) const
3123 {
3124     ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3125     if ( pSet )
3126         return pSet->mnSplitSize;
3127     else
3128         return 0;
3129 }
3130 
3131 // -----------------------------------------------------------------------
3132 
3133 void SplitWindow::SetItemBackground( sal_uInt16 nSetId )
3134 {
3135     Wallpaper aWall;
3136     SetItemBackground( nSetId, aWall );
3137 }
3138 
3139 // -----------------------------------------------------------------------
3140 
3141 void SplitWindow::SetItemBackground( sal_uInt16 nSetId, const Wallpaper& rWallpaper )
3142 {
3143     ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3144 
3145     if ( pSet )
3146     {
3147         sal_Bool bUpdate = sal_True;
3148 
3149         if ( rWallpaper.GetStyle() == WALLPAPER_NULL )
3150         {
3151             if ( pSet->mpWallpaper )
3152             {
3153                 delete pSet->mpWallpaper;
3154                 pSet->mpWallpaper = NULL;
3155             }
3156             else
3157                 bUpdate = sal_False;
3158         }
3159         else
3160         {
3161             // Ab jetzt muss immer invalidiert werden
3162             mbInvalidate = sal_True;
3163 
3164             if ( !pSet->mpWallpaper )
3165                 pSet->mpWallpaper = new Wallpaper( rWallpaper );
3166             else
3167                 *(pSet->mpWallpaper) = rWallpaper;
3168         }
3169 
3170         // Beim MainSet koennen wir den Background umsetzen
3171         if ( pSet == mpMainSet )
3172             ImplInitSettings();
3173 
3174         if ( bUpdate )
3175             ImplUpdateSet( pSet );
3176     }
3177 }
3178 
3179 // -----------------------------------------------------------------------
3180 
3181 Wallpaper SplitWindow::GetItemBackground( sal_uInt16 nSetId ) const
3182 {
3183     ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3184 
3185     if ( pSet && pSet->mpWallpaper )
3186         return *(pSet->mpWallpaper);
3187     else
3188     {
3189         Wallpaper aWall;
3190         return aWall;
3191     }
3192 }
3193 
3194 // -----------------------------------------------------------------------
3195 
3196 sal_Bool SplitWindow::IsItemBackground( sal_uInt16 nSetId ) const
3197 {
3198     ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3199 
3200     if ( pSet && pSet->mpWallpaper )
3201         return sal_True;
3202     else
3203         return sal_False;
3204 }
3205 
3206 // -----------------------------------------------------------------------
3207 
3208 void SplitWindow::SetItemBitmap( sal_uInt16 nSetId, const Bitmap& rBitmap )
3209 {
3210     ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3211 
3212     if ( pSet )
3213     {
3214         sal_Bool bUpdate = sal_True;
3215 
3216         if ( !rBitmap )
3217         {
3218             if ( pSet->mpBitmap )
3219             {
3220                 delete pSet->mpBitmap;
3221                 pSet->mpBitmap = NULL;
3222             }
3223             else
3224                 bUpdate = sal_False;
3225         }
3226         else
3227         {
3228             // Ab jetzt muss immer invalidiert werden
3229             mbInvalidate = sal_True;
3230 
3231             if ( !pSet->mpBitmap )
3232                 pSet->mpBitmap = new Bitmap( rBitmap );
3233             else
3234                 *(pSet->mpBitmap) = rBitmap;
3235         }
3236 
3237         // Beim MainSet koennen wir den Background umsetzen
3238         if ( pSet == mpMainSet )
3239             ImplInitSettings();
3240 
3241         if ( bUpdate )
3242             ImplUpdateSet( pSet );
3243     }
3244 }
3245 
3246 // -----------------------------------------------------------------------
3247 
3248 Bitmap SplitWindow::GetItemBitmap( sal_uInt16 nSetId ) const
3249 {
3250     ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3251 
3252     if ( pSet && pSet->mpBitmap )
3253         return *(pSet->mpBitmap);
3254     else
3255     {
3256         Bitmap aBitmap;
3257         return aBitmap;
3258     }
3259 }
3260 
3261 // -----------------------------------------------------------------------
3262 
3263 void SplitWindow::SplitItem( sal_uInt16 nId, long nNewSize,
3264                              sal_Bool bPropSmall, sal_Bool bPropGreat )
3265 {
3266     sal_uInt16          nItems;
3267     sal_uInt16          nPos;
3268     sal_uInt16          nMin;
3269     sal_uInt16          nMax;
3270     sal_uInt16          i;
3271     sal_uInt16          n;
3272     long            nDelta;
3273     long            nTempDelta;
3274     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3275     ImplSplitItem*  pItems;
3276 
3277     if ( !pSet )
3278         return;
3279 
3280     nItems = pSet->mnItems;
3281     pItems = pSet->mpItems;
3282 
3283     // When there is an explicit minimum or maximum size then move nNewSize
3284     // into that range (when it is not yet already in it.)
3285     nNewSize = ValidateSize(nNewSize, pItems[nPos]);
3286 
3287     if ( mbCalc )
3288     {
3289         pItems[nPos].mnSize = nNewSize;
3290         return;
3291     }
3292 
3293     nDelta = nNewSize-pItems[nPos].mnPixSize;
3294     if ( !nDelta )
3295         return;
3296 
3297     // Bereich berechnen, der beim Splitten betroffen sein kann
3298     nMin = 0;
3299     nMax = nItems;
3300     for ( i = 0; i < nItems; i++ )
3301     {
3302         if ( pItems[i].mbFixed )
3303         {
3304             if ( i < nPos )
3305                 nMin = i+1;
3306             else
3307                 nMax = i;
3308         }
3309     }
3310 
3311     // Wenn das Fenster sizeable ist, wird das TopSet anders behandelt
3312     sal_Bool bSmall  = sal_True;
3313     sal_Bool bGreat  = sal_True;
3314     if ( (pSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) )
3315     {
3316         if ( nPos < pSet->mnItems-1 )
3317         {
3318             if ( !((bPropSmall && bPropGreat) ||
3319                    ((nDelta > 0) && bPropSmall) ||
3320                    ((nDelta < 0) && bPropGreat)) )
3321             {
3322                 if ( nDelta < 0 )
3323                     bGreat = sal_False;
3324                 else
3325                     bSmall = sal_False;
3326             }
3327         }
3328         else
3329         {
3330             if ( nDelta < 0 )
3331                 bGreat = sal_False;
3332             else
3333                 bSmall = sal_False;
3334         }
3335     }
3336     else if ( nPos >= nMax )
3337     {
3338         bSmall = sal_False;
3339         bGreat = sal_False;
3340     }
3341     else if ( nPos && (nPos >= pSet->mnItems-1) )
3342     {
3343         nPos--;
3344         nDelta *= -1;
3345         sal_Bool bTemp = bPropSmall;
3346         bPropSmall = bPropGreat;
3347         bPropGreat = bTemp;
3348     }
3349 
3350     // Jetzt die Fenster splitten
3351     if ( nDelta < 0 )
3352     {
3353         if ( bGreat )
3354         {
3355             if ( bPropGreat )
3356             {
3357                 nTempDelta = nDelta;
3358                 do
3359                 {
3360                     n = nPos+1;
3361                     do
3362                     {
3363                         if ( nTempDelta )
3364                         {
3365                             pItems[n].mnPixSize++;
3366                             nTempDelta++;
3367                         }
3368                         n++;
3369                     }
3370                     while ( n < nMax );
3371                 }
3372                 while ( nTempDelta );
3373             }
3374             else
3375                 pItems[nPos+1].mnPixSize -= nDelta;
3376         }
3377 
3378         if ( bSmall )
3379         {
3380             if ( bPropSmall )
3381             {
3382                 do
3383                 {
3384                     n = nPos+1;
3385                     do
3386                     {
3387                         if ( nDelta && pItems[n-1].mnPixSize )
3388                         {
3389                             pItems[n-1].mnPixSize--;
3390                             nDelta++;
3391                         }
3392 
3393                         n--;
3394                     }
3395                     while ( n > nMin );
3396                 }
3397                 while ( nDelta );
3398             }
3399             else
3400             {
3401                 n = nPos+1;
3402                 do
3403                 {
3404                     if ( pItems[n-1].mnPixSize+nDelta < 0 )
3405                     {
3406                         nDelta += pItems[n-1].mnPixSize;
3407                         pItems[n-1].mnPixSize = 0;
3408                     }
3409                     else
3410                     {
3411                         pItems[n-1].mnPixSize += nDelta;
3412                         break;
3413                     }
3414                     n--;
3415                 }
3416                 while ( n > nMin );
3417             }
3418         }
3419     }
3420     else
3421     {
3422         if ( bGreat )
3423         {
3424             if ( bPropGreat )
3425             {
3426                 nTempDelta = nDelta;
3427                 do
3428                 {
3429                     n = nPos+1;
3430                     do
3431                     {
3432                         if ( nTempDelta )
3433                         {
3434                             pItems[n-1].mnPixSize++;
3435                             nTempDelta--;
3436                         }
3437                         n--;
3438                     }
3439                     while ( n > nMin );
3440                 }
3441                 while ( nTempDelta );
3442             }
3443             else
3444                 pItems[nPos].mnPixSize += nDelta;
3445         }
3446 
3447         if ( bSmall )
3448         {
3449             if ( bPropSmall )
3450             {
3451                 do
3452                 {
3453                     n = nPos+1;
3454                     do
3455                     {
3456                         if ( nDelta && pItems[n].mnPixSize )
3457                         {
3458                             pItems[n].mnPixSize--;
3459                             nDelta--;
3460                         }
3461 
3462                         n++;
3463                     }
3464                     while ( n < nMax );
3465                 }
3466                 while ( nDelta );
3467             }
3468             else
3469             {
3470                 n = nPos+1;
3471                 do
3472                 {
3473                     if ( pItems[n].mnPixSize-nDelta < 0 )
3474                     {
3475                         nDelta -= pItems[n].mnPixSize;
3476                         pItems[n].mnPixSize = 0;
3477                     }
3478                     else
3479                     {
3480                         pItems[n].mnPixSize -= nDelta;
3481                         break;
3482                     }
3483                     n++;
3484                 }
3485                 while ( n < nMax );
3486             }
3487         }
3488     }
3489 
3490     // Original-Groessen updaten
3491     ImplCalcLogSize( pItems, nItems );
3492 
3493     ImplUpdate();
3494 }
3495 
3496 // -----------------------------------------------------------------------
3497 
3498 void SplitWindow::SetItemSize( sal_uInt16 nId, long nNewSize )
3499 {
3500     sal_uInt16          nPos;
3501     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3502     ImplSplitItem*  pItem;
3503 
3504     if ( !pSet )
3505         return;
3506 
3507     // Testen, ob sich Groesse aendert
3508     pItem = &(pSet->mpItems[nPos]);
3509     if ( pItem->mnSize != nNewSize )
3510     {
3511         // Neue Groesse setzen und neu durchrechnen
3512         pItem->mnSize = nNewSize;
3513         pSet->mbCalcPix = sal_True;
3514         ImplUpdate();
3515     }
3516 }
3517 
3518 // -----------------------------------------------------------------------
3519 
3520 long SplitWindow::GetItemSize( sal_uInt16 nId ) const
3521 {
3522     sal_uInt16          nPos;
3523     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3524 
3525     if ( pSet )
3526         return pSet->mpItems[nPos].mnSize;
3527     else
3528         return 0;
3529 }
3530 
3531 // -----------------------------------------------------------------------
3532 
3533 long SplitWindow::GetItemSize( sal_uInt16 nId, SplitWindowItemBits nBits ) const
3534 {
3535     sal_uInt16          nPos;
3536     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3537 
3538     if ( pSet )
3539     {
3540         if ( nBits == pSet->mpItems[nPos].mnBits )
3541             return pSet->mpItems[nPos].mnSize;
3542         else
3543         {
3544             ((SplitWindow*)this)->ImplCalcLayout();
3545 
3546             long                nRelSize = 0;
3547             long                nPerSize = 0;
3548             ImplSplitItem*      pItems;
3549             sal_uInt16              nItems;
3550             SplitWindowItemBits nTempBits;
3551             sal_uInt16              i;
3552             nItems = pSet->mnItems;
3553             pItems = pSet->mpItems;
3554             for ( i = 0; i < nItems; i++ )
3555             {
3556                 if ( i == nPos )
3557                     nTempBits = nBits;
3558                 else
3559                     nTempBits = pItems[i].mnBits;
3560                 if ( nTempBits & SWIB_RELATIVESIZE )
3561                     nRelSize += pItems[i].mnPixSize;
3562                 else if ( nTempBits & SWIB_PERCENTSIZE )
3563                     nPerSize += pItems[i].mnPixSize;
3564             }
3565             nPerSize += nRelSize;
3566             if ( nBits & SWIB_RELATIVESIZE )
3567             {
3568                 if ( nRelSize )
3569                     return (pItems[nPos].mnPixSize+(nRelSize/2))/nRelSize;
3570                 else
3571                     return 1;
3572             }
3573             else if ( nBits & SWIB_PERCENTSIZE )
3574             {
3575                 if ( nPerSize )
3576                     return (pItems[nPos].mnPixSize*100)/nPerSize;
3577                 else
3578                     return 1;
3579             }
3580             else
3581                 return pItems[nPos].mnPixSize;
3582         }
3583     }
3584     else
3585         return 0;
3586 }
3587 
3588 
3589 
3590 
3591 void SplitWindow::SetItemSizeRange (sal_uInt16 nId, const Range aRange)
3592 {
3593     sal_uInt16 nPos;
3594     ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos);
3595 
3596     if (pSet != NULL)
3597     {
3598         pSet->mpItems[nPos].mnMinSize = aRange.Min();
3599         pSet->mpItems[nPos].mnMaxSize = aRange.Max();
3600     }
3601 }
3602 
3603 
3604 
3605 
3606 Range SplitWindow::GetItemSizeRange (sal_uInt16 nId) const
3607 {
3608     sal_uInt16 nPos;
3609     ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos);
3610 
3611     if (pSet != NULL)
3612         return Range (pSet->mpItems[nPos].mnMinSize, pSet->mpItems[nPos].mnMaxSize);
3613     else
3614         return Range(-1,-1);
3615 }
3616 
3617 
3618 // -----------------------------------------------------------------------
3619 
3620 void SplitWindow::SetItemBits( sal_uInt16 nId, SplitWindowItemBits nNewBits )
3621 {
3622     sal_uInt16          nPos;
3623     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3624     ImplSplitItem*  pItem;
3625 
3626     if ( !pSet )
3627         return;
3628 
3629     pItem = &(pSet->mpItems[nPos]);
3630     if ( pItem->mpWindow )
3631         nNewBits &= ~SWIB_COLSET;
3632 
3633     if ( pItem->mnBits != nNewBits )
3634     {
3635         // Neue Bits setzen und neu durchrechnen
3636         pItem->mnBits = nNewBits;
3637         pSet->mbCalcPix = sal_True;
3638         ImplUpdate();
3639     }
3640 }
3641 
3642 // -----------------------------------------------------------------------
3643 
3644 SplitWindowItemBits SplitWindow::GetItemBits( sal_uInt16 nId ) const
3645 {
3646     sal_uInt16          nPos;
3647     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3648 
3649     if ( pSet )
3650         return pSet->mpItems[nPos].mnBits;
3651     else
3652         return 0;
3653 }
3654 
3655 // -----------------------------------------------------------------------
3656 
3657 Window* SplitWindow::GetItemWindow( sal_uInt16 nId ) const
3658 {
3659     sal_uInt16          nPos;
3660     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3661 
3662     if ( pSet )
3663         return pSet->mpItems[nPos].mpWindow;
3664     else
3665         return NULL;
3666 }
3667 
3668 // -----------------------------------------------------------------------
3669 
3670 sal_uInt16 SplitWindow::GetSet( sal_uInt16 nId ) const
3671 {
3672     sal_uInt16          nPos;
3673     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3674 
3675     if ( pSet )
3676         return pSet->mnId;
3677     else
3678         return 0;
3679 }
3680 
3681 // -----------------------------------------------------------------------
3682 
3683 sal_Bool SplitWindow::GetSet( sal_uInt16 nId, sal_uInt16& rSetId, sal_uInt16& rPos ) const
3684 {
3685     ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, rPos );
3686     if ( pSet )
3687     {
3688         rSetId = pSet->mnId;
3689         return sal_True;
3690     }
3691     else
3692         return sal_False;
3693 }
3694 
3695 // -----------------------------------------------------------------------
3696 
3697 sal_Bool SplitWindow::IsItemValid( sal_uInt16 nId ) const
3698 {
3699     sal_uInt16          nPos;
3700     ImplSplitSet*   pSet = ImplFindItem( mpBaseSet, nId, nPos );
3701 
3702     if ( pSet )
3703         return sal_True;
3704     else
3705         return sal_False;
3706 }
3707 
3708 // -----------------------------------------------------------------------
3709 
3710 sal_uInt16 SplitWindow::GetItemId( Window* pWindow ) const
3711 {
3712     return ImplFindItem( mpBaseSet, pWindow );
3713 }
3714 
3715 // -----------------------------------------------------------------------
3716 
3717 sal_uInt16 SplitWindow::GetItemId( const Point& rPos ) const
3718 {
3719     return ImplFindItem( mpBaseSet, rPos, mbHorz, !mbBottomRight );
3720 }
3721 
3722 // -----------------------------------------------------------------------
3723 
3724 sal_uInt16 SplitWindow::GetItemPos( sal_uInt16 nId, sal_uInt16 nSetId ) const
3725 {
3726     ImplSplitSet*   pSet = ImplFindSet( mpBaseSet, nSetId );
3727     sal_uInt16          nPos = SPLITWINDOW_ITEM_NOTFOUND;
3728 
3729     if ( pSet )
3730     {
3731         for ( sal_uInt16 i = 0; i < pSet->mnItems; i++ )
3732         {
3733             if ( pSet->mpItems[i].mnId == nId )
3734             {
3735                 nPos = i;
3736                 break;
3737             }
3738         }
3739     }
3740 
3741     return nPos;
3742 }
3743 
3744 // -----------------------------------------------------------------------
3745 
3746 sal_uInt16 SplitWindow::GetItemId( sal_uInt16 nPos, sal_uInt16 nSetId ) const
3747 {
3748     ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
3749     if ( pSet && (nPos < pSet->mnItems) )
3750         return pSet->mpItems[nPos].mnId;
3751     else
3752         return 0;
3753 }
3754 
3755 // -----------------------------------------------------------------------
3756 
3757 sal_uInt16 SplitWindow::GetItemCount( sal_uInt16 nSetId ) const
3758 {
3759     ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
3760     if ( pSet )
3761         return pSet->mnItems;
3762     else
3763         return 0;
3764 }
3765 
3766 // -----------------------------------------------------------------------
3767 
3768 void SplitWindow::ImplNewAlign()
3769 {
3770     if ( mbNoAlign )
3771     {
3772         mbHorz        = sal_False;
3773         mbBottomRight = sal_False;
3774     }
3775     else if ( meAlign == WINDOWALIGN_TOP )
3776     {
3777         mbHorz        = sal_True;
3778         mbBottomRight = sal_False;
3779     }
3780     else if ( meAlign == WINDOWALIGN_BOTTOM )
3781     {
3782         mbHorz        = sal_True;
3783         mbBottomRight = sal_True;
3784     }
3785     else if ( meAlign == WINDOWALIGN_LEFT )
3786     {
3787         mbHorz        = sal_False;
3788         mbBottomRight = sal_False;
3789     }
3790     else if ( meAlign == WINDOWALIGN_RIGHT )
3791     {
3792         mbHorz        = sal_False;
3793         mbBottomRight = sal_True;
3794     }
3795 
3796     if ( mnWinStyle & WB_BORDER )
3797     {
3798         ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
3799                         mnRightBorder, mnBottomBorder );
3800     }
3801 
3802     if ( IsReallyVisible() && IsUpdateMode() )
3803         Invalidate();
3804     ImplUpdate();
3805 }
3806 
3807 // -----------------------------------------------------------------------
3808 
3809 void SplitWindow::SetNoAlign( sal_Bool bNoAlign )
3810 {
3811     bNoAlign = bNoAlign != 0;
3812     if ( mbNoAlign != bNoAlign )
3813     {
3814         mbNoAlign = bNoAlign;
3815         ImplNewAlign();
3816     }
3817 }
3818 
3819 // -----------------------------------------------------------------------
3820 
3821 void SplitWindow::SetAlign( WindowAlign eNewAlign )
3822 {
3823     if ( meAlign != eNewAlign )
3824     {
3825         meAlign = eNewAlign;
3826         ImplNewAlign();
3827     }
3828 }
3829 
3830 // -----------------------------------------------------------------------
3831 
3832 Size SplitWindow::CalcWindowSizePixel( const Size& rSize, WindowAlign eAlign,
3833                                        WinBits nWinStyle, sal_Bool bExtra )
3834 {
3835     long    nLeft;
3836     long    nTop;
3837     long    nRight;
3838     long    nBottom;
3839     Size    aSize = rSize;
3840 
3841     ImplCalcBorder( eAlign, sal_False, nLeft, nTop, nRight, nBottom );
3842     aSize.Width()   += nLeft+nRight;
3843     aSize.Height()  += nTop+nBottom;
3844 
3845     if ( nWinStyle & WB_SIZEABLE )
3846     {
3847         if ( (eAlign == WINDOWALIGN_TOP) || (eAlign == WINDOWALIGN_BOTTOM) )
3848         {
3849             aSize.Height() += SPLITWIN_SPLITSIZE-2;
3850             if ( bExtra )
3851                 aSize.Height() += SPLITWIN_SPLITSIZEEXLN;
3852         }
3853         else
3854         {
3855             aSize.Width() += SPLITWIN_SPLITSIZE-2;
3856             if ( bExtra )
3857                 aSize.Width() += SPLITWIN_SPLITSIZEEXLN;
3858         }
3859     }
3860 
3861     return aSize;
3862 }
3863 
3864 // -----------------------------------------------------------------------
3865 
3866 void SplitWindow::ShowAutoHideButton( sal_Bool bShow )
3867 {
3868     mbAutoHide = bShow;
3869     ImplUpdate();
3870 }
3871 
3872 // -----------------------------------------------------------------------
3873 
3874 void SplitWindow::ShowFadeInHideButton( sal_Bool bShow )
3875 {
3876     mbFadeIn = bShow;
3877     ImplUpdate();
3878 }
3879 
3880 // -----------------------------------------------------------------------
3881 
3882 void SplitWindow::ShowFadeOutButton( sal_Bool bShow )
3883 {
3884     mbFadeOut = bShow;
3885     ImplUpdate();
3886 }
3887 
3888 // -----------------------------------------------------------------------
3889 
3890 void SplitWindow::SetAutoHideState( sal_Bool bAutoHide )
3891 {
3892     mbAutoHideIn = bAutoHide;
3893     if ( IsReallyVisible() )
3894     {
3895         Rectangle aRect;
3896         ImplGetAutoHideRect( aRect );
3897         Invalidate( aRect );
3898     }
3899 }
3900 
3901 // -----------------------------------------------------------------------
3902 
3903 long SplitWindow::GetFadeInSize() const
3904 {
3905     long n = 0;
3906 
3907     if ( mbHorz )
3908         n = mnTopBorder+mnBottomBorder;
3909     else
3910         n = mnLeftBorder+mnRightBorder;
3911 
3912     return n+SPLITWIN_SPLITSIZE+SPLITWIN_SPLITSIZEEX-2;
3913 }
3914 
3915 // -----------------------------------------------------------------------
3916 
3917 Rectangle SplitWindow::GetAutoHideRect() const
3918 {
3919     Rectangle aRect;
3920     ImplGetAutoHideRect( aRect, sal_True );
3921     return aRect;
3922 }
3923 
3924 // -----------------------------------------------------------------------
3925 
3926 Rectangle SplitWindow::GetFadeInRect() const
3927 {
3928     Rectangle aRect;
3929     ImplGetFadeInRect( aRect, sal_True );
3930     return aRect;
3931 }
3932 
3933 // -----------------------------------------------------------------------
3934 
3935 Rectangle SplitWindow::GetFadeOutRect() const
3936 {
3937     Rectangle aRect;
3938     ImplGetFadeOutRect( aRect, sal_True );
3939     return aRect;
3940 }
3941