tdf#70102 Code support for RTL variants in icon themes
UNO commands may optionally rotate or mirror their icons depending on context (usually based on writing direction). This approach is an easy way to provide large numbers of such context-sensitive icons, but suffers from serious drawbacks in certain cases. For example, icons which contain asymmetrical symbols or text will be obviously mirrored, and icon themes which use shading will appear inconsistent next to non-transformed icons from the same theme. This code change lets icon themes provide specialized graphics for the left-right-top-bottom text direction. Such specializations are available for any command which specifies COMMAND_PROPERTY_MIRROR. Direction-specialized versions should be placed in the `cmd/rltb` directory within the icon theme. Localized specializations may also be nested inside that directory. For example, icons in `cmd/rltb/en` will be used for English in RTL context. Change-Id: Ic7a8cf3a6657a171e92123413d1c47e621f1bddd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182761 Reviewed-by: Jonathan Clark <jonathan@libreoffice.org> Tested-by: Jenkins
This commit is contained in:
@@ -21,11 +21,13 @@ namespace vcl
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr o3tl::enumarray<ImageType, OUString> ImageType_Prefixes
|
||||
{
|
||||
u"cmd/sc_"_ustr,
|
||||
u"cmd/lc_"_ustr,
|
||||
u"cmd/32/"_ustr
|
||||
std::map<std::tuple<ImageType, ImageWritingDirection>, OUString> const ImageType_Prefixes{
|
||||
{ { ImageType::Size16, ImageWritingDirection::DontCare }, u"cmd/sc_"_ustr },
|
||||
{ { ImageType::Size26, ImageWritingDirection::DontCare }, u"cmd/lc_"_ustr },
|
||||
{ { ImageType::Size32, ImageWritingDirection::DontCare }, u"cmd/32/"_ustr },
|
||||
{ { ImageType::Size16, ImageWritingDirection::RightLeftTopBottom }, u"cmd/rltb/sc_"_ustr },
|
||||
{ { ImageType::Size26, ImageWritingDirection::RightLeftTopBottom }, u"cmd/rltb/lc_"_ustr },
|
||||
{ { ImageType::Size32, ImageWritingDirection::RightLeftTopBottom }, u"cmd/rltb/32/"_ustr },
|
||||
};
|
||||
|
||||
OUString lclConvertToCanonicalName(const OUString& rFileName)
|
||||
@@ -116,32 +118,36 @@ bool CommandImageResolver::hasImage(const OUString& rCommandURL)
|
||||
return pIterator != m_aCommandToImageNameMap.end();
|
||||
}
|
||||
|
||||
ImageList* CommandImageResolver::getImageList(ImageType nImageType)
|
||||
ImageList* CommandImageResolver::getImageList(ImageType nImageType, ImageWritingDirection nImageDir)
|
||||
{
|
||||
const OUString sIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
|
||||
|
||||
if (sIconTheme != m_sIconTheme)
|
||||
{
|
||||
m_sIconTheme = sIconTheme;
|
||||
for (auto& rp : m_pImageList)
|
||||
rp.reset();
|
||||
m_pImageList.clear();
|
||||
}
|
||||
|
||||
if (!m_pImageList[nImageType])
|
||||
auto stKey = std::make_tuple(nImageType, nImageDir);
|
||||
if (auto it = m_pImageList.find(stKey); it != m_pImageList.end())
|
||||
{
|
||||
const OUString& sIconPath = ImageType_Prefixes[nImageType];
|
||||
m_pImageList[nImageType].reset( new ImageList(m_aImageNameVector, sIconPath) );
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
return m_pImageList[nImageType].get();
|
||||
const OUString& sIconPath = ImageType_Prefixes.at(stKey);
|
||||
auto pImageList = std::make_unique<ImageList>(m_aImageNameVector, sIconPath);
|
||||
|
||||
return m_pImageList.emplace(stKey, std::move(pImageList)).first->second.get();
|
||||
}
|
||||
|
||||
Image CommandImageResolver::getImageFromCommandURL(ImageType nImageType, const OUString& rCommandURL)
|
||||
Image CommandImageResolver::getImageFromCommandURL(ImageType nImageType,
|
||||
ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL)
|
||||
{
|
||||
CommandToImageNameMap::const_iterator pIterator = m_aCommandToImageNameMap.find(rCommandURL);
|
||||
if (pIterator != m_aCommandToImageNameMap.end())
|
||||
{
|
||||
ImageList* pImageList = getImageList(nImageType);
|
||||
ImageList* pImageList = getImageList(nImageType, nImageDir);
|
||||
return pImageList->GetImage(pIterator->second);
|
||||
}
|
||||
return Image();
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcl/image.hxx>
|
||||
#include <o3tl/enumarray.hxx>
|
||||
|
||||
#include <com/sun/star/uno/Sequence.hxx>
|
||||
|
||||
@@ -19,6 +18,8 @@
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
|
||||
namespace vcl
|
||||
{
|
||||
@@ -31,17 +32,18 @@ private:
|
||||
std::vector<OUString> m_aImageCommandNameVector;
|
||||
std::vector<OUString> m_aImageNameVector;
|
||||
|
||||
o3tl::enumarray<ImageType, std::unique_ptr<ImageList>> m_pImageList;
|
||||
std::map<std::tuple<ImageType, ImageWritingDirection>, std::unique_ptr<ImageList>> m_pImageList;
|
||||
OUString m_sIconTheme;
|
||||
|
||||
ImageList* getImageList(ImageType nImageType);
|
||||
ImageList* getImageList(ImageType nImageType, ImageWritingDirection nImageDir);
|
||||
|
||||
public:
|
||||
CommandImageResolver();
|
||||
~CommandImageResolver();
|
||||
|
||||
void registerCommands(const css::uno::Sequence<OUString>& aCommandSequence);
|
||||
Image getImageFromCommandURL(ImageType nImageType, const OUString& rCommandURL);
|
||||
Image getImageFromCommandURL(ImageType nImageType, ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL);
|
||||
|
||||
std::vector<OUString>& getCommandNames() { return m_aImageCommandNameVector; }
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ using namespace ::com::sun::star::beans;
|
||||
using namespace ::com::sun::star::ui;
|
||||
using namespace ::cppu;
|
||||
|
||||
const sal_Int16 MAX_IMAGETYPE_VALUE = css::ui::ImageType::SIZE_32;
|
||||
|
||||
constexpr OUString IMAGE_FOLDER = u"images"_ustr;
|
||||
constexpr OUString BITMAPS_FOLDER = u"Bitmaps"_ustr;
|
||||
|
||||
@@ -83,6 +81,10 @@ constexpr o3tl::enumarray<vcl::ImageType, OUString> BITMAP_FILE_NAMES
|
||||
|
||||
namespace framework
|
||||
{
|
||||
namespace
|
||||
{
|
||||
using ImageIndex = std::tuple<vcl::ImageType, vcl::ImageWritingDirection>;
|
||||
}
|
||||
|
||||
static GlobalImageList* pGlobalImageList = nullptr;
|
||||
|
||||
@@ -159,14 +161,16 @@ void CmdImageList::initialize()
|
||||
m_bInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
Image CmdImageList::getImageFromCommandURL(vcl::ImageType nImageType, const OUString& rCommandURL)
|
||||
Image CmdImageList::getImageFromCommandURL(vcl::ImageType nImageType,
|
||||
vcl::ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL)
|
||||
{
|
||||
initialize();
|
||||
return m_aResolver.getImageFromCommandURL(nImageType, rCommandURL);
|
||||
return m_aResolver.getImageFromCommandURL(nImageType, nImageDir, rCommandURL);
|
||||
}
|
||||
|
||||
bool CmdImageList::hasImage(vcl::ImageType /*nImageType*/, const OUString& rCommandURL)
|
||||
bool CmdImageList::hasImage(vcl::ImageType /*nImageType*/, vcl::ImageWritingDirection /*nImageDir*/,
|
||||
const OUString& rCommandURL)
|
||||
{
|
||||
initialize();
|
||||
return m_aResolver.hasImage(rCommandURL);
|
||||
@@ -189,16 +193,19 @@ GlobalImageList::~GlobalImageList()
|
||||
pGlobalImageList = nullptr;
|
||||
}
|
||||
|
||||
Image GlobalImageList::getImageFromCommandURL( vcl::ImageType nImageType, const OUString& rCommandURL )
|
||||
Image GlobalImageList::getImageFromCommandURL(vcl::ImageType nImageType,
|
||||
vcl::ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL)
|
||||
{
|
||||
std::unique_lock guard( getGlobalImageListMutex() );
|
||||
return CmdImageList::getImageFromCommandURL( nImageType, rCommandURL );
|
||||
std::unique_lock guard(getGlobalImageListMutex());
|
||||
return CmdImageList::getImageFromCommandURL(nImageType, nImageDir, rCommandURL);
|
||||
}
|
||||
|
||||
bool GlobalImageList::hasImage( vcl::ImageType nImageType, const OUString& rCommandURL )
|
||||
bool GlobalImageList::hasImage(vcl::ImageType nImageType, vcl::ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL)
|
||||
{
|
||||
std::unique_lock guard( getGlobalImageListMutex() );
|
||||
return CmdImageList::hasImage( nImageType, rCommandURL );
|
||||
std::unique_lock guard(getGlobalImageListMutex());
|
||||
return CmdImageList::hasImage(nImageType, nImageDir, rCommandURL);
|
||||
}
|
||||
|
||||
::std::vector< OUString >& GlobalImageList::getImageCommandNames()
|
||||
@@ -235,14 +242,36 @@ static bool implts_checkAndScaleGraphic( uno::Reference< XGraphic >& rOutGraphic
|
||||
return true;
|
||||
}
|
||||
|
||||
static vcl::ImageType implts_convertImageTypeToIndex( sal_Int16 nImageType )
|
||||
static std::optional<ImageIndex> implts_convertImageTypeToIndex(sal_Int16 nImageType)
|
||||
{
|
||||
sal_Int16 nSanitize = 0;
|
||||
|
||||
vcl::ImageType nType = vcl::ImageType::Size16;
|
||||
vcl::ImageWritingDirection nDir = vcl::ImageWritingDirection::DontCare;
|
||||
|
||||
if (nImageType & css::ui::ImageType::SIZE_LARGE)
|
||||
return vcl::ImageType::Size26;
|
||||
{
|
||||
nType = vcl::ImageType::Size26;
|
||||
nSanitize |= css::ui::ImageType::SIZE_LARGE;
|
||||
}
|
||||
else if (nImageType & css::ui::ImageType::SIZE_32)
|
||||
return vcl::ImageType::Size32;
|
||||
else
|
||||
return vcl::ImageType::Size16;
|
||||
{
|
||||
nType = vcl::ImageType::Size32;
|
||||
nSanitize |= css::ui::ImageType::SIZE_32;
|
||||
}
|
||||
|
||||
if (nImageType & css::ui::ImageType::DIR_RL_TB)
|
||||
{
|
||||
nDir = vcl::ImageWritingDirection::RightLeftTopBottom;
|
||||
nSanitize |= css::ui::ImageType::DIR_RL_TB;
|
||||
}
|
||||
|
||||
if (nSanitize != nImageType)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return ImageIndex{ nType, nDir };
|
||||
}
|
||||
|
||||
ImageList* ImageManagerImpl::implts_getUserImageList( vcl::ImageType nImageType )
|
||||
@@ -632,7 +661,9 @@ Sequence< OUString > ImageManagerImpl::getAllImageNames( ::sal_Int16 nImageType
|
||||
|
||||
std::unordered_set< OUString > aImageCmdNames;
|
||||
|
||||
vcl::ImageType nIndex = implts_convertImageTypeToIndex( nImageType );
|
||||
auto nIndex = implts_convertImageTypeToIndex(nImageType);
|
||||
if (!nIndex.has_value())
|
||||
throw IllegalArgumentException();
|
||||
|
||||
sal_uInt32 i( 0 );
|
||||
if ( m_bUseGlobal )
|
||||
@@ -650,7 +681,7 @@ Sequence< OUString > ImageManagerImpl::getAllImageNames( ::sal_Int16 nImageType
|
||||
aImageCmdNames.insert( rModuleImageNameVector[i] );
|
||||
}
|
||||
|
||||
ImageList* pImageList = implts_getUserImageList(nIndex);
|
||||
ImageList* pImageList = implts_getUserImageList(std::get<0>(*nIndex));
|
||||
std::vector< OUString > rUserImageNames;
|
||||
pImageList->GetImageNames( rUserImageNames );
|
||||
const sal_uInt32 nUserCount = rUserImageNames.size();
|
||||
@@ -668,20 +699,24 @@ bool ImageManagerImpl::hasImage( ::sal_Int16 nImageType, const OUString& aComman
|
||||
if ( m_bDisposed )
|
||||
throw DisposedException();
|
||||
|
||||
if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
|
||||
auto nIndex = implts_convertImageTypeToIndex(nImageType);
|
||||
if (!nIndex.has_value())
|
||||
throw IllegalArgumentException();
|
||||
|
||||
vcl::ImageType nIndex = implts_convertImageTypeToIndex( nImageType );
|
||||
if ( m_bUseGlobal && implts_getGlobalImageList()->hasImage( nIndex, aCommandURL ))
|
||||
if (m_bUseGlobal
|
||||
&& implts_getGlobalImageList()->hasImage(std::get<0>(*nIndex), std::get<1>(*nIndex),
|
||||
aCommandURL))
|
||||
return true;
|
||||
else
|
||||
{
|
||||
if ( m_bUseGlobal && implts_getDefaultImageList()->hasImage( nIndex, aCommandURL ))
|
||||
if (m_bUseGlobal
|
||||
&& implts_getDefaultImageList()->hasImage(std::get<0>(*nIndex), std::get<1>(*nIndex),
|
||||
aCommandURL))
|
||||
return true;
|
||||
else
|
||||
{
|
||||
// User layer
|
||||
ImageList* pImageList = implts_getUserImageList(nIndex);
|
||||
ImageList* pImageList = implts_getUserImageList(std::get<0>(*nIndex));
|
||||
if ( pImageList )
|
||||
return ( pImageList->GetImagePos( aCommandURL ) != IMAGELIST_IMAGE_NOTFOUND );
|
||||
}
|
||||
@@ -708,12 +743,12 @@ Sequence< uno::Reference< XGraphic > > ImageManagerImpl::getImages(
|
||||
if ( m_bDisposed )
|
||||
throw DisposedException();
|
||||
|
||||
if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
|
||||
auto nIndex = implts_convertImageTypeToIndex(nImageType);
|
||||
if (!nIndex.has_value())
|
||||
throw IllegalArgumentException();
|
||||
|
||||
Sequence< uno::Reference< XGraphic > > aGraphSeq( aCommandURLSequence.getLength() );
|
||||
|
||||
vcl::ImageType nIndex = implts_convertImageTypeToIndex( nImageType );
|
||||
rtl::Reference< GlobalImageList > rGlobalImageList;
|
||||
CmdImageList* pDefaultImageList = nullptr;
|
||||
if ( m_bUseGlobal )
|
||||
@@ -721,7 +756,7 @@ Sequence< uno::Reference< XGraphic > > ImageManagerImpl::getImages(
|
||||
rGlobalImageList = implts_getGlobalImageList();
|
||||
pDefaultImageList = implts_getDefaultImageList();
|
||||
}
|
||||
ImageList* pUserImageList = implts_getUserImageList(nIndex);
|
||||
ImageList* pUserImageList = implts_getUserImageList(std::get<0>(*nIndex));
|
||||
|
||||
// We have to search our image list in the following order:
|
||||
// 1. user image list (read/write)
|
||||
@@ -734,11 +769,17 @@ Sequence< uno::Reference< XGraphic > > ImageManagerImpl::getImages(
|
||||
Image aImage = pUserImageList->GetImage( rURL );
|
||||
if ( !aImage && m_bUseGlobal )
|
||||
{
|
||||
aImage = pDefaultImageList->getImageFromCommandURL( nIndex, rURL );
|
||||
if ( !aImage )
|
||||
aImage = rGlobalImageList->getImageFromCommandURL( nIndex, rURL );
|
||||
aImage = pDefaultImageList->getImageFromCommandURL(std::get<0>(*nIndex),
|
||||
std::get<1>(*nIndex), rURL);
|
||||
if (!aImage)
|
||||
aImage = rGlobalImageList->getImageFromCommandURL(std::get<0>(*nIndex),
|
||||
std::get<1>(*nIndex), rURL);
|
||||
}
|
||||
|
||||
// tdf#70102: Writing direction specializations are always optional. Suppress
|
||||
// missing image file warnings on load.
|
||||
aImage.SetOptional(std::get<1>(*nIndex) != vcl::ImageWritingDirection::DontCare);
|
||||
|
||||
aGraphSeqRange[n++] = GetXGraphic(aImage);
|
||||
}
|
||||
|
||||
@@ -760,21 +801,21 @@ void ImageManagerImpl::replaceImages(
|
||||
if ( m_bDisposed )
|
||||
throw DisposedException();
|
||||
|
||||
if (( aCommandURLSequence.getLength() != aGraphicsSequence.getLength() ) ||
|
||||
(( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE )))
|
||||
auto nIndex = implts_convertImageTypeToIndex(nImageType);
|
||||
if ((aCommandURLSequence.getLength() != aGraphicsSequence.getLength())
|
||||
|| (!nIndex.has_value()))
|
||||
throw IllegalArgumentException();
|
||||
|
||||
if ( m_bReadOnly )
|
||||
throw IllegalAccessException();
|
||||
|
||||
vcl::ImageType nIndex = implts_convertImageTypeToIndex( nImageType );
|
||||
ImageList* pImageList = implts_getUserImageList(nIndex);
|
||||
ImageList* pImageList = implts_getUserImageList(std::get<0>(*nIndex));
|
||||
|
||||
uno::Reference< XGraphic > xGraphic;
|
||||
for ( sal_Int32 i = 0; i < aCommandURLSequence.getLength(); i++ )
|
||||
{
|
||||
// Check size and scale. If we don't have any graphics ignore it
|
||||
if ( !implts_checkAndScaleGraphic( xGraphic, aGraphicsSequence[i], nIndex ))
|
||||
if (!implts_checkAndScaleGraphic(xGraphic, aGraphicsSequence[i], std::get<0>(*nIndex)))
|
||||
continue;
|
||||
|
||||
sal_uInt16 nPos = pImageList->GetImagePos( aCommandURLSequence[i] );
|
||||
@@ -797,7 +838,7 @@ void ImageManagerImpl::replaceImages(
|
||||
if (( pInsertedImages != nullptr ) || ( pReplacedImages != nullptr ))
|
||||
{
|
||||
m_bModified = true;
|
||||
m_bUserImageListModified[nIndex] = true;
|
||||
m_bUserImageListModified[std::get<0>(*nIndex)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -838,13 +879,13 @@ void ImageManagerImpl::removeImages( ::sal_Int16 nImageType, const Sequence< OUS
|
||||
if ( m_bDisposed )
|
||||
throw DisposedException();
|
||||
|
||||
if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
|
||||
auto nIndex = implts_convertImageTypeToIndex(nImageType);
|
||||
if (!nIndex.has_value())
|
||||
throw IllegalArgumentException();
|
||||
|
||||
if ( m_bReadOnly )
|
||||
throw IllegalAccessException();
|
||||
|
||||
vcl::ImageType nIndex = implts_convertImageTypeToIndex( nImageType );
|
||||
rtl::Reference< GlobalImageList > rGlobalImageList;
|
||||
CmdImageList* pDefaultImageList = nullptr;
|
||||
if ( m_bUseGlobal )
|
||||
@@ -852,7 +893,7 @@ void ImageManagerImpl::removeImages( ::sal_Int16 nImageType, const Sequence< OUS
|
||||
rGlobalImageList = implts_getGlobalImageList();
|
||||
pDefaultImageList = implts_getDefaultImageList();
|
||||
}
|
||||
ImageList* pImageList = implts_getUserImageList(nIndex);
|
||||
ImageList* pImageList = implts_getUserImageList(std::get<0>(*nIndex));
|
||||
uno::Reference<XGraphic> xEmptyGraphic;
|
||||
|
||||
for ( const OUString& rURL : aCommandURLSequence )
|
||||
@@ -867,9 +908,11 @@ void ImageManagerImpl::removeImages( ::sal_Int16 nImageType, const Sequence< OUS
|
||||
{
|
||||
// Check, if we have an image in our module/global image list. If we find one =>
|
||||
// this is a replace instead of a remove operation!
|
||||
Image aNewImage = pDefaultImageList->getImageFromCommandURL( nIndex, rURL );
|
||||
if ( !aNewImage )
|
||||
aNewImage = rGlobalImageList->getImageFromCommandURL( nIndex, rURL );
|
||||
Image aNewImage = pDefaultImageList->getImageFromCommandURL(
|
||||
std::get<0>(*nIndex), std::get<1>(*nIndex), rURL);
|
||||
if (!aNewImage)
|
||||
aNewImage = rGlobalImageList->getImageFromCommandURL(
|
||||
std::get<0>(*nIndex), std::get<1>(*nIndex), rURL);
|
||||
if ( !aNewImage )
|
||||
{
|
||||
if ( !pRemovedImages )
|
||||
@@ -895,7 +938,7 @@ void ImageManagerImpl::removeImages( ::sal_Int16 nImageType, const Sequence< OUS
|
||||
if (( pReplacedImages != nullptr ) || ( pRemovedImages != nullptr ))
|
||||
{
|
||||
m_bModified = true;
|
||||
m_bUserImageListModified[nIndex] = true;
|
||||
m_bUserImageListModified[std::get<0>(*nIndex)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1003,9 +1046,11 @@ void ImageManagerImpl::reload()
|
||||
{
|
||||
if ( m_bUseGlobal )
|
||||
{
|
||||
Image aImage = pDefaultImageList->getImageFromCommandURL( i, oldUserCmdImage.first );
|
||||
if ( !aImage )
|
||||
aImage = rGlobalImageList->getImageFromCommandURL( i, oldUserCmdImage.first );
|
||||
Image aImage = pDefaultImageList->getImageFromCommandURL(
|
||||
i, vcl::ImageWritingDirection::DontCare, oldUserCmdImage.first);
|
||||
if (!aImage)
|
||||
aImage = rGlobalImageList->getImageFromCommandURL(
|
||||
i, vcl::ImageWritingDirection::DontCare, oldUserCmdImage.first);
|
||||
|
||||
if ( !aImage )
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <comphelper/interfacecontainer4.hxx>
|
||||
#include <rtl/ustring.hxx>
|
||||
|
||||
#include <o3tl/enumarray.hxx>
|
||||
#include <rtl/ref.hxx>
|
||||
#include <salhelper/simplereferenceobject.hxx>
|
||||
|
||||
@@ -47,8 +48,11 @@ namespace framework
|
||||
CmdImageList(css::uno::Reference< css::uno::XComponentContext > xContext, OUString aModuleIdentifier);
|
||||
virtual ~CmdImageList();
|
||||
|
||||
virtual Image getImageFromCommandURL(vcl::ImageType nImageType, const OUString& rCommandURL);
|
||||
virtual bool hasImage(vcl::ImageType nImageType, const OUString& rCommandURL);
|
||||
virtual Image getImageFromCommandURL(vcl::ImageType nImageType,
|
||||
vcl::ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL);
|
||||
virtual bool hasImage(vcl::ImageType nImageType, vcl::ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL);
|
||||
virtual std::vector<OUString>& getImageCommandNames();
|
||||
|
||||
protected:
|
||||
@@ -68,8 +72,11 @@ namespace framework
|
||||
explicit GlobalImageList(const css::uno::Reference< css::uno::XComponentContext >& rxContext);
|
||||
virtual ~GlobalImageList() override;
|
||||
|
||||
virtual Image getImageFromCommandURL( vcl::ImageType nImageType, const OUString& rCommandURL ) override;
|
||||
virtual bool hasImage( vcl::ImageType nImageType, const OUString& rCommandURL ) override;
|
||||
virtual Image getImageFromCommandURL(vcl::ImageType nImageType,
|
||||
vcl::ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL) override;
|
||||
virtual bool hasImage(vcl::ImageType nImageType, vcl::ImageWritingDirection nImageDir,
|
||||
const OUString& rCommandURL) override;
|
||||
virtual ::std::vector< OUString >& getImageCommandNames() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -394,6 +394,20 @@ void ImageOrientationController::statusChanged(const css::frame::FeatureStateEve
|
||||
OUString aCommand = m_pToolbar->get_item_ident(i);
|
||||
if (vcl::CommandInfoProvider::IsMirrored(aCommand, getModuleName()))
|
||||
{
|
||||
if (m_bMirrored)
|
||||
{
|
||||
// Search for a specialized mirrored graphic
|
||||
auto xRltbGraphic = vcl::CommandInfoProvider::GetXGraphicForCommand(
|
||||
aCommand, m_xFrame, m_pToolbar->get_icon_size(),
|
||||
vcl::ImageWritingDirection::RightLeftTopBottom);
|
||||
if (xRltbGraphic)
|
||||
{
|
||||
m_pToolbar->set_item_image_mirrored(aCommand, false);
|
||||
m_pToolbar->set_item_image(aCommand, xRltbGraphic);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
m_pToolbar->set_item_image_mirrored(aCommand, m_bMirrored);
|
||||
auto xGraphic(vcl::CommandInfoProvider::GetXGraphicForCommand(
|
||||
aCommand, m_xFrame, m_pToolbar->get_icon_size()));
|
||||
@@ -408,8 +422,25 @@ void ImageOrientationController::statusChanged(const css::frame::FeatureStateEve
|
||||
{
|
||||
ToolBoxItemId nItemId = pToolBox->GetItemId(i);
|
||||
OUString aCommand = pToolBox->GetItemCommand(nItemId);
|
||||
|
||||
bool bCmdMirrored = vcl::CommandInfoProvider::IsMirrored(aCommand, getModuleName());
|
||||
if (bCmdMirrored && m_bMirrored)
|
||||
{
|
||||
// Search for a specialized mirrored graphic
|
||||
auto xRltbGraphic = vcl::CommandInfoProvider::GetXGraphicForCommand(
|
||||
aCommand, m_xFrame, pToolBox->GetImageSize(),
|
||||
vcl::ImageWritingDirection::RightLeftTopBottom);
|
||||
if (xRltbGraphic)
|
||||
{
|
||||
pToolBox->SetItemImageMirrorMode(nItemId, false);
|
||||
pToolBox->SetItemImageAngle(nItemId, m_nRotationAngle);
|
||||
pToolBox->SetItemImage(nItemId, Image{ xRltbGraphic });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bool bModified = false;
|
||||
if (vcl::CommandInfoProvider::IsMirrored(aCommand, getModuleName()))
|
||||
if (bCmdMirrored)
|
||||
{
|
||||
pToolBox->SetItemImageMirrorMode(nItemId, m_bMirrored);
|
||||
bModified = true;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 387 B |
Binary file not shown.
|
After Width: | Height: | Size: 444 B |
Binary file not shown.
|
After Width: | Height: | Size: 381 B |
@@ -80,12 +80,14 @@ namespace vcl::CommandInfoProvider {
|
||||
VCL_DLLPUBLIC css::uno::Reference<css::graphic::XGraphic> GetXGraphicForCommand(
|
||||
const OUString& rsCommandName,
|
||||
const css::uno::Reference<css::frame::XFrame>& rxFrame,
|
||||
vcl::ImageType eImageType = vcl::ImageType::Small);
|
||||
vcl::ImageType eImageType = vcl::ImageType::Small,
|
||||
vcl::ImageWritingDirection eImageDir = vcl::ImageWritingDirection::DontCare);
|
||||
|
||||
VCL_DLLPUBLIC Image GetImageForCommand(
|
||||
const OUString& rsCommandName,
|
||||
const css::uno::Reference<css::frame::XFrame>& rxFrame,
|
||||
vcl::ImageType eImageType = vcl::ImageType::Small);
|
||||
vcl::ImageType eImageType = vcl::ImageType::Small,
|
||||
vcl::ImageWritingDirection eImageDir = vcl::ImageWritingDirection::DontCare);
|
||||
|
||||
VCL_DLLPUBLIC sal_Int32 GetPropertiesForCommand(
|
||||
const OUString& rsCommandName,
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
|
||||
Size GetSizePixel() const;
|
||||
BitmapEx GetBitmapEx() const;
|
||||
void SetOptional(bool bValue);
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
|
||||
@@ -308,6 +308,15 @@ namespace vcl
|
||||
Small = Size16,
|
||||
LAST = Size32,
|
||||
};
|
||||
|
||||
// Specifies a writing direction-based specialization for an image.
|
||||
// Sets do not necessarily provide all possible specializations.
|
||||
enum class ImageWritingDirection
|
||||
{
|
||||
LeftRightTopBottom = 0,
|
||||
RightLeftTopBottom,
|
||||
DontCare = LeftRightTopBottom,
|
||||
};
|
||||
}
|
||||
|
||||
enum class DrawFrameStyle
|
||||
|
||||
@@ -51,6 +51,13 @@ constants ImageType
|
||||
*/
|
||||
const short COLOR_HIGHCONTRAST = 4;
|
||||
|
||||
/** an image unspecialized, or for lr-tb writing.
|
||||
*/
|
||||
const short DIR_LR_TB = 0;
|
||||
|
||||
/** an image specialized for rl-tb writing.
|
||||
*/
|
||||
const short DIR_RL_TB = 8;
|
||||
};
|
||||
|
||||
}; }; }; };
|
||||
|
||||
@@ -40,6 +40,8 @@ private:
|
||||
BitmapEx maBitmapEx;
|
||||
BitmapEx maDisabledBitmapEx;
|
||||
|
||||
bool bOptional = false;
|
||||
|
||||
bool loadStockAtScale(SalGraphics* pGraphics, BitmapEx &rBitmapEx);
|
||||
|
||||
public:
|
||||
@@ -64,6 +66,8 @@ public:
|
||||
/// Taking account of HiDPI scaling
|
||||
BitmapEx const & getBitmapExForHiDPI(bool bDisabled, SalGraphics* pGraphics);
|
||||
|
||||
void SetOptional(bool bValue);
|
||||
|
||||
bool isEqual(const ImplImage &ref) const;
|
||||
bool isSizeEmpty() const
|
||||
{
|
||||
|
||||
@@ -339,18 +339,25 @@ OUString GetRealCommandForCommand(const css::uno::Sequence<css::beans::PropertyV
|
||||
|
||||
Reference<graphic::XGraphic> GetXGraphicForCommand(const OUString& rsCommandName,
|
||||
const Reference<frame::XFrame>& rxFrame,
|
||||
vcl::ImageType eImageType)
|
||||
vcl::ImageType eImageType,
|
||||
vcl::ImageWritingDirection eImageDir)
|
||||
{
|
||||
if (rsCommandName.isEmpty())
|
||||
return nullptr;
|
||||
|
||||
sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT);
|
||||
sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT
|
||||
| ui::ImageType::DIR_LR_TB);
|
||||
|
||||
if (eImageType == vcl::ImageType::Size26)
|
||||
nImageType |= ui::ImageType::SIZE_LARGE;
|
||||
else if (eImageType == vcl::ImageType::Size32)
|
||||
nImageType |= ui::ImageType::SIZE_32;
|
||||
|
||||
if (eImageDir == vcl::ImageWritingDirection::RightLeftTopBottom)
|
||||
{
|
||||
nImageType |= ui::ImageType::DIR_RL_TB;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Reference<frame::XController> xController(rxFrame->getController(), UNO_SET_THROW);
|
||||
@@ -392,11 +399,10 @@ Reference<graphic::XGraphic> GetXGraphicForCommand(const OUString& rsCommandName
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Image GetImageForCommand(const OUString& rsCommandName,
|
||||
const Reference<frame::XFrame>& rxFrame,
|
||||
vcl::ImageType eImageType)
|
||||
Image GetImageForCommand(const OUString& rsCommandName, const Reference<frame::XFrame>& rxFrame,
|
||||
vcl::ImageType eImageType, vcl::ImageWritingDirection eImageDir)
|
||||
{
|
||||
return Image(GetXGraphicForCommand(rsCommandName, rxFrame, eImageType));
|
||||
return Image(GetXGraphicForCommand(rsCommandName, rxFrame, eImageType, eImageDir));
|
||||
}
|
||||
|
||||
sal_Int32 GetPropertiesForCommand (
|
||||
|
||||
@@ -101,6 +101,14 @@ BitmapEx Image::GetBitmapEx() const
|
||||
return BitmapEx();
|
||||
}
|
||||
|
||||
void Image::SetOptional(bool bValue)
|
||||
{
|
||||
if (mpImplData)
|
||||
{
|
||||
mpImplData->SetOptional(bValue);
|
||||
}
|
||||
}
|
||||
|
||||
bool Image::operator==(const Image& rImage) const
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
@@ -92,15 +92,16 @@ bool ImplImage::loadStockAtScale(SalGraphics* pGraphics, BitmapEx &rBitmapEx)
|
||||
if (!ImageTree::get().loadImage(aFileName, aIconTheme, aBitmapEx, true,
|
||||
nScalePercentage, eScalingFlags))
|
||||
{
|
||||
SAL_WARN("vcl", "Failed to load scaled image from " << maStockName <<
|
||||
" and " << aFileName << " at " << fScale);
|
||||
SAL_WARN_IF(!bOptional, "vcl",
|
||||
"Failed to load scaled image from " << maStockName << " and "
|
||||
<< aFileName << " at " << fScale);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_WARN("vcl", "Failed to load scaled image from " << maStockName <<
|
||||
" at " << fScale);
|
||||
SAL_WARN_IF(!bOptional, "vcl",
|
||||
"Failed to load scaled image from " << maStockName << " at " << fScale);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -123,7 +124,7 @@ Size ImplImage::getSizePixel()
|
||||
aRet = maSizePixel;
|
||||
}
|
||||
else
|
||||
SAL_WARN("vcl", "Failed to load stock icon " << maStockName);
|
||||
SAL_WARN_IF(!bOptional, "vcl", "Failed to load stock icon " << maStockName);
|
||||
}
|
||||
return aRet;
|
||||
}
|
||||
@@ -149,6 +150,8 @@ BitmapEx const & ImplImage::getBitmapEx(bool bDisabled)
|
||||
return maBitmapEx;
|
||||
}
|
||||
|
||||
void ImplImage::SetOptional(bool bValue) { bOptional = bValue; }
|
||||
|
||||
bool ImplImage::isEqual(const ImplImage &ref) const
|
||||
{
|
||||
if (isStock() != ref.isStock())
|
||||
|
||||
Reference in New Issue
Block a user