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