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