diff options
Diffstat (limited to 'sdext/source/presenter/PresenterTheme.cxx')
-rw-r--r-- | sdext/source/presenter/PresenterTheme.cxx | 1417 |
1 files changed, 1417 insertions, 0 deletions
diff --git a/sdext/source/presenter/PresenterTheme.cxx b/sdext/source/presenter/PresenterTheme.cxx new file mode 100644 index 000000000000..6688f7e8b679 --- /dev/null +++ b/sdext/source/presenter/PresenterTheme.cxx @@ -0,0 +1,1417 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sdext.hxx" + +#include "PresenterTheme.hxx" +#include "PresenterBitmapContainer.hxx" +#include "PresenterCanvasHelper.hxx" +#include "PresenterComponent.hxx" +#include "PresenterConfigurationAccess.hxx" +#include "PresenterHelper.hxx" +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/beans/UnknownPropertyException.hpp> +#include <com/sun/star/deployment/XPackageInformationProvider.hpp> +#include <com/sun/star/drawing/XPresenterHelper.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/rendering/PanoseWeight.hpp> +#include <com/sun/star/rendering/XBitmap.hpp> +#include <com/sun/star/util/Color.hpp> +#include <boost/bind.hpp> +#include <map> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::std; +using ::rtl::OUString; + +#define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))) + +namespace sdext { namespace presenter { + +namespace { + +class BorderSize +{ +public: + const static sal_Int32 mnInvalidValue = -10000; + + BorderSize (void) : mnLeft(mnInvalidValue), + mnTop(mnInvalidValue), + mnRight(mnInvalidValue), + mnBottom(mnInvalidValue) {} + + sal_Int32 mnLeft; + sal_Int32 mnTop; + sal_Int32 mnRight; + sal_Int32 mnBottom; + + vector<sal_Int32> ToVector (void) + { + vector<sal_Int32> 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<XComponentContext> mxComponentContext; + Reference<rendering::XCanvas> mxCanvas; + Reference<drawing::XPresenterHelper> mxPresenterHelper; + OUString msBasePath; + + ReadContext ( + const Reference<XComponentContext>& rxContext, + const Reference<rendering::XCanvas>& rxCanvas); + ~ReadContext (void); + + /** 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 ::rtl::OUString& rsFontPath, + const PresenterTheme::SharedFontDescriptor& rpDefault); + static PresenterTheme::SharedFontDescriptor ReadFont ( + const Reference<beans::XPropertySet>& rxFontProperties, + const PresenterTheme::SharedFontDescriptor& rpDefault); + + ::boost::shared_ptr<PresenterTheme::Theme> ReadTheme ( + PresenterConfigurationAccess& rConfiguration, + const OUString& rsThemeName); + + BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode); + + void SetBitmapSourceExtension (const OUString& rsExtensionName); + +private: + Any GetByName ( + const Reference<container::XNameAccess>& rxNode, + const OUString& rsName) const; +}; + + + + +/** A PaneStyle describes how a pane is rendered. +*/ +class PaneStyle +{ +public: + PaneStyle (void); + ~PaneStyle (void); + + const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const; + + OUString msStyleName; + ::boost::shared_ptr<PaneStyle> mpParentStyle; + PresenterTheme::SharedFontDescriptor mpFont; + BorderSize maInnerBorderSize; + BorderSize maOuterBorderSize; + ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps; + + PresenterTheme::SharedFontDescriptor GetFont (void) const; + +private: + + void UpdateBorderSize (BorderSize& rBorderSize, bool bInner); +}; + +typedef ::boost::shared_ptr<PaneStyle> SharedPaneStyle; + + + + +class PaneStyleContainer : vector<SharedPaneStyle> +{ +public: + void Read ( + ReadContext& rReadContext, + const Reference<container::XHierarchicalNameAccess>& rThemeRoot); + + SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const; + +private: + void ProcessPaneStyle ( + ReadContext& rReadContext, + const ::rtl::OUString& rsKey, + const ::std::vector<css::uno::Any>& rValues); +}; + + + + +/** A ViewStyle describes how a view is displayed. +*/ +class ViewStyle +{ +public: + ViewStyle (void); + ~ViewStyle (void); + + const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const; + + PresenterTheme::SharedFontDescriptor GetFont (void) const; + + OUString msStyleName; + ::boost::shared_ptr<ViewStyle> mpParentStyle; + PresenterTheme::SharedFontDescriptor mpFont; + ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps; + SharedBitmapDescriptor mpBackground; +}; + +typedef ::boost::shared_ptr<ViewStyle> SharedViewStyle; + + + + +class ViewStyleContainer : vector<SharedViewStyle> +{ +public: + void Read ( + ReadContext& rReadContext, + const Reference<container::XHierarchicalNameAccess>& rThemeRoot); + + SharedViewStyle GetViewStyle (const OUString& rsStyleName) const; + +private: + void ProcessViewStyle( + ReadContext& rReadContext, + const Reference<beans::XPropertySet>& rxProperties); +}; + + + + +class ViewDescriptor +{ +}; +typedef ::boost::shared_ptr<ViewDescriptor> SharedViewDescriptor; +typedef ::std::vector<SharedViewDescriptor> ViewDescriptorContainer; + + + +class StyleAssociationContainer +{ +public: + void Read ( + ReadContext& rReadContext, + const Reference<container::XHierarchicalNameAccess>& rThemeRoot); + + OUString GetStyleName (const OUString& rsResourceName) const; + +private: + typedef map<OUString, OUString> StyleAssociations; + StyleAssociations maStyleAssociations; + + void ProcessStyleAssociation( + ReadContext& rReadContext, + const ::rtl::OUString& rsKey, + const ::std::vector<css::uno::Any>& rValues); +}; + +} // end of anonymous namespace + + +class PresenterTheme::Theme +{ +public: + Theme ( + const OUString& rsName, + const Reference<container::XHierarchicalNameAccess>& rThemeRoot, + const OUString& rsNodeName); + ~Theme (void); + + void Read ( + PresenterConfigurationAccess& rConfiguration, + ReadContext& rReadContext); + + OUString msThemeName; + OUString msConfigurationNodeName; + ::boost::shared_ptr<Theme> mpParentTheme; + SharedBitmapDescriptor mpBackground; + PaneStyleContainer maPaneStyles; + ViewStyleContainer maViewStyles; + ViewDescriptorContainer maViewDescriptors; + StyleAssociationContainer maStyleAssociations; + Reference<container::XHierarchicalNameAccess> mxThemeRoot; + ::boost::shared_ptr<PresenterBitmapContainer> mpIconContainer; + typedef map<rtl::OUString,SharedFontDescriptor> 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<beans::XPropertySet>& rxProperties); +}; + + + + +//===== PresenterTheme ======================================================== + +PresenterTheme::PresenterTheme ( + const css::uno::Reference<css::uno::XComponentContext>& rxContext, + const rtl::OUString& rsThemeName, + const css::uno::Reference<css::rendering::XCanvas>& rxCanvas) + : mxContext(rxContext), + msThemeName(rsThemeName), + mpTheme(), + mpBitmapContainer(), + mxCanvas(rxCanvas) +{ + mpTheme = ReadTheme(); +} + + + + +PresenterTheme::~PresenterTheme (void) +{ +} + + + + +void SAL_CALL PresenterTheme::disposing (void) +{ +} + + + + +::boost::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme (void) +{ + ReadContext aReadContext(mxContext, mxCanvas); + + PresenterConfigurationAccess aConfiguration ( + mxContext, + OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")), + PresenterConfigurationAccess::READ_ONLY); + + return aReadContext.ReadTheme(aConfiguration, msThemeName); +} + + + + +bool PresenterTheme::HasCanvas (void) const +{ + return mxCanvas.is(); +} + + + + +void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas) +{ + if ( ! mxCanvas.is() && rxCanvas.is()) + { + mxCanvas = rxCanvas; + ReadTheme(); + } +} + + + + +OUString PresenterTheme::GetStyleName (const ::rtl::OUString& rsResourceURL) const +{ + OUString sStyleName; + ::boost::shared_ptr<Theme> pTheme (mpTheme); + while (sStyleName.getLength()==0 && pTheme.get()!=NULL) + { + sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL); + pTheme = pTheme->mpParentTheme; + } + return sStyleName; +} + + + + +::std::vector<sal_Int32> PresenterTheme::GetBorderSize ( + const ::rtl::OUString& rsStyleName, + const bool bOuter) const +{ + OSL_ASSERT(mpTheme.get() != NULL); + + SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); + if (pPaneStyle.get() != NULL) + 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 OUString& rsFontPath, + const PresenterTheme::SharedFontDescriptor& rpDefault) +{ + return ReadContext::ReadFont(rxNode, rsFontPath, rpDefault); +} + + + + +bool PresenterTheme::ConvertToColor ( + const Any& rColorSequence, + sal_uInt32& rColor) +{ + Sequence<sal_Int8> aByteSequence; + if (rColorSequence >>= aByteSequence) + { + const sal_Int32 nByteCount (aByteSequence.getLength()); + const sal_uInt8* pArray = reinterpret_cast<const sal_uInt8*>(aByteSequence.getConstArray()); + rColor = 0; + for (sal_Int32 nIndex=0; nIndex<nByteCount; ++nIndex) + { + rColor = (rColor << 8) | *pArray++; + } + return true; + } + else + return false; +} + + + + +::boost::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle ( + const ::rtl::OUString& rsStyleName, + const PresenterConfigurationAccess::WriteMode) const +{ + if (mpTheme.get() == NULL) + return ::boost::shared_ptr<PresenterConfigurationAccess>(); + + // Open configuration for writing. + ::boost::shared_ptr<PresenterConfigurationAccess> pConfiguration ( + new PresenterConfigurationAccess( + mxContext, + OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.extension.PresenterScreen/")), + PresenterConfigurationAccess::READ_WRITE)); + + // Get configuration node for the view style container of the current + // theme. + if (pConfiguration->GoToChild( + A2S("Presenter/Themes/") + mpTheme->msConfigurationNodeName + A2S("/ViewStyles"))) + { + pConfiguration->GoToChild( + ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual, + rsStyleName, + A2S("StyleName"), + _2)); + } + return pConfiguration; +} + + + + +::rtl::OUString PresenterTheme::GetThemeName (void) const +{ + if (mpTheme.get() != NULL) + return mpTheme->msThemeName; + else + return OUString(); +} + + + + +SharedBitmapDescriptor PresenterTheme::GetBitmap ( + const OUString& rsStyleName, + const OUString& rsBitmapName) const +{ + if (mpTheme.get() != NULL) + { + if (rsStyleName.getLength() == 0) + { + if (rsBitmapName == A2S("Background")) + { + ::boost::shared_ptr<Theme> pTheme (mpTheme); + while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL) + pTheme = pTheme->mpParentTheme; + if (pTheme.get() != NULL) + return pTheme->mpBackground; + else + return SharedBitmapDescriptor(); + } + } + else + { + SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); + if (pPaneStyle.get() != NULL) + { + SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName)); + if (pBitmap.get() != NULL) + return pBitmap; + } + + SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); + if (pViewStyle.get() != NULL) + { + SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName)); + if (pBitmap.get() != NULL) + return pBitmap; + } + } + } + + return SharedBitmapDescriptor(); +} + + + + +SharedBitmapDescriptor PresenterTheme::GetBitmap ( + const OUString& rsBitmapName) const +{ + if (mpTheme.get() != NULL) + { + if (rsBitmapName == A2S("Background")) + { + ::boost::shared_ptr<Theme> pTheme (mpTheme); + while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL) + pTheme = pTheme->mpParentTheme; + if (pTheme.get() != NULL) + return pTheme->mpBackground; + else + return SharedBitmapDescriptor(); + } + else + { + if (mpTheme->mpIconContainer.get() != NULL) + return mpTheme->mpIconContainer->GetBitmap(rsBitmapName); + } + } + + return SharedBitmapDescriptor(); +} + + + + +::boost::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer (void) const +{ + if (mpTheme.get() != NULL) + return mpTheme->mpIconContainer; + else + return ::boost::shared_ptr<PresenterBitmapContainer>(); +} + + + + +PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont ( + const OUString& rsStyleName) const +{ + if (mpTheme.get() != NULL) + { + SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); + if (pPaneStyle.get() != NULL) + return pPaneStyle->GetFont(); + + SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); + if (pViewStyle.get() != NULL) + return pViewStyle->GetFont(); + + ::boost::shared_ptr<Theme> pTheme (mpTheme); + while (pTheme.get() != NULL) + { + 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 (void) + : msFamilyName(), + msStyleName(), + mnSize(12), + mnColor(0x00000000), + msAnchor(OUString(RTL_CONSTASCII_USTRINGPARAM("Left"))), + mnXOffset(0), + mnYOffset(0) +{ +} + + + + +PresenterTheme::FontDescriptor::FontDescriptor ( + const ::boost::shared_ptr<FontDescriptor>& rpDescriptor) + : msFamilyName(), + msStyleName(), + mnSize(12), + mnColor(0x00000000), + msAnchor(OUString(RTL_CONSTASCII_USTRINGPARAM("Left"))), + mnXOffset(0), + mnYOffset(0) +{ + if (rpDescriptor.get() != NULL) + { + 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.getLength() == 0) + aFontRequest.FontDescription.FamilyName = A2S("Tahoma"); + aFontRequest.FontDescription.StyleName = msStyleName; + aFontRequest.CellSize = nCellSize; + + // Make an attempt at translating the style name(s)into a corresponding + // font description. + if (msStyleName == A2S("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, A2S("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<container::XHierarchicalNameAccess>& rxThemeRoot, + const OUString& rsNodeName) + : msThemeName(rsName), + msConfigurationNodeName(rsNodeName), + mpParentTheme(), + maPaneStyles(), + maViewStyles(), + maStyleAssociations(), + mxThemeRoot(rxThemeRoot), + mpIconContainer() +{ +} + + + + +PresenterTheme::Theme::~Theme (void) +{ +} + + + + +void PresenterTheme::Theme::Read ( + PresenterConfigurationAccess& rConfiguration, + ReadContext& rReadContext) +{ + PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("ThemeName")) + >>= msThemeName; + + // Parent theme name. + OUString sParentThemeName; + if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("ParentTheme")) + >>= sParentThemeName) + && sParentThemeName.getLength()>0) + { + mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName); + } + + // Read the extension that contains the bitmaps referenced in this + // theme. + OUString sBitmapSourceExtension; + if ((PresenterConfigurationAccess::GetConfigurationNode( + mxThemeRoot, A2S("BitmapSourceExtension")) >>= sBitmapSourceExtension) + && sBitmapSourceExtension.getLength()>0) + { + rReadContext.SetBitmapSourceExtension(sBitmapSourceExtension); + } + else + { + rReadContext.SetBitmapSourceExtension(PresenterComponent::gsExtensionIdentifier); + } + + // Background. + mpBackground = PresenterBitmapContainer::LoadBitmap( + mxThemeRoot, + A2S("Background"), + rReadContext.mxPresenterHelper, + rReadContext.msBasePath, + 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<container::XNameAccess>( + PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("Bitmaps")), + UNO_QUERY), + mpParentTheme.get()!=NULL + ? mpParentTheme->mpIconContainer + : ::boost::shared_ptr<PresenterBitmapContainer>(), + rReadContext.mxComponentContext, + rReadContext.mxCanvas, + rReadContext.msBasePath)); + + // Read fonts. + Reference<container::XNameAccess> xFontNode( + PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("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() != NULL) + return pPaneStyle; + else if (mpParentTheme.get() != NULL) + return mpParentTheme->GetPaneStyle(rsStyleName); + else + return SharedPaneStyle(); +} + + + + +SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const +{ + SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName)); + if (pViewStyle.get() != NULL) + return pViewStyle; + else if (mpParentTheme.get() != NULL) + return mpParentTheme->GetViewStyle(rsStyleName); + else + return SharedViewStyle(); +} + + + + +void PresenterTheme::Theme::ProcessFont( + ReadContext& rReadContext, + const OUString& rsKey, + const Reference<beans::XPropertySet>& rxProperties) +{ + (void)rReadContext; + 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), + mxPresenterHelper(), + msBasePath() +{ + Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager()); + if (xFactory.is()) + { + mxPresenterHelper = Reference<drawing::XPresenterHelper>( + xFactory->createInstanceWithContext( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterHelper")), + rxContext), + UNO_QUERY_THROW); + } + + // Get base path to bitmaps. + SetBitmapSourceExtension(PresenterComponent::gsExtensionIdentifier); +} + + + + +ReadContext::~ReadContext (void) +{ +} + + + + +PresenterTheme::SharedFontDescriptor ReadContext::ReadFont ( + const Reference<container::XHierarchicalNameAccess>& rxNode, + const OUString& rsFontPath, + 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) +{ + ::boost::shared_ptr<PresenterTheme::FontDescriptor> pDescriptor ( + new PresenterTheme::FontDescriptor(rpDefault)); + + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("FamilyName")) >>= pDescriptor->msFamilyName; + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Style")) >>= pDescriptor->msStyleName; + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Size")) >>= pDescriptor->mnSize; + PresenterTheme::ConvertToColor( + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Color")), + pDescriptor->mnColor); + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Anchor")) >>= pDescriptor->msAnchor; + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("XOffset")) >>= pDescriptor->mnXOffset; + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("YOffset")) >>= pDescriptor->mnYOffset; + + return pDescriptor; +} + + + + +Any ReadContext::GetByName ( + const Reference<container::XNameAccess>& rxNode, + const OUString& rsName) const +{ + OSL_ASSERT(rxNode.is()); + if (rxNode->hasByName(rsName)) + return rxNode->getByName(rsName); + else + return Any(); +} + + + + +::boost::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme ( + PresenterConfigurationAccess& rConfiguration, + const OUString& rsThemeName) +{ + ::boost::shared_ptr<PresenterTheme::Theme> pTheme; + + OUString sCurrentThemeName (rsThemeName); + if (sCurrentThemeName.getLength() == 0) + { + // No theme name given. Look up the CurrentTheme property. + rConfiguration.GetConfigurationNode(A2S("Presenter/CurrentTheme")) >>= sCurrentThemeName; + if (sCurrentThemeName.getLength() == 0) + { + // Still no name. Use "DefaultTheme". + sCurrentThemeName = A2S("DefaultTheme"); + } + } + + Reference<container::XNameAccess> xThemes ( + rConfiguration.GetConfigurationNode(A2S("Presenter/Themes")), + UNO_QUERY); + if (xThemes.is()) + { + // Iterate over all themes and search the one with the given name. + Sequence<OUString> aKeys (xThemes->getElementNames()); + for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex) + { + const OUString& rsKey (aKeys[nItemIndex]); + Reference<container::XHierarchicalNameAccess> xTheme ( + xThemes->getByName(rsKey), UNO_QUERY); + if (xTheme.is()) + { + OUString sThemeName; + PresenterConfigurationAccess::GetConfigurationNode(xTheme, A2S("ThemeName")) + >>= sThemeName; + if (sThemeName == sCurrentThemeName) + { + pTheme.reset(new PresenterTheme::Theme(sThemeName,xTheme,rsKey)); + break; + } + } + } + } + + if (pTheme.get() != NULL) + { + pTheme->Read(rConfiguration, *this); + } + + return pTheme; +} + + + + +BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode) +{ + BorderSize aBorderSize; + + if (rxNode.is()) + { + GetByName(rxNode, A2S("Left")) >>= aBorderSize.mnLeft; + GetByName(rxNode, A2S("Top")) >>= aBorderSize.mnTop; + GetByName(rxNode, A2S("Right")) >>= aBorderSize.mnRight; + GetByName(rxNode, A2S("Bottom")) >>= aBorderSize.mnBottom; + } + + return aBorderSize; +} + + + + +void ReadContext::SetBitmapSourceExtension (const OUString& rsExtensionIdentifier) +{ + // Get base path to bitmaps. + msBasePath = PresenterComponent::GetBasePath(mxComponentContext, rsExtensionIdentifier); +} + + + + +//===== PaneStyleContainer ==================================================== + +void PaneStyleContainer::Read ( + ReadContext& rReadContext, + const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) +{ + Reference<container::XNameAccess> xPaneStyleList ( + PresenterConfigurationAccess::GetConfigurationNode( + rxThemeRoot, + A2S("PaneStyles")), + UNO_QUERY); + if (xPaneStyleList.is()) + { + ::std::vector<rtl::OUString> aProperties; + aProperties.reserve(6); + aProperties.push_back(A2S("StyleName")); + aProperties.push_back(A2S("ParentStyle")); + aProperties.push_back(A2S("TitleFont")); + aProperties.push_back(A2S("InnerBorderSize")); + aProperties.push_back(A2S("OuterBorderSize")); + aProperties.push_back(A2S("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<Any>& rValues) +{ + (void)rsKey; + + if (rValues.size() != 6) + return; + + ::boost::shared_ptr<PaneStyle> pStyle (new PaneStyle()); + + rValues[0] >>= pStyle->msStyleName; + + OUString sParentStyleName; + if (rValues[1] >>= sParentStyleName) + { + // Find parent style. + PaneStyleContainer::const_iterator iStyle; + for (iStyle=begin(); iStyle!=end(); ++iStyle) + if ((*iStyle)->msStyleName.equals(sParentStyleName)) + { + pStyle->mpParentStyle = *iStyle; + break; + } + } + + Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY); + pStyle->mpFont = rReadContext.ReadFont( + xFontNode, A2S(""), PresenterTheme::SharedFontDescriptor()); + + Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY); + pStyle->maInnerBorderSize = rReadContext.ReadBorderSize(xInnerBorderSizeNode); + Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY); + pStyle->maOuterBorderSize = rReadContext.ReadBorderSize(xOuterBorderSizeNode); + + if (pStyle->mpParentStyle.get() != NULL) + { + 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.reset(new PresenterBitmapContainer( + xBitmapsNode, + pStyle->mpParentStyle.get()!=NULL + ? pStyle->mpParentStyle->mpBitmaps + : ::boost::shared_ptr<PresenterBitmapContainer>(), + rReadContext.mxComponentContext, + rReadContext.mxCanvas, + rReadContext.msBasePath, + rReadContext.mxPresenterHelper)); + } + + push_back(pStyle); +} + + + + +SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const +{ + const_iterator iEnd (end()); + for (const_iterator iStyle=begin(); iStyle!=iEnd; ++iStyle) + if ((*iStyle)->msStyleName == rsStyleName) + return *iStyle; + return SharedPaneStyle(); +} + + + + +//===== PaneStyle ============================================================= + +PaneStyle::PaneStyle (void) + : msStyleName(), + mpParentStyle(), + mpFont(), + maInnerBorderSize(), + maOuterBorderSize(), + mpBitmaps() +{ +} + + + + +PaneStyle::~PaneStyle (void) +{ +} + + + + +void PaneStyle::UpdateBorderSize (BorderSize& rBorderSize, bool bInner) +{ + if (mpParentStyle.get() != NULL) + mpParentStyle->UpdateBorderSize(rBorderSize, bInner); + + BorderSize& rThisBorderSize (bInner ? maInnerBorderSize : maOuterBorderSize); + if (rThisBorderSize.mnLeft >= 0) + rBorderSize.mnLeft = rThisBorderSize.mnLeft; + if (rThisBorderSize.mnTop >= 0) + rBorderSize.mnTop = rThisBorderSize.mnTop; + if (rThisBorderSize.mnRight >= 0) + rBorderSize.mnRight = rThisBorderSize.mnRight; + if (rThisBorderSize.mnBottom >= 0) + rBorderSize.mnBottom = rThisBorderSize.mnBottom; +} + + + + +const SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const +{ + if (mpBitmaps.get() != NULL) + { + const SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName); + if (pBitmap.get() != NULL) + return pBitmap; + } + + if (mpParentStyle.get() != NULL) + return mpParentStyle->GetBitmap(rsBitmapName); + else + return SharedBitmapDescriptor(); +} + + + + +PresenterTheme::SharedFontDescriptor PaneStyle::GetFont (void) const +{ + if (mpFont.get() != NULL) + return mpFont; + else if (mpParentStyle.get() != NULL) + return mpParentStyle->GetFont(); + else + return PresenterTheme::SharedFontDescriptor(); +} + + + + +//===== ViewStyleContainer ==================================================== + +void ViewStyleContainer::Read ( + ReadContext& rReadContext, + const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) +{ + (void)rReadContext; + + Reference<container::XNameAccess> xViewStyleList ( + PresenterConfigurationAccess::GetConfigurationNode( + rxThemeRoot, + A2S("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<beans::XPropertySet>& rxProperties) +{ + ::boost::shared_ptr<ViewStyle> pStyle (new ViewStyle()); + + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("StyleName")) + >>= pStyle->msStyleName; + + OUString sParentStyleName; + if (PresenterConfigurationAccess::GetProperty(rxProperties, A2S("ParentStyle")) + >>= sParentStyleName) + { + // Find parent style. + ViewStyleContainer::const_iterator iStyle; + for (iStyle=begin(); iStyle!=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<container::XHierarchicalNameAccess> xFontNode ( + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Font")), UNO_QUERY); + PresenterTheme::SharedFontDescriptor pFont ( + rReadContext.ReadFont(xFontNode, sPathToFont, PresenterTheme::SharedFontDescriptor())); + if (pFont.get() != NULL) + pStyle->mpFont = pFont; + + Reference<container::XHierarchicalNameAccess> xBackgroundNode ( + PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Background")), + UNO_QUERY); + SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap( + xBackgroundNode, + OUString(), + rReadContext.mxPresenterHelper, + rReadContext.msBasePath, + rReadContext.mxCanvas, + SharedBitmapDescriptor())); + if (pBackground.get() != NULL && pBackground->GetNormalBitmap().is()) + pStyle->mpBackground = pBackground; + + push_back(pStyle); +} + + + + +SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const +{ + const_iterator iEnd (end()); + for (const_iterator iStyle=begin(); iStyle!=iEnd; ++iStyle) + if ((*iStyle)->msStyleName == rsStyleName) + return *iStyle; + return SharedViewStyle(); +} + + + + +//===== ViewStyle ============================================================= + +ViewStyle::ViewStyle (void) + : msStyleName(), + mpParentStyle(), + mpFont(), + mpBackground() +{ +} + + + + +ViewStyle::~ViewStyle (void) +{ +} + + + + +const SharedBitmapDescriptor ViewStyle::GetBitmap (const OUString& rsBitmapName) const +{ + if (rsBitmapName == A2S("Background")) + return mpBackground; + else + return SharedBitmapDescriptor(); +} + + + + +PresenterTheme::SharedFontDescriptor ViewStyle::GetFont (void) const +{ + if (mpFont.get() != NULL) + return mpFont; + else if (mpParentStyle.get() != NULL) + return mpParentStyle->GetFont(); + else + return PresenterTheme::SharedFontDescriptor(); +} + + + + +//===== StyleAssociationContainer ============================================= + +void StyleAssociationContainer::Read ( + ReadContext& rReadContext, + const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) +{ + Reference<container::XNameAccess> xStyleAssociationList ( + PresenterConfigurationAccess::GetConfigurationNode( + rxThemeRoot, + A2S("StyleAssociations")), + UNO_QUERY); + if (xStyleAssociationList.is()) + { + ::std::vector<rtl::OUString> aProperties (2); + aProperties[0] = A2S("ResourceURL"); + aProperties[1] = A2S("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<Any>& 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: */ |