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