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