/* -*- 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 "PresenterHelper.hxx" #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::std; namespace sdext { namespace 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 ToVector() { vector aSequence (4); aSequence[0] = mnLeft == mnInvalidValue ? 0 : mnLeft; aSequence[1] = mnTop == mnInvalidValue ? 0 : mnTop; aSequence[2] = mnRight == mnInvalidValue ? 0 : mnRight; aSequence[3] = mnBottom == mnInvalidValue ? 0 : mnBottom; return aSequence; }; 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 mxComponentContext; Reference mxCanvas; Reference mxPresenterHelper; ReadContext ( const Reference& rxContext, const Reference& rxCanvas); ~ReadContext(); /** 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& rxTheme, const OUString& rsFontPath, const PresenterTheme::SharedFontDescriptor& rpDefault); static PresenterTheme::SharedFontDescriptor ReadFont ( const Reference& rxFontProperties, const PresenterTheme::SharedFontDescriptor& rpDefault); std::shared_ptr ReadTheme ( PresenterConfigurationAccess& rConfiguration, const OUString& rsThemeName); static BorderSize ReadBorderSize (const Reference& rxNode); private: static Any GetByName ( const Reference& rxNode, const OUString& rsName); }; /** A PaneStyle describes how a pane is rendered. */ class PaneStyle { public: PaneStyle(); ~PaneStyle(); const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const; OUString msStyleName; std::shared_ptr mpParentStyle; PresenterTheme::SharedFontDescriptor mpFont; BorderSize maInnerBorderSize; BorderSize maOuterBorderSize; std::shared_ptr mpBitmaps; PresenterTheme::SharedFontDescriptor GetFont() const; }; typedef std::shared_ptr SharedPaneStyle; class PaneStyleContainer { private: ::std::vector mStyles; public: void Read ( ReadContext& rReadContext, const Reference& rThemeRoot); SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const; private: void ProcessPaneStyle ( ReadContext& rReadContext, const OUString& rsKey, const ::std::vector& rValues); }; /** A ViewStyle describes how a view is displayed. */ class ViewStyle { public: ViewStyle(); ~ViewStyle(); const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const; PresenterTheme::SharedFontDescriptor GetFont() const; OUString msStyleName; std::shared_ptr mpParentStyle; PresenterTheme::SharedFontDescriptor mpFont; std::shared_ptr mpBitmaps; SharedBitmapDescriptor mpBackground; }; typedef std::shared_ptr SharedViewStyle; class ViewStyleContainer { private: ::std::vector mStyles; public: void Read ( ReadContext& rReadContext, const Reference& rThemeRoot); SharedViewStyle GetViewStyle (const OUString& rsStyleName) const; private: void ProcessViewStyle( ReadContext& rReadContext, const Reference& rxProperties); }; class ViewDescriptor { }; typedef std::shared_ptr SharedViewDescriptor; typedef ::std::vector ViewDescriptorContainer; class StyleAssociationContainer { public: void Read ( ReadContext& rReadContext, const Reference& rThemeRoot); OUString GetStyleName (const OUString& rsResourceName) const; private: typedef map StyleAssociations; StyleAssociations maStyleAssociations; void ProcessStyleAssociation( ReadContext& rReadContext, const OUString& rsKey, const ::std::vector& rValues); }; } // end of anonymous namespace class PresenterTheme::Theme { public: Theme ( const OUString& rsName, const Reference& rThemeRoot, const OUString& rsNodeName); ~Theme(); void Read ( PresenterConfigurationAccess& rConfiguration, ReadContext& rReadContext); OUString msThemeName; OUString msConfigurationNodeName; std::shared_ptr mpParentTheme; SharedBitmapDescriptor mpBackground; PaneStyleContainer maPaneStyles; ViewStyleContainer maViewStyles; StyleAssociationContainer maStyleAssociations; Reference mxThemeRoot; std::shared_ptr mpIconContainer; typedef map FontContainer; FontContainer maFontContainer; SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const; SharedViewStyle GetViewStyle (const OUString& rsStyleName) const; private: void ProcessFont( ReadContext& rReadContext, const OUString& rsKey, const Reference& rxProperties); }; //===== PresenterTheme ======================================================== PresenterTheme::PresenterTheme ( const css::uno::Reference& rxContext, const OUString& rsThemeName, const css::uno::Reference& rxCanvas) : mxContext(rxContext), msThemeName(rsThemeName), mpTheme(), mpBitmapContainer(), mxCanvas(rxCanvas) { mpTheme = ReadTheme(); } PresenterTheme::~PresenterTheme() { } std::shared_ptr PresenterTheme::ReadTheme() { ReadContext aReadContext(mxContext, mxCanvas); PresenterConfigurationAccess aConfiguration ( mxContext, OUString("/org.openoffice.Office.PresenterScreen/"), PresenterConfigurationAccess::READ_ONLY); return aReadContext.ReadTheme(aConfiguration, msThemeName); } bool PresenterTheme::HasCanvas() const { return mxCanvas.is(); } void PresenterTheme::ProvideCanvas (const Reference& rxCanvas) { if ( ! mxCanvas.is() && rxCanvas.is()) { mxCanvas = rxCanvas; ReadTheme(); } } OUString PresenterTheme::GetStyleName (const OUString& rsResourceURL) const { OUString sStyleName; std::shared_ptr pTheme (mpTheme); while (sStyleName.isEmpty() && pTheme.get()!=nullptr) { sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL); pTheme = pTheme->mpParentTheme; } return sStyleName; } ::std::vector PresenterTheme::GetBorderSize ( const OUString& rsStyleName, const bool bOuter) const { OSL_ASSERT(mpTheme.get() != nullptr); SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); if (pPaneStyle.get() != nullptr) if (bOuter) return pPaneStyle->maOuterBorderSize.ToVector(); else return pPaneStyle->maInnerBorderSize.ToVector(); else { return ::std::vector(4,0); } } PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont ( const Reference& rxNode, const OUString& rsFontPath, const PresenterTheme::SharedFontDescriptor& rpDefault) { return ReadContext::ReadFont(rxNode, rsFontPath, rpDefault); } bool PresenterTheme::ConvertToColor ( const Any& rColorSequence, sal_uInt32& rColor) { Sequence aByteSequence; if (rColorSequence >>= aByteSequence) { const sal_Int32 nByteCount (aByteSequence.getLength()); const sal_uInt8* pArray = reinterpret_cast(aByteSequence.getConstArray()); rColor = 0; for (sal_Int32 nIndex=0; nIndex PresenterTheme::GetNodeForViewStyle ( const OUString& rsStyleName) const { if (mpTheme.get() == nullptr) return std::shared_ptr(); // Open configuration for writing. std::shared_ptr pConfiguration ( new PresenterConfigurationAccess( mxContext, OUString("/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( ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual, rsStyleName, OUString("StyleName"), _2)); } return pConfiguration; } SharedBitmapDescriptor PresenterTheme::GetBitmap ( const OUString& rsStyleName, const OUString& rsBitmapName) const { if (mpTheme.get() != nullptr) { if (rsStyleName.isEmpty()) { if (rsBitmapName == "Background") { std::shared_ptr pTheme (mpTheme); while (pTheme.get()!=nullptr && pTheme->mpBackground.get()==nullptr) pTheme = pTheme->mpParentTheme; if (pTheme.get() != nullptr) return pTheme->mpBackground; else return SharedBitmapDescriptor(); } } else { SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); if (pPaneStyle.get() != nullptr) { SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName)); if (pBitmap.get() != nullptr) return pBitmap; } SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); if (pViewStyle.get() != nullptr) { SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName)); if (pBitmap.get() != nullptr) return pBitmap; } } } return SharedBitmapDescriptor(); } SharedBitmapDescriptor PresenterTheme::GetBitmap ( const OUString& rsBitmapName) const { if (mpTheme.get() != nullptr) { if (rsBitmapName == "Background") { std::shared_ptr pTheme (mpTheme); while (pTheme.get()!=nullptr && pTheme->mpBackground.get()==nullptr) pTheme = pTheme->mpParentTheme; if (pTheme.get() != nullptr) return pTheme->mpBackground; else return SharedBitmapDescriptor(); } else { if (mpTheme->mpIconContainer.get() != nullptr) return mpTheme->mpIconContainer->GetBitmap(rsBitmapName); } } return SharedBitmapDescriptor(); } std::shared_ptr PresenterTheme::GetBitmapContainer() const { if (mpTheme.get() != nullptr) return mpTheme->mpIconContainer; else return std::shared_ptr(); } PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont ( const OUString& rsStyleName) const { if (mpTheme.get() != nullptr) { SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); if (pPaneStyle.get() != nullptr) return pPaneStyle->GetFont(); SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); if (pViewStyle.get() != nullptr) return pViewStyle->GetFont(); std::shared_ptr pTheme (mpTheme); while (pTheme.get() != 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& rpDescriptor) : msFamilyName(), msStyleName(), mnSize(12), mnColor(0x00000000), msAnchor(OUString("Left")), mnXOffset(0), mnYOffset(0) { if (rpDescriptor.get() != 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& 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 PresenterTheme::FontDescriptor::CreateFont ( const Reference& 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(), geometry::Matrix2D(1,0,0,1)); } double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize ( const Reference& 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 xFont (CreateFont(rxCanvas, nCellSize)); if ( ! xFont.is()) return nDesignSize; geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X")); const double nAscent (-aBox.Y1); const double nDescent (aBox.Y2); const double nScale = (nAscent+nDescent) / nAscent; return nDesignSize * nScale; } //===== Theme ================================================================= PresenterTheme::Theme::Theme ( const OUString& rsName, const Reference& rxThemeRoot, const OUString& rsNodeName) : msThemeName(rsName), msConfigurationNodeName(rsNodeName), mpParentTheme(), maPaneStyles(), maViewStyles(), maStyleAssociations(), mxThemeRoot(rxThemeRoot), mpIconContainer() { } PresenterTheme::Theme::~Theme() { } void PresenterTheme::Theme::Read ( PresenterConfigurationAccess& rConfiguration, ReadContext& rReadContext) { PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ThemeName") >>= msThemeName; // 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(rReadContext, mxThemeRoot); // Pane styles. maPaneStyles.Read(rReadContext, mxThemeRoot); // View styles. maViewStyles.Read(rReadContext, mxThemeRoot); // Read bitmaps. mpIconContainer.reset( new PresenterBitmapContainer( Reference( PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"), UNO_QUERY), mpParentTheme.get()!=nullptr ? mpParentTheme->mpIconContainer : std::shared_ptr(), rReadContext.mxComponentContext, rReadContext.mxCanvas)); // Read fonts. Reference xFontNode( PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Fonts"), UNO_QUERY); PresenterConfigurationAccess::ForAll( xFontNode, ::boost::bind(&PresenterTheme::Theme::ProcessFont, this, ::boost::ref(rReadContext), _1, _2)); } SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const { SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName)); if (pPaneStyle.get() != nullptr) return pPaneStyle; else if (mpParentTheme.get() != nullptr) return mpParentTheme->GetPaneStyle(rsStyleName); else return SharedPaneStyle(); } SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const { SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName)); if (pViewStyle.get() != nullptr) return pViewStyle; else if (mpParentTheme.get() != nullptr) return mpParentTheme->GetViewStyle(rsStyleName); else return SharedViewStyle(); } void PresenterTheme::Theme::ProcessFont( ReadContext& rReadContext, const OUString& rsKey, const Reference& rxProperties) { (void)rReadContext; maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor()); } namespace { //===== ReadContext =========================================================== ReadContext::ReadContext ( const css::uno::Reference& rxContext, const Reference& rxCanvas) : mxComponentContext(rxContext), mxCanvas(rxCanvas), mxPresenterHelper() { Reference xFactory (rxContext->getServiceManager()); if (xFactory.is()) { mxPresenterHelper.set( xFactory->createInstanceWithContext( "com.sun.star.comp.Draw.PresenterHelper", rxContext), UNO_QUERY_THROW); } } ReadContext::~ReadContext() { } PresenterTheme::SharedFontDescriptor ReadContext::ReadFont ( const Reference& rxNode, const OUString& rsFontPath, const PresenterTheme::SharedFontDescriptor& rpDefault) { if ( ! rxNode.is()) return PresenterTheme::SharedFontDescriptor(); try { Reference xFont ( PresenterConfigurationAccess::GetConfigurationNode( rxNode, rsFontPath), UNO_QUERY_THROW); Reference xProperties (xFont, UNO_QUERY_THROW); return ReadFont(xProperties, rpDefault); } catch (Exception&) { OSL_ASSERT(false); } return PresenterTheme::SharedFontDescriptor(); } PresenterTheme::SharedFontDescriptor ReadContext::ReadFont ( const Reference& rxProperties, const PresenterTheme::SharedFontDescriptor& rpDefault) { std::shared_ptr pDescriptor ( new 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& rxNode, const OUString& rsName) { OSL_ASSERT(rxNode.is()); if (rxNode->hasByName(rsName)) return rxNode->getByName(rsName); else return Any(); } std::shared_ptr ReadContext::ReadTheme ( PresenterConfigurationAccess& rConfiguration, const OUString& rsThemeName) { std::shared_ptr 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 xThemes ( rConfiguration.GetConfigurationNode("Presenter/Themes"), UNO_QUERY); if (xThemes.is()) { // Iterate over all themes and search the one with the given name. Sequence aKeys (xThemes->getElementNames()); for (sal_Int32 nItemIndex=0; nItemIndex < aKeys.getLength(); ++nItemIndex) { const OUString& rsKey (aKeys[nItemIndex]); Reference xTheme ( xThemes->getByName(rsKey), UNO_QUERY); if (xTheme.is()) { OUString sThemeName; PresenterConfigurationAccess::GetConfigurationNode(xTheme, "ThemeName") >>= sThemeName; if (sThemeName == sCurrentThemeName) { pTheme.reset(new PresenterTheme::Theme(sThemeName,xTheme,rsKey)); break; } } } } if (pTheme.get() != nullptr) { pTheme->Read(rConfiguration, *this); } return pTheme; } BorderSize ReadContext::ReadBorderSize (const Reference& 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 ( ReadContext& rReadContext, const Reference& rxThemeRoot) { Reference xPaneStyleList ( PresenterConfigurationAccess::GetConfigurationNode( rxThemeRoot, "PaneStyles"), UNO_QUERY); if (xPaneStyleList.is()) { ::std::vector aProperties; aProperties.reserve(6); aProperties.push_back("StyleName"); aProperties.push_back("ParentStyle"); aProperties.push_back("TitleFont"); aProperties.push_back("InnerBorderSize"); aProperties.push_back("OuterBorderSize"); aProperties.push_back("BorderBitmapList"); PresenterConfigurationAccess::ForAll( xPaneStyleList, aProperties, ::boost::bind(&PaneStyleContainer::ProcessPaneStyle, this, ::boost::ref(rReadContext), _1, _2)); } } void PaneStyleContainer::ProcessPaneStyle( ReadContext& rReadContext, const OUString& rsKey, const ::std::vector& rValues) { (void)rsKey; if (rValues.size() != 6) return; std::shared_ptr pStyle (new PaneStyle()); rValues[0] >>= pStyle->msStyleName; OUString sParentStyleName; if (rValues[1] >>= sParentStyleName) { // Find parent style. ::std::vector::const_iterator iStyle; for (iStyle=mStyles.begin(); iStyle!=mStyles.end(); ++iStyle) if ((*iStyle)->msStyleName.equals(sParentStyleName)) { pStyle->mpParentStyle = *iStyle; break; } } Reference xFontNode (rValues[2], UNO_QUERY); pStyle->mpFont = ReadContext::ReadFont( xFontNode, "", PresenterTheme::SharedFontDescriptor()); Reference xInnerBorderSizeNode (rValues[3], UNO_QUERY); pStyle->maInnerBorderSize = ReadContext::ReadBorderSize(xInnerBorderSizeNode); Reference xOuterBorderSizeNode (rValues[4], UNO_QUERY); pStyle->maOuterBorderSize = ReadContext::ReadBorderSize(xOuterBorderSizeNode); if (pStyle->mpParentStyle.get() != nullptr) { pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize); pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize); } if (rReadContext.mxCanvas.is()) { Reference xBitmapsNode (rValues[5], UNO_QUERY); pStyle->mpBitmaps.reset(new PresenterBitmapContainer( xBitmapsNode, pStyle->mpParentStyle.get()!=nullptr ? pStyle->mpParentStyle->mpBitmaps : std::shared_ptr(), rReadContext.mxComponentContext, rReadContext.mxCanvas, rReadContext.mxPresenterHelper)); } mStyles.push_back(pStyle); } SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const { ::std::vector::const_iterator iEnd (mStyles.end()); for (::std::vector::const_iterator iStyle=mStyles.begin(); iStyle!=iEnd; ++iStyle) if ((*iStyle)->msStyleName == rsStyleName) return *iStyle; return SharedPaneStyle(); } //===== PaneStyle ============================================================= PaneStyle::PaneStyle() : msStyleName(), mpParentStyle(), mpFont(), maInnerBorderSize(), maOuterBorderSize(), mpBitmaps() { } PaneStyle::~PaneStyle() { } const SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const { if (mpBitmaps.get() != nullptr) { const SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName); if (pBitmap.get() != nullptr) return pBitmap; } if (mpParentStyle.get() != nullptr) return mpParentStyle->GetBitmap(rsBitmapName); else return SharedBitmapDescriptor(); } PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const { if (mpFont.get() != nullptr) return mpFont; else if (mpParentStyle.get() != nullptr) return mpParentStyle->GetFont(); else return PresenterTheme::SharedFontDescriptor(); } //===== ViewStyleContainer ==================================================== void ViewStyleContainer::Read ( ReadContext& rReadContext, const Reference& rxThemeRoot) { (void)rReadContext; Reference xViewStyleList ( PresenterConfigurationAccess::GetConfigurationNode( rxThemeRoot, "ViewStyles"), UNO_QUERY); if (xViewStyleList.is()) { PresenterConfigurationAccess::ForAll( xViewStyleList, ::boost::bind(&ViewStyleContainer::ProcessViewStyle, this, ::boost::ref(rReadContext), _2)); } } void ViewStyleContainer::ProcessViewStyle( ReadContext& rReadContext, const Reference& rxProperties) { std::shared_ptr pStyle (new ViewStyle()); PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName") >>= pStyle->msStyleName; OUString sParentStyleName; if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle") >>= sParentStyleName) { // Find parent style. ::std::vector::const_iterator iStyle; for (iStyle=mStyles.begin(); iStyle!=mStyles.end(); ++iStyle) if ((*iStyle)->msStyleName.equals(sParentStyleName)) { pStyle->mpParentStyle = *iStyle; pStyle->mpFont = (*iStyle)->mpFont; pStyle->mpBackground = (*iStyle)->mpBackground; break; } } const OUString sPathToFont; // empty string Reference xFontNode ( PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY); PresenterTheme::SharedFontDescriptor pFont ( ReadContext::ReadFont(xFontNode, sPathToFont, PresenterTheme::SharedFontDescriptor())); if (pFont.get() != nullptr) pStyle->mpFont = pFont; Reference xBackgroundNode ( PresenterConfigurationAccess::GetProperty(rxProperties, "Background"), UNO_QUERY); SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap( xBackgroundNode, OUString(), rReadContext.mxPresenterHelper, rReadContext.mxCanvas, SharedBitmapDescriptor())); if (pBackground.get() != nullptr && pBackground->GetNormalBitmap().is()) pStyle->mpBackground = pBackground; mStyles.push_back(pStyle); } SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const { ::std::vector::const_iterator iEnd (mStyles.end()); for (::std::vector::const_iterator iStyle=mStyles.begin(); iStyle!=iEnd; ++iStyle) if ((*iStyle)->msStyleName == rsStyleName) return *iStyle; return SharedViewStyle(); } //===== ViewStyle ============================================================= ViewStyle::ViewStyle() : msStyleName(), mpParentStyle(), mpFont(), mpBackground() { } ViewStyle::~ViewStyle() { } const SharedBitmapDescriptor ViewStyle::GetBitmap (const OUString& rsBitmapName) const { if (rsBitmapName == "Background") return mpBackground; else return SharedBitmapDescriptor(); } PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const { if (mpFont.get() != nullptr) return mpFont; else if (mpParentStyle.get() != nullptr) return mpParentStyle->GetFont(); else return PresenterTheme::SharedFontDescriptor(); } //===== StyleAssociationContainer ============================================= void StyleAssociationContainer::Read ( ReadContext& rReadContext, const Reference& rxThemeRoot) { Reference xStyleAssociationList ( PresenterConfigurationAccess::GetConfigurationNode( rxThemeRoot, "StyleAssociations"), UNO_QUERY); if (xStyleAssociationList.is()) { ::std::vector aProperties (2); aProperties[0] = "ResourceURL"; aProperties[1] = "StyleName"; PresenterConfigurationAccess::ForAll( xStyleAssociationList, aProperties, ::boost::bind(&StyleAssociationContainer::ProcessStyleAssociation, this, ::boost::ref(rReadContext), _1, _2)); } } 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( ReadContext& rReadContext, const OUString& rsKey, const ::std::vector& rValues) { (void)rReadContext; (void)rsKey; 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: */