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