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