Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/debug.hxx>
21 : #include <vcl/builder.hxx>
22 : #include <vcl/decoview.hxx>
23 : #include <vcl/svapp.hxx>
24 : #include <vcl/scrbar.hxx>
25 : #include <vcl/help.hxx>
26 : #include <vcl/settings.hxx>
27 :
28 : #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
29 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
30 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
31 : #include <com/sun/star/lang/XComponent.hpp>
32 : #include <rtl/ustring.hxx>
33 : #include "valueimp.hxx"
34 :
35 : #include <svtools/valueset.hxx>
36 :
37 : namespace
38 : {
39 :
40 : enum {
41 : ITEM_OFFSET = 4,
42 : ITEM_OFFSET_DOUBLE = 6,
43 : NAME_LINE_OFF_X = 2,
44 : NAME_LINE_OFF_Y = 2,
45 : NAME_LINE_HEIGHT = 2,
46 : NAME_OFFSET = 2,
47 : SCRBAR_OFFSET = 1,
48 : SCROLL_OFFSET = 4
49 : };
50 :
51 : }
52 :
53 :
54 : // - ValueSet -
55 :
56 :
57 0 : void ValueSet::ImplInit()
58 : {
59 0 : mpNoneItem = NULL;
60 0 : mpScrBar = NULL;
61 0 : mnItemWidth = 0;
62 0 : mnItemHeight = 0;
63 0 : mnTextOffset = 0;
64 0 : mnVisLines = 0;
65 0 : mnLines = 0;
66 0 : mnUserItemWidth = 0;
67 0 : mnUserItemHeight = 0;
68 0 : mnFirstLine = 0;
69 0 : mnSelItemId = 0;
70 0 : mnHighItemId = 0;
71 0 : mnCols = 0;
72 0 : mnCurCol = 0;
73 0 : mnUserCols = 0;
74 0 : mnUserVisLines = 0;
75 0 : mnSpacing = 0;
76 0 : mnFrameStyle = 0;
77 0 : mbFormat = true;
78 0 : mbHighlight = false;
79 0 : mbSelection = false;
80 0 : mbNoSelection = true;
81 0 : mbDrawSelection = true;
82 0 : mbBlackSel = false;
83 0 : mbDoubleSel = false;
84 0 : mbScroll = false;
85 0 : mbFullMode = true;
86 0 : mbEdgeBlending = false;
87 0 : mbHasVisibleItems = false;
88 :
89 : // #106446#, #106601# force mirroring of virtual device
90 0 : maVirDev.EnableRTL( GetParent()->IsRTLEnabled() );
91 :
92 0 : ImplInitSettings( true, true, true );
93 0 : }
94 :
95 :
96 :
97 0 : ValueSet::ValueSet( Window* pParent, WinBits nWinStyle, bool bDisableTransientChildren ) :
98 : Control( pParent, nWinStyle ),
99 : maVirDev( *this ),
100 0 : maColor( COL_TRANSPARENT )
101 : {
102 0 : ImplInit();
103 0 : mbIsTransientChildrenDisabled = bDisableTransientChildren;
104 0 : }
105 :
106 0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeValueSet(Window *pParent, VclBuilder::stringmap &rMap)
107 : {
108 0 : WinBits nWinBits = WB_TABSTOP;
109 :
110 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
111 0 : if (!sBorder.isEmpty())
112 0 : nWinBits |= WB_BORDER;
113 :
114 0 : return new ValueSet(pParent, nWinBits);
115 : }
116 :
117 :
118 :
119 0 : ValueSet::ValueSet( Window* pParent, const ResId& rResId, bool bDisableTransientChildren ) :
120 : Control( pParent, rResId ),
121 : maVirDev( *this ),
122 0 : maColor( COL_TRANSPARENT )
123 : {
124 0 : ImplInit();
125 0 : mbIsTransientChildrenDisabled = bDisableTransientChildren;
126 0 : }
127 :
128 :
129 :
130 0 : ValueSet::~ValueSet()
131 : {
132 : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
133 0 : xComponent (GetAccessible(false), ::com::sun::star::uno::UNO_QUERY);
134 0 : if (xComponent.is())
135 0 : xComponent->dispose ();
136 :
137 0 : delete mpScrBar;
138 0 : delete mpNoneItem;
139 :
140 0 : ImplDeleteItems();
141 0 : }
142 :
143 :
144 :
145 0 : void ValueSet::ImplDeleteItems()
146 : {
147 0 : const size_t n = mItemList.size();
148 :
149 0 : for ( size_t i = 0; i < n; ++i )
150 : {
151 0 : ValueSetItem *const pItem = mItemList[i];
152 0 : if ( pItem->mbVisible && ImplHasAccessibleListeners() )
153 : {
154 0 : ::com::sun::star::uno::Any aOldAny, aNewAny;
155 :
156 0 : aOldAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled );
157 0 : ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
158 : }
159 :
160 0 : delete pItem;
161 : }
162 :
163 0 : mItemList.clear();
164 0 : }
165 :
166 :
167 :
168 0 : void ValueSet::ImplInitSettings( bool bFont, bool bForeground, bool bBackground )
169 : {
170 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
171 :
172 0 : if ( bFont )
173 : {
174 0 : Font aFont;
175 0 : aFont = rStyleSettings.GetAppFont();
176 0 : if ( IsControlFont() )
177 0 : aFont.Merge( GetControlFont() );
178 0 : SetZoomedPointFont( aFont );
179 : }
180 :
181 0 : if ( bForeground || bFont )
182 : {
183 0 : Color aColor;
184 0 : if ( IsControlForeground() )
185 0 : aColor = GetControlForeground();
186 : else
187 0 : aColor = rStyleSettings.GetButtonTextColor();
188 0 : SetTextColor( aColor );
189 0 : SetTextFillColor();
190 : }
191 :
192 0 : if ( bBackground )
193 : {
194 0 : Color aColor;
195 0 : if ( IsControlBackground() )
196 0 : aColor = GetControlBackground();
197 0 : else if ( GetStyle() & WB_MENUSTYLEVALUESET )
198 0 : aColor = rStyleSettings.GetMenuColor();
199 0 : else if ( IsEnabled() && (GetStyle() & WB_FLATVALUESET) )
200 0 : aColor = rStyleSettings.GetWindowColor();
201 : else
202 0 : aColor = rStyleSettings.GetFaceColor();
203 0 : SetBackground( aColor );
204 : }
205 0 : }
206 :
207 :
208 :
209 0 : void ValueSet::ImplInitScrollBar()
210 : {
211 0 : if ( GetStyle() & WB_VSCROLL )
212 : {
213 0 : if ( !mpScrBar )
214 : {
215 0 : mpScrBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
216 0 : mpScrBar->SetScrollHdl( LINK( this, ValueSet, ImplScrollHdl ) );
217 : }
218 : else
219 : {
220 : // adapt the width because of the changed settings
221 0 : long nScrBarWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
222 0 : mpScrBar->setPosSizePixel( 0, 0, nScrBarWidth, 0, WINDOW_POSSIZE_WIDTH );
223 : }
224 : }
225 0 : }
226 :
227 :
228 :
229 0 : void ValueSet::ImplFormatItem( ValueSetItem* pItem, Rectangle aRect )
230 : {
231 0 : WinBits nStyle = GetStyle();
232 0 : if ( nStyle & WB_ITEMBORDER )
233 : {
234 0 : aRect.Left()++;
235 0 : aRect.Top()++;
236 0 : aRect.Right()--;
237 0 : aRect.Bottom()--;
238 0 : if ( nStyle & WB_FLATVALUESET )
239 : {
240 0 : if ( nStyle & WB_DOUBLEBORDER )
241 : {
242 0 : aRect.Left() += 2;
243 0 : aRect.Top() += 2;
244 0 : aRect.Right() -= 2;
245 0 : aRect.Bottom() -= 2;
246 : }
247 : else
248 : {
249 0 : aRect.Left()++;
250 0 : aRect.Top()++;
251 0 : aRect.Right()--;
252 0 : aRect.Bottom()--;
253 : }
254 : }
255 : else
256 : {
257 0 : DecorationView aView( &maVirDev );
258 0 : aRect = aView.DrawFrame( aRect, mnFrameStyle );
259 : }
260 : }
261 :
262 0 : if ( pItem == mpNoneItem )
263 0 : pItem->maText = GetText();
264 :
265 0 : if ( (aRect.GetHeight() > 0) && (aRect.GetWidth() > 0) )
266 : {
267 0 : const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
268 :
269 0 : if ( pItem == mpNoneItem )
270 : {
271 0 : maVirDev.SetFont( GetFont() );
272 0 : maVirDev.SetTextColor( ( nStyle & WB_MENUSTYLEVALUESET ) ? rStyleSettings.GetMenuTextColor() : rStyleSettings.GetWindowTextColor() );
273 0 : maVirDev.SetTextFillColor();
274 0 : maVirDev.SetFillColor( ( nStyle & WB_MENUSTYLEVALUESET ) ? rStyleSettings.GetMenuColor() : rStyleSettings.GetWindowColor() );
275 0 : maVirDev.DrawRect( aRect );
276 0 : Point aTxtPos( aRect.Left()+2, aRect.Top() );
277 0 : long nTxtWidth = GetTextWidth( pItem->maText );
278 0 : if ( nStyle & WB_RADIOSEL )
279 : {
280 0 : aTxtPos.X() += 4;
281 0 : aTxtPos.Y() += 4;
282 : }
283 0 : if ( (aTxtPos.X()+nTxtWidth) > aRect.Right() )
284 : {
285 0 : maVirDev.SetClipRegion( Region( aRect ) );
286 0 : maVirDev.DrawText( aTxtPos, pItem->maText );
287 0 : maVirDev.SetClipRegion();
288 : }
289 : else
290 0 : maVirDev.DrawText( aTxtPos, pItem->maText );
291 : }
292 0 : else if ( pItem->meType == VALUESETITEM_COLOR )
293 : {
294 0 : maVirDev.SetFillColor( pItem->maColor );
295 0 : maVirDev.DrawRect( aRect );
296 : }
297 : else
298 : {
299 0 : if ( IsColor() )
300 0 : maVirDev.SetFillColor( maColor );
301 0 : else if ( nStyle & WB_MENUSTYLEVALUESET )
302 0 : maVirDev.SetFillColor( rStyleSettings.GetMenuColor() );
303 0 : else if ( IsEnabled() )
304 0 : maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
305 : else
306 0 : maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
307 0 : maVirDev.DrawRect( aRect );
308 :
309 0 : if ( pItem->meType == VALUESETITEM_USERDRAW )
310 : {
311 0 : UserDrawEvent aUDEvt( &maVirDev, aRect, pItem->mnId );
312 0 : UserDraw( aUDEvt );
313 : }
314 : else
315 : {
316 0 : Size aImageSize = pItem->maImage.GetSizePixel();
317 0 : Size aRectSize = aRect.GetSize();
318 0 : Point aPos( aRect.Left(), aRect.Top() );
319 0 : aPos.X() += (aRectSize.Width()-aImageSize.Width())/2;
320 0 : aPos.Y() += (aRectSize.Height()-aImageSize.Height())/2;
321 :
322 0 : sal_uInt16 nImageStyle = 0;
323 0 : if( !IsEnabled() )
324 0 : nImageStyle |= IMAGE_DRAW_DISABLE;
325 :
326 0 : if ( (aImageSize.Width() > aRectSize.Width()) ||
327 0 : (aImageSize.Height() > aRectSize.Height()) )
328 : {
329 0 : maVirDev.SetClipRegion( Region( aRect ) );
330 0 : maVirDev.DrawImage( aPos, pItem->maImage, nImageStyle);
331 0 : maVirDev.SetClipRegion();
332 : }
333 : else
334 0 : maVirDev.DrawImage( aPos, pItem->maImage, nImageStyle );
335 : }
336 : }
337 :
338 0 : const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);
339 :
340 0 : if(nEdgeBlendingPercent)
341 : {
342 0 : const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
343 0 : const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
344 0 : const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
345 0 : const BitmapEx aBlendFrame(createBlendFrame(aRect.GetSize(), nAlpha, rTopLeft, rBottomRight));
346 :
347 0 : if(!aBlendFrame.IsEmpty())
348 : {
349 0 : maVirDev.DrawBitmapEx(aRect.TopLeft(), aBlendFrame);
350 0 : }
351 : }
352 : }
353 0 : }
354 :
355 :
356 :
357 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ValueSet::CreateAccessible()
358 : {
359 0 : return new ValueSetAcc( this, mbIsTransientChildrenDisabled );
360 : }
361 :
362 :
363 :
364 0 : void ValueSet::Format()
365 : {
366 0 : Size aWinSize = GetOutputSizePixel();
367 0 : size_t nItemCount = mItemList.size();
368 0 : WinBits nStyle = GetStyle();
369 0 : long nTxtHeight = GetTextHeight();
370 : long nOff;
371 : long nNoneHeight;
372 : long nNoneSpace;
373 0 : ScrollBar* pDelScrBar = NULL;
374 :
375 : // consider the scrolling
376 0 : if ( nStyle & WB_VSCROLL )
377 0 : ImplInitScrollBar();
378 : else
379 : {
380 0 : if ( mpScrBar )
381 : {
382 : // delete ScrollBar not until later, to prevent recursive calls
383 0 : pDelScrBar = mpScrBar;
384 0 : mpScrBar = NULL;
385 : }
386 : }
387 :
388 : // calculate item offset
389 0 : if ( nStyle & WB_ITEMBORDER )
390 : {
391 0 : if ( nStyle & WB_DOUBLEBORDER )
392 0 : nOff = ITEM_OFFSET_DOUBLE;
393 : else
394 0 : nOff = ITEM_OFFSET;
395 : }
396 : else
397 0 : nOff = 0;
398 :
399 : // consider size, if NameField does exist
400 0 : if ( nStyle & WB_NAMEFIELD )
401 : {
402 0 : mnTextOffset = aWinSize.Height()-nTxtHeight-NAME_OFFSET;
403 0 : aWinSize.Height() -= nTxtHeight+NAME_OFFSET;
404 :
405 0 : if ( !(nStyle & WB_FLATVALUESET) )
406 : {
407 0 : mnTextOffset -= NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
408 0 : aWinSize.Height() -= NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
409 : }
410 : }
411 : else
412 0 : mnTextOffset = 0;
413 :
414 : // consider offset and size, if NoneField does exist
415 0 : if ( nStyle & WB_NONEFIELD )
416 : {
417 0 : nNoneHeight = nTxtHeight+nOff;
418 0 : nNoneSpace = mnSpacing;
419 0 : if ( nStyle & WB_RADIOSEL )
420 0 : nNoneHeight += 8;
421 : }
422 : else
423 : {
424 0 : nNoneHeight = 0;
425 0 : nNoneSpace = 0;
426 :
427 0 : if ( mpNoneItem )
428 : {
429 0 : delete mpNoneItem;
430 0 : mpNoneItem = NULL;
431 : }
432 : }
433 :
434 : // calculate ScrollBar width
435 0 : long nScrBarWidth = 0;
436 0 : if ( mpScrBar )
437 0 : nScrBarWidth = mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
438 :
439 : // calculate number of columns
440 0 : if ( !mnUserCols )
441 : {
442 0 : if ( mnUserItemWidth )
443 : {
444 0 : mnCols = (sal_uInt16)((aWinSize.Width()-nScrBarWidth+mnSpacing) / (mnUserItemWidth+mnSpacing));
445 0 : if ( !mnCols )
446 0 : mnCols = 1;
447 : }
448 : else
449 0 : mnCols = 1;
450 : }
451 : else
452 0 : mnCols = mnUserCols;
453 :
454 : // calculate number of rows
455 0 : mbScroll = false;
456 : // Floor( (M+N-1)/N )==Ceiling( M/N )
457 0 : mnLines = (static_cast<long>(nItemCount)+mnCols-1) / mnCols;
458 0 : if ( !mnLines )
459 0 : mnLines = 1;
460 :
461 0 : long nCalcHeight = aWinSize.Height()-nNoneHeight;
462 0 : if ( mnUserVisLines )
463 0 : mnVisLines = mnUserVisLines;
464 0 : else if ( mnUserItemHeight )
465 : {
466 0 : mnVisLines = (nCalcHeight-nNoneSpace+mnSpacing) / (mnUserItemHeight+mnSpacing);
467 0 : if ( !mnVisLines )
468 0 : mnVisLines = 1;
469 : }
470 : else
471 0 : mnVisLines = mnLines;
472 0 : if ( mnLines > mnVisLines )
473 0 : mbScroll = true;
474 0 : if ( mnLines <= mnVisLines )
475 0 : mnFirstLine = 0;
476 : else
477 : {
478 0 : if ( mnFirstLine > (sal_uInt16)(mnLines-mnVisLines) )
479 0 : mnFirstLine = (sal_uInt16)(mnLines-mnVisLines);
480 : }
481 :
482 : // calculate item size
483 0 : const long nColSpace = (mnCols-1)*mnSpacing;
484 0 : const long nLineSpace = ((mnVisLines-1)*mnSpacing)+nNoneSpace;
485 0 : if ( mnUserItemWidth && !mnUserCols )
486 : {
487 0 : mnItemWidth = mnUserItemWidth;
488 0 : if ( mnItemWidth > aWinSize.Width()-nScrBarWidth-nColSpace )
489 0 : mnItemWidth = aWinSize.Width()-nScrBarWidth-nColSpace;
490 : }
491 : else
492 0 : mnItemWidth = (aWinSize.Width()-nScrBarWidth-nColSpace) / mnCols;
493 0 : if ( mnUserItemHeight && !mnUserVisLines )
494 : {
495 0 : mnItemHeight = mnUserItemHeight;
496 0 : if ( mnItemHeight > nCalcHeight-nNoneSpace )
497 0 : mnItemHeight = nCalcHeight-nNoneSpace;
498 : }
499 : else
500 : {
501 0 : nCalcHeight -= nLineSpace;
502 0 : mnItemHeight = nCalcHeight / mnVisLines;
503 : }
504 :
505 : // Init VirDev
506 0 : maVirDev.SetSettings( GetSettings() );
507 0 : maVirDev.SetBackground( GetBackground() );
508 0 : maVirDev.SetOutputSizePixel( aWinSize, true );
509 :
510 : // nothing is changed in case of too small items
511 0 : if ( (mnItemWidth <= 0) ||
512 0 : (mnItemHeight <= (( nStyle & WB_ITEMBORDER ) ? 4 : 2)) ||
513 : !nItemCount )
514 : {
515 0 : mbHasVisibleItems = false;
516 :
517 0 : if ( nStyle & WB_NONEFIELD )
518 : {
519 0 : if ( mpNoneItem )
520 : {
521 0 : mpNoneItem->mbVisible = false;
522 0 : mpNoneItem->maText = GetText();
523 : }
524 : }
525 :
526 0 : for ( size_t i = 0; i < nItemCount; i++ )
527 : {
528 0 : mItemList[i]->mbVisible = false;
529 : }
530 :
531 0 : if ( mpScrBar )
532 0 : mpScrBar->Hide();
533 : }
534 : else
535 : {
536 0 : mbHasVisibleItems = true;
537 :
538 : // determine Frame-Style
539 0 : if ( nStyle & WB_DOUBLEBORDER )
540 0 : mnFrameStyle = FRAME_DRAW_DOUBLEIN;
541 : else
542 0 : mnFrameStyle = FRAME_DRAW_IN;
543 :
544 : // determine selected color and width
545 : // if necessary change the colors, to make the selection
546 : // better detectable
547 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
548 0 : Color aHighColor( rStyleSettings.GetHighlightColor() );
549 0 : if ( ((aHighColor.GetRed() > 0x80) || (aHighColor.GetGreen() > 0x80) ||
550 0 : (aHighColor.GetBlue() > 0x80)) ||
551 0 : ((aHighColor.GetRed() == 0x80) && (aHighColor.GetGreen() == 0x80) &&
552 0 : (aHighColor.GetBlue() == 0x80)) )
553 0 : mbBlackSel = true;
554 : else
555 0 : mbBlackSel = false;
556 :
557 : // draw the selection with double width if the items are bigger
558 0 : if ( (nStyle & WB_DOUBLEBORDER) &&
559 0 : ((mnItemWidth >= 25) && (mnItemHeight >= 20)) )
560 0 : mbDoubleSel = true;
561 : else
562 0 : mbDoubleSel = false;
563 :
564 : // calculate offsets
565 : long nStartX;
566 : long nStartY;
567 0 : if ( mbFullMode )
568 : {
569 0 : long nAllItemWidth = (mnItemWidth*mnCols)+nColSpace;
570 0 : long nAllItemHeight = (mnItemHeight*mnVisLines)+nNoneHeight+nLineSpace;
571 0 : nStartX = (aWinSize.Width()-nScrBarWidth-nAllItemWidth)/2;
572 0 : nStartY = (aWinSize.Height()-nAllItemHeight)/2;
573 : }
574 : else
575 : {
576 0 : nStartX = 0;
577 0 : nStartY = 0;
578 : }
579 :
580 : // calculate and draw items
581 0 : maVirDev.SetLineColor();
582 0 : long x = nStartX;
583 0 : long y = nStartY;
584 :
585 : // create NoSelection field and show it
586 0 : if ( nStyle & WB_NONEFIELD )
587 : {
588 0 : if ( !mpNoneItem )
589 0 : mpNoneItem = new ValueSetItem( *this );
590 :
591 0 : mpNoneItem->mnId = 0;
592 0 : mpNoneItem->meType = VALUESETITEM_NONE;
593 0 : mpNoneItem->mbVisible = true;
594 0 : maNoneItemRect.Left() = x;
595 0 : maNoneItemRect.Top() = y;
596 0 : maNoneItemRect.Right() = maNoneItemRect.Left()+aWinSize.Width()-x-1;
597 0 : maNoneItemRect.Bottom() = y+nNoneHeight-1;
598 :
599 0 : ImplFormatItem( mpNoneItem, maNoneItemRect );
600 :
601 0 : y += nNoneHeight+nNoneSpace;
602 : }
603 :
604 : // draw items
605 0 : sal_uLong nFirstItem = mnFirstLine * mnCols;
606 0 : sal_uLong nLastItem = nFirstItem + (mnVisLines * mnCols);
607 :
608 0 : maItemListRect.Left() = x;
609 0 : maItemListRect.Top() = y;
610 0 : maItemListRect.Right() = x + mnCols*(mnItemWidth+mnSpacing) - mnSpacing - 1;
611 0 : maItemListRect.Bottom() = y + mnVisLines*(mnItemHeight+mnSpacing) - mnSpacing - 1;
612 :
613 0 : if ( !mbFullMode )
614 : {
615 : // If want also draw parts of items in the last line,
616 : // then we add one more line if parts of these line are
617 : // visible
618 0 : if ( y+(mnVisLines*(mnItemHeight+mnSpacing)) < aWinSize.Height() )
619 0 : nLastItem += mnCols;
620 0 : maItemListRect.Bottom() = aWinSize.Height() - y;
621 : }
622 0 : for ( size_t i = 0; i < nItemCount; i++ )
623 : {
624 0 : ValueSetItem *const pItem = mItemList[i];
625 :
626 0 : if ( (i >= nFirstItem) && (i < nLastItem) )
627 : {
628 0 : if( !pItem->mbVisible && ImplHasAccessibleListeners() )
629 : {
630 0 : ::com::sun::star::uno::Any aOldAny, aNewAny;
631 :
632 0 : aNewAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled );
633 0 : ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
634 : }
635 :
636 0 : pItem->mbVisible = true;
637 0 : ImplFormatItem( pItem, Rectangle( Point(x,y), Size(mnItemWidth, mnItemHeight) ) );
638 :
639 0 : if ( !((i+1) % mnCols) )
640 : {
641 0 : x = nStartX;
642 0 : y += mnItemHeight+mnSpacing;
643 : }
644 : else
645 0 : x += mnItemWidth+mnSpacing;
646 : }
647 : else
648 : {
649 0 : if( pItem->mbVisible && ImplHasAccessibleListeners() )
650 : {
651 0 : ::com::sun::star::uno::Any aOldAny, aNewAny;
652 :
653 0 : aOldAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled );
654 0 : ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
655 : }
656 :
657 0 : pItem->mbVisible = false;
658 : }
659 : }
660 :
661 : // arrange ScrollBar, set values and show it
662 0 : if ( mpScrBar )
663 : {
664 0 : Point aPos( aWinSize.Width()-nScrBarWidth+SCRBAR_OFFSET, 0 );
665 0 : Size aSize( nScrBarWidth-SCRBAR_OFFSET, aWinSize.Height() );
666 : // If a none field is visible, then we center the scrollbar
667 0 : if ( nStyle & WB_NONEFIELD )
668 : {
669 0 : aPos.Y() = nStartY+nNoneHeight+1;
670 0 : aSize.Height() = ((mnItemHeight+mnSpacing)*mnVisLines)-2-mnSpacing;
671 : }
672 0 : mpScrBar->SetPosSizePixel( aPos, aSize );
673 0 : mpScrBar->SetRangeMax( mnLines );
674 0 : mpScrBar->SetVisibleSize( mnVisLines );
675 0 : mpScrBar->SetThumbPos( (long)mnFirstLine );
676 0 : long nPageSize = mnVisLines;
677 0 : if ( nPageSize < 1 )
678 0 : nPageSize = 1;
679 0 : mpScrBar->SetPageSize( nPageSize );
680 0 : mpScrBar->Show();
681 : }
682 : }
683 :
684 : // waiting for the next since the formatting is finished
685 0 : mbFormat = false;
686 :
687 : // delete ScrollBar
688 0 : delete pDelScrBar;
689 0 : }
690 :
691 :
692 :
693 0 : void ValueSet::ImplDrawItemText(const OUString& rText)
694 : {
695 0 : if ( !(GetStyle() & WB_NAMEFIELD) )
696 0 : return;
697 :
698 0 : Size aWinSize = GetOutputSizePixel();
699 0 : long nTxtWidth = GetTextWidth(rText);
700 0 : long nTxtOffset = mnTextOffset;
701 :
702 : // delete rectangle and show text
703 0 : if ( GetStyle() & WB_FLATVALUESET )
704 : {
705 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
706 0 : SetLineColor();
707 0 : SetFillColor( rStyleSettings.GetFaceColor() );
708 0 : DrawRect( Rectangle( Point( 0, nTxtOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
709 0 : SetTextColor( rStyleSettings.GetButtonTextColor() );
710 : }
711 : else
712 : {
713 0 : nTxtOffset += NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
714 0 : Erase( Rectangle( Point( 0, nTxtOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
715 : }
716 0 : DrawText( Point( (aWinSize.Width()-nTxtWidth) / 2, nTxtOffset+(NAME_OFFSET/2) ), rText );
717 : }
718 :
719 :
720 :
721 0 : void ValueSet::ImplDrawSelect()
722 : {
723 0 : if ( !IsReallyVisible() )
724 0 : return;
725 :
726 0 : const bool bFocus = HasFocus();
727 0 : const bool bDrawSel = !( (mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight) );
728 :
729 0 : if ( !bFocus && !bDrawSel )
730 : {
731 0 : ImplDrawItemText(OUString());
732 0 : return;
733 : }
734 :
735 0 : ImplDrawSelect( mnSelItemId, bFocus, bDrawSel );
736 0 : if (mbHighlight)
737 : {
738 0 : ImplDrawSelect( mnHighItemId, bFocus, bDrawSel );
739 : }
740 : }
741 :
742 :
743 :
744 0 : void ValueSet::ImplDrawSelect( sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel )
745 : {
746 : ValueSetItem* pItem;
747 0 : Rectangle aRect;
748 0 : if ( nItemId )
749 : {
750 0 : const size_t nPos = GetItemPos( nItemId );
751 0 : pItem = mItemList[ nPos ];
752 0 : aRect = ImplGetItemRect( nPos );
753 : }
754 0 : else if ( mpNoneItem )
755 : {
756 0 : pItem = mpNoneItem;
757 0 : aRect = maNoneItemRect;
758 : }
759 0 : else if ( bFocus && (pItem = ImplGetFirstItem()) )
760 : {
761 0 : aRect = ImplGetItemRect( 0 );
762 : }
763 : else
764 : {
765 0 : return;
766 : }
767 :
768 0 : if ( pItem->mbVisible )
769 : {
770 : // draw selection
771 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
772 0 : Control::SetFillColor();
773 :
774 0 : Color aDoubleColor( rStyleSettings.GetHighlightColor() );
775 0 : Color aSingleColor( rStyleSettings.GetHighlightTextColor() );
776 0 : if( !mbDoubleSel )
777 : {
778 : /*
779 : * #99777# contrast enhancement for thin mode
780 : */
781 0 : const Wallpaper& rWall = GetDisplayBackground();
782 0 : if( ! rWall.IsBitmap() && ! rWall.IsGradient() )
783 : {
784 0 : const Color& rBack = rWall.GetColor();
785 0 : if( rBack.IsDark() && ! aDoubleColor.IsBright() )
786 : {
787 0 : aDoubleColor = Color( COL_WHITE );
788 0 : aSingleColor = Color( COL_BLACK );
789 : }
790 0 : else if( rBack.IsBright() && ! aDoubleColor.IsDark() )
791 : {
792 0 : aDoubleColor = Color( COL_BLACK );
793 0 : aSingleColor = Color( COL_WHITE );
794 : }
795 : }
796 : }
797 :
798 : // specify selection output
799 0 : WinBits nStyle = GetStyle();
800 0 : if ( nStyle & WB_MENUSTYLEVALUESET )
801 : {
802 0 : if ( bFocus )
803 0 : ShowFocus( aRect );
804 :
805 0 : if ( bDrawSel )
806 : {
807 0 : SetLineColor( mbBlackSel ? Color( COL_BLACK ) : aDoubleColor );
808 0 : DrawRect( aRect );
809 : }
810 : }
811 0 : else if ( nStyle & WB_RADIOSEL )
812 : {
813 0 : aRect.Left() += 3;
814 0 : aRect.Top() += 3;
815 0 : aRect.Right() -= 3;
816 0 : aRect.Bottom() -= 3;
817 0 : if ( nStyle & WB_DOUBLEBORDER )
818 : {
819 0 : aRect.Left()++;
820 0 : aRect.Top()++;
821 0 : aRect.Right()--;
822 0 : aRect.Bottom()--;
823 : }
824 :
825 0 : if ( bFocus )
826 0 : ShowFocus( aRect );
827 :
828 0 : aRect.Left()++;
829 0 : aRect.Top()++;
830 0 : aRect.Right()--;
831 0 : aRect.Bottom()--;
832 :
833 0 : if ( bDrawSel )
834 : {
835 0 : SetLineColor( aDoubleColor );
836 0 : aRect.Left()++;
837 0 : aRect.Top()++;
838 0 : aRect.Right()--;
839 0 : aRect.Bottom()--;
840 0 : DrawRect( aRect );
841 0 : aRect.Left()++;
842 0 : aRect.Top()++;
843 0 : aRect.Right()--;
844 0 : aRect.Bottom()--;
845 0 : DrawRect( aRect );
846 : }
847 : }
848 : else
849 : {
850 0 : if ( bDrawSel )
851 : {
852 0 : SetLineColor( mbBlackSel ? Color( COL_BLACK ) : aDoubleColor );
853 0 : DrawRect( aRect );
854 : }
855 0 : if ( mbDoubleSel )
856 : {
857 0 : aRect.Left()++;
858 0 : aRect.Top()++;
859 0 : aRect.Right()--;
860 0 : aRect.Bottom()--;
861 0 : if ( bDrawSel )
862 0 : DrawRect( aRect );
863 : }
864 0 : aRect.Left()++;
865 0 : aRect.Top()++;
866 0 : aRect.Right()--;
867 0 : aRect.Bottom()--;
868 0 : Rectangle aRect2 = aRect;
869 0 : aRect.Left()++;
870 0 : aRect.Top()++;
871 0 : aRect.Right()--;
872 0 : aRect.Bottom()--;
873 0 : if ( bDrawSel )
874 0 : DrawRect( aRect );
875 0 : if ( mbDoubleSel )
876 : {
877 0 : aRect.Left()++;
878 0 : aRect.Top()++;
879 0 : aRect.Right()--;
880 0 : aRect.Bottom()--;
881 0 : if ( bDrawSel )
882 0 : DrawRect( aRect );
883 : }
884 :
885 0 : if ( bDrawSel )
886 : {
887 0 : SetLineColor( mbBlackSel ? Color( COL_WHITE ) : aSingleColor );
888 : }
889 : else
890 : {
891 0 : SetLineColor( Color( COL_LIGHTGRAY ) );
892 : }
893 0 : DrawRect( aRect2 );
894 :
895 0 : if ( bFocus )
896 0 : ShowFocus( aRect2 );
897 : }
898 :
899 0 : ImplDrawItemText(pItem->maText);
900 : }
901 : }
902 :
903 :
904 :
905 0 : void ValueSet::ImplHideSelect( sal_uInt16 nItemId )
906 : {
907 0 : Rectangle aRect;
908 :
909 0 : const size_t nItemPos = GetItemPos( nItemId );
910 0 : if ( nItemPos != VALUESET_ITEM_NOTFOUND )
911 : {
912 0 : if ( !mItemList[nItemPos]->mbVisible )
913 : {
914 0 : return;
915 : }
916 0 : aRect = ImplGetItemRect(nItemPos);
917 : }
918 : else
919 : {
920 0 : if ( !mpNoneItem )
921 : {
922 0 : return;
923 : }
924 0 : aRect = maNoneItemRect;
925 : }
926 :
927 0 : HideFocus();
928 0 : const Point aPos = aRect.TopLeft();
929 0 : const Size aSize = aRect.GetSize();
930 0 : DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
931 : }
932 :
933 :
934 :
935 0 : void ValueSet::ImplHighlightItem( sal_uInt16 nItemId, bool bIsSelection )
936 : {
937 0 : if ( mnHighItemId != nItemId )
938 : {
939 : // remember the old item to delete the previous selection
940 0 : sal_uInt16 nOldItem = mnHighItemId;
941 0 : mnHighItemId = nItemId;
942 :
943 : // don't draw the selection if nothing is selected
944 0 : if ( !bIsSelection && mbNoSelection )
945 0 : mbDrawSelection = false;
946 :
947 : // remove the old selection and draw the new one
948 0 : ImplHideSelect( nOldItem );
949 0 : ImplDrawSelect();
950 0 : mbDrawSelection = true;
951 : }
952 0 : }
953 :
954 :
955 :
956 0 : void ValueSet::ImplDraw()
957 : {
958 0 : if ( mbFormat )
959 0 : Format();
960 :
961 0 : HideFocus();
962 :
963 0 : Point aDefPos;
964 0 : Size aSize = maVirDev.GetOutputSizePixel();
965 :
966 0 : if ( mpScrBar && mpScrBar->IsVisible() )
967 : {
968 0 : Point aScrPos = mpScrBar->GetPosPixel();
969 0 : Size aScrSize = mpScrBar->GetSizePixel();
970 0 : Point aTempPos( 0, aScrPos.Y() );
971 0 : Size aTempSize( aSize.Width(), aScrPos.Y() );
972 :
973 0 : DrawOutDev( aDefPos, aTempSize, aDefPos, aTempSize, maVirDev );
974 0 : aTempSize.Width() = aScrPos.X()-1;
975 0 : aTempSize.Height() = aScrSize.Height();
976 0 : DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
977 0 : aTempPos.Y() = aScrPos.Y()+aScrSize.Height();
978 0 : aTempSize.Width() = aSize.Width();
979 0 : aTempSize.Height() = aSize.Height()-aTempPos.Y();
980 0 : DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
981 : }
982 : else
983 0 : DrawOutDev( aDefPos, aSize, aDefPos, aSize, maVirDev );
984 :
985 : // draw parting line to the Namefield
986 0 : if ( GetStyle() & WB_NAMEFIELD )
987 : {
988 0 : if ( !(GetStyle() & WB_FLATVALUESET) )
989 : {
990 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
991 0 : Size aWinSize = GetOutputSizePixel();
992 0 : Point aPos1( NAME_LINE_OFF_X, mnTextOffset+NAME_LINE_OFF_Y );
993 0 : Point aPos2( aWinSize.Width()-(NAME_LINE_OFF_X*2), mnTextOffset+NAME_LINE_OFF_Y );
994 0 : if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
995 : {
996 0 : SetLineColor( rStyleSettings.GetShadowColor() );
997 0 : DrawLine( aPos1, aPos2 );
998 0 : aPos1.Y()++;
999 0 : aPos2.Y()++;
1000 0 : SetLineColor( rStyleSettings.GetLightColor() );
1001 : }
1002 : else
1003 0 : SetLineColor( rStyleSettings.GetWindowTextColor() );
1004 0 : DrawLine( aPos1, aPos2 );
1005 : }
1006 : }
1007 :
1008 0 : ImplDrawSelect();
1009 0 : }
1010 :
1011 :
1012 :
1013 0 : bool ValueSet::ImplScroll( const Point& rPos )
1014 : {
1015 0 : if ( !mbScroll || !maItemListRect.IsInside(rPos) )
1016 0 : return false;
1017 :
1018 0 : const long nScrollOffset = (mnItemHeight <= 16) ? SCROLL_OFFSET/2 : SCROLL_OFFSET;
1019 0 : bool bScroll = false;
1020 :
1021 0 : if ( rPos.Y() <= maItemListRect.Top()+nScrollOffset )
1022 : {
1023 0 : if ( mnFirstLine > 0 )
1024 : {
1025 0 : --mnFirstLine;
1026 0 : bScroll = true;
1027 : }
1028 : }
1029 0 : else if ( rPos.Y() >= maItemListRect.Bottom()-nScrollOffset )
1030 : {
1031 0 : if ( mnFirstLine < static_cast<sal_uInt16>(mnLines-mnVisLines) )
1032 : {
1033 0 : ++mnFirstLine;
1034 0 : bScroll = true;
1035 : }
1036 : }
1037 :
1038 0 : if ( !bScroll )
1039 0 : return false;
1040 :
1041 0 : mbFormat = true;
1042 0 : ImplDraw();
1043 0 : return true;
1044 : }
1045 :
1046 :
1047 :
1048 0 : size_t ValueSet::ImplGetItem( const Point& rPos, bool bMove ) const
1049 : {
1050 0 : if ( !mbHasVisibleItems )
1051 : {
1052 0 : return VALUESET_ITEM_NOTFOUND;
1053 : }
1054 :
1055 0 : if ( mpNoneItem && maNoneItemRect.IsInside( rPos ) )
1056 : {
1057 0 : return VALUESET_ITEM_NONEITEM;
1058 : }
1059 :
1060 0 : if ( maItemListRect.IsInside( rPos ) )
1061 : {
1062 0 : const int xc = rPos.X()-maItemListRect.Left();
1063 0 : const int yc = rPos.Y()-maItemListRect.Top();
1064 : // The point is inside the area of item list,
1065 : // let's find the containing item.
1066 0 : const int col = xc/(mnItemWidth+mnSpacing);
1067 0 : const int x = xc%(mnItemWidth+mnSpacing);
1068 0 : const int row = yc/(mnItemHeight+mnSpacing);
1069 0 : const int y = yc%(mnItemHeight+mnSpacing);
1070 :
1071 0 : if (x<mnItemWidth && y<mnItemHeight)
1072 : {
1073 : // the point is inside item rect and not inside spacing
1074 0 : const size_t item = (mnFirstLine+row)*mnCols+col;
1075 0 : if (item < mItemList.size())
1076 : {
1077 0 : return item;
1078 : }
1079 : }
1080 :
1081 : // return the previously selected item if spacing is set and
1082 : // the mouse hasn't left the window yet
1083 0 : if ( bMove && mnSpacing && mnHighItemId )
1084 : {
1085 0 : return GetItemPos( mnHighItemId );
1086 : }
1087 : }
1088 :
1089 0 : return VALUESET_ITEM_NOTFOUND;
1090 : }
1091 :
1092 :
1093 :
1094 0 : ValueSetItem* ValueSet::ImplGetItem( size_t nPos )
1095 : {
1096 0 : if ( nPos == VALUESET_ITEM_NONEITEM )
1097 0 : return mpNoneItem;
1098 : else
1099 0 : return ( nPos < mItemList.size() ) ? mItemList[nPos] : NULL;
1100 : }
1101 :
1102 :
1103 :
1104 0 : ValueSetItem* ValueSet::ImplGetFirstItem()
1105 : {
1106 0 : return mItemList.size() ? mItemList[0] : NULL;
1107 : }
1108 :
1109 :
1110 :
1111 0 : sal_uInt16 ValueSet::ImplGetVisibleItemCount() const
1112 : {
1113 0 : sal_uInt16 nRet = 0;
1114 0 : const size_t nItemCount = mItemList.size();
1115 :
1116 0 : for ( size_t n = 0; n < nItemCount; ++n )
1117 : {
1118 0 : if ( mItemList[n]->mbVisible )
1119 0 : ++nRet;
1120 : }
1121 :
1122 0 : return nRet;
1123 : }
1124 :
1125 :
1126 :
1127 0 : void ValueSet::ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
1128 : {
1129 0 : ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( false ) );
1130 :
1131 0 : if( pAcc )
1132 0 : pAcc->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
1133 0 : }
1134 :
1135 :
1136 :
1137 0 : bool ValueSet::ImplHasAccessibleListeners()
1138 : {
1139 0 : ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( false ) );
1140 0 : return( pAcc && pAcc->HasAccessibleListeners() );
1141 : }
1142 :
1143 :
1144 :
1145 0 : IMPL_LINK( ValueSet,ImplScrollHdl, ScrollBar*, pScrollBar )
1146 : {
1147 0 : sal_uInt16 nNewFirstLine = (sal_uInt16)pScrollBar->GetThumbPos();
1148 0 : if ( nNewFirstLine != mnFirstLine )
1149 : {
1150 0 : mnFirstLine = nNewFirstLine;
1151 0 : mbFormat = true;
1152 0 : ImplDraw();
1153 : }
1154 0 : return 0;
1155 : }
1156 :
1157 :
1158 :
1159 0 : IMPL_LINK_NOARG(ValueSet, ImplTimerHdl)
1160 : {
1161 0 : ImplTracking( GetPointerPosPixel(), true );
1162 0 : return 0;
1163 : }
1164 :
1165 :
1166 :
1167 0 : void ValueSet::ImplTracking( const Point& rPos, bool bRepeat )
1168 : {
1169 0 : if ( bRepeat || mbSelection )
1170 : {
1171 0 : if ( ImplScroll( rPos ) )
1172 : {
1173 0 : if ( mbSelection )
1174 : {
1175 0 : maTimer.SetTimeoutHdl( LINK( this, ValueSet, ImplTimerHdl ) );
1176 0 : maTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
1177 0 : maTimer.Start();
1178 : }
1179 : }
1180 : }
1181 :
1182 0 : ValueSetItem* pItem = ImplGetItem( ImplGetItem( rPos ) );
1183 0 : if ( pItem )
1184 : {
1185 0 : if( GetStyle() & WB_MENUSTYLEVALUESET )
1186 0 : mbHighlight = true;
1187 :
1188 0 : ImplHighlightItem( pItem->mnId );
1189 : }
1190 : else
1191 : {
1192 0 : if( GetStyle() & WB_MENUSTYLEVALUESET )
1193 0 : mbHighlight = true;
1194 :
1195 0 : ImplHighlightItem( mnSelItemId, false );
1196 : }
1197 0 : }
1198 :
1199 :
1200 :
1201 0 : void ValueSet::ImplEndTracking( const Point& rPos, bool bCancel )
1202 : {
1203 : ValueSetItem* pItem;
1204 :
1205 : // restore the old status in case of termination
1206 0 : if ( bCancel )
1207 0 : pItem = NULL;
1208 : else
1209 0 : pItem = ImplGetItem( ImplGetItem( rPos ) );
1210 :
1211 0 : if ( pItem )
1212 : {
1213 0 : SelectItem( pItem->mnId );
1214 0 : if ( !mbSelection && !(GetStyle() & WB_NOPOINTERFOCUS) )
1215 0 : GrabFocus();
1216 0 : mbHighlight = false;
1217 0 : mbSelection = false;
1218 0 : Select();
1219 : }
1220 : else
1221 : {
1222 0 : ImplHighlightItem( mnSelItemId, false );
1223 0 : mbHighlight = false;
1224 0 : mbSelection = false;
1225 : }
1226 0 : }
1227 :
1228 :
1229 :
1230 0 : void ValueSet::MouseButtonDown( const MouseEvent& rMEvt )
1231 : {
1232 0 : if ( rMEvt.IsLeft() )
1233 : {
1234 0 : ValueSetItem* pItem = ImplGetItem( ImplGetItem( rMEvt.GetPosPixel() ) );
1235 0 : if ( mbSelection )
1236 : {
1237 0 : mbHighlight = true;
1238 0 : if ( pItem )
1239 : {
1240 0 : mnHighItemId = mnSelItemId;
1241 0 : ImplHighlightItem( pItem->mnId );
1242 : }
1243 :
1244 0 : return;
1245 : }
1246 : else
1247 : {
1248 0 : if ( pItem && !rMEvt.IsMod2() )
1249 : {
1250 0 : if ( rMEvt.GetClicks() == 1 )
1251 : {
1252 0 : mbHighlight = true;
1253 0 : mnHighItemId = mnSelItemId;
1254 0 : ImplHighlightItem( pItem->mnId );
1255 0 : StartTracking( STARTTRACK_SCROLLREPEAT );
1256 : }
1257 0 : else if ( rMEvt.GetClicks() == 2 )
1258 0 : DoubleClick();
1259 :
1260 0 : return;
1261 : }
1262 : }
1263 : }
1264 :
1265 0 : Control::MouseButtonDown( rMEvt );
1266 : }
1267 :
1268 :
1269 :
1270 0 : void ValueSet::MouseButtonUp( const MouseEvent& rMEvt )
1271 : {
1272 : // because of SelectionMode
1273 0 : if ( rMEvt.IsLeft() && mbSelection )
1274 0 : ImplEndTracking( rMEvt.GetPosPixel(), false );
1275 : else
1276 0 : Control::MouseButtonUp( rMEvt );
1277 0 : }
1278 :
1279 :
1280 :
1281 0 : void ValueSet::MouseMove( const MouseEvent& rMEvt )
1282 : {
1283 : // because of SelectionMode
1284 0 : if ( mbSelection || (GetStyle() & WB_MENUSTYLEVALUESET) )
1285 0 : ImplTracking( rMEvt.GetPosPixel(), false );
1286 0 : Control::MouseMove( rMEvt );
1287 0 : }
1288 :
1289 :
1290 :
1291 0 : void ValueSet::Tracking( const TrackingEvent& rTEvt )
1292 : {
1293 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
1294 :
1295 0 : if ( rTEvt.IsTrackingEnded() )
1296 0 : ImplEndTracking( aMousePos, rTEvt.IsTrackingCanceled() );
1297 : else
1298 0 : ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
1299 0 : }
1300 :
1301 :
1302 :
1303 0 : void ValueSet::KeyInput( const KeyEvent& rKEvt )
1304 : {
1305 0 : size_t nLastItem = mItemList.size();
1306 :
1307 0 : if ( !nLastItem || !ImplGetFirstItem() )
1308 : {
1309 0 : Control::KeyInput( rKEvt );
1310 0 : return;
1311 : }
1312 :
1313 0 : if ( mbFormat )
1314 0 : Format();
1315 :
1316 0 : --nLastItem;
1317 0 : const size_t nCurPos = mnSelItemId ? GetItemPos( mnSelItemId )
1318 0 : : mpNoneItem ? VALUESET_ITEM_NONEITEM : 0;
1319 0 : size_t nItemPos = VALUESET_ITEM_NOTFOUND;
1320 0 : size_t nVStep = mnCols;
1321 :
1322 0 : switch ( rKEvt.GetKeyCode().GetCode() )
1323 : {
1324 : case KEY_HOME:
1325 0 : nItemPos = mpNoneItem ? VALUESET_ITEM_NONEITEM : 0;
1326 0 : break;
1327 :
1328 : case KEY_END:
1329 0 : nItemPos = nLastItem;
1330 0 : break;
1331 :
1332 : case KEY_LEFT:
1333 0 : if (nCurPos != VALUESET_ITEM_NONEITEM)
1334 : {
1335 0 : if (nCurPos)
1336 : {
1337 0 : nItemPos = nCurPos-1;
1338 : }
1339 0 : else if (mpNoneItem)
1340 : {
1341 0 : nItemPos = VALUESET_ITEM_NONEITEM;
1342 : }
1343 : }
1344 0 : break;
1345 :
1346 : case KEY_RIGHT:
1347 0 : if (nCurPos < nLastItem)
1348 : {
1349 0 : if (nCurPos == VALUESET_ITEM_NONEITEM)
1350 : {
1351 0 : nItemPos = 0;
1352 : }
1353 : else
1354 : {
1355 0 : nItemPos = nCurPos+1;
1356 : }
1357 : }
1358 0 : break;
1359 :
1360 : case KEY_PAGEUP:
1361 0 : if (rKEvt.GetKeyCode().IsShift() || rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
1362 : {
1363 0 : Control::KeyInput( rKEvt );
1364 0 : return;
1365 : }
1366 0 : nVStep *= mnVisLines;
1367 : // intentional fall-through
1368 : case KEY_UP:
1369 0 : if (nCurPos != VALUESET_ITEM_NONEITEM)
1370 : {
1371 0 : if (nCurPos == nLastItem)
1372 : {
1373 0 : const size_t nCol = nLastItem % mnCols;
1374 0 : if (nCol < mnCurCol)
1375 : {
1376 : // Move to previous row/page, keeping the old column
1377 0 : nVStep -= mnCurCol - nCol;
1378 : }
1379 : }
1380 0 : if (nCurPos >= nVStep)
1381 : {
1382 : // Go up of a whole page
1383 0 : nItemPos = nCurPos-nVStep;
1384 : }
1385 0 : else if (mpNoneItem)
1386 : {
1387 0 : nItemPos = VALUESET_ITEM_NONEITEM;
1388 : }
1389 0 : else if (nCurPos > mnCols)
1390 : {
1391 : // Go to same column in first row
1392 0 : nItemPos = nCurPos % mnCols;
1393 : }
1394 : }
1395 0 : break;
1396 :
1397 : case KEY_PAGEDOWN:
1398 0 : if (rKEvt.GetKeyCode().IsShift() || rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
1399 : {
1400 0 : Control::KeyInput( rKEvt );
1401 0 : return;
1402 : }
1403 0 : nVStep *= mnVisLines;
1404 : // intentional fall-through
1405 : case KEY_DOWN:
1406 0 : if (nCurPos != nLastItem)
1407 : {
1408 0 : if (nCurPos == VALUESET_ITEM_NONEITEM)
1409 : {
1410 0 : nItemPos = nVStep-mnCols+mnCurCol;
1411 : }
1412 : else
1413 : {
1414 0 : nItemPos = nCurPos+nVStep;
1415 : }
1416 0 : if (nItemPos > nLastItem)
1417 : {
1418 0 : nItemPos = nLastItem;
1419 : }
1420 : }
1421 0 : break;
1422 :
1423 : case KEY_RETURN:
1424 0 : if (GetStyle() & WB_NO_DIRECTSELECT)
1425 : {
1426 0 : Select();
1427 0 : break;
1428 : }
1429 : // intentional fall-through
1430 : default:
1431 0 : Control::KeyInput( rKEvt );
1432 0 : return;
1433 : }
1434 :
1435 : // This point is reached only if key travelling was used,
1436 : // in which case selection mode should be switched off
1437 0 : EndSelection();
1438 :
1439 0 : if ( nItemPos != VALUESET_ITEM_NOTFOUND )
1440 : {
1441 0 : if ( nItemPos!=VALUESET_ITEM_NONEITEM && nItemPos<nLastItem )
1442 : {
1443 : // update current column only in case of a new position
1444 : // which is also not a "specially" handled one.
1445 0 : mnCurCol = nItemPos % mnCols;
1446 : }
1447 0 : const sal_uInt16 nItemId = (nItemPos != VALUESET_ITEM_NONEITEM) ? GetItemId( nItemPos ) : 0;
1448 0 : if ( nItemId != mnSelItemId )
1449 : {
1450 0 : SelectItem( nItemId );
1451 0 : if (!(GetStyle() & WB_NO_DIRECTSELECT))
1452 : {
1453 : // select only if WB_NO_DIRECTSELECT is not set
1454 0 : Select();
1455 : }
1456 : }
1457 : }
1458 : }
1459 :
1460 :
1461 :
1462 0 : void ValueSet::Command( const CommandEvent& rCEvt )
1463 : {
1464 0 : if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
1465 0 : (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
1466 0 : (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
1467 : {
1468 0 : if ( HandleScrollCommand( rCEvt, NULL, mpScrBar ) )
1469 0 : return;
1470 : }
1471 :
1472 0 : Control::Command( rCEvt );
1473 : }
1474 :
1475 :
1476 :
1477 0 : void ValueSet::Paint( const Rectangle& )
1478 : {
1479 0 : if ( GetStyle() & WB_FLATVALUESET )
1480 : {
1481 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1482 0 : SetLineColor();
1483 0 : SetFillColor( rStyleSettings.GetFaceColor() );
1484 0 : long nOffY = maVirDev.GetOutputSizePixel().Height();
1485 0 : Size aWinSize = GetOutputSizePixel();
1486 0 : DrawRect( Rectangle( Point( 0, nOffY ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
1487 : }
1488 :
1489 0 : ImplDraw();
1490 0 : }
1491 :
1492 :
1493 :
1494 0 : void ValueSet::GetFocus()
1495 : {
1496 : OSL_TRACE ("value set getting focus");
1497 0 : ImplDrawSelect();
1498 0 : Control::GetFocus();
1499 :
1500 : // Tell the accessible object that we got the focus.
1501 0 : ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( false ) );
1502 0 : if( pAcc )
1503 0 : pAcc->GetFocus();
1504 0 : }
1505 :
1506 :
1507 :
1508 0 : void ValueSet::LoseFocus()
1509 : {
1510 : OSL_TRACE ("value set losing focus");
1511 0 : if ( mbNoSelection && mnSelItemId )
1512 0 : ImplHideSelect( mnSelItemId );
1513 : else
1514 0 : HideFocus();
1515 0 : Control::LoseFocus();
1516 :
1517 : // Tell the accessible object that we lost the focus.
1518 0 : ValueSetAcc* pAcc = ValueSetAcc::getImplementation( GetAccessible( false ) );
1519 0 : if( pAcc )
1520 0 : pAcc->LoseFocus();
1521 0 : }
1522 :
1523 :
1524 :
1525 0 : void ValueSet::Resize()
1526 : {
1527 0 : mbFormat = true;
1528 0 : if ( IsReallyVisible() && IsUpdateMode() )
1529 0 : Invalidate();
1530 0 : Control::Resize();
1531 0 : }
1532 :
1533 :
1534 :
1535 0 : void ValueSet::RequestHelp( const HelpEvent& rHEvt )
1536 : {
1537 0 : if ( (rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON)) == HELPMODE_QUICK )
1538 : {
1539 0 : Point aPos = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
1540 0 : size_t nItemPos = ImplGetItem( aPos );
1541 0 : if ( nItemPos != VALUESET_ITEM_NOTFOUND )
1542 : {
1543 0 : Rectangle aItemRect = ImplGetItemRect( nItemPos );
1544 0 : Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1545 0 : aItemRect.Left() = aPt.X();
1546 0 : aItemRect.Top() = aPt.Y();
1547 0 : aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1548 0 : aItemRect.Right() = aPt.X();
1549 0 : aItemRect.Bottom() = aPt.Y();
1550 0 : Help::ShowQuickHelp( this, aItemRect, GetItemText( ImplGetItem( nItemPos )->mnId ) );
1551 0 : return;
1552 : }
1553 : }
1554 :
1555 0 : Control::RequestHelp( rHEvt );
1556 : }
1557 :
1558 :
1559 :
1560 0 : void ValueSet::StateChanged( StateChangedType nType )
1561 : {
1562 0 : Control::StateChanged( nType );
1563 :
1564 0 : if ( nType == STATE_CHANGE_INITSHOW )
1565 : {
1566 0 : if ( mbFormat )
1567 0 : Format();
1568 : }
1569 0 : else if ( nType == STATE_CHANGE_UPDATEMODE )
1570 : {
1571 0 : if ( IsReallyVisible() && IsUpdateMode() )
1572 0 : Invalidate();
1573 : }
1574 0 : else if ( nType == STATE_CHANGE_TEXT )
1575 : {
1576 0 : if ( mpNoneItem && !mbFormat && IsReallyVisible() && IsUpdateMode() )
1577 : {
1578 0 : ImplFormatItem( mpNoneItem, maNoneItemRect );
1579 0 : Invalidate( maNoneItemRect );
1580 : }
1581 : }
1582 0 : else if ( (nType == STATE_CHANGE_ZOOM) ||
1583 : (nType == STATE_CHANGE_CONTROLFONT) )
1584 : {
1585 0 : ImplInitSettings( true, false, false );
1586 0 : Invalidate();
1587 : }
1588 0 : else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1589 : {
1590 0 : ImplInitSettings( false, true, false );
1591 0 : Invalidate();
1592 : }
1593 0 : else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1594 : {
1595 0 : ImplInitSettings( false, false, true );
1596 0 : Invalidate();
1597 : }
1598 0 : else if ( (nType == STATE_CHANGE_STYLE) || (nType == STATE_CHANGE_ENABLE) )
1599 : {
1600 0 : mbFormat = true;
1601 0 : ImplInitSettings( false, false, true );
1602 0 : Invalidate();
1603 : }
1604 0 : }
1605 :
1606 :
1607 :
1608 0 : void ValueSet::DataChanged( const DataChangedEvent& rDCEvt )
1609 : {
1610 0 : Control::DataChanged( rDCEvt );
1611 :
1612 0 : if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1613 0 : (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
1614 0 : (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1615 0 : ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1616 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1617 : {
1618 0 : mbFormat = true;
1619 0 : ImplInitSettings( true, true, true );
1620 0 : Invalidate();
1621 : }
1622 0 : }
1623 :
1624 :
1625 :
1626 0 : void ValueSet::Select()
1627 : {
1628 0 : maSelectHdl.Call( this );
1629 0 : }
1630 :
1631 :
1632 :
1633 0 : void ValueSet::DoubleClick()
1634 : {
1635 0 : maDoubleClickHdl.Call( this );
1636 0 : }
1637 :
1638 :
1639 :
1640 0 : void ValueSet::UserDraw( const UserDrawEvent& )
1641 : {
1642 0 : }
1643 :
1644 :
1645 :
1646 0 : void ValueSet::InsertItem( sal_uInt16 nItemId, const Image& rImage, size_t nPos )
1647 : {
1648 0 : ValueSetItem* pItem = new ValueSetItem( *this );
1649 0 : pItem->mnId = nItemId;
1650 0 : pItem->meType = VALUESETITEM_IMAGE;
1651 0 : pItem->maImage = rImage;
1652 0 : ImplInsertItem( pItem, nPos );
1653 0 : }
1654 :
1655 :
1656 :
1657 0 : void ValueSet::InsertItem( sal_uInt16 nItemId, const Color& rColor, size_t nPos )
1658 : {
1659 0 : ValueSetItem* pItem = new ValueSetItem( *this );
1660 0 : pItem->mnId = nItemId;
1661 0 : pItem->meType = VALUESETITEM_COLOR;
1662 0 : pItem->maColor = rColor;
1663 0 : ImplInsertItem( pItem, nPos );
1664 0 : }
1665 :
1666 :
1667 :
1668 0 : void ValueSet::InsertItem( sal_uInt16 nItemId, const Image& rImage,
1669 : const OUString& rText, size_t nPos )
1670 : {
1671 0 : ValueSetItem* pItem = new ValueSetItem( *this );
1672 0 : pItem->mnId = nItemId;
1673 0 : pItem->meType = VALUESETITEM_IMAGE;
1674 0 : pItem->maImage = rImage;
1675 0 : pItem->maText = rText;
1676 0 : ImplInsertItem( pItem, nPos );
1677 0 : }
1678 :
1679 :
1680 :
1681 0 : void ValueSet::InsertItem( sal_uInt16 nItemId, const Color& rColor,
1682 : const OUString& rText, size_t nPos )
1683 : {
1684 0 : ValueSetItem* pItem = new ValueSetItem( *this );
1685 0 : pItem->mnId = nItemId;
1686 0 : pItem->meType = VALUESETITEM_COLOR;
1687 0 : pItem->maColor = rColor;
1688 0 : pItem->maText = rText;
1689 0 : ImplInsertItem( pItem, nPos );
1690 0 : }
1691 :
1692 :
1693 :
1694 0 : void ValueSet::InsertItem( sal_uInt16 nItemId, size_t nPos )
1695 : {
1696 0 : ValueSetItem* pItem = new ValueSetItem( *this );
1697 0 : pItem->mnId = nItemId;
1698 0 : pItem->meType = VALUESETITEM_USERDRAW;
1699 0 : ImplInsertItem( pItem, nPos );
1700 0 : }
1701 :
1702 :
1703 :
1704 0 : void ValueSet::ImplInsertItem( ValueSetItem *const pItem, const size_t nPos )
1705 : {
1706 : DBG_ASSERT( pItem->mnId, "ValueSet::InsertItem(): ItemId == 0" );
1707 : DBG_ASSERT( GetItemPos( pItem->mnId ) == VALUESET_ITEM_NOTFOUND,
1708 : "ValueSet::InsertItem(): ItemId already exists" );
1709 :
1710 0 : if ( nPos < mItemList.size() ) {
1711 0 : ValueItemList::iterator it = mItemList.begin();
1712 0 : ::std::advance( it, nPos );
1713 0 : mItemList.insert( it, pItem );
1714 : } else {
1715 0 : mItemList.push_back( pItem );
1716 : }
1717 :
1718 0 : queue_resize();
1719 :
1720 0 : mbFormat = true;
1721 0 : if ( IsReallyVisible() && IsUpdateMode() )
1722 0 : Invalidate();
1723 0 : }
1724 :
1725 :
1726 :
1727 0 : Rectangle ValueSet::ImplGetItemRect( size_t nPos ) const
1728 : {
1729 0 : const size_t nVisibleBegin = static_cast<size_t>(mnFirstLine)*mnCols;
1730 0 : const size_t nVisibleEnd = nVisibleBegin + static_cast<size_t>(mnVisLines)*mnCols;
1731 :
1732 : // Check if the item is inside the range of the displayed ones,
1733 : // taking into account that last row could be incomplete
1734 0 : if ( nPos<nVisibleBegin || nPos>=nVisibleEnd || nPos>=mItemList.size() )
1735 0 : return Rectangle();
1736 :
1737 0 : nPos -= nVisibleBegin;
1738 :
1739 0 : const size_t row = nPos/mnCols;
1740 0 : const size_t col = nPos%mnCols;
1741 0 : const long x = maItemListRect.Left()+col*(mnItemWidth+mnSpacing);
1742 0 : const long y = maItemListRect.Top()+row*(mnItemHeight+mnSpacing);
1743 :
1744 0 : return Rectangle( Point(x, y), Size(mnItemWidth, mnItemHeight) );
1745 : }
1746 :
1747 :
1748 :
1749 0 : void ValueSet::RemoveItem( sal_uInt16 nItemId )
1750 : {
1751 0 : size_t nPos = GetItemPos( nItemId );
1752 :
1753 0 : if ( nPos == VALUESET_ITEM_NOTFOUND )
1754 0 : return;
1755 :
1756 0 : if ( nPos < mItemList.size() ) {
1757 0 : ValueItemList::iterator it = mItemList.begin();
1758 0 : ::std::advance( it, nPos );
1759 0 : delete *it;
1760 0 : mItemList.erase( it );
1761 : }
1762 :
1763 : // reset variables
1764 0 : if ( (mnHighItemId == nItemId) || (mnSelItemId == nItemId) )
1765 : {
1766 0 : mnCurCol = 0;
1767 0 : mnHighItemId = 0;
1768 0 : mnSelItemId = 0;
1769 0 : mbNoSelection = true;
1770 : }
1771 :
1772 0 : queue_resize();
1773 :
1774 0 : mbFormat = true;
1775 0 : if ( IsReallyVisible() && IsUpdateMode() )
1776 0 : Invalidate();
1777 : }
1778 :
1779 :
1780 :
1781 0 : void ValueSet::Clear()
1782 : {
1783 0 : ImplDeleteItems();
1784 :
1785 : // reset variables
1786 0 : mnFirstLine = 0;
1787 0 : mnCurCol = 0;
1788 0 : mnHighItemId = 0;
1789 0 : mnSelItemId = 0;
1790 0 : mbNoSelection = true;
1791 :
1792 0 : mbFormat = true;
1793 0 : if ( IsReallyVisible() && IsUpdateMode() )
1794 0 : Invalidate();
1795 0 : }
1796 :
1797 :
1798 :
1799 0 : size_t ValueSet::GetItemCount() const
1800 : {
1801 0 : return mItemList.size();
1802 : }
1803 :
1804 :
1805 :
1806 0 : size_t ValueSet::GetItemPos( sal_uInt16 nItemId ) const
1807 : {
1808 0 : for ( size_t i = 0, n = mItemList.size(); i < n; ++i ) {
1809 0 : if ( mItemList[i]->mnId == nItemId ) {
1810 0 : return i;
1811 : }
1812 : }
1813 0 : return VALUESET_ITEM_NOTFOUND;
1814 : }
1815 :
1816 :
1817 :
1818 0 : sal_uInt16 ValueSet::GetItemId( size_t nPos ) const
1819 : {
1820 0 : return ( nPos < mItemList.size() ) ? mItemList[nPos]->mnId : 0 ;
1821 : }
1822 :
1823 :
1824 :
1825 0 : sal_uInt16 ValueSet::GetItemId( const Point& rPos ) const
1826 : {
1827 0 : size_t nItemPos = ImplGetItem( rPos );
1828 0 : if ( nItemPos != VALUESET_ITEM_NOTFOUND )
1829 0 : return GetItemId( nItemPos );
1830 :
1831 0 : return 0;
1832 : }
1833 :
1834 :
1835 :
1836 0 : Rectangle ValueSet::GetItemRect( sal_uInt16 nItemId ) const
1837 : {
1838 0 : const size_t nPos = GetItemPos( nItemId );
1839 :
1840 0 : if ( nPos!=VALUESET_ITEM_NOTFOUND && mItemList[nPos]->mbVisible )
1841 0 : return ImplGetItemRect( nPos );
1842 :
1843 0 : return Rectangle();
1844 : }
1845 :
1846 :
1847 :
1848 0 : void ValueSet::EnableFullItemMode( bool bFullMode )
1849 : {
1850 0 : mbFullMode = bFullMode;
1851 0 : }
1852 :
1853 :
1854 :
1855 0 : void ValueSet::SetColCount( sal_uInt16 nNewCols )
1856 : {
1857 0 : if ( mnUserCols != nNewCols )
1858 : {
1859 0 : mnUserCols = nNewCols;
1860 0 : mbFormat = true;
1861 0 : queue_resize();
1862 0 : if ( IsReallyVisible() && IsUpdateMode() )
1863 0 : Invalidate();
1864 : }
1865 0 : }
1866 :
1867 :
1868 :
1869 0 : void ValueSet::SetLineCount( sal_uInt16 nNewLines )
1870 : {
1871 0 : if ( mnUserVisLines != nNewLines )
1872 : {
1873 0 : mnUserVisLines = nNewLines;
1874 0 : mbFormat = true;
1875 0 : queue_resize();
1876 0 : if ( IsReallyVisible() && IsUpdateMode() )
1877 0 : Invalidate();
1878 : }
1879 0 : }
1880 :
1881 :
1882 :
1883 0 : void ValueSet::SetItemWidth( long nNewItemWidth )
1884 : {
1885 0 : if ( mnUserItemWidth != nNewItemWidth )
1886 : {
1887 0 : mnUserItemWidth = nNewItemWidth;
1888 0 : mbFormat = true;
1889 0 : queue_resize();
1890 0 : if ( IsReallyVisible() && IsUpdateMode() )
1891 0 : Invalidate();
1892 : }
1893 0 : }
1894 :
1895 : //method to set accessible when the style is user draw.
1896 0 : void ValueSet::InsertItem( sal_uInt16 nItemId, const OUString& rText, size_t nPos )
1897 : {
1898 : DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
1899 : DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
1900 : "ValueSet::InsertItem(): ItemId already exists" );
1901 0 : ValueSetItem* pItem = new ValueSetItem( *this );
1902 0 : pItem->mnId = nItemId;
1903 0 : pItem->meType = VALUESETITEM_USERDRAW;
1904 0 : pItem->maText = rText;
1905 0 : ImplInsertItem( pItem, nPos );
1906 0 : }
1907 :
1908 :
1909 :
1910 0 : void ValueSet::SetItemHeight( long nNewItemHeight )
1911 : {
1912 0 : if ( mnUserItemHeight != nNewItemHeight )
1913 : {
1914 0 : mnUserItemHeight = nNewItemHeight;
1915 0 : mbFormat = true;
1916 0 : queue_resize();
1917 0 : if ( IsReallyVisible() && IsUpdateMode() )
1918 0 : Invalidate();
1919 : }
1920 0 : }
1921 :
1922 :
1923 :
1924 0 : void ValueSet::SelectItem( sal_uInt16 nItemId )
1925 : {
1926 0 : size_t nItemPos = 0;
1927 :
1928 0 : if ( nItemId )
1929 : {
1930 0 : nItemPos = GetItemPos( nItemId );
1931 0 : if ( nItemPos == VALUESET_ITEM_NOTFOUND )
1932 0 : return;
1933 : }
1934 :
1935 0 : if ( (mnSelItemId != nItemId) || mbNoSelection )
1936 : {
1937 0 : sal_uInt16 nOldItem = mnSelItemId ? mnSelItemId : 1;
1938 0 : mnSelItemId = nItemId;
1939 0 : mbNoSelection = false;
1940 :
1941 0 : bool bNewOut = !mbFormat && IsReallyVisible() && IsUpdateMode();
1942 0 : bool bNewLine = false;
1943 :
1944 : // if necessary scroll to the visible area
1945 0 : if ( mbScroll && nItemId )
1946 : {
1947 0 : sal_uInt16 nNewLine = (sal_uInt16)(nItemPos / mnCols);
1948 0 : if ( nNewLine < mnFirstLine )
1949 : {
1950 0 : mnFirstLine = nNewLine;
1951 0 : bNewLine = true;
1952 : }
1953 0 : else if ( nNewLine > (sal_uInt16)(mnFirstLine+mnVisLines-1) )
1954 : {
1955 0 : mnFirstLine = (sal_uInt16)(nNewLine-mnVisLines+1);
1956 0 : bNewLine = true;
1957 : }
1958 : }
1959 :
1960 0 : if ( bNewOut )
1961 : {
1962 0 : if ( bNewLine )
1963 : {
1964 : // redraw everything if the visible area has changed
1965 0 : mbFormat = true;
1966 0 : ImplDraw();
1967 : }
1968 : else
1969 : {
1970 : // remove old selection and draw the new one
1971 0 : ImplHideSelect( nOldItem );
1972 0 : ImplDrawSelect();
1973 : }
1974 : }
1975 :
1976 0 : if( ImplHasAccessibleListeners() )
1977 : {
1978 : // focus event (deselect)
1979 0 : if( nOldItem )
1980 : {
1981 0 : const size_t nPos = GetItemPos( nItemId );
1982 :
1983 0 : if( nPos != VALUESET_ITEM_NOTFOUND )
1984 : {
1985 : ValueItemAcc* pItemAcc = ValueItemAcc::getImplementation(
1986 0 : mItemList[nPos]->GetAccessible( mbIsTransientChildrenDisabled ) );
1987 :
1988 0 : if( pItemAcc )
1989 : {
1990 0 : ::com::sun::star::uno::Any aOldAny, aNewAny;
1991 0 : if( !mbIsTransientChildrenDisabled )
1992 : {
1993 0 : aOldAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
1994 0 : static_cast< ::cppu::OWeakObject* >( pItemAcc ));
1995 0 : ImplFireAccessibleEvent (::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
1996 : }
1997 : else
1998 : {
1999 0 : aOldAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
2000 0 : pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
2001 0 : }
2002 : }
2003 : }
2004 : }
2005 :
2006 : // focus event (select)
2007 0 : const size_t nPos = GetItemPos( mnSelItemId );
2008 :
2009 : ValueSetItem* pItem;
2010 0 : if( nPos != VALUESET_ITEM_NOTFOUND )
2011 0 : pItem = mItemList[nPos];
2012 : else
2013 0 : pItem = mpNoneItem;
2014 :
2015 0 : ValueItemAcc* pItemAcc = NULL;
2016 0 : if (pItem != NULL)
2017 0 : pItemAcc = ValueItemAcc::getImplementation( pItem->GetAccessible( mbIsTransientChildrenDisabled ) );
2018 :
2019 0 : if( pItemAcc )
2020 : {
2021 0 : ::com::sun::star::uno::Any aOldAny, aNewAny;
2022 0 : if( !mbIsTransientChildrenDisabled )
2023 : {
2024 0 : aNewAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
2025 0 : static_cast< ::cppu::OWeakObject* >( pItemAcc ));
2026 0 : ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
2027 : }
2028 : else
2029 : {
2030 0 : aNewAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
2031 0 : pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
2032 0 : }
2033 : }
2034 :
2035 : // selection event
2036 0 : ::com::sun::star::uno::Any aOldAny, aNewAny;
2037 0 : ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny );
2038 : }
2039 0 : maHighlightHdl.Call(this);
2040 : }
2041 : }
2042 :
2043 :
2044 :
2045 0 : void ValueSet::SetNoSelection()
2046 : {
2047 0 : mbNoSelection = true;
2048 0 : mbHighlight = false;
2049 0 : mbSelection = false;
2050 :
2051 0 : if ( IsReallyVisible() && IsUpdateMode() )
2052 0 : ImplDraw();
2053 0 : }
2054 :
2055 :
2056 :
2057 0 : void ValueSet::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
2058 : {
2059 0 : size_t nPos = GetItemPos( nItemId );
2060 :
2061 0 : if ( nPos == VALUESET_ITEM_NOTFOUND )
2062 0 : return;
2063 :
2064 0 : ValueSetItem* pItem = mItemList[nPos];
2065 0 : pItem->meType = VALUESETITEM_IMAGE;
2066 0 : pItem->maImage = rImage;
2067 :
2068 0 : if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2069 : {
2070 0 : const Rectangle aRect = ImplGetItemRect(nPos);
2071 0 : ImplFormatItem( pItem, aRect );
2072 0 : Invalidate( aRect );
2073 : }
2074 : else
2075 0 : mbFormat = true;
2076 : }
2077 :
2078 :
2079 :
2080 0 : Image ValueSet::GetItemImage( sal_uInt16 nItemId ) const
2081 : {
2082 0 : size_t nPos = GetItemPos( nItemId );
2083 :
2084 0 : if ( nPos != VALUESET_ITEM_NOTFOUND )
2085 0 : return mItemList[nPos]->maImage;
2086 : else
2087 0 : return Image();
2088 : }
2089 :
2090 :
2091 :
2092 0 : void ValueSet::SetItemColor( sal_uInt16 nItemId, const Color& rColor )
2093 : {
2094 0 : size_t nPos = GetItemPos( nItemId );
2095 :
2096 0 : if ( nPos == VALUESET_ITEM_NOTFOUND )
2097 0 : return;
2098 :
2099 0 : ValueSetItem* pItem = mItemList[nPos];
2100 0 : pItem->meType = VALUESETITEM_COLOR;
2101 0 : pItem->maColor = rColor;
2102 :
2103 0 : if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2104 : {
2105 0 : const Rectangle aRect = ImplGetItemRect(nPos);
2106 0 : ImplFormatItem( pItem, aRect );
2107 0 : Invalidate( aRect );
2108 : }
2109 : else
2110 0 : mbFormat = true;
2111 : }
2112 :
2113 :
2114 :
2115 0 : Color ValueSet::GetItemColor( sal_uInt16 nItemId ) const
2116 : {
2117 0 : size_t nPos = GetItemPos( nItemId );
2118 :
2119 0 : if ( nPos != VALUESET_ITEM_NOTFOUND )
2120 0 : return mItemList[nPos]->maColor;
2121 : else
2122 0 : return Color();
2123 : }
2124 :
2125 :
2126 :
2127 0 : void ValueSet::SetItemData( sal_uInt16 nItemId, void* pData )
2128 : {
2129 0 : size_t nPos = GetItemPos( nItemId );
2130 :
2131 0 : if ( nPos == VALUESET_ITEM_NOTFOUND )
2132 0 : return;
2133 :
2134 0 : ValueSetItem* pItem = mItemList[nPos];
2135 0 : pItem->mpData = pData;
2136 :
2137 0 : if ( pItem->meType == VALUESETITEM_USERDRAW )
2138 : {
2139 0 : if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2140 : {
2141 0 : const Rectangle aRect = ImplGetItemRect(nPos);
2142 0 : ImplFormatItem( pItem, aRect );
2143 0 : Invalidate( aRect );
2144 : }
2145 : else
2146 0 : mbFormat = true;
2147 : }
2148 : }
2149 :
2150 :
2151 :
2152 0 : void* ValueSet::GetItemData( sal_uInt16 nItemId ) const
2153 : {
2154 0 : size_t nPos = GetItemPos( nItemId );
2155 :
2156 0 : if ( nPos != VALUESET_ITEM_NOTFOUND )
2157 0 : return mItemList[nPos]->mpData;
2158 : else
2159 0 : return NULL;
2160 : }
2161 :
2162 :
2163 :
2164 0 : void ValueSet::SetItemText(sal_uInt16 nItemId, const OUString& rText)
2165 : {
2166 0 : size_t nPos = GetItemPos( nItemId );
2167 :
2168 0 : if ( nPos == VALUESET_ITEM_NOTFOUND )
2169 0 : return;
2170 :
2171 :
2172 0 : ValueSetItem* pItem = mItemList[nPos];
2173 :
2174 : // Remember old and new name for accessibility event.
2175 0 : ::com::sun::star::uno::Any aOldName, aNewName;
2176 0 : OUString sString (pItem->maText);
2177 0 : aOldName <<= sString;
2178 0 : sString = rText;
2179 0 : aNewName <<= sString;
2180 :
2181 0 : pItem->maText = rText;
2182 :
2183 0 : if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
2184 : {
2185 0 : sal_uInt16 nTempId = mnSelItemId;
2186 :
2187 0 : if ( mbHighlight )
2188 0 : nTempId = mnHighItemId;
2189 :
2190 0 : if ( nTempId == nItemId )
2191 0 : ImplDrawItemText(pItem->maText);
2192 : }
2193 :
2194 0 : if (ImplHasAccessibleListeners())
2195 : {
2196 : ::com::sun::star::uno::Reference<
2197 : ::com::sun::star::accessibility::XAccessible> xAccessible (
2198 0 : pItem->GetAccessible( mbIsTransientChildrenDisabled ) );
2199 0 : static_cast<ValueItemAcc*>(xAccessible.get())->FireAccessibleEvent (
2200 : ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED,
2201 0 : aOldName, aNewName);
2202 0 : }
2203 : }
2204 :
2205 :
2206 :
2207 0 : OUString ValueSet::GetItemText( sal_uInt16 nItemId ) const
2208 : {
2209 0 : size_t nPos = GetItemPos( nItemId );
2210 :
2211 0 : if ( nPos != VALUESET_ITEM_NOTFOUND )
2212 0 : return mItemList[nPos]->maText;
2213 :
2214 0 : return OUString();
2215 : }
2216 :
2217 :
2218 :
2219 0 : void ValueSet::SetColor( const Color& rColor )
2220 : {
2221 0 : maColor = rColor;
2222 0 : mbFormat = true;
2223 0 : if ( IsReallyVisible() && IsUpdateMode() )
2224 0 : ImplDraw();
2225 0 : }
2226 :
2227 :
2228 :
2229 0 : void ValueSet::SetExtraSpacing( sal_uInt16 nNewSpacing )
2230 : {
2231 0 : if ( GetStyle() & WB_ITEMBORDER )
2232 : {
2233 0 : mnSpacing = nNewSpacing;
2234 :
2235 0 : mbFormat = true;
2236 0 : queue_resize();
2237 0 : if ( IsReallyVisible() && IsUpdateMode() )
2238 0 : Invalidate();
2239 : }
2240 0 : }
2241 :
2242 :
2243 :
2244 0 : void ValueSet::StartSelection()
2245 : {
2246 0 : mbHighlight = true;
2247 0 : mbSelection = true;
2248 0 : mnHighItemId = mnSelItemId;
2249 0 : }
2250 :
2251 :
2252 :
2253 0 : void ValueSet::EndSelection()
2254 : {
2255 0 : if ( mbHighlight )
2256 : {
2257 0 : if ( IsTracking() )
2258 0 : EndTracking( ENDTRACK_CANCEL );
2259 :
2260 0 : ImplHighlightItem( mnSelItemId );
2261 0 : mbHighlight = false;
2262 : }
2263 0 : mbSelection = false;
2264 0 : }
2265 :
2266 :
2267 :
2268 0 : bool ValueSet::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
2269 : {
2270 0 : if ( rCEvt.GetCommand() != COMMAND_STARTDRAG )
2271 0 : return false;
2272 :
2273 : // if necessary abort an existing action
2274 0 : EndSelection();
2275 :
2276 : // Check out if the clicked on page is selected. If this is not the
2277 : // case set it as the current item. We only check mouse actions since
2278 : // drag-and-drop can also be triggered by the keyboard
2279 : sal_uInt16 nSelId;
2280 0 : if ( rCEvt.IsMouseEvent() )
2281 0 : nSelId = GetItemId( rCEvt.GetMousePosPixel() );
2282 : else
2283 0 : nSelId = mnSelItemId;
2284 :
2285 : // don't activate dragging if no item was clicked on
2286 0 : if ( !nSelId )
2287 0 : return false;
2288 :
2289 : // Check out if the page was selected. If not set as current page and
2290 : // call select.
2291 0 : if ( nSelId != mnSelItemId )
2292 : {
2293 0 : SelectItem( nSelId );
2294 0 : Update();
2295 0 : Select();
2296 : }
2297 :
2298 0 : Region aRegion;
2299 :
2300 : // assign region
2301 0 : rRegion = aRegion;
2302 :
2303 0 : return true;
2304 : }
2305 :
2306 :
2307 :
2308 0 : Size ValueSet::CalcWindowSizePixel( const Size& rItemSize, sal_uInt16 nDesireCols,
2309 : sal_uInt16 nDesireLines ) const
2310 : {
2311 0 : size_t nCalcCols = nDesireCols;
2312 0 : size_t nCalcLines = nDesireLines;
2313 :
2314 0 : if ( !nCalcCols )
2315 : {
2316 0 : if ( mnUserCols )
2317 0 : nCalcCols = mnUserCols;
2318 : else
2319 0 : nCalcCols = 1;
2320 : }
2321 :
2322 0 : if ( !nCalcLines )
2323 : {
2324 0 : nCalcLines = mnVisLines;
2325 :
2326 0 : if ( mbFormat )
2327 : {
2328 0 : if ( mnUserVisLines )
2329 0 : nCalcLines = mnUserVisLines;
2330 : else
2331 : {
2332 : // Floor( (M+N-1)/N )==Ceiling( M/N )
2333 0 : nCalcLines = (mItemList.size()+nCalcCols-1) / nCalcCols;
2334 0 : if ( !nCalcLines )
2335 0 : nCalcLines = 1;
2336 : }
2337 : }
2338 : }
2339 :
2340 0 : Size aSize( rItemSize.Width()*nCalcCols, rItemSize.Height()*nCalcLines );
2341 0 : WinBits nStyle = GetStyle();
2342 0 : long nTxtHeight = GetTextHeight();
2343 : long n;
2344 :
2345 0 : if ( nStyle & WB_ITEMBORDER )
2346 : {
2347 0 : if ( nStyle & WB_DOUBLEBORDER )
2348 0 : n = ITEM_OFFSET_DOUBLE;
2349 : else
2350 0 : n = ITEM_OFFSET;
2351 :
2352 0 : aSize.Width() += n*nCalcCols;
2353 0 : aSize.Height() += n*nCalcLines;
2354 : }
2355 : else
2356 0 : n = 0;
2357 :
2358 0 : if ( mnSpacing )
2359 : {
2360 0 : aSize.Width() += mnSpacing*(nCalcCols-1);
2361 0 : aSize.Height() += mnSpacing*(nCalcLines-1);
2362 : }
2363 :
2364 0 : if ( nStyle & WB_NAMEFIELD )
2365 : {
2366 0 : aSize.Height() += nTxtHeight + NAME_OFFSET;
2367 0 : if ( !(nStyle & WB_FLATVALUESET) )
2368 0 : aSize.Height() += NAME_LINE_HEIGHT+NAME_LINE_OFF_Y;
2369 : }
2370 :
2371 0 : if ( nStyle & WB_NONEFIELD )
2372 : {
2373 0 : aSize.Height() += nTxtHeight + n + mnSpacing;
2374 0 : if ( nStyle & WB_RADIOSEL )
2375 0 : aSize.Height() += 8;
2376 : }
2377 :
2378 : // sum possible ScrollBar width
2379 0 : aSize.Width() += GetScrollWidth();
2380 :
2381 0 : return aSize;
2382 : }
2383 :
2384 :
2385 :
2386 0 : Size ValueSet::CalcItemSizePixel( const Size& rItemSize, bool bOut ) const
2387 : {
2388 0 : Size aSize = rItemSize;
2389 :
2390 0 : WinBits nStyle = GetStyle();
2391 0 : if ( nStyle & WB_ITEMBORDER )
2392 : {
2393 : long n;
2394 :
2395 0 : if ( nStyle & WB_DOUBLEBORDER )
2396 0 : n = ITEM_OFFSET_DOUBLE;
2397 : else
2398 0 : n = ITEM_OFFSET;
2399 :
2400 0 : if ( bOut )
2401 : {
2402 0 : aSize.Width() += n;
2403 0 : aSize.Height() += n;
2404 : }
2405 : else
2406 : {
2407 0 : aSize.Width() -= n;
2408 0 : aSize.Height() -= n;
2409 : }
2410 : }
2411 :
2412 0 : return aSize;
2413 : }
2414 :
2415 :
2416 :
2417 0 : long ValueSet::GetScrollWidth() const
2418 : {
2419 0 : if ( GetStyle() & WB_VSCROLL )
2420 : {
2421 0 : ((ValueSet*)this)->ImplInitScrollBar();
2422 0 : return mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
2423 : }
2424 : else
2425 0 : return 0;
2426 : }
2427 :
2428 :
2429 :
2430 0 : void ValueSet::SetHighlightHdl( const Link& rLink )
2431 : {
2432 0 : maHighlightHdl = rLink;
2433 0 : }
2434 :
2435 0 : Size ValueSet::GetOptimalSize() const
2436 : {
2437 0 : Size aLargestItemSize;
2438 :
2439 0 : for (size_t i = 0, n = mItemList.size(); i < n; ++i)
2440 : {
2441 0 : const ValueSetItem* pItem = mItemList[i];
2442 0 : if (!pItem->mbVisible)
2443 0 : continue;
2444 :
2445 0 : if (pItem->meType != VALUESETITEM_IMAGE)
2446 : {
2447 : //handle determining an optimal size for this case
2448 0 : continue;
2449 : }
2450 :
2451 0 : Size aImageSize = pItem->maImage.GetSizePixel();
2452 0 : aLargestItemSize.Width() = std::max(aLargestItemSize.Width(), aImageSize.Width());
2453 0 : aLargestItemSize.Height() = std::max(aLargestItemSize.Height(), aImageSize.Height());
2454 : }
2455 :
2456 0 : return CalcWindowSizePixel(aLargestItemSize);
2457 : }
2458 :
2459 :
2460 :
2461 0 : void ValueSet::SetEdgeBlending(bool bNew)
2462 : {
2463 0 : if(mbEdgeBlending != bNew)
2464 : {
2465 0 : mbEdgeBlending = bNew;
2466 0 : mbFormat = true;
2467 :
2468 0 : if(IsReallyVisible() && IsUpdateMode())
2469 : {
2470 0 : Invalidate();
2471 : }
2472 : }
2473 0 : }
2474 :
2475 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|