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