office-gobmx/sdext/source/presenter/PresenterTheme.cxx
Mike Kaganski 8a017d25a6 Avoid COW overhead using css::uno::Sequence
The scenarios are:

1. Calling sequence's begin() and end() in pairs to pass to algorithms
   (both calls use getArray(), which does the COW checks)
2. In addition to #1, calling end() again when checking result of find
   algorithms, and/or begin() to calculate result's distance
3. Using non-const sequences in range-based for loops, which internally
   do #1
4. Assigning sequence to another sequence variable, and then modifying
   one of them

In many cases, the sequences could be made const, or treated as const
for the purposes of the algorithms (using std::as_const, std::cbegin,
and std::cend). Where algorithm modifies the sequence, it was changed
to only call getArray() once. For that, css::uno::toNonConstRange was
introduced, which returns a struct (sublclass of std::pair) with two
iterators [begin, end], that are calculated using one call to begin()
and one call to getLength().

To handle #4, css::uno::Sequence::swap was introduced, that swaps the
internal pointer to uno_Sequence. So when a local Sequence variable
should be assigned to another variable, and the latter will be modified
further, it's now possible to use swap instead, so the two sequences
are kept independent.

The modified places were found by temporarily removing non-const end().

Change-Id: I8fe2787f200eecb70744e8b77fbdf7a49653f628
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123542
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
2021-10-14 06:00:49 +02:00

