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_svtools.hxx"
30 #include <tools/list.hxx>
31 #include <tools/debug.hxx>
32 #include <vcl/decoview.hxx>
33 #include <vcl/svapp.hxx>
34 #ifndef _SCRBAR_HXX
35 #include <vcl/scrbar.hxx>
36 #endif
37 #ifndef _HELP_HXX
38 #include <vcl/help.hxx>
39 #endif
40 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
41 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
42 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 #include <com/sun/star/lang/XComponent.hpp>
44 #include <rtl/ustring.hxx>
45 
46 #include "valueimp.hxx"
47 
48 #define _SV_VALUESET_CXX
49 #include <svtools/valueset.hxx>
50 
51 // ------------
52 // - ValueSet -
53 // ------------
54 
55 void ValueSet::ImplInit()
56 {
57 	// Size aWinSize		= GetSizePixel();
58     mpImpl              = new ValueSet_Impl;
59 	mpNoneItem			= NULL;
60 	mpScrBar			= NULL;
61 	mnTextOffset		= 0;
62 	mnVisLines			= 0;
63 	mnLines 			= 0;
64 	mnUserItemWidth 	= 0;
65 	mnUserItemHeight	= 0;
66 	mnFirstLine 		= 0;
67 	mnOldItemId 		= 0;
68 	mnSelItemId 		= 0;
69 	mnHighItemId		= 0;
70 	mnDropPos			= VALUESET_ITEM_NOTFOUND;
71 	mnCols				= 0;
72 	mnCurCol			= 0;
73 	mnUserCols			= 0;
74 	mnUserVisLines		= 0;
75 	mnSpacing			= 0;
76 	mnFrameStyle		= 0;
77 	mbFormat			= sal_True;
78 	mbHighlight 		= sal_False ;
79 	mbSelection 		= sal_False;
80 	mbNoSelection		= sal_True;
81 	mbDrawSelection 	= sal_True;
82 	mbBlackSel			= sal_False;
83 	mbDoubleSel 		= sal_False;
84 	mbScroll			= sal_False;
85 	mbDropPos			= sal_False;
86 	mbFullMode			= sal_True;
87 
88     // #106446#, #106601# force mirroring of virtual device
89     maVirDev.EnableRTL( GetParent()->IsRTLEnabled() );
90 
91 	ImplInitSettings( sal_True, sal_True, sal_True );
92 }
93 
94 // -----------------------------------------------------------------------
95 
96 ValueSet::ValueSet( Window* pParent, WinBits nWinStyle, bool bDisableTransientChildren ) :
97 	Control( pParent, nWinStyle ),
98 	maVirDev( *this ),
99 	maColor( COL_TRANSPARENT )
100 {
101 	ImplInit();
102     if( mpImpl )
103         mpImpl->mbIsTransientChildrenDisabled = bDisableTransientChildren;
104 }
105 
106 // -----------------------------------------------------------------------
107 
108 ValueSet::ValueSet( Window* pParent, const ResId& rResId, bool bDisableTransientChildren ) :
109 	Control( pParent, rResId ),
110 	maVirDev( *this ),
111 	maColor( COL_TRANSPARENT )
112 {
113 	ImplInit();
114     if( mpImpl )
115         mpImpl->mbIsTransientChildrenDisabled = bDisableTransientChildren;
116 }
117 
118 // -----------------------------------------------------------------------
119 
120 ValueSet::~ValueSet()
121 {
122     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
123           xComponent (GetAccessible(sal_False), ::com::sun::star::uno::UNO_QUERY);
124     if (xComponent.is())
125         xComponent->dispose ();
126 
127 	if ( mpScrBar )
128 		delete mpScrBar;
129 
130 	if ( mpNoneItem )
131 		delete mpNoneItem;
132 
133 	ImplDeleteItems();
134     delete mpImpl;
135 }
136 
137 // -----------------------------------------------------------------------
138 
139 void ValueSet::ImplDeleteItems()
140 {
141     for( ValueSetItem* pItem = mpImpl->mpItemList->First(); pItem; pItem = mpImpl->mpItemList->Next() )
142 	{
143         if( !pItem->maRect.IsEmpty() && ImplHasAccessibleListeners() )
144         {
145             ::com::sun::star::uno::Any aOldAny, aNewAny;
146 
147             aOldAny <<= pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled );
148             ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
149         }
150 
151 		delete pItem;
152 	}
153 
154     mpImpl->mpItemList->Clear();
155 }
156 
157 // -----------------------------------------------------------------------
158 
159 void ValueSet::ImplInitSettings( sal_Bool bFont,
160 								 sal_Bool bForeground, sal_Bool bBackground )
161 {
162 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
163 
164 	if ( bFont )
165 	{
166 		Font aFont;
167 		aFont = rStyleSettings.GetAppFont();
168 		if ( IsControlFont() )
169 			aFont.Merge( GetControlFont() );
170 		SetZoomedPointFont( aFont );
171 	}
172 
173 	if ( bForeground || bFont )
174 	{
175 		Color aColor;
176 		if ( IsControlForeground() )
177 			aColor = GetControlForeground();
178 		else
179 			aColor = rStyleSettings.GetButtonTextColor();
180 		SetTextColor( aColor );
181 		SetTextFillColor();
182 	}
183 
184 	if ( bBackground )
185 	{
186 		Color aColor;
187 		if ( IsControlBackground() )
188 			aColor = GetControlBackground();
189         else if ( GetStyle() & WB_MENUSTYLEVALUESET )
190             aColor = rStyleSettings.GetMenuColor();
191         else if ( IsEnabled() && (GetStyle() & WB_FLATVALUESET) )
192             aColor = rStyleSettings.GetWindowColor();
193 		else
194 			aColor = rStyleSettings.GetFaceColor();
195 		SetBackground( aColor );
196 	}
197 }
198 
199 // -----------------------------------------------------------------------
200 
201 void ValueSet::ImplInitScrollBar()
202 {
203 	if ( GetStyle() & WB_VSCROLL )
204 	{
205 		if ( !mpScrBar )
206 		{
207 			mpScrBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
208 			mpScrBar->SetScrollHdl( LINK( this, ValueSet, ImplScrollHdl ) );
209 		}
210 		else
211 		{
212 			// Wegen Einstellungsaenderungen passen wir hier die Breite an
213 			long nScrBarWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
214 			mpScrBar->SetPosSizePixel( 0, 0, nScrBarWidth, 0, WINDOW_POSSIZE_WIDTH );
215 		}
216 	}
217 }
218 
219 // -----------------------------------------------------------------------
220 
221 void ValueSet::ImplFormatItem( ValueSetItem* pItem )
222 {
223 	if ( pItem->meType == VALUESETITEM_SPACE )
224 		return;
225 
226 	Rectangle aRect = pItem->maRect;
227 	WinBits nStyle = GetStyle();
228 	if ( nStyle & WB_ITEMBORDER )
229 	{
230 		aRect.Left()++;
231 		aRect.Top()++;
232 		aRect.Right()--;
233 		aRect.Bottom()--;
234 		if ( nStyle & WB_FLATVALUESET )
235 		{
236 			if ( nStyle  & WB_DOUBLEBORDER )
237 			{
238 				aRect.Left()	+= 2;
239 				aRect.Top() 	+= 2;
240 				aRect.Right()	-= 2;
241 				aRect.Bottom()	-= 2;
242 			}
243 			else
244 			{
245 				aRect.Left()++;
246 				aRect.Top()++;
247 				aRect.Right()--;
248 				aRect.Bottom()--;
249 			}
250 		}
251 		else
252 		{
253 			DecorationView aView( &maVirDev );
254 			aRect = aView.DrawFrame( aRect, mnFrameStyle );
255 		}
256 	}
257 
258 	if ( pItem == mpNoneItem )
259 		pItem->maText = GetText();
260 
261 	if ( (aRect.GetHeight() > 0) && (aRect.GetWidth() > 0) )
262 	{
263 		if ( pItem == mpNoneItem )
264 		{
265 			const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
266 			maVirDev.SetFont( GetFont() );
267 			maVirDev.SetTextColor( ( nStyle & WB_MENUSTYLEVALUESET ) ? rStyleSettings.GetMenuTextColor() : rStyleSettings.GetWindowTextColor() );
268 			maVirDev.SetTextFillColor();
269 			maVirDev.SetFillColor( ( nStyle & WB_MENUSTYLEVALUESET ) ? rStyleSettings.GetMenuColor() : rStyleSettings.GetWindowColor() );
270 			maVirDev.DrawRect( aRect );
271 			Point	aTxtPos( aRect.Left()+2, aRect.Top() );
272 			long	nTxtWidth = GetTextWidth( pItem->maText );
273 			if ( nStyle & WB_RADIOSEL )
274 			{
275 				aTxtPos.X() += 4;
276 				aTxtPos.Y() += 4;
277 			}
278 			if ( (aTxtPos.X()+nTxtWidth) > aRect.Right() )
279 			{
280 				maVirDev.SetClipRegion( Region( aRect ) );
281 				maVirDev.DrawText( aTxtPos, pItem->maText );
282 				maVirDev.SetClipRegion();
283 			}
284 			else
285 				maVirDev.DrawText( aTxtPos, pItem->maText );
286 		}
287 		else if ( pItem->meType == VALUESETITEM_COLOR )
288 		{
289 			maVirDev.SetFillColor( pItem->maColor );
290 			maVirDev.DrawRect( aRect );
291 		}
292 		else
293 		{
294 			const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
295 			if ( IsColor() )
296 				maVirDev.SetFillColor( maColor );
297             else if ( nStyle & WB_MENUSTYLEVALUESET )
298                 maVirDev.SetFillColor( rStyleSettings.GetMenuColor() );
299             else if ( IsEnabled() )
300                 maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
301             else
302                 maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
303 			maVirDev.DrawRect( aRect );
304 
305 			if ( pItem->meType == VALUESETITEM_USERDRAW )
306 			{
307 				UserDrawEvent aUDEvt( &maVirDev, aRect, pItem->mnId );
308 				UserDraw( aUDEvt );
309 			}
310 			else
311 			{
312 				Size	aImageSize = pItem->maImage.GetSizePixel();
313 				Size	aRectSize = aRect.GetSize();
314 				Point	aPos( aRect.Left(), aRect.Top() );
315 				aPos.X() += (aRectSize.Width()-aImageSize.Width())/2;
316 				aPos.Y() += (aRectSize.Height()-aImageSize.Height())/2;
317 
318 			    sal_uInt16  nImageStyle  = 0;
319                 if( !IsEnabled() )
320 					nImageStyle  |= IMAGE_DRAW_DISABLE;
321 
322 				if ( (aImageSize.Width()  > aRectSize.Width()) ||
323 					 (aImageSize.Height() > aRectSize.Height()) )
324 				{
325 					maVirDev.SetClipRegion( Region( aRect ) );
326 					maVirDev.DrawImage( aPos, pItem->maImage, nImageStyle);
327 					maVirDev.SetClipRegion();
328 				}
329 				else
330 					maVirDev.DrawImage( aPos, pItem->maImage, nImageStyle );
331 			}
332 		}
333 	}
334 }
335 
336 // -----------------------------------------------------------------------
337 
338 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ValueSet::CreateAccessible()
339 {
340     return new ValueSetAcc( this, mpImpl->mbIsTransientChildrenDisabled );
341 }
342 
343 // -----------------------------------------------------------------------
344 
345 void ValueSet::Format()
346 {
347 	Size		aWinSize = GetOutputSizePixel();
348     sal_uLong       nItemCount = mpImpl->mpItemList->Count();
349 	WinBits 	nStyle = GetStyle();
350 	long		nTxtHeight = GetTextHeight();
351 	long		nOff;
352 	long		nSpace;
353 	long		nNoneHeight;
354 	long		nNoneSpace;
355 	ScrollBar*	pDelScrBar = NULL;
356 
357 	// Scrolling beruecksichtigen
358 	if ( nStyle & WB_VSCROLL )
359 		ImplInitScrollBar();
360 	else
361 	{
362 		if ( mpScrBar )
363 		{
364 			// ScrollBar erst spaeter zerstoeren, damit keine rekursiven
365 			// Aufrufe entstehen koennen
366 			pDelScrBar = mpScrBar;
367 			mpScrBar = NULL;
368 		}
369 	}
370 
371 	// Item-Offset berechnen
372 	if ( nStyle & WB_ITEMBORDER )
373 	{
374 		if ( nStyle & WB_DOUBLEBORDER )
375 			nOff = ITEM_OFFSET_DOUBLE;
376 		else
377 			nOff = ITEM_OFFSET;
378 	}
379 	else
380 		nOff = 0;
381 	nSpace = mnSpacing;
382 
383 	// Groesse beruecksichtigen, wenn NameField vorhanden
384 	if ( nStyle & WB_NAMEFIELD )
385 	{
386 		mnTextOffset = aWinSize.Height()-nTxtHeight-NAME_OFFSET;
387 		aWinSize.Height() -= nTxtHeight+NAME_OFFSET;
388 
389 		if ( !(nStyle & WB_FLATVALUESET) )
390 		{
391 			mnTextOffset -= NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
392 			aWinSize.Height() -= NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
393 		}
394 	}
395 	else
396 		mnTextOffset = 0;
397 
398 	// Offset und Groesse beruecksichtigen, wenn NoneField vorhanden
399 	if ( nStyle & WB_NONEFIELD )
400 	{
401 		nNoneHeight = nTxtHeight+nOff;
402 		nNoneSpace = nSpace;
403 		if ( nStyle & WB_RADIOSEL )
404 			nNoneHeight += 8;
405 	}
406 	else
407 	{
408 		nNoneHeight = 0;
409 		nNoneSpace = 0;
410 
411 		if ( mpNoneItem )
412 		{
413 			delete mpNoneItem;
414 			mpNoneItem = NULL;
415 		}
416 	}
417 
418 	// Breite vom ScrollBar berechnen
419 	long nScrBarWidth = 0;
420 	if ( mpScrBar )
421 		nScrBarWidth = mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
422 
423 	// Spaltenanzahl berechnen
424 	if ( !mnUserCols )
425 	{
426 		if ( mnUserItemWidth )
427 		{
428 			mnCols = (sal_uInt16)((aWinSize.Width()-nScrBarWidth+nSpace) / (mnUserItemWidth+nSpace));
429 			if ( !mnCols )
430 				mnCols = 1;
431 		}
432 		else
433 			mnCols = 1;
434 	}
435 	else
436 		mnCols = mnUserCols;
437 
438 	// Zeilenanzahl berechnen
439 	mbScroll = sal_False;
440     mnLines = (long)mpImpl->mpItemList->Count() / mnCols;
441     if ( mpImpl->mpItemList->Count() % mnCols )
442 		mnLines++;
443 	else if ( !mnLines )
444 		mnLines = 1;
445 
446 	long nCalcHeight = aWinSize.Height()-nNoneHeight;
447 	if ( mnUserVisLines )
448 		mnVisLines = mnUserVisLines;
449 	else if ( mnUserItemHeight )
450 	{
451 		mnVisLines = (nCalcHeight-nNoneSpace+nSpace) / (mnUserItemHeight+nSpace);
452 		if ( !mnVisLines )
453 			mnVisLines = 1;
454 	}
455 	else
456 		mnVisLines = mnLines;
457 	if ( mnLines > mnVisLines )
458 		mbScroll = sal_True;
459 	if ( mnLines <= mnVisLines )
460 		mnFirstLine = 0;
461 	else
462 	{
463 		if ( mnFirstLine > (sal_uInt16)(mnLines-mnVisLines) )
464 			mnFirstLine = (sal_uInt16)(mnLines-mnVisLines);
465 	}
466 
467 	// Itemgroessen berechnen
468 	long nColSpace	= (mnCols-1)*nSpace;
469 	long nLineSpace = ((mnVisLines-1)*nSpace)+nNoneSpace;
470 	long nItemWidth;
471 	long nItemHeight;
472 	if ( mnUserItemWidth && !mnUserCols )
473 	{
474 		nItemWidth = mnUserItemWidth;
475 		if ( nItemWidth > aWinSize.Width()-nScrBarWidth-nColSpace )
476 			nItemWidth = aWinSize.Width()-nScrBarWidth-nColSpace;
477 	}
478 	else
479 		nItemWidth = (aWinSize.Width()-nScrBarWidth-nColSpace) / mnCols;
480 	if ( mnUserItemHeight && !mnUserVisLines )
481 	{
482 		nItemHeight = mnUserItemHeight;
483 		if ( nItemHeight > nCalcHeight-nNoneSpace )
484 			nItemHeight = nCalcHeight-nNoneSpace;
485 	}
486 	else
487 	{
488 		nCalcHeight -= nLineSpace;
489 		nItemHeight = nCalcHeight / mnVisLines;
490 	}
491 
492 	// Init VirDev
493 	maVirDev.SetSettings( GetSettings() );
494 	maVirDev.SetBackground( GetBackground() );
495 	maVirDev.SetOutputSizePixel( aWinSize, sal_True );
496 
497 	// Bei zu kleinen Items machen wir nichts
498 	long nMinHeight = 2;
499 	if ( nStyle & WB_ITEMBORDER )
500 		nMinHeight = 4;
501 	if ( (nItemWidth <= 0) || (nItemHeight <= nMinHeight) || !nItemCount )
502 	{
503 		if ( nStyle & WB_NONEFIELD )
504 		{
505 			if ( mpNoneItem )
506 			{
507 				mpNoneItem->maRect.SetEmpty();
508 				mpNoneItem->maText = GetText();
509 			}
510 		}
511 
512 		for ( sal_uLong i = 0; i < nItemCount; i++ )
513 		{
514             ValueSetItem* pItem = mpImpl->mpItemList->GetObject( i );
515 			pItem->maRect.SetEmpty();
516 		}
517 
518 		if ( mpScrBar )
519 			mpScrBar->Hide();
520 	}
521 	else
522 	{
523 		// Frame-Style ermitteln
524 		if ( nStyle & WB_DOUBLEBORDER )
525 			mnFrameStyle = FRAME_DRAW_DOUBLEIN;
526 		else
527 			mnFrameStyle = FRAME_DRAW_IN;
528 
529 		// Selektionsfarben und -breiten ermitteln
530 		// Gegebenenfalls die Farben anpassen, damit man die Selektion besser
531 		// erkennen kann
532 		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
533 		Color aHighColor( rStyleSettings.GetHighlightColor() );
534 		if ( ((aHighColor.GetRed() > 0x80) || (aHighColor.GetGreen() > 0x80) ||
535 			  (aHighColor.GetBlue() > 0x80)) ||
536 			 ((aHighColor.GetRed() == 0x80) && (aHighColor.GetGreen() == 0x80) &&
537 			  (aHighColor.GetBlue() == 0x80)) )
538 			mbBlackSel = sal_True;
539 		else
540 			mbBlackSel = sal_False;
541 
542 		// Wenn die Items groesser sind, dann die Selektion doppelt so breit
543 		// zeichnen
544 		if ( (nStyle & WB_DOUBLEBORDER) &&
545 			 ((nItemWidth >= 25) && (nItemHeight >= 20)) )
546 			mbDoubleSel = sal_True;
547 		else
548 			mbDoubleSel = sal_False;
549 
550 		// Calculate offsets
551 		long nStartX;
552 		long nStartY;
553 		if ( mbFullMode )
554 		{
555 			long nAllItemWidth = (nItemWidth*mnCols)+nColSpace;
556 			long nAllItemHeight = (nItemHeight*mnVisLines)+nNoneHeight+nLineSpace;
557 			nStartX = (aWinSize.Width()-nScrBarWidth-nAllItemWidth)/2;
558 			nStartY = (aWinSize.Height()-nAllItemHeight)/2;
559 		}
560 		else
561 		{
562 			nStartX = 0;
563 			nStartY = 0;
564 		}
565 
566 		// Items berechnen und zeichnen
567 		maVirDev.SetLineColor();
568 		long x = nStartX;
569 		long y = nStartY;
570 
571 		// NoSelection-Field erzeugen und anzeigen
572 		if ( nStyle & WB_NONEFIELD )
573 		{
574 			if ( !mpNoneItem )
575 				mpNoneItem = new ValueSetItem( *this );
576 
577 			mpNoneItem->mnId			= 0;
578 			mpNoneItem->meType			= VALUESETITEM_NONE;
579 			mpNoneItem->maRect.Left()	= x;
580 			mpNoneItem->maRect.Top()	= y;
581 			mpNoneItem->maRect.Right()	= mpNoneItem->maRect.Left()+aWinSize.Width()-x-1;
582 			mpNoneItem->maRect.Bottom() = y+nNoneHeight-1;
583 
584 			ImplFormatItem( mpNoneItem );
585 
586 			y += nNoneHeight+nNoneSpace;
587 		}
588 
589 		// draw items
590 		sal_uLong nFirstItem = mnFirstLine * mnCols;
591 		sal_uLong nLastItem = nFirstItem + (mnVisLines * mnCols);
592 
593         if ( !mbFullMode )
594 		{
595 			// If want also draw parts of items in the last line,
596 			// then we add one more line if parts of these line are
597 			// visible
598 			if ( y+(mnVisLines*(nItemHeight+nSpace)) < aWinSize.Height() )
599 				nLastItem += mnCols;
600 		}
601 		for ( sal_uLong i = 0; i < nItemCount; i++ )
602 		{
603             ValueSetItem*   pItem = mpImpl->mpItemList->GetObject( i );
604 
605 			if ( (i >= nFirstItem) && (i < nLastItem) )
606 			{
607                 const sal_Bool bWasEmpty = pItem->maRect.IsEmpty();
608 
609 				pItem->maRect.Left()	= x;
610 				pItem->maRect.Top() 	= y;
611 				pItem->maRect.Right()	= pItem->maRect.Left()+nItemWidth-1;
612 				pItem->maRect.Bottom()	= pItem->maRect.Top()+nItemHeight-1;
613 
614                 if( bWasEmpty && ImplHasAccessibleListeners() )
615                 {
616                     ::com::sun::star::uno::Any aOldAny, aNewAny;
617 
618                     aNewAny <<= pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled );
619                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
620                 }
621 
622 				ImplFormatItem( pItem );
623 
624 				if ( !((i+1) % mnCols) )
625 				{
626 					x = nStartX;
627 					y += nItemHeight+nSpace;
628 				}
629 				else
630 					x += nItemWidth+nSpace;
631 			}
632 			else
633             {
634                 if( !pItem->maRect.IsEmpty() && ImplHasAccessibleListeners() )
635                 {
636                     ::com::sun::star::uno::Any aOldAny, aNewAny;
637 
638                     aOldAny <<= pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled );
639                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
640                 }
641 
642                 pItem->maRect.SetEmpty();
643             }
644 		}
645 
646 		// ScrollBar anordnen, Werte setzen und anzeigen
647 		if ( mpScrBar )
648 		{
649 			Point	aPos( aWinSize.Width()-nScrBarWidth+SCRBAR_OFFSET, 0 );
650 			Size	aSize( nScrBarWidth-SCRBAR_OFFSET, aWinSize.Height() );
651 			// If a none field is visible, then we center the scrollbar
652 			if ( nStyle & WB_NONEFIELD )
653 			{
654 				aPos.Y() = nStartY+nNoneHeight+1;
655 				aSize.Height() = ((nItemHeight+nSpace)*mnVisLines)-2-nSpace;
656 			}
657 			mpScrBar->SetPosSizePixel( aPos, aSize );
658 			mpScrBar->SetRangeMax( mnLines );
659 			mpScrBar->SetVisibleSize( mnVisLines );
660 			mpScrBar->SetThumbPos( (long)mnFirstLine );
661 			long nPageSize = mnVisLines;
662 			if ( nPageSize < 1 )
663 				nPageSize = 1;
664 			mpScrBar->SetPageSize( nPageSize );
665 			mpScrBar->Show();
666 		}
667 	}
668 
669 	// Jetzt haben wir formatiert und warten auf das naechste
670 	mbFormat = sal_False;
671 
672 	// ScrollBar loeschen
673 	if ( pDelScrBar )
674 		delete pDelScrBar;
675 }
676 
677 // -----------------------------------------------------------------------
678 
679 void ValueSet::ImplDrawItemText( const XubString& rText )
680 {
681 	if ( !(GetStyle() & WB_NAMEFIELD) )
682 		return;
683 
684 	Size	aWinSize = GetOutputSizePixel();
685 	long	nTxtWidth = GetTextWidth( rText );
686 	long	nTxtOffset = mnTextOffset;
687 
688 	// Rechteck loeschen und Text ausgeben
689 	if ( GetStyle() & WB_FLATVALUESET )
690 	{
691 		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
692 		SetLineColor();
693 		SetFillColor( rStyleSettings.GetFaceColor() );
694 		DrawRect( Rectangle( Point( 0, nTxtOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
695 		SetTextColor( rStyleSettings.GetButtonTextColor() );
696 	}
697 	else
698 	{
699 		nTxtOffset += NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
700 		Erase( Rectangle( Point( 0, nTxtOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
701 	}
702 	DrawText( Point( (aWinSize.Width()-nTxtWidth) / 2, nTxtOffset+(NAME_OFFSET/2) ), rText );
703 }
704 
705 // -----------------------------------------------------------------------
706 
707 void ValueSet::ImplDrawSelect()
708 {
709 	if ( !IsReallyVisible() )
710 		return;
711 
712 	sal_Bool bFocus = HasFocus();
713 	sal_Bool bDrawSel;
714 
715 	if ( (mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight) )
716 		bDrawSel = sal_False;
717 	else
718 		bDrawSel = sal_True;
719 
720 	if ( !bFocus &&
721 		 ((mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight)) )
722 	{
723 		XubString aEmptyStr;
724 		ImplDrawItemText( aEmptyStr );
725 		return;
726 	}
727 
728 	sal_uInt16 nItemId = mnSelItemId;
729 
730 	for( int stage = 0; stage < 2; stage++ )
731 	{
732 		if( stage == 1 )
733 		{
734 			if ( mbHighlight )
735 				nItemId = mnHighItemId;
736 			else
737 				break;
738 		}
739 
740 		ValueSetItem* pItem;
741 		if ( nItemId )
742             pItem = mpImpl->mpItemList->GetObject( GetItemPos( nItemId ) );
743 		else
744 		{
745 			if ( mpNoneItem )
746 				pItem = mpNoneItem;
747 			else
748 			{
749 				pItem = ImplGetFirstItem();
750 				if ( !bFocus || !pItem )
751 					continue;
752 			}
753 		}
754 
755 		if ( pItem->maRect.IsEmpty() )
756 			continue;
757 
758 		// Selection malen
759 		const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();
760 		Rectangle				aRect = pItem->maRect;
761 		Control::SetFillColor();
762 
763 		Color aDoubleColor( rStyleSettings.GetHighlightColor() );
764 		Color aSingleColor( rStyleSettings.GetHighlightTextColor() );
765 		if( ! mbDoubleSel )
766 		{
767 			/*
768 			*  #99777# contrast enhancement for thin mode
769 			*/
770 			const Wallpaper& rWall = GetDisplayBackground();
771 			if( ! rWall.IsBitmap() && ! rWall.IsGradient() )
772 			{
773 				const Color& rBack = rWall.GetColor();
774 				if( rBack.IsDark() && ! aDoubleColor.IsBright() )
775 				{
776 					aDoubleColor = Color( COL_WHITE );
777 					aSingleColor = Color( COL_BLACK );
778 				}
779 				else if( rBack.IsBright() && ! aDoubleColor.IsDark() )
780 				{
781 					aDoubleColor = Color( COL_BLACK );
782 					aSingleColor = Color( COL_WHITE );
783 				}
784 			}
785 		}
786 
787 		// Selectionsausgabe festlegen
788 		WinBits nStyle = GetStyle();
789 		if ( nStyle & WB_MENUSTYLEVALUESET )
790 		{
791 			if ( bFocus )
792 				ShowFocus( aRect );
793 
794 			if ( bDrawSel )
795 			{
796 				if ( mbBlackSel )
797 					SetLineColor( Color( COL_BLACK ) );
798 				else
799 					SetLineColor( aDoubleColor );
800 				DrawRect( aRect );
801 			}
802 		}
803 		else if ( nStyle & WB_RADIOSEL )
804 		{
805 			aRect.Left()	+= 3;
806 			aRect.Top() 	+= 3;
807 			aRect.Right()	-= 3;
808 			aRect.Bottom()	-= 3;
809 			if ( nStyle & WB_DOUBLEBORDER )
810 			{
811 				aRect.Left()++;
812 				aRect.Top()++;
813 				aRect.Right()--;
814 				aRect.Bottom()--;
815 			}
816 
817 			if ( bFocus )
818 				ShowFocus( aRect );
819 
820 			aRect.Left()++;
821 			aRect.Top()++;
822 			aRect.Right()--;
823 			aRect.Bottom()--;
824 
825 			if ( bDrawSel )
826 			{
827 				SetLineColor( aDoubleColor );
828 				aRect.Left()++;
829 				aRect.Top()++;
830 				aRect.Right()--;
831 				aRect.Bottom()--;
832 				DrawRect( aRect );
833 				aRect.Left()++;
834 				aRect.Top()++;
835 				aRect.Right()--;
836 				aRect.Bottom()--;
837 				DrawRect( aRect );
838 			}
839 		}
840 		else
841 		{
842 			if ( bDrawSel )
843 			{
844 				if ( mbBlackSel )
845 					SetLineColor( Color( COL_BLACK ) );
846 				else
847 					SetLineColor( aDoubleColor );
848 				DrawRect( aRect );
849 			}
850 			if ( mbDoubleSel )
851 			{
852 				aRect.Left()++;
853 				aRect.Top()++;
854 				aRect.Right()--;
855 				aRect.Bottom()--;
856 				if ( bDrawSel )
857 					DrawRect( aRect );
858 			}
859 			aRect.Left()++;
860 			aRect.Top()++;
861 			aRect.Right()--;
862 			aRect.Bottom()--;
863 			Rectangle aRect2 = aRect;
864 			aRect.Left()++;
865 			aRect.Top()++;
866 			aRect.Right()--;
867 			aRect.Bottom()--;
868 			if ( bDrawSel )
869 				DrawRect( aRect );
870 			if ( mbDoubleSel )
871 			{
872 				aRect.Left()++;
873 				aRect.Top()++;
874 				aRect.Right()--;
875 				aRect.Bottom()--;
876 				if ( bDrawSel )
877 					DrawRect( aRect );
878 			}
879 
880 			if ( bDrawSel )
881 			{
882 				if ( mbBlackSel )
883 					SetLineColor( Color( COL_WHITE ) );
884 				else
885 					SetLineColor( aSingleColor );
886 			}
887 			else
888 				SetLineColor( Color( COL_LIGHTGRAY ) );
889 			DrawRect( aRect2 );
890 
891 			if ( bFocus )
892 				ShowFocus( aRect2 );
893 		}
894 
895 		ImplDrawItemText( pItem->maText );
896 	}
897 }
898 
899 // -----------------------------------------------------------------------
900 
901 void ValueSet::ImplHideSelect( sal_uInt16 nItemId )
902 {
903 	Rectangle aRect;
904 
905     sal_uInt16 nItemPos = GetItemPos( nItemId );
906 	if ( nItemPos != sal::static_int_cast<sal_uInt16>(LIST_ENTRY_NOTFOUND) )
907         aRect = mpImpl->mpItemList->GetObject( nItemPos )->maRect;
908 	else
909 	{
910 		if ( mpNoneItem )
911 			aRect = mpNoneItem->maRect;
912 	}
913 
914 	if ( !aRect.IsEmpty() )
915 	{
916 		HideFocus();
917 		Point aPos	= aRect.TopLeft();
918 		Size  aSize = aRect.GetSize();
919 		DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
920 	}
921 }
922 
923 // -----------------------------------------------------------------------
924 
925 void ValueSet::ImplHighlightItem( sal_uInt16 nItemId, sal_Bool bIsSelection )
926 {
927 	if ( mnHighItemId != nItemId )
928 	{
929 		// Alten merken, um vorherige Selektion zu entfernen
930 		sal_uInt16 nOldItem = mnHighItemId;
931 		mnHighItemId = nItemId;
932 
933 		// Wenn keiner selektiert ist, dann Selektion nicht malen
934 		if ( !bIsSelection && mbNoSelection )
935 			mbDrawSelection = sal_False;
936 
937 		// Neu ausgeben und alte Selection wegnehmen
938 		ImplHideSelect( nOldItem );
939 		ImplDrawSelect();
940 		mbDrawSelection = sal_True;
941 	}
942 }
943 
944 // -----------------------------------------------------------------------
945 
946 void ValueSet::ImplDrawDropPos( sal_Bool bShow )
947 {
948     if ( (mnDropPos != VALUESET_ITEM_NOTFOUND) && mpImpl->mpItemList->Count() )
949 	{
950 		sal_uInt16	nItemPos = mnDropPos;
951 		sal_uInt16	nItemId1;
952 		sal_uInt16	nItemId2 = 0;
953 		sal_Bool	bRight;
954         if ( nItemPos >= mpImpl->mpItemList->Count() )
955 		{
956             nItemPos = (sal_uInt16)(mpImpl->mpItemList->Count()-1);
957 			bRight = sal_True;
958 		}
959 		else
960 			bRight = sal_False;
961 
962 		nItemId1 = GetItemId( nItemPos );
963 		if ( (nItemId1 != mnSelItemId) && (nItemId1 != mnHighItemId) )
964 			nItemId1 = 0;
965         Rectangle aRect2 = mpImpl->mpItemList->GetObject( nItemPos )->maRect;
966 		Rectangle aRect1;
967 		if ( bRight )
968 		{
969 			aRect1 = aRect2;
970 			aRect2.SetEmpty();
971 		}
972 		else if ( nItemPos > 0 )
973 		{
974             aRect1 = mpImpl->mpItemList->GetObject( nItemPos-1 )->maRect;
975 			nItemId2 = GetItemId( nItemPos-1 );
976 			if ( (nItemId2 != mnSelItemId) && (nItemId2 != mnHighItemId) )
977 				nItemId2 = 0;
978 		}
979 
980 		// Items ueberhaupt sichtbar (nur Erstes/Letztes)
981 		if ( !aRect1.IsEmpty() || !aRect2.IsEmpty() )
982 		{
983 			if ( nItemId1 )
984 				ImplHideSelect( nItemId1 );
985 			if ( nItemId2 )
986 				ImplHideSelect( nItemId2 );
987 
988 			if ( bShow )
989 			{
990 				const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
991 				long	nX;
992 				long	nY;
993 				SetLineColor( rStyleSettings.GetButtonTextColor() );
994 				if ( !aRect1.IsEmpty() )
995 				{
996 					Point aPos = aRect1.RightCenter();
997 					nX = aPos.X()-2;
998 					nY = aPos.Y();
999 					for ( sal_uInt16 i = 0; i < 4; i++ )
1000 						DrawLine( Point( nX-i, nY-i ), Point( nX-i, nY+i ) );
1001 				}
1002 				if ( !aRect2.IsEmpty() )
1003 				{
1004 					Point aPos = aRect2.LeftCenter();
1005 					nX = aPos.X()+2;
1006 					nY = aPos.Y();
1007 					for ( sal_uInt16 i = 0; i < 4; i++ )
1008 						DrawLine( Point( nX+i, nY-i ), Point( nX+i, nY+i ) );
1009 				}
1010 			}
1011 			else
1012 			{
1013 				if ( !aRect1.IsEmpty() )
1014 				{
1015 					Point aPos	= aRect1.TopLeft();
1016 					Size  aSize = aRect1.GetSize();
1017 					DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
1018 				}
1019 				if ( !aRect2.IsEmpty() )
1020 				{
1021 					Point aPos	= aRect2.TopLeft();
1022 					Size  aSize = aRect2.GetSize();
1023 					DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
1024 				}
1025 			}
1026 
1027 			if ( nItemId1 || nItemId2 )
1028 				ImplDrawSelect();
1029 		}
1030 	}
1031 }
1032 
1033 // -----------------------------------------------------------------------
1034 
1035 void ValueSet::ImplDraw()
1036 {
1037 	if ( mbFormat )
1038 		Format();
1039 
1040 	HideFocus();
1041 
1042 	Point	aDefPos;
1043 	Size	aSize = maVirDev.GetOutputSizePixel();
1044 
1045 	if ( mpScrBar && mpScrBar->IsVisible() )
1046 	{
1047 		Point	aScrPos = mpScrBar->GetPosPixel();
1048 		Size	aScrSize = mpScrBar->GetSizePixel();
1049 		Point	aTempPos( 0, aScrPos.Y() );
1050 		Size	aTempSize( aSize.Width(), aScrPos.Y() );
1051 
1052 		DrawOutDev( aDefPos, aTempSize, aDefPos, aTempSize, maVirDev );
1053 		aTempSize.Width()	= aScrPos.X()-1;
1054 		aTempSize.Height()	= aScrSize.Height();
1055 		DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
1056 		aTempPos.Y()		= aScrPos.Y()+aScrSize.Height();
1057 		aTempSize.Width()	= aSize.Width();
1058 		aTempSize.Height()	= aSize.Height()-aTempPos.Y();
1059 		DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
1060 	}
1061 	else
1062 		DrawOutDev( aDefPos, aSize, aDefPos, aSize, maVirDev );
1063 
1064 	// Trennlinie zum Namefield zeichnen
1065 	if ( GetStyle() & WB_NAMEFIELD )
1066 	{
1067 		if ( !(GetStyle() & WB_FLATVALUESET) )
1068 		{
1069 			const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1070 			Size aWinSize = GetOutputSizePixel();
1071 			Point aPos1( NAME_LINE_OFF_X, mnTextOffset+NAME_LINE_OFF_Y );
1072 			Point aPos2( aWinSize.Width()-(NAME_LINE_OFF_X*2), mnTextOffset+NAME_LINE_OFF_Y );
1073 			if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
1074 			{
1075 				SetLineColor( rStyleSettings.GetShadowColor() );
1076 				DrawLine( aPos1, aPos2 );
1077 				aPos1.Y()++;
1078 				aPos2.Y()++;
1079 				SetLineColor( rStyleSettings.GetLightColor() );
1080 			}
1081 			else
1082 				SetLineColor( rStyleSettings.GetWindowTextColor() );
1083 			DrawLine( aPos1, aPos2 );
1084 		}
1085 	}
1086 
1087 	ImplDrawSelect();
1088 }
1089 
1090 // -----------------------------------------------------------------------
1091 
1092 sal_Bool ValueSet::ImplScroll( const Point& rPos )
1093 {
1094 	Size aOutSize = GetOutputSizePixel();
1095 	long nScrBarWidth;
1096 
1097 	if ( mpScrBar )
1098 		nScrBarWidth = mpScrBar->GetSizePixel().Width();
1099 	else
1100 		nScrBarWidth = 0;
1101 
1102 	if ( !mbScroll || (rPos.X() < 0) || (rPos.X() > aOutSize.Width()-nScrBarWidth) )
1103 		return sal_False;
1104 
1105 	long			 nScrollOffset;
1106 	sal_uInt16			 nOldLine = mnFirstLine;
1107     const Rectangle& rTopRect = mpImpl->mpItemList->GetObject( mnFirstLine*mnCols )->maRect;
1108 	if ( rTopRect.GetHeight() <= 16 )
1109 		nScrollOffset = VALUESET_SCROLL_OFFSET/2;
1110 	else
1111 		nScrollOffset = VALUESET_SCROLL_OFFSET;
1112 	if ( (mnFirstLine > 0) && (rPos.Y() >= 0) )
1113 	{
1114 		long nTopPos = rTopRect.Top();
1115 		if ( (rPos.Y() >= nTopPos) && (rPos.Y() <= nTopPos+nScrollOffset) )
1116 			mnFirstLine--;
1117 	}
1118 	if ( (mnFirstLine == nOldLine) &&
1119 		 (mnFirstLine < (sal_uInt16)(mnLines-mnVisLines)) && (rPos.Y() < aOutSize.Height()) )
1120 	{
1121         long nBottomPos = mpImpl->mpItemList->GetObject( (mnFirstLine+mnVisLines-1)*mnCols )->maRect.Bottom();
1122 		if ( (rPos.Y() >= nBottomPos-nScrollOffset) && (rPos.Y() <= nBottomPos) )
1123 			mnFirstLine++;
1124 	}
1125 
1126 	if ( mnFirstLine != nOldLine )
1127 	{
1128 		mbFormat = sal_True;
1129 		ImplDraw();
1130 		return sal_True;
1131 	}
1132 	else
1133 		return sal_False;
1134 }
1135 
1136 // -----------------------------------------------------------------------
1137 
1138 sal_uInt16 ValueSet::ImplGetItem( const Point& rPos, sal_Bool bMove ) const
1139 {
1140 	if ( mpNoneItem )
1141 	{
1142 		if ( mpNoneItem->maRect.IsInside( rPos ) )
1143 			return VALUESET_ITEM_NONEITEM;
1144 	}
1145 
1146 	Point	  aDefPos;
1147 	Rectangle aWinRect( aDefPos, maVirDev.GetOutputSizePixel() );
1148 
1149     sal_uLong nItemCount = mpImpl->mpItemList->Count();
1150 	for ( sal_uLong i = 0; i < nItemCount; i++ )
1151 	{
1152         ValueSetItem* pItem = mpImpl->mpItemList->GetObject( i );
1153 		if ( pItem->maRect.IsInside( rPos ) )
1154 		{
1155 			if ( aWinRect.IsInside( rPos ) )
1156 				return (sal_uInt16)i;
1157 			else
1158 				return VALUESET_ITEM_NOTFOUND;
1159 		}
1160 	}
1161 
1162 	// Wenn Spacing gesetzt ist, wird der vorher selektierte
1163 	// Eintrag zurueckgegeben, wenn die Maus noch nicht das Fenster
1164 	// verlassen hat
1165 	if ( bMove && mnSpacing && mnHighItemId )
1166 	{
1167 		if ( aWinRect.IsInside( rPos ) )
1168 			return GetItemPos( mnHighItemId );
1169 	}
1170 
1171 	return VALUESET_ITEM_NOTFOUND;
1172 }
1173 
1174 // -----------------------------------------------------------------------
1175 
1176 ValueSetItem* ValueSet::ImplGetItem( sal_uInt16 nPos )
1177 {
1178 	if ( nPos == VALUESET_ITEM_NONEITEM )
1179 		return mpNoneItem;
1180 	else
1181         return mpImpl->mpItemList->GetObject( nPos );
1182 }
1183 
1184 // -----------------------------------------------------------------------
1185 
1186 ValueSetItem* ValueSet::ImplGetFirstItem()
1187 {
1188     sal_uInt16 nItemCount = (sal_uInt16)mpImpl->mpItemList->Count();
1189 	sal_uInt16 i = 0;
1190 
1191 	while ( i < nItemCount )
1192 	{
1193         ValueSetItem* pItem = mpImpl->mpItemList->GetObject( i );
1194 		if ( pItem->meType != VALUESETITEM_SPACE )
1195 			return pItem;
1196 		i++;
1197 	}
1198 
1199 	return NULL;
1200 }
1201 
1202 // -----------------------------------------------------------------------
1203 
1204 sal_uInt16 ValueSet::ImplGetVisibleItemCount() const
1205 {
1206     sal_uInt16 nRet = 0;
1207 
1208     for( sal_Int32 n = 0, nItemCount = mpImpl->mpItemList->Count(); n < nItemCount; n++  )
1209     {
1210         ValueSetItem* pItem = mpImpl->mpItemList->GetObject( n );
1211 
1212         if( pItem->meType != VALUESETITEM_SPACE && !pItem->maRect.IsEmpty() )
1213             nRet++;
1214     }
1215 
1216     return nRet;
1217 }
1218 
1219 // -----------------------------------------------------------------------
1220 
1221 ValueSetItem* ValueSet::ImplGetVisibleItem( sal_uInt16 nVisiblePos )
1222 {
1223     ValueSetItem*   pRet = NULL;
1224     sal_uInt16          nFoundPos = 0;
1225 
1226     for( sal_Int32 n = 0, nItemCount = mpImpl->mpItemList->Count(); ( n < nItemCount ) && !pRet; n++  )
1227     {
1228         ValueSetItem* pItem = mpImpl->mpItemList->GetObject( n );
1229 
1230         if( ( pItem->meType != VALUESETITEM_SPACE ) && !pItem->maRect.IsEmpty() && ( nVisiblePos == nFoundPos++ ) )
1231             pRet = pItem;
1232     }
1233 
1234     return pRet;
1235 }
1236 
1237 // -----------------------------------------------------------------------
1238 
1239 void ValueSet::ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
1240 {
1241     ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( sal_False ) );
1242 
1243     if( pAcc )
1244         pAcc->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
1245 }
1246 
1247 // -----------------------------------------------------------------------
1248 
1249 sal_Bool ValueSet::ImplHasAccessibleListeners()
1250 {
1251     ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( sal_False ) );
1252     return( pAcc && pAcc->HasAccessibleListeners() );
1253 }
1254 
1255 // -----------------------------------------------------------------------
1256 
1257 IMPL_LINK( ValueSet,ImplScrollHdl, ScrollBar*, pScrollBar )
1258 {
1259 	sal_uInt16 nNewFirstLine = (sal_uInt16)pScrollBar->GetThumbPos();
1260 	if ( nNewFirstLine != mnFirstLine )
1261 	{
1262 		mnFirstLine = nNewFirstLine;
1263 		mbFormat = sal_True;
1264 		ImplDraw();
1265 	}
1266 	return 0;
1267 }
1268 
1269 // -----------------------------------------------------------------------
1270 
1271 IMPL_LINK( ValueSet,ImplTimerHdl, Timer*, EMPTYARG )
1272 {
1273 	ImplTracking( GetPointerPosPixel(), sal_True );
1274 	return 0;
1275 }
1276 
1277 // -----------------------------------------------------------------------
1278 
1279 void ValueSet::ImplTracking( const Point& rPos, sal_Bool bRepeat )
1280 {
1281 	if ( bRepeat || mbSelection )
1282 	{
1283 		if ( ImplScroll( rPos ) )
1284 		{
1285 			if ( mbSelection )
1286 			{
1287 				maTimer.SetTimeoutHdl( LINK( this, ValueSet, ImplTimerHdl ) );
1288 				maTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
1289 				maTimer.Start();
1290 			}
1291 		}
1292 	}
1293 
1294 	ValueSetItem* pItem = ImplGetItem( ImplGetItem( rPos ) );
1295 	if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
1296 	{
1297 		if( GetStyle() & WB_MENUSTYLEVALUESET )
1298 			mbHighlight = sal_True;
1299 
1300 		ImplHighlightItem( pItem->mnId );
1301 	}
1302 	else
1303 	{
1304 		if( GetStyle() & WB_MENUSTYLEVALUESET )
1305 			mbHighlight = sal_True;
1306 
1307 		ImplHighlightItem( mnSelItemId, sal_False );
1308 	}
1309 }
1310 
1311 // -----------------------------------------------------------------------
1312 
1313 void ValueSet::ImplEndTracking( const Point& rPos, sal_Bool bCancel )
1314 {
1315 	ValueSetItem* pItem;
1316 
1317 	// Bei Abbruch, den alten Status wieder herstellen
1318 	if ( bCancel )
1319 		pItem = NULL;
1320 	else
1321 		pItem = ImplGetItem( ImplGetItem( rPos ) );
1322 
1323 	if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
1324 	{
1325 		SelectItem( pItem->mnId );
1326 		if ( !mbSelection && !(GetStyle() & WB_NOPOINTERFOCUS) )
1327 			GrabFocus();
1328 		mbHighlight = sal_False;
1329 		mbSelection = sal_False;
1330 		Select();
1331 	}
1332 	else
1333 	{
1334 		ImplHighlightItem( mnSelItemId, sal_False );
1335 		mbHighlight = sal_False;
1336 		mbSelection = sal_False;
1337 	}
1338 }
1339 
1340 // -----------------------------------------------------------------------
1341 
1342 void ValueSet::MouseButtonDown( const MouseEvent& rMEvt )
1343 {
1344 	if ( rMEvt.IsLeft() )
1345 	{
1346 		ValueSetItem* pItem = ImplGetItem( ImplGetItem( rMEvt.GetPosPixel() ) );
1347 		if ( mbSelection )
1348 		{
1349 			mbHighlight = sal_True;
1350 			if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
1351 			{
1352 				mnOldItemId  = mnSelItemId;
1353 				mnHighItemId = mnSelItemId;
1354 				ImplHighlightItem( pItem->mnId );
1355 			}
1356 
1357 			return;
1358 		}
1359 		else
1360 		{
1361 			if ( pItem && (pItem->meType != VALUESETITEM_SPACE) && !rMEvt.IsMod2() )
1362 			{
1363 				if ( (pItem->mnBits & VIB_NODOUBLECLICK) || (rMEvt.GetClicks() == 1) )
1364 				{
1365 					mnOldItemId  = mnSelItemId;
1366 					mbHighlight  = sal_True;
1367 					mnHighItemId = mnSelItemId;
1368 					ImplHighlightItem( pItem->mnId );
1369 					StartTracking( STARTTRACK_SCROLLREPEAT );
1370 				}
1371 				else if ( rMEvt.GetClicks() == 2 )
1372 					DoubleClick();
1373 
1374 				return;
1375 			}
1376 		}
1377 	}
1378 
1379 	Control::MouseButtonDown( rMEvt );
1380 }
1381 
1382 // -----------------------------------------------------------------------
1383 
1384 void ValueSet::MouseButtonUp( const MouseEvent& rMEvt )
1385 {
1386 	// Wegen SelectionMode
1387 	if ( rMEvt.IsLeft() && mbSelection )
1388 		ImplEndTracking( rMEvt.GetPosPixel(), sal_False );
1389 	else
1390 		Control::MouseButtonUp( rMEvt );
1391 }
1392 
1393 // -----------------------------------------------------------------------
1394 
1395 void ValueSet::MouseMove( const MouseEvent& rMEvt )
1396 {
1397 	// Wegen SelectionMode
1398 	if ( mbSelection || (GetStyle() & WB_MENUSTYLEVALUESET) )
1399 		ImplTracking( rMEvt.GetPosPixel(), sal_False );
1400 	Control::MouseMove( rMEvt );
1401 }
1402 
1403 // -----------------------------------------------------------------------
1404 
1405 void ValueSet::Tracking( const TrackingEvent& rTEvt )
1406 {
1407 	Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
1408 
1409 	if ( rTEvt.IsTrackingEnded() )
1410 		ImplEndTracking( aMousePos, rTEvt.IsTrackingCanceled() );
1411 	else
1412 		ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
1413 }
1414 
1415 // -----------------------------------------------------------------------
1416 
1417 void ValueSet::KeyInput( const KeyEvent& rKEvt )
1418 {
1419     sal_uInt16 nLastItem = (sal_uInt16)mpImpl->mpItemList->Count();
1420 	sal_uInt16 nItemPos = VALUESET_ITEM_NOTFOUND;
1421 	sal_uInt16 nCurPos = VALUESET_ITEM_NONEITEM;
1422 	sal_uInt16 nCalcPos;
1423 
1424 	if ( !nLastItem || !ImplGetFirstItem() )
1425 	{
1426 		Control::KeyInput( rKEvt );
1427 		return;
1428 	}
1429 	else
1430 		nLastItem--;
1431 
1432 	if ( mnSelItemId )
1433 		nCurPos = GetItemPos( mnSelItemId );
1434 	nCalcPos = nCurPos;
1435 
1436     //switch off selection mode if key travelling is used
1437     sal_Bool bDefault = sal_False;
1438     switch ( rKEvt.GetKeyCode().GetCode() )
1439 	{
1440 		case KEY_HOME:
1441 			if ( mpNoneItem )
1442 				nItemPos = VALUESET_ITEM_NONEITEM;
1443 			else
1444 			{
1445 				nItemPos = 0;
1446 				while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE )
1447 					nItemPos++;
1448 			}
1449 			break;
1450 
1451 		case KEY_END:
1452 			nItemPos = nLastItem;
1453 			while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE )
1454 			{
1455 				if ( nItemPos == 0 )
1456 					nItemPos = VALUESET_ITEM_NONEITEM;
1457 				else
1458 					nItemPos--;
1459 			}
1460 			break;
1461 
1462 		case KEY_LEFT:
1463 		case KEY_RIGHT:
1464             if ( rKEvt.GetKeyCode().GetCode()==KEY_LEFT )
1465             {
1466                 do
1467                 {
1468                     if ( nCalcPos == VALUESET_ITEM_NONEITEM )
1469                         nItemPos = nLastItem;
1470                     else if ( !nCalcPos )
1471                     {
1472                         if ( mpNoneItem )
1473                             nItemPos = VALUESET_ITEM_NONEITEM;
1474                         else
1475                             nItemPos = nLastItem;
1476                     }
1477                     else
1478                         nItemPos = nCalcPos-1;
1479                     nCalcPos = nItemPos;
1480                 }
1481                 while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
1482             }
1483             else
1484             {
1485                 do
1486                 {
1487                     if ( nCalcPos == VALUESET_ITEM_NONEITEM )
1488                         nItemPos = 0;
1489                     else if ( nCalcPos == nLastItem )
1490                     {
1491                         if ( mpNoneItem )
1492                             nItemPos = VALUESET_ITEM_NONEITEM;
1493                         else
1494                             nItemPos = 0;
1495                     }
1496                     else
1497                         nItemPos = nCalcPos+1;
1498                     nCalcPos = nItemPos;
1499                 }
1500                 while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
1501             }
1502             break;
1503 
1504 		case KEY_UP:
1505 		case KEY_PAGEUP:
1506         {
1507             if( rKEvt.GetKeyCode().GetCode() != KEY_PAGEUP ||
1508                 ( !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2() ) )
1509             {
1510                 const long nLineCount = ( ( KEY_UP == rKEvt.GetKeyCode().GetCode() ) ? 1 : mnVisLines );
1511 			    do
1512 			    {
1513 				    if ( nCalcPos == VALUESET_ITEM_NONEITEM )
1514 				    {
1515 					    if ( nLastItem+1 <= mnCols )
1516 						    nItemPos = mnCurCol;
1517 					    else
1518 					    {
1519 						    nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(mnCurCol%mnCols);
1520 						    if ( nItemPos+mnCols <= nLastItem )
1521 							    nItemPos = nItemPos + mnCols;
1522 					    }
1523 				    }
1524 				    else if ( nCalcPos >= ( nLineCount * mnCols ) )
1525 					    nItemPos = sal::static_int_cast< sal_uInt16 >(
1526                             nCalcPos - ( nLineCount * mnCols ));
1527 				    else
1528 				    {
1529 						if ( mpNoneItem )
1530 						{
1531 							mnCurCol  = nCalcPos%mnCols;
1532 							nItemPos = VALUESET_ITEM_NONEITEM;
1533 						}
1534 						else
1535 						{
1536 							if ( nLastItem+1 <= mnCols )
1537 								nItemPos = nCalcPos;
1538 							else
1539 							{
1540 								nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(nCalcPos%mnCols);
1541 								if ( nItemPos+mnCols <= nLastItem )
1542 									nItemPos = nItemPos + mnCols;
1543 							}
1544 						}
1545 				    }
1546 				    nCalcPos = nItemPos;
1547 			    }
1548 			    while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
1549             }
1550             else
1551     			Control::KeyInput( rKEvt );
1552         }
1553 		break;
1554 
1555 		case KEY_DOWN:
1556 		case KEY_PAGEDOWN:
1557         {
1558             if( rKEvt.GetKeyCode().GetCode() != KEY_PAGEDOWN ||
1559                 ( !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2() ) )
1560             {
1561                 const long nLineCount = ( ( KEY_DOWN == rKEvt.GetKeyCode().GetCode() ) ? 1 : mnVisLines );
1562                 do
1563 			    {
1564 				    if ( nCalcPos == VALUESET_ITEM_NONEITEM )
1565 					    nItemPos = mnCurCol;
1566 				    else if ( nCalcPos + ( nLineCount * mnCols ) <= nLastItem )
1567 					    nItemPos = sal::static_int_cast< sal_uInt16 >(
1568                             nCalcPos + ( nLineCount * mnCols ));
1569 				    else
1570 				    {
1571 #if 0
1572 						if( (KEY_DOWN == rKEvt.GetKeyCode().GetCode() ) && (GetStyle() & WB_MENUSTYLEVALUESET) )
1573 						{
1574 							Window* pParent = GetParent();
1575 							pParent->GrabFocus();
1576 							pParent->KeyInput( rKEvt );
1577 							break;
1578 						}
1579 						else
1580 #endif
1581 						{
1582 							if ( mpNoneItem )
1583 							{
1584 								mnCurCol  = nCalcPos%mnCols;
1585 								nItemPos = VALUESET_ITEM_NONEITEM;
1586 							}
1587 							else
1588 								nItemPos = nCalcPos%mnCols;
1589 						}
1590 				    }
1591 				    nCalcPos = nItemPos;
1592 			    }
1593 			    while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
1594             }
1595             else
1596     			Control::KeyInput( rKEvt );
1597 
1598         }
1599         break;
1600         case KEY_RETURN:
1601             //enable default handling of KEY_RETURN in dialogs
1602 			if(0 != (GetStyle()&WB_NO_DIRECTSELECT))
1603             {
1604                 Select();
1605                 break;
1606             }
1607             //no break;
1608 		default:
1609 			Control::KeyInput( rKEvt );
1610             bDefault = sal_True;
1611 			break;
1612 	}
1613     if(!bDefault)
1614         EndSelection();
1615     if ( nItemPos != VALUESET_ITEM_NOTFOUND )
1616 	{
1617 		sal_uInt16 nItemId;
1618 		if ( nItemPos != VALUESET_ITEM_NONEITEM )
1619 			nItemId = GetItemId( nItemPos );
1620 		else
1621 			nItemId = 0;
1622 
1623 		if ( nItemId != mnSelItemId )
1624 		{
1625 			SelectItem( nItemId );
1626 			//select only if WB_NO_DIRECTSELECT is not set
1627 			if(0 == (GetStyle()&WB_NO_DIRECTSELECT))
1628 				Select();
1629 		}
1630 	}
1631 }
1632 
1633 // -----------------------------------------------------------------------
1634 
1635 void ValueSet::Command( const CommandEvent& rCEvt )
1636 {
1637 	if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
1638 		 (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
1639 		 (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
1640 	{
1641 		if ( HandleScrollCommand( rCEvt, NULL, mpScrBar ) )
1642 			return;
1643 	}
1644 
1645 	Control::Command( rCEvt );
1646 }
1647 
1648 // -----------------------------------------------------------------------
1649 
1650 void ValueSet::Paint( const Rectangle& )
1651 {
1652 	if ( GetStyle() & WB_FLATVALUESET )
1653 	{
1654 		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1655 		SetLineColor();
1656 		SetFillColor( rStyleSettings.GetFaceColor() );
1657 		long nOffY = maVirDev.GetOutputSizePixel().Height();
1658 		Size aWinSize = GetOutputSizePixel();
1659 		DrawRect( Rectangle( Point( 0, nOffY ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
1660 	}
1661 
1662 	ImplDraw();
1663 }
1664 
1665 // -----------------------------------------------------------------------
1666 
1667 void ValueSet::GetFocus()
1668 {
1669     OSL_TRACE ("value set getting focus");
1670 	ImplDrawSelect();
1671 	Control::GetFocus();
1672 
1673     // Tell the accessible object that we got the focus.
1674     ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( sal_False ) );
1675     if( pAcc )
1676         pAcc->GetFocus();
1677 }
1678 
1679 // -----------------------------------------------------------------------
1680 
1681 void ValueSet::LoseFocus()
1682 {
1683     OSL_TRACE ("value set losing focus");
1684 	if ( mbNoSelection && mnSelItemId )
1685 		ImplHideSelect( mnSelItemId );
1686 	else
1687 		HideFocus();
1688 	Control::LoseFocus();
1689 
1690     // Tell the accessible object that we lost the focus.
1691     ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( sal_False ) );
1692     if( pAcc )
1693         pAcc->LoseFocus();
1694 }
1695 
1696 // -----------------------------------------------------------------------
1697 
1698 void ValueSet::Resize()
1699 {
1700 	mbFormat = sal_True;
1701 	if ( IsReallyVisible() && IsUpdateMode() )
1702 		Invalidate();
1703 	Control::Resize();
1704 }
1705 
1706 // -----------------------------------------------------------------------
1707 
1708 void ValueSet::RequestHelp( const HelpEvent& rHEvt )
1709 {
1710 	if ( (rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON)) == HELPMODE_QUICK )
1711 	{
1712 		Point aPos = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
1713 		sal_uInt16 nItemPos = ImplGetItem( aPos );
1714 		if ( nItemPos != VALUESET_ITEM_NOTFOUND )
1715 		{
1716 			ValueSetItem* pItem = ImplGetItem( nItemPos );
1717 			Rectangle aItemRect = pItem->maRect;
1718 			Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1719 			aItemRect.Left()   = aPt.X();
1720 			aItemRect.Top()    = aPt.Y();
1721 			aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1722 			aItemRect.Right()  = aPt.X();
1723 			aItemRect.Bottom() = aPt.Y();
1724 			Help::ShowQuickHelp( this, aItemRect, GetItemText( pItem->mnId ) );
1725 			return;
1726 		}
1727 	}
1728 
1729 	Control::RequestHelp( rHEvt );
1730 }
1731 
1732 // -----------------------------------------------------------------------
1733 
1734 void ValueSet::StateChanged( StateChangedType nType )
1735 {
1736 	Control::StateChanged( nType );
1737 
1738 	if ( nType == STATE_CHANGE_INITSHOW )
1739 	{
1740 		if ( mbFormat )
1741 			Format();
1742 	}
1743 	else if ( nType == STATE_CHANGE_UPDATEMODE )
1744 	{
1745 		if ( IsReallyVisible() && IsUpdateMode() )
1746 			Invalidate();
1747 	}
1748 	else if ( nType == STATE_CHANGE_TEXT )
1749 	{
1750 		if ( mpNoneItem && !mbFormat && IsReallyVisible() && IsUpdateMode() )
1751 		{
1752 			ImplFormatItem( mpNoneItem );
1753 			Invalidate( mpNoneItem->maRect );
1754 		}
1755 	}
1756 	else if ( (nType == STATE_CHANGE_ZOOM) ||
1757 			  (nType == STATE_CHANGE_CONTROLFONT) )
1758 	{
1759 		ImplInitSettings( sal_True, sal_False, sal_False );
1760 		Invalidate();
1761 	}
1762 	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1763 	{
1764 		ImplInitSettings( sal_False, sal_True, sal_False );
1765 		Invalidate();
1766 	}
1767 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1768 	{
1769 		ImplInitSettings( sal_False, sal_False, sal_True );
1770 		Invalidate();
1771 	}
1772     else if ( (nType == STATE_CHANGE_STYLE) || (nType == STATE_CHANGE_ENABLE) )
1773 	{
1774 		mbFormat = sal_True;
1775 		ImplInitSettings( sal_False, sal_False, sal_True );
1776 		Invalidate();
1777 	}
1778 }
1779 
1780 // -----------------------------------------------------------------------
1781 
1782 void ValueSet::DataChanged( const DataChangedEvent& rDCEvt )
1783 {
1784 	Control::DataChanged( rDCEvt );
1785 
1786 	if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1787 		 (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
1788 		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1789 		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1790 		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1791 	{
1792 		mbFormat = sal_True;
1793 		ImplInitSettings( sal_True, sal_True, sal_True );
1794 		Invalidate();
1795 	}
1796 }
1797 
1798 // -----------------------------------------------------------------------
1799 
1800 void ValueSet::Select()
1801 {
1802 	maSelectHdl.Call( this );
1803 }
1804 
1805 // -----------------------------------------------------------------------
1806 
1807 void ValueSet::DoubleClick()
1808 {
1809 	maDoubleClickHdl.Call( this );
1810 }
1811 
1812 // -----------------------------------------------------------------------
1813 
1814 void ValueSet::UserDraw( const UserDrawEvent& )
1815 {
1816 }
1817 
1818 // -----------------------------------------------------------------------
1819 
1820 void ValueSet::InsertItem( sal_uInt16 nItemId, const Image& rImage, sal_uInt16 nPos )
1821 {
1822 	DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
1823 	DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
1824 				"ValueSet::InsertItem(): ItemId already exists" );
1825 
1826 	ValueSetItem* pItem = new ValueSetItem( *this );
1827 	pItem->mnId 	= nItemId;
1828 	pItem->meType	= VALUESETITEM_IMAGE;
1829 	pItem->maImage	= rImage;
1830     mpImpl->mpItemList->Insert( pItem, (sal_uLong)nPos );
1831 
1832 	mbFormat = sal_True;
1833 	if ( IsReallyVisible() && IsUpdateMode() )
1834 		Invalidate();
1835 }
1836 
1837 // -----------------------------------------------------------------------
1838 
1839 void ValueSet::InsertItem( sal_uInt16 nItemId, const Color& rColor, sal_uInt16 nPos )
1840 {
1841 	DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
1842 	DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
1843 				"ValueSet::InsertItem(): ItemId already exists" );
1844 
1845 	ValueSetItem* pItem = new ValueSetItem( *this );
1846 	pItem->mnId 	= nItemId;
1847 	pItem->meType	= VALUESETITEM_COLOR;
1848 	pItem->maColor	= rColor;
1849     mpImpl->mpItemList->Insert( pItem, (sal_uLong)nPos );
1850 
1851 	mbFormat = sal_True;
1852 	if ( IsReallyVisible() && IsUpdateMode() )
1853 		Invalidate();
1854 }
1855 
1856 // -----------------------------------------------------------------------
1857 
1858 void ValueSet::InsertItem( sal_uInt16 nItemId, const Image& rImage,
1859 						   const XubString& rText, sal_uInt16 nPos )
1860 {
1861 	DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
1862 	DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
1863 				"ValueSet::InsertItem(): ItemId already exists" );
1864 
1865 	ValueSetItem* pItem = new ValueSetItem( *this );
1866 	pItem->mnId 	= nItemId;
1867 	pItem->meType	= VALUESETITEM_IMAGE;
1868 	pItem->maImage	= rImage;
1869 	pItem->maText	= rText;
1870     mpImpl->mpItemList->Insert( pItem, (sal_uLong)nPos );
1871 
1872 	mbFormat = sal_True;
1873 	if ( IsReallyVisible() && IsUpdateMode() )
1874 		Invalidate();
1875 }
1876 
1877 // -----------------------------------------------------------------------
1878 
1879 void ValueSet::InsertItem( sal_uInt16 nItemId, const Color& rColor,
1880 						   const XubString& rText, sal_uInt16 nPos )
1881 {
1882 	DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
1883 	DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
1884 				"ValueSet::InsertItem(): ItemId already exists" );
1885 
1886 	ValueSetItem* pItem = new ValueSetItem( *this );
1887 	pItem->mnId 	= nItemId;
1888 	pItem->meType	= VALUESETITEM_COLOR;
1889 	pItem->maColor	= rColor;
1890 	pItem->maText	= rText;
1891     mpImpl->mpItemList->Insert( pItem, (sal_uLong)nPos );
1892 
1893 	mbFormat = sal_True;
1894 	if ( IsReallyVisible() && IsUpdateMode() )
1895 		Invalidate();
1896 }
1897 
1898 // -----------------------------------------------------------------------
1899 
1900 void ValueSet::InsertItem( sal_uInt16 nItemId, sal_uInt16 nPos )
1901 {
1902 	DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
1903 	DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
1904 				"ValueSet::InsertItem(): ItemId already exists" );
1905 
1906 	ValueSetItem* pItem = new ValueSetItem( *this );
1907 	pItem->mnId 	= nItemId;
1908 	pItem->meType	= VALUESETITEM_USERDRAW;
1909     mpImpl->mpItemList->Insert( pItem, (sal_uLong)nPos );
1910 
1911 	mbFormat = sal_True;
1912 	if ( IsReallyVisible() && IsUpdateMode() )
1913 		Invalidate();
1914 }
1915 
1916 // -----------------------------------------------------------------------
1917 
1918 void ValueSet::InsertSpace( sal_uInt16 nItemId, sal_uInt16 nPos )
1919 {
1920 	DBG_ASSERT( nItemId, "ValueSet::InsertSpace(): ItemId == 0" );
1921 	DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
1922 				"ValueSet::InsertSpace(): ItemId already exists" );
1923 
1924 	ValueSetItem* pItem = new ValueSetItem( *this );
1925 	pItem->mnId 	= nItemId;
1926 	pItem->meType	= VALUESETITEM_SPACE;
1927     mpImpl->mpItemList->Insert( pItem, (sal_uLong)nPos );
1928 
1929 	mbFormat = sal_True;
1930 	if ( IsReallyVisible() && IsUpdateMode() )
1931 		Invalidate();
1932 }
1933 
1934 // -----------------------------------------------------------------------
1935 
1936 void ValueSet::RemoveItem( sal_uInt16 nItemId )
1937 {
1938 	sal_uInt16 nPos = GetItemPos( nItemId );
1939 
1940 	if ( nPos == VALUESET_ITEM_NOTFOUND )
1941 		return;
1942 
1943     delete mpImpl->mpItemList->Remove( nPos );
1944 
1945 	// Variablen zuruecksetzen
1946 	if ( (mnHighItemId == nItemId) || (mnSelItemId == nItemId) )
1947 	{
1948 		mnCurCol		= 0;
1949 		mnOldItemId 	= 0;
1950 		mnHighItemId	= 0;
1951 		mnSelItemId 	= 0;
1952 		mbNoSelection	= sal_True;
1953 	}
1954 
1955 	mbFormat = sal_True;
1956 	if ( IsReallyVisible() && IsUpdateMode() )
1957 		Invalidate();
1958 }
1959 
1960 // -----------------------------------------------------------------------
1961 
1962 void ValueSet::CopyItems( const ValueSet& rValueSet )
1963 {
1964     ImplDeleteItems();
1965 
1966     ValueSetItem* pItem = rValueSet.mpImpl->mpItemList->First();
1967 	while ( pItem )
1968 	{
1969         ValueSetItem* pNewItem = new ValueSetItem( *this );
1970 
1971         pNewItem->mnId = pItem->mnId;
1972         pNewItem->mnBits = pItem->mnBits;
1973         pNewItem->meType = pItem->meType;
1974         pNewItem->maImage = pItem->maImage;
1975         pNewItem->maColor = pItem->maColor;
1976         pNewItem->maText = pItem->maText;
1977         pNewItem->mpData = pItem->mpData;
1978         pNewItem->maRect = pItem->maRect;
1979         pNewItem->mpxAcc = NULL;
1980 
1981         mpImpl->mpItemList->Insert( pNewItem );
1982         pItem = rValueSet.mpImpl->mpItemList->Next();
1983 	}
1984 
1985 	// Variablen zuruecksetzen
1986 	mnFirstLine 	= 0;
1987 	mnCurCol		= 0;
1988 	mnOldItemId 	= 0;
1989 	mnHighItemId	= 0;
1990 	mnSelItemId 	= 0;
1991 	mbNoSelection	= sal_True;
1992 
1993 	mbFormat = sal_True;
1994 	if ( IsReallyVisible() && IsUpdateMode() )
1995 		Invalidate();
1996 }
1997 
1998 // -----------------------------------------------------------------------
1999 
2000 void ValueSet::Clear()
2001 {
2002     ImplDeleteItems();
2003 
2004 	// Variablen zuruecksetzen
2005 	mnFirstLine 	= 0;
2006 	mnCurCol		= 0;
2007 	mnOldItemId 	= 0;
2008 	mnHighItemId	= 0;
2009 	mnSelItemId 	= 0;
2010 	mbNoSelection	= sal_True;
2011 
2012 	mbFormat = sal_True;
2013 	if ( IsReallyVisible() && IsUpdateMode() )
2014 		Invalidate();
2015 }
2016 
2017 // -----------------------------------------------------------------------
2018 
2019 sal_uInt16 ValueSet::GetItemCount() const
2020 {
2021     return (sal_uInt16)mpImpl->mpItemList->Count();
2022 }
2023 
2024 // -----------------------------------------------------------------------
2025 
2026 sal_uInt16 ValueSet::GetItemPos( sal_uInt16 nItemId ) const
2027 {
2028     ValueSetItem* pItem = mpImpl->mpItemList->First();
2029 	while ( pItem )
2030 	{
2031 		if ( pItem->mnId == nItemId )
2032             return (sal_uInt16)mpImpl->mpItemList->GetCurPos();
2033         pItem = mpImpl->mpItemList->Next();
2034 	}
2035 
2036 	return VALUESET_ITEM_NOTFOUND;
2037 }
2038 
2039 // -----------------------------------------------------------------------
2040 
2041 sal_uInt16 ValueSet::GetItemId( sal_uInt16 nPos ) const
2042 {
2043     ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
2044 
2045 	if ( pItem )
2046 		return pItem->mnId;
2047 	else
2048 		return 0;
2049 }
2050 
2051 // -----------------------------------------------------------------------
2052 
2053 sal_uInt16 ValueSet::GetItemId( const Point& rPos ) const
2054 {
2055 	sal_uInt16 nItemPos = ImplGetItem( rPos );
2056 	if ( nItemPos != VALUESET_ITEM_NOTFOUND )
2057 		return GetItemId( nItemPos );
2058 
2059 	return 0;
2060 }
2061 
2062 // -----------------------------------------------------------------------
2063 
2064 Rectangle ValueSet::GetItemRect( sal_uInt16 nItemId ) const
2065 {
2066 	sal_uInt16 nPos = GetItemPos( nItemId );
2067 
2068 	if ( nPos != VALUESET_ITEM_NOTFOUND )
2069         return mpImpl->mpItemList->GetObject( nPos )->maRect;
2070 	else
2071 		return Rectangle();
2072 }
2073 
2074 // -----------------------------------------------------------------------
2075 
2076 void ValueSet::EnableFullItemMode( sal_Bool bFullMode )
2077 {
2078 	mbFullMode = bFullMode;
2079 }
2080 
2081 // -----------------------------------------------------------------------
2082 
2083 void ValueSet::SetColCount( sal_uInt16 nNewCols )
2084 {
2085 	if ( mnUserCols != nNewCols )
2086 	{
2087 		mnUserCols = nNewCols;
2088 		mbFormat = sal_True;
2089 		if ( IsReallyVisible() && IsUpdateMode() )
2090 			Invalidate();
2091 	}
2092 }
2093 
2094 // -----------------------------------------------------------------------
2095 
2096 void ValueSet::SetLineCount( sal_uInt16 nNewLines )
2097 {
2098 	if ( mnUserVisLines != nNewLines )
2099 	{
2100 		mnUserVisLines = nNewLines;
2101 		mbFormat = sal_True;
2102 		if ( IsReallyVisible() && IsUpdateMode() )
2103 			Invalidate();
2104 	}
2105 }
2106 
2107 // -----------------------------------------------------------------------
2108 
2109 void ValueSet::SetItemWidth( long nNewItemWidth )
2110 {
2111 	if ( mnUserItemWidth != nNewItemWidth )
2112 	{
2113 		mnUserItemWidth = nNewItemWidth;
2114 		mbFormat = sal_True;
2115 		if ( IsReallyVisible() && IsUpdateMode() )
2116 			Invalidate();
2117 	}
2118 }
2119 
2120 // -----------------------------------------------------------------------
2121 
2122 void ValueSet::SetItemHeight( long nNewItemHeight )
2123 {
2124 	if ( mnUserItemHeight != nNewItemHeight )
2125 	{
2126 		mnUserItemHeight = nNewItemHeight;
2127 		mbFormat = sal_True;
2128 		if ( IsReallyVisible() && IsUpdateMode() )
2129 			Invalidate();
2130 	}
2131 }
2132 
2133 // -----------------------------------------------------------------------
2134 
2135 void ValueSet::SetFirstLine( sal_uInt16 nNewLine )
2136 {
2137 	if ( mnFirstLine != nNewLine )
2138 	{
2139 		mnFirstLine = nNewLine;
2140 		mbFormat = sal_True;
2141 		if ( IsReallyVisible() && IsUpdateMode() )
2142 			Invalidate();
2143 	}
2144 }
2145 
2146 // -----------------------------------------------------------------------
2147 
2148 void ValueSet::SelectItem( sal_uInt16 nItemId )
2149 {
2150 	sal_uInt16 nItemPos = 0;
2151 
2152 	if ( nItemId )
2153 	{
2154 		nItemPos = GetItemPos( nItemId );
2155 		if ( nItemPos == VALUESET_ITEM_NOTFOUND )
2156 			return;
2157         if ( mpImpl->mpItemList->GetObject( nItemPos )->meType == VALUESETITEM_SPACE )
2158 			return;
2159 	}
2160 
2161 	if ( (mnSelItemId != nItemId) || mbNoSelection )
2162 	{
2163         sal_uInt16 nOldItem = mnSelItemId ? mnSelItemId : 1;
2164 		mnSelItemId = nItemId;
2165 		mbNoSelection = sal_False;
2166 
2167 		sal_Bool bNewOut;
2168 		sal_Bool bNewLine;
2169 		if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2170 			bNewOut = sal_True;
2171 		else
2172 			bNewOut = sal_False;
2173 		bNewLine = sal_False;
2174 
2175 		// Gegebenenfalls in den sichtbaren Bereich scrollen
2176 		if ( mbScroll && nItemId )
2177 		{
2178 			sal_uInt16 nNewLine = (sal_uInt16)(nItemPos / mnCols);
2179 			if ( nNewLine < mnFirstLine )
2180 			{
2181 				mnFirstLine = nNewLine;
2182 				bNewLine = sal_True;
2183 			}
2184 			else if ( nNewLine > (sal_uInt16)(mnFirstLine+mnVisLines-1) )
2185 			{
2186 				mnFirstLine = (sal_uInt16)(nNewLine-mnVisLines+1);
2187 				bNewLine = sal_True;
2188 			}
2189 		}
2190 
2191 		if ( bNewOut )
2192 		{
2193 			if ( bNewLine )
2194 			{
2195 				// Falls sich der sichtbare Bereich geaendert hat,
2196 				// alles neu ausgeben
2197 				mbFormat = sal_True;
2198 				ImplDraw();
2199 			}
2200 			else
2201 			{
2202 				// alte Selection wegnehmen und neue ausgeben
2203 				ImplHideSelect( nOldItem );
2204 				ImplDrawSelect();
2205 			}
2206 		}
2207 
2208         if( ImplHasAccessibleListeners() )
2209         {
2210             // focus event (deselect)
2211             if( nOldItem )
2212             {
2213 	            const sal_uInt16 nPos = GetItemPos( nItemId );
2214 
2215 	            if( nPos != VALUESET_ITEM_NOTFOUND )
2216                 {
2217                     ValueItemAcc* pItemAcc = ValueItemAcc::getImplementation(
2218                         mpImpl->mpItemList->GetObject( nPos )->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
2219 
2220                     if( pItemAcc )
2221                     {
2222                         ::com::sun::star::uno::Any aOldAny, aNewAny;
2223                         if( !mpImpl->mbIsTransientChildrenDisabled)
2224                         {
2225                             aOldAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
2226                                 static_cast< ::cppu::OWeakObject* >( pItemAcc ));
2227                             ImplFireAccessibleEvent (::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
2228                         }
2229                         else
2230                         {
2231                             aOldAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
2232                             pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
2233                         }
2234                     }
2235                 }
2236             }
2237 
2238             // focus event (select)
2239             const sal_uInt16 nPos = GetItemPos( mnSelItemId );
2240 
2241             ValueSetItem* pItem;
2242             if( nPos != VALUESET_ITEM_NOTFOUND )
2243                 pItem = mpImpl->mpItemList->GetObject(nPos);
2244             else
2245                 pItem = mpNoneItem;
2246 
2247             ValueItemAcc* pItemAcc = NULL;
2248             if (pItem != NULL)
2249                 pItemAcc = ValueItemAcc::getImplementation(pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
2250 
2251             if( pItemAcc )
2252             {
2253                 ::com::sun::star::uno::Any aOldAny, aNewAny;
2254                 if( !mpImpl->mbIsTransientChildrenDisabled)
2255                 {
2256                     aNewAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
2257                         static_cast< ::cppu::OWeakObject* >( pItemAcc ));
2258                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
2259                 }
2260                 else
2261                 {
2262                     aNewAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
2263                     pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
2264                 }
2265             }
2266 
2267             // selection event
2268             ::com::sun::star::uno::Any aOldAny, aNewAny;
2269             ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny );
2270         }
2271 		mpImpl->maHighlightHdl.Call(this);
2272 	}
2273 }
2274 
2275 // -----------------------------------------------------------------------
2276 
2277 void ValueSet::SetNoSelection()
2278 {
2279 	mbNoSelection	= sal_True;
2280 	mbHighlight 	= sal_False;
2281 	mbSelection 	= sal_False;
2282 
2283 	if ( IsReallyVisible() && IsUpdateMode() )
2284 		ImplDraw();
2285 }
2286 
2287 // -----------------------------------------------------------------------
2288 
2289 void ValueSet::SetItemBits( sal_uInt16 nItemId, sal_uInt16 nItemBits )
2290 {
2291 	sal_uInt16 nPos = GetItemPos( nItemId );
2292 
2293 	if ( nPos != VALUESET_ITEM_NOTFOUND )
2294         mpImpl->mpItemList->GetObject( nPos )->mnBits = nItemBits;
2295 }
2296 
2297 // -----------------------------------------------------------------------
2298 
2299 sal_uInt16 ValueSet::GetItemBits( sal_uInt16 nItemId ) const
2300 {
2301 	sal_uInt16 nPos = GetItemPos( nItemId );
2302 
2303 	if ( nPos != VALUESET_ITEM_NOTFOUND )
2304         return mpImpl->mpItemList->GetObject( nPos )->mnBits;
2305 	else
2306 		return 0;
2307 }
2308 
2309 // -----------------------------------------------------------------------
2310 
2311 void ValueSet::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
2312 {
2313 	sal_uInt16 nPos = GetItemPos( nItemId );
2314 
2315 	if ( nPos == VALUESET_ITEM_NOTFOUND )
2316 		return;
2317 
2318     ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
2319 	pItem->meType  = VALUESETITEM_IMAGE;
2320 	pItem->maImage = rImage;
2321 
2322 	if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2323 	{
2324 		ImplFormatItem( pItem );
2325 		Invalidate( pItem->maRect );
2326 	}
2327 	else
2328 		mbFormat = sal_True;
2329 }
2330 
2331 // -----------------------------------------------------------------------
2332 
2333 Image ValueSet::GetItemImage( sal_uInt16 nItemId ) const
2334 {
2335 	sal_uInt16 nPos = GetItemPos( nItemId );
2336 
2337 	if ( nPos != VALUESET_ITEM_NOTFOUND )
2338         return mpImpl->mpItemList->GetObject( nPos )->maImage;
2339 	else
2340 		return Image();
2341 }
2342 
2343 // -----------------------------------------------------------------------
2344 
2345 void ValueSet::SetItemColor( sal_uInt16 nItemId, const Color& rColor )
2346 {
2347 	sal_uInt16 nPos = GetItemPos( nItemId );
2348 
2349 	if ( nPos == VALUESET_ITEM_NOTFOUND )
2350 		return;
2351 
2352     ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
2353 	pItem->meType  = VALUESETITEM_COLOR;
2354 	pItem->maColor = rColor;
2355 
2356 	if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2357 	{
2358 		ImplFormatItem( pItem );
2359 		Invalidate( pItem->maRect );
2360 	}
2361 	else
2362 		mbFormat = sal_True;
2363 }
2364 
2365 // -----------------------------------------------------------------------
2366 
2367 Color ValueSet::GetItemColor( sal_uInt16 nItemId ) const
2368 {
2369 	sal_uInt16 nPos = GetItemPos( nItemId );
2370 
2371 	if ( nPos != VALUESET_ITEM_NOTFOUND )
2372         return mpImpl->mpItemList->GetObject( nPos )->maColor;
2373 	else
2374 		return Color();
2375 }
2376 
2377 // -----------------------------------------------------------------------
2378 
2379 void ValueSet::SetItemData( sal_uInt16 nItemId, void* pData )
2380 {
2381 	sal_uInt16 nPos = GetItemPos( nItemId );
2382 
2383 	if ( nPos == VALUESET_ITEM_NOTFOUND )
2384 		return;
2385 
2386     ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
2387 	pItem->mpData = pData;
2388 
2389 	if ( pItem->meType == VALUESETITEM_USERDRAW )
2390 	{
2391 		if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2392 		{
2393 			ImplFormatItem( pItem );
2394 			Invalidate( pItem->maRect );
2395 		}
2396 		else
2397 			mbFormat = sal_True;
2398 	}
2399 }
2400 
2401 // -----------------------------------------------------------------------
2402 
2403 void* ValueSet::GetItemData( sal_uInt16 nItemId ) const
2404 {
2405 	sal_uInt16 nPos = GetItemPos( nItemId );
2406 
2407 	if ( nPos != VALUESET_ITEM_NOTFOUND )
2408         return mpImpl->mpItemList->GetObject( nPos )->mpData;
2409 	else
2410 		return NULL;
2411 }
2412 
2413 // -----------------------------------------------------------------------
2414 
2415 void ValueSet::SetItemText( sal_uInt16 nItemId, const XubString& rText )
2416 {
2417 	sal_uInt16 nPos = GetItemPos( nItemId );
2418 
2419 	if ( nPos == VALUESET_ITEM_NOTFOUND )
2420 		return;
2421 
2422 
2423     ValueSetItem* pItem = mpImpl->mpItemList->GetObject( nPos );
2424 
2425     // Remember old and new name for accessibility event.
2426     ::com::sun::star::uno::Any aOldName, aNewName;
2427     ::rtl::OUString sString (pItem->maText);
2428     aOldName <<= sString;
2429     sString = rText;
2430     aNewName <<= sString;
2431 
2432 	pItem->maText = rText;
2433 
2434 	if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2435 	{
2436 		sal_uInt16 nTempId = mnSelItemId;
2437 
2438 		if ( mbHighlight )
2439 			nTempId = mnHighItemId;
2440 
2441 		if ( nTempId == nItemId )
2442 			ImplDrawItemText( pItem->maText );
2443 	}
2444 
2445     if (ImplHasAccessibleListeners())
2446     {
2447         ::com::sun::star::uno::Reference<
2448               ::com::sun::star::accessibility::XAccessible> xAccessible (
2449                   pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
2450         static_cast<ValueItemAcc*>(xAccessible.get())->FireAccessibleEvent (
2451             ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED,
2452             aOldName, aNewName);
2453     }
2454 }
2455 
2456 // -----------------------------------------------------------------------
2457 
2458 XubString ValueSet::GetItemText( sal_uInt16 nItemId ) const
2459 {
2460 	sal_uInt16 nPos = GetItemPos( nItemId );
2461 
2462 	if ( nPos != VALUESET_ITEM_NOTFOUND )
2463         return mpImpl->mpItemList->GetObject( nPos )->maText;
2464 	else
2465 		return XubString();
2466 }
2467 
2468 // -----------------------------------------------------------------------
2469 
2470 void ValueSet::SetColor( const Color& rColor )
2471 {
2472 	maColor 	= rColor;
2473 	mbFormat	= sal_True;
2474 	if ( IsReallyVisible() && IsUpdateMode() )
2475 		ImplDraw();
2476 }
2477 
2478 // -----------------------------------------------------------------------
2479 
2480 void ValueSet::SetExtraSpacing( sal_uInt16 nNewSpacing )
2481 {
2482 	if ( GetStyle() & WB_ITEMBORDER )
2483 	{
2484 		mnSpacing = nNewSpacing;
2485 
2486 		mbFormat = sal_True;
2487 		if ( IsReallyVisible() && IsUpdateMode() )
2488 			Invalidate();
2489 	}
2490 }
2491 
2492 // -----------------------------------------------------------------------
2493 
2494 void ValueSet::StartSelection()
2495 {
2496 	mnOldItemId 	= mnSelItemId;
2497 	mbHighlight 	= sal_True;
2498 	mbSelection 	= sal_True;
2499 	mnHighItemId	= mnSelItemId;
2500 }
2501 
2502 // -----------------------------------------------------------------------
2503 
2504 void ValueSet::EndSelection()
2505 {
2506 	if ( mbHighlight )
2507 	{
2508 		if ( IsTracking() )
2509 			EndTracking( ENDTRACK_CANCEL );
2510 
2511 		ImplHighlightItem( mnSelItemId );
2512 		mbHighlight = sal_False;
2513 	}
2514 	mbSelection = sal_False;
2515 }
2516 
2517 // -----------------------------------------------------------------------
2518 
2519 sal_Bool ValueSet::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
2520 {
2521 	if ( rCEvt.GetCommand() != COMMAND_STARTDRAG )
2522 		return sal_False;
2523 
2524 	// Gegebenenfalls eine vorhandene Aktion abbrechen
2525 	EndSelection();
2526 
2527 	// Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
2528 	// der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
2529 	// Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
2530 	// dies nur bei einer Mausaktion.
2531 	sal_uInt16 nSelId;
2532 	if ( rCEvt.IsMouseEvent() )
2533 		nSelId = GetItemId( rCEvt.GetMousePosPixel() );
2534 	else
2535 		nSelId = mnSelItemId;
2536 
2537 	// Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
2538 	if ( !nSelId )
2539 		return sal_False;
2540 
2541 	// Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
2542 	// Seite setzen und Select rufen.
2543 	if ( nSelId != mnSelItemId )
2544 	{
2545 		SelectItem( nSelId );
2546 		Update();
2547 		Select();
2548 	}
2549 
2550 	Region aRegion;
2551 
2552 	// Region zuweisen
2553 	rRegion = aRegion;
2554 
2555 	return sal_True;
2556 }
2557 
2558 // -----------------------------------------------------------------------
2559 
2560 Size ValueSet::CalcWindowSizePixel( const Size& rItemSize, sal_uInt16 nDesireCols,
2561 									sal_uInt16 nDesireLines )
2562 {
2563 	long nCalcCols = (long)nDesireCols;
2564 	long nCalcLines = (long)nDesireLines;
2565 
2566 	if ( !nCalcCols )
2567 	{
2568 		if ( mnUserCols )
2569 			nCalcCols = (long)mnUserCols;
2570 		else
2571 			nCalcCols = 1;
2572 	}
2573 
2574 	if ( !nCalcLines )
2575 	{
2576 		nCalcLines = mnVisLines;
2577 
2578 		if ( mbFormat )
2579 		{
2580 			if ( mnUserVisLines )
2581 				nCalcLines = mnUserVisLines;
2582 			else
2583 			{
2584                 nCalcLines = (long)mpImpl->mpItemList->Count() / nCalcCols;
2585                 if ( mpImpl->mpItemList->Count() % nCalcCols )
2586 					nCalcLines++;
2587 				else if ( !nCalcLines )
2588 					nCalcLines = 1;
2589 			}
2590 		}
2591 	}
2592 
2593 	Size		aSize( rItemSize.Width()*nCalcCols, rItemSize.Height()*nCalcLines );
2594 	WinBits 	nStyle = GetStyle();
2595 	long		nTxtHeight = GetTextHeight();
2596 	long		nSpace;
2597 	long		n;
2598 
2599 	if ( nStyle & WB_ITEMBORDER )
2600 	{
2601 		if ( nStyle & WB_DOUBLEBORDER )
2602 			n = ITEM_OFFSET_DOUBLE;
2603 		else
2604 			n = ITEM_OFFSET;
2605 
2606 		aSize.Width()  += n*nCalcCols;
2607 		aSize.Height() += n*nCalcLines;
2608 	}
2609 	else
2610 		n = 0;
2611 
2612 	if ( mnSpacing )
2613 	{
2614 		nSpace = mnSpacing;
2615 		aSize.Width()  += mnSpacing*(nCalcCols-1);
2616 		aSize.Height() += mnSpacing*(nCalcLines-1);
2617 	}
2618 	else
2619 		nSpace = 0;
2620 
2621 	if ( nStyle & WB_NAMEFIELD )
2622 	{
2623 		aSize.Height() += nTxtHeight + NAME_OFFSET;
2624 		if ( !(nStyle & WB_FLATVALUESET) )
2625 			aSize.Height() += NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
2626 	}
2627 
2628 	if ( nStyle & WB_NONEFIELD )
2629 	{
2630 		aSize.Height() += nTxtHeight + n + nSpace;
2631 		if ( nStyle & WB_RADIOSEL )
2632 			aSize.Height() += 8;
2633 	}
2634 
2635 	// Evt. ScrollBar-Breite aufaddieren
2636 	aSize.Width() += GetScrollWidth();
2637 
2638 	return aSize;
2639 }
2640 
2641 // -----------------------------------------------------------------------
2642 
2643 Size ValueSet::CalcItemSizePixel( const Size& rItemSize, sal_Bool bOut ) const
2644 {
2645 	Size aSize = rItemSize;
2646 
2647 	WinBits nStyle = GetStyle();
2648 	if ( nStyle & WB_ITEMBORDER )
2649 	{
2650 		long n;
2651 
2652 		if ( nStyle & WB_DOUBLEBORDER )
2653 			n = ITEM_OFFSET_DOUBLE;
2654 		else
2655 			n = ITEM_OFFSET;
2656 
2657 		if ( bOut )
2658 		{
2659 			aSize.Width()  += n;
2660 			aSize.Height() += n;
2661 		}
2662 		else
2663 		{
2664 			aSize.Width()  -= n;
2665 			aSize.Height() -= n;
2666 		}
2667 	}
2668 
2669 	return aSize;
2670 }
2671 
2672 // -----------------------------------------------------------------------
2673 
2674 long ValueSet::GetScrollWidth() const
2675 {
2676 	if ( GetStyle() & WB_VSCROLL )
2677 	{
2678 		((ValueSet*)this)->ImplInitScrollBar();
2679 		return mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
2680 	}
2681 	else
2682 		return 0;
2683 }
2684 
2685 // -----------------------------------------------------------------------
2686 
2687 sal_uInt16 ValueSet::ShowDropPos( const Point& rPos )
2688 {
2689 	mbDropPos = sal_True;
2690 
2691 	// Gegebenenfalls scrollen
2692 	ImplScroll( rPos );
2693 
2694 	// DropPosition ermitteln
2695 	sal_uInt16 nPos = ImplGetItem( rPos, sal_True );
2696 	if ( nPos == VALUESET_ITEM_NONEITEM )
2697 		nPos = 0;
2698 	else if ( nPos == VALUESET_ITEM_NOTFOUND )
2699 	{
2700 		Size aOutSize = GetOutputSizePixel();
2701 		if ( GetStyle() & WB_NAMEFIELD )
2702 			aOutSize.Height() = mnTextOffset;
2703 		if ( (rPos.X() >= 0) && (rPos.X() < aOutSize.Width()) &&
2704 			 (rPos.Y() >= 0) && (rPos.Y() < aOutSize.Height()) )
2705             nPos = (sal_uInt16)mpImpl->mpItemList->Count();
2706 	}
2707 	else
2708 	{
2709 		// Im letzten viertel, dann wird ein Item spaeter eingefuegt
2710         Rectangle aRect = mpImpl->mpItemList->GetObject( nPos )->maRect;
2711 		if ( rPos.X() > aRect.Left()+aRect.GetWidth()-(aRect.GetWidth()/4) )
2712 			nPos++;
2713 	}
2714 
2715 	if ( nPos != mnDropPos )
2716 	{
2717 		ImplDrawDropPos( sal_False );
2718 		mnDropPos = nPos;
2719 		ImplDrawDropPos( sal_True );
2720 	}
2721 
2722 	return mnDropPos;
2723 }
2724 
2725 // -----------------------------------------------------------------------
2726 
2727 void ValueSet::HideDropPos()
2728 {
2729 	if ( mbDropPos )
2730 	{
2731 		ImplDrawDropPos( sal_False );
2732 		mbDropPos = sal_False;
2733 	}
2734 }
2735 
2736 // -----------------------------------------------------------------------
2737 
2738 bool ValueSet::IsRTLActive (void)
2739 {
2740     return Application::GetSettings().GetLayoutRTL() && IsRTLEnabled();
2741 }
2742 
2743 // -----------------------------------------------------------------------
2744 
2745 void ValueSet::SetHighlightHdl( const Link& rLink )
2746 {
2747 	mpImpl->maHighlightHdl = rLink;
2748 }
2749 
2750 // -----------------------------------------------------------------------
2751 
2752 const Link& ValueSet::GetHighlightHdl() const
2753 {
2754 	return mpImpl->maHighlightHdl;
2755 }
2756 
2757 // -----------------------------------------------------------------------
2758 
2759