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