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