1060 lines
32 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 "PresenterTheme.hxx"
#include "PresenterBitmapContainer.hxx"
#include "PresenterCanvasHelper.hxx"
#include "PresenterConfigurationAccess.hxx"
#include <com/sun/star/drawing/XPresenterHelper.hpp>
#include <com/sun/star/rendering/PanoseWeight.hpp>
#include <osl/diagnose.h>
#include <map>
#include <numeric>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::std;
namespace sdext::presenter {
namespace {
class BorderSize
{
public:
const static sal_Int32 mnInvalidValue = -10000;
BorderSize() : mnLeft(mnInvalidValue),
mnTop(mnInvalidValue),
mnRight(mnInvalidValue),
mnBottom(mnInvalidValue) {}
sal_Int32 mnLeft;
sal_Int32 mnTop;
sal_Int32 mnRight;
sal_Int32 mnBottom;
vector<sal_Int32> ToVector()
{
return
{
mnLeft == mnInvalidValue ? 0 : mnLeft,
mnTop == mnInvalidValue ? 0 : mnTop,
mnRight == mnInvalidValue ? 0 : mnRight,
mnBottom == mnInvalidValue ? 0 : mnBottom
};
};
void Merge (const BorderSize& rBorderSize)
{
if (mnLeft == mnInvalidValue)
mnLeft = rBorderSize.mnLeft;
if (mnTop == mnInvalidValue)
mnTop = rBorderSize.mnTop;
if (mnRight == mnInvalidValue)
mnRight = rBorderSize.mnRight;
if (mnBottom == mnInvalidValue)
mnBottom = rBorderSize.mnBottom;
}
};
/** Reading a theme from the configurations is done in various classes. The
ReadContext gives access to frequently used objects and functions to make
the configuration handling easier.
*/
class ReadContext
{
public:
Reference<XComponentContext> mxComponentContext;
Reference<rendering::XCanvas> mxCanvas;
Reference<drawing::XPresenterHelper> mxPresenterHelper;
ReadContext (
const Reference<XComponentContext>& rxContext,
const Reference<rendering::XCanvas>& rxCanvas);
/** Read data describing a font from the node that can be reached from
the given root via the given path.
@param rsFontPath
May be empty.
*/
static PresenterTheme::SharedFontDescriptor ReadFont (
const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme,
const PresenterTheme::SharedFontDescriptor& rpDefault);
static PresenterTheme::SharedFontDescriptor ReadFont (
const Reference<beans::XPropertySet>& rxFontProperties,
const PresenterTheme::SharedFontDescriptor& rpDefault);
std::shared_ptr<PresenterTheme::Theme> ReadTheme (
PresenterConfigurationAccess& rConfiguration,
const OUString& rsThemeName);
static BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode);
private:
static Any GetByName (
const Reference<container::XNameAccess>& rxNode,
const OUString& rsName);
};
/** A PaneStyle describes how a pane is rendered.
*/
class PaneStyle
{
public:
PaneStyle();
SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
OUString msStyleName;
std::shared_ptr<PaneStyle> mpParentStyle;
PresenterTheme::SharedFontDescriptor mpFont;
BorderSize maInnerBorderSize;
BorderSize maOuterBorderSize;
std::shared_ptr<PresenterBitmapContainer> mpBitmaps;
PresenterTheme::SharedFontDescriptor GetFont() const;
};
typedef std::shared_ptr<PaneStyle> SharedPaneStyle;
class PaneStyleContainer
{
private:
::std::vector<SharedPaneStyle> mStyles;
public:
void Read (
const ReadContext& rReadContext,
const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
private:
void ProcessPaneStyle (
ReadContext const & rReadContext,
const ::std::vector<css::uno::Any>& rValues);
};
/** A ViewStyle describes how a view is displayed.
*/
class ViewStyle
{
public:
ViewStyle();
SharedBitmapDescriptor GetBitmap (std::u16string_view sBitmapName) const;
PresenterTheme::SharedFontDescriptor GetFont() const;
OUString msStyleName;
std::shared_ptr<ViewStyle> mpParentStyle;
PresenterTheme::SharedFontDescriptor mpFont;
SharedBitmapDescriptor mpBackground;
};
typedef std::shared_ptr<ViewStyle> SharedViewStyle;
class ViewStyleContainer
{
private:
::std::vector<SharedViewStyle> mStyles;
public:
void Read (
const ReadContext& rReadContext,
const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
private:
void ProcessViewStyle(
ReadContext const & rReadContext,
const Reference<beans::XPropertySet>& rxProperties);
};
class StyleAssociationContainer
{
public:
void Read (
const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
OUString GetStyleName (const OUString& rsResourceName) const;
private:
typedef map<OUString, OUString> StyleAssociations;
StyleAssociations maStyleAssociations;
void ProcessStyleAssociation(
const ::std::vector<css::uno::Any>& rValues);
};
} // end of anonymous namespace
class PresenterTheme::Theme
{
public:
Theme (
const Reference<container::XHierarchicalNameAccess>& rThemeRoot,
const OUString& rsNodeName);
void Read (
PresenterConfigurationAccess& rConfiguration,
ReadContext& rReadContext);
OUString msConfigurationNodeName;
std::shared_ptr<Theme> mpParentTheme;
SharedBitmapDescriptor mpBackground;
PaneStyleContainer maPaneStyles;
ViewStyleContainer maViewStyles;
StyleAssociationContainer maStyleAssociations;
Reference<container::XHierarchicalNameAccess> mxThemeRoot;
std::shared_ptr<PresenterBitmapContainer> mpIconContainer;
typedef map<OUString,SharedFontDescriptor> FontContainer;
FontContainer maFontContainer;
SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
private:
void ProcessFont(
const OUString& rsKey,
const Reference<beans::XPropertySet>& rxProperties);
};
//===== PresenterTheme ========================================================
PresenterTheme::PresenterTheme (
const css::uno::Reference<css::uno::XComponentContext>& rxContext,
const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
: mxContext(rxContext),
mxCanvas(rxCanvas)
{
mpTheme = ReadTheme();
}
PresenterTheme::~PresenterTheme()
{
}
std::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme()
{
ReadContext aReadContext(mxContext, mxCanvas);
PresenterConfigurationAccess aConfiguration (
mxContext,
"/org.openoffice.Office.PresenterScreen/",
PresenterConfigurationAccess::READ_ONLY);
return aReadContext.ReadTheme(aConfiguration, OUString());
}
bool PresenterTheme::HasCanvas() const
{
return mxCanvas.is();
}
void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas)
{
if ( ! mxCanvas.is() && rxCanvas.is())
{
mxCanvas = rxCanvas;
ReadTheme();
}
}
OUString PresenterTheme::GetStyleName (const OUString& rsResourceURL) const
{
OUString sStyleName;
std::shared_ptr<Theme> pTheme (mpTheme);
while (sStyleName.isEmpty() && pTheme != nullptr)
{
sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL);
pTheme = pTheme->mpParentTheme;
}
return sStyleName;
}
::std::vector<sal_Int32> PresenterTheme::GetBorderSize (
const OUString& rsStyleName,
const bool bOuter) const
{
OSL_ASSERT(mpTheme != nullptr);
SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
if (pPaneStyle)
if (bOuter)
return pPaneStyle->maOuterBorderSize.ToVector();
else
return pPaneStyle->maInnerBorderSize.ToVector();
else
{
return ::std::vector<sal_Int32>(4,0);
}
}
PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont (
const Reference<container::XHierarchicalNameAccess>& rxNode,
const PresenterTheme::SharedFontDescriptor& rpDefault)
{
return ReadContext::ReadFont(rxNode, rpDefault);
}
bool PresenterTheme::ConvertToColor (
const Any& rColorSequence,
sal_uInt32& rColor)
{
Sequence<sal_Int8> aByteSequence;
if (rColorSequence >>= aByteSequence)
{
rColor = std::accumulate(std::cbegin(aByteSequence), std::cend(aByteSequence), sal_uInt32(0),
[](const sal_uInt32 nRes, const sal_uInt8 nByte) { return (nRes << 8) | nByte; });
return true;
}
else
return false;
}
std::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle (
const OUString& rsStyleName) const
{
if (mpTheme == nullptr)
return std::shared_ptr<PresenterConfigurationAccess>();
// Open configuration for writing.
auto pConfiguration = std::make_shared<PresenterConfigurationAccess>(
mxContext,
"/org.openoffice.Office.PresenterScreen/",
PresenterConfigurationAccess::READ_WRITE);
// Get configuration node for the view style container of the current
// theme.
if (pConfiguration->GoToChild( OUString(
"Presenter/Themes/" + mpTheme->msConfigurationNodeName + "/ViewStyles")))
{
pConfiguration->GoToChild(
[&rsStyleName] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
{
return PresenterConfigurationAccess::IsStringPropertyEqual(
rsStyleName, "StyleName", xProps);
});
}
return pConfiguration;
}
SharedBitmapDescriptor PresenterTheme::GetBitmap (
const OUString& rsStyleName,
const OUString& rsBitmapName) const
{
if (mpTheme != nullptr)
{
if (rsStyleName.isEmpty())
{
if (rsBitmapName == "Background")
{
std::shared_ptr<Theme> pTheme (mpTheme);
while (pTheme != nullptr && !pTheme->mpBackground)
pTheme = pTheme->mpParentTheme;
if (pTheme != nullptr)
return pTheme->mpBackground;
else
return SharedBitmapDescriptor();
}
}
else
{
SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
if (pPaneStyle)
{
SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
if (pBitmap)
return pBitmap;
}
SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
if (pViewStyle)
{
SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
if (pBitmap)
return pBitmap;
}
}
}
return SharedBitmapDescriptor();
}
SharedBitmapDescriptor PresenterTheme::GetBitmap (
const OUString& rsBitmapName) const
{
if (mpTheme != nullptr)
{
if (rsBitmapName == "Background")
{
std::shared_ptr<Theme> pTheme (mpTheme);
while (pTheme != nullptr && !pTheme->mpBackground)
pTheme = pTheme->mpParentTheme;
if (pTheme != nullptr)
return pTheme->mpBackground;
else
return SharedBitmapDescriptor();
}
else
{
if (mpTheme->mpIconContainer != nullptr)
return mpTheme->mpIconContainer->GetBitmap(rsBitmapName);
}
}
return SharedBitmapDescriptor();
}
std::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer() const
{
if (mpTheme != nullptr)
return mpTheme->mpIconContainer;
else
return std::shared_ptr<PresenterBitmapContainer>();
}
PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont (
const OUString& rsStyleName) const
{
if (mpTheme != nullptr)
{
SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
if (pPaneStyle)
return pPaneStyle->GetFont();
SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
if (pViewStyle)
return pViewStyle->GetFont();
std::shared_ptr<Theme> pTheme (mpTheme);
while (pTheme != nullptr)
{
Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName));
if (iFont != pTheme->maFontContainer.end())
return iFont->second;
pTheme = pTheme->mpParentTheme;
}
}
return SharedFontDescriptor();
}
//===== FontDescriptor ========================================================
PresenterTheme::FontDescriptor::FontDescriptor (
const std::shared_ptr<FontDescriptor>& rpDescriptor)
: mnSize(12),
mnColor(0x00000000),
msAnchor(OUString("Left")),
mnXOffset(0),
mnYOffset(0)
{
if (rpDescriptor != nullptr)
{
msFamilyName = rpDescriptor->msFamilyName;
msStyleName = rpDescriptor->msStyleName;
mnSize = rpDescriptor->mnSize;
mnColor = rpDescriptor->mnColor;
msAnchor = rpDescriptor->msAnchor;
mnXOffset = rpDescriptor->mnXOffset;
mnYOffset = rpDescriptor->mnYOffset;
}
}
bool PresenterTheme::FontDescriptor::PrepareFont (
const Reference<rendering::XCanvas>& rxCanvas)
{
if (mxFont.is())
return true;
if ( ! rxCanvas.is())
return false;
const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize));
mxFont = CreateFont(rxCanvas, nCellSize);
return mxFont.is();
}
Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont (
const Reference<rendering::XCanvas>& rxCanvas,
const double nCellSize) const
{
rendering::FontRequest aFontRequest;
aFontRequest.FontDescription.FamilyName = msFamilyName;
if (msFamilyName.isEmpty())
aFontRequest.FontDescription.FamilyName = "Tahoma";
aFontRequest.FontDescription.StyleName = msStyleName;
aFontRequest.CellSize = nCellSize;
// Make an attempt at translating the style name(s)into a corresponding
// font description.
if (msStyleName == "Bold")
aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY;
return rxCanvas->createFont(
aFontRequest,
Sequence<beans::PropertyValue>(),
geometry::Matrix2D(1,0,0,1));
}
double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize (
const Reference<rendering::XCanvas>& rxCanvas,
const double nDesignSize) const
{
// Use the given design size as initial value in calculating the cell
// size.
double nCellSize (nDesignSize);
if ( ! rxCanvas.is())
{
// We need the canvas to do the conversion. Return the design size,
// it is the our best guess in this circumstance.
return nDesignSize;
}
Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize));
if ( ! xFont.is())
return nDesignSize;
geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X"));
const double nAscent (-aBox.Y1);
//tdf#112408
if (nAscent == 0)
return nDesignSize;
const double nDescent (aBox.Y2);
const double nScale = (nAscent+nDescent) / nAscent;
return nDesignSize * nScale;
}
//===== Theme =================================================================
PresenterTheme::Theme::Theme (
const Reference<container::XHierarchicalNameAccess>& rxThemeRoot,
const OUString& rsNodeName)
: msConfigurationNodeName(rsNodeName),
maPaneStyles(),
maViewStyles(),
maStyleAssociations(),
mxThemeRoot(rxThemeRoot)
{
}
void PresenterTheme::Theme::Read (
PresenterConfigurationAccess& rConfiguration,
ReadContext& rReadContext)
{
// Parent theme name.
OUString sParentThemeName;
if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ParentTheme")
>>= sParentThemeName)
&& !sParentThemeName.isEmpty())
{
mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName);
}
// Background.
mpBackground = PresenterBitmapContainer::LoadBitmap(
mxThemeRoot,
"Background",
rReadContext.mxPresenterHelper,
rReadContext.mxCanvas,
SharedBitmapDescriptor());
// Style associations.
maStyleAssociations.Read(mxThemeRoot);
// Pane styles.
maPaneStyles.Read(rReadContext, mxThemeRoot);
// View styles.
maViewStyles.Read(rReadContext, mxThemeRoot);
// Read bitmaps.
mpIconContainer = std::make_shared<PresenterBitmapContainer>(
Reference<container::XNameAccess>(
PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"), UNO_QUERY),
mpParentTheme != nullptr ? mpParentTheme->mpIconContainer
: std::shared_ptr<PresenterBitmapContainer>(),
rReadContext.mxComponentContext, rReadContext.mxCanvas);
// Read fonts.
Reference<container::XNameAccess> xFontNode(
PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Fonts"),
UNO_QUERY);
PresenterConfigurationAccess::ForAll(
xFontNode,
[this] (OUString const& rKey, uno::Reference<beans::XPropertySet> const& xProps)
{
return this->ProcessFont(rKey, xProps);
});
}
SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
{
SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName));
if (pPaneStyle)
return pPaneStyle;
else if (mpParentTheme != nullptr)
return mpParentTheme->GetPaneStyle(rsStyleName);
else
return SharedPaneStyle();
}
SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
{
SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName));
if (pViewStyle)
return pViewStyle;
else if (mpParentTheme != nullptr)
return mpParentTheme->GetViewStyle(rsStyleName);
else
return SharedViewStyle();
}
void PresenterTheme::Theme::ProcessFont(
const OUString& rsKey,
const Reference<beans::XPropertySet>& rxProperties)
{
maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor());
}
namespace {
//===== ReadContext ===========================================================
ReadContext::ReadContext (
const css::uno::Reference<css::uno::XComponentContext>& rxContext,
const Reference<rendering::XCanvas>& rxCanvas)
: mxComponentContext(rxContext),
mxCanvas(rxCanvas)
{
Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
if (xFactory.is())
{
mxPresenterHelper.set(
xFactory->createInstanceWithContext(
"com.sun.star.comp.Draw.PresenterHelper",
rxContext),
UNO_QUERY_THROW);
}
}
PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
const Reference<container::XHierarchicalNameAccess>& rxNode,
const PresenterTheme::SharedFontDescriptor& rpDefault)
{
if ( ! rxNode.is())
return PresenterTheme::SharedFontDescriptor();
try
{
Reference<container::XHierarchicalNameAccess> xFont (
PresenterConfigurationAccess::GetConfigurationNode(
rxNode,
/*rsFontPath*/""),
UNO_QUERY_THROW);
Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
return ReadFont(xProperties, rpDefault);
}
catch (Exception&)
{
OSL_ASSERT(false);
}
return PresenterTheme::SharedFontDescriptor();
}
PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
const Reference<beans::XPropertySet>& rxProperties,
const PresenterTheme::SharedFontDescriptor& rpDefault)
{
auto pDescriptor = std::make_shared<PresenterTheme::FontDescriptor>(rpDefault);
PresenterConfigurationAccess::GetProperty(rxProperties, "FamilyName") >>= pDescriptor->msFamilyName;
PresenterConfigurationAccess::GetProperty(rxProperties, "Style") >>= pDescriptor->msStyleName;
PresenterConfigurationAccess::GetProperty(rxProperties, "Size") >>= pDescriptor->mnSize;
PresenterTheme::ConvertToColor(
PresenterConfigurationAccess::GetProperty(rxProperties, "Color"),
pDescriptor->mnColor);
PresenterConfigurationAccess::GetProperty(rxProperties, "Anchor") >>= pDescriptor->msAnchor;
PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pDescriptor->mnXOffset;
PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pDescriptor->mnYOffset;
return pDescriptor;
}
Any ReadContext::GetByName (
const Reference<container::XNameAccess>& rxNode,
const OUString& rsName)
{
OSL_ASSERT(rxNode.is());
if (rxNode->hasByName(rsName))
return rxNode->getByName(rsName);
else
return Any();
}
std::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
PresenterConfigurationAccess& rConfiguration,
const OUString& rsThemeName)
{
std::shared_ptr<PresenterTheme::Theme> pTheme;
OUString sCurrentThemeName (rsThemeName);
if (sCurrentThemeName.isEmpty())
{
// No theme name given. Look up the CurrentTheme property.
rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName;
if (sCurrentThemeName.isEmpty())
{
// Still no name. Use "DefaultTheme".
sCurrentThemeName = "DefaultTheme";
}
}
Reference<container::XNameAccess> xThemes (
rConfiguration.GetConfigurationNode("Presenter/Themes"),
UNO_QUERY);
if (xThemes.is())
{
// Iterate over all themes and search the one with the given name.
const Sequence<OUString> aKeys (xThemes->getElementNames());
for (const OUString& rsKey : aKeys)
{
Reference<container::XHierarchicalNameAccess> xTheme (
xThemes->getByName(rsKey), UNO_QUERY);
if (xTheme.is())
{
OUString sThemeName;
PresenterConfigurationAccess::GetConfigurationNode(xTheme, "ThemeName")
>>= sThemeName;
if (sThemeName == sCurrentThemeName)
{
pTheme = std::make_shared<PresenterTheme::Theme>(xTheme,rsKey);
break;
}
}
}
}
if (pTheme != nullptr)
{
pTheme->Read(rConfiguration, *this);
}
return pTheme;
}
BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
{
BorderSize aBorderSize;
if (rxNode.is())
{
GetByName(rxNode, "Left") >>= aBorderSize.mnLeft;
GetByName(rxNode, "Top") >>= aBorderSize.mnTop;
GetByName(rxNode, "Right") >>= aBorderSize.mnRight;
GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom;
}
return aBorderSize;
}
//===== PaneStyleContainer ====================================================
void PaneStyleContainer::Read (
const ReadContext& rReadContext,
const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
{
Reference<container::XNameAccess> xPaneStyleList (
PresenterConfigurationAccess::GetConfigurationNode(
rxThemeRoot,
"PaneStyles"),
UNO_QUERY);
if (!xPaneStyleList.is())
return;
::std::vector<OUString> aProperties;
aProperties.reserve(6);
aProperties.emplace_back("StyleName");
aProperties.emplace_back("ParentStyle");
aProperties.emplace_back("TitleFont");
aProperties.emplace_back("InnerBorderSize");
aProperties.emplace_back("OuterBorderSize");
aProperties.emplace_back("BorderBitmapList");
PresenterConfigurationAccess::ForAll(
xPaneStyleList,
aProperties,
[this, &rReadContext] (std::vector<uno::Any> const& rValues)
{
return this->ProcessPaneStyle(rReadContext, rValues);
});
}
void PaneStyleContainer::ProcessPaneStyle(
ReadContext const & rReadContext,
const ::std::vector<Any>& rValues)
{
if (rValues.size() != 6)
return;
auto pStyle = std::make_shared<PaneStyle>();
rValues[0] >>= pStyle->msStyleName;
OUString sParentStyleName;
if (rValues[1] >>= sParentStyleName)
{
// Find parent style.
auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
[&sParentStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
if (iStyle != mStyles.end())
pStyle->mpParentStyle = *iStyle;
}
Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
pStyle->mpFont = ReadContext::ReadFont(
xFontNode, PresenterTheme::SharedFontDescriptor());
Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY);
pStyle->maInnerBorderSize = ReadContext::ReadBorderSize(xInnerBorderSizeNode);
Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY);
pStyle->maOuterBorderSize = ReadContext::ReadBorderSize(xOuterBorderSizeNode);
if (pStyle->mpParentStyle != nullptr)
{
pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
}
if (rReadContext.mxCanvas.is())
{
Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY);
pStyle->mpBitmaps = std::make_shared<PresenterBitmapContainer>(
xBitmapsNode,
pStyle->mpParentStyle != nullptr ? pStyle->mpParentStyle->mpBitmaps
: std::shared_ptr<PresenterBitmapContainer>(),
rReadContext.mxComponentContext, rReadContext.mxCanvas,
rReadContext.mxPresenterHelper);
}
mStyles.push_back(pStyle);
}
SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
{
auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
[&rsStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
if (iStyle != mStyles.end())
return *iStyle;
return SharedPaneStyle();
}
//===== PaneStyle =============================================================
PaneStyle::PaneStyle()
{
}
SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
{
if (mpBitmaps != nullptr)
{
SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
if (pBitmap)
return pBitmap;
}
if (mpParentStyle != nullptr)
return mpParentStyle->GetBitmap(rsBitmapName);
else
return SharedBitmapDescriptor();
}
PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const
{
if (mpFont)
return mpFont;
else if (mpParentStyle != nullptr)
return mpParentStyle->GetFont();
else
return PresenterTheme::SharedFontDescriptor();
}
//===== ViewStyleContainer ====================================================
void ViewStyleContainer::Read (
const ReadContext& rReadContext,
const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
{
Reference<container::XNameAccess> xViewStyleList (
PresenterConfigurationAccess::GetConfigurationNode(
rxThemeRoot,
"ViewStyles"),
UNO_QUERY);
if (xViewStyleList.is())
{
PresenterConfigurationAccess::ForAll(
xViewStyleList,
[this, &rReadContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
{
return this->ProcessViewStyle(rReadContext, xProps);
});
}
}
void ViewStyleContainer::ProcessViewStyle(
ReadContext const & rReadContext,
const Reference<beans::XPropertySet>& rxProperties)
{
auto pStyle = std::make_shared<ViewStyle>();
PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName")
>>= pStyle->msStyleName;
OUString sParentStyleName;
if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle")
>>= sParentStyleName)
{
// Find parent style.
auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
[&sParentStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
if (iStyle != mStyles.end())
{
pStyle->mpParentStyle = *iStyle;
pStyle->mpFont = (*iStyle)->mpFont;
pStyle->mpBackground = (*iStyle)->mpBackground;
}
}
Reference<container::XHierarchicalNameAccess> xFontNode (
PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY);
PresenterTheme::SharedFontDescriptor pFont (
ReadContext::ReadFont(xFontNode, PresenterTheme::SharedFontDescriptor()));
if (pFont)
pStyle->mpFont = pFont;
Reference<container::XHierarchicalNameAccess> xBackgroundNode (
PresenterConfigurationAccess::GetProperty(rxProperties, "Background"),
UNO_QUERY);
SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap(
xBackgroundNode,
OUString(),
rReadContext.mxPresenterHelper,
rReadContext.mxCanvas,
SharedBitmapDescriptor()));
if (pBackground && pBackground->GetNormalBitmap().is())
pStyle->mpBackground = pBackground;
mStyles.push_back(pStyle);
}
SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
{
auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
[&rsStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
if (iStyle != mStyles.end())
return *iStyle;
return SharedViewStyle();
}
//===== ViewStyle =============================================================
ViewStyle::ViewStyle()
{
}
SharedBitmapDescriptor ViewStyle::GetBitmap (std::u16string_view rsBitmapName) const
{
if (rsBitmapName == u"Background")
return mpBackground;
else
return SharedBitmapDescriptor();
}
PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const
{
if (mpFont)
return mpFont;
else if (mpParentStyle != nullptr)
return mpParentStyle->GetFont();
else
return PresenterTheme::SharedFontDescriptor();
}
//===== StyleAssociationContainer =============================================
void StyleAssociationContainer::Read (
const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
{
Reference<container::XNameAccess> xStyleAssociationList (
PresenterConfigurationAccess::GetConfigurationNode(
rxThemeRoot,
"StyleAssociations"),
UNO_QUERY);
if (!xStyleAssociationList.is())
return;
::std::vector<OUString> aProperties { "ResourceURL", "StyleName" };
PresenterConfigurationAccess::ForAll(
xStyleAssociationList,
aProperties,
[this] (std::vector<uno::Any> const& rValues)
{
return this->ProcessStyleAssociation(rValues);
});
}
OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
{
StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
if (iAssociation != maStyleAssociations.end())
return iAssociation->second;
else
return OUString();
}
void StyleAssociationContainer::ProcessStyleAssociation(
const ::std::vector<Any>& rValues)
{
if (rValues.size() != 2)
return;
OUString sResourceURL;
OUString sStyleName;
if ((rValues[0] >>= sResourceURL)
&& (rValues[1] >>= sStyleName))
{
maStyleAssociations[sResourceURL] = sStyleName;
}
}
} // end of anonymous namespace
} // end of namespace ::sdext::presenter
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */