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