Files
odfstudio/svtools/source/control/valueset.cxx
T
Michael Weghorn dc79823c7e svtools: Drop unused ValueSet::{Format,ImpFormatItem} param
Now after

    Change-Id: I3593630b4758d0547264c0ed63fec7ac111ccfd7
    Author: Michael Weghorn <m.weghorn@posteo.de>
    Date:   Tue Oct 6 17:30:24 2026 +0200

        svtools: Drop ValueSetItemType::ImageAndText and related logic

, the `rRendercontext` param for ValueSet::ImplFormatItem
is unused, so drop it, and also the then unused
corresponding ValueSet::Format param.

Change-Id: Ibc8afabf147974da1ed67ef903abc13c054c4c12
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211911
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2026-10-07 20:26:40 +02:00

1712 lines
47 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <sal/config.h>
#include <o3tl/safeint.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <tools/debug.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/decoview.hxx>
#include <vcl/event.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <vcl/virdev.hxx>
#include <vcl/lineinfo.hxx>
#include <vcl/weld/ScrolledWindow.hxx>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <rtl/ustring.hxx>
#include <sal/log.hxx>
#include "valueimp.hxx"
#include <svtools/valueset.hxx>
#include <uiobject.hxx>
#include <vcl/uitest/logger.hxx>
#include <vcl/uitest/eventdescription.hxx>
using namespace css::uno;
using namespace css::accessibility;
namespace
{
void collectUIInformation( const OUString& aID , const OUString& aParentID , const OUString& aPos )
{
EventDescription aDescription;
aDescription.aID = aID ;
aDescription.aParameters = {{"POS", aPos }};
aDescription.aAction = "SELECT";
aDescription.aKeyWord = "ValueSet";
aDescription.aParent = aParentID;
UITestLogger::getInstance().logEvent(aDescription);
}
enum
{
ITEM_OFFSET = 4,
ITEM_OFFSET_DOUBLE = 6,
NAME_LINE_OFF_X = 2,
NAME_LINE_OFF_Y = 2,
NAME_LINE_HEIGHT = 2,
NAME_OFFSET = 2,
};
}
ValueSet::ValueSet(std::unique_ptr<weld::ScrolledWindow> pScrolledWindow)
: maVirDev( VclPtr<VirtualDevice>::Create(DeviceFormat::WITH_ALPHA))
, mxScrolledWindow(std::move(pScrolledWindow))
, mnHighItemId(0)
, maColor(COL_TRANSPARENT)
, mnStyle(0)
, mbFormat(true)
, mbHighlight(false)
{
mnItemWidth = 0;
mnItemHeight = 0;
mnVisLines = 0;
mnLines = 0;
mnUserItemWidth = 0;
mnUserItemHeight = 0;
mnFirstLine = 0;
mnSelItemId = 0;
mnSavedItemId = -1;
mnCols = 0;
mnCurCol = 0;
mnUserCols = 0;
mnUserVisLines = 0;
mnSpacing = 0;
mnMargin = 0;
mnFrameStyle = DrawFrameStyle::NONE;
mbNoSelection = true;
mbDoubleSel = false;
mbFullMode = true;
mbEdgeBlending = false;
mbHasVisibleItems = false;
if (mxScrolledWindow)
mxScrolledWindow->connect_vadjustment_value_changed(LINK(this, ValueSet, ImplScrollHdl));
}
void ValueSet::SetDrawingArea(weld::DrawingArea* pDrawingArea)
{
CustomWidgetController::SetDrawingArea(pDrawingArea);
// #106446#, #106601# force mirroring of virtual device
maVirDev->EnableRTL(pDrawingArea->get_direction());
}
rtl::Reference<comphelper::OAccessible> ValueSet::CreateAccessible()
{
if (!mxAccessible)
mxAccessible.set(new ValueSetAcc(this));
return mxAccessible;
}
ValueSet::~ValueSet()
{
ImplDeleteItems();
if (mxAccessible)
mxAccessible->Invalidate();
}
void ValueSet::ImplDeleteItems()
{
const size_t n = mItemList.size();
for ( size_t i = 0; i < n; ++i )
{
if (ValueSetItem* pItem = mItemList[i].get())
{
rtl::Reference<ValueItemAcc> xItemAcc = pItem->GetAccessible(false);
if (xItemAcc.is())
{
Any aOldAny;
Any aNewAny;
aOldAny <<= Reference<XAccessible>(xItemAcc);
ImplFireAccessibleEvent(AccessibleEventId::CHILD, aOldAny, aNewAny);
xItemAcc->dispose();
}
}
mItemList[i].reset();
}
mItemList.clear();
}
void ValueSet::Select()
{
collectUIInformation(GetDrawingArea()->get_buildable_name() , GetDrawingArea()->get_help_id() , OUString::number(GetSelectedItemId()));
maSelectHdl.Call( this );
}
void ValueSet::UserDraw( const UserDrawEvent& )
{
}
size_t ValueSet::ImplGetItem( const Point& rPos ) const
{
if (!mbHasVisibleItems)
{
return VALUESET_ITEM_NOTFOUND;
}
if (maItemListRect.Contains(rPos))
{
const int xc = rPos.X() - maItemListRect.Left();
const int yc = rPos.Y() - maItemListRect.Top();
// The point is inside the area of item list,
// let's find the containing item.
const int col = xc / (mnItemWidth + mnSpacing);
const int x = xc % (mnItemWidth + mnSpacing);
const int row = yc / (mnItemHeight + mnSpacing);
const int y = yc % (mnItemHeight + mnSpacing);
if (x < mnItemWidth && y < mnItemHeight)
{
// the point is inside item rect and not inside spacing
const size_t item = (mnFirstLine + row) * static_cast<size_t>(mnCols) + col;
if (item < mItemList.size())
{
return item;
}
}
}
return VALUESET_ITEM_NOTFOUND;
}
ValueSetItem* ValueSet::ImplGetItem( size_t nPos )
{
return (nPos < mItemList.size()) ? mItemList[nPos].get() : nullptr;
}
ValueSetItem* ValueSet::ImplGetFirstItem()
{
return !mItemList.empty() ? mItemList[0].get() : nullptr;
}
sal_uInt16 ValueSet::ImplGetVisibleItemCount() const
{
sal_uInt16 nRet = 0;
const size_t nItemCount = mItemList.size();
for ( size_t n = 0; n < nItemCount; ++n )
{
if ( mItemList[n]->mbVisible )
++nRet;
}
return nRet;
}
void ValueSet::ImplFireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue )
{
if( mxAccessible )
mxAccessible->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
}
bool ValueSet::ImplHasAccessibleListeners() const
{
return mxAccessible && mxAccessible->HasAccessibleListeners();
}
IMPL_LINK(ValueSet, ImplScrollHdl, weld::ScrolledWindow&, rScrollWin, void)
{
auto nNewFirstLine = rScrollWin.vadjustment_get_value();
if ( nNewFirstLine != mnFirstLine )
{
mnFirstLine = nNewFirstLine;
mbFormat = true;
Invalidate();
}
}
void ValueSet::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
{
rRenderContext.SetBackground(Application::GetSettings().GetStyleSettings().GetFaceColor());
rRenderContext.Erase();
ImplDraw(rRenderContext);
}
void ValueSet::GetFocus()
{
SAL_INFO("svtools", "value set getting focus");
Invalidate();
CustomWidgetController::GetFocus();
// Tell the accessible object that we got the focus.
if (mxAccessible)
mxAccessible->GetFocus();
}
void ValueSet::LoseFocus()
{
SAL_INFO("svtools", "value set losing focus");
Invalidate();
CustomWidgetController::LoseFocus();
// Tell the accessible object that we lost the focus.
if( mxAccessible )
mxAccessible->LoseFocus();
}
void ValueSet::Resize()
{
mbFormat = true;
if (IsReallyVisible())
Invalidate();
CustomWidgetController::Resize();
}
bool ValueSet::KeyInput( const KeyEvent& rKeyEvent )
{
size_t nLastItem = mItemList.size();
if ( !nLastItem || !ImplGetFirstItem() )
return CustomWidgetController::KeyInput(rKeyEvent);
if (mbFormat)
Invalidate();
--nLastItem;
const size_t nCurPos
= mnSelItemId ? GetItemPos(mnSelItemId) : 0;
size_t nItemPos = VALUESET_ITEM_NOTFOUND;
size_t nVStep = mnCols;
switch (rKeyEvent.GetKeyCode().GetCode())
{
case KEY_HOME:
nItemPos = 0;
break;
case KEY_END:
nItemPos = nLastItem;
break;
case KEY_LEFT:
if (nCurPos)
nItemPos = nCurPos - 1;
break;
case KEY_RIGHT:
if (nCurPos < nLastItem)
nItemPos = nCurPos + 1;
break;
case KEY_PAGEUP:
if (rKeyEvent.GetKeyCode().IsShift() || rKeyEvent.GetKeyCode().IsMod1() || rKeyEvent.GetKeyCode().IsMod2())
{
return CustomWidgetController::KeyInput(rKeyEvent);
}
nVStep *= mnVisLines;
[[fallthrough]];
case KEY_UP:
if (nCurPos == nLastItem)
{
const size_t nCol = mnCols ? nLastItem % mnCols : 0;
if (nCol < mnCurCol)
{
// Move to previous row/page, keeping the old column
nVStep -= mnCurCol - nCol;
}
}
if (nCurPos >= nVStep)
{
// Go up of a whole page
nItemPos = nCurPos - nVStep;
}
else if (nCurPos > mnCols)
{
// Go to same column in first row
nItemPos = nCurPos % mnCols;
}
break;
case KEY_PAGEDOWN:
if (rKeyEvent.GetKeyCode().IsShift() || rKeyEvent.GetKeyCode().IsMod1() || rKeyEvent.GetKeyCode().IsMod2())
{
return CustomWidgetController::KeyInput(rKeyEvent);
}
nVStep *= mnVisLines;
[[fallthrough]];
case KEY_DOWN:
if (nCurPos != nLastItem)
{
nItemPos = nCurPos + nVStep;
if (nItemPos > nLastItem)
{
nItemPos = nLastItem;
}
}
break;
case KEY_RETURN:
if (GetStyle() & WB_NO_DIRECTSELECT)
{
// tdf#142479 on return select the entry the cursor is in
// before calling Select
const sal_uInt16 nItemId = GetItemId(nCurPos);
if (nItemId != mnSelItemId)
SelectItem(nItemId);
Select();
break;
}
[[fallthrough]];
default:
return CustomWidgetController::KeyInput(rKeyEvent);
}
if ( nItemPos == VALUESET_ITEM_NOTFOUND )
return true;
if (nItemPos < nLastItem)
{
// update current column only in case of a new position
// which is also not a "specially" handled one.
mnCurCol = mnCols ? nItemPos % mnCols : 0;
}
const sal_uInt16 nItemId = GetItemId(nItemPos);
if ( nItemId != mnSelItemId )
{
SelectItem( nItemId );
if (!(GetStyle() & WB_NO_DIRECTSELECT))
{
// select only if WB_NO_DIRECTSELECT is not set
Select();
}
}
return true;
}
void ValueSet::ImplTracking(bool bLeaveWindow, const Point& rPos)
{
if (GetStyle() & WB_MENUSTYLEVALUESET || GetStyle() & WB_FLATVALUESET)
mbHighlight = true;
if (ValueSetItem* pItem = bLeaveWindow ? nullptr : ImplGetItem(ImplGetItem(rPos)))
ImplHighlightItem(pItem->mnId);
else
ImplHighlightItem(0);
}
bool ValueSet::MouseButtonDown( const MouseEvent& rMouseEvent )
{
if (rMouseEvent.IsLeft() && !rMouseEvent.IsMod2())
{
bool bConsumed = false;
ValueSetItem* pItem = ImplGetItem( ImplGetItem( rMouseEvent.GetPosPixel() ) );
if (rMouseEvent.GetClicks() == 1)
{
if (pItem)
SelectItem(pItem->mnId);
GrabFocus();
bConsumed = true;
}
else if (pItem && rMouseEvent.GetClicks() == 2)
{
maDoubleClickHdl.Call(this);
bConsumed = true;
}
return bConsumed;
}
return CustomWidgetController::MouseButtonDown( rMouseEvent );
}
bool ValueSet::MouseButtonUp( const MouseEvent& rMouseEvent )
{
if (rMouseEvent.IsLeft() && !rMouseEvent.IsMod2())
{
// tdf#165881 MouseUp may be seen without previous MouseDown. Select
// what's under the mouse on mouse release when in menu-alike modes.
const bool bMenuAlike = GetStyle() & WB_MENUSTYLEVALUESET || GetStyle() & WB_FLATVALUESET;
if (bMenuAlike)
{
if (ValueSetItem* pItem = ImplGetItem(ImplGetItem(rMouseEvent.GetPosPixel())))
SelectItem(pItem->mnId);
}
// tdf#142150 MouseUp seen without previous MouseDown
if (mnSelItemId)
Select();
return true;
}
return CustomWidgetController::MouseButtonUp( rMouseEvent );
}
bool ValueSet::MouseMove(const MouseEvent& rMouseEvent)
{
// because of SelectionMode
if ((GetStyle() & WB_MENUSTYLEVALUESET) || (GetStyle() & WB_FLATVALUESET))
ImplTracking(rMouseEvent.IsLeaveWindow(), rMouseEvent.GetPosPixel());
return CustomWidgetController::MouseMove(rMouseEvent);
}
void ValueSet::QueueReformat()
{
queue_resize();
RecalcScrollBar();
mbFormat = true;
if (IsReallyVisible())
Invalidate();
}
void ValueSet::RemoveItem( sal_uInt16 nItemId )
{
size_t nPos = GetItemPos( nItemId );
if ( nPos == VALUESET_ITEM_NOTFOUND )
return;
mItemList.erase( mItemList.begin() + nPos );
// reset variables
if (mnHighItemId == nItemId || mnSelItemId == nItemId)
{
mnCurCol = 0;
mnHighItemId = 0;
mnSelItemId = 0;
mbNoSelection = true;
}
QueueReformat();
}
bool ValueSet::TurnOffScrollBar()
{
if (mxScrolledWindow->get_vpolicy() == VclPolicyType::NEVER)
return false;
mxScrolledWindow->set_vpolicy(VclPolicyType::NEVER);
weld::DrawingArea* pDrawingArea = GetDrawingArea();
Size aPrefSize(pDrawingArea->get_preferred_size());
pDrawingArea->set_size_request(aPrefSize.Width() + GetScrollWidth(), aPrefSize.Height());
return true;
}
void ValueSet::TurnOnScrollBar()
{
if (mxScrolledWindow->get_vpolicy() == VclPolicyType::ALWAYS)
return;
mxScrolledWindow->set_vpolicy(VclPolicyType::ALWAYS);
weld::DrawingArea* pDrawingArea = GetDrawingArea();
Size aPrefSize(pDrawingArea->get_preferred_size());
pDrawingArea->set_size_request(aPrefSize.Width() - GetScrollWidth(), aPrefSize.Height());
}
void ValueSet::RecalcScrollBar()
{
if (!mxScrolledWindow)
return;
const bool bScrollAllowed = GetStyle() & WB_VSCROLL;
if (!bScrollAllowed)
return;
// reset scrolled window state to initial value so it will get configured
// to the right adjustment on the next format which we toggle on to happen
// if the scrolledwindow wasn't in its initial state already
if (TurnOffScrollBar())
mbFormat = true;
}
void ValueSet::Clear()
{
ImplDeleteItems();
// reset variables
mnFirstLine = 0;
mnCurCol = 0;
mnHighItemId = 0;
mnSelItemId = 0;
mbNoSelection = true;
RecalcScrollBar();
mbFormat = true;
if (IsReallyVisible())
Invalidate();
}
size_t ValueSet::GetItemCount() const
{
return mItemList.size();
}
size_t ValueSet::GetItemPos( sal_uInt16 nItemId ) const
{
for ( size_t i = 0, n = mItemList.size(); i < n; ++i ) {
if ( mItemList[i]->mnId == nItemId ) {
return i;
}
}
return VALUESET_ITEM_NOTFOUND;
}
sal_uInt16 ValueSet::GetItemId( size_t nPos ) const
{
return ( nPos < mItemList.size() ) ? mItemList[nPos]->mnId : 0 ;
}
sal_uInt16 ValueSet::GetItemId( const Point& rPos ) const
{
size_t nItemPos = ImplGetItem( rPos );
if ( nItemPos != VALUESET_ITEM_NOTFOUND )
return GetItemId( nItemPos );
return 0;
}
tools::Rectangle ValueSet::GetItemRect( sal_uInt16 nItemId ) const
{
const size_t nPos = GetItemPos( nItemId );
if ( nPos!=VALUESET_ITEM_NOTFOUND && mItemList[nPos]->mbVisible )
return ImplGetItemRect( nPos );
return tools::Rectangle();
}
tools::Rectangle ValueSet::ImplGetItemRect( size_t nPos ) const
{
const size_t nVisibleBegin = static_cast<size_t>(mnFirstLine)*mnCols;
const size_t nVisibleEnd = nVisibleBegin + static_cast<size_t>(mnVisLines)*mnCols;
// Check if the item is inside the range of the displayed ones,
// taking into account that last row could be incomplete
if ( nPos<nVisibleBegin || nPos>=nVisibleEnd || nPos>=mItemList.size() )
return tools::Rectangle();
nPos -= nVisibleBegin;
const size_t row = mnCols ? nPos/mnCols : 0;
const size_t col = mnCols ? nPos%mnCols : 0;
const tools::Long x = maItemListRect.Left()+col*(mnItemWidth+mnSpacing);
const tools::Long y = maItemListRect.Top()+row*(mnItemHeight+mnSpacing);
return tools::Rectangle( Point(x, y), Size(mnItemWidth, mnItemHeight) );
}
void ValueSet::ImplHighlightItem(sal_uInt16 nItemId)
{
if ( mnHighItemId == nItemId )
return;
// remember the old item to delete the previous selection
mnHighItemId = nItemId;
// remove the old selection and draw the new one
Invalidate();
}
void ValueSet::ImplDraw(vcl::RenderContext& rRenderContext)
{
if (mbFormat)
Format();
Point aDefPos;
Size aSize = maVirDev->GetOutputSizePixel();
rRenderContext.DrawOutDev(aDefPos, aSize, aDefPos, aSize, *maVirDev);
ImplDrawSelect(rRenderContext);
}
void ValueSet::SetFirstLine(sal_uInt16 nNewFirstLine)
{
if (nNewFirstLine != mnFirstLine)
{
mnFirstLine = nNewFirstLine;
if (mxScrolledWindow)
mxScrolledWindow->vadjustment_set_value(mnFirstLine);
}
}
void ValueSet::SelectItem( sal_uInt16 nItemId )
{
size_t nItemPos = 0;
if ( nItemId )
{
nItemPos = GetItemPos( nItemId );
if ( nItemPos == VALUESET_ITEM_NOTFOUND )
return;
}
if ( !((mnSelItemId != nItemId) || mbNoSelection) )
return;
const sal_uInt16 nOldItem = mnSelItemId;
mnSelItemId = nItemId;
mbNoSelection = false;
bool bNewOut = !mbFormat && IsReallyVisible();
bool bNewLine = false;
if (!mnCols && GetDrawingArea())
{
Format();
// reset scrollbar so it's set to the later calculated mnFirstLine on
// the next Format
RecalcScrollBar();
}
// if necessary scroll to the visible area
if (nItemId && mnCols)
{
sal_uInt16 nNewLine = static_cast<sal_uInt16>(nItemPos / mnCols);
if ( nNewLine < mnFirstLine )
{
SetFirstLine(nNewLine);
bNewLine = true;
}
else if (mnFirstLine + mnVisLines - 1 >= 0
&& nNewLine > o3tl::make_unsigned(mnFirstLine + mnVisLines - 1))
{
SetFirstLine(static_cast<sal_uInt16>(nNewLine-mnVisLines+1));
bNewLine = true;
}
}
if ( bNewOut )
{
if ( bNewLine )
{
// redraw everything if the visible area has changed
mbFormat = true;
}
Invalidate();
}
if( !ImplHasAccessibleListeners() )
return;
// focus event (deselect)
if( nOldItem )
{
const size_t nPos = GetItemPos( nItemId );
if( nPos != VALUESET_ITEM_NOTFOUND )
{
rtl::Reference<ValueItemAcc> pItemAcc =
mItemList[nPos]->GetAccessible();
if( pItemAcc )
{
Any aOldAny;
Any aNewAny;
aOldAny <<= Reference(getXWeak(pItemAcc.get()));
ImplFireAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
}
}
}
if (mxAccessible->getAccessibleStateSet() & css::accessibility::AccessibleStateType::FOCUSED)
{
// focus event (select)
const size_t nPos = GetItemPos(mnSelItemId);
ValueSetItem* pItem = nullptr;
if (nPos != VALUESET_ITEM_NOTFOUND)
pItem = mItemList[nPos].get();
ValueItemAcc* pItemAcc = nullptr;
if (pItem != nullptr)
pItemAcc =
pItem->GetAccessible().get();
if (pItemAcc)
{
Any aOldAny;
Any aNewAny;
aNewAny <<= Reference(getXWeak(pItemAcc));
ImplFireAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny);
}
}
// selection event
Any aOldAny;
Any aNewAny;
ImplFireAccessibleEvent(AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny);
}
void ValueSet::SetNoSelection()
{
mbNoSelection = true;
mbHighlight = false;
if (IsReallyVisible())
Invalidate();
}
void ValueSet::SetStyle(WinBits nStyle)
{
if (nStyle != mnStyle)
{
mnStyle = nStyle;
mbFormat = true;
Invalidate();
}
}
void ValueSet::Format()
{
Size aWinSize(GetOutputSizePixel());
size_t nItemCount = mItemList.size();
WinBits nStyle = GetStyle();
if (mxScrolledWindow && !(nStyle & WB_VSCROLL) && mxScrolledWindow->get_vpolicy() != VclPolicyType::NEVER)
TurnOffScrollBar();
if ( mnMargin )
{
aWinSize.AdjustWidth(-mnMargin * 2);
aWinSize.AdjustHeight(-mnMargin * 2);
}
// calculate number of columns
if (!mnUserCols)
{
if (mnUserItemWidth)
{
mnCols = static_cast<sal_uInt16>((aWinSize.Width() - mnSpacing) / (mnUserItemWidth + mnSpacing));
if (mnCols <= 0)
mnCols = 1;
}
else
{
mnCols = 1;
}
}
else
{
mnCols = mnUserCols;
}
// calculate number of rows
auto nOldLines = mnLines;
// Floor( (M+N-1)/N )==Ceiling( M/N )
mnLines = (static_cast<tools::Long>(nItemCount) + mnCols - 1) / mnCols;
if (mnLines <= 0)
mnLines = 1;
bool bAdjustmentOutOfDate = nOldLines != mnLines;
auto nOldVisLines = mnVisLines;
tools::Long nCalcHeight = aWinSize.Height();
if (mnUserVisLines)
{
mnVisLines = mnUserVisLines;
}
else if (mnUserItemHeight)
{
mnVisLines = (nCalcHeight + mnSpacing) / (mnUserItemHeight + mnSpacing);
if (!mnVisLines)
mnVisLines = 1;
}
else
{
mnVisLines = mnLines;
}
bAdjustmentOutOfDate |= nOldVisLines != mnVisLines;
if (mnLines <= mnVisLines)
{
SetFirstLine(0);
}
else
{
if (mnFirstLine > o3tl::make_unsigned(mnLines - mnVisLines))
SetFirstLine(static_cast<sal_uInt16>(mnLines - mnVisLines));
}
// calculate item size
const tools::Long nColSpace = (mnCols - 1) * static_cast<tools::Long>(mnSpacing);
const tools::Long nLineSpace = (mnVisLines - 1) * mnSpacing;
if (mnUserItemWidth && !mnUserCols)
{
mnItemWidth = mnUserItemWidth;
if (mnItemWidth > aWinSize.Width() - nColSpace)
mnItemWidth = aWinSize.Width() - nColSpace;
}
else
mnItemWidth = (aWinSize.Width() - nColSpace) / mnCols;
if (mnUserItemHeight && !mnUserVisLines)
{
mnItemHeight = mnUserItemHeight;
if (mnItemHeight > nCalcHeight)
mnItemHeight = nCalcHeight;
}
else
{
nCalcHeight -= nLineSpace;
mnItemHeight = nCalcHeight / mnVisLines;
}
// Init VirDev
maVirDev->SetBackground(Application::GetSettings().GetStyleSettings().GetFaceColor());
Size aDevSize(aWinSize);
aDevSize.AdjustWidth(mnMargin * 2);
aDevSize.AdjustHeight(mnMargin * 2);
maVirDev->SetOutputSizePixel(aDevSize);
maVirDev->Erase();
// nothing is changed in case of too small items
if ((mnItemWidth <= 0) ||
(mnItemHeight <= ((nStyle & WB_ITEMBORDER) ? 4 : 2)) ||
!nItemCount)
{
mbHasVisibleItems = false;
for (size_t i = 0; i < nItemCount; i++)
{
mItemList[i]->mbVisible = false;
}
if (mxScrolledWindow && mxScrolledWindow->get_vpolicy() != VclPolicyType::NEVER)
TurnOffScrollBar();
}
else
{
mbHasVisibleItems = true;
// determine Frame-Style
if (nStyle & WB_DOUBLEBORDER)
mnFrameStyle = DrawFrameStyle::DoubleIn;
else
mnFrameStyle = DrawFrameStyle::In;
// draw the selection with double width if the items are bigger
if ((nStyle & WB_DOUBLEBORDER) &&
((mnItemWidth >= 25) && (mnItemHeight >= 20)))
{
mbDoubleSel = true;
}
else
{
mbDoubleSel = false;
}
// calculate offsets
tools::Long nStartX;
tools::Long nStartY;
if (mbFullMode)
{
tools::Long nAllItemWidth = (mnItemWidth * mnCols) + nColSpace;
tools::Long nAllItemHeight = (mnItemHeight * mnVisLines) + nLineSpace;
nStartX = (aWinSize.Width() - nAllItemWidth) / 2;
nStartY = (aWinSize.Height() - nAllItemHeight) / 2;
}
else
{
nStartX = 0;
nStartY = 0;
}
nStartX += mnMargin;
nStartY += mnMargin;
// calculate and draw items
maVirDev->SetLineColor();
tools::Long x = nStartX;
tools::Long y = nStartY;
// draw items
size_t nFirstItem = static_cast<size_t>(mnFirstLine) * mnCols;
size_t nLastItem = nFirstItem + (mnVisLines * mnCols);
maItemListRect.SetLeft( x );
maItemListRect.SetTop( y );
maItemListRect.SetRight( x + mnCols * (mnItemWidth + mnSpacing) - mnSpacing - 1 );
maItemListRect.SetBottom( y + mnVisLines * (mnItemHeight + mnSpacing) - mnSpacing - 1 );
if (!mbFullMode)
{
// If want also draw parts of items in the last line,
// then we add one more line if parts of these line are
// visible
if (y + (mnVisLines * (mnItemHeight + mnSpacing)) < aWinSize.Height())
nLastItem += mnCols;
maItemListRect.SetBottom( aWinSize.Height() - y );
}
for (size_t i = 0; i < nItemCount; i++)
{
ValueSetItem* pItem = mItemList[i].get();
if (i >= nFirstItem && i < nLastItem)
{
if (!pItem->mbVisible && ImplHasAccessibleListeners())
{
Any aOldAny;
Any aNewAny;
aNewAny <<= Reference<XAccessible>(pItem->GetAccessible());
ImplFireAccessibleEvent(AccessibleEventId::CHILD, aOldAny, aNewAny);
}
pItem->mbVisible = true;
ImplFormatItem(*pItem,
tools::Rectangle(Point(x, y), Size(mnItemWidth, mnItemHeight)));
if (!((i + 1) % mnCols))
{
x = nStartX;
y += mnItemHeight + mnSpacing;
}
else
x += mnItemWidth + mnSpacing;
}
else
{
if (pItem->mbVisible && ImplHasAccessibleListeners())
{
Any aOldAny;
Any aNewAny;
aOldAny <<= Reference<XAccessible>(pItem->GetAccessible());
ImplFireAccessibleEvent(AccessibleEventId::CHILD, aOldAny, aNewAny);
}
pItem->mbVisible = false;
}
}
// arrange ScrollBar, set values and show it
if (mxScrolledWindow && (nStyle & WB_VSCROLL))
{
bool bTurnScrollbarOn = mxScrolledWindow->get_vpolicy() != VclPolicyType::ALWAYS;
if (bAdjustmentOutOfDate || bTurnScrollbarOn)
{
tools::Long nPageSize = mnVisLines;
if (nPageSize < 1)
nPageSize = 1;
mxScrolledWindow->vadjustment_configure(mnFirstLine, mnLines, 1, mnVisLines,
nPageSize);
}
if (bTurnScrollbarOn)
TurnOnScrollBar();
}
}
// waiting for the next since the formatting is finished
mbFormat = false;
}
void ValueSet::ImplDrawSelect(vcl::RenderContext& rRenderContext)
{
if (!IsReallyVisible())
return;
const bool bFocus = HasFocus();
if (!bFocus && mbNoSelection && !mbHighlight)
return;
tools::Rectangle aSelectedRect, aHoverRect;
ValueSetItem* pSelectedItem = ImplGetDrawSelectItem(mnSelItemId, bFocus, aSelectedRect);
ValueSetItem* pHighlightItem = mnHighItemId ? ImplGetDrawSelectItem(mnHighItemId, false, aHoverRect) : nullptr;
if (pSelectedItem)
{
const bool bHover = pSelectedItem == pHighlightItem;
ImplDrawSelect(rRenderContext, aSelectedRect, bFocus, !mbNoSelection, true, bHover);
}
if (pHighlightItem && (pSelectedItem != pHighlightItem || mbNoSelection))
{
// For the case that there isn't a selected item, but due to wanting to
// show focus is in the valueset, the above block will have drawn the
// first item with a focus rect. For that situation; if the valueset is
// the thin WB_MENUSTYLEVALUESET case then blend this highlight border
// on top of that focus rect and it will appear with a highlighted
// focus rect. If it's the other case of a thicker border then redraw
// the focus rect highlighted with the hover color.
bool bDrawFocus;
WinBits nStyle = GetStyle();
if (nStyle & WB_MENUSTYLEVALUESET)
bDrawFocus = false;
else
bDrawFocus = pSelectedItem == pHighlightItem && mbNoSelection;
ImplDrawSelect(rRenderContext, aHoverRect, bDrawFocus, mbHighlight, false, true);
}
}
ValueSetItem* ValueSet::ImplGetDrawSelectItem(sal_uInt16 nItemId, const bool bFocus, tools::Rectangle& rRect)
{
ValueSetItem* pItem = nullptr;
if (nItemId)
{
const size_t nPos = GetItemPos( nItemId );
pItem = mItemList[ nPos ].get();
rRect = ImplGetItemRect( nPos );
}
else if (bFocus && (pItem = ImplGetFirstItem()))
{
rRect = ImplGetItemRect(0);
}
return pItem;
}
void ValueSet::ImplDrawSelect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect,
const bool bFocus, const bool bDrawSel, const bool bSelected,
const bool bHover)
{
tools::Rectangle aRect(rRect);
// draw selection
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
rRenderContext.SetFillColor();
Color aDoubleColor;
Color aSingleColor;
sal_uInt16 nTransparencePercent = 0;
if (bSelected && bHover)
{
aDoubleColor = rStyleSettings.GetActiveColor();
aSingleColor = rStyleSettings.GetActiveTextColor();
}
else if (bSelected || bHover)
{
aDoubleColor = rStyleSettings.GetHighlightColor();
aSingleColor = rStyleSettings.GetHighlightTextColor();
if (bHover)
{
nTransparencePercent = 55;
}
}
// specify selection output
WinBits nStyle = GetStyle();
if (nStyle & WB_MENUSTYLEVALUESET)
{
if (bFocus)
InvertFocusRect(rRenderContext, aRect);
if (bDrawSel)
{
rRenderContext.SetLineColor(aDoubleColor);
aRect.AdjustLeft( -1 );
aRect.AdjustTop( -1 );
aRect.AdjustRight( -2 );
aRect.AdjustBottom( -2 );
const tools::Polygon aPoly(aRect);
LineInfo aLineInfo;
aLineInfo.SetWidth(3);
rRenderContext.DrawPolyLine(aPoly, aLineInfo); // tdf#136917
}
}
else
{
rRenderContext.SetLineColor(aDoubleColor);
tools::Rectangle aFocusRect;
if (!mbDoubleSel)
{
// an outer rectangle surrounding a "focus" rectangle, surrounding
// an inner rectangle. Focus rectangle is always drawn, but rendered
// empty when there is no focus. e.g. as seen in color valuesets
if (bDrawSel)
{
tools::PolyPolygon aPolyPoly(1);
aPolyPoly.Insert(tools::Polygon(aRect));
rRenderContext.DrawTransparent(aPolyPoly, nTransparencePercent);
}
aRect.AdjustLeft( 1 );
aRect.AdjustTop( 1 );
aRect.AdjustRight( -1 );
aRect.AdjustBottom( -1 );
aFocusRect = aRect;
aRect.AdjustLeft( 1 );
aRect.AdjustTop( 1 );
aRect.AdjustRight( -1 );
aRect.AdjustBottom( -1 );
if (bDrawSel)
{
tools::PolyPolygon aPolyPoly(1);
aPolyPoly.Insert(tools::Polygon(aRect));
rRenderContext.DrawTransparent(aPolyPoly, nTransparencePercent);
}
if (bDrawSel)
rRenderContext.SetLineColor(aSingleColor);
else
rRenderContext.SetLineColor(COL_LIGHTGRAY);
rRenderContext.DrawRect(aFocusRect);
}
else
{
// a thick bordered rectangle surrounding an optional "focus"
// rectangle which is only drawn when focused, as seen in format,
// bullets and numbering in writer
const int nAdjust = 2;
aRect.AdjustLeft(nAdjust);
aRect.AdjustTop(nAdjust);
aRect.AdjustRight(-nAdjust);
aRect.AdjustBottom(-nAdjust);
aFocusRect = aRect;
if (bDrawSel)
{
const basegfx::B2DPolygon aRectPoly(
basegfx::utils::createPolygonFromRect(
vcl::unotools::b2DRectangleFromRectangle(aRect)));
const int nThickness = nAdjust * 2;
if (!rRenderContext.DrawPolyLineDirect(basegfx::B2DHomMatrix(),
aRectPoly,
nThickness,
nTransparencePercent / 100.0,
nullptr,
basegfx::B2DLineJoin::Miter))
{
SAL_WARN("svtools", "presumably impossible in practice, but fallback to see something");
rRenderContext.DrawPolyLine(aRectPoly, nThickness, basegfx::B2DLineJoin::Miter);
}
}
if (bFocus)
{
if (bDrawSel)
rRenderContext.SetLineColor(aSingleColor);
else
rRenderContext.SetLineColor(COL_LIGHTGRAY);
rRenderContext.DrawRect(aFocusRect);
}
}
if (bFocus)
InvertFocusRect(rRenderContext, aFocusRect);
}
}
void ValueSet::ImplFormatItem(ValueSetItem& rItem, tools::Rectangle aRect)
{
WinBits nStyle = GetStyle();
if (nStyle & WB_ITEMBORDER)
{
aRect.AdjustLeft(1 );
aRect.AdjustTop(1 );
aRect.AdjustRight( -1 );
aRect.AdjustBottom( -1 );
if (nStyle & WB_FLATVALUESET)
{
sal_Int32 nBorder = (nStyle & WB_DOUBLEBORDER) ? 2 : 1;
aRect.AdjustLeft(nBorder );
aRect.AdjustTop(nBorder );
aRect.AdjustRight( -nBorder );
aRect.AdjustBottom( -nBorder );
}
else
{
DecorationView aView(maVirDev.get());
aRect = aView.DrawFrame(aRect, mnFrameStyle);
}
}
if ((aRect.GetHeight() <= 0) || (aRect.GetWidth() <= 0))
return;
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
if (rItem.meType == ValueSetItemType::Color)
{
maVirDev->SetFillColor(rItem.maColor);
maVirDev->DrawRect(aRect);
}
else
{
if (IsColor())
maVirDev->SetFillColor(maColor);
else if (nStyle & WB_MENUSTYLEVALUESET)
maVirDev->SetFillColor(rStyleSettings.GetMenuColor());
else if (IsEnabled())
maVirDev->SetFillColor(rStyleSettings.GetWindowColor());
else
maVirDev->SetFillColor(rStyleSettings.GetFaceColor());
maVirDev->DrawRect(aRect);
if (rItem.meType == ValueSetItemType::UserDraw)
{
UserDrawEvent aUDEvt(maVirDev.get(), aRect, rItem.mnId);
UserDraw(aUDEvt);
}
else
{
Size aImageSize = rItem.maImage.GetSizePixel();
Size aRectSize = aRect.GetSize();
Point aPos(aRect.Left(), aRect.Top());
aPos.AdjustX((aRectSize.Width() - aImageSize.Width()) / 2 );
aPos.AdjustY((aRectSize.Height() - aImageSize.Height()) / 2);
DrawImageFlags nImageStyle = DrawImageFlags::NONE;
if (!IsEnabled())
nImageStyle |= DrawImageFlags::Disable;
if (aImageSize.Width() > aRectSize.Width() ||
aImageSize.Height() > aRectSize.Height())
{
maVirDev->SetClipRegion(vcl::Region(aRect));
maVirDev->DrawImage(aPos, rItem.maImage, nImageStyle);
maVirDev->SetClipRegion();
}
else
maVirDev->DrawImage(aPos, rItem.maImage, nImageStyle);
}
}
const sal_uInt16 nEdgeBlendingPercent = mbEdgeBlending ? rStyleSettings.GetEdgeBlending() : 0;
if (nEdgeBlendingPercent)
{
const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
const sal_uInt8 nAlpha(255 - ((nEdgeBlendingPercent * 255) / 100));
const Bitmap aBlendFrame(createAlphaBlendFrame(aRect.GetSize(), nAlpha, rTopLeft, rBottomRight));
if (!aBlendFrame.IsEmpty())
{
maVirDev->DrawBitmap(aRect.TopLeft(), aBlendFrame);
}
}
}
void ValueSet::StyleUpdated()
{
mbFormat = true;
CustomWidgetController::StyleUpdated();
}
void ValueSet::EnableFullItemMode( bool bFullMode )
{
mbFullMode = bFullMode;
}
void ValueSet::SetColCount( sal_uInt16 nNewCols )
{
if ( mnUserCols != nNewCols )
{
mnUserCols = nNewCols;
QueueReformat();
}
}
void ValueSet::SetItemColor( sal_uInt16 nItemId, const Color& rColor )
{
size_t nPos = GetItemPos( nItemId );
if ( nPos == VALUESET_ITEM_NOTFOUND )
return;
ValueSetItem* pItem = mItemList[nPos].get();
pItem->meType = ValueSetItemType::Color;
pItem->maColor = rColor;
if (!mbFormat && IsReallyVisible())
{
const tools::Rectangle aRect = ImplGetItemRect(nPos);
Invalidate( aRect );
}
else
mbFormat = true;
}
Color ValueSet::GetItemColor( sal_uInt16 nItemId ) const
{
size_t nPos = GetItemPos( nItemId );
if ( nPos != VALUESET_ITEM_NOTFOUND )
return mItemList[nPos]->maColor;
else
return Color();
}
Size ValueSet::CalcWindowSizePixel( const Size& rItemSize, sal_uInt16 nDesireCols,
sal_uInt16 nDesireLines ) const
{
size_t nCalcCols = nDesireCols;
size_t nCalcLines = nDesireLines;
if ( !nCalcCols )
{
if ( mnUserCols )
nCalcCols = mnUserCols;
else
nCalcCols = 1;
}
if ( !nCalcLines )
{
nCalcLines = mnVisLines;
if ( mbFormat )
{
if ( mnUserVisLines )
nCalcLines = mnUserVisLines;
else
{
// Floor( (M+N-1)/N )==Ceiling( M/N )
nCalcLines = (mItemList.size()+nCalcCols-1) / nCalcCols;
if ( !nCalcLines )
nCalcLines = 1;
}
}
}
Size aSize( rItemSize.Width() * nCalcCols, rItemSize.Height() * nCalcLines );
WinBits nStyle = GetStyle();
if ( nStyle & WB_ITEMBORDER )
{
tools::Long n;
if ( nStyle & WB_DOUBLEBORDER )
n = ITEM_OFFSET_DOUBLE;
else
n = ITEM_OFFSET;
aSize.AdjustWidth(n * nCalcCols );
aSize.AdjustHeight(n * nCalcLines );
}
if ( mnSpacing )
{
aSize.AdjustWidth(mnSpacing * (nCalcCols - 1) );
aSize.AdjustHeight(mnSpacing * (nCalcLines - 1) );
}
if ( mnMargin )
{
aSize.AdjustWidth(mnMargin * 2);
aSize.AdjustHeight(mnMargin * 2);
}
return aSize;
}
void ValueSet::InsertItem( sal_uInt16 nItemId, const Image& rImage )
{
std::unique_ptr<ValueSetItem> pItem(new ValueSetItem( *this ));
pItem->mnId = nItemId;
pItem->meType = ValueSetItemType::Image;
pItem->maImage = rImage;
ImplInsertItem( std::move(pItem), VALUESET_APPEND );
}
void ValueSet::InsertItem( sal_uInt16 nItemId, const Image& rImage,
const OUString& rText, size_t nPos)
{
std::unique_ptr<ValueSetItem> pItem(new ValueSetItem( *this ));
pItem->mnId = nItemId;
pItem->meType = ValueSetItemType::Image;
pItem->maImage = rImage;
pItem->maText = rText;
ImplInsertItem( std::move(pItem), nPos );
}
void ValueSet::InsertItem( sal_uInt16 nItemId, size_t nPos )
{
std::unique_ptr<ValueSetItem> pItem(new ValueSetItem( *this ));
pItem->mnId = nItemId;
pItem->meType = ValueSetItemType::UserDraw;
ImplInsertItem( std::move(pItem), nPos );
}
void ValueSet::InsertItem( sal_uInt16 nItemId, const Color& rColor,
const OUString& rText )
{
std::unique_ptr<ValueSetItem> pItem(new ValueSetItem( *this ));
pItem->mnId = nItemId;
pItem->meType = ValueSetItemType::Color;
pItem->maColor = rColor;
pItem->maText = rText;
ImplInsertItem( std::move(pItem), VALUESET_APPEND );
}
void ValueSet::ImplInsertItem( std::unique_ptr<ValueSetItem> pItem, const size_t nPos )
{
DBG_ASSERT( pItem->mnId, "ValueSet::InsertItem(): ItemId == 0" );
DBG_ASSERT( GetItemPos( pItem->mnId ) == VALUESET_ITEM_NOTFOUND,
"ValueSet::InsertItem(): ItemId already exists" );
if ( nPos < mItemList.size() ) {
mItemList.insert( mItemList.begin() + nPos, std::move(pItem) );
} else {
mItemList.push_back( std::move(pItem) );
}
QueueReformat();
}
int ValueSet::GetScrollWidth() const
{
if (mxScrolledWindow)
return mxScrolledWindow->get_scroll_thickness();
return 0;
}
void ValueSet::SetEdgeBlending(bool bNew)
{
if(mbEdgeBlending != bNew)
{
mbEdgeBlending = bNew;
mbFormat = true;
if (GetDrawingArea() && IsReallyVisible())
{
Invalidate();
}
}
}
Size ValueSet::CalcItemSizePixel( const Size& rItemSize) const
{
Size aSize = rItemSize;
WinBits nStyle = GetStyle();
if ( nStyle & WB_ITEMBORDER )
{
tools::Long n;
if ( nStyle & WB_DOUBLEBORDER )
n = ITEM_OFFSET_DOUBLE;
else
n = ITEM_OFFSET;
aSize.AdjustWidth(n );
aSize.AdjustHeight(n );
}
return aSize;
}
void ValueSet::SetLineCount( sal_uInt16 nNewLines )
{
if ( mnUserVisLines != nNewLines )
{
mnUserVisLines = nNewLines;
QueueReformat();
}
}
void ValueSet::SetItemWidth( tools::Long nNewItemWidth )
{
if ( mnUserItemWidth != nNewItemWidth )
{
mnUserItemWidth = nNewItemWidth;
QueueReformat();
}
}
//method to set accessible when the style is user draw.
void ValueSet::InsertItem( sal_uInt16 nItemId, const OUString& rText, size_t nPos )
{
DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
"ValueSet::InsertItem(): ItemId already exists" );
std::unique_ptr<ValueSetItem> pItem(new ValueSetItem( *this ));
pItem->mnId = nItemId;
pItem->meType = ValueSetItemType::UserDraw;
pItem->maText = rText;
ImplInsertItem( std::move(pItem), nPos );
}
void ValueSet::SetItemHeight( tools::Long nNewItemHeight )
{
if ( mnUserItemHeight != nNewItemHeight )
{
mnUserItemHeight = nNewItemHeight;
QueueReformat();
}
}
OUString ValueSet::RequestHelp(tools::Rectangle& rHelpRect)
{
Point aPos = rHelpRect.TopLeft();
const size_t nItemPos = ImplGetItem( aPos );
OUString sRet;
if (nItemPos != VALUESET_ITEM_NOTFOUND)
{
rHelpRect = ImplGetItemRect(nItemPos);
sRet = GetItemText(ImplGetItem(nItemPos)->mnId);
}
return sRet;
}
const OUString & ValueSet::GetItemText(sal_uInt16 nItemId) const
{
const size_t nPos = GetItemPos(nItemId);
if ( nPos != VALUESET_ITEM_NOTFOUND )
return mItemList[nPos]->maText;
return EMPTY_OUSTRING;
}
void ValueSet::SetExtraSpacing( sal_uInt16 nNewSpacing )
{
if ( GetStyle() & WB_ITEMBORDER )
{
mnSpacing = nNewSpacing;
QueueReformat();
}
}
void ValueSet::SetMargin( sal_uInt16 nNewMargin )
{
mnMargin = nNewMargin;
QueueReformat();
}
void ValueSet::SetFormat()
{
mbFormat = true;
}
void ValueSet::SetItemText(sal_uInt16 nItemId, const OUString& rText)
{
size_t nPos = GetItemPos( nItemId );
if ( nPos == VALUESET_ITEM_NOTFOUND )
return;
ValueSetItem* pItem = mItemList[nPos].get();
// Remember old and new name for accessibility event.
Any aOldName;
Any aNewName;
OUString sString (pItem->maText);
aOldName <<= sString;
sString = rText;
aNewName <<= sString;
pItem->maText = rText;
if (!mbFormat && IsReallyVisible())
{
sal_uInt16 nTempId = mnSelItemId;
if (mbHighlight)
nTempId = mnHighItemId;
if (nTempId == nItemId)
Invalidate();
}
if (ImplHasAccessibleListeners())
{
rtl::Reference<ValueItemAcc> xAccessible(pItem->GetAccessible());
xAccessible->FireAccessibleEvent(AccessibleEventId::NAME_CHANGED, aOldName, aNewName);
}
}
Size ValueSet::GetLargestItemSize()
{
Size aLargestItem;
for (const std::unique_ptr<ValueSetItem>& pItem : mItemList)
{
if (!pItem->mbVisible)
continue;
if (pItem->meType != ValueSetItemType::Image)
{
// handle determining an optimal size for this case
continue;
}
Size aSize = pItem->maImage.GetSizePixel();
aLargestItem.setWidth( std::max(aLargestItem.Width(), aSize.Width()) );
aLargestItem.setHeight( std::max(aLargestItem.Height(), aSize.Height()) );
}
return aLargestItem;
}
void ValueSet::SetOptimalSize()
{
Size aLargestSize(GetLargestItemSize());
aLargestSize.setWidth(std::max(aLargestSize.Width(), mnUserItemWidth));
aLargestSize.setHeight(std::max(aLargestSize.Height(), mnUserItemHeight));
Size aPrefSize(CalcWindowSizePixel(aLargestSize));
GetDrawingArea()->set_size_request(aPrefSize.Width(), aPrefSize.Height());
}
Image ValueSet::GetItemImage(sal_uInt16 nItemId) const
{
size_t nPos = GetItemPos( nItemId );
if ( nPos != VALUESET_ITEM_NOTFOUND )
return mItemList[nPos]->maImage;
else
return Image();
}
void ValueSet::SetColor(const Color& rColor)
{
maColor = rColor;
mbFormat = true;
if (IsReallyVisible())
Invalidate();
}
void ValueSet::Show()
{
if (mxScrolledWindow)
mxScrolledWindow->show();
CustomWidgetController::Show();
}
void ValueSet::Hide()
{
CustomWidgetController::Hide();
if (mxScrolledWindow)
mxScrolledWindow->hide();
}
FactoryFunction ValueSet::GetUITestFactory() const
{
return ValueSetUIObject::create;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */