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