From ff30491fc477a39f8f5509298fbd84449f7665b3 Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Thu, 17 Sep 2009 11:09:25 +0000 Subject: CWS-TOOLING: integrate CWS dr69 2009-09-09 11:45:28 +0200 dr r275979 : suncc failure 2009-09-09 11:33:34 +0200 dr r275977 : gcc warning 2009-09-09 11:09:02 +0200 er r275976 : #i87171# reworked name check for creating defined names 2009-09-09 10:38:02 +0200 dr r275973 : adapt changes in oox base class 2009-09-09 10:21:03 +0200 dr r275969 : remove faulty pagesize stuff 2009-09-09 10:20:13 +0200 dr r275968 : remove faulty pagesize stuff 2009-09-08 20:24:39 +0200 nn r275958 : #i104899# interpret cells when creating chart listener after loading 2009-09-08 16:05:37 +0200 er r275937 : ScXMLDDELinkContext::EndElement: Excel writes bad ODF without 's table:number-columns-repeated attribute; be lenient ... 2009-09-08 13:14:54 +0200 er r275925 : #i103315# handle external references in Excel's ODF msoxl namespace 2009-09-07 17:37:18 +0200 dr r275907 : #i104753# crash when deleting cell with note 2009-09-07 14:02:29 +0200 dr r275896 : #i103520# reworked sheet name buffer to resolve internal hyperlinks, fix almost all remaining problems with external links in BIFF, fix auto color import for BIFF 2009-09-06 20:01:05 +0200 er r275862 : #i35913# fix regression introduced by integration of CWS fhawfixes1; patch from 2009-09-05 18:32:00 +0200 er r275847 : #i104156# merge #i103918# from uncloned dr68ooo311 2009-09-05 18:19:23 +0200 er r275846 : #i104156# merge #i103317# from uncloned dr68ooo311 2009-09-05 17:32:12 +0200 er r275844 : #i104484# glueState: correct casts in range bounds; patch from slightly modified 2009-09-03 17:26:38 +0200 dr r275764 : #i103520# handle apostrophs in sheet names in internal URLs 2009-09-03 17:21:26 +0200 dr r275763 : #i95271# show text formatting in temp notes 2009-09-03 12:24:52 +0200 dr r275747 : unused declaration 2009-09-02 21:33:03 +0200 dr r275727 : #i96438# cleanup color handling in xls filter, extend VML color parser 2009-09-02 15:39:57 +0200 dr r275715 : #158571# #i96438# accept also VML colors in the form '#RRGGBB [xyz]' 2009-09-02 15:16:36 +0200 dr r275714 : #158571# #i96438# set note text 2009-09-02 14:59:33 +0200 dr r275713 : #158571# #i96438# load custom line dashes from DrawingML and VML 2009-09-02 11:53:35 +0200 dr r275702 : #158571# #i96438# import VML fill gradients 2009-08-31 19:28:10 +0200 dr r275632 : #158571# #i96438# more vml formatting 2009-08-31 14:29:30 +0200 dr r275606 : #158571# #i96438# changed handling of xml token ids/names 2009-08-28 18:25:26 +0200 dr r275545 : #158571# #i96438# preparations for and basic support of VML shape formatting, load spreadsheet cell notes position, formatting, and visibility 2009-08-25 19:08:31 +0200 dr r275378 : #i103390# dump BIFF STYLEEXT 2009-08-25 18:28:50 +0200 dr r275377 : #i103390# improve built-in style handling 2009-08-25 18:27:38 +0200 dr r275376 : #i103390# improve built-in style handling 2009-08-04 18:49:40 +0200 dr r274629 : CWS-TOOLING: rebase CWS dr69 to trunk@274622 (milestone: DEV300:m54) --- oox/inc/oox/core/fasttokenhandler.hxx | 28 +- oox/inc/oox/core/filterbase.hxx | 7 +- oox/inc/oox/core/xmlfilterbase.hxx | 3 - oox/inc/oox/drawingml/color.hxx | 32 +- oox/inc/oox/drawingml/customshapeproperties.hxx | 2 +- oox/inc/oox/drawingml/drawingmltypes.hxx | 8 + oox/inc/oox/drawingml/fillproperties.hxx | 22 +- oox/inc/oox/drawingml/lineproperties.hxx | 17 +- oox/inc/oox/helper/containerhelper.hxx | 33 +- oox/inc/oox/helper/helper.hxx | 3 +- oox/inc/oox/helper/propertymap.hxx | 14 +- oox/inc/oox/ole/axcontrolhelper.hxx | 2 - oox/inc/oox/ppt/pptimport.hxx | 5 +- oox/inc/oox/token/propertylist.hxx | 53 ++ oox/inc/oox/token/tokenmap.hxx | 84 ++++ oox/inc/oox/vml/vmldrawing.hxx | 4 + oox/inc/oox/vml/vmlformatting.hxx | 187 ++++++++ oox/inc/oox/vml/vmlshape.hxx | 30 +- oox/inc/oox/vml/vmlshapecontainer.hxx | 22 + oox/inc/oox/vml/vmlshapecontext.hxx | 6 +- oox/inc/oox/xls/biffhelper.hxx | 1 + oox/inc/oox/xls/chartsheetfragment.hxx | 4 +- oox/inc/oox/xls/defnamesbuffer.hxx | 38 +- oox/inc/oox/xls/drawingfragment.hxx | 6 + oox/inc/oox/xls/excelfilter.hxx | 30 +- oox/inc/oox/xls/excelhandlers.hxx | 14 +- oox/inc/oox/xls/externallinkbuffer.hxx | 30 +- oox/inc/oox/xls/richstring.hxx | 6 + oox/inc/oox/xls/stylesbuffer.hxx | 68 ++- oox/inc/oox/xls/themebuffer.hxx | 2 - oox/inc/oox/xls/viewsettings.hxx | 12 +- oox/inc/oox/xls/workbookfragment.hxx | 2 +- oox/inc/oox/xls/workbookhelper.hxx | 9 +- oox/inc/oox/xls/worksheetbuffer.hxx | 54 ++- oox/inc/oox/xls/worksheetfragment.hxx | 4 +- oox/inc/oox/xls/worksheethelper.hxx | 7 +- oox/source/core/fasttokenhandler.cxx | 95 ++++ oox/source/core/filterbase.cxx | 14 +- oox/source/core/makefile.mk | 1 + oox/source/core/xmlfilterbase.cxx | 15 +- oox/source/drawingml/chart/objectformatter.cxx | 4 +- oox/source/drawingml/clrschemecontext.cxx | 1 + oox/source/drawingml/color.cxx | 582 +++++++++++----------- oox/source/drawingml/customshapeproperties.cxx | 2 +- oox/source/drawingml/fillproperties.cxx | 60 ++- oox/source/drawingml/lineproperties.cxx | 153 ++++-- oox/source/drawingml/linepropertiescontext.cxx | 6 + oox/source/drawingml/shape.cxx | 6 +- oox/source/drawingml/table/tablecell.cxx | 3 +- oox/source/drawingml/textcharacterproperties.cxx | 1 + oox/source/drawingml/textparagraphproperties.cxx | 1 + oox/source/dump/biffdumper.cxx | 19 +- oox/source/dump/biffdumper.ini | 22 +- oox/source/helper/propertymap.cxx | 24 +- oox/source/ole/axcontrolhelper.cxx | 10 +- oox/source/ppt/animvariantcontext.cxx | 1 + oox/source/ppt/pptimport.cxx | 20 +- oox/source/ppt/slidepersist.cxx | 4 +- oox/source/ppt/timenodelistcontext.cxx | 1 + oox/source/shape/FastTokenHandlerService.hxx | 19 +- oox/source/shape/ShapeFilterBase.cxx | 5 - oox/source/shape/ShapeFilterBase.hxx | 3 - oox/source/token/gentoken.pl | 14 +- oox/source/token/propertylist.cxx | 14 +- oox/source/token/tokenmap.cxx | 96 ++-- oox/source/token/tokens.txt | 8 + oox/source/vml/makefile.mk | 1 + oox/source/vml/vmldrawing.cxx | 5 + oox/source/vml/vmldrawingfragment.cxx | 4 +- oox/source/vml/vmlformatting.cxx | 585 +++++++++++++++++++++++ oox/source/vml/vmlshape.cxx | 173 ++++--- oox/source/vml/vmlshapecontext.cxx | 152 ++++-- oox/source/xls/chartsheetfragment.cxx | 4 +- oox/source/xls/commentsbuffer.cxx | 39 +- oox/source/xls/defnamesbuffer.cxx | 146 ++++-- oox/source/xls/drawingfragment.cxx | 42 ++ oox/source/xls/excelfilter.cxx | 64 ++- oox/source/xls/excelhandlers.cxx | 6 +- oox/source/xls/externallinkbuffer.cxx | 166 +++++-- oox/source/xls/externallinkfragment.cxx | 6 +- oox/source/xls/pivotcachebuffer.cxx | 4 +- oox/source/xls/richstring.cxx | 12 +- oox/source/xls/stylesbuffer.cxx | 394 +++++++-------- oox/source/xls/themebuffer.cxx | 8 - oox/source/xls/viewsettings.cxx | 29 +- oox/source/xls/workbookfragment.cxx | 69 +-- oox/source/xls/workbookhelper.cxx | 33 +- oox/source/xls/worksheetbuffer.cxx | 147 +++--- oox/source/xls/worksheetfragment.cxx | 4 +- oox/source/xls/worksheethelper.cxx | 86 ++-- oox/workben/pagesize/excel_pagesize.txt | 66 --- oox/workben/pagesize/parsePageSize.py | 78 --- 92 files changed, 2899 insertions(+), 1477 deletions(-) create mode 100644 oox/inc/oox/token/propertylist.hxx create mode 100644 oox/inc/oox/token/tokenmap.hxx create mode 100644 oox/inc/oox/vml/vmlformatting.hxx create mode 100644 oox/source/core/fasttokenhandler.cxx create mode 100644 oox/source/vml/vmlformatting.cxx delete mode 100644 oox/workben/pagesize/excel_pagesize.txt delete mode 100755 oox/workben/pagesize/parsePageSize.py (limited to 'oox') diff --git a/oox/inc/oox/core/fasttokenhandler.hxx b/oox/inc/oox/core/fasttokenhandler.hxx index 3944011507b2..45709f9da401 100644 --- a/oox/inc/oox/core/fasttokenhandler.hxx +++ b/oox/inc/oox/core/fasttokenhandler.hxx @@ -28,27 +28,41 @@ * ************************************************************************/ -#ifndef OOX_FASTTOKENHANDLER_HXX -#define OOX_FASTTOKENHANDLER_HXX +#ifndef OOX_CORE_FASTTOKENHANDLER_HXX +#define OOX_CORE_FASTTOKENHANDLER_HXX #include #include +namespace oox { class TokenMap; } + namespace oox { +namespace core { + +// ============================================================================ +/** Wrapper implementing the com.sun.star.xml.sax.XFastTokenHandler API interface + that provides access to the tokens generated from the internal token name list. + */ class FastTokenHandler : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastTokenHandler > { public: explicit FastTokenHandler(); virtual ~FastTokenHandler(); - virtual ::sal_Int32 SAL_CALL getToken( const ::rtl::OUString& Identifier ) throw (::com::sun::star::uno::RuntimeException); - virtual ::rtl::OUString SAL_CALL getIdentifier( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getUTF8Identifier( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Int32 SAL_CALL getTokenFromUTF8( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& Identifier ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getToken( const ::rtl::OUString& rIdentifier ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getIdentifier( sal_Int32 nToken ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getUTF8Identifier( sal_Int32 nToken ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getTokenFromUTF8( const ::com::sun::star::uno::Sequence< sal_Int8 >& Identifier ) throw (::com::sun::star::uno::RuntimeException); + +private: + const TokenMap& mrTokenMap; /// Reference to global token map singleton. }; -} +// ============================================================================ + +} // namespace core +} // namespace oox #endif diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx index 9115c88be4e7..adfb8d6d0941 100644 --- a/oox/inc/oox/core/filterbase.hxx +++ b/oox/inc/oox/core/filterbase.hxx @@ -198,8 +198,13 @@ public: sal_Int32 convertScreenPixelX( double fPixelX ) const; /** Converts the passed value from vertical screen pixels to 1/100 mm. */ sal_Int32 convertScreenPixelY( double fPixelY ) const; + /** Returns a system color specified by the passed XML token identifier. */ - sal_Int32 getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb = -1 ) const; + sal_Int32 getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb = API_RGB_TRANSPARENT ) const; + /** Derived classes may implement to resolve a scheme color from the passed XML token identifier. */ + virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const; + /** Derived classes may implement to resolve a palette index to an RGB color. */ + virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const; /** Requests a password from the media descriptor or from the user. On success, the password will be inserted into the media descriptor. */ diff --git a/oox/inc/oox/core/xmlfilterbase.hxx b/oox/inc/oox/core/xmlfilterbase.hxx index d1b79dc116d8..510b00ea81fc 100644 --- a/oox/inc/oox/core/xmlfilterbase.hxx +++ b/oox/inc/oox/core/xmlfilterbase.hxx @@ -87,9 +87,6 @@ public: virtual const ::oox::drawingml::Theme* getCurrentTheme() const = 0; - /** Has to be implemented by each filter to resolve scheme colors. */ - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const = 0; - /** Has to be implemented by each filter to return the collection of VML shapes. */ virtual ::oox::vml::Drawing* getVmlDrawing() = 0; diff --git a/oox/inc/oox/drawingml/color.hxx b/oox/inc/oox/drawingml/color.hxx index 91fddf0be69f..b1de124adad5 100644 --- a/oox/inc/oox/drawingml/color.hxx +++ b/oox/inc/oox/drawingml/color.hxx @@ -34,10 +34,11 @@ #include #include #include +#include +#include +#include "oox/helper/helper.hxx" -namespace oox { namespace core { - class XmlFilterBase; -} } +namespace oox { namespace core { class FilterBase; } } namespace oox { namespace drawingml { @@ -50,6 +51,11 @@ public: Color(); ~Color(); + /** Returns the RGB value for the passed DrawingML color token, or nDefaultRgb on error. */ + static sal_Int32 getDmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ); + /** Returns the RGB value for the passed VML color token, or nDefaultRgb on error. */ + static sal_Int32 getVmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ); + /** Sets the color to unused state. */ void setUnused(); /** Sets an RGB value (hexadecimal RRGGBB) from the a:srgbClr element. */ @@ -64,6 +70,8 @@ public: void setSchemeClr( sal_Int32 nToken ); /** Sets a system color from the a:sysClr element. */ void setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb ); + /** Sets a palette color index. */ + void setPaletteClr( sal_Int32 nPaletteIdx ); /** Inserts the passed color transformation. */ void addTransformation( sal_Int32 nElement, sal_Int32 nValue = -1 ); @@ -71,17 +79,21 @@ public: void addChartTintTransformation( double fTint ); /** Inserts Excel specific color tint (-1.0...0.0 = shade, 0.0...1.0 = tint). */ void addExcelTintTransformation( double fTint ); + /** Removes all color transformations. */ + void clearTransformations(); + /** Removes transparence from the color. */ + void clearTransparence(); /** Overwrites this color with the passed color, if it is used. */ inline void assignIfUsed( const Color& rColor ) { if( rColor.isUsed() ) *this = rColor; } - /** Removes transparence from the color. */ - void clearTransparence(); /** Returns true, if the color is initialized. */ bool isUsed() const { return meMode != COLOR_UNUSED; } + /** Returns true, if the color is a placeholder color in theme style lists. */ + bool isPlaceHolder() const { return meMode == COLOR_PH; } /** Returns the final RGB color value. @param nPhClr Actual color for the phClr placeholder color used in theme style lists. */ - sal_Int32 getColor( const ::oox::core::XmlFilterBase& rFilter, sal_Int32 nPhClr = -1 ) const; + sal_Int32 getColor( const ::oox::core::FilterBase& rFilter, sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Returns true, if the color has a transparence set. */ bool hasTransparence() const; @@ -89,6 +101,9 @@ public: sal_Int16 getTransparence() const; private: + /** Internal helper for getColor(). */ + void setResolvedRgb( sal_Int32 nRgb ) const; + /** Converts the color components to RGB values. */ void toRgb() const; /** Converts the color components to CRGB values (gamma corrected percentage). */ @@ -104,8 +119,9 @@ private: COLOR_CRGB, /// Relative RGB (r/g/b: 0...100000). COLOR_HSL, /// HSL (hue: 0...21600000, sat/lum: 0...100000). COLOR_SCHEME, /// Color from scheme. - COLOR_PH, /// Placeholder color in theme style lists. + COLOR_PALETTE, /// Color from application defined palette. COLOR_SYSTEM, /// Color from system palette. + COLOR_PH, /// Placeholder color in theme style lists. COLOR_FINAL /// Finalized RGB color. }; @@ -120,7 +136,7 @@ private: mutable ColorMode meMode; /// Current color mode. mutable TransformVec maTransforms; /// Color transformations. - mutable sal_Int32 mnC1; /// Red, red%, hue, scheme token, system token, or final RGB. + mutable sal_Int32 mnC1; /// Red, red%, hue, scheme token, palette index, system token, or final RGB. mutable sal_Int32 mnC2; /// Green, green%, saturation, or system default RGB. mutable sal_Int32 mnC3; /// Blue, blue%, or luminance. sal_Int32 mnAlpha; /// Alpha value (color opacity). diff --git a/oox/inc/oox/drawingml/customshapeproperties.hxx b/oox/inc/oox/drawingml/customshapeproperties.hxx index 17a308a6331c..9857a75e4836 100644 --- a/oox/inc/oox/drawingml/customshapeproperties.hxx +++ b/oox/inc/oox/drawingml/customshapeproperties.hxx @@ -72,7 +72,7 @@ public: virtual ~CustomShapeProperties(); void apply( const CustomShapePropertiesPtr& ); - void pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase, + void pushToPropSet( const ::oox::core::FilterBase& rFilterBase, const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > & xPropSet, const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape > & xShape) const; diff --git a/oox/inc/oox/drawingml/drawingmltypes.hxx b/oox/inc/oox/drawingml/drawingmltypes.hxx index fbec84c4b81c..41365f8df086 100644 --- a/oox/inc/oox/drawingml/drawingmltypes.hxx +++ b/oox/inc/oox/drawingml/drawingmltypes.hxx @@ -43,6 +43,14 @@ namespace drawingml { // ============================================================================ +const sal_Int32 PER_PERCENT = 1000; +const sal_Int32 MAX_PERCENT = 100 * PER_PERCENT; + +const sal_Int32 PER_DEGREE = 60000; +const sal_Int32 MAX_DEGREE = 360 * PER_DEGREE; + +// ============================================================================ + struct LineProperties; typedef ::boost::shared_ptr< LineProperties > LinePropertiesPtr; diff --git a/oox/inc/oox/drawingml/fillproperties.hxx b/oox/inc/oox/drawingml/fillproperties.hxx index 9190b87e0e53..9504da617083 100644 --- a/oox/inc/oox/drawingml/fillproperties.hxx +++ b/oox/inc/oox/drawingml/fillproperties.hxx @@ -159,18 +159,20 @@ struct FillProperties /** Writes the properties to the passed property map. */ void pushToPropMap( PropertyMap& rPropMap, - const FillPropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const; + const FillPropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nShapeRotation = 0, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Writes the properties to the passed property set. */ void pushToPropSet( PropertySet& rPropSet, - const FillPropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const; + const FillPropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nShapeRotation = 0, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; }; // ============================================================================ @@ -185,14 +187,14 @@ struct GraphicProperties /** Writes the properties to the passed property map. */ void pushToPropMap( PropertyMap& rPropMap, - const ::oox::core::XmlFilterBase& rFilter, - sal_Int32 nPhClr ) const; + const ::oox::core::FilterBase& rFilter, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Writes the properties to the passed property set. */ void pushToPropSet( PropertySet& rPropSet, - const ::oox::core::XmlFilterBase& rFilter, - sal_Int32 nPhClr ) const; + const ::oox::core::FilterBase& rFilter, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; }; // ============================================================================ diff --git a/oox/inc/oox/drawingml/lineproperties.hxx b/oox/inc/oox/drawingml/lineproperties.hxx index 2aa9ac7fedeb..db337c520092 100644 --- a/oox/inc/oox/drawingml/lineproperties.hxx +++ b/oox/inc/oox/drawingml/lineproperties.hxx @@ -86,11 +86,16 @@ struct LineArrowProperties struct LineProperties { + typedef ::std::pair< sal_Int32, sal_Int32 > DashStop; + typedef ::std::vector< DashStop > DashStopVector; + LineArrowProperties maStartArrow; /// Start line arrow style. LineArrowProperties maEndArrow; /// End line arrow style. FillProperties maLineFill; /// Line fill (solid, gradient, ...). + DashStopVector maCustomDash; /// User-defined line dash style. OptValue< sal_Int32 > moLineWidth; /// Line width (EMUs). OptValue< sal_Int32 > moPresetDash; /// Preset dash (OOXML token). + OptValue< sal_Int32 > moLineCompound; /// Line compound type (OOXML token). OptValue< sal_Int32 > moLineCap; /// Line cap (OOXML token). OptValue< sal_Int32 > moLineJoint; /// Line joint type (OOXML token). @@ -102,18 +107,18 @@ struct LineProperties /** Writes the properties to the passed property map. */ void pushToPropMap( PropertyMap& rPropMap, - const LinePropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nPhClr ) const; + const LinePropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; /** Writes the properties to the passed property map. */ void pushToPropSet( PropertySet& rPropSet, - const LinePropertyIds& rPropIds, - const ::oox::core::XmlFilterBase& rFilter, + const ::oox::core::FilterBase& rFilter, ModelObjectHelper& rModelObjHelper, - sal_Int32 nPhClr ) const; + const LinePropertyIds& rPropIds = DEFAULT_IDS, + sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const; }; // ============================================================================ diff --git a/oox/inc/oox/helper/containerhelper.hxx b/oox/inc/oox/helper/containerhelper.hxx index be3736e92a47..8186d537faee 100644 --- a/oox/inc/oox/helper/containerhelper.hxx +++ b/oox/inc/oox/helper/containerhelper.hxx @@ -91,7 +91,7 @@ public: template< typename FunctorType > inline void forEach( const FunctorType& rFunctor ) const { - ::std::for_each( this->begin(), this->end(), Functor< FunctorType >( rFunctor ) ); + ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) ); } /** Calls the passed member function of ObjType on every contained object. */ @@ -115,13 +115,30 @@ public: forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) ); } + /** Searches for an element by using the passed functor that takes a + constant reference of the object type (const ObjType&). */ + template< typename FunctorType > + inline value_type findIf( const FunctorType& rFunctor ) const + { + typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) ); + return (aIt == this->end()) ? value_type() : *aIt; + } + private: template< typename FunctorType > - struct Functor + struct ForEachFunctor + { + const FunctorType& mrFunctor; + inline explicit ForEachFunctor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline void operator()( const value_type& rxValue ) const { if( rxValue.get() ) mrFunctor( *rxValue ); } + }; + + template< typename FunctorType > + struct FindFunctor { const FunctorType& mrFunctor; - inline explicit Functor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} - inline void operator()( const value_type& rValue ) const { mrFunctor( *rValue ); } + inline explicit FindFunctor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline bool operator()( const value_type& rxValue ) const { return rxValue.get() && mrFunctor( *rxValue ); } }; inline const value_type* getRef( sal_Int32 nIndex ) const @@ -170,7 +187,7 @@ public: template< typename FunctorType > inline void forEach( const FunctorType& rFunctor ) const { - ::std::for_each( this->begin(), this->end(), Functor< FunctorType >( rFunctor ) ); + ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) ); } /** Calls the passed member function of ObjType on every contained object. */ @@ -196,11 +213,11 @@ public: private: template< typename FunctorType > - struct Functor + struct ForEachFunctor { const FunctorType& mrFunctor; - inline explicit Functor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} - inline void operator()( const value_type& rValue ) const { mrFunctor( *rValue.second ); } + inline explicit ForEachFunctor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline void operator()( const value_type& rValue ) const { if( rValue.second.get() ) mrFunctor( *rValue.second ); } }; inline const mapped_type* getRef( key_type nKey ) const diff --git a/oox/inc/oox/helper/helper.hxx b/oox/inc/oox/helper/helper.hxx index d6e2286fd8ac..f08f807da2a2 100644 --- a/oox/inc/oox/helper/helper.hxx +++ b/oox/inc/oox/helper/helper.hxx @@ -104,7 +104,8 @@ inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax ) template< typename ReturnType, typename Type > inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd ) { - BOOST_STATIC_ASSERT( ::std::numeric_limits< Type >::is_integer ); +// this BOOST_STATIC_ASSERT fails with suncc +// BOOST_STATIC_ASSERT( ::std::numeric_limits< Type >::is_integer ); Type nInterval = nEnd - nBegin; Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval); return static_cast< ReturnType >( nValue - nCount * nInterval ); diff --git a/oox/inc/oox/helper/propertymap.hxx b/oox/inc/oox/helper/propertymap.hxx index a3e84c4b73fe..58a769adbb48 100644 --- a/oox/inc/oox/helper/propertymap.hxx +++ b/oox/inc/oox/helper/propertymap.hxx @@ -44,13 +44,7 @@ namespace com { namespace sun { namespace star { namespace beans { namespace oox { -// ============================================================================ - -/** A vector that contains all predefined property names used in the filters. */ -struct PropertyNamesList : public ::std::vector< ::rtl::OUString > -{ - explicit PropertyNamesList(); -}; +struct PropertyList; // ============================================================================ @@ -66,6 +60,9 @@ typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > PropertyMapBase; class PropertyMap : public PropertyMapBase { public: + explicit PropertyMap(); + ~PropertyMap(); + /** Returns the name of the passed property identifier. */ static const ::rtl::OUString& getPropertyName( sal_Int32 nPropId ); @@ -94,6 +91,9 @@ public: /** Creates and fills a new instance supporting the XPropertySet interface. */ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > makePropertySet() const; + +private: + const PropertyList* mpPropNames; }; // ============================================================================ diff --git a/oox/inc/oox/ole/axcontrolhelper.hxx b/oox/inc/oox/ole/axcontrolhelper.hxx index 392a24a2704e..713cbcae362e 100644 --- a/oox/inc/oox/ole/axcontrolhelper.hxx +++ b/oox/inc/oox/ole/axcontrolhelper.hxx @@ -83,8 +83,6 @@ protected: /** Derived classes returns the UNO form of the current context. Called exactly once. */ virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > createControlForm() const = 0; - /** Derived classes may implement to resolve a palette index to an RGB color. */ - virtual sal_Int32 getPaletteColor( sal_uInt16 nPaletteIdx ) const; private: const ::oox::core::FilterBase& mrFilter; diff --git a/oox/inc/oox/ppt/pptimport.hxx b/oox/inc/oox/ppt/pptimport.hxx index d865e48c2569..d6c1d899ac35 100644 --- a/oox/inc/oox/ppt/pptimport.hxx +++ b/oox/inc/oox/ppt/pptimport.hxx @@ -56,10 +56,9 @@ public: virtual bool importDocument() throw(); virtual bool exportDocument() throw(); - virtual const ::oox::drawingml::Theme* getCurrentTheme() const; - - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; + virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const; + virtual const ::oox::drawingml::Theme* getCurrentTheme() const; virtual ::oox::vml::Drawing* getVmlDrawing(); virtual const oox::drawingml::table::TableStyleListPtr getTableStyles(); virtual ::oox::drawingml::chart::ChartConverter& getChartConverter(); diff --git a/oox/inc/oox/token/propertylist.hxx b/oox/inc/oox/token/propertylist.hxx new file mode 100644 index 000000000000..abc776c348f6 --- /dev/null +++ b/oox/inc/oox/token/propertylist.hxx @@ -0,0 +1,53 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: propertylist.hxx,v $ + * $Revision: 1.1 $ + * + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_TOKEN_PROPERTYLIST_HXX +#define OOX_TOKEN_PROPERTYLIST_HXX + +#include +#include + +namespace oox { + +// ============================================================================ + +/** A vector that contains all predefined property names used in the filters. */ +struct PropertyList : public ::std::vector< ::rtl::OUString > +{ + explicit PropertyList(); + ~PropertyList(); +}; + +// ============================================================================ + +} // namespace oox + +#endif + diff --git a/oox/inc/oox/token/tokenmap.hxx b/oox/inc/oox/token/tokenmap.hxx new file mode 100644 index 000000000000..e4dd0be121ce --- /dev/null +++ b/oox/inc/oox/token/tokenmap.hxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: fasttokenhandler.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_TOKEN_TOKENMAP_HXX +#define OOX_TOKEN_TOKENMAP_HXX + +#include +#include +#include +#include + +namespace oox { + +// ============================================================================ + +class TokenMap +{ +public: + explicit TokenMap(); + ~TokenMap(); + + /** Returns the Unicode name of the passed token identifier. */ + ::rtl::OUString getUnicodeTokenName( sal_Int32 nToken ) const; + + /** Returns the token identifier for the passed Unicode token name. */ + sal_Int32 getTokenFromUnicode( const ::rtl::OUString& rUnicodeName ) const; + + /** Returns the UTF8 name of the passed token identifier as byte sequence. */ + ::com::sun::star::uno::Sequence< sal_Int8 > + getUtf8TokenName( sal_Int32 nToken ) const; + + /** Returns the token identifier for the passed UTF8 token name. */ + sal_Int32 getTokenFromUtf8( + const ::com::sun::star::uno::Sequence< sal_Int8 >& rUtf8Name ) const; + +private: + struct TokenName + { + ::rtl::OUString maUniName; + ::com::sun::star::uno::Sequence< sal_Int8 > maUtf8Name; + }; + typedef ::std::vector< TokenName > TokenNameVector; + + TokenNameVector maTokenNames; + +}; + +// ============================================================================ + +struct StaticTokenMap : public ::rtl::Static< TokenMap, StaticTokenMap > {}; + +// ============================================================================ + +} // namespace oox + +#endif + diff --git a/oox/inc/oox/vml/vmldrawing.hxx b/oox/inc/oox/vml/vmldrawing.hxx index 4be185bbcd2a..f0bd75046c37 100644 --- a/oox/inc/oox/vml/vmldrawing.hxx +++ b/oox/inc/oox/vml/vmldrawing.hxx @@ -47,6 +47,7 @@ namespace oox { namespace ole { class AxControlHelper; } } namespace oox { namespace vml { +class ShapeBase; class ShapeContainer; struct ShapeClientData; @@ -133,6 +134,9 @@ public: /** Returns the registered info structure for a form control, if extant. */ const ControlInfo* getControlInfo( const ::rtl::OUString& rShapeId ) const; + /** Derived classes may disable conversion of specific shapes. */ + virtual bool isShapeSupported( const ShapeBase& rShape ) const; + /** Derived classes may calculate the shape rectangle from a non-standard anchor information string. */ virtual bool convertShapeClientAnchor( diff --git a/oox/inc/oox/vml/vmlformatting.hxx b/oox/inc/oox/vml/vmlformatting.hxx new file mode 100644 index 000000000000..b37da4daa28c --- /dev/null +++ b/oox/inc/oox/vml/vmlformatting.hxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: vmlformatting.hxx,v $ + * $Revision: 1.1 $ + * + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_VML_VMLFORMATTING_HXX +#define OOX_VML_VMLFORMATTING_HXX + +#include "oox/helper/helper.hxx" + +namespace oox { class PropertyMap; } +namespace oox { namespace core { class FilterBase; } } + +namespace oox { +namespace vml { + +// ============================================================================ + +typedef ::std::pair< sal_Int32, sal_Int32 > Int32Pair; +typedef ::std::pair< double, double > DoublePair; + +// ============================================================================ + +class ConversionHelper +{ +public: + /** Returns two values contained in rValue separated by cSep. + */ + static bool separatePair( + ::rtl::OUString& orValue1, ::rtl::OUString& orValue2, + const ::rtl::OUString& rValue, sal_Unicode cSep ); + + /** Returns the boolean value from the passed string of a VML attribute. + Supported values: 'f', 't', 'false', 'true'. False for anything else. + */ + static bool decodeBool( const ::rtl::OUString& rValue ); + + /** Converts the passed VML percentage measure string to a normalized + floating-point value. + + @param rValue The VML percentage value. This is a floating-point value + with optional following '%' sign. If the '%' sign is missing, the + floating point value will be returned unmodified. If the '%' sign + is present, the value will be divided by 100. + */ + static double decodePercent( + const ::rtl::OUString& rValue, + double fDefValue ); + + /** Converts the passed VML measure string to EMU (English Metric Units). + + @param rFilter The core filter object needed to perform pixel + conversion according to the current output device. + + @param rValue The VML measure value. This is a floating-point value + with optional measure string following the value. + + @param nRefValue Reference value needed for percentage measure. + + @param bPixelX Set to true if the value is oriented horizontally (e.g. + X coordinates, widths). Set to false if the value is oriented + vertically (e.g. Y coordinates, heights). This is needed because + output devices may specify different width and height for a pixel. + + @param bDefaultAsPixel Set to true if omitted measure unit means + pixel. Set to false if omitted measure unit means EMU. + */ + static sal_Int32 decodeMeasureToEmu( + const ::oox::core::FilterBase& rFilter, + const ::rtl::OUString& rValue, + sal_Int32 nRefValue, + bool bPixelX, + bool bDefaultAsPixel ); + + /** Converts the passed VML measure string to 1/100 mm. + + @param rFilter See above. + @param rValue See above. + @param nRefValue See above. + @param bPixelX See above. + @param bDefaultAsPixel See above. + */ + static sal_Int32 decodeMeasureToHmm( + const ::oox::core::FilterBase& rFilter, + const ::rtl::OUString& rValue, + sal_Int32 nRefValue, + bool bPixelX, + bool bDefaultAsPixel ); + +private: + ConversionHelper(); + ~ConversionHelper(); +}; + +// ============================================================================ + +/** The stroke arrow model structure contains all properties for an line end arrow. */ +struct StrokeArrowModel +{ + OptValue< sal_Int32 > moArrowType; + OptValue< sal_Int32 > moArrowWidth; + OptValue< sal_Int32 > moArrowLength; + + void assignUsed( const StrokeArrowModel& rSource ); +}; + +// ============================================================================ + +/** The stroke model structure contains all shape border properties. */ +struct StrokeModel +{ + OptValue< bool > moStroked; /// Shape border line on/off. + StrokeArrowModel maStartArrow; /// Start line arrow style. + StrokeArrowModel maEndArrow; /// End line arrow style. + OptValue< ::rtl::OUString > moColor; /// Solid line color. + OptValue< double > moOpacity; /// Solid line color opacity. + OptValue< ::rtl::OUString > moWeight; /// Line width. + OptValue< ::rtl::OUString > moDashStyle; /// Line dash (predefined or manually). + OptValue< sal_Int32 > moLineStyle; /// Line style (single, double, ...). + OptValue< sal_Int32 > moEndCap; /// Type of line end cap. + OptValue< sal_Int32 > moJoinStyle; /// Type of line join. + + void assignUsed( const StrokeModel& rSource ); + + /** Writes the properties to the passed property map. */ + void pushToPropMap( + PropertyMap& rPropMap, + const ::oox::core::FilterBase& rFilter ) const; +}; + +// ============================================================================ + +/** The fill model structure contains all shape fill properties. */ +struct FillModel +{ + OptValue< bool > moFilled; /// Shape fill on/off. + OptValue< ::rtl::OUString > moColor; /// Solid fill color. + OptValue< double > moOpacity; /// Solid fill color opacity. + OptValue< ::rtl::OUString > moColor2; /// End color of gradient. + OptValue< double > moOpacity2; /// End color opycity of gradient. + OptValue< sal_Int32 > moType; /// Fill type. + OptValue< sal_Int32 > moAngle; /// Gradient rotation angle. + OptValue< double > moFocus; /// Linear gradient focus of second color. + OptValue< DoublePair > moFocusPos; /// Rectanguar gradient focus position of second color. + OptValue< DoublePair > moFocusSize; /// Rectanguar gradient focus size of second color. + OptValue< bool > moRotate; /// True = rotate gradient/bitmap with shape. + + void assignUsed( const FillModel& rSource ); + + /** Writes the properties to the passed property map. */ + void pushToPropMap( + PropertyMap& rPropMap, + const ::oox::core::FilterBase& rFilter ) const; +}; + +// ============================================================================ + +} // namespace vml +} // namespace oox + +#endif + diff --git a/oox/inc/oox/vml/vmlshape.hxx b/oox/inc/oox/vml/vmlshape.hxx index f4719f4c1d97..323e643cee50 100644 --- a/oox/inc/oox/vml/vmlshape.hxx +++ b/oox/inc/oox/vml/vmlshape.hxx @@ -34,7 +34,7 @@ #include #include #include -#include "oox/helper/helper.hxx" +#include "oox/vml/vmlformatting.hxx" namespace com { namespace sun { namespace star { namespace awt { struct Rectangle; } @@ -56,12 +56,10 @@ struct ShapeTypeModel { ::rtl::OUString maShapeId; /// Unique identifier of the shape. ::rtl::OUString maName; /// Name of the shape, if present. - OptValue< sal_Int32 > monShapeType; /// Builtin shape type identifier. + OptValue< sal_Int32 > moShapeType; /// Builtin shape type identifier. - OptValue< sal_Int32 > monCoordLeft; /// Left position of coordinate system for children scaling. - OptValue< sal_Int32 > monCoordTop; /// Top position of coordinate system for children scaling. - OptValue< sal_Int32 > monCoordWidth; /// Width of coordinate system for children scaling. - OptValue< sal_Int32 > monCoordHeight; /// Height of coordinate system for children scaling. + OptValue< Int32Pair > moCoordPos; /// Top-left position of coordinate system for children scaling. + OptValue< Int32Pair > moCoordSize; /// Size of coordinate system for children scaling. ::rtl::OUString maPosition; /// Position type of the shape. ::rtl::OUString maLeft; /// X position of the shape bounding box (number with unit). ::rtl::OUString maTop; /// Y position of the shape bounding box (number with unit). @@ -70,11 +68,8 @@ struct ShapeTypeModel ::rtl::OUString maMarginLeft; /// X position of the shape bounding box to shape anchor (number with unit). ::rtl::OUString maMarginTop; /// Y position of the shape bounding box to shape anchor (number with unit). - OptValue< bool > mobStroked; /// True or missing = solid border line. - OptValue< ::rtl::OUString > moStrokeColor; /// Solid border color. - - OptValue< bool > mobFilled; /// True or missing = path is filled. - OptValue< ::rtl::OUString > moFillColor; /// Solid fill color. + StrokeModel maStrokeModel; /// Border line formatting. + FillModel maFillModel; /// Shape fill formatting. OptValue< ::rtl::OUString > moGraphicPath; /// Path to a graphic for this shape. OptValue< ::rtl::OUString > moGraphicTitle; /// Title of the graphic. @@ -131,7 +126,10 @@ struct ShapeClientData ::rtl::OUString maLinkedCell; /// Link to value cell associated to the control. ::rtl::OUString maSourceRange; /// Link to cell range used as data source for the control. sal_Int32 mnObjType; /// Type of the shape. + sal_Int32 mnCol; /// Column index for spreadsheet cell note. + sal_Int32 mnRow; /// Row index for spreadsheet cell note. bool mbPrintObject; /// True = print the object. + bool mbVisible; /// True = cell note is visible. explicit ShapeClientData(); }; @@ -179,6 +177,11 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor = 0 ) const; + /** Converts position and formatting into the passed existing XShape. */ + void convertFormatting( + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, + const ShapeParentAnchor* pParentAnchor = 0 ) const; + protected: explicit ShapeBase( const Drawing& rDrawing ); @@ -188,6 +191,11 @@ protected: const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, const ::com::sun::star::awt::Rectangle& rShapeRect ) const = 0; + /** Calculates the final shape rectangle according to the passed anchor, + if present, otherwise according to the own anchor settings. */ + ::com::sun::star::awt::Rectangle calcShapeRectangle( + const ShapeParentAnchor* pParentAnchor ) const; + /** Converts common shape properties such as formatting attributes. */ void convertShapeProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape ) const; diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx index d8c9b575a6ad..caa8a1a59c6d 100644 --- a/oox/inc/oox/vml/vmlshapecontainer.hxx +++ b/oox/inc/oox/vml/vmlshapecontainer.hxx @@ -73,6 +73,7 @@ public: /** Returns true, if this contaikner does not contain any shapes. */ inline bool empty() const { return maShapes.empty(); } + /** Returns the shape template with the passed identifier. @param bDeep True = searches in all group shapes too. */ const ShapeType* getShapeTypeById( const ::rtl::OUString& rShapeId, bool bDeep ) const; @@ -80,6 +81,15 @@ public: @param bDeep True = searches in all group shapes too. */ const ShapeBase* getShapeById( const ::rtl::OUString& rShapeId, bool bDeep ) const; + /** Searches for a shape type by using the passed functor that takes a + constant reference of a ShapeType object. */ + template< typename Functor > + const ShapeType* findShapeType( const Functor& rFunctor ) const; + /** Searches for a shape by using the passed functor that takes a constant + reference of a ShapeBase object. */ + template< typename Functor > + const ShapeBase* findShape( const Functor& rFunctor ) const; + /** Returns the first shape in the collection (Word only). */ const ShapeBase* getFirstShape() const; @@ -111,6 +121,18 @@ ShapeT& ShapeContainer::createShape() return *xShape; } +template< typename Functor > +const ShapeType* ShapeContainer::findShapeType( const Functor& rFunctor ) const +{ + return maTypes.findIf( rFunctor ).get(); +} + +template< typename Functor > +const ShapeBase* ShapeContainer::findShape( const Functor& rFunctor ) const +{ + return maShapes.findIf( rFunctor ).get(); +} + // ============================================================================ } // namespace vml diff --git a/oox/inc/oox/vml/vmlshapecontext.hxx b/oox/inc/oox/vml/vmlshapecontext.hxx index 0cc0be1f963a..dbc5e1aa611d 100644 --- a/oox/inc/oox/vml/vmlshapecontext.hxx +++ b/oox/inc/oox/vml/vmlshapecontext.hxx @@ -70,7 +70,7 @@ class ShapeContextBase : public ::oox::core::ContextHandler2 { public: static ::oox::core::ContextHandlerRef - createContext( + createShapeContext( ::oox::core::ContextHandler2Helper& rParent, sal_Int32 nElement, const AttributeList& rAttribs, @@ -94,10 +94,6 @@ public: onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); private: - /** Processes the 'coordorigin' attribute. */ - void setCoordOrigin( const ::rtl::OUString& rCoordOrigin ); - /** Processes the 'coordsize' attribute. */ - void setCoordSize( const ::rtl::OUString& rCoordSize ); /** Processes the 'style' attribute. */ void setStyle( const ::rtl::OUString& rStyle ); diff --git a/oox/inc/oox/xls/biffhelper.hxx b/oox/inc/oox/xls/biffhelper.hxx index 1da2c362170f..d5be59019315 100644 --- a/oox/inc/oox/xls/biffhelper.hxx +++ b/oox/inc/oox/xls/biffhelper.hxx @@ -470,6 +470,7 @@ const sal_uInt16 BIFF_ID_STANDARDWIDTH = 0x0099; const sal_uInt16 BIFF2_ID_STRING = 0x0007; const sal_uInt16 BIFF3_ID_STRING = 0x0207; const sal_uInt16 BIFF_ID_STYLE = 0x0293; +const sal_uInt16 BIFF_ID_STYLEEXT = 0x0892; const sal_uInt16 BIFF_ID_SXEXT = 0x00DC; const sal_uInt16 BIFF_ID_TOPMARGIN = 0x0028; const sal_uInt16 BIFF_ID_TXO = 0x01B6; diff --git a/oox/inc/oox/xls/chartsheetfragment.hxx b/oox/inc/oox/xls/chartsheetfragment.hxx index d1effba29166..3e6f5d9d7a6d 100644 --- a/oox/inc/oox/xls/chartsheetfragment.hxx +++ b/oox/inc/oox/xls/chartsheetfragment.hxx @@ -45,7 +45,7 @@ public: const WorkbookHelper& rHelper, const ::rtl::OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, - sal_Int32 nSheet ); + sal_Int16 nSheet ); protected: // oox.core.ContextHandler2Helper interface ------------------------------- @@ -76,7 +76,7 @@ public: explicit BiffChartsheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, - sal_Int32 nSheet ); + sal_Int16 nSheet ); /** Imports the entire sheet fragment, returns true, if EOF record has been reached. */ virtual bool importFragment(); diff --git a/oox/inc/oox/xls/defnamesbuffer.hxx b/oox/inc/oox/xls/defnamesbuffer.hxx index 88e4f7272d8e..88c83c0491b3 100644 --- a/oox/inc/oox/xls/defnamesbuffer.hxx +++ b/oox/inc/oox/xls/defnamesbuffer.hxx @@ -86,17 +86,12 @@ struct DefinedNameModel class DefinedNameBase : public WorkbookHelper { public: - explicit DefinedNameBase( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ); - - /** Returns true, if this defined name is global in the document. */ - inline bool isGlobalName() const { return maModel.mnSheet < 0; } + explicit DefinedNameBase( const WorkbookHelper& rHelper ); /** Returns the original name as imported from or exported to the file. */ inline const ::rtl::OUString& getModelName() const { return maModel.maName; } /** Returns the name as used in the Calc document. */ inline const ::rtl::OUString& getCalcName() const { return maCalcName; } - /** Returns the 0-based sheet index for local names, or -1 for global names. */ - inline sal_Int32 getSheetIndex() const { return maModel.mnSheet; } /** Returns the original name as imported from or exported to the file. */ const ::rtl::OUString& getUpcaseModelName() const; @@ -105,21 +100,19 @@ public: protected: /** Imports the OOX formula string, using the passed formula context. */ - void importOoxFormula( FormulaContext& rContext ); + void importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet ); /** Imports the OOBIN formula, using the passed formula context. */ - void importOobFormula( FormulaContext& rContext, RecordInputStream& rStrm ); + void importOobFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, RecordInputStream& rStrm ); /** Imports the BIFF formula, using the passed formula context. */ - void importBiffFormula( FormulaContext& rContext, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ); + void importBiffFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ); /** Tries to convert the passed token sequence to a SingleReference or ComplexReference. */ - void setReference( const ApiTokenSequence& rTokens ); + void extractReference( const ApiTokenSequence& rTokens ); protected: DefinedNameModel maModel; /// Model data for this defined name. mutable ::rtl::OUString maUpModelName; /// Model name converted to uppercase ASCII. ::rtl::OUString maCalcName; /// Final name used in the Calc document. - -private: ::com::sun::star::uno::Any maRefAny; /// Single cell/range reference. }; @@ -128,7 +121,7 @@ private: class DefinedName : public DefinedNameBase { public: - explicit DefinedName( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ); + explicit DefinedName( const WorkbookHelper& rHelper ); /** Sets the attributes for this defined name from the passed attribute set. */ void importDefinedName( const AttributeList& rAttribs ); @@ -137,7 +130,7 @@ public: /** Imports the defined name from a DEFINEDNAME record in the passed stream. */ void importDefinedName( RecordInputStream& rStrm ); /** Imports the defined name from a DEFINEDNAME record in the passed BIFF stream. */ - void importDefinedName( BiffInputStream& rStrm ); + void importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet ); /** Creates a defined name in the Calc document. */ void createNameObject(); @@ -148,9 +141,13 @@ public: inline bool isBuiltinName() const { return mcBuiltinId != OOX_DEFNAME_UNKNOWN; } /** Returns true, if this defined name is a macro function call. */ inline bool isMacroFunction() const { return maModel.mbMacro && maModel.mbFunction; } + /** Returns true, if this defined name is global in the document. */ + inline bool isGlobalName() const { return mnCalcSheet < 0; } /** Returns the token index used in API token arrays (com.sun.star.sheet.FormulaToken). */ inline sal_Int32 getTokenIndex() const { return mnTokenIndex; } + /** Returns the 0-based sheet index for local names, or -1 for global names. */ + inline sal_Int16 getLocalCalcSheet() const { return mnCalcSheet; } /** Tries to resolve the defined name to an absolute cell range. */ bool getAbsoluteRange( ::com::sun::star::table::CellRangeAddress& orRange ) const; @@ -167,6 +164,7 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange > mxNamedRange; /// XNamedRange interface of the defined name. sal_Int32 mnTokenIndex; /// Name index used in API token array. + sal_Int16 mnCalcSheet; /// Calc sheet index for sheet-local names. sal_Unicode mcBuiltinId; /// Identifier for built-in defined names. StreamDataSeqPtr mxFormula; /// Formula data for OOBIN import. BiffStreamPosPtr mxBiffStrm; /// Cached BIFF stream for formula import. @@ -182,9 +180,9 @@ class DefinedNamesBuffer : public WorkbookHelper public: explicit DefinedNamesBuffer( const WorkbookHelper& rHelper ); - /** Sets the current sheet index for files with local defined names, e.g. - BIFF4 workspaces. All created names initially will contain this index. */ - void setLocalSheetIndex( sal_Int32 nLocalSheet ); + /** Sets the sheet index for local names (BIFF2-BIFF4 only). */ + void setLocalCalcSheet( sal_Int16 nCalcSheet ); + /** Imports a defined name from the passed attribute set. */ DefinedNameRef importDefinedName( const AttributeList& rAttribs ); /** Imports a defined name from a DEFINEDNAME record in the passed stream. */ @@ -203,7 +201,7 @@ public: @param nSheet The sheet index for local names or -1 for global names. If no local name is found, tries to find a matching global name. @return Reference to the defined name or empty reference. */ - DefinedNameRef getByModelName( const ::rtl::OUString& rModelName, sal_Int32 nSheet = -1 ) const; + DefinedNameRef getByModelName( const ::rtl::OUString& rModelName, sal_Int16 nCalcSheet = -1 ) const; private: DefinedNameRef createDefinedName(); @@ -213,8 +211,8 @@ private: typedef RefMap< sal_Int32, DefinedName > DefNameMap; DefNameVector maDefNames; /// List of all defined names in insertion order. - DefNameMap maDefNameMap; /// Maps all defined names by API token index. */ - sal_Int32 mnLocalSheet; /// Current sheet index for import of BIFF sheet-local names. + DefNameMap maDefNameMap; /// Maps all defined names by API token index. + sal_Int16 mnCalcSheet; /// Current sheet index for BIFF2-BIFF4 names (always sheet-local). }; // ============================================================================ diff --git a/oox/inc/oox/xls/drawingfragment.hxx b/oox/inc/oox/xls/drawingfragment.hxx index f1fee71e5c1c..67009f436360 100644 --- a/oox/inc/oox/xls/drawingfragment.hxx +++ b/oox/inc/oox/xls/drawingfragment.hxx @@ -170,6 +170,12 @@ class VmlDrawing : public ::oox::vml::Drawing, public WorksheetHelper public: explicit VmlDrawing( const WorksheetHelper& rHelper ); + /** Returns the drawing shape for a cell note at the specified position. */ + const ::oox::vml::ShapeBase* getNoteShape( const ::com::sun::star::table::CellAddress& rPos ) const; + + /** Filters cell note shapes. */ + virtual bool isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const; + /** Calculates the shape rectangle from a cell anchor string. */ virtual bool convertShapeClientAnchor( ::com::sun::star::awt::Rectangle& orShapeRect, diff --git a/oox/inc/oox/xls/excelfilter.hxx b/oox/inc/oox/xls/excelfilter.hxx index ed6c32cdc463..28059fe30ce7 100644 --- a/oox/inc/oox/xls/excelfilter.hxx +++ b/oox/inc/oox/xls/excelfilter.hxx @@ -41,7 +41,23 @@ namespace xls { class WorkbookHelper; -class ExcelFilter : public ::oox::core::XmlFilterBase +class ExcelFilterBase +{ +protected: + explicit ExcelFilterBase(); + virtual ~ExcelFilterBase(); + + void setWorkbookHelper( WorkbookHelper& rHelper ); + WorkbookHelper& getWorkbookHelper() const; + void clearWorkbookHelper(); + +private: + WorkbookHelper* mpHelper; /// Nonowning pointer to helper base. +}; + +// ============================================================================ + +class ExcelFilter : public ::oox::core::XmlFilterBase, public ExcelFilterBase { public: explicit ExcelFilter( @@ -51,23 +67,21 @@ public: virtual bool importDocument() throw(); virtual bool exportDocument() throw(); - virtual const ::oox::drawingml::Theme* getCurrentTheme() const; - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; + virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const; + virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const; + virtual const ::oox::drawingml::Theme* getCurrentTheme() const; virtual ::oox::vml::Drawing* getVmlDrawing(); virtual const ::oox::drawingml::table::TableStyleListPtr getTableStyles(); virtual ::oox::drawingml::chart::ChartConverter& getChartConverter(); private: virtual ::rtl::OUString implGetImplementationName() const; - -private: - WorkbookHelper* mpHelper; /// Nonowning pointer to helper base. }; // ============================================================================ -class ExcelBiffFilter : public ::oox::core::BinaryFilterBase +class ExcelBiffFilter : public ::oox::core::BinaryFilterBase, public ExcelFilterBase { public: explicit ExcelBiffFilter( @@ -77,6 +91,8 @@ public: virtual bool importDocument() throw(); virtual bool exportDocument() throw(); + virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const; + private: virtual ::rtl::OUString implGetImplementationName() const; }; diff --git a/oox/inc/oox/xls/excelhandlers.hxx b/oox/inc/oox/xls/excelhandlers.hxx index 3b34a14963ec..76d0e599e502 100644 --- a/oox/inc/oox/xls/excelhandlers.hxx +++ b/oox/inc/oox/xls/excelhandlers.hxx @@ -74,7 +74,7 @@ public: ParentType& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); template< typename ParentType > explicit OoxWorksheetContextBase( ParentType& rParent ); @@ -84,7 +84,7 @@ public: template< typename ParentType > OoxWorksheetContextBase::OoxWorksheetContextBase( ParentType& rParent, - ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : ::oox::core::ContextHandler2( rParent ), WorksheetHelperRoot( rParent, xProgressBar, eSheetType, nSheet ) { @@ -125,7 +125,7 @@ public: const ::rtl::OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); explicit OoxWorksheetFragmentBase( const WorksheetHelper& rHelper, @@ -236,7 +236,7 @@ protected: const ParentType& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); template< typename ParentType > explicit BiffWorksheetContextBase( const ParentType& rParent ); @@ -246,7 +246,7 @@ protected: template< typename ParentType > BiffWorksheetContextBase::BiffWorksheetContextBase( const ParentType& rParent, - ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : BiffContextHandler( rParent ), WorksheetHelperRoot( rParent, xProgressBar, eSheetType, nSheet ) { @@ -346,7 +346,7 @@ protected: const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); }; // ============================================================================ @@ -359,7 +359,7 @@ public: explicit BiffSkipWorksheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, - sal_Int32 nSheet ); + sal_Int16 nSheet ); virtual bool importFragment(); }; diff --git a/oox/inc/oox/xls/externallinkbuffer.hxx b/oox/inc/oox/xls/externallinkbuffer.hxx index a50170544813..a4ede4403fe3 100644 --- a/oox/inc/oox/xls/externallinkbuffer.hxx +++ b/oox/inc/oox/xls/externallinkbuffer.hxx @@ -70,9 +70,7 @@ class ExternalLink; class ExternalName : public DefinedNameBase { public: - explicit ExternalName( - const ExternalLink& rParentLink, - sal_Int32 nLocalSheet ); + explicit ExternalName( const ExternalLink& rParentLink ); /** Appends the passed value to the result set. */ template< typename Type > @@ -109,8 +107,10 @@ public: /** Returns true, if the name refers to an OLE object. */ inline bool isOleObject() const { return maExtNameModel.mbOleObj; } +#if 0 /** Returns the sheet cache index if this is a sheet-local external name. */ sal_Int32 getSheetCacheIndex() const; +#endif /** Returns the DDE item info needed by the XML formula parser. */ bool getDdeItemInfo( @@ -123,6 +123,8 @@ public: ::rtl::OUString& orDdeItem ); private: + /** Tries to convert the passed token sequence to an ExternalReference. */ + void extractExternalReference( const ApiTokenSequence& rTokens ); /** Sets the size of the result matrix. */ void setResultSize( sal_Int32 nColumns, sal_Int32 nRows ); @@ -265,14 +267,20 @@ public: /** Returns the type of the external library if this is a library link. */ FunctionLibraryType getFuncLibraryType() const; - /** Returns the internal sheet index or external sheet cache index for the passed sheet. */ - sal_Int32 getSheetIndex( sal_Int32 nTabId = 0 ) const; - /** Returns the internal sheet range or range of external sheet caches for the passed sheet range (BIFF only). */ - void getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const; + /** Returns the internal Calc sheet index or for the passed sheet. */ + sal_Int16 getCalcSheetIndex( sal_Int32 nTabId = 0 ) const; + + /** Returns the token index of the external document. */ + sal_Int32 getDocumentLinkIndex() const; + /** Returns the external sheet cache index or for the passed sheet. */ + sal_Int32 getSheetCacheIndex( sal_Int32 nTabId = 0 ) const; /** Returns the sheet cache of the external sheet with the passed index. */ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache > - getExternalSheetCache( sal_Int32 nTabId ); + getSheetCache( sal_Int32 nTabId ) const; + + /** Returns the internal sheet range or range of external sheet caches for the passed sheet range (BIFF only). */ + void getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const; /** Returns the external name with the passed zero-based index. */ ExternalNameRef getNameByIndex( sal_Int32 nIndex ) const; @@ -289,7 +297,8 @@ private: ExternalNameRef createExternalName(); private: - typedef ::std::vector< sal_Int32 > IndexVector; + typedef ::std::vector< sal_Int16 > Int16Vector; + typedef ::std::vector< sal_Int32 > Int32Vector; typedef RefVector< ExternalName > ExternalNameVector; ExternalLinkType meLinkType; /// Type of this link object. @@ -299,7 +308,8 @@ private: ::rtl::OUString maTargetUrl; /// Target link, DDE topic, OLE target. ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalDocLink > mxDocLink; /// Interface for an external document. - IndexVector maIndexes; /// Internal sheet indexes or external sheet cache indexes. + Int16Vector maCalcSheets; /// Internal sheet indexes. + Int32Vector maSheetCaches; /// External sheet cache indexes. ExternalNameVector maExtNames; /// Defined names in external document. }; diff --git a/oox/inc/oox/xls/richstring.hxx b/oox/inc/oox/xls/richstring.hxx index 23a0801531ae..47a55e92c350 100644 --- a/oox/inc/oox/xls/richstring.hxx +++ b/oox/inc/oox/xls/richstring.hxx @@ -71,6 +71,9 @@ public: /** Final processing after import of all strings. */ void finalizeImport(); + /** Returns the text data of this portion. */ + inline const ::rtl::OUString& getText() const { return maText; } + /** Converts the portion and appends it to the passed XText. */ void convert( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >& rxText, @@ -254,6 +257,9 @@ public: /** Final processing after import of all strings. */ void finalizeImport(); + /** Returns the plain text concatenated from all string portions. */ + ::rtl::OUString getPlainText() const; + /** Converts the string and writes it into the passed XText. */ void convert( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >& rxText, diff --git a/oox/inc/oox/xls/stylesbuffer.hxx b/oox/inc/oox/xls/stylesbuffer.hxx index 13890aec7223..2b5b5bf3e7f7 100644 --- a/oox/inc/oox/xls/stylesbuffer.hxx +++ b/oox/inc/oox/xls/stylesbuffer.hxx @@ -38,6 +38,7 @@ #include #include #include "oox/helper/containerhelper.hxx" +#include "oox/drawingml/color.hxx" #include "oox/xls/numberformatsbuffer.hxx" namespace com { namespace sun { namespace star { @@ -46,8 +47,6 @@ namespace com { namespace sun { namespace star { namespace oox { class PropertySet; } -#define OOX_XLS_USE_DEFAULT_STYLE 0 - namespace oox { namespace xls { @@ -67,9 +66,6 @@ const sal_Int32 OOX_COLOR_FONTAUTO = 0x7FFF; /// Font auto color (sys // ---------------------------------------------------------------------------- -const sal_Int32 API_RGB_TRANSPARENT = -1; /// Transparent color for API calls. -const sal_Int32 API_RGB_BLACK = 0; /// Black color for API calls. - const sal_Int16 API_LINE_NONE = 0; const sal_Int16 API_LINE_HAIR = 2; const sal_Int16 API_LINE_THIN = 35; @@ -85,11 +81,9 @@ const sal_Int8 API_ESCAPEHEIGHT_DEFAULT = 58; /// Relative character h // ============================================================================ -class Color +class Color : public ::oox::drawingml::Color { public: - explicit Color(); - /** Sets the color to automatic. */ void setAuto(); /** Sets the color to the passed RGB value. */ @@ -115,23 +109,7 @@ public: void importColorRgb( BiffInputStream& rStrm ); /** Returns true, if the color is set to automatic. */ - bool isAuto() const; - /** Returns the RGB value of the color, or nAuto for automatic colors. */ - sal_Int32 getColor( const WorkbookHelper& rHelper, sal_Int32 nAuto = API_RGB_TRANSPARENT ) const; - -private: - enum ColorMode - { - COLOR_AUTO, /// Automatic color (dependent on context). - COLOR_RGB, /// Hexadecimal RGB color. - COLOR_THEME, /// Indexed theme color. - COLOR_INDEXED, /// Indexed palette color. - COLOR_FINAL /// Finalized RGB color (resolved theme, applied tint). - }; - - mutable ColorMode meMode; /// Current color mode. - mutable sal_Int32 mnValue; /// RGB value, palette index, scheme index. - double mfTint; /// Color tint (darken/lighten). + inline bool isAuto() const { return isPlaceHolder(); } }; // ---------------------------------------------------------------------------- @@ -851,8 +829,6 @@ struct CellStyleModel inline bool isBuiltin() const { return mbBuiltin && (mnBuiltinId >= 0); } /** Returns true, if this style represents the default document cell style. */ bool isDefaultStyle() const; - /** Returns the style name used in the UI. */ - ::rtl::OUString createStyleName() const; }; // ============================================================================ @@ -868,18 +844,29 @@ public: void importCellStyle( RecordInputStream& rStrm ); /** Imports style settings from a STYLE record. */ void importStyle( BiffInputStream& rStrm ); + /** Sets the final style name to be used in the document. */ + inline void setFinalStyleName( const ::rtl::OUString& rStyleName ) { maFinalName = rStyleName; } + /** Returns true, if this style is a builtin style. */ + inline bool isBuiltin() const { return maModel.isBuiltin(); } /** Returns true, if this style represents the default document cell style. */ inline bool isDefaultStyle() const { return maModel.isDefaultStyle(); } /** Returns the XF identifier for this cell style. */ inline sal_Int32 getXfId() const { return maModel.mnXfId; } - - /** Creates the style sheet described by the style XF with the passed identifier. */ - const ::rtl::OUString& createCellStyle( sal_Int32 nXfId, bool bSkipDefaultBuiltin = false ); + /** Calculates a readable style name according to the settings. */ + ::rtl::OUString calcInitialStyleName() const; + /** Returns the final style name used in the document. */ + inline const ::rtl::OUString& getFinalStyleName() const { return maFinalName; } + + /** Creates the style sheet in the document described by this cell style object. */ + void createCellStyle(); + /** Creates the cell style, if it is user-defined or modified built-in. */ + void finalizeImport(); private: CellStyleModel maModel; - ::rtl::OUString maCalcName; /// Final style name used in API. + ::rtl::OUString maFinalName; /// Final style name used in API. + bool mbCreated; /// True = style sheet created. }; typedef ::boost::shared_ptr< CellStyle > CellStyleRef; @@ -964,11 +951,8 @@ public: const ::rtl::OUString& createCellStyle( sal_Int32 nXfId ) const; /** Creates the style sheet described by the DXF with the passed identifier. */ const ::rtl::OUString& createDxfStyle( sal_Int32 nDxfId ) const; -#if OOX_XLS_USE_DEFAULT_STYLE -#else /** Returns the default style sheet for unused cells. */ const ::rtl::OUString& getDefaultStyleName() const; -#endif /** Writes the font attributes of the specified font data to the passed property map. */ void writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const; @@ -992,12 +976,13 @@ private: void insertCellStyle( CellStyleRef xCellStyle ); private: - typedef RefVector< Font > FontVec; - typedef RefVector< Border > BorderVec; - typedef RefVector< Fill > FillVec; - typedef RefVector< Xf > XfVec; - typedef RefVector< Dxf > DxfVec; - typedef RefMap< sal_Int32, CellStyle > CellStyleMap; + typedef RefVector< Font > FontVec; + typedef RefVector< Border > BorderVec; + typedef RefVector< Fill > FillVec; + typedef RefVector< Xf > XfVec; + typedef RefVector< Dxf > DxfVec; + typedef RefMap< sal_Int32, CellStyle > CellStyleIdMap; + typedef RefMap< ::rtl::OUString, CellStyle > CellStyleNameMap; ColorPalette maPalette; /// Color palette. FontVec maFonts; /// List of font objects. @@ -1007,7 +992,8 @@ private: XfVec maCellXfs; /// List of cell formats. XfVec maStyleXfs; /// List of cell styles. DxfVec maDxfs; /// List of differential cell styles. - CellStyleMap maCellStyles; /// List of named cell styles. + CellStyleIdMap maCellStylesById; /// List of named cell styles, mapped by XF identifier. + CellStyleNameMap maCellStylesByName; /// List of named cell styles, mapped by name. ::rtl::OUString maDefStyleName; /// API name of default cell style. sal_Int32 mnDefStyleXf; /// Style XF index of default cell style. }; diff --git a/oox/inc/oox/xls/themebuffer.hxx b/oox/inc/oox/xls/themebuffer.hxx index ca0a80d983fe..b1ee4b4ebc66 100644 --- a/oox/inc/oox/xls/themebuffer.hxx +++ b/oox/inc/oox/xls/themebuffer.hxx @@ -49,8 +49,6 @@ public: /** Returns the theme color with the specified token identifier. */ sal_Int32 getColorByToken( sal_Int32 nToken ) const; - /** Returns the theme color with the specified index. */ - sal_Int32 getColorByIndex( sal_Int32 nIndex ) const; /** Returns the default font data for the current file type. */ inline const FontModel& getDefaultFontModel() const { return *mxDefFontModel; } diff --git a/oox/inc/oox/xls/viewsettings.hxx b/oox/inc/oox/xls/viewsettings.hxx index fceb1bc1a63c..f18d0371c6c2 100644 --- a/oox/inc/oox/xls/viewsettings.hxx +++ b/oox/inc/oox/xls/viewsettings.hxx @@ -92,6 +92,8 @@ struct SheetViewModel sal_Int32 getNormalZoom() const; /** Returns the zoom in pagebreak preview (returns default, if current value is 0). */ sal_Int32 getPageBreakZoom() const; + /** Returns the grid color as RGB value. */ + sal_Int32 getGridColor( const ::oox::core::FilterBase& rFilter ) const; /** Returns the selection data, if available, otherwise 0. */ const PaneSelectionModel* getPaneSelection( sal_Int32 nPaneId ) const; @@ -186,23 +188,23 @@ public: void importWindow1( BiffInputStream& rStrm ); /** Stores converted view settings for a specific worksheet. */ - void setSheetViewSettings( sal_Int32 nSheet, + void setSheetViewSettings( sal_Int16 nSheet, const SheetViewModelRef& rxSheetView, const ::com::sun::star::uno::Any& rProperties ); /** Converts all imported document view settings. */ void finalizeImport(); - /** Returns the index of the active sheet. */ - sal_Int32 getActiveSheetIndex() const; + /** Returns the Calc index of the active sheet. */ + sal_Int16 getActiveCalcSheet() const; private: WorkbookViewModel& createWorkbookView(); private: typedef RefVector< WorkbookViewModel > WorkbookViewModelVec; - typedef RefMap< sal_Int32, SheetViewModel > SheetViewModelMap; - typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > SheetPropertiesMap; + typedef RefMap< sal_Int16, SheetViewModel > SheetViewModelMap; + typedef ::std::map< sal_Int16, ::com::sun::star::uno::Any > SheetPropertiesMap; WorkbookViewModelVec maBookViews; /// Workbook view models. SheetViewModelMap maSheetViews; /// Active view model for each sheet. diff --git a/oox/inc/oox/xls/workbookfragment.hxx b/oox/inc/oox/xls/workbookfragment.hxx index a691fcf5cf57..d3925f9113d8 100644 --- a/oox/inc/oox/xls/workbookfragment.hxx +++ b/oox/inc/oox/xls/workbookfragment.hxx @@ -94,7 +94,7 @@ private: /** Imports a sheet fragment with passed type from current stream position. */ bool importSheetFragment( ISegmentProgressBar& rProgressBar, - BiffFragmentType eFragment, sal_Int32 nSheet ); + BiffFragmentType eFragment, sal_Int16 nCalcSheet ); }; // ============================================================================ diff --git a/oox/inc/oox/xls/workbookhelper.hxx b/oox/inc/oox/xls/workbookhelper.hxx index 207b69184c1d..1c4210deabf6 100644 --- a/oox/inc/oox/xls/workbookhelper.hxx +++ b/oox/inc/oox/xls/workbookhelper.hxx @@ -253,7 +253,7 @@ public: /** Returns a reference to the specified spreadsheet in the document model. */ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > - getSheetFromDoc( sal_Int32 nSheet ) const; + getSheetFromDoc( sal_Int16 nSheet ) const; /** Returns a reference to the specified spreadsheet in the document model. */ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > getSheetFromDoc( const ::rtl::OUString& rSheet ) const; @@ -281,12 +281,11 @@ public: createNamedRangeObject( ::rtl::OUString& orName, sal_Int32 nNameFlags = 0 ) const; - /** Creates a com.sun.star.style.Style object and returns its final name. */ + /** Creates and returns a com.sun.star.style.Style object for cells or pages. */ ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > createStyleObject( ::rtl::OUString& orStyleName, - bool bPageStyle, - bool bRenameOldExisting = false ) const; + bool bPageStyle ) const; // buffers ---------------------------------------------------------------- @@ -361,7 +360,7 @@ public: /** Enables workbook file mode, used for BIFF4 workspace files. */ void setIsWorkbookFile(); /** Recreates global buffers that are used per sheet in specific BIFF versions. */ - void createBuffersPerSheet(); + void createBuffersPerSheet( sal_Int16 nSheet ); /** Returns the codec helper that stores the encoder/decoder object. */ BiffCodecHelper& getCodecHelper() const; diff --git a/oox/inc/oox/xls/worksheetbuffer.hxx b/oox/inc/oox/xls/worksheetbuffer.hxx index a4ebdedef7e2..327ff5c5638d 100644 --- a/oox/inc/oox/xls/worksheetbuffer.hxx +++ b/oox/inc/oox/xls/worksheetbuffer.hxx @@ -31,9 +31,8 @@ #ifndef OOX_XLS_WORKSHEETBUFFER_HXX #define OOX_XLS_WORKSHEETBUFFER_HXX -#include -#include #include +#include "oox/helper/containerhelper.hxx" #include "oox/xls/workbookhelper.hxx" namespace com { namespace sun { namespace star { @@ -50,7 +49,6 @@ struct SheetInfoModel { ::rtl::OUString maRelId; /// Relation identifier for the sheet substream. ::rtl::OUString maName; /// Original name of the sheet. - ::rtl::OUString maFinalName; /// Final (converted) name of the sheet. sal_Int32 mnSheetId; /// Sheet identifier. sal_Int32 mnState; /// Visibility state. @@ -70,6 +68,9 @@ class WorksheetBuffer : public WorkbookHelper public: explicit WorksheetBuffer( const WorkbookHelper& rHelper ); + /** Returns the base file name without path and file extension. */ + static ::rtl::OUString getBaseFileName( const ::rtl::OUString& rUrl ); + /** Initializes the buffer for single sheet files (BIFF2-BIFF4). */ void initializeSingleSheet(); @@ -79,34 +80,49 @@ public: void importSheet( RecordInputStream& rStrm ); /** Imports the SHEET record from the passed BIFF stream. */ void importSheet( BiffInputStream& rStrm ); - /** Inserts a new empty sheet into the document. Looks for an unused name. - @return Internal index of the new sheet. */ + @return Index of the new sheet in the Calc document. */ sal_Int16 insertEmptySheet( const ::rtl::OUString& rPreferredName, bool bVisible ); /** Returns the number of original sheets contained in the workbook. */ - sal_Int32 getSheetCount() const; - /** Returns the OOX relation identifier of the specified sheet. */ - ::rtl::OUString getSheetRelId( sal_Int32 nSheet ) const; - /** Returns the finalized name of the specified sheet. */ - ::rtl::OUString getCalcSheetName( sal_Int32 nSheet ) const; - /** Returns the finalized name of the sheet with the passed original name. */ - ::rtl::OUString getCalcSheetName( const ::rtl::OUString& rModelName ) const; - /** Returns the index of the sheet with the passed original name. */ - sal_Int32 getCalcSheetIndex( const ::rtl::OUString& rModelName ) const; + sal_Int32 getWorksheetCount() const; + /** Returns the OOX relation identifier of the specified worksheet. */ + ::rtl::OUString getWorksheetRelId( sal_Int32 nWorksheet ) const; + + /** Returns the Calc index of the specified worksheet. */ + sal_Int16 getCalcSheetIndex( sal_Int32 nWorksheet ) const; + /** Returns the finalized name of the specified worksheet. */ + ::rtl::OUString getCalcSheetName( sal_Int32 nWorksheet ) const; + + /** Returns the Calc index of the sheet with the passed original worksheet name. */ + sal_Int16 getCalcSheetIndex( const ::rtl::OUString& rWorksheetName ) const; + /** Returns the finalized name of the sheet with the passed worksheet name. */ + ::rtl::OUString getCalcSheetName( const ::rtl::OUString& rWorksheetName ) const; private: - typedef ::std::pair< sal_Int16, ::rtl::OUString > IndexNamePair; + struct SheetInfo : public SheetInfoModel + { + ::rtl::OUString maCalcName; + ::rtl::OUString maCalcQuotedName; + sal_Int16 mnCalcSheet; + + explicit SheetInfo( const SheetInfoModel& rModel, sal_Int16 nCalcSheet, const ::rtl::OUString& rCalcName ); + }; - const SheetInfoModel* getSheetInfo( sal_Int32 nSheet ) const; + typedef ::std::pair< sal_Int16, ::rtl::OUString > IndexNamePair; - IndexNamePair insertSheet( const ::rtl::OUString& rPreferredName, sal_Int16 nSheet, bool bVisible ); + /** Creates a new sheet in the Calc document. Does not insert anything in the own lists. */ + IndexNamePair createSheet( const ::rtl::OUString& rPreferredName, sal_Int32 nSheetPos, bool bVisible ); + /** Creates a new sheet in the Calc document and inserts the related SheetInfo. */ void insertSheet( const SheetInfoModel& rModel ); private: - typedef ::std::vector< SheetInfoModel > SheetInfoModelVec; + typedef RefVector< SheetInfo > SheetInfoVector; + SheetInfoVector maSheetInfos; - SheetInfoModelVec maSheetInfos; + struct SheetNameCompare { bool operator()( const ::rtl::OUString& rName1, const ::rtl::OUString& rName2 ) const; }; + typedef RefMap< ::rtl::OUString, SheetInfo, SheetNameCompare > SheetInfoMap; + SheetInfoMap maSheetInfosByName; }; // ============================================================================ diff --git a/oox/inc/oox/xls/worksheetfragment.hxx b/oox/inc/oox/xls/worksheetfragment.hxx index e5721265937f..110851ea9521 100644 --- a/oox/inc/oox/xls/worksheetfragment.hxx +++ b/oox/inc/oox/xls/worksheetfragment.hxx @@ -71,7 +71,7 @@ public: const ::rtl::OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); protected: // oox.core.ContextHandler2Helper interface ------------------------------- @@ -147,7 +147,7 @@ public: const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); virtual ~BiffWorksheetFragment(); /** Imports the entire worksheet fragment, returns true, if EOF record has been reached. */ diff --git a/oox/inc/oox/xls/worksheethelper.hxx b/oox/inc/oox/xls/worksheethelper.hxx index fc097783510b..7bb9b52ff117 100644 --- a/oox/inc/oox/xls/worksheethelper.hxx +++ b/oox/inc/oox/xls/worksheethelper.hxx @@ -175,8 +175,9 @@ struct PageBreakModel /** Stores data about a hyperlink range. */ struct HyperlinkModel : public ::oox::ole::StdHlinkInfo { - ::com::sun::star::table::CellRangeAddress maRange; - ::rtl::OUString maTooltip; + ::com::sun::star::table::CellRangeAddress + maRange; /// The cell area containing the hyperlink. + ::rtl::OUString maTooltip; /// Additional tooltip text. explicit HyperlinkModel(); }; @@ -442,7 +443,7 @@ protected: const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); /** Constructs from another sheet helper, does not create a data object. */ explicit WorksheetHelperRoot( diff --git a/oox/source/core/fasttokenhandler.cxx b/oox/source/core/fasttokenhandler.cxx new file mode 100644 index 000000000000..cb8841b7dc9f --- /dev/null +++ b/oox/source/core/fasttokenhandler.cxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tokenmap.cxx,v $ + * $Revision: 1.4 $ + * + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/core/fasttokenhandler.hxx" +#include +#include "oox/token/tokenmap.hxx" + +using ::rtl::OUString; +using ::osl::Mutex; +using ::osl::MutexGuard; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::RuntimeException; + +namespace oox { +namespace core { + +// ============================================================================ + +namespace { + +Mutex& lclGetTokenMutex() +{ + static Mutex aMutex; + return aMutex; +} + +} // namespace + +// ============================================================================ + +FastTokenHandler::FastTokenHandler() : + mrTokenMap( StaticTokenMap::get() ) +{ +} + +FastTokenHandler::~FastTokenHandler() +{ +} + +sal_Int32 FastTokenHandler::getToken( const OUString& rIdentifier ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getTokenFromUnicode( rIdentifier ); +} + +OUString FastTokenHandler::getIdentifier( sal_Int32 nToken ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getUnicodeTokenName( nToken ); +} + +Sequence< sal_Int8 > FastTokenHandler::getUTF8Identifier( sal_Int32 nToken ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getUtf8TokenName( nToken ); +} + +sal_Int32 FastTokenHandler::getTokenFromUTF8( const Sequence< sal_Int8 >& rIdentifier ) throw( RuntimeException ) +{ + MutexGuard aGuard( lclGetTokenMutex() ); + return mrTokenMap.getTokenFromUtf8( rIdentifier ); +} + +// ============================================================================ + +} // namespace core +} // namespace oox + diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index 55793859fe2e..d289255bac98 100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -471,7 +471,19 @@ sal_Int32 FilterBase::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) { FilterBaseImpl::SystemPalette::const_iterator aIt = mxImpl->maSystemPalette.find( nToken ); OSL_ENSURE( aIt != mxImpl->maSystemPalette.end(), "FilterBase::getSystemColor - invalid token identifier" ); - return (aIt == mxImpl->maSystemPalette.end()) ? ((nDefaultRgb < 0) ? API_RGB_WHITE : nDefaultRgb) : aIt->second; + return (aIt == mxImpl->maSystemPalette.end()) ? nDefaultRgb : aIt->second; +} + +sal_Int32 FilterBase::getSchemeColor( sal_Int32 /*nToken*/ ) const +{ + OSL_ENSURE( false, "FilterBase::getSchemeColor - scheme colors not implemented" ); + return API_RGB_TRANSPARENT; +} + +sal_Int32 FilterBase::getPaletteColor( sal_Int32 /*nPaletteIdx*/ ) const +{ + OSL_ENSURE( false, "FilterBase::getPaletteColor - palette colors not implemented" ); + return API_RGB_TRANSPARENT; } OUString FilterBase::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk index 51804e1d04c8..84d12776eadd 100644 --- a/oox/source/core/makefile.mk +++ b/oox/source/core/makefile.mk @@ -54,6 +54,7 @@ SLOFILES = \ $(SLO)$/contexthandler.obj \ $(SLO)$/contexthandler2.obj \ $(SLO)$/facreg.obj \ + $(SLO)$/fasttokenhandler.obj \ $(SLO)$/filterbase.obj \ $(SLO)$/filterdetect.obj \ $(SLO)$/fragmenthandler.obj \ diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index 27b3eef0ce60..07652c5c447b 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -32,6 +32,7 @@ #include +#include #include #include #include @@ -52,6 +53,7 @@ #include "oox/core/recordparser.hxx" #include "oox/core/relationshandler.hxx" +using ::rtl::OStringBuffer; using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::com::sun::star::beans::StringPair; @@ -209,8 +211,17 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r InputSource aSource; aSource.aInputStream = xInStrm; aSource.sSystemId = aFragmentPath; - xParser->parseStream( aSource ); - return true; + // own try/catch block for showing parser failure assertion with fragment path + try + { + xParser->parseStream( aSource ); + return true; + } + catch( Exception& ) + { + OSL_ENSURE( false, OStringBuffer( "XmlFilterBase::importFragment - XML parser failed in fragment '" ). + append( OUStringToOString( aFragmentPath, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); + } } catch( Exception& ) { diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx index 6ddb72bd3040..46253e92dd68 100644 --- a/oox/source/drawingml/chart/objectformatter.cxx +++ b/oox/source/drawingml/chart/objectformatter.cxx @@ -892,7 +892,7 @@ void LineFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Sh aLineProps.assignUsed( *mxAutoLine ); if( rxShapeProp.is() ) aLineProps.assignUsed( rxShapeProp->getLineProperties() ); - aLineProps.pushToPropSet( rPropSet, mrLinePropIds, mrData.mrFilter, mrData.maModelObjHelper, getPhColor( nSeriesIdx ) ); + aLineProps.pushToPropSet( rPropSet, mrData.mrFilter, mrData.maModelObjHelper, mrLinePropIds, getPhColor( nSeriesIdx ) ); } // ============================================================================ @@ -920,7 +920,7 @@ void FillFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Sh aFillProps.assignUsed( rxShapeProp->getFillProperties() ); if( pPicOptions ) lclConvertPictureOptions( aFillProps, *pPicOptions ); - aFillProps.pushToPropSet( rPropSet, mrFillPropIds, mrData.mrFilter, mrData.maModelObjHelper, 0, getPhColor( nSeriesIdx ) ); + aFillProps.pushToPropSet( rPropSet, mrData.mrFilter, mrData.maModelObjHelper, mrFillPropIds, 0, getPhColor( nSeriesIdx ) ); } // ============================================================================ diff --git a/oox/source/drawingml/clrschemecontext.cxx b/oox/source/drawingml/clrschemecontext.cxx index 6eedb908c00e..a8fa5d737c63 100644 --- a/oox/source/drawingml/clrschemecontext.cxx +++ b/oox/source/drawingml/clrschemecontext.cxx @@ -30,6 +30,7 @@ #include "oox/drawingml/clrschemecontext.hxx" #include "oox/core/namespaces.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "tokens.hxx" using namespace ::oox::core; diff --git a/oox/source/drawingml/color.cxx b/oox/source/drawingml/color.cxx index c269379b5adc..009be55424f3 100644 --- a/oox/source/drawingml/color.cxx +++ b/oox/source/drawingml/color.cxx @@ -29,11 +29,15 @@ ************************************************************************/ #include "oox/drawingml/color.hxx" -#include "oox/core/namespaces.hxx" -#include "oox/core/xmlfilterbase.hxx" -#include "tokens.hxx" #include #include +#include "tokens.hxx" +#include "oox/helper/containerhelper.hxx" +#include "oox/core/namespaces.hxx" +#include "oox/core/filterbase.hxx" +#include "oox/drawingml/drawingmltypes.hxx" + +using ::rtl::OUString; namespace oox { namespace drawingml { @@ -42,164 +46,127 @@ namespace drawingml { namespace { -const sal_Int32 PER_PERCENT = 1000; -const sal_Int32 MAX_PERCENT = 100 * PER_PERCENT; +/** Global storage for predefined color values used in OOXML file formats. */ +struct PresetColorsPool +{ + typedef ::std::vector< sal_Int32 > ColorVector; -const sal_Int32 PER_DEGREE = 60000; -const sal_Int32 MAX_DEGREE = 360 * PER_DEGREE; + ColorVector maDmlColors; /// Predefined colors in DrawingML, indexed by XML token. + ColorVector maVmlColors; /// Predefined colors in VML, indexed by XML token. -const double DEC_GAMMA = 2.3; -const double INC_GAMMA = 1.0 / DEC_GAMMA; + explicit PresetColorsPool(); +}; -sal_Int32 lclGetPresetColor( sal_Int32 nToken ) +// ---------------------------------------------------------------------------- + +PresetColorsPool::PresetColorsPool() : + maDmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ), + maVmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ) { - switch( nToken ) + // predefined colors in DrawingML (map XML token identifiers to RGB values) + static const sal_Int32 spnDmlColors[] = { - case XML_aliceBlue: return 0xF0F8FF; - case XML_antiqueWhite: return 0xFAEBD7; - case XML_aqua: return 0x00FFFF; - case XML_aquamarine: return 0x7FFFD4; - case XML_azure: return 0xF0FFFF; - case XML_beige: return 0xF5F5DC; - case XML_bisque: return 0xFFE4C4; - case XML_black: return 0x000000; - case XML_blanchedAlmond: return 0xFFEBCD; - case XML_blue: return 0x0000FF; - case XML_blueViolet: return 0x8A2BE2; - case XML_brown: return 0xA52A2A; - case XML_burlyWood: return 0xDEB887; - case XML_cadetBlue: return 0x5F9EA0; - case XML_chartreuse: return 0x7FFF00; - case XML_chocolate: return 0xD2691E; - case XML_coral: return 0xFF7F50; - case XML_cornflowerBlue: return 0x6495ED; - case XML_cornsilk: return 0xFFF8DC; - case XML_crimson: return 0xDC143C; - case XML_cyan: return 0x00FFFF; - case XML_deepPink: return 0xFF1493; - case XML_deepSkyBlue: return 0x00BFFF; - case XML_dimGray: return 0x696969; - case XML_dkBlue: return 0x00008B; - case XML_dkCyan: return 0x008B8B; - case XML_dkGoldenrod: return 0xB8860B; - case XML_dkGray: return 0xA9A9A9; - case XML_dkGreen: return 0x006400; - case XML_dkKhaki: return 0xBDB76B; - case XML_dkMagenta: return 0x8B008B; - case XML_dkOliveGreen: return 0x556B2F; - case XML_dkOrange: return 0xFF8C00; - case XML_dkOrchid: return 0x9932CC; - case XML_dkRed: return 0x8B0000; - case XML_dkSalmon: return 0xE9967A; - case XML_dkSeaGreen: return 0x8FBC8B; - case XML_dkSlateBlue: return 0x483D8B; - case XML_dkSlateGray: return 0x2F4F4F; - case XML_dkTurquoise: return 0x00CED1; - case XML_dkViolet: return 0x9400D3; - case XML_dodgerBlue: return 0x1E90FF; - case XML_firebrick: return 0xB22222; - case XML_floralWhite: return 0xFFFAF0; - case XML_forestGreen: return 0x228B22; - case XML_fuchsia: return 0xFF00FF; - case XML_gainsboro: return 0xDCDCDC; - case XML_ghostWhite: return 0xF8F8FF; - case XML_gold: return 0xFFD700; - case XML_goldenrod: return 0xDAA520; - case XML_gray: return 0x808080; - case XML_green: return 0x008000; - case XML_greenYellow: return 0xADFF2F; - case XML_honeydew: return 0xF0FFF0; - case XML_hotPink: return 0xFF69B4; - case XML_indianRed: return 0xCD5C5C; - case XML_indigo: return 0x4B0082; - case XML_ivory: return 0xFFFFF0; - case XML_khaki: return 0xF0E68C; - case XML_lavender: return 0xE6E6FA; - case XML_lavenderBlush: return 0xFFF0F5; - case XML_lawnGreen: return 0x7CFC00; - case XML_lemonChiffon: return 0xFFFACD; - case XML_lime: return 0x00FF00; - case XML_limeGreen: return 0x32CD32; - case XML_linen: return 0xFAF0E6; - case XML_ltBlue: return 0xADD8E6; - case XML_ltCoral: return 0xF08080; - case XML_ltCyan: return 0xE0FFFF; - case XML_ltGoldenrodYellow: return 0xFAFA78; - case XML_ltGray: return 0xD3D3D3; - case XML_ltGreen: return 0x90EE90; - case XML_ltPink: return 0xFFB6C1; - case XML_ltSalmon: return 0xFFA07A; - case XML_ltSeaGreen: return 0x20B2AA; - case XML_ltSkyBlue: return 0x87CEFA; - case XML_ltSlateGray: return 0x778899; - case XML_ltSteelBlue: return 0xB0C4DE; - case XML_ltYellow: return 0xFFFFE0; - case XML_magenta: return 0xFF00FF; - case XML_maroon: return 0x800000; - case XML_medAquamarine: return 0x66CDAA; - case XML_medBlue: return 0x0000CD; - case XML_medOrchid: return 0xBA55D3; - case XML_medPurple: return 0x9370DB; - case XML_medSeaGreen: return 0x3CB371; - case XML_medSlateBlue: return 0x7B68EE; - case XML_medSpringGreen: return 0x00FA9A; - case XML_medTurquoise: return 0x48D1CC; - case XML_medVioletRed: return 0xC71585; - case XML_midnightBlue: return 0x191970; - case XML_mintCream: return 0xF5FFFA; - case XML_mistyRose: return 0xFFE4E1; - case XML_moccasin: return 0xFFE4B5; - case XML_navajoWhite: return 0xFFDEAD; - case XML_navy: return 0x000080; - case XML_oldLace: return 0xFDF5E6; - case XML_olive: return 0x808000; - case XML_oliveDrab: return 0x6B8E23; - case XML_orange: return 0xFFA500; - case XML_orangeRed: return 0xFF4500; - case XML_orchid: return 0xDA70D6; - case XML_paleGoldenrod: return 0xEEE8AA; - case XML_paleGreen: return 0x98FB98; - case XML_paleTurquoise: return 0xAFEEEE; - case XML_paleVioletRed: return 0xDB7093; - case XML_papayaWhip: return 0xFFEFD5; - case XML_peachPuff: return 0xFFDAB9; - case XML_peru: return 0xCD853F; - case XML_pink: return 0xFFC0CB; - case XML_plum: return 0xDDA0DD; - case XML_powderBlue: return 0xB0E0E6; - case XML_purple: return 0x800080; - case XML_red: return 0xFF0000; - case XML_rosyBrown: return 0xBC8F8F; - case XML_royalBlue: return 0x4169E1; - case XML_saddleBrown: return 0x8B4513; - case XML_salmon: return 0xFA8072; - case XML_sandyBrown: return 0xF4A460; - case XML_seaGreen: return 0x2E8B57; - case XML_seaShell: return 0xFFF5EE; - case XML_sienna: return 0xA0522D; - case XML_silver: return 0xC0C0C0; - case XML_skyBlue: return 0x87CEEB; - case XML_slateBlue: return 0x6A5ACD; - case XML_slateGray: return 0x708090; - case XML_snow: return 0xFFFAFA; - case XML_springGreen: return 0x00FF7F; - case XML_steelBlue: return 0x4682B4; - case XML_tan: return 0xD2B48C; - case XML_teal: return 0x008080; - case XML_thistle: return 0xD8BFD8; - case XML_tomato: return 0xFF6347; - case XML_turquoise: return 0x40E0D0; - case XML_violet: return 0xEE82EE; - case XML_wheat: return 0xF5DEB3; - case XML_white: return 0xFFFFFF; - case XML_whiteSmoke: return 0xF5F5F5; - case XML_yellow: return 0xFFFF00; - case XML_yellowGreen: return 0x9ACD32; - } - OSL_ENSURE( false, "lclGetPresetColor - invalid preset color token" ); - return API_RGB_BLACK; + XML_aliceBlue, 0xF0F8FF, XML_antiqueWhite, 0xFAEBD7, + XML_aqua, 0x00FFFF, XML_aquamarine, 0x7FFFD4, + XML_azure, 0xF0FFFF, XML_beige, 0xF5F5DC, + XML_bisque, 0xFFE4C4, XML_black, 0x000000, + XML_blanchedAlmond, 0xFFEBCD, XML_blue, 0x0000FF, + XML_blueViolet, 0x8A2BE2, XML_brown, 0xA52A2A, + XML_burlyWood, 0xDEB887, XML_cadetBlue, 0x5F9EA0, + XML_chartreuse, 0x7FFF00, XML_chocolate, 0xD2691E, + XML_coral, 0xFF7F50, XML_cornflowerBlue, 0x6495ED, + XML_cornsilk, 0xFFF8DC, XML_crimson, 0xDC143C, + XML_cyan, 0x00FFFF, XML_deepPink, 0xFF1493, + XML_deepSkyBlue, 0x00BFFF, XML_dimGray, 0x696969, + XML_dkBlue, 0x00008B, XML_dkCyan, 0x008B8B, + XML_dkGoldenrod, 0xB8860B, XML_dkGray, 0xA9A9A9, + XML_dkGreen, 0x006400, XML_dkKhaki, 0xBDB76B, + XML_dkMagenta, 0x8B008B, XML_dkOliveGreen, 0x556B2F, + XML_dkOrange, 0xFF8C00, XML_dkOrchid, 0x9932CC, + XML_dkRed, 0x8B0000, XML_dkSalmon, 0xE9967A, + XML_dkSeaGreen, 0x8FBC8B, XML_dkSlateBlue, 0x483D8B, + XML_dkSlateGray, 0x2F4F4F, XML_dkTurquoise, 0x00CED1, + XML_dkViolet, 0x9400D3, XML_dodgerBlue, 0x1E90FF, + XML_firebrick, 0xB22222, XML_floralWhite, 0xFFFAF0, + XML_forestGreen, 0x228B22, XML_fuchsia, 0xFF00FF, + XML_gainsboro, 0xDCDCDC, XML_ghostWhite, 0xF8F8FF, + XML_gold, 0xFFD700, XML_goldenrod, 0xDAA520, + XML_gray, 0x808080, XML_green, 0x008000, + XML_greenYellow, 0xADFF2F, XML_honeydew, 0xF0FFF0, + XML_hotPink, 0xFF69B4, XML_indianRed, 0xCD5C5C, + XML_indigo, 0x4B0082, XML_ivory, 0xFFFFF0, + XML_khaki, 0xF0E68C, XML_lavender, 0xE6E6FA, + XML_lavenderBlush, 0xFFF0F5, XML_lawnGreen, 0x7CFC00, + XML_lemonChiffon, 0xFFFACD, XML_lime, 0x00FF00, + XML_limeGreen, 0x32CD32, XML_linen, 0xFAF0E6, + XML_ltBlue, 0xADD8E6, XML_ltCoral, 0xF08080, + XML_ltCyan, 0xE0FFFF, XML_ltGoldenrodYellow, 0xFAFA78, + XML_ltGray, 0xD3D3D3, XML_ltGreen, 0x90EE90, + XML_ltPink, 0xFFB6C1, XML_ltSalmon, 0xFFA07A, + XML_ltSeaGreen, 0x20B2AA, XML_ltSkyBlue, 0x87CEFA, + XML_ltSlateGray, 0x778899, XML_ltSteelBlue, 0xB0C4DE, + XML_ltYellow, 0xFFFFE0, XML_magenta, 0xFF00FF, + XML_maroon, 0x800000, XML_medAquamarine, 0x66CDAA, + XML_medBlue, 0x0000CD, XML_medOrchid, 0xBA55D3, + XML_medPurple, 0x9370DB, XML_medSeaGreen, 0x3CB371, + XML_medSlateBlue, 0x7B68EE, XML_medSpringGreen, 0x00FA9A, + XML_medTurquoise, 0x48D1CC, XML_medVioletRed, 0xC71585, + XML_midnightBlue, 0x191970, XML_mintCream, 0xF5FFFA, + XML_mistyRose, 0xFFE4E1, XML_moccasin, 0xFFE4B5, + XML_navajoWhite, 0xFFDEAD, XML_navy, 0x000080, + XML_oldLace, 0xFDF5E6, XML_olive, 0x808000, + XML_oliveDrab, 0x6B8E23, XML_orange, 0xFFA500, + XML_orangeRed, 0xFF4500, XML_orchid, 0xDA70D6, + XML_paleGoldenrod, 0xEEE8AA, XML_paleGreen, 0x98FB98, + XML_paleTurquoise, 0xAFEEEE, XML_paleVioletRed, 0xDB7093, + XML_papayaWhip, 0xFFEFD5, XML_peachPuff, 0xFFDAB9, + XML_peru, 0xCD853F, XML_pink, 0xFFC0CB, + XML_plum, 0xDDA0DD, XML_powderBlue, 0xB0E0E6, + XML_purple, 0x800080, XML_red, 0xFF0000, + XML_rosyBrown, 0xBC8F8F, XML_royalBlue, 0x4169E1, + XML_saddleBrown, 0x8B4513, XML_salmon, 0xFA8072, + XML_sandyBrown, 0xF4A460, XML_seaGreen, 0x2E8B57, + XML_seaShell, 0xFFF5EE, XML_sienna, 0xA0522D, + XML_silver, 0xC0C0C0, XML_skyBlue, 0x87CEEB, + XML_slateBlue, 0x6A5ACD, XML_slateGray, 0x708090, + XML_snow, 0xFFFAFA, XML_springGreen, 0x00FF7F, + XML_steelBlue, 0x4682B4, XML_tan, 0xD2B48C, + XML_teal, 0x008080, XML_thistle, 0xD8BFD8, + XML_tomato, 0xFF6347, XML_turquoise, 0x40E0D0, + XML_violet, 0xEE82EE, XML_wheat, 0xF5DEB3, + XML_white, 0xFFFFFF, XML_whiteSmoke, 0xF5F5F5, + XML_yellow, 0xFFFF00, XML_yellowGreen, 0x9ACD32 + }; + for( const sal_Int32* pnEntry = spnDmlColors; pnEntry < STATIC_ARRAY_END( spnDmlColors ); pnEntry += 2 ) + maDmlColors[ static_cast< size_t >( pnEntry[ 0 ] ) ] = pnEntry[ 1 ]; + + // predefined colors in VML (map XML token identifiers to RGB values) + static const sal_Int32 spnVmlColors[] = + { + XML_aqua, 0x00FFFF, XML_black, 0x000000, + XML_blue, 0x0000FF, XML_fuchsia, 0xFF00FF, + XML_gray, 0x808080, XML_green, 0x008000, + XML_lime, 0x00FF00, XML_maroon, 0x800000, + XML_navy, 0x000080, XML_olive, 0x808000, + XML_purple, 0x800080, XML_red, 0xFF0000, + XML_silver, 0xC0C0C0, XML_teal, 0x008080, + XML_white, 0xFFFFFF, XML_yellow, 0xFFFF00 + }; + for( const sal_Int32* pnEntry = spnVmlColors; pnEntry < STATIC_ARRAY_END( spnVmlColors ); pnEntry += 2 ) + maVmlColors[ static_cast< size_t >( pnEntry[ 0 ] ) ] = pnEntry[ 1 ]; } +// ---------------------------------------------------------------------------- + +struct StaticPresetColorsPool : public ::rtl::Static< PresetColorsPool, StaticPresetColorsPool > {}; + +// ---------------------------------------------------------------------------- + +const double DEC_GAMMA = 2.3; +const double INC_GAMMA = 1.0 / DEC_GAMMA; + +// ---------------------------------------------------------------------------- + inline void lclRgbToRgbComponents( sal_Int32& ornR, sal_Int32& ornG, sal_Int32& ornB, sal_Int32 nRgb ) { ornR = (nRgb >> 16) & 0xFF; @@ -248,7 +215,7 @@ void lclOffValue( sal_Int32& ornValue, sal_Int32 nOff, sal_Int32 nMax = MAX_PERC } // namespace -// ---------------------------------------------------------------------------- +// ============================================================================ Color::Color() : meMode( COLOR_UNUSED ), @@ -263,6 +230,24 @@ Color::~Color() { } +/*static*/ sal_Int32 Color::getDmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) +{ + /* Do not pass nDefaultRgb to ContainerHelper::getVectorElement(), to be + able to catch the existing vector entries without corresponding XML + token identifier. */ + sal_Int32 nRgbValue = ContainerHelper::getVectorElement( StaticPresetColorsPool::get().maDmlColors, nToken, API_RGB_TRANSPARENT ); + return (nRgbValue >= 0) ? nRgbValue : nDefaultRgb; +} + +/*static*/ sal_Int32 Color::getVmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) +{ + /* Do not pass nDefaultRgb to ContainerHelper::getVectorElement(), to be + able to catch the existing vector entries without corresponding XML + token identifier. */ + sal_Int32 nRgbValue = ContainerHelper::getVectorElement( StaticPresetColorsPool::get().maVmlColors, nToken, API_RGB_TRANSPARENT ); + return (nRgbValue >= 0) ? nRgbValue : nDefaultRgb; +} + void Color::setUnused() { meMode = COLOR_UNUSED; @@ -299,7 +284,10 @@ void Color::setHslClr( sal_Int32 nHue, sal_Int32 nSat, sal_Int32 nLum ) void Color::setPrstClr( sal_Int32 nToken ) { - setSrgbClr( lclGetPresetColor( nToken ) ); + sal_Int32 nRgbValue = getDmlPresetColor( nToken, API_RGB_TRANSPARENT ); + OSL_ENSURE( nRgbValue >= 0, "Color::setPrstClr - invalid preset color token" ); + if( nRgbValue >= 0 ) + setSrgbClr( nRgbValue ); } void Color::setSchemeClr( sal_Int32 nToken ) @@ -309,6 +297,13 @@ void Color::setSchemeClr( sal_Int32 nToken ) mnC1 = nToken; } +void Color::setPaletteClr( sal_Int32 nPaletteIdx ) +{ + OSL_ENSURE( nPaletteIdx >= 0, "Color::setPaletteClr - invalid palette index" ); + meMode = COLOR_PALETTE; + mnC1 = nPaletteIdx; +} + void Color::setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb ) { OSL_ENSURE( (-1 <= nLastRgb) && (nLastRgb <= 0xFFFFFF), "Color::setSysClr - invalid RGB value" ); @@ -347,12 +342,18 @@ void Color::addExcelTintTransformation( double fTint ) maTransforms.push_back( Transformation( NMSP_XLS | XML_tint, nValue ) ); } +void Color::clearTransformations() +{ + maTransforms.clear(); + clearTransparence(); +} + void Color::clearTransparence() { mnAlpha = MAX_PERCENT; } -sal_Int32 Color::getColor( const ::oox::core::XmlFilterBase& rFilter, sal_Int32 nPhClr ) const +sal_Int32 Color::getColor( const ::oox::core::FilterBase& rFilter, sal_Int32 nPhClr ) const { /* Special handling for theme style list placeholder colors (state COLOR_PH), Color::getColor() may be called with different placeholder @@ -364,151 +365,154 @@ sal_Int32 Color::getColor( const ::oox::core::XmlFilterBase& rFilter, sal_Int32 switch( meMode ) { - case COLOR_UNUSED: return -1; - case COLOR_FINAL: return mnC1; + case COLOR_UNUSED: mnC1 = API_RGB_TRANSPARENT; break; case COLOR_RGB: break; // nothing to do case COLOR_CRGB: break; // nothing to do case COLOR_HSL: break; // nothing to do - case COLOR_SCHEME: - meMode = COLOR_RGB; - lclRgbToRgbComponents( mnC1, mnC2, mnC3, rFilter.getSchemeClr( mnC1 ) ); - break; - case COLOR_PH: - meMode = COLOR_RGB; - lclRgbToRgbComponents( mnC1, mnC2, mnC3, nPhClr ); - bIsPh = true; - break; - case COLOR_SYSTEM: - meMode = COLOR_RGB; - lclRgbToRgbComponents( mnC1, mnC2, mnC3, rFilter.getSystemColor( mnC1, mnC2 ) ); - break; + case COLOR_SCHEME: setResolvedRgb( rFilter.getSchemeColor( mnC1 ) ); break; + case COLOR_PALETTE: setResolvedRgb( rFilter.getPaletteColor( mnC1 ) ); break; + case COLOR_SYSTEM: setResolvedRgb( rFilter.getSystemColor( mnC1, mnC2 ) ); break; + case COLOR_PH: setResolvedRgb( nPhClr ); bIsPh = true; break; + + case COLOR_FINAL: return mnC1; } - for( TransformVec::const_iterator aIt = maTransforms.begin(), aEnd = maTransforms.end(); aIt != aEnd; ++aIt ) + // if color is UNUSED or turns to UNUSED in setResolvedRgb, do not perform transformations + if( meMode != COLOR_UNUSED ) { - switch( aIt->mnToken ) + for( TransformVec::const_iterator aIt = maTransforms.begin(), aEnd = maTransforms.end(); aIt != aEnd; ++aIt ) { - case XML_red: toCrgb(); lclSetValue( mnC1, aIt->mnValue ); break; - case XML_redMod: toCrgb(); lclModValue( mnC1, aIt->mnValue ); break; - case XML_redOff: toCrgb(); lclOffValue( mnC1, aIt->mnValue ); break; - case XML_green: toCrgb(); lclSetValue( mnC2, aIt->mnValue ); break; - case XML_greenMod: toCrgb(); lclModValue( mnC2, aIt->mnValue ); break; - case XML_greenOff: toCrgb(); lclOffValue( mnC2, aIt->mnValue ); break; - case XML_blue: toCrgb(); lclSetValue( mnC3, aIt->mnValue ); break; - case XML_blueMod: toCrgb(); lclModValue( mnC3, aIt->mnValue ); break; - case XML_blueOff: toCrgb(); lclOffValue( mnC3, aIt->mnValue ); break; - - case XML_hue: toHsl(); lclSetValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; - case XML_hueMod: toHsl(); lclModValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; - case XML_hueOff: toHsl(); lclOffValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; - case XML_sat: toHsl(); lclSetValue( mnC2, aIt->mnValue ); break; - case XML_satMod: toHsl(); lclModValue( mnC2, aIt->mnValue ); break; - case XML_satOff: toHsl(); lclOffValue( mnC2, aIt->mnValue ); break; - - case XML_lum: - toHsl(); - lclSetValue( mnC3, aIt->mnValue ); - // if color changes to black or white, it will stay gray if luminance changes again - if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; - break; - case XML_lumMod: - toHsl(); - lclModValue( mnC3, aIt->mnValue ); - // if color changes to black or white, it will stay gray if luminance changes again - if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; - break; - case XML_lumOff: - toHsl(); - lclOffValue( mnC3, aIt->mnValue ); - // if color changes to black or white, it will stay gray if luminance changes again - if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; - break; - - case XML_shade: - // shade: 0% = black, 100% = original color - toCrgb(); - OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid shade value" ); - if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) - { - double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; - mnC1 = static_cast< sal_Int32 >( mnC1 * fFactor ); - mnC2 = static_cast< sal_Int32 >( mnC2 * fFactor ); - mnC3 = static_cast< sal_Int32 >( mnC3 * fFactor ); - } - break; - case XML_tint: - // tint: 0% = white, 100% = original color - toCrgb(); - OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); - if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) - { - double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; - mnC1 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC1) * fFactor ); - mnC2 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC2) * fFactor ); - mnC3 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC3) * fFactor ); - } - break; - case XLS_TOKEN( tint ): - // Excel tint: move luminance relative to current value - toHsl(); - OSL_ENSURE( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); - if( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue < 0) ) - { - // negative: luminance towards 0% (black) - lclModValue( mnC3, aIt->mnValue + MAX_PERCENT ); - } - else if( (0 < aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) - { - // positive: luminance towards 100% (white) - mnC3 = MAX_PERCENT - mnC3; - lclModValue( mnC3, MAX_PERCENT - aIt->mnValue ); + switch( aIt->mnToken ) + { + case XML_red: toCrgb(); lclSetValue( mnC1, aIt->mnValue ); break; + case XML_redMod: toCrgb(); lclModValue( mnC1, aIt->mnValue ); break; + case XML_redOff: toCrgb(); lclOffValue( mnC1, aIt->mnValue ); break; + case XML_green: toCrgb(); lclSetValue( mnC2, aIt->mnValue ); break; + case XML_greenMod: toCrgb(); lclModValue( mnC2, aIt->mnValue ); break; + case XML_greenOff: toCrgb(); lclOffValue( mnC2, aIt->mnValue ); break; + case XML_blue: toCrgb(); lclSetValue( mnC3, aIt->mnValue ); break; + case XML_blueMod: toCrgb(); lclModValue( mnC3, aIt->mnValue ); break; + case XML_blueOff: toCrgb(); lclOffValue( mnC3, aIt->mnValue ); break; + + case XML_hue: toHsl(); lclSetValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; + case XML_hueMod: toHsl(); lclModValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; + case XML_hueOff: toHsl(); lclOffValue( mnC1, aIt->mnValue, MAX_DEGREE ); break; + case XML_sat: toHsl(); lclSetValue( mnC2, aIt->mnValue ); break; + case XML_satMod: toHsl(); lclModValue( mnC2, aIt->mnValue ); break; + case XML_satOff: toHsl(); lclOffValue( mnC2, aIt->mnValue ); break; + + case XML_lum: + toHsl(); + lclSetValue( mnC3, aIt->mnValue ); + // if color changes to black or white, it will stay gray if luminance changes again + if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; + break; + case XML_lumMod: + toHsl(); + lclModValue( mnC3, aIt->mnValue ); + // if color changes to black or white, it will stay gray if luminance changes again + if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; + break; + case XML_lumOff: + toHsl(); + lclOffValue( mnC3, aIt->mnValue ); + // if color changes to black or white, it will stay gray if luminance changes again + if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0; + break; + + case XML_shade: + // shade: 0% = black, 100% = original color + toCrgb(); + OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid shade value" ); + if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) + { + double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; + mnC1 = static_cast< sal_Int32 >( mnC1 * fFactor ); + mnC2 = static_cast< sal_Int32 >( mnC2 * fFactor ); + mnC3 = static_cast< sal_Int32 >( mnC3 * fFactor ); + } + break; + case XML_tint: + // tint: 0% = white, 100% = original color + toCrgb(); + OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); + if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) + { + double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT; + mnC1 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC1) * fFactor ); + mnC2 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC2) * fFactor ); + mnC3 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC3) * fFactor ); + } + break; + case XLS_TOKEN( tint ): + // Excel tint: move luminance relative to current value + toHsl(); + OSL_ENSURE( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" ); + if( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue < 0) ) + { + // negative: luminance towards 0% (black) + lclModValue( mnC3, aIt->mnValue + MAX_PERCENT ); + } + else if( (0 < aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) ) + { + // positive: luminance towards 100% (white) + mnC3 = MAX_PERCENT - mnC3; + lclModValue( mnC3, MAX_PERCENT - aIt->mnValue ); + mnC3 = MAX_PERCENT - mnC3; + } + break; + + case XML_gray: + // change color to gray, weighted RGB: 22% red, 72% green, 6% blue + toRgb(); + mnC1 = mnC2 = mnC3 = (mnC1 * 22 + mnC2 * 72 + mnC3 * 6) / 100; + break; + + case XML_comp: + // comp: rotate hue by 180 degrees, do not change lum/sat + toHsl(); + (mnC1 += 180 * PER_DEGREE) %= MAX_DEGREE; + break; + case XML_inv: + // invert percentual RGB values + toCrgb(); + mnC1 = MAX_PERCENT - mnC1; + mnC2 = MAX_PERCENT - mnC2; mnC3 = MAX_PERCENT - mnC3; - } - break; - - case XML_gray: - // change color to gray, weighted RGB: 22% red, 72% green, 6% blue - toRgb(); - mnC1 = mnC2 = mnC3 = (mnC1 * 22 + mnC2 * 72 + mnC3 * 6) / 100; - break; - - case XML_comp: - // comp: rotate hue by 180 degrees, do not change lum/sat - toHsl(); - (mnC1 += 180 * PER_DEGREE) %= MAX_DEGREE; - break; - case XML_inv: - // invert percentual RGB values - toCrgb(); - mnC1 = MAX_PERCENT - mnC1; - mnC2 = MAX_PERCENT - mnC2; - mnC3 = MAX_PERCENT - mnC3; - break; - - case XML_gamma: - // increase gamma of color - toCrgb(); - mnC1 = lclGamma( mnC1, INC_GAMMA ); - mnC2 = lclGamma( mnC2, INC_GAMMA ); - mnC3 = lclGamma( mnC3, INC_GAMMA ); - break; - case XML_invGamma: - // decrease gamma of color - toCrgb(); - mnC1 = lclGamma( mnC1, DEC_GAMMA ); - mnC2 = lclGamma( mnC2, DEC_GAMMA ); - mnC3 = lclGamma( mnC3, DEC_GAMMA ); - break; + break; + + case XML_gamma: + // increase gamma of color + toCrgb(); + mnC1 = lclGamma( mnC1, INC_GAMMA ); + mnC2 = lclGamma( mnC2, INC_GAMMA ); + mnC3 = lclGamma( mnC3, INC_GAMMA ); + break; + case XML_invGamma: + // decrease gamma of color + toCrgb(); + mnC1 = lclGamma( mnC1, DEC_GAMMA ); + mnC2 = lclGamma( mnC2, DEC_GAMMA ); + mnC3 = lclGamma( mnC3, DEC_GAMMA ); + break; + } } + + // store resulting RGB value in mnC1 + toRgb(); + mnC1 = lclRgbComponentsToRgb( mnC1, mnC2, mnC3 ); + } + else // if( meMode != COLOR_UNUSED ) + { + mnC1 = API_RGB_TRANSPARENT; } - toRgb(); meMode = bIsPh ? COLOR_PH : COLOR_FINAL; if( meMode == COLOR_FINAL ) maTransforms.clear(); - return mnC1 = lclRgbComponentsToRgb( mnC1, mnC2, mnC3 ); + return mnC1; } bool Color::hasTransparence() const @@ -523,6 +527,12 @@ sal_Int16 Color::getTransparence() const // private -------------------------------------------------------------------- +void Color::setResolvedRgb( sal_Int32 nRgb ) const +{ + meMode = (nRgb < 0) ? COLOR_UNUSED : COLOR_RGB; + lclRgbToRgbComponents( mnC1, mnC2, mnC3, nRgb ); +} + void Color::toRgb() const { switch( meMode ) diff --git a/oox/source/drawingml/customshapeproperties.cxx b/oox/source/drawingml/customshapeproperties.cxx index 5a1756e6d110..fdede72a7e8e 100644 --- a/oox/source/drawingml/customshapeproperties.cxx +++ b/oox/source/drawingml/customshapeproperties.cxx @@ -63,7 +63,7 @@ void CustomShapeProperties::apply( const CustomShapePropertiesPtr& /* rSourceCus // not sure if this needs to be implemented } -void CustomShapeProperties::pushToPropSet( const ::oox::core::XmlFilterBase& /* rFilterBase */, +void CustomShapeProperties::pushToPropSet( const ::oox::core::FilterBase& /* rFilterBase */, const Reference < XPropertySet >& xPropSet, const Reference < XShape > & xShape ) const { if ( maShapePresetType.getLength() ) diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index 46fe6ae5292c..f6a72c3aafce 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -44,7 +44,8 @@ #include "oox/helper/modelobjecthelper.hxx" #include "oox/helper/propertymap.hxx" #include "oox/helper/propertyset.hxx" -#include "oox/core/xmlfilterbase.hxx" +#include "oox/core/filterbase.hxx" +#include "oox/drawingml/drawingmltypes.hxx" using namespace ::com::sun::star; using namespace ::com::sun::star::drawing; @@ -55,7 +56,8 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; -using ::oox::core::XmlFilterBase; +using ::com::sun::star::geometry::IntegerRectangle2D; +using ::oox::core::FilterBase; namespace oox { namespace drawingml { @@ -106,7 +108,7 @@ RectanglePoint lclGetRectanglePoint( sal_Int32 nToken ) return RectanglePoint_LEFT_TOP; } -const awt::Size lclGetOriginalSize( const XmlFilterBase& rFilter, const Reference< XGraphic >& rxGraphic ) +const awt::Size lclGetOriginalSize( const FilterBase& rFilter, const Reference< XGraphic >& rxGraphic ) { awt::Size aSize100thMM( 0, 0 ); try @@ -222,8 +224,8 @@ Color FillProperties::getBestSolidColor() const return aSolidColor; } -void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, +void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const FillPropertyIds& rPropIds, sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const { if( moFillType.has() ) @@ -254,7 +256,8 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds aGradient.StartIntensity = 100; aGradient.EndIntensity = 100; - if( maGradientProps.maGradientStops.size() > 1 ) + size_t nColorCount = maGradientProps.maGradientStops.size(); + if( nColorCount > 1 ) { aGradient.StartColor = maGradientProps.maGradientStops.begin()->second.getColor( rFilter, nPhClr ); aGradient.EndColor = maGradientProps.maGradientStops.rbegin()->second.getColor( rFilter, nPhClr ); @@ -264,19 +267,36 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds if ( !maGradientProps.moRotateWithShape.get( false ) ) nShapeRotation = 0; + sal_Int32 nDmlAngle = 0; if( maGradientProps.moGradientPath.has() ) { aGradient.Style = (maGradientProps.moGradientPath.get() == XML_circle) ? awt::GradientStyle_ELLIPTICAL : awt::GradientStyle_RECT; - aGradient.Angle = static_cast< sal_Int16 >( (900 - (nShapeRotation / 6000)) % 3600 ); - aGradient.XOffset = maGradientProps.moFillToRect.has() ? getLimitedValue< sal_Int16, sal_Int32 >( maGradientProps.moFillToRect.get().X1 / 1000, 30, 70 ) : 50; - aGradient.YOffset = maGradientProps.moFillToRect.has() ? getLimitedValue< sal_Int16, sal_Int32 >( maGradientProps.moFillToRect.get().Y1 / 1000, 30, 70 ) : 50; + // position of gradient center (limited to [30%;70%], otherwise gradient is too hidden) + IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.get( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) ); + sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2; + aGradient.XOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterX / PER_PERCENT, 30, 70 ); + sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2; + aGradient.YOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterY / PER_PERCENT, 30, 70 ); ::std::swap( aGradient.StartColor, aGradient.EndColor ); + nDmlAngle = nShapeRotation; } else { - aGradient.Style = awt::GradientStyle_LINEAR; - aGradient.Angle = static_cast< sal_Int16 >( (4500 - ((maGradientProps.moShadeAngle.get( 0 ) - nShapeRotation) / 6000)) % 3600 ); + /* Try to detect a VML axial gradient. This type of + gradient is simulated by a 3-point linear gradient + with equal start and end color. */ + bool bAxial = (nColorCount == 3) && (aGradient.StartColor == aGradient.EndColor); + aGradient.Style = bAxial ? awt::GradientStyle_AXIAL : awt::GradientStyle_LINEAR; + if( bAxial ) + { + GradientFillProperties::GradientStopMap::const_iterator aIt = maGradientProps.maGradientStops.begin(); + // API StartColor is inner color in axial gradient + aGradient.StartColor = (++aIt)->second.getColor( rFilter, nPhClr ); + } + nDmlAngle = maGradientProps.moShadeAngle.get( 0 ) - nShapeRotation; } + // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees) + aGradient.Angle = static_cast< sal_Int16 >( (4500 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 ); // push gradient or named gradient to property map if( rPropIds.mbNamedFillGradient ) @@ -340,10 +360,10 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) ) { // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm - double fScaleX = maBlipProps.moTileScaleX.get( 100000 ) / 100000.0; + double fScaleX = maBlipProps.moTileScaleX.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT ); sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 ); rPropMap.setProperty( rPropIds[ FillBitmapSizeXId ], nFillBmpSizeX ); - double fScaleY = maBlipProps.moTileScaleY.get( 100000 ) / 100000.0; + double fScaleY = maBlipProps.moTileScaleY.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT ); sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 ); rPropMap.setProperty( rPropIds[ FillBitmapSizeYId ], nFillBmpSizeY ); @@ -383,12 +403,12 @@ void FillProperties::pushToPropMap( PropertyMap& rPropMap, const FillPropertyIds } } -void FillProperties::pushToPropSet( PropertySet& rPropSet, const FillPropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, +void FillProperties::pushToPropSet( PropertySet& rPropSet, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const FillPropertyIds& rPropIds, sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const { PropertyMap aPropMap; - pushToPropMap( aPropMap, rPropIds, rFilter, rModelObjHelper, nShapeRotation, nPhClr ); + pushToPropMap( aPropMap, rFilter, rModelObjHelper, rPropIds, nShapeRotation, nPhClr ); rPropSet.setProperties( aPropMap ); } @@ -399,7 +419,7 @@ void GraphicProperties::assignUsed( const GraphicProperties& rSourceProps ) maBlipProps.assignUsed( rSourceProps.maBlipProps ); } -void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFilterBase& rFilter, sal_Int32 nPhClr ) const +void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter, sal_Int32 nPhClr ) const { if( maBlipProps.mxGraphic.is() ) { @@ -436,15 +456,15 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFilterBas rPropMap[ PROP_GraphicColorMode ] <<= eColorMode; // brightness and contrast - sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.get( 0 ) / 1000, -100, 100 ); + sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.get( 0 ) / PER_PERCENT, -100, 100 ); if( nBrightness != 0 ) rPropMap[ PROP_AdjustLuminance ] <<= nBrightness; - sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.get( 0 ) / 1000, -100, 100 ); + sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.get( 0 ) / PER_PERCENT, -100, 100 ); if( nContrast != 0 ) rPropMap[ PROP_AdjustContrast ] <<= nContrast; } -void GraphicProperties::pushToPropSet( PropertySet& rPropSet, const XmlFilterBase& rFilter, sal_Int32 nPhClr ) const +void GraphicProperties::pushToPropSet( PropertySet& rPropSet, const FilterBase& rFilter, sal_Int32 nPhClr ) const { PropertyMap aPropMap; pushToPropMap( aPropMap, rFilter, nPhClr ); diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx index 7f31bc05cb7e..6cee420c167d 100644 --- a/oox/source/drawingml/lineproperties.cxx +++ b/oox/source/drawingml/lineproperties.cxx @@ -43,8 +43,8 @@ #include "oox/helper/modelobjecthelper.hxx" #include "oox/helper/propertymap.hxx" #include "oox/helper/propertyset.hxx" +#include "oox/core/filterbase.hxx" #include "oox/core/namespaces.hxx" -#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" using namespace ::com::sun::star::drawing; @@ -55,7 +55,7 @@ using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; using ::com::sun::star::awt::Point; using ::com::sun::star::container::XNameContainer; -using ::oox::core::XmlFilterBase; +using ::oox::core::FilterBase; namespace oox { namespace drawingml { @@ -82,6 +82,85 @@ static const sal_Int32 spnDefaultLineIds[ LineId_END ] = // ---------------------------------------------------------------------------- +void lclSetDashData( LineDash& orLineDash, sal_Int16 nDots, sal_Int32 nDotLen, + sal_Int16 nDashes, sal_Int32 nDashLen, sal_Int32 nDistance ) +{ + orLineDash.Dots = nDots; + orLineDash.DotLen = nDotLen; + orLineDash.Dashes = nDashes; + orLineDash.DashLen = nDashLen; + orLineDash.Distance = nDistance; +} + +/** Converts the specified preset dash to API dash. + + Line length and dot length are set relative to line width and have to be + multiplied by the actual line width after this function. + */ +void lclConvertPresetDash( LineDash& orLineDash, sal_Int32 nPresetDash ) +{ + switch( nPresetDash ) + { + case XML_dot: lclSetDashData( orLineDash, 1, 1, 0, 0, 3 ); break; + case XML_dash: lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); break; + case XML_dashDot: lclSetDashData( orLineDash, 1, 1, 1, 4, 3 ); break; + + case XML_lgDash: lclSetDashData( orLineDash, 0, 0, 1, 8, 3 ); break; + case XML_lgDashDot: lclSetDashData( orLineDash, 1, 1, 1, 8, 3 ); break; + case XML_lgDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 8, 3 ); break; + + case XML_sysDot: lclSetDashData( orLineDash, 1, 1, 0, 0, 1 ); break; + case XML_sysDash: lclSetDashData( orLineDash, 0, 0, 1, 3, 1 ); break; + case XML_sysDashDot: lclSetDashData( orLineDash, 1, 1, 1, 3, 1 ); break; + case XML_sysDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 3, 1 ); break; + + default: + OSL_ENSURE( false, "lclConvertPresetDash - unsupported preset dash" ); + lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); + } +} + +/** Converts the passed custom dash to API dash. + + Line length and dot length are set relative to line width and have to be + multiplied by the actual line width after this function. + */ +void lclConvertCustomDash( LineDash& orLineDash, const LineProperties::DashStopVector& rCustomDash ) +{ + if( rCustomDash.empty() ) + { + OSL_ENSURE( false, "lclConvertCustomDash - unexpected empty custom dash" ); + lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); + return; + } + + // count dashes and dots (stops equal or less than 2 are assumed to be dots) + sal_Int16 nDots = 0; + sal_Int32 nDotLen = 0; + sal_Int16 nDashes = 0; + sal_Int32 nDashLen = 0; + sal_Int32 nDistance = 0; + for( LineProperties::DashStopVector::const_iterator aIt = rCustomDash.begin(), aEnd = rCustomDash.end(); aIt != aEnd; ++aIt ) + { + if( aIt->first <= 2 ) + { + ++nDots; + nDotLen += aIt->first; + } + else + { + ++nDashes; + nDashLen += aIt->first; + } + nDistance += aIt->second; + } + orLineDash.DotLen = (nDots > 0) ? ::std::max< sal_Int32 >( nDotLen / nDots, 1 ) : 0; + orLineDash.Dots = nDots; + orLineDash.DashLen = (nDashes > 0) ? ::std::max< sal_Int32 >( nDashLen / nDashes, 1 ) : 0; + orLineDash.Dashes = nDashes; + orLineDash.Distance = ::std::max< sal_Int32 >( nDistance / rCustomDash.size(), 1 ); +} + DashStyle lclGetDashStyle( sal_Int32 nToken ) { switch( nToken ) @@ -122,7 +201,7 @@ sal_Int32 lclGetArrowSize( sal_Int32 nToken ) // ---------------------------------------------------------------------------- void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& rArrowProps, - const LinePropertyIds& rPropIds, ModelObjectHelper& rModelObjHelper, sal_Int32 nLineWidth, bool bLineEnd ) + ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nLineWidth, bool bLineEnd ) { PolyPolygonBezierCoords aMarker; OUString aMarkerName; @@ -310,14 +389,17 @@ void LineProperties::assignUsed( const LineProperties& rSourceProps ) maStartArrow.assignUsed( rSourceProps.maStartArrow ); maEndArrow.assignUsed( rSourceProps.maEndArrow ); maLineFill.assignUsed( rSourceProps.maLineFill ); + if( !rSourceProps.maCustomDash.empty() ) + maCustomDash = rSourceProps.maCustomDash; moLineWidth.assignIfUsed( rSourceProps.moLineWidth ); moPresetDash.assignIfUsed( rSourceProps.moPresetDash ); + moLineCompound.assignIfUsed( rSourceProps.moLineCompound ); moLineCap.assignIfUsed( rSourceProps.moLineCap ); moLineJoint.assignIfUsed( rSourceProps.moLineJoint ); } -void LineProperties::pushToPropMap( PropertyMap& rPropMap, const LinePropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, sal_Int32 nPhClr ) const +void LineProperties::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const { // line fill type must exist, otherwise ignore other properties if( maLineFill.moFillType.has() ) @@ -326,51 +408,22 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, const LinePropertyIds LineStyle eLineStyle = (maLineFill.moFillType.get() == XML_noFill) ? LineStyle_NONE : LineStyle_SOLID; // create line dash from preset dash token (not for invisible line) - if( (eLineStyle != LineStyle_NONE) && moPresetDash.differsFrom( XML_solid ) ) + if( (eLineStyle != LineStyle_NONE) && (moPresetDash.differsFrom( XML_solid ) || (!moPresetDash && !maCustomDash.empty())) ) { LineDash aLineDash; - - sal_Int32 nLineWidth = GetCoordinate( moLineWidth.get( 103500 ) ); aLineDash.Style = lclGetDashStyle( moLineCap.get( XML_rnd ) ); - aLineDash.Dots = 1; - aLineDash.DotLen = nLineWidth; - aLineDash.Dashes = 0; - aLineDash.DashLen = 8 * nLineWidth; - aLineDash.Distance = 3 * nLineWidth; - switch( moPresetDash.get() ) - { - default: - case XML_dash: - case XML_sysDash: - aLineDash.DashLen = 4 * nLineWidth; - // passthrough intended - case XML_lgDash: - aLineDash.Dots = 0; - aLineDash.Dashes = 1; - break; - - case XML_dashDot: - case XML_sysDashDot: - aLineDash.DashLen = 4 * nLineWidth; - // passthrough intended - case XML_lgDashDot: - aLineDash.Dashes = 1; - break; - - case XML_sysDashDotDot: - aLineDash.DashLen = 4 * nLineWidth; - // passthrough intended - case XML_lgDashDotDot: - aLineDash.Dots = 2; - aLineDash.Dashes = 1; - break; + // convert preset dash or custom dash + if( moPresetDash.has() ) + lclConvertPresetDash( aLineDash, moPresetDash.get() ); + else + lclConvertCustomDash( aLineDash, maCustomDash ); - case XML_dot: - case XML_sysDot: - aLineDash.Distance = aLineDash.DotLen; - break; - } + // convert relative dash/dot length to absolute length + sal_Int32 nLineWidth = GetCoordinate( moLineWidth.get( 103500 ) ); + aLineDash.DotLen *= nLineWidth; + aLineDash.DashLen *= nLineWidth; + aLineDash.Distance *= nLineWidth; if( rPropIds.mbNamedLineDash ) { @@ -409,16 +462,16 @@ void LineProperties::pushToPropMap( PropertyMap& rPropMap, const LinePropertyIds } // line markers - lclPushMarkerProperties( rPropMap, maStartArrow, rPropIds, rModelObjHelper, moLineWidth.get( 0 ), false ); - lclPushMarkerProperties( rPropMap, maEndArrow, rPropIds, rModelObjHelper, moLineWidth.get( 0 ), true ); + lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), false ); + lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), true ); } } -void LineProperties::pushToPropSet( PropertySet& rPropSet, const LinePropertyIds& rPropIds, - const XmlFilterBase& rFilter, ModelObjectHelper& rModelObjHelper, sal_Int32 nPhClr ) const +void LineProperties::pushToPropSet( PropertySet& rPropSet, const FilterBase& rFilter, + ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const { PropertyMap aPropMap; - pushToPropMap( aPropMap, rPropIds, rFilter, rModelObjHelper, nPhClr ); + pushToPropMap( aPropMap, rFilter, rModelObjHelper, rPropIds, nPhClr ); rPropSet.setProperties( aPropMap ); } diff --git a/oox/source/drawingml/linepropertiescontext.cxx b/oox/source/drawingml/linepropertiescontext.cxx index b98f30738ec0..e6c6f76d5585 100644 --- a/oox/source/drawingml/linepropertiescontext.cxx +++ b/oox/source/drawingml/linepropertiescontext.cxx @@ -53,6 +53,7 @@ LinePropertiesContext::LinePropertiesContext( ContextHandler& rParent, const Ref { AttributeList aAttribs( xAttribs ); mrLineProperties.moLineWidth = aAttribs.getInteger( XML_w ); + mrLineProperties.moLineCompound = aAttribs.getToken( XML_cmpd ); mrLineProperties.moLineCap = aAttribs.getToken( XML_cap ); } @@ -79,6 +80,11 @@ Reference< XFastContextHandler > LinePropertiesContext::createFastChildContext( mrLineProperties.moPresetDash = aAttribs.getToken( XML_val ); break; case A_TOKEN( custDash ): // CT_DashStopList + xRet = this; + break; + case A_TOKEN( ds ): + mrLineProperties.maCustomDash.push_back( LineProperties::DashStop( + aAttribs.getInteger( XML_d, 0 ), aAttribs.getInteger( XML_sp, 0 ) ) ); break; // LineJoinPropertiesGroup diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 329aa6b36226..b1d68fabcb11 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -423,11 +423,11 @@ Reference< XShape > Shape::createAndInsert( // applying properties PropertySet aPropSet( xSet ); if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) ) - mpGraphicPropertiesPtr->pushToPropSet( aPropSet, rFilterBase, -1 ); + mpGraphicPropertiesPtr->pushToPropSet( aPropSet, rFilterBase ); if ( mpTablePropertiesPtr.get() && ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.TableShape" ) ) ) mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle ); - aFillProperties.pushToPropSet( aPropSet, FillProperties::DEFAULT_IDS, rFilterBase, rFilterBase.getModelObjectHelper(), mnRotation, nFillPhClr ); - aLineProperties.pushToPropSet( aPropSet, LineProperties::DEFAULT_IDS, rFilterBase, rFilterBase.getModelObjectHelper(), nLinePhClr ); + aFillProperties.pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper(), FillProperties::DEFAULT_IDS, mnRotation, nFillPhClr ); + aLineProperties.pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper(), LineProperties::DEFAULT_IDS, nLinePhClr ); // applying autogrowheight property before setting shape size, because // the shape size might be changed if currently autogrowheight is true diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx index 58aaf9081385..332e6f55601e 100644 --- a/oox/source/drawingml/table/tablecell.cxx +++ b/oox/source/drawingml/table/tablecell.cxx @@ -363,8 +363,7 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, ::oo aFillProperties.assignUsed( maFillProperties ); PropertySet aPropSet( xPropSet ); // TODO: phClr? - aFillProperties.pushToPropSet( aPropSet, FillProperties::DEFAULT_IDS, - rFilterBase, rFilterBase.getModelObjectHelper(), 0, -1 ); + aFillProperties.pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper() ); } } } } diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx index a5ef7558701f..41855170d26b 100644 --- a/oox/source/drawingml/textcharacterproperties.cxx +++ b/oox/source/drawingml/textcharacterproperties.cxx @@ -34,6 +34,7 @@ #include #include "oox/helper/helper.hxx" #include "oox/helper/propertyset.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "properties.hxx" #include "tokens.hxx" diff --git a/oox/source/drawingml/textparagraphproperties.cxx b/oox/source/drawingml/textparagraphproperties.cxx index c8197e3d78a3..35fe17716250 100644 --- a/oox/source/drawingml/textparagraphproperties.cxx +++ b/oox/source/drawingml/textparagraphproperties.cxx @@ -41,6 +41,7 @@ #include "oox/helper/helper.hxx" #include "oox/helper/propertyset.hxx" #include "oox/core/namespaces.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "properties.hxx" #include "tokens.hxx" diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 60cca8754a91..da21926e04bf 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -685,12 +685,12 @@ sal_uInt16 BiffObjectBase::dumpRepeatedRecId() void BiffObjectBase::dumpFrHeader( bool bWithFlags, bool bWithRange ) { - dumpHex< sal_uInt16 >( "rec-id", getRecNames() ); - sal_Int16 nFlags = bWithFlags ? dumpHex< sal_uInt16 >( "flags", "FR-FLAGS" ) : 0x0001; + dumpHex< sal_uInt16 >( "fr-rec-id", getRecNames() ); + sal_Int16 nFlags = bWithFlags ? dumpHex< sal_uInt16 >( "fr-flags", "FR-FLAGS" ) : 0x0001; if( bWithRange ) { if( getFlag< sal_uInt16 >( nFlags, 0x0001 ) ) - dumpRange( "range" ); + dumpRange( "fr-range" ); else dumpUnused( 8 ); } @@ -2698,14 +2698,23 @@ void WorkbookStreamObject::implDumpRecordBody() sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "STYLE-FLAGS" ); if( getFlag( nFlags, BIFF_STYLE_BUILTIN ) ) { - dumpDec< sal_uInt8 >( "builtin-idx", "STYLE-BUILTIN" ); - dumpDec< sal_uInt8 >( "outline-level" ); + dumpDec< sal_Int8 >( "builtin-idx", "STYLE-BUILTIN" ); + dumpDec< sal_Int8 >( "outline-level" ); } else dumpString( "style-name", BIFF_STR_8BITLENGTH ); } break; + case BIFF_ID_STYLEEXT: + dumpFrHeader( true, true ); + dumpHex< sal_uInt8 >( "flags", "STYLEEXT-FLAGS" ); + dumpDec< sal_uInt8 >( "category", "STYLEEXT-CATEGORY" ); + dumpDec< sal_Int8 >( "builtin-idx", "STYLEEXT-BUILTIN" ); + dumpDec< sal_Int8 >( "outline-level" ); + dumpUnicodeArray( "style-name", rStrm.readuInt16() ); + break; + case BIFF_ID_SXEXT: if( eBiff == BIFF8 ) { diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index 48c514b170d2..e9766865dd8b 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -347,6 +347,7 @@ multilist=RECORD-NAMES-BIFF8 0x0858=CHPIVOTREF,,,,,,, 0x0860=,,SHEETLAYOUT,,,,,SHEETPROTECTION 0x0868=,,,CHFRLABELPROPS,,,, + 0x0890=,,STYLEEXT,,,,, # chart records 0x1058=,,,,,,,CH3DDATAFORMAT 0x1060=CHFONTBASE,CHPIEEXT,CHLABELRANGE2,CHDATATABLE,CHPLOTGROWTH,CHSERINDEX,CHESCHERFORMAT,CHPIEEXTSETT @@ -1654,7 +1655,26 @@ combilist=STYLE-FLAGS 0x8000=builtin end -shortlist=STYLE-BUILTIN,0,normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink +shortlist=STYLE-BUILTIN,-1,user-defined,normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink + +# STYLEEXT ------------------------------------------------------------------- + +flagslist=STYLEEXT-FLAGS + 0x01=builtin + 0x02=hidden + 0x04=custom +end + +shortlist=STYLEEXT-CATEGORY,0,custom,good-bad-neutral,data-model,title-heading,themed,number-format + +multilist=STYLEEXT-BUILTIN + include=STYLE-BUILTIN + 10=note,warning-text,,,,title,heading-1,heading-2,heading-3,heading-4 + 20=input,output,calculation,check-cell,linked-cell,total,good,bad,neutral,accent1 + 30=20%-accent1,40%-accent1,60%-accent1,accent2,20%-accent2,40%-accent2,60%-accent2,accent3,20%-accent3,40%-accent3 + 40=60%-accent3,accent4,20%-accent4,40%-accent4,60%-accent4,accent5,20%-accent5,40%-accent5,60%-accent5,accent6 + 50=20%-accent6,40%-accent6,60%-accent6,explanatory-text +end # SXEXT ---------------------------------------------------------------------- diff --git a/oox/source/helper/propertymap.cxx b/oox/source/helper/propertymap.cxx index ccc5cfdd62b4..a40b4a737bd3 100644 --- a/oox/source/helper/propertymap.cxx +++ b/oox/source/helper/propertymap.cxx @@ -35,6 +35,7 @@ #include #include #include "properties.hxx" +#include "oox/token/propertylist.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Any; @@ -59,7 +60,7 @@ namespace oox { namespace { /** Thread-save singleton of a vector of all supported property names. */ -struct PropertyNamesPool : public ::rtl::Static< PropertyNamesList, PropertyNamesPool > {}; +struct StaticPropertyList : public ::rtl::Static< PropertyList, StaticPropertyList > {}; // ---------------------------------------------------------------------------- @@ -103,7 +104,7 @@ GenericPropertySet::GenericPropertySet() GenericPropertySet::GenericPropertySet( const PropertyMap& rPropMap ) { - const PropertyNamesList& rPropNames = PropertyNamesPool::get(); + const PropertyList& rPropNames = StaticPropertyList::get(); for( PropertyMap::const_iterator aIt = rPropMap.begin(), aEnd = rPropMap.end(); aIt != aEnd; ++aIt ) maPropMap[ rPropNames[ aIt->first ] ] = aIt->second; } @@ -170,10 +171,19 @@ sal_Bool SAL_CALL GenericPropertySet::hasPropertyByName( const OUString& rProper // ============================================================================ -const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) +PropertyMap::PropertyMap() : + mpPropNames( &StaticPropertyList::get() ) +{ +} + +PropertyMap::~PropertyMap() +{ +} + +/*static*/ const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) { OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" ); - return PropertyNamesPool::get()[ nPropId ]; + return StaticPropertyList::get()[ nPropId ]; } const Any* PropertyMap::getProperty( sal_Int32 nPropId ) const @@ -187,12 +197,11 @@ Sequence< PropertyValue > PropertyMap::makePropertyValueSequence() const Sequence< PropertyValue > aSeq( static_cast< sal_Int32 >( size() ) ); if( !empty() ) { - const PropertyNamesList& rPropNames = PropertyNamesPool::get(); PropertyValue* pValues = aSeq.getArray(); for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pValues ) { OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::makePropertyValueSequence - invalid property identifier" ); - pValues->Name = rPropNames[ aIt->first ]; + pValues->Name = (*mpPropNames)[ aIt->first ]; pValues->Value = aIt->second; pValues->State = ::com::sun::star::beans::PropertyState_DIRECT_VALUE; } @@ -206,13 +215,12 @@ void PropertyMap::fillSequences( Sequence< OUString >& rNames, Sequence< Any >& rValues.realloc( static_cast< sal_Int32 >( size() ) ); if( !empty() ) { - const PropertyNamesList& rPropNames = PropertyNamesPool::get(); OUString* pNames = rNames.getArray(); Any* pValues = rValues.getArray(); for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pNames, ++pValues ) { OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::fillSequences - invalid property identifier" ); - *pNames = rPropNames[ aIt->first ]; + *pNames = (*mpPropNames)[ aIt->first ]; *pValues = aIt->second; } } diff --git a/oox/source/ole/axcontrolhelper.cxx b/oox/source/ole/axcontrolhelper.cxx index a1bd9bfd9ac7..cd8180728074 100644 --- a/oox/source/ole/axcontrolhelper.cxx +++ b/oox/source/ole/axcontrolhelper.cxx @@ -117,12 +117,12 @@ sal_Int32 AxControlHelper::convertColor( sal_uInt32 nAxColor ) const switch( meColorMode ) { case AX_DEFAULTCOLORMODE_BGR: return lclDecodeBgrColor( nAxColor ); - case AX_DEFAULTCOLORMODE_PALETTE: return getPaletteColor( static_cast< sal_uInt16 >( nAxColor & AX_PALETTECOLOR_MASK ) ); + case AX_DEFAULTCOLORMODE_PALETTE: return mrFilter.getPaletteColor( nAxColor & AX_PALETTECOLOR_MASK ); } break; case AX_COLORTYPE_PALETTE: - return getPaletteColor( static_cast< sal_uInt16 >( nAxColor & AX_PALETTECOLOR_MASK ) ); + return mrFilter.getPaletteColor( nAxColor & AX_PALETTECOLOR_MASK ); case AX_COLORTYPE_BGR: return lclDecodeBgrColor( nAxColor ); @@ -134,12 +134,6 @@ sal_Int32 AxControlHelper::convertColor( sal_uInt32 nAxColor ) const return 0; } -sal_Int32 AxControlHelper::getPaletteColor( sal_uInt16 /*nPaletteIdx*/ ) const -{ - OSL_ENSURE( false, "AxControlHelper::getPaletteColor - palette colors not implemented" ); - return 0; -} - // ============================================================================ AxEmbeddedControlHelper::AxEmbeddedControlHelper( const FilterBase& rFilter, diff --git a/oox/source/ppt/animvariantcontext.cxx b/oox/source/ppt/animvariantcontext.cxx index e8f60d9df234..f3b9de2dbf7a 100644 --- a/oox/source/ppt/animvariantcontext.cxx +++ b/oox/source/ppt/animvariantcontext.cxx @@ -40,6 +40,7 @@ #include "oox/helper/attributelist.hxx" #include "oox/core/namespaces.hxx" #include "oox/core/fragmenthandler.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/colorchoicecontext.hxx" #include "pptfilterhelpers.hxx" #include "tokens.hxx" diff --git a/oox/source/ppt/pptimport.cxx b/oox/source/ppt/pptimport.cxx index f772a9236785..0e463099e9c5 100644 --- a/oox/source/ppt/pptimport.cxx +++ b/oox/source/ppt/pptimport.cxx @@ -88,12 +88,7 @@ bool PowerPointImport::exportDocument() throw() return false; } -const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const -{ - return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : 0; -} - -sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const +sal_Int32 PowerPointImport::getSchemeColor( sal_Int32 nToken ) const { sal_Int32 nColor = 0; if ( mpActualSlidePersist ) @@ -101,7 +96,7 @@ sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const sal_Bool bColorMapped = sal_False; oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() ); if ( pClrMapPtr ) - bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken ); + bColorMapped = pClrMapPtr->getColorMap( nToken ); if ( !bColorMapped ) // try masterpage mapping { @@ -110,18 +105,18 @@ sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const { pClrMapPtr = pMasterPersist->getClrMap(); if ( pClrMapPtr ) - bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken ); + bColorMapped = pClrMapPtr->getColorMap( nToken ); } } oox::drawingml::ClrSchemePtr pClrSchemePtr( mpActualSlidePersist->getClrScheme() ); if ( pClrSchemePtr ) - pClrSchemePtr->getColor( nColorSchemeToken, nColor ); + pClrSchemePtr->getColor( nToken, nColor ); else { ::oox::drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme(); if( pTheme ) { - pTheme->getClrScheme().getColor( nColorSchemeToken, nColor ); + pTheme->getClrScheme().getColor( nToken, nColor ); } else { @@ -132,6 +127,11 @@ sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const return nColor; } +const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const +{ + return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : 0; +} + ::oox::vml::Drawing* PowerPointImport::getVmlDrawing() { return mpActualSlidePersist ? mpActualSlidePersist->getDrawing() : 0; diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx index 5ce09bbbdbd5..f85e5ec72876 100644 --- a/oox/source/ppt/slidepersist.cxx +++ b/oox/source/ppt/slidepersist.cxx @@ -180,9 +180,7 @@ void SlidePersist::createBackground( const XmlFilterBase& rFilterBase ) uno::Reference< beans::XPropertySet > xPagePropSet( mxPage, uno::UNO_QUERY_THROW ); uno::Reference< beans::XPropertySet > xPropertySet( aPropMap.makePropertySet() ); PropertySet aPropSet( xPropertySet ); - mpBackgroundPropertiesPtr->pushToPropSet( - aPropSet, ::oox::drawingml::FillProperties::DEFAULT_IDS, - rFilterBase, rFilterBase.getModelObjectHelper(), 0, -1 ); + mpBackgroundPropertiesPtr->pushToPropSet( aPropSet, rFilterBase, rFilterBase.getModelObjectHelper() ); xPagePropSet->setPropertyValue( sBackground, Any( xPropertySet ) ); } catch( Exception ) diff --git a/oox/source/ppt/timenodelistcontext.cxx b/oox/source/ppt/timenodelistcontext.cxx index 70da57a52bd4..12fe9809ba5d 100644 --- a/oox/source/ppt/timenodelistcontext.cxx +++ b/oox/source/ppt/timenodelistcontext.cxx @@ -51,6 +51,7 @@ #include "oox/helper/attributelist.hxx" #include "oox/core/namespaces.hxx" +#include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "oox/drawingml/colorchoicecontext.hxx" #include "oox/ppt/slidetransition.hxx" diff --git a/oox/source/shape/FastTokenHandlerService.hxx b/oox/source/shape/FastTokenHandlerService.hxx index 64b79ab943ee..c41403539d11 100644 --- a/oox/source/shape/FastTokenHandlerService.hxx +++ b/oox/source/shape/FastTokenHandlerService.hxx @@ -27,17 +27,16 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#ifndef OOX_SHAPE_FAST_TOKEN_HANDLER_SERVICE_HXX -#define OOX_SHAPE_FAST_TOKEN_HANDLER_SERVICE_HXX -#include +#ifndef OOX_SHAPE_FASTTOKENHANDLERSERVICE_HXX +#define OOX_SHAPE_FASTTOKENHANDLERSERVICE_HXX -#include "sal/config.h" -#include "cppuhelper/factory.hxx" -#include "cppuhelper/implementationentry.hxx" -#include "cppuhelper/implbase2.hxx" -#include "com/sun/star/lang/XServiceInfo.hpp" -#include "com/sun/star/xml/sax/XFastTokenHandler.hpp" +#include +#include +#include +#include +#include +#include "oox/core/fasttokenhandler.hxx" namespace css = ::com::sun::star; @@ -70,7 +69,7 @@ private: virtual ~FastTokenHandlerService() {} css::uno::Reference< css::uno::XComponentContext > m_xContext; - FastTokenHandler mFastTokenHandler; + ::oox::core::FastTokenHandler mFastTokenHandler; }; ::rtl::OUString SAL_CALL FastTokenHandlerService_getImplementationName(); diff --git a/oox/source/shape/ShapeFilterBase.cxx b/oox/source/shape/ShapeFilterBase.cxx index 0933af28ffd5..9105b6ca38eb 100644 --- a/oox/source/shape/ShapeFilterBase.cxx +++ b/oox/source/shape/ShapeFilterBase.cxx @@ -53,11 +53,6 @@ const ::oox::drawingml::Theme* ShapeFilterBase::getCurrentTheme() const return 0; } -sal_Int32 ShapeFilterBase::getSchemeClr(sal_Int32 /*nColorSchemeToken*/ ) const -{ - return 0; -} - ::oox::vml::Drawing* ShapeFilterBase::getVmlDrawing() { return 0; diff --git a/oox/source/shape/ShapeFilterBase.hxx b/oox/source/shape/ShapeFilterBase.hxx index d90904ed22cc..1a2edcb461f2 100644 --- a/oox/source/shape/ShapeFilterBase.hxx +++ b/oox/source/shape/ShapeFilterBase.hxx @@ -55,9 +55,6 @@ public: /** Has to be implemented by each filter, returns the current theme. */ virtual const ::oox::drawingml::Theme* getCurrentTheme() const; - /** Has to be implemented by each filter to resolve scheme colors. */ - virtual sal_Int32 getSchemeClr( sal_Int32 nColorSchemeToken ) const; - /** Has to be implemented by each filter to return the collection of VML shapes. */ virtual ::oox::vml::Drawing* getVmlDrawing(); diff --git a/oox/source/token/gentoken.pl b/oox/source/token/gentoken.pl index 6c7c126bc4e2..196ac37ebb5c 100644 --- a/oox/source/token/gentoken.pl +++ b/oox/source/token/gentoken.pl @@ -3,7 +3,7 @@ $ARGV1 = shift @ARGV; $ARGV2 = shift @ARGV; $ARGV3 = shift @ARGV; -open ( TOKENS, $ARGV0 ) || die "can't open token file: $!"; +open ( TOKENS, $ARGV0 ) || die "can't open $ARGV0 file: $!"; my %tokens; while ( ) @@ -17,15 +17,15 @@ while ( ) } close ( TOKENS ); -open ( HXX, ">$ARGV1" ) or die "can't open tokens.hxx file: $!"; -open ( WORDS, ">$ARGV2" ) or die "can't open tokenwords.inl file: $!"; -open ( GPERF, ">$ARGV3" ) or die "can't open tokens.gperf file: $!"; +open ( HXX, ">$ARGV1" ) or die "can't open $ARGV1 file: $!"; +open ( WORDS, ">$ARGV2" ) or die "can't open $ARGV2 file: $!"; +open ( GPERF, ">$ARGV3" ) or die "can't open $ARGV3 file: $!"; print ( HXX "#ifndef OOX_TOKENS_HXX\n" ); print ( HXX "#define OOX_TOKENS_HXX\n\n" ); -print ( HXX "#include \n" ); +print ( HXX "#include \n" ); -print ( WORDS "static const sal_Char* tokentowordlist[] = {\n" ); +print ( WORDS "static const sal_Char* xmltokenwordlist[] = {\n" ); print ( GPERF "%language=C++\n" ); print ( GPERF "%global-table\n" ); @@ -47,7 +47,7 @@ foreach( sort( keys( %tokens ) ) ) } print ( HXX "const sal_Int32 XML_TOKEN_COUNT = $i;\n" ); -print ( HXX "const sal_Int32 XML_TOKEN_INVALID = -1;\n\n" ); +print ( HXX "const sal_Int32 XML_TOKEN_INVALID = ::com::sun::star::xml::sax::FastToken::DONTKNOW;\n\n" ); print ( HXX "const sal_Int32 XML_ROOT_CONTEXT = SAL_MAX_INT32;\n\n" ); print ( HXX "#endif\n" ); diff --git a/oox/source/token/propertylist.cxx b/oox/source/token/propertylist.cxx index b6be034daabc..153b15f32461 100644 --- a/oox/source/token/propertylist.cxx +++ b/oox/source/token/propertylist.cxx @@ -28,23 +28,31 @@ * ************************************************************************/ -#include +#include "oox/token/propertylist.hxx" #include "properties.hxx" -#include "oox/helper/propertymap.hxx" namespace oox { +namespace { + +// include auto-generated property name lists #include "propertywords.inc" +} // namespace + // ============================================================================ -PropertyNamesList::PropertyNamesList() +PropertyList::PropertyList() { reserve( static_cast< size_t >( PROP_COUNT ) ); for( sal_Int32 nIdx = 0; nIdx < PROP_COUNT; ++nIdx ) push_back( ::rtl::OUString::createFromAscii( propertywordlist[ nIdx ] ) ); } +PropertyList::~PropertyList() +{ +} + // ============================================================================ } // namespace oox diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx index 93da78313a69..733b18fd1f01 100644 --- a/oox/source/token/tokenmap.cxx +++ b/oox/source/token/tokenmap.cxx @@ -28,104 +28,84 @@ * ************************************************************************/ -#include -#include +#include "oox/token/tokenmap.hxx" #include -#include -#include "oox/core/fasttokenhandler.hxx" +#include #include "tokens.hxx" +#include "oox/helper/containerhelper.hxx" using ::rtl::OString; -using ::rtl::OStringBuffer; using ::rtl::OUString; -using ::rtl::OUStringToOString; -using ::osl::Mutex; -using ::osl::MutexGuard; using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::xml::sax::FastToken::DONTKNOW; namespace oox { -#include "tokens.inc" -#include "tokenwords.inc" - // ============================================================================ namespace { -Mutex& lclGetTokenMutex() -{ - static Mutex aMutex; - return aMutex; -} +// include auto-generated token lists +#include "tokens.inc" +#include "tokenwords.inc" } // namespace // ============================================================================ -FastTokenHandler::FastTokenHandler() +TokenMap::TokenMap() : + maTokenNames( static_cast< size_t >( XML_TOKEN_COUNT ) ) { + const sal_Char* const* ppcTokenWord = xmltokenwordlist; + for( TokenNameVector::iterator aIt = maTokenNames.begin(), aEnd = maTokenNames.end(); aIt != aEnd; ++aIt, ++ppcTokenWord ) + { + OString aUtf8Token( *ppcTokenWord ); + aIt->maUniName = OStringToOUString( aUtf8Token, RTL_TEXTENCODING_UTF8 ); + aIt->maUtf8Name = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUtf8Token.getStr() ), aUtf8Token.getLength() ); + } + #if OSL_DEBUG_LEVEL > 0 - MutexGuard aGuard( lclGetTokenMutex() ); + // check that the perfect_hash is in sync with the token name list bool bOk = true; - for( sal_Int32 nIdx = 0; bOk && (nIdx < XML_TOKEN_COUNT); ++nIdx ) + for( sal_Int32 nToken = 0; bOk && (nToken < XML_TOKEN_COUNT); ++nToken ) { // check that the getIdentifier <-> getToken roundtrip works - OUString aToken = getIdentifier( nIdx ); - bOk = getToken( aToken ) == nIdx; - OSL_ENSURE( bOk, OStringBuffer( "FastTokenHandler::FastTokenHandler - token list broken, #" ). - append( nIdx ).append( ", '" ). - append( OUStringToOString( aToken, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); + OString aUtf8Name = OUStringToOString( maTokenNames[ nToken ].maUniName, RTL_TEXTENCODING_UTF8 ); + struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); + bOk = pToken && (pToken->nToken == nToken); + OSL_ENSURE( bOk, ::rtl::OStringBuffer( "FastTokenHandler::FastTokenHandler - token list broken, #" ). + append( nToken ).append( ", '" ).append( aUtf8Name ).append( '\'' ).getStr() ); } #endif } -FastTokenHandler::~FastTokenHandler() +TokenMap::~TokenMap() { } -sal_Int32 FastTokenHandler::getToken( const OUString& rIdentifier ) throw( RuntimeException ) +OUString TokenMap::getUnicodeTokenName( sal_Int32 nToken ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - OString aUTF8 = OUStringToOString( rIdentifier, RTL_TEXTENCODING_UTF8 ); - - struct xmltoken * t = Perfect_Hash::in_word_set( aUTF8.getStr(), aUTF8.getLength() ); - return t ? t->nToken : DONTKNOW; + const TokenName* pTokenName = ContainerHelper::getVectorElement( maTokenNames, nToken ); + return pTokenName ? pTokenName->maUniName : OUString(); } -OUString FastTokenHandler::getIdentifier( sal_Int32 nToken ) throw( RuntimeException ) +sal_Int32 TokenMap::getTokenFromUnicode( const OUString& rUnicodeName ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - if( nToken >= XML_TOKEN_COUNT ) - return OUString(); - - static OUString aTokens[XML_TOKEN_COUNT]; - - if( aTokens[nToken].getLength() == 0 ) - aTokens[nToken] = OUString::createFromAscii( tokentowordlist[nToken] ); - - return aTokens[nToken]; + OString aUtf8Name = OUStringToOString( rUnicodeName, RTL_TEXTENCODING_UTF8 ); + struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() ); + return pToken ? pToken->nToken : XML_TOKEN_INVALID; } -Sequence< sal_Int8 > FastTokenHandler::getUTF8Identifier( sal_Int32 nToken ) throw( RuntimeException ) +Sequence< sal_Int8 > TokenMap::getUtf8TokenName( sal_Int32 nToken ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - if( nToken >= XML_TOKEN_COUNT ) - return Sequence< sal_Int8 >(); - - return Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8 *>(tokentowordlist[nToken]), strlen(tokentowordlist[nToken])); + const TokenName* pTokenName = ContainerHelper::getVectorElement( maTokenNames, nToken ); + return pTokenName ? pTokenName->maUtf8Name : Sequence< sal_Int8 >(); } -sal_Int32 FastTokenHandler::getTokenFromUTF8( const Sequence< sal_Int8 >& rIdentifier ) throw( RuntimeException ) +sal_Int32 TokenMap::getTokenFromUtf8( const Sequence< sal_Int8 >& rUtf8Name ) const { - MutexGuard aGuard( lclGetTokenMutex() ); - - struct xmltoken * t = Perfect_Hash::in_word_set( reinterpret_cast< const char* >( rIdentifier.getConstArray() ), rIdentifier.getLength()); - return t ? t->nToken : DONTKNOW; + struct xmltoken* pToken = Perfect_Hash::in_word_set( + reinterpret_cast< const char* >( rUtf8Name.getConstArray() ), rUtf8Name.getLength() ); + return pToken ? pToken->nToken : XML_TOKEN_INVALID; } // ============================================================================ diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 36e33e9d3f1a..4bf407747d95 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -1541,6 +1541,7 @@ dashLongHeavy dashSmallGap dashUpDiag dashVert +dashdot dashed dashedHeavy dashedSmall @@ -3063,6 +3064,9 @@ long longCurve longFileNames longText +longdash +longdashdot +longdashdotdot loop low lowKashida @@ -4448,6 +4452,10 @@ shininess shorebirdTracks short shortcutKey +shortdash +shortdashdot +shortdashdotdot +shortdot show showAll showAnimation diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk index 305353eb8f02..e4bc963cb1f6 100644 --- a/oox/source/vml/makefile.mk +++ b/oox/source/vml/makefile.mk @@ -47,6 +47,7 @@ ENABLE_EXCEPTIONS=TRUE SLOFILES = \ $(SLO)$/vmldrawing.obj \ $(SLO)$/vmldrawingfragment.obj \ + $(SLO)$/vmlformatting.obj \ $(SLO)$/vmlinputstream.obj \ $(SLO)$/vmlshape.obj \ $(SLO)$/vmlshapecontainer.obj \ diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx index 42529ea4a351..f7d9827851f9 100644 --- a/oox/source/vml/vmldrawing.cxx +++ b/oox/source/vml/vmldrawing.cxx @@ -147,6 +147,11 @@ const ControlInfo* Drawing::getControlInfo( const OUString& rShapeId ) const return ContainerHelper::getMapElement( maControls, rShapeId ); } +bool Drawing::isShapeSupported( const ShapeBase& /*rShape*/ ) const +{ + return true; +} + bool Drawing::convertShapeClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const { return false; diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index b622df39941c..6eab7efdba0e 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -63,7 +63,7 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At // DOCX filter handles plain shape elements with this fragment handler case VMLDRAWING_WORD: if( isRootElement() ) - return ShapeContextBase::createContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); + return ShapeContextBase::createShapeContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); break; // XLSX and PPTX filters load the entire VML fragment @@ -75,7 +75,7 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At if( nElement == XML_xml ) return this; break; case XML_xml: - return ShapeContextBase::createContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); + return ShapeContextBase::createShapeContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); } break; } diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx new file mode 100644 index 000000000000..a45054a77b52 --- /dev/null +++ b/oox/source/vml/vmlformatting.cxx @@ -0,0 +1,585 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: vmlformatting.cxx,v $ + * $Revision: 1.1 $ + * + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/vml/vmlformatting.hxx" +#include +#include "tokens.hxx" +#include "oox/token/tokenmap.hxx" +#include "oox/helper/propertymap.hxx" +#include "oox/core/filterbase.hxx" +#include "oox/drawingml/color.hxx" +#include "oox/drawingml/drawingmltypes.hxx" +#include "oox/drawingml/fillproperties.hxx" +#include "oox/drawingml/lineproperties.hxx" + +using ::rtl::OStringBuffer; +using ::rtl::OUString; +using ::com::sun::star::geometry::IntegerRectangle2D; +using ::oox::core::FilterBase; +using ::oox::drawingml::Color; +using ::oox::drawingml::FillProperties; +using ::oox::drawingml::LineArrowProperties; +using ::oox::drawingml::LineProperties; + +namespace oox { +namespace vml { + +// ============================================================================ + +namespace { + +bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& rValue ) +{ + // extract the double value and find start position of unit characters + rtl_math_ConversionStatus eConvStatus = rtl_math_ConversionStatus_Ok; + orfValue = ::rtl::math::stringToDouble( rValue, '.', '\0', &eConvStatus, &ornEndPos ); + return eConvStatus == rtl_math_ConversionStatus_Ok; +} + +} // namespace + +// ---------------------------------------------------------------------------- + +/*static*/ bool ConversionHelper::separatePair( OUString& orValue1, OUString& orValue2, + const OUString& rValue, sal_Unicode cSep ) +{ + sal_Int32 nSepPos = rValue.indexOf( cSep ); + if( nSepPos >= 0 ) + { + orValue1 = rValue.copy( 0, nSepPos ).trim(); + orValue2 = rValue.copy( nSepPos + 1 ).trim(); + } + else + { + orValue1 = rValue.trim(); + } + return (orValue1.getLength() > 0) && (orValue2.getLength() > 0); +} + +/*static*/ bool ConversionHelper::decodeBool( const OUString& rValue ) +{ + // anything else than 't' or 'true' is considered to be false, as specified + return ((rValue.getLength() == 1) && (rValue[ 0 ] == 't')) || (rValue == CREATE_OUSTRING( "true" )); +} + +/*static*/ double ConversionHelper::decodePercent( const OUString& rValue, double fDefValue ) +{ + if( rValue.getLength() == 0 ) + return fDefValue; + + double fValue = 0.0; + sal_Int32 nEndPos = 0; + if( !lclExtractDouble( fValue, nEndPos, rValue ) ) + return fDefValue; + + if( nEndPos == rValue.getLength() ) + return fValue; + + if( (nEndPos + 1 == rValue.getLength()) && (rValue[ nEndPos ] == '%') ) + return fValue / 100.0; + + OSL_ENSURE( false, "ConversionHelper::decodePercent - unknown measure unit" ); + return fDefValue; +} + +/*static*/ sal_Int32 ConversionHelper::decodeMeasureToEmu( const FilterBase& rFilter, + const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel ) +{ + // default for missing values is 0 + if( rValue.getLength() == 0 ) + return 0; + + // TODO: according to spec, value may contain "auto" + if( rValue.equalsAscii( "auto" ) ) + { + OSL_ENSURE( false, "ConversionHelper::decodeMeasureToEmu - special value 'auto' must be handled by caller" ); + return nRefValue; + } + + // extract the double value and find start position of unit characters + double fValue = 0.0; + sal_Int32 nEndPos = 0; + if( !lclExtractDouble( fValue, nEndPos, rValue ) || (fValue == 0.0) ) + return 0; + + // process trailing unit, convert to EMU + static const OUString saPx = CREATE_OUSTRING( "px" ); + OUString aUnit; + if( (0 < nEndPos) && (nEndPos < rValue.getLength()) ) + aUnit = rValue.copy( nEndPos ); + else if( bDefaultAsPixel ) + aUnit = saPx; + // else default is EMU + + if( aUnit.getLength() == 2 ) + { + sal_Unicode cChar1 = aUnit[ 0 ]; + sal_Unicode cChar2 = aUnit[ 1 ]; + if( (cChar1 == 'i') && (cChar2 == 'n') ) // 1 inch = 914,400 EMU + fValue *= 914400.0; + else if( (cChar1 == 'c') && (cChar2 == 'm') ) // 1 cm = 360,000 EMU + fValue *= 360000.0; + else if( (cChar1 == 'm') && (cChar2 == 'm') ) // 1 mm = 36,000 EMU + fValue *= 36000.0; + else if( (cChar1 == 'p') && (cChar2 == 't') ) // 1 point = 1/72 inch = 12,700 MEU + fValue *= 12700.0; + else if( (cChar1 == 'p') && (cChar2 == 'c') ) // 1 pica = 1/6 inch = 152,400 EMU + fValue *= 152400.0; + else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device, factor 360 to convert 1/100mm to EMU + fValue = bPixelX ? rFilter.convertScreenPixelX( 360.0 * fValue ) : rFilter.convertScreenPixelY( 360.0 * fValue ); + } + else if( (aUnit.getLength() == 1) && (aUnit[ 0 ] == '%') ) + { + fValue *= nRefValue / 100.0; + } + else if( bDefaultAsPixel || (aUnit.getLength() > 0) ) // default as EMU and no unit -> do nothing + { + OSL_ENSURE( false, "ConversionHelper::decodeMeasureToEmu - unknown measure unit" ); + fValue = nRefValue; + } + return static_cast< sal_Int32 >( fValue + 0.5 ); +} + +/*static*/ sal_Int32 ConversionHelper::decodeMeasureToHmm( const FilterBase& rFilter, + const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel ) +{ + return (decodeMeasureToEmu( rFilter, rValue, nRefValue, bPixelX, bDefaultAsPixel ) + 180) / 360; +} + +// ============================================================================ + +namespace { + +/** Converts a VML color attribute to a DrawingML color. + + @param orDmlColor (out-parameter) The destination DrawingML color. + + @param roVmlColor The VML string representation of the color. If existing, + this can be a 6-digit hexadecimal RGB value with leading '#' character, + a predefined color name (e.g. 'black', 'red', etc.), the index into an + application defined color palette in brackets with leading color name + (e.g. 'red [9]' or 'windowColor [64]'), or a color modifier used in + one-color gradients (e.g. 'fill darken(128)' or 'fill lighten(0)'. + + @param roVmlOpacity The opacity of the color. If existing, this should be + a floating-point value in the range [0.0;1.0]. + + @param nDefaultRgb Deafult RGB color used if the parameter roVmlColor is + empty. + + @param nPrimaryRgb If set to something else than API_RGB_TRANSPARENT, + specifies the color to be used to resolve the color modifiers used in + one-color gradients. + */ +void lclGetColor( Color& orDmlColor, const FilterBase& rFilter, + const OptValue< OUString >& roVmlColor, const OptValue< double >& roVmlOpacity, + sal_Int32 nDefaultRgb, sal_Int32 nPrimaryRgb = API_RGB_TRANSPARENT ) +{ + // convert opacity + const sal_Int32 DML_FULL_OPAQUE = ::oox::drawingml::MAX_PERCENT; + double fOpacity = roVmlOpacity.get( 1.0 ); + sal_Int32 nOpacity = getLimitedValue< sal_Int32, double >( fOpacity * DML_FULL_OPAQUE, 0, DML_FULL_OPAQUE ); + if( nOpacity < DML_FULL_OPAQUE ) + orDmlColor.addTransformation( XML_alpha, nOpacity ); + + // color attribute not present - set passed default color + if( !roVmlColor.has() ) + { + orDmlColor.setSrgbClr( nDefaultRgb ); + return; + } + + // separate leading color name or RGB value from following palette index + OUString aColorName, aColorIndex; + ConversionHelper::separatePair( aColorName, aColorIndex, roVmlColor.get(), ' ' ); + + // RGB colors in the format '#RRGGBB' + if( (aColorName.getLength() == 7) && (aColorName[ 0 ] == '#') ) + { + orDmlColor.setSrgbClr( aColorName.copy( 1 ).toInt32( 16 ) ); + return; + } + + // RGB colors in the format '#RGB' + if( (aColorName.getLength() == 4) && (aColorName[ 0 ] == '#') ) + { + sal_Int32 nR = aColorName.copy( 1, 1 ).toInt32( 16 ) * 0x11; + sal_Int32 nG = aColorName.copy( 2, 1 ).toInt32( 16 ) * 0x11; + sal_Int32 nB = aColorName.copy( 3, 1 ).toInt32( 16 ) * 0x11; + orDmlColor.setSrgbClr( (nR << 16) | (nG << 8) | nB ); + return; + } + + /* Predefined color names or system color names (resolve to RGB to detect + valid color name). */ + sal_Int32 nColorToken = StaticTokenMap::get().getTokenFromUnicode( aColorName ); + sal_Int32 nRgbValue = Color::getVmlPresetColor( nColorToken, API_RGB_TRANSPARENT ); + if( nRgbValue == API_RGB_TRANSPARENT ) + nRgbValue = rFilter.getSystemColor( nColorToken, API_RGB_TRANSPARENT ); + if( nRgbValue != API_RGB_TRANSPARENT ) + { + orDmlColor.setSrgbClr( nRgbValue ); + return; + } + + // try palette colors enclosed in brackets + if( (aColorIndex.getLength() >= 3) && (aColorIndex[ 0 ] == '[') && (aColorIndex[ aColorIndex.getLength() - 1 ] == ']') ) + { + orDmlColor.setPaletteClr( aColorIndex.copy( 1, aColorIndex.getLength() - 2 ).toInt32() ); + return; + } + + // try fill gradient modificator 'fill ()' + if( (nPrimaryRgb != API_RGB_TRANSPARENT) && (nColorToken == XML_fill) ) + { + sal_Int32 nOpenParen = aColorIndex.indexOf( '(' ); + sal_Int32 nCloseParen = aColorIndex.indexOf( ')' ); + if( (2 <= nOpenParen) && (nOpenParen + 1 < nCloseParen) && (nCloseParen + 1 == aColorIndex.getLength()) ) + { + sal_Int32 nModToken = XML_TOKEN_INVALID; + switch( StaticTokenMap::get().getTokenFromUnicode( aColorIndex.copy( 0, nOpenParen ) ) ) + { + case XML_darken: nModToken = XML_shade; + case XML_lighten: nModToken = XML_tint; + } + sal_Int32 nValue = aColorIndex.copy( nOpenParen + 1, nCloseParen - nOpenParen - 1 ).toInt32(); + if( (nModToken != XML_TOKEN_INVALID) && (0 <= nValue) && (nValue < 255) ) + { + /* Simulate this modifier color by a color with related transformation. + The modifier amount has to be converted from the range [0;255] to + percentage [0;100000] used by DrawingML. */ + orDmlColor.setSrgbClr( nPrimaryRgb ); + orDmlColor.addTransformation( nModToken, static_cast< sal_Int32 >( nValue * ::oox::drawingml::MAX_PERCENT / 255 ) ); + return; + } + } + } + + OSL_ENSURE( false, OStringBuffer( "lclGetColor - invalid VML color name '" ). + append( OUStringToOString( roVmlColor.get(), RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); + orDmlColor.setSrgbClr( nDefaultRgb ); +} + +sal_Int32 lclGetEmu( const FilterBase& rFilter, const OptValue< OUString >& roValue, sal_Int32 nDefValue ) +{ + return roValue.has() ? ConversionHelper::decodeMeasureToEmu( rFilter, roValue.get(), 0, false, false ) : nDefValue; +} + +void lclGetDmlLineDash( OptValue< sal_Int32 >& oroPresetDash, LineProperties::DashStopVector& orCustomDash, const OptValue< OUString >& roDashStyle ) +{ + if( roDashStyle.has() ) + { + const OUString& rDashStyle = roDashStyle.get(); + switch( StaticTokenMap::get().getTokenFromUnicode( rDashStyle ) ) + { + case XML_solid: oroPresetDash = XML_solid; return; + case XML_shortdot: oroPresetDash = XML_sysDot; return; + case XML_shortdash: oroPresetDash = XML_sysDash; return; + case XML_shortdashdot: oroPresetDash = XML_sysDashDot; return; + case XML_shortdashdotdot: oroPresetDash = XML_sysDashDotDot; return; + case XML_dot: oroPresetDash = XML_dot; return; + case XML_dash: oroPresetDash = XML_dash; return; + case XML_dashdot: oroPresetDash = XML_dashDot; return; + case XML_longdash: oroPresetDash = XML_lgDash; return; + case XML_longdashdot: oroPresetDash = XML_lgDashDot; return; + case XML_longdashdotdot: oroPresetDash = XML_lgDashDotDot; return; + + // try to convert user-defined dash style + default: + { + ::std::vector< sal_Int32 > aValues; + sal_Int32 nIndex = 0; + while( nIndex >= 0 ) + aValues.push_back( rDashStyle.getToken( 0, ' ', nIndex ).toInt32() ); + size_t nPairs = aValues.size() / 2; // ignore last value if size is odd + for( size_t nPairIdx = 0; nPairIdx < nPairs; ++nPairIdx ) + orCustomDash.push_back( LineProperties::DashStop( aValues[ 2 * nPairIdx ], aValues[ 2 * nPairIdx + 1 ] ) ); + } + } + } +} + +sal_Int32 lclGetDmlArrowType( const OptValue< sal_Int32 >& roArrowType ) +{ + if( roArrowType.has() ) switch( roArrowType.get() ) + { + case XML_none: return XML_none; + case XML_block: return XML_triangle; + case XML_classic: return XML_stealth; + case XML_diamond: return XML_diamond; + case XML_oval: return XML_oval; + case XML_open: return XML_arrow; + } + return XML_none; +} + +sal_Int32 lclGetDmlArrowWidth( const OptValue< sal_Int32 >& roArrowWidth ) +{ + if( roArrowWidth.has() ) switch( roArrowWidth.get() ) + { + case XML_narrow: return XML_sm; + case XML_medium: return XML_med; + case XML_wide: return XML_lg; + } + return XML_med; +} + +sal_Int32 lclGetDmlArrowLength( const OptValue< sal_Int32 >& roArrowLength ) +{ + if( roArrowLength.has() ) switch( roArrowLength.get() ) + { + case XML_short: return XML_sm; + case XML_medium: return XML_med; + case XML_long: return XML_lg; + } + return XML_med; +} + +void lclConvertArrow( LineArrowProperties& orArrowProp, const StrokeArrowModel& rStrokeArrow ) +{ + orArrowProp.moArrowType = lclGetDmlArrowType( rStrokeArrow.moArrowType ); + orArrowProp.moArrowWidth = lclGetDmlArrowWidth( rStrokeArrow.moArrowWidth ); + orArrowProp.moArrowLength = lclGetDmlArrowLength( rStrokeArrow.moArrowLength ); +} + +sal_Int32 lclGetDmlLineCompound( const OptValue< sal_Int32 >& roLineStyle ) +{ + if( roLineStyle.has() ) switch( roLineStyle.get() ) + { + case XML_single: return XML_sng; + case XML_thinThin: return XML_dbl; + case XML_thinThick: return XML_thinThick; + case XML_thickThin: return XML_thickThin; + case XML_thickBetweenThin: return XML_tri; + } + return XML_sng; +} + +sal_Int32 lclGetDmlLineCap( const OptValue< sal_Int32 >& roEndCap ) +{ + if( roEndCap.has() ) switch( roEndCap.get() ) + { + case XML_flat: return XML_flat; + case XML_square: return XML_sq; + case XML_round: return XML_rnd; + } + return XML_flat; // different defaults in VML (flat) and DrawingML (square) +} + +sal_Int32 lclGetDmlLineJoint( const OptValue< sal_Int32 >& roJoinStyle ) +{ + if( roJoinStyle.has() ) switch( roJoinStyle.get() ) + { + case XML_round: return XML_round; + case XML_bevel: return XML_bevel; + case XML_miter: return XML_miter; + } + return XML_round; +} + +} // namespace + +// ============================================================================ + +void StrokeArrowModel::assignUsed( const StrokeArrowModel& rSource ) +{ + moArrowType.assignIfUsed( rSource.moArrowType ); + moArrowWidth.assignIfUsed( rSource.moArrowWidth ); + moArrowLength.assignIfUsed( rSource.moArrowLength ); +} + +// ============================================================================ + +void StrokeModel::assignUsed( const StrokeModel& rSource ) +{ + moStroked.assignIfUsed( rSource.moStroked ); + maStartArrow.assignUsed( rSource.maStartArrow ); + maEndArrow.assignUsed( rSource.maEndArrow ); + moColor.assignIfUsed( rSource.moColor ); + moOpacity.assignIfUsed( rSource.moOpacity ); + moWeight.assignIfUsed( rSource.moWeight ); + moDashStyle.assignIfUsed( rSource.moDashStyle ); + moLineStyle.assignIfUsed( rSource.moLineStyle ); + moEndCap.assignIfUsed( rSource.moEndCap ); + moJoinStyle.assignIfUsed( rSource.moJoinStyle ); +} + +void StrokeModel::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter ) const +{ + /* Convert VML line formatting to DrawingML line formatting and let the + DrawingML code do the hard work. */ + LineProperties aLineProps; + + if( moStroked.get( true ) ) + { + aLineProps.maLineFill.moFillType = XML_solidFill; + lclConvertArrow( aLineProps.maStartArrow, maStartArrow ); + lclConvertArrow( aLineProps.maEndArrow, maEndArrow ); + lclGetColor( aLineProps.maLineFill.maFillColor, rFilter, moColor, moOpacity, API_RGB_BLACK ); + aLineProps.moLineWidth = lclGetEmu( rFilter, moWeight, 1 ); + lclGetDmlLineDash( aLineProps.moPresetDash, aLineProps.maCustomDash, moDashStyle ); + aLineProps.moLineCompound = lclGetDmlLineCompound( moLineStyle ); + aLineProps.moLineCap = lclGetDmlLineCap( moEndCap ); + aLineProps.moLineJoint = lclGetDmlLineJoint( moJoinStyle ); + } + else + { + aLineProps.maLineFill.moFillType = XML_noFill; + } + + aLineProps.pushToPropMap( rPropMap, rFilter, rFilter.getModelObjectHelper() ); +} + +// ============================================================================ + +void FillModel::assignUsed( const FillModel& rSource ) +{ + moFilled.assignIfUsed( rSource.moFilled ); + moColor.assignIfUsed( rSource.moColor ); + moOpacity.assignIfUsed( rSource.moOpacity ); + moColor2.assignIfUsed( rSource.moColor2 ); + moOpacity2.assignIfUsed( rSource.moOpacity2 ); + moType.assignIfUsed( rSource.moType ); + moAngle.assignIfUsed( rSource.moAngle ); + moFocus.assignIfUsed( rSource.moFocus ); + moFocusPos.assignIfUsed( rSource.moFocusPos ); + moFocusSize.assignIfUsed( rSource.moFocusSize ); + moRotate.assignIfUsed( rSource.moRotate ); +} + +void FillModel::pushToPropMap( PropertyMap& rPropMap, const FilterBase& rFilter ) const +{ + /* Convert VML fill formatting to DrawingML fill formatting and let the + DrawingML code do the hard work. */ + FillProperties aFillProps; + + if( moFilled.get( true ) ) + { + sal_Int32 nFillType = moType.get( XML_solid ); + switch( nFillType ) + { + case XML_gradient: + case XML_gradientRadial: + { + aFillProps.moFillType = XML_gradFill; + aFillProps.maGradientProps.moRotateWithShape = moRotate.get( false ); + double fFocus = moFocus.get( 0.0 ); + + // prepare colors + Color aColor1, aColor2; + lclGetColor( aColor1, rFilter, moColor, moOpacity, API_RGB_WHITE ); + lclGetColor( aColor2, rFilter, moColor2, moOpacity2, API_RGB_WHITE, aColor1.getColor( rFilter ) ); + + // type XML_gradient is linear or axial gradient + if( nFillType == XML_gradient ) + { + // normalize angle to range [0;360) degrees + sal_Int32 nVmlAngle = getIntervalValue< sal_Int32, sal_Int32 >( moAngle.get( 0 ), 0, 360 ); + + // focus of -50% or 50% is axial gradient + if( ((-0.75 <= fFocus) && (fFocus <= -0.25)) || ((0.25 <= fFocus) && (fFocus <= 0.75)) ) + { + /* According to spec, focus of 50% is outer-to-inner, + and -50% is inner-to-outer (color to color2). + BUT: For angles >= 180 deg., the behaviour is + reversed... that's not spec'ed of course. So, + [0;180) deg. and 50%, or [180;360) deg. and -50% is + outer-to-inner in fact. */ + bool bOuterToInner = (fFocus > 0.0) == (nVmlAngle < 180); + // simulate axial gradient by 3-step DrawingML gradient + const Color& rOuterColor = bOuterToInner ? aColor1 : aColor2; + const Color& rInnerColor = bOuterToInner ? aColor2 : aColor1; + aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aFillProps.maGradientProps.maGradientStops[ 1.0 ] = rOuterColor; + aFillProps.maGradientProps.maGradientStops[ 0.5 ] = rInnerColor; + } + else // focus of -100%, 0%, and 100% is linear gradient + { + /* According to spec, focus of -100% or 100% swaps the + start and stop colors, effectively reversing the + gradient. BUT: For angles >= 180 deg., the + behaviour is reversed. This means that in this case + a focus of 0% swaps the gradient. */ + if( ((fFocus < -0.75) || (fFocus > 0.75)) == (nVmlAngle < 180) ) + (nVmlAngle += 180) %= 360; + // set the start and stop colors + aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aColor1; + aFillProps.maGradientProps.maGradientStops[ 1.0 ] = aColor2; + } + + // VML counts counterclockwise from bottom, DrawingML clockwise from left + sal_Int32 nDmlAngle = (630 - nVmlAngle) % 360; + aFillProps.maGradientProps.moShadeAngle = nDmlAngle * ::oox::drawingml::PER_DEGREE; + } + else // XML_gradientRadial is rectangular gradient + { + aFillProps.maGradientProps.moGradientPath = XML_rect; + // convert VML focus position and size to DrawingML fill-to-rect + DoublePair aFocusPos = moFocusPos.get( DoublePair( 0.0, 0.0 ) ); + DoublePair aFocusSize = moFocusSize.get( DoublePair( 0.0, 0.0 ) ); + double fLeft = getLimitedValue< double, double >( aFocusPos.first, 0.0, 1.0 ); + double fTop = getLimitedValue< double, double >( aFocusPos.second, 0.0, 1.0 ); + double fRight = getLimitedValue< double, double >( fLeft + aFocusSize.first, fLeft, 1.0 ); + double fBottom = getLimitedValue< double, double >( fTop + aFocusSize.second, fTop, 1.0 ); + aFillProps.maGradientProps.moFillToRect = IntegerRectangle2D( + static_cast< sal_Int32 >( fLeft * ::oox::drawingml::MAX_PERCENT ), + static_cast< sal_Int32 >( fTop * ::oox::drawingml::MAX_PERCENT ), + static_cast< sal_Int32 >( (1.0 - fRight) * ::oox::drawingml::MAX_PERCENT ), + static_cast< sal_Int32 >( (1.0 - fBottom) * ::oox::drawingml::MAX_PERCENT ) ); + + // set the start and stop colors (focus of 0% means outer-to-inner) + bool bOuterToInner = (-0.5 <= fFocus) && (fFocus <= 0.5); + aFillProps.maGradientProps.maGradientStops[ 0.0 ] = bOuterToInner ? aColor2 : aColor1; + aFillProps.maGradientProps.maGradientStops[ 1.0 ] = bOuterToInner ? aColor1 : aColor2; + } + } + break; + + case XML_solid: + default: + { + aFillProps.moFillType = XML_solidFill; + // fill color (default is white) + lclGetColor( aFillProps.maFillColor, rFilter, moColor, moOpacity, API_RGB_WHITE ); + } + } + } + else + { + aFillProps.moFillType = XML_noFill; + } + + aFillProps.pushToPropMap( rPropMap, rFilter, rFilter.getModelObjectHelper() ); +} + +// ============================================================================ + +} // namespace vml +} // namespace oox + diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index d586196acee4..fe07172599a9 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -75,57 +74,6 @@ namespace vml { namespace { -sal_Int32 lclGetMeasure( const XmlFilterBase& /*rFilter*/, const OUString& rValue, sal_Int32 nRefValue ) -{ - // default for missing values is 0 - if( rValue.getLength() == 0 ) - return 0; - - // TODO: according to spec, value may contain "auto" - if( rValue.equalsAscii( "auto" ) ) - return nRefValue; - - // extract the double value and find start position of unit characters - rtl_math_ConversionStatus eConvStatus = rtl_math_ConversionStatus_Ok; - sal_Int32 nEndPos = 0; - double fValue = ::rtl::math::stringToDouble( rValue, '.', '\0', &eConvStatus, &nEndPos ); - if( (eConvStatus != rtl_math_ConversionStatus_Ok) || (fValue == 0.0) ) - return 0; - - // process trailing unit, convert to 1/100 mm - static const OUString saPx = CREATE_OUSTRING( "px" ); - OUString aUnit = ((0 < nEndPos) && (nEndPos < rValue.getLength())) ? rValue.copy( nEndPos ) : saPx; - if( aUnit.getLength() == 2 ) - { - sal_Unicode cChar1 = aUnit[ 0 ]; - sal_Unicode cChar2 = aUnit[ 1 ]; - if( (cChar1 == 'i') && (cChar2 == 'n') ) // 1 inch = 2540 1/100mm - fValue *= 2540.0; - else if( (cChar1 == 'c') && (cChar2 == 'm') ) // 1 cm = 1000 1/100mm - fValue *= 1000.0; - else if( (cChar1 == 'm') && (cChar2 == 'm') ) // 1 mm = 100 1/100mm - fValue *= 100.0; - else if( (cChar1 == 'p') && (cChar2 == 't') ) // 1 point = 1/72 inch - fValue *= 2540.0 / 72.0; - else if( (cChar1 == 'p') && (cChar2 == 'c') ) // 1 pica = 1/6 inch - fValue *= 2540.0 / 6.0; - else if( (cChar1 == 'e') && (cChar2 == 'm') ) // relative to refvalue - fValue *= nRefValue; - else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device - fValue *= 1.0; - } - else if( (aUnit.getLength() == 1) && (aUnit[ 0 ] == '%') ) - { - fValue *= nRefValue / 100.0; - } - else - { - OSL_ENSURE( false, "lclGetMeasure - unknown measure unit" ); - fValue = nRefValue; - } - return static_cast< sal_Int32 >( fValue + 0.5 ); -} - Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys ) { double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width; @@ -164,7 +112,7 @@ Reference< XShape > lclCreateXShape( const XmlFilterBase& rFilter, const OUStrin return xShape; } -void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XShape >& rxShape, const Rectangle& rShapeRect ) +void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XShape >& rxShape ) { OSL_ENSURE( rxShapes.is(), "lclInsertXShape - missing XShapes container" ); OSL_ENSURE( rxShape.is(), "lclInsertXShape - missing XShape" ); @@ -172,20 +120,28 @@ void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XSh { // insert shape into passed shape collection (maybe drawpage or group shape) rxShapes->add( rxShape ); - // set position/size - rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); - rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); } catch( Exception& ) { } } +void lclSetXShapeRect( const Reference< XShape >& rxShape, const Rectangle& rShapeRect ) +{ + OSL_ENSURE( rxShape.is(), "lclSetXShapeRect - missing XShape" ); + if( rxShape.is() ) + { + rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); + rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); + } +} + Reference< XShape > lclCreateAndInsertXShape( const XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes, const OUString& rService, const Rectangle& rShapeRect ) { Reference< XShape > xShape = lclCreateXShape( rFilter, rService ); - lclInsertXShape( rxShapes, xShape, rShapeRect ); + lclInsertXShape( rxShapes, xShape ); + lclSetXShapeRect( xShape, rShapeRect ); return xShape; } @@ -199,17 +155,13 @@ ShapeTypeModel::ShapeTypeModel() void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource ) { - monShapeType.assignIfUsed( rSource.monShapeType ); - monCoordLeft.assignIfUsed( rSource.monCoordLeft ); - monCoordTop.assignIfUsed( rSource.monCoordTop ); - monCoordWidth.assignIfUsed( rSource.monCoordWidth ); - monCoordHeight.assignIfUsed( rSource.monCoordHeight ); + moShapeType.assignIfUsed( rSource.moShapeType ); + moCoordPos.assignIfUsed( rSource.moCoordPos ); + moCoordSize.assignIfUsed( rSource.moCoordSize ); /* The style properties position, left, top, width, height, margin-left, margin-top are not derived from shape template to shape. */ - mobStroked.assignIfUsed( rSource.mobStroked ); - moStrokeColor.assignIfUsed( rSource.moStrokeColor ); - mobFilled.assignIfUsed( rSource.mobFilled ); - moFillColor.assignIfUsed( rSource.moFillColor ); + maStrokeModel.assignUsed( rSource.maStrokeModel ); + maFillModel.assignUsed( rSource.maFillModel ); moGraphicPath.assignIfUsed( rSource.moGraphicPath ); moGraphicTitle.assignIfUsed( rSource.moGraphicTitle ); } @@ -232,11 +184,9 @@ OUString ShapeType::getGraphicPath() const Rectangle ShapeType::getCoordSystem() const { - return Rectangle( - maTypeModel.monCoordLeft.get( 0 ), - maTypeModel.monCoordTop.get( 0 ), - maTypeModel.monCoordWidth.get( 1000 ), - maTypeModel.monCoordHeight.get( 1000 ) ); + Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) ); + Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) ); + return Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second ); } Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const @@ -250,10 +200,10 @@ Rectangle ShapeType::getAbsRectangle() const { const XmlFilterBase& rFilter = mrDrawing.getFilter(); return Rectangle( - lclGetMeasure( rFilter, maTypeModel.maLeft, 0 ) + lclGetMeasure( rFilter, maTypeModel.maMarginLeft, 0 ), - lclGetMeasure( rFilter, maTypeModel.maTop, 0 ) + lclGetMeasure( rFilter, maTypeModel.maMarginTop, 0 ), - lclGetMeasure( rFilter, maTypeModel.maWidth, 0 ), - lclGetMeasure( rFilter, maTypeModel.maHeight, 0 ) ); + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maLeft, 0, true, true ) + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maMarginLeft, 0, true, true ), + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maMarginTop, 0, false, true ), + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maWidth, 0, true, true ), + ConversionHelper::decodeMeasureToHmm( rFilter, maTypeModel.maHeight, 0, false, true ) ); } Rectangle ShapeType::getRelRectangle() const @@ -269,7 +219,10 @@ Rectangle ShapeType::getRelRectangle() const ShapeClientData::ShapeClientData() : mnObjType( XML_TOKEN_INVALID ), - mbPrintObject( true ) + mnCol( -1 ), + mnRow( -1 ), + mbPrintObject( true ), + mbVisible( false ) { } @@ -313,27 +266,55 @@ const ShapeBase* ShapeBase::getChildById( const OUString& ) const Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const { Reference< XShape > xShape; + if( mrDrawing.isShapeSupported( *this ) ) + { + /* Calculate shape rectangle. Applications may do something special + according to some imported shape client data (e.g. Excel cell anchor). */ + Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); + // convert the shape, if the calculated rectangle is not empty + if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) + xShape = implConvertAndInsert( rxShapes, aShapeRect ); + } + return xShape; +} + +void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const +{ + if( rxShape.is() ) + { + /* Calculate shape rectangle. Applications may do something special + according to some imported shape client data (e.g. Excel cell anchor). */ + Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); + // convert the shape, if the calculated rectangle is not empty + if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) ) + { + lclSetXShapeRect( rxShape, aShapeRect ); + convertShapeProperties( rxShape ); + } + } +} + +// protected ------------------------------------------------------------------ + +Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const +{ /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ Rectangle aShapeRect; if( !maShapeModel.mxClientData.get() || !mrDrawing.convertShapeClientAnchor( aShapeRect, maShapeModel.mxClientData->maAnchor ) ) aShapeRect = getRectangle( pParentAnchor ); - // convert the shape, if the calculated rectangle is not empty - if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) - xShape = implConvertAndInsert( rxShapes, aShapeRect ); - return xShape; + return aShapeRect; } -// protected ------------------------------------------------------------------ - void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const { - // shape properties - PropertySet aPropSet( rxShape ); + PropertyMap aPropMap; + + maTypeModel.maStrokeModel.pushToPropMap( aPropMap, mrDrawing.getFilter() ); + maTypeModel.maFillModel.pushToPropMap( aPropMap, mrDrawing.getFilter() ); - // fill style - bool bFilled = maTypeModel.mobFilled.get( true ); - aPropSet.setProperty( PROP_FillStyle, bFilled ? ::com::sun::star::drawing::FillStyle_SOLID : ::com::sun::star::drawing::FillStyle_NONE ); + PropertySet aPropSet( rxShape ); + aPropSet.setProperties( aPropMap ); } // ============================================================================ @@ -405,7 +386,7 @@ Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes { // create the custom shape geometry Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW ); - xDefaulter->createCustomShapeDefaults( OUString::valueOf( maTypeModel.monShapeType.get( 0 ) ) ); + xDefaulter->createCustomShapeDefaults( OUString::valueOf( maTypeModel.moShapeType.get( 0 ) ) ); // convert common properties convertShapeProperties( xShape ); } @@ -537,21 +518,27 @@ const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - Reference< XShape > xShape; + Reference< XShape > xGroupShape; // check that this shape contains children and a valid coordinate system ShapeParentAnchor aParentAnchor; aParentAnchor.maShapeRect = rShapeRect; aParentAnchor.maCoordSys = getCoordSystem(); if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try { - xShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rShapeRect ); - Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW ); - mxChildren->convertAndInsert( xShapes, &aParentAnchor ); + xGroupShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rShapeRect ); + Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW ); + mxChildren->convertAndInsert( xChildShapes, &aParentAnchor ); + // no child shape has been created - delete the group shape + if( !xChildShapes->hasElements() ) + { + rxShapes->remove( xGroupShape ); + xGroupShape.clear(); + } } catch( Exception& ) { } - return xShape; + return xGroupShape; } // ============================================================================ diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index dcf842a67a8f..725af97777c3 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -45,19 +45,62 @@ namespace vml { namespace { -bool lclSeparateValue( OUString& orName, OUString& orValue, const OUString& rAttrib, sal_Unicode cSep = ':' ) +/** Returns the boolean value from the specified VML attribute (if present). + */ +OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nElement ) +{ + OptValue< OUString > oValue = rAttribs.getString( nElement ); + if( oValue.has() ) return OptValue< bool >( ConversionHelper::decodeBool( oValue.get() ) ); + return OptValue< bool >(); +} + +/** Returns the percentage value from the specified VML attribute (if present). + The value will be normalized (1.0 is returned for 100%). + */ +OptValue< double > lclDecodePercent( const AttributeList& rAttribs, sal_Int32 nElement, double fDefValue ) +{ + OptValue< OUString > oValue = rAttribs.getString( nElement ); + if( oValue.has() ) return OptValue< double >( ConversionHelper::decodePercent( oValue.get(), fDefValue ) ); + return OptValue< double >(); +} + +/** Returns the integer value pair from the specified VML attribute (if present). + */ +OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int32 nElement ) +{ + OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< Int32Pair > oRetValue; + if( oValue.has() ) + { + OUString aValue1, aValue2; + ConversionHelper::separatePair( aValue1, aValue2, oValue.get(), ',' ); + oRetValue = Int32Pair( aValue1.toInt32(), aValue2.toInt32() ); + } + return oRetValue; +} + +/** Returns the percentage pair from the specified VML attribute (if present). + */ +OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_Int32 nElement ) { - sal_Int32 nSepPos = rAttrib.indexOf( cSep ); - if( nSepPos <= 0 ) return false; - orName = rAttrib.copy( 0, nSepPos ).trim(); - orValue = rAttrib.copy( nSepPos + 1 ).trim(); - return (orName.getLength() > 0) && (orValue.getLength() > 0); + OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< DoublePair > oRetValue; + if( oValue.has() ) + { + OUString aValue1, aValue2; + ConversionHelper::separatePair( aValue1, aValue2, oValue.get(), ',' ); + oRetValue = DoublePair( + ConversionHelper::decodePercent( aValue1, 0.0 ), + ConversionHelper::decodePercent( aValue2, 0.0 ) ); + } + return oRetValue; } -/** Returns the boolean value from the passed string (supported: f, t, False, True). +/** Returns the boolean value from the passed string of an attribute in the x: + namespace (VML for spreadsheets). Supported values: f, t, False, True. @param bDefaultForEmpty Default value for the empty string. */ -bool lclDecodeBool( const OUString& rValue, bool bDefaultForEmpty ) +bool lclDecodeVmlxBool( const OUString& rValue, bool bDefaultForEmpty ) { if( rValue.getLength() == 0 ) return bDefaultForEmpty; // anything else than 't' or 'True' is considered to be false, as specified @@ -85,11 +128,14 @@ void ShapeClientDataContext::onEndElement( const OUString& rChars ) { switch( getCurrentElement() ) { - case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = rChars; break; - case VMLX_TOKEN( FmlaLink ): mrClientData.maLinkedCell = rChars; break; - case VMLX_TOKEN( FmlaPict ): mrClientData.maPictureLink = rChars; break; - case VMLX_TOKEN( FmlaRange ): mrClientData.maSourceRange = rChars; break; - case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeBool( rChars, true ); break; + case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = rChars; break; + case VMLX_TOKEN( FmlaPict ): mrClientData.maPictureLink = rChars; break; + case VMLX_TOKEN( FmlaLink ): mrClientData.maLinkedCell = rChars; break; + case VMLX_TOKEN( FmlaRange ): mrClientData.maSourceRange = rChars; break; + case VMLX_TOKEN( Column ): mrClientData.mnCol = rChars.toInt32(); break; + case VMLX_TOKEN( Row ): mrClientData.mnRow = rChars.toInt32(); break; + case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeVmlxBool( rChars, true ); break; + case VMLX_TOKEN( Visible ): mrClientData.mbVisible = true; break; } } @@ -100,7 +146,7 @@ ShapeContextBase::ShapeContextBase( ContextHandler2Helper& rParent ) : { } -/*static*/ ContextHandlerRef ShapeContextBase::createContext( ContextHandler2Helper& rParent, +/*static*/ ContextHandlerRef ShapeContextBase::createShapeContext( ContextHandler2Helper& rParent, sal_Int32 nElement, const AttributeList& rAttribs, ShapeContainer& rShapes ) { switch( nElement ) @@ -144,24 +190,56 @@ ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, const Attrib if( bHasOspid ) mrTypeModel.maName = rAttribs.getXString( XML_id, OUString() ); // builtin shape type identifier - mrTypeModel.monShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); - // coordinate system position/size - setCoordOrigin( rAttribs.getString( XML_coordorigin, OUString() ) ); - setCoordSize( rAttribs.getString( XML_coordsize, OUString() ) ); - // CSS style + mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); + + // coordinate system position/size, CSS style + mrTypeModel.moCoordPos = lclDecodeInt32Pair( rAttribs, XML_coordorigin ); + mrTypeModel.moCoordSize = lclDecodeInt32Pair( rAttribs, XML_coordsize ); setStyle( rAttribs.getString( XML_style, OUString() ) ); - // border line - mrTypeModel.mobStroked = rAttribs.getBool( XML_stroked ); - mrTypeModel.moStrokeColor = rAttribs.getString( XML_strokecolor ); - // shape fill - mrTypeModel.mobFilled = rAttribs.getBool( XML_filled ); - mrTypeModel.moFillColor = rAttribs.getString( XML_fillcolor ); + + // stroke settings (may be overridden by v:stroke element later) + mrTypeModel.maStrokeModel.moStroked = lclDecodeBool( rAttribs, XML_stroked ); + mrTypeModel.maStrokeModel.moColor = rAttribs.getString( XML_strokecolor ); + mrTypeModel.maStrokeModel.moWeight = rAttribs.getString( XML_strokeweight ); + + // fill settings (may be overridden by v:fill element later) + mrTypeModel.maFillModel.moFilled = lclDecodeBool( rAttribs, XML_filled ); + mrTypeModel.maFillModel.moColor = rAttribs.getString( XML_fillcolor ); } ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { if( isRootElement() ) switch( nElement ) { + case VML_TOKEN( stroke ): + mrTypeModel.maStrokeModel.moStroked.assignIfUsed( lclDecodeBool( rAttribs, XML_on ) ); + mrTypeModel.maStrokeModel.maStartArrow.moArrowType = rAttribs.getToken( XML_startarrow ); + mrTypeModel.maStrokeModel.maStartArrow.moArrowWidth = rAttribs.getToken( XML_startarrowwidth ); + mrTypeModel.maStrokeModel.maStartArrow.moArrowLength = rAttribs.getToken( XML_startarrowlength ); + mrTypeModel.maStrokeModel.maEndArrow.moArrowType = rAttribs.getToken( XML_endarrow ); + mrTypeModel.maStrokeModel.maEndArrow.moArrowWidth = rAttribs.getToken( XML_endarrowwidth ); + mrTypeModel.maStrokeModel.maEndArrow.moArrowLength = rAttribs.getToken( XML_endarrowlength ); + mrTypeModel.maStrokeModel.moColor.assignIfUsed( rAttribs.getString( XML_color ) ); + mrTypeModel.maStrokeModel.moOpacity = lclDecodePercent( rAttribs, XML_opacity, 1.0 ); + mrTypeModel.maStrokeModel.moWeight.assignIfUsed( rAttribs.getString( XML_weight ) ); + mrTypeModel.maStrokeModel.moDashStyle = rAttribs.getString( XML_dashstyle ); + mrTypeModel.maStrokeModel.moLineStyle = rAttribs.getToken( XML_linestyle ); + mrTypeModel.maStrokeModel.moEndCap = rAttribs.getToken( XML_endcap ); + mrTypeModel.maStrokeModel.moJoinStyle = rAttribs.getToken( XML_joinstyle ); + break; + case VML_TOKEN( fill ): + mrTypeModel.maFillModel.moFilled.assignIfUsed( lclDecodeBool( rAttribs, XML_on ) ); + mrTypeModel.maFillModel.moColor.assignIfUsed( rAttribs.getString( XML_color ) ); + mrTypeModel.maFillModel.moOpacity = lclDecodePercent( rAttribs, XML_opacity, 1.0 ); + mrTypeModel.maFillModel.moColor2 = rAttribs.getString( XML_color2 ); + mrTypeModel.maFillModel.moOpacity2 = lclDecodePercent( rAttribs, XML_opacity2, 1.0 ); + mrTypeModel.maFillModel.moType = rAttribs.getToken( XML_type ); + mrTypeModel.maFillModel.moAngle = rAttribs.getInteger( XML_angle ); + mrTypeModel.maFillModel.moFocus = lclDecodePercent( rAttribs, XML_focus, 0.0 ); + mrTypeModel.maFillModel.moFocusPos = lclDecodePercentPair( rAttribs, XML_focusposition ); + mrTypeModel.maFillModel.moFocusSize = lclDecodePercentPair( rAttribs, XML_focussize ); + mrTypeModel.maFillModel.moRotate = lclDecodeBool( rAttribs, XML_rotate ); + break; case VML_TOKEN( imagedata ): OptValue< OUString > oGraphicRelId = rAttribs.getString( O_TOKEN( relid ) ); if( oGraphicRelId.has() ) @@ -172,33 +250,13 @@ ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const A return 0; } -void ShapeTypeContext::setCoordOrigin( const OUString& rCoordOrigin ) -{ - OUString aCoordL, aCoordT; - if( lclSeparateValue( aCoordL, aCoordT, rCoordOrigin, ',' ) ) - { - mrTypeModel.monCoordLeft = aCoordL.toInt32(); - mrTypeModel.monCoordTop = aCoordT.toInt32(); - } -} - -void ShapeTypeContext::setCoordSize( const OUString& rCoordSize ) -{ - OUString aCoordW, aCoordH; - if( lclSeparateValue( aCoordW, aCoordH, rCoordSize, ',' ) ) - { - mrTypeModel.monCoordWidth = aCoordW.toInt32(); - mrTypeModel.monCoordHeight = aCoordH.toInt32(); - } -} - void ShapeTypeContext::setStyle( const OUString& rStyle ) { sal_Int32 nIndex = 0; while( nIndex >= 0 ) { OUString aName, aValue; - if( lclSeparateValue( aName, aValue, rStyle.getToken( 0, ';', nIndex ) ) ) + if( ConversionHelper::separatePair( aName, aValue, rStyle.getToken( 0, ';', nIndex ), ':' ) ) { if( aName.equalsAscii( "position" ) ) mrTypeModel.maPosition = aValue; else if( aName.equalsAscii( "left" ) ) mrTypeModel.maLeft = aValue; @@ -255,7 +313,7 @@ GroupShapeContext::GroupShapeContext( ContextHandler2Helper& rParent, const Attr ContextHandlerRef GroupShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { // try to create a context of an embedded shape - ContextHandlerRef xContext = ShapeContextBase::createContext( *this, nElement, rAttribs, mrShapes ); + ContextHandlerRef xContext = createShapeContext( *this, nElement, rAttribs, mrShapes ); // handle remaining stuff of this shape in base class return xContext.get() ? xContext : ShapeContext::onCreateContext( nElement, rAttribs ); } diff --git a/oox/source/xls/chartsheetfragment.cxx b/oox/source/xls/chartsheetfragment.cxx index 3df5ff9c3e2a..7e5b9198c1da 100644 --- a/oox/source/xls/chartsheetfragment.cxx +++ b/oox/source/xls/chartsheetfragment.cxx @@ -47,7 +47,7 @@ namespace xls { // ============================================================================ OoxChartsheetFragment::OoxChartsheetFragment( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, sal_Int32 nSheet ) : + const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, sal_Int16 nSheet ) : OoxWorksheetFragmentBase( rHelper, rFragmentPath, xProgressBar, SHEETTYPE_CHARTSHEET, nSheet ) { } @@ -185,7 +185,7 @@ void OoxChartsheetFragment::importDrawing( RecordInputStream& rStrm ) // ============================================================================ BiffChartsheetFragment::BiffChartsheetFragment( const BiffWorkbookFragmentBase& rParent, - ISegmentProgressBarRef xProgressBar, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, sal_Int16 nSheet ) : BiffWorksheetFragmentBase( rParent, xProgressBar, SHEETTYPE_CHARTSHEET, nSheet ) { } diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index 1f725bfd7fbc..c8f11d55154e 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -33,22 +33,24 @@ #include #include #include -#include #include "oox/helper/attributelist.hxx" #include "oox/helper/recordinputstream.hxx" +#include "oox/vml/vmlshape.hxx" #include "oox/xls/addressconverter.hxx" +#include "oox/xls/drawingfragment.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::drawing::XShape; using ::com::sun::star::table::CellAddress; +using ::com::sun::star::sheet::XSheetAnnotation; using ::com::sun::star::sheet::XSheetAnnotationAnchor; using ::com::sun::star::sheet::XSheetAnnotationShapeSupplier; using ::com::sun::star::sheet::XSheetAnnotations; using ::com::sun::star::sheet::XSheetAnnotationsSupplier; -using ::com::sun::star::text::XText; namespace oox { namespace xls { @@ -98,16 +100,29 @@ void Comment::finalizeImport() if( getAddressConverter().checkCellAddress( aNotePos, true ) && maModel.mxText.get() ) try { maModel.mxText->finalizeImport(); - Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); - Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); - // create note with dummy non-empty string (required by implementation) - xAnnos->insertNew( aNotePos, OUString( sal_Unicode( ' ' ) ) ); - // receive craeted note from cell (insertNew does not return the note) -// Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); -// Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnnoAnchor->getAnnotation(), UNO_QUERY_THROW ); -// Reference< XText > xNoteText( xAnnoShapeSupp->getAnnotationShape(), UNO_QUERY_THROW ); -// xNoteText->setString( OUString() ); -// maModel.mxText->convert( xNoteText, -1 ); + OUString aNoteText = maModel.mxText->getPlainText(); + // non-empty string required by note implementation + if( aNoteText.getLength() > 0 ) + { + Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW ); + Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW ); + xAnnos->insertNew( aNotePos, aNoteText ); + // receive craeted note from cell (insertNew does not return the note) + Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW ); + Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW ); + Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW ); + Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW ); + // convert shape formatting + if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) ) + { + // position and formatting + pNoteShape->convertFormatting( xAnnoShape ); + // visibility + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; + bool bVisible = rxClientData.get() && rxClientData->mbVisible; + xAnno->setIsVisible( bVisible ); + } + } } catch( Exception& ) { diff --git a/oox/source/xls/defnamesbuffer.cxx b/oox/source/xls/defnamesbuffer.cxx index 786d0cd41334..b2c724b6728d 100644 --- a/oox/source/xls/defnamesbuffer.cxx +++ b/oox/source/xls/defnamesbuffer.cxx @@ -31,6 +31,7 @@ #include "oox/xls/defnamesbuffer.hxx" #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include "oox/xls/biffinputstream.hxx" #include "oox/xls/externallinkbuffer.hxx" #include "oox/xls/formulaparser.hxx" +#include "oox/xls/worksheetbuffer.hxx" using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -52,10 +54,10 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::table::CellAddress; using ::com::sun::star::table::CellRangeAddress; using ::com::sun::star::sheet::ComplexReference; +using ::com::sun::star::sheet::ExternalReference; using ::com::sun::star::sheet::SingleReference; using ::com::sun::star::sheet::XFormulaTokens; using ::com::sun::star::sheet::XPrintAreas; -using namespace ::com::sun::star::sheet::ReferenceFlags; namespace oox { namespace xls { @@ -205,6 +207,7 @@ void lclConvertRefFlags( sal_Int32& ornFlags, sal_Int32& ornAbsPos, sal_Int32& o void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBaseAddress, bool bColRel, bool bRowRel ) { + using namespace ::com::sun::star::sheet::ReferenceFlags; lclConvertRefFlags( orApiRef.Flags, orApiRef.Column, orApiRef.RelativeColumn, rBaseAddress.Column, COLUMN_RELATIVE, bColRel ); @@ -213,14 +216,33 @@ void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBa rBaseAddress.Row, ROW_RELATIVE, bRowRel ); } +Any lclConvertReference( const Any& rRefAny, const CellAddress& rBaseAddress, sal_uInt16 nRelFlags ) +{ + if( rRefAny.has< SingleReference >() && !getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ) && !getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) ) + { + SingleReference aApiRef; + rRefAny >>= aApiRef; + lclConvertSingleRefFlags( aApiRef, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); + return Any( aApiRef ); + } + if( rRefAny.has< ComplexReference >() ) + { + ComplexReference aApiRef; + rRefAny >>= aApiRef; + lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) ); + lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) ); + return Any( aApiRef ); + } + return Any(); +} + } // namespace // ---------------------------------------------------------------------------- -DefinedNameBase::DefinedNameBase( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ) : +DefinedNameBase::DefinedNameBase( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ) { - maModel.mnSheet = nLocalSheet; } const OUString& DefinedNameBase::getUpcaseModelName() const @@ -237,62 +259,63 @@ Any DefinedNameBase::getReference( const CellAddress& rBaseAddress ) const sal_Unicode cFlagsChar = getUpcaseModelName()[ 1 ]; if( ('A' <= cFlagsChar) && (cFlagsChar <= 'P') ) { - sal_uInt16 nFlags = static_cast< sal_uInt16 >( cFlagsChar - 'A' ); - if( maRefAny.has< SingleReference >() && (cFlagsChar <= 'D') ) + sal_uInt16 nRelFlags = static_cast< sal_uInt16 >( cFlagsChar - 'A' ); + if( maRefAny.has< ExternalReference >() ) { - SingleReference aApiRef; - maRefAny >>= aApiRef; - lclConvertSingleRefFlags( aApiRef, rBaseAddress, getFlag( nFlags, BIFF_REFFLAG_COL1REL ), getFlag( nFlags, BIFF_REFFLAG_ROW1REL ) ); - return Any( aApiRef ); + ExternalReference aApiExtRef; + maRefAny >>= aApiExtRef; + Any aRefAny = lclConvertReference( aApiExtRef.Reference, rBaseAddress, nRelFlags ); + if( aRefAny.hasValue() ) + { + aApiExtRef.Reference <<= aRefAny; + return Any( aApiExtRef ); + } } - if( maRefAny.has< ComplexReference >() ) + else { - ComplexReference aApiRef; - maRefAny >>= aApiRef; - lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddress, getFlag( nFlags, BIFF_REFFLAG_COL1REL ), getFlag( nFlags, BIFF_REFFLAG_ROW1REL ) ); - lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddress, getFlag( nFlags, BIFF_REFFLAG_COL2REL ), getFlag( nFlags, BIFF_REFFLAG_ROW2REL ) ); - return Any( aApiRef ); + return lclConvertReference( maRefAny, rBaseAddress, nRelFlags ); } } } return Any(); } -void DefinedNameBase::importOoxFormula( FormulaContext& rContext ) +void DefinedNameBase::importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet ) { if( maModel.maFormula.getLength() > 0 ) { - rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maModel.mnSheet ), 0, 0 ) ); + rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); getFormulaParser().importFormula( rContext, maModel.maFormula ); } else getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME ); } -void DefinedNameBase::importOobFormula( FormulaContext& rContext, RecordInputStream& rStrm ) +void DefinedNameBase::importOobFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, RecordInputStream& rStrm ) { - rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maModel.mnSheet ), 0, 0 ) ); + rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); getFormulaParser().importFormula( rContext, rStrm ); } -void DefinedNameBase::importBiffFormula( FormulaContext& rContext, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) +void DefinedNameBase::importBiffFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) { - rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maModel.mnSheet ), 0, 0 ) ); + rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) ); if( !pnFmlaSize || (*pnFmlaSize > 0) ) getFormulaParser().importFormula( rContext, rStrm, pnFmlaSize ); else getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME ); } -void DefinedNameBase::setReference( const ApiTokenSequence& rTokens ) +void DefinedNameBase::extractReference( const ApiTokenSequence& rTokens ) { + OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "DefinedNameBase::extractReference - unexpected call" ); maRefAny = getFormulaParser().extractReference( rTokens ); } // ============================================================================ -DefinedName::DefinedName( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ) : - DefinedNameBase( rHelper, nLocalSheet ), +DefinedName::DefinedName( const WorkbookHelper& rHelper ) : + DefinedNameBase( rHelper ), mnTokenIndex( -1 ), mcBuiltinId( OOX_DEFNAME_UNKNOWN ), mnFmlaSize( 0 ) @@ -309,6 +332,7 @@ void DefinedName::importDefinedName( const AttributeList& rAttribs ) maModel.mbVBName = rAttribs.getBool( XML_vbProcedure, false ); maModel.mbHidden = rAttribs.getBool( XML_hidden, false ); mcBuiltinId = lclGetBuiltinIdFromOox( maModel.maName ); + mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1; } void DefinedName::setFormula( const OUString& rFormula ) @@ -322,6 +346,7 @@ void DefinedName::importDefinedName( RecordInputStream& rStrm ) rStrm >> nFlags; rStrm.skip( 1 ); // keyboard shortcut rStrm >> maModel.mnSheet >> maModel.maName; + mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1; // macro function/command, hidden flag maModel.mnFuncGroupId = extractValue< sal_Int32 >( nFlags, 6, 9 ); @@ -351,7 +376,7 @@ void DefinedName::importDefinedName( RecordInputStream& rStrm ) } } -void DefinedName::importDefinedName( BiffInputStream& rStrm ) +void DefinedName::importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet ) { BiffType eBiff = getBiff(); sal_uInt16 nFlags = 0; @@ -421,26 +446,45 @@ void DefinedName::importDefinedName( BiffInputStream& rStrm ) case BIFF2: case BIFF3: case BIFF4: + // BIFF2-BIFF4: all defined names are sheet-local + mnCalcSheet = nCalcSheet; break; case BIFF5: // #i44019# nTabId may be invalid, resolve nRefId to sheet index if( nRefId != BIFF_DEFNAME_GLOBAL ) if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() ) if( pExtLink->getLinkType() == LINKTYPE_INTERNAL ) - maModel.mnSheet = pExtLink->getSheetIndex(); + mnCalcSheet = pExtLink->getCalcSheetIndex(); break; case BIFF8: - // convert one-based sheet index to zero-based + // convert one-based worksheet index to zero-based Calc sheet index OSL_ENSURE( nTabId >= 0, "DefinedName::importDefinedName - invalid local sheet index" ); if( nTabId != BIFF_DEFNAME_GLOBAL ) - maModel.mnSheet = nTabId - 1; + mnCalcSheet = getWorksheets().getCalcSheetIndex( nTabId - 1 ); break; case BIFF_UNKNOWN: break; } - // store record position to be able to import token array later - mxBiffStrm.reset( new BiffInputStreamPos( rStrm ) ); + if( (getBiff() <= BIFF4) && maModel.mbHidden && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') ) + { + /* Read the token array of special internal names containing addresses + for BIFF3-BIFF4 3D references immediately. It is expected that + these names contain a simple cell reference or range reference. + Other regular defined names and external names rely on existence of + this reference. */ + TokensFormulaContext aContext( true, true ); + importBiffFormula( aContext, mnCalcSheet, rStrm, &mnFmlaSize ); + extractReference( aContext.getTokens() ); + } + else + { + /* Store record position of other defined names to be able to import + token array later. This is needed to correctly resolve references + to names that are stored later in the defined names list following + this name. */ + mxBiffStrm.reset( new BiffInputStreamPos( rStrm ) ); + } } void DefinedName::createNameObject() @@ -459,7 +503,8 @@ void DefinedName::createNameObject() // append sheet index for local names in multi-sheet documents if( isWorkbookFile() && !isGlobalName() ) - maCalcName = OUStringBuffer( maCalcName ).append( sal_Unicode( '_' ) ).append( maModel.mnSheet + 1 ).makeStringAndClear(); + maCalcName = OUStringBuffer( maCalcName ).append( sal_Unicode( '_' ) ). + append( static_cast< sal_Int32 >( mnCalcSheet + 1 ) ).makeStringAndClear(); // special flags for this name sal_Int32 nNameFlags = 0; @@ -506,18 +551,18 @@ void DefinedName::convertFormula() { case OOX_DEFNAME_PRINTAREA: { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( maModel.mnSheet ), UNO_QUERY ); + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); ApiCellRangeList aPrintRanges; - getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, maModel.mnSheet ); + getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, mnCalcSheet ); if( xPrintAreas.is() && !aPrintRanges.empty() ) xPrintAreas->setPrintAreas( ContainerHelper::vectorToSequence( aPrintRanges ) ); } break; case OOX_DEFNAME_PRINTTITLES: { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( maModel.mnSheet ), UNO_QUERY ); + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); ApiCellRangeList aTitleRanges; - getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, maModel.mnSheet ); + getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, mnCalcSheet ); if( xPrintAreas.is() && !aTitleRanges.empty() ) { bool bHasRowTitles = false; @@ -545,13 +590,6 @@ void DefinedName::convertFormula() break; } } - else if( mxBiffStrm.get() && maModel.mbHidden && (maModel.maName.getLength() > 0) && (maModel.maName[ 0 ] == '\x01') ) - { - // import BIFF2-BIFF4 external references - TokensFormulaContext aContext( true, true ); - implImportBiffFormula( aContext ); - setReference( aContext.getTokens() ); - } } bool DefinedName::getAbsoluteRange( CellRangeAddress& orRange ) const @@ -567,32 +605,34 @@ void DefinedName::implImportOoxFormula( FormulaContext& rContext ) if( mxFormula.get() ) { RecordInputStream aStrm( *mxFormula ); - importOobFormula( rContext, aStrm ); + importOobFormula( rContext, mnCalcSheet, aStrm ); } else - importOoxFormula( rContext ); + importOoxFormula( rContext, mnCalcSheet ); } void DefinedName::implImportBiffFormula( FormulaContext& rContext ) { - OSL_ENSURE( mxBiffStrm.get(), "DefinedName::importBiffFormula - missing BIFF stream" ); + OSL_ENSURE( mxBiffStrm.get(), "DefinedName::implImportBiffFormula - missing BIFF stream" ); BiffInputStream& rStrm = mxBiffStrm->getStream(); BiffInputStreamPosGuard aStrmGuard( rStrm ); if( mxBiffStrm->restorePosition() ) - importBiffFormula( rContext, rStrm, &mnFmlaSize ); + importBiffFormula( rContext, mnCalcSheet, rStrm, &mnFmlaSize ); } // ============================================================================ DefinedNamesBuffer::DefinedNamesBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ), - mnLocalSheet( -1 ) + mnCalcSheet( -1 ) { } -void DefinedNamesBuffer::setLocalSheetIndex( sal_Int32 nLocalSheet ) +void DefinedNamesBuffer::setLocalCalcSheet( sal_Int16 nCalcSheet ) { - mnLocalSheet = nLocalSheet; + OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), + "DefinedNamesBuffer::setLocalCalcSheet - invalid call" ); + mnCalcSheet = nCalcSheet; } DefinedNameRef DefinedNamesBuffer::importDefinedName( const AttributeList& rAttribs ) @@ -609,7 +649,7 @@ void DefinedNamesBuffer::importDefinedName( RecordInputStream& rStrm ) void DefinedNamesBuffer::importDefinedName( BiffInputStream& rStrm ) { - createDefinedName()->importDefinedName( rStrm ); + createDefinedName()->importDefinedName( rStrm, mnCalcSheet ); } void DefinedNamesBuffer::finalizeImport() @@ -639,7 +679,7 @@ DefinedNameRef DefinedNamesBuffer::getByTokenIndex( sal_Int32 nIndex ) const return maDefNameMap.get( nIndex ); } -DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, sal_Int32 nSheet ) const +DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, sal_Int16 nCalcSheet ) const { DefinedNameRef xGlobalName; // a found global name DefinedNameRef xLocalName; // a found local name @@ -648,7 +688,7 @@ DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, s DefinedNameRef xCurrName = *aIt; if( xCurrName->getModelName() == rModelName ) { - if( xCurrName->getSheetIndex() == nSheet ) + if( xCurrName->getLocalCalcSheet() == nCalcSheet ) xLocalName = xCurrName; else if( xCurrName->isGlobalName() ) xGlobalName = xCurrName; @@ -659,7 +699,7 @@ DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, s DefinedNameRef DefinedNamesBuffer::createDefinedName() { - DefinedNameRef xDefName( new DefinedName( *this, mnLocalSheet ) ); + DefinedNameRef xDefName( new DefinedName( *this ) ); maDefNames.push_back( xDefName ); return xDefName; } diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index 7c338c55af6f..3b72126f7df6 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -43,7 +43,9 @@ #include "oox/drawingml/shapecontext.hxx" #include "oox/drawingml/shapegroupcontext.hxx" #include "oox/vml/vmlshape.hxx" +#include "oox/vml/vmlshapecontainer.hxx" #include "oox/xls/formulaparser.hxx" +#include "oox/xls/stylesbuffer.hxx" #include "oox/xls/themebuffer.hxx" #include "oox/xls/unitconverter.hxx" @@ -537,12 +539,52 @@ void OoxDrawingFragment::onEndElement( const OUString& rChars ) // ============================================================================ +namespace { + +class VmlFindNoteFunc +{ +public: + explicit VmlFindNoteFunc( const CellAddress& rPos ); + bool operator()( const ::oox::vml::ShapeBase& rShape ) const; + +private: + sal_Int32 mnCol; + sal_Int32 mnRow; +}; + +VmlFindNoteFunc::VmlFindNoteFunc( const CellAddress& rPos ) : + mnCol( rPos.Column ), + mnRow( rPos.Row ) +{ +} + +bool VmlFindNoteFunc::operator()( const ::oox::vml::ShapeBase& rShape ) const +{ + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = rShape.getShapeModel().mxClientData; + return rxClientData.get() && (rxClientData->mnCol == mnCol) && (rxClientData->mnRow == mnRow); +} + +} // namespace + +// ---------------------------------------------------------------------------- + VmlDrawing::VmlDrawing( const WorksheetHelper& rHelper ) : ::oox::vml::Drawing( rHelper.getOoxFilter(), rHelper.getDrawPage(), ::oox::vml::VMLDRAWING_EXCEL ), WorksheetHelper( rHelper ) { } +const ::oox::vml::ShapeBase* VmlDrawing::getNoteShape( const CellAddress& rPos ) const +{ + return getShapes().findShape( VmlFindNoteFunc( rPos ) ); +} + +bool VmlDrawing::isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const +{ + const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = rShape.getShapeModel().mxClientData; + return !rxClientData.get() || (rxClientData->mnObjType != XML_Note); +} + bool VmlDrawing::convertShapeClientAnchor( Rectangle& orShapeRect, const OUString& rShapeAnchor ) const { if( rShapeAnchor.getLength() == 0 ) diff --git a/oox/source/xls/excelfilter.cxx b/oox/source/xls/excelfilter.cxx index f460f3e8fdcb..a5bfe5e3d1d9 100644 --- a/oox/source/xls/excelfilter.cxx +++ b/oox/source/xls/excelfilter.cxx @@ -58,6 +58,34 @@ namespace xls { // ============================================================================ +ExcelFilterBase::ExcelFilterBase() : + mpHelper( 0 ) +{ +} + +ExcelFilterBase::~ExcelFilterBase() +{ + OSL_ENSURE( !mpHelper, "ExcelFilterBase::~ExcelFilterBase - workbook helper not cleared" ); +} + +void ExcelFilterBase::setWorkbookHelper( WorkbookHelper& rHelper ) +{ + mpHelper = &rHelper; +} + +WorkbookHelper& ExcelFilterBase::getWorkbookHelper() const +{ + OSL_ENSURE( mpHelper, "ExcelFilterBase::getWorkbookHelper - missing workbook helper" ); + return *mpHelper; +} + +void ExcelFilterBase::clearWorkbookHelper() +{ + mpHelper = 0; +} + +// ============================================================================ + OUString SAL_CALL ExcelFilter_getImplementationName() throw() { return CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilter" ); @@ -79,8 +107,7 @@ Reference< XInterface > SAL_CALL ExcelFilter_createInstance( // ---------------------------------------------------------------------------- ExcelFilter::ExcelFilter( const Reference< XMultiServiceFactory >& rxGlobalFactory ) : - XmlFilterBase( rxGlobalFactory ), - mpHelper( 0 ) + XmlFilterBase( rxGlobalFactory ) { } @@ -102,9 +129,9 @@ bool ExcelFilter::importDocument() throw() WorkbookHelperRoot aHelper( *this ); if( aHelper.isValid() ) { - mpHelper = &aHelper; // needed for callbacks + setWorkbookHelper( aHelper ); // needed for callbacks bRet = importFragment( new OoxWorkbookFragment( aHelper, aWorkbookPath ) ); - mpHelper = 0; + clearWorkbookHelper(); } } return bRet; @@ -115,15 +142,19 @@ bool ExcelFilter::exportDocument() throw() return false; } -const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const +sal_Int32 ExcelFilter::getSchemeColor( sal_Int32 nToken ) const { - return &mpHelper->getTheme(); + return getWorkbookHelper().getTheme().getColorByToken( nToken ); } -sal_Int32 ExcelFilter::getSchemeClr( sal_Int32 nColorSchemeToken ) const +sal_Int32 ExcelFilter::getPaletteColor( sal_Int32 nPaletteIdx ) const { - OSL_ENSURE( mpHelper, "ExcelFilter::getSchemeClr - no workbook helper" ); - return mpHelper->getTheme().getColorByToken( nColorSchemeToken ); + return getWorkbookHelper().getStyles().getPaletteColor( nPaletteIdx ); +} + +const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const +{ + return &getWorkbookHelper().getTheme(); } ::oox::vml::Drawing* ExcelFilter::getVmlDrawing() @@ -138,8 +169,7 @@ const TableStyleListPtr ExcelFilter::getTableStyles() ::oox::drawingml::chart::ChartConverter& ExcelFilter::getChartConverter() { - OSL_ENSURE( mpHelper, "ExcelFilter::getChartConverter - no workbook helper" ); - return mpHelper->getChartConverter(); + return getWorkbookHelper().getChartConverter(); } OUString ExcelFilter::implGetImplementationName() const @@ -202,7 +232,12 @@ bool ExcelBiffFilter::importDocument() throw() if( eBiff != BIFF_UNKNOWN ) { WorkbookHelperRoot aHelper( *this, eBiff ); - bRet = aHelper.isValid() && BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment(); + if( aHelper.isValid() ) + { + setWorkbookHelper( aHelper ); // needed for callbacks + bRet = BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment(); + clearWorkbookHelper(); + } } return bRet; } @@ -212,6 +247,11 @@ bool ExcelBiffFilter::exportDocument() throw() return false; } +sal_Int32 ExcelBiffFilter::getPaletteColor( sal_Int32 nPaletteIdx ) const +{ + return getWorkbookHelper().getStyles().getPaletteColor( nPaletteIdx ); +} + OUString ExcelBiffFilter::implGetImplementationName() const { return ExcelBiffFilter_getImplementationName(); diff --git a/oox/source/xls/excelhandlers.cxx b/oox/source/xls/excelhandlers.cxx index 3941bb306177..aa5a8634a60d 100644 --- a/oox/source/xls/excelhandlers.cxx +++ b/oox/source/xls/excelhandlers.cxx @@ -52,7 +52,7 @@ OoxWorkbookFragmentBase::OoxWorkbookFragmentBase( // ============================================================================ OoxWorksheetFragmentBase::OoxWorksheetFragmentBase( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ), WorksheetHelperRoot( rHelper, xProgressBar, eSheetType, nSheet ) { @@ -228,7 +228,7 @@ BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelpe // ============================================================================ BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const BiffWorkbookFragmentBase& rParent, - ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : BiffFragmentHandler( rParent ), WorksheetHelperRoot( rParent, xProgressBar, eSheetType, nSheet ) { @@ -237,7 +237,7 @@ BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const BiffWorkbookFragment // ============================================================================ BiffSkipWorksheetFragment::BiffSkipWorksheetFragment( - const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, sal_Int32 nSheet ) : + const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, sal_Int16 nSheet ) : BiffWorksheetFragmentBase( rParent, xProgressBar, SHEETTYPE_EMPTYSHEET, nSheet ) { } diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx index 564775228d2a..26a1df09cc69 100644 --- a/oox/source/xls/externallinkbuffer.cxx +++ b/oox/source/xls/externallinkbuffer.cxx @@ -30,8 +30,12 @@ #include "oox/xls/externallinkbuffer.hxx" #include +#include #include #include +#include +#include +#include #include #include #include @@ -55,9 +59,12 @@ using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::table::CellAddress; +using ::com::sun::star::sheet::ComplexReference; using ::com::sun::star::sheet::DDEItemInfo; using ::com::sun::star::sheet::DDELinkInfo; using ::com::sun::star::sheet::ExternalLinkInfo; +using ::com::sun::star::sheet::ExternalReference; +using ::com::sun::star::sheet::SingleReference; using ::com::sun::star::sheet::XDDELinks; using ::com::sun::star::sheet::XDDELinkResults; using ::com::sun::star::sheet::XExternalDocLinks; @@ -105,8 +112,8 @@ ExternalNameModel::ExternalNameModel() : // ============================================================================ -ExternalName::ExternalName( const ExternalLink& rParentLink, sal_Int32 nLocalSheet ) : - DefinedNameBase( rParentLink, nLocalSheet ), +ExternalName::ExternalName( const ExternalLink& rParentLink ) : + DefinedNameBase( rParentLink ), mrParentLink( rParentLink ), mnStorageId( 0 ), mbDdeLinkCreated( false ) @@ -239,16 +246,27 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) rStrm.readByteStringUC( false, getTextEncoding() ); OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importExternalName - empty name" ); + // load cell references that are stored in hidden external names (seen in BIFF3-BIFF4) + bool bHiddenRef = (getBiff() <= BIFF4) && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') && (rStrm.getRemaining() > 2); switch( mrParentLink.getLinkType() ) { case LINKTYPE_INTERNAL: + // cell references to other internal sheets are stored in hidden external names + if( bHiddenRef && (getBiff() == BIFF4) && isWorkbookFile() ) + { + TokensFormulaContext aContext( true, true ); + importBiffFormula( aContext, mrParentLink.getCalcSheetIndex(), rStrm ); + extractReference( aContext.getTokens() ); + } + break; + case LINKTYPE_EXTERNAL: - // cell references that are stored in hidden external names (seen in BIFF3-BIFF4) - if( (getBiff() <= BIFF4) && (maModel.maName.getLength() > 0) && (maModel.maName[ 0 ] == '\x01') && (rStrm.getRemaining() > 2) ) + // cell references to other documents are stored in hidden external names + if( bHiddenRef ) { TokensFormulaContext aContext( true, true ); - importBiffFormula( aContext, rStrm ); - setReference( aContext.getTokens() ); + importBiffFormula( aContext, 0, rStrm ); + extractExternalReference( aContext.getTokens() ); } break; @@ -300,6 +318,7 @@ void ExternalName::importExternalName( BiffInputStream& rStrm ) } } +#if 0 sal_Int32 ExternalName::getSheetCacheIndex() const { OSL_ENSURE( mrParentLink.getLinkType() == LINKTYPE_DDE, "ExternalName::getSheetCacheIndex - unexpected link type" ); @@ -337,6 +356,7 @@ sal_Int32 ExternalName::getSheetCacheIndex() const } return nCacheIdx; } +#endif bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const { @@ -381,6 +401,51 @@ bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, return false; } +// private -------------------------------------------------------------------- + +namespace { + +void lclSetSheetCacheIndex( SingleReference& orApiRef, sal_Int32 nCacheIdx ) +{ + using namespace ::com::sun::star::sheet::ReferenceFlags; + setFlag( orApiRef.Flags, SHEET_RELATIVE, false ); + setFlag( orApiRef.Flags, SHEET_3D, true ); + orApiRef.Sheet = nCacheIdx; +} + +} // namespace + +void ExternalName::extractExternalReference( const ApiTokenSequence& rTokens ) +{ + OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "ExternalName::setExternalReference - unexpected call" ); + sal_Int32 nDocLinkIdx = mrParentLink.getDocumentLinkIndex(); + sal_Int32 nCacheIdx = mrParentLink.getSheetCacheIndex(); + if( (nDocLinkIdx >= 0) && (nCacheIdx >= 0) ) + { + ExternalReference aExtApiRef; + aExtApiRef.Index = nDocLinkIdx; + + Any aRefAny = getFormulaParser().extractReference( rTokens ); + if( aRefAny.has< SingleReference >() ) + { + SingleReference aApiRef; + aRefAny >>= aApiRef; + lclSetSheetCacheIndex( aApiRef, nCacheIdx ); + aExtApiRef.Reference <<= aApiRef; + maRefAny <<= aExtApiRef; + } + else if( aRefAny.has< ComplexReference >() ) + { + ComplexReference aApiRef; + aRefAny >>= aApiRef; + lclSetSheetCacheIndex( aApiRef.Reference1, nCacheIdx ); + lclSetSheetCacheIndex( aApiRef.Reference2, nCacheIdx ); + aExtApiRef.Reference <<= aApiRef; + maRefAny <<= aExtApiRef; + } + } +} + void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows ) { OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_DDE) || (mrParentLink.getLinkType() == LINKTYPE_OLE) || @@ -564,10 +629,10 @@ void ExternalLink::importExternSheet( BiffInputStream& rStrm ) switch( meLinkType ) { case LINKTYPE_INTERNAL: - maIndexes.push_back( getWorksheets().getCalcSheetIndex( aSheetName ) ); + maCalcSheets.push_back( getWorksheets().getCalcSheetIndex( aSheetName ) ); break; case LINKTYPE_EXTERNAL: - insertExternalSheet( aSheetName ); + insertExternalSheet( (aSheetName.getLength() > 0) ? aSheetName : WorksheetBuffer::getBaseFileName( maTargetUrl ) ); break; default:; } @@ -659,11 +724,41 @@ FunctionLibraryType ExternalLink::getFuncLibraryType() const return (meLinkType == LINKTYPE_LIBRARY) ? meFuncLibType : FUNCLIB_UNKNOWN; } -sal_Int32 ExternalLink::getSheetIndex( sal_Int32 nTabId ) const +sal_Int16 ExternalLink::getCalcSheetIndex( sal_Int32 nTabId ) const { + OSL_ENSURE( meLinkType == LINKTYPE_INTERNAL, "ExternalLink::getCalcSheetIndex - invalid link type" ); OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOX) || (getBiff() == BIFF8), - "ExternalLink::getSheetIndex - invalid sheet index" ); - return ContainerHelper::getVectorElement< sal_Int32 >( maIndexes, nTabId, -1 ); + "ExternalLink::getCalcSheetIndex - invalid sheet index" ); + return ContainerHelper::getVectorElement< sal_Int16 >( maCalcSheets, nTabId, -1 ); +} + +sal_Int32 ExternalLink::getDocumentLinkIndex() const +{ + OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getDocumentLinkIndex - invalid link type" ); + return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1; +} + +sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const +{ + OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getSheetCacheIndex - invalid link type" ); + OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOX) || (getBiff() == BIFF8), + "ExternalLink::getSheetCacheIndex - invalid sheet index" ); + return ContainerHelper::getVectorElement< sal_Int32 >( maSheetCaches, nTabId, -1 ); +} + +Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const +{ + sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId ); + if( mxDocLink.is() && (nCacheIdx >= 0) ) try + { + // existing mxDocLink implies that this is an external link + Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW ); + return xSheetCache; + } + catch( Exception& ) + { + } + return 0; } void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const @@ -681,12 +776,12 @@ void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId case LINKTYPE_EXTERNAL: { - sal_Int32 nDocLinkIndex = mxDocLink.is() ? mxDocLink->getTokenIndex() : -1; + sal_Int32 nDocLinkIdx = getDocumentLinkIndex(); switch( getFilterType() ) { case FILTER_OOX: // OOBIN: passed indexes point into sheet list of EXTSHEETLIST - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) ); break; case FILTER_BIFF: switch( getBiff() ) @@ -694,17 +789,17 @@ void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId case BIFF2: case BIFF3: case BIFF4: - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) ); break; case BIFF5: // BIFF5: first sheet from this external link, last sheet is passed in nTabId2 if( const ExternalLink* pExtLink2 = getExternalLinks().getExternalLink( nTabId2 ).get() ) if( (pExtLink2->getLinkType() == LINKTYPE_EXTERNAL) && (maTargetUrl == pExtLink2->getTargetUrl()) ) - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex(), pExtLink2->getSheetIndex() ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex(), pExtLink2->getSheetCacheIndex() ); break; case BIFF8: // BIFF8: passed indexes point into sheet list of EXTERNALBOOK - orSheetRange.setExternalRange( nDocLinkIndex, getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) ); + orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) ); break; case BIFF_UNKNOWN: break; } @@ -720,21 +815,6 @@ void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId } } -Reference< XExternalSheetCache > ExternalLink::getExternalSheetCache( sal_Int32 nTabId ) -{ - const sal_Int32* pnCacheId = ContainerHelper::getVectorElement( maIndexes, nTabId ); - if( mxDocLink.is() && pnCacheId ) try - { - // existing mxDocLink implies that this is an external link - Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( *pnCacheId ), UNO_QUERY_THROW ); - return xSheetCache; - } - catch( Exception& ) - { - } - return 0; -} - ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const { return maExtNames.get( nIndex ); @@ -790,21 +870,21 @@ OUString ExternalLink::parseBiffTargetUrl( const OUString& rBiffTargetUrl ) OUString aClassName, aTargetUrl, aSheetName; switch( getAddressConverter().parseBiffTargetUrl( aClassName, aTargetUrl, aSheetName, rBiffTargetUrl ) ) - { + { case BIFF_TARGETTYPE_URL: if( aTargetUrl.getLength() == 0 ) - { + { meLinkType = (aSheetName.getLength() > 0) ? LINKTYPE_INTERNAL : LINKTYPE_SELF; - } - else if( (aTargetUrl.getLength() == 1) && (aTargetUrl[ 0 ] == ':') ) - { - if( getBiff() >= BIFF4 ) - meLinkType = LINKTYPE_ANALYSIS; - } + } + else if( (aTargetUrl.getLength() == 1) && (aTargetUrl[ 0 ] == ':') ) + { + if( getBiff() >= BIFF4 ) + meLinkType = LINKTYPE_ANALYSIS; + } else if( (aTargetUrl.getLength() > 1) || (aTargetUrl[ 0 ] != ' ') ) - { + { setExternalTargetUrl( aTargetUrl, OOX_TARGETTYPE_EXTLINK ); - } + } break; case BIFF_TARGETTYPE_SAMESHEET: @@ -834,13 +914,13 @@ void ExternalLink::insertExternalSheet( const OUString& rSheetName ) { Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName ); sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1; - maIndexes.push_back( nCacheIdx ); + maSheetCaches.push_back( nCacheIdx ); } } ExternalNameRef ExternalLink::createExternalName() { - ExternalNameRef xExtName( new ExternalName( *this, getSheetIndex() ) ); + ExternalNameRef xExtName( new ExternalName( *this ) ); maExtNames.push_back( xExtName ); return xExtName; } diff --git a/oox/source/xls/externallinkfragment.cxx b/oox/source/xls/externallinkfragment.cxx index 0245c44eb13c..39686ae7cb64 100644 --- a/oox/source/xls/externallinkfragment.cxx +++ b/oox/source/xls/externallinkfragment.cxx @@ -338,7 +338,7 @@ ContextHandlerRef OoxExternalLinkFragment::onCreateRecordContext( sal_Int32 nRec ContextHandlerRef OoxExternalLinkFragment::createSheetDataContext( sal_Int32 nSheetId ) { - return new OoxExternalSheetDataContext( *this, mrExtLink.getExternalSheetCache( nSheetId ) ); + return new OoxExternalSheetDataContext( *this, mrExtLink.getSheetCache( nSheetId ) ); } // oox.core.FragmentHandler2 interface ---------------------------------------- @@ -475,11 +475,11 @@ void BiffExternalLinkFragment::importXct() case BIFF3: case BIFF4: case BIFF5: - mxSheetCache = mxExtLink->getExternalSheetCache( 0 ); + mxSheetCache = mxExtLink->getSheetCache( 0 ); break; case BIFF8: mrStrm.skip( 2 ); - mxSheetCache = mxExtLink->getExternalSheetCache( mrStrm.readInt16() ); + mxSheetCache = mxExtLink->getSheetCache( mrStrm.readInt16() ); break; case BIFF_UNKNOWN: break; } diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx index 33465d81d466..7b503142a89e 100644 --- a/oox/source/xls/pivotcachebuffer.cxx +++ b/oox/source/xls/pivotcachebuffer.cxx @@ -1369,7 +1369,7 @@ void PivotCache::importDConUrl( BiffInputStream& rStrm ) void PivotCache::finalizeInternalSheetSource() { // resolve sheet name to sheet index - sal_Int32 nSheet = getWorksheets().getCalcSheetIndex( maSheetSrcModel.maSheet ); + sal_Int16 nSheet = getWorksheets().getCalcSheetIndex( maSheetSrcModel.maSheet ); // if cache is based on a defined name or table, try to resolve to cell range if( maSheetSrcModel.maDefName.getLength() > 0 ) @@ -1393,7 +1393,7 @@ void PivotCache::finalizeInternalSheetSource() else if( nSheet >= 0 ) { // insert sheet index into the range, range address will be checked below - maSheetSrcModel.maRange.Sheet = static_cast< sal_Int16 >( nSheet ); + maSheetSrcModel.maRange.Sheet = nSheet; mbValidSource = true; } // else sheet has been deleted, generate the source data from cache diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx index d4e93f4bf47a..a4f8f1379654 100644 --- a/oox/source/xls/richstring.cxx +++ b/oox/source/xls/richstring.cxx @@ -29,6 +29,7 @@ ************************************************************************/ #include "oox/xls/richstring.hxx" +#include #include #include "oox/helper/attributelist.hxx" #include "oox/helper/propertyset.hxx" @@ -37,6 +38,7 @@ using ::rtl::OString; using ::rtl::OUString; +using ::rtl::OUStringBuffer; using ::com::sun::star::uno::Reference; using ::com::sun::star::text::XText; using ::com::sun::star::text::XTextRange; @@ -490,12 +492,20 @@ void RichString::finalizeImport() maFontPortions.forEachMem( &RichStringPortion::finalizeImport ); } +OUString RichString::getPlainText() const +{ + OUStringBuffer aBuffer; + for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt ) + aBuffer.append( (*aIt)->getText() ); + return aBuffer.makeStringAndClear(); +} + void RichString::convert( const Reference< XText >& rxText, sal_Int32 nXfId ) const { for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt ) { (*aIt)->convert( rxText, nXfId ); - nXfId = -1; + nXfId = -1; // use passed XF identifier for first portion only } } diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx index 64d660f5c559..dc7456e1e4c9 100644 --- a/oox/source/xls/stylesbuffer.cxx +++ b/oox/source/xls/stylesbuffer.cxx @@ -29,7 +29,8 @@ ************************************************************************/ #include "oox/xls/stylesbuffer.hxx" -#include +#include +#include #include #include #include @@ -59,14 +60,22 @@ using ::rtl::OUString; using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::container::XNameAccess; +using ::com::sun::star::container::XNamed; using ::com::sun::star::awt::FontDescriptor; using ::com::sun::star::awt::XDevice; using ::com::sun::star::awt::XFont2; using ::com::sun::star::table::BorderLine; using ::com::sun::star::text::XText; using ::com::sun::star::style::XStyle; +using ::oox::core::FilterBase; namespace oox { namespace xls { @@ -257,6 +266,11 @@ const sal_uInt32 BIFF_XF_DIAG_BLTR = 0x80000000; /// Bottom-left to t const sal_uInt16 BIFF_STYLE_BUILTIN = 0x8000; const sal_uInt16 BIFF_STYLE_XFMASK = 0x0FFF; +// BIFF STYLEEXT flags +const sal_uInt8 BIFF_STYLEEXT_BUILTIN = 0x01; +const sal_uInt8 BIFF_STYLEEXT_HIDDEN = 0x02; +const sal_uInt8 BIFF_STYLEEXT_CUSTOM = 0x04; + // BIFF conditional formatting const sal_uInt32 BIFF_CFRULE_BORDER_LEFT = 0x00000400; const sal_uInt32 BIFF_CFRULE_BORDER_RIGHT = 0x00000800; @@ -280,8 +294,7 @@ const sal_uInt32 BIFF_CFRULE_FONT_ESCAPEM = 0x00000001; /// Font escapement // ---------------------------------------------------------------------------- -template< typename StreamType > -sal_Int32 lclReadRgbColor( StreamType& rStrm ) +sal_Int32 lclReadRgbColor( BinaryInputStream& rStrm ) { sal_uInt8 nR, nG, nB, nA; rStrm >> nR >> nG >> nB >> nA; @@ -299,39 +312,34 @@ sal_Int32 lclReadRgbColor( StreamType& rStrm ) // ---------------------------------------------------------------------------- -Color::Color() : - meMode( COLOR_AUTO ), - mnValue( 0 ), - mfTint( 0.0 ) -{ -} - void Color::setAuto() { - meMode = COLOR_AUTO; - mnValue = 0; - mfTint = 0.0; + clearTransformations(); + setSchemeClr( XML_phClr ); } void Color::setRgb( sal_Int32 nRgbValue, double fTint ) { - meMode = COLOR_RGB; - mnValue = nRgbValue; - mfTint = fTint; + clearTransformations(); + setSrgbClr( nRgbValue & 0xFFFFFF ); + if( fTint != 0.0 ) addExcelTintTransformation( fTint ); } void Color::setTheme( sal_Int32 nThemeIdx, double fTint ) { - meMode = COLOR_THEME; - mnValue = nThemeIdx; - mfTint = fTint; + clearTransformations(); + static const sal_Int32 spnColorTokens[] = { + XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2, + XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink }; + setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) ); + if( fTint != 0.0 ) addExcelTintTransformation( fTint ); } void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint ) { - meMode = COLOR_INDEXED; - mnValue = nPaletteIdx; - mfTint = fTint; + clearTransformations(); + setPaletteClr( nPaletteIdx ); + if( fTint != 0.0 ) addExcelTintTransformation( fTint ); } void Color::importColor( const AttributeList& rAttribs ) @@ -408,38 +416,6 @@ void Color::importColorRgb( BiffInputStream& rStrm ) setRgb( lclReadRgbColor( rStrm ) ); } -bool Color::isAuto() const -{ - return meMode == COLOR_AUTO; -} - -sal_Int32 Color::getColor( const WorkbookHelper& rHelper, sal_Int32 nAuto ) const -{ - switch( meMode ) - { - case COLOR_AUTO: return nAuto; - case COLOR_FINAL: return mnValue; - - case COLOR_RGB: mnValue &= 0xFFFFFF; break; - case COLOR_THEME: mnValue = rHelper.getTheme().getColorByIndex( mnValue ); break; - case COLOR_INDEXED: mnValue = rHelper.getStyles().getPaletteColor( mnValue ); break; - } - - // color tint - OSL_ENSURE( (rHelper.getFilterType() == FILTER_OOX) || (mfTint == 0.0), - "Color::getColor - color tint only supported in OOX filter" ); - if( (mnValue >= 0) && (rHelper.getFilterType() == FILTER_OOX) && (mfTint != 0.0) ) - { - ::oox::drawingml::Color aTransformColor; - aTransformColor.setSrgbClr( mnValue ); - aTransformColor.addExcelTintTransformation( mfTint ); - mnValue = aTransformColor.getColor( rHelper.getOoxFilter() ); - } - - meMode = COLOR_FINAL; - return mnValue; -} - RecordInputStream& operator>>( RecordInputStream& rStrm, Color& orColor ) { orColor.importColor( rStrm ); @@ -532,14 +508,13 @@ ColorPalette::ColorPalette( const WorkbookHelper& rHelper ) : void ColorPalette::importPaletteColor( const AttributeList& rAttribs ) { - appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ) ); + appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_WHITE ) ); } void ColorPalette::importPaletteColor( RecordInputStream& rStrm ) { - Color aColor; - aColor.importColorRgb( rStrm ); - appendColor( aColor.getColor( *this ) ); + sal_Int32 nRgb = lclReadRgbColor( rStrm ); + appendColor( nRgb & 0xFFFFFF ); } void ColorPalette::importPalette( BiffInputStream& rStrm ) @@ -550,11 +525,10 @@ void ColorPalette::importPalette( BiffInputStream& rStrm ) // fill palette from BIFF_COLOR_USEROFFSET mnAppendIndex = BIFF_COLOR_USEROFFSET; - Color aColor; for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex ) { - aColor.importColorRgb( rStrm ); - appendColor( aColor.getColor( *this ) ); + sal_Int32 nRgb = lclReadRgbColor( rStrm ); + appendColor( nRgb & 0xFFFFFF ); } } @@ -574,7 +548,7 @@ sal_Int32 ColorPalette::getColor( sal_Int32 nPaletteIdx ) const case OOX_COLOR_WINDOWBACK: case OOX_COLOR_CHWINDOWBACK: nColor = getBaseFilter().getSystemColor( XML_window ); break; case OOX_COLOR_BUTTONBACK: nColor = getBaseFilter().getSystemColor( XML_btnFace ); break; - case OOX_COLOR_CHBORDERAUTO: nColor = 0x000000; /* really always black? */ break; + case OOX_COLOR_CHBORDERAUTO: nColor = API_RGB_BLACK; /* really always black? */ break; case OOX_COLOR_NOTEBACK: nColor = getBaseFilter().getSystemColor( XML_infoBk ); break; case OOX_COLOR_NOTETEXT: nColor = getBaseFilter().getSystemColor( XML_infoText ); break; case OOX_COLOR_FONTAUTO: nColor = API_RGB_TRANSPARENT; break; @@ -1013,7 +987,7 @@ void Font::finalizeImport() rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) ); // color, height, weight, slant, strikeout, outline, shadow - maApiData.mnColor = maModel.maColor.getColor( *this, API_RGB_TRANSPARENT ); + maApiData.mnColor = maModel.maColor.getColor( getBaseFilter() ); maApiData.maDesc.Height = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 ); maApiData.maDesc.Weight = maModel.mbBold ? cssawt::FontWeight::BOLD : cssawt::FontWeight::NORMAL; maApiData.maDesc.Slant = maModel.mbItalic ? cssawt::FontSlant_ITALIC : cssawt::FontSlant_NONE; @@ -1750,7 +1724,7 @@ BorderLineModel* Border::getBorderLine( sal_Int32 nElement ) bool Border::convertBorderLine( BorderLine& rBorderLine, const BorderLineModel& rModel ) { - rBorderLine.Color = rModel.maColor.getColor( *this, API_RGB_BLACK ); + rBorderLine.Color = rModel.maColor.getColor( getBaseFilter(), API_RGB_BLACK ); switch( rModel.mnStyle ) { case XML_dashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; @@ -2046,6 +2020,8 @@ void Fill::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) void Fill::finalizeImport() { + const FilterBase& rFilter = getBaseFilter(); + if( mxPatternModel.get() ) { // finalize the OOX data struct @@ -2096,15 +2072,16 @@ void Fill::finalizeImport() case XML_solid: nAlpha = 0x80; break; } + sal_Int32 nWinTextColor = rFilter.getSystemColor( XML_windowText ); + sal_Int32 nWinColor = rFilter.getSystemColor( XML_window ); + if( !rModel.mbPattColorUsed ) rModel.maPatternColor.setAuto(); - sal_Int32 nPattColor = rModel.maPatternColor.getColor( - *this, getBaseFilter().getSystemColor( XML_windowText ) ); + sal_Int32 nPattColor = rModel.maPatternColor.getColor( rFilter, nWinTextColor ); if( !rModel.mbFillColorUsed ) rModel.maFillColor.setAuto(); - sal_Int32 nFillColor = rModel.maFillColor.getColor( - *this, getBaseFilter().getSystemColor( XML_window ) ); + sal_Int32 nFillColor = rModel.maFillColor.getColor( rFilter, nWinColor ); maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha ); maApiData.mbTransparent = false; @@ -2116,11 +2093,11 @@ void Fill::finalizeImport() maApiData.mbUsed = true; // no support for differential attributes GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin(); OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); - maApiData.mnColor = aIt->second.getColor( *this ); + maApiData.mnColor = aIt->second.getColor( rFilter, API_RGB_WHITE ); if( ++aIt != rModel.maColors.end() ) { OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); - sal_Int32 nEndColor = aIt->second.getColor( *this ); + sal_Int32 nEndColor = aIt->second.getColor( rFilter, API_RGB_WHITE ); maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 ); maApiData.mbTransparent = false; } @@ -2369,10 +2346,7 @@ void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const // create and set cell style if( maModel.mbCellXf ) - { - const OUString& rStyleName = rStyles.createCellStyle( maModel.mnStyleXfId ); - rPropMap[ PROP_CellStyle ] <<= rStyleName; - } + rPropMap[ PROP_CellStyle ] <<= rStyles.createCellStyle( maModel.mnStyleXfId ); if( maModel.mbFontUsed ) rStyles.writeFontToPropertyMap( rPropMap, maModel.mnFontId ); @@ -2585,11 +2559,7 @@ namespace { const sal_Char* const spcLegacyStyleNamePrefix = "Excel_BuiltIn_"; const sal_Char* const sppcLegacyStyleNames[] = { -#if OOX_XLS_USE_DEFAULT_STYLE - "", // use existing "Default" style -#else "Normal", -#endif "RowLevel_", // outline level will be appended "ColumnLevel_", // outline level will be appended "Comma", @@ -2605,11 +2575,7 @@ const sal_Int32 snLegacyStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY const sal_Char* const spcStyleNamePrefix = "Excel Built-in "; const sal_Char* const sppcStyleNames[] = { -#if OOX_XLS_USE_DEFAULT_STYLE - "", // use existing "Default" style -#else "Normal", -#endif "RowLevel_", // outline level will be appended "ColLevel_", // outline level will be appended "Comma", @@ -2666,50 +2632,32 @@ const sal_Char* const sppcStyleNames[] = }; const sal_Int32 snStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( sppcStyleNames ) ); -#if OOX_XLS_USE_DEFAULT_STYLE -const sal_Char* const spcDefaultStyleName = "Default"; -#endif - OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 ) { + OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" ); OUStringBuffer aStyleName; - OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown builtin style" ); -#if OOX_XLS_USE_DEFAULT_STYLE - if( nBuiltinId == OOX_STYLE_NORMAL ) // "Normal" becomes "Default" style - { - aStyleName.appendAscii( spcDefaultStyleName ); - } + aStyleName.appendAscii( spcStyleNamePrefix ); + if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ][ 0 ] != 0) ) + aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] ); + else if( rName.getLength() > 0 ) + aStyleName.append( rName ); else - { -#endif - aStyleName.appendAscii( spcStyleNamePrefix ); - if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ][ 0 ] != 0) ) - aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] ); - else if( rName.getLength() > 0 ) - aStyleName.append( rName ); - else - aStyleName.append( nBuiltinId ); - if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) - aStyleName.append( nLevel ); -#if OOX_XLS_USE_DEFAULT_STYLE - } -#endif + aStyleName.append( nBuiltinId ); + if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) + aStyleName.append( nLevel ); return aStyleName.makeStringAndClear(); } -bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar ) +OUString lclGetBuiltInStyleName( const OUString& rName ) { -#if OOX_XLS_USE_DEFAULT_STYLE - // "Default" becomes "Normal" - if( rStyleName.equalsIgnoreAsciiCaseAscii( spcDefaultStyleName ) ) - { - if( pnBuiltinId ) *pnBuiltinId = OOX_STYLE_NORMAL; - if( pnNextChar ) *pnNextChar = rStyleName.getLength(); - return true; - } -#endif + OUStringBuffer aStyleName; + aStyleName.appendAscii( spcStyleNamePrefix ).append( rName ); + return aStyleName.makeStringAndClear(); +} - // try the other builtin styles +bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar ) +{ + // try the other built-in styles OUString aPrefix = OUString::createFromAscii( spcStyleNamePrefix ); sal_Int32 nPrefixLen = aPrefix.getLength(); sal_Int32 nFoundId = 0; @@ -2719,20 +2667,13 @@ bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, OUString aShortName; for( sal_Int32 nId = 0; nId < snStyleNamesCount; ++nId ) { -#if OOX_XLS_USE_DEFAULT_STYLE - if( nId != OOX_STYLE_NORMAL ) + aShortName = OUString::createFromAscii( sppcStyleNames[ nId ] ); + if( rStyleName.matchIgnoreAsciiCase( aShortName, nPrefixLen ) && + (nNextChar < nPrefixLen + aShortName.getLength()) ) { -#endif - aShortName = OUString::createFromAscii( sppcStyleNames[ nId ] ); - if( rStyleName.matchIgnoreAsciiCase( aShortName, nPrefixLen ) && - (nNextChar < nPrefixLen + aShortName.getLength()) ) - { - nFoundId = nId; - nNextChar = nPrefixLen + aShortName.getLength(); - } -#if OOX_XLS_USE_DEFAULT_STYLE + nFoundId = nId; + nNextChar = nPrefixLen + aShortName.getLength(); } -#endif } } @@ -2796,15 +2737,11 @@ bool CellStyleModel::isDefaultStyle() const return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL); } -OUString CellStyleModel::createStyleName() const -{ - return isBuiltin() ? lclGetBuiltinStyleName( mnBuiltinId, maName, mnLevel ) : maName; -} - // ============================================================================ CellStyle::CellStyle( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ) + WorkbookHelper( rHelper ), + mbCreated( false ) { } @@ -2823,8 +2760,8 @@ void CellStyle::importCellStyle( RecordInputStream& rStrm ) { sal_uInt16 nFlags; rStrm >> maModel.mnXfId >> nFlags; - maModel.mnBuiltinId = rStrm.readuInt8(); - maModel.mnLevel = rStrm.readuInt8(); + maModel.mnBuiltinId = rStrm.readInt8(); + maModel.mnLevel = rStrm.readInt8(); rStrm >> maModel.maName; maModel.mbBuiltin = getFlag( nFlags, OOBIN_CELLSTYLE_BUILTIN ); maModel.mbCustom = getFlag( nFlags, OOBIN_CELLSTYLE_CUSTOM ); @@ -2839,62 +2776,74 @@ void CellStyle::importStyle( BiffInputStream& rStrm ) maModel.mbBuiltin = getFlag( nStyleXf, BIFF_STYLE_BUILTIN ); if( maModel.mbBuiltin ) { - maModel.mnBuiltinId = rStrm.readuInt8(); - maModel.mnLevel = rStrm.readuInt8(); + maModel.mnBuiltinId = rStrm.readInt8(); + maModel.mnLevel = rStrm.readInt8(); } else { maModel.maName = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() ); + // #i103281# check if this is a new built-in style introduced in XL2007 + if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_STYLEEXT) && rStrm.startNextRecord() ) + { + sal_uInt8 nExtFlags; + rStrm.skip( 12 ); + rStrm >> nExtFlags; + maModel.mbBuiltin = getFlag( nExtFlags, BIFF_STYLEEXT_BUILTIN ); + maModel.mbCustom = getFlag( nExtFlags, BIFF_STYLEEXT_CUSTOM ); + maModel.mbHidden = getFlag( nExtFlags, BIFF_STYLEEXT_HIDDEN ); + if( maModel.mbBuiltin ) + { + maModel.mnBuiltinId = rStrm.readInt8(); + maModel.mnLevel = rStrm.readInt8(); + } + } } } -const OUString& CellStyle::createCellStyle( sal_Int32 nXfId, bool bSkipDefaultBuiltin ) +OUString CellStyle::calcInitialStyleName() const { - if( maCalcName.getLength() == 0 ) + return isBuiltin() ? lclGetBuiltinStyleName( maModel.mnBuiltinId, maModel.maName, maModel.mnLevel ) : maModel.maName; +} + +void CellStyle::createCellStyle() +{ + // #i1624# #i1768# ignore unnamed user styles + if( !mbCreated ) + mbCreated = maFinalName.getLength() == 0; + + /* #i103281# do not create another style of the same name, if it exists + already. This is needed to prevent that styles pasted from clipboard + get duplicated over and over. */ + if( !mbCreated ) try { - bool bBuiltin = maModel.isBuiltin(); - if( !bSkipDefaultBuiltin || !bBuiltin || maModel.mbCustom ) - { - // name of the style (generate unique name for builtin styles) - maCalcName = maModel.createStyleName(); - // #i1624# #i1768# ignore unnamed user styles - if( maCalcName.getLength() > 0 ) - { - Reference< XStyle > xStyle; -#if OOX_XLS_USE_DEFAULT_STYLE - // special handling for default style (do not create, but use existing) - if( isDefaultStyle() ) - { - /* Set all flags to true to have all properties in the style, - even if the used flags are not set (that's what Excel does). */ - if( Xf* pXf = getStyles().getStyleXf( nXfId ).get() ) - pXf->setAllUsedFlags( true ); - // use existing built-in style - xStyle = getStyleObject( maCalcName, false ); - } - else -#endif - { - /* Insert into cell styles collection, rename existing user styles, - if this is a built-in style, but do not do this in BIFF4 workspace - files, where built-in styles occur repeatedly. */ - bool bRenameExisting = bBuiltin && (getBiff() != BIFF4); - xStyle = createStyleObject( maCalcName, false, bRenameExisting ); - } - - // write style formatting properties - PropertySet aPropSet( xStyle ); - getStyles().writeStyleXfToPropertySet( aPropSet, nXfId ); -#if OOX_XLS_USE_DEFAULT_STYLE -#else - if( !isDefaultStyle() && xStyle.is() ) - xStyle->setParentStyle( getStyles().getDefaultStyleName() ); -#endif - } - } + Reference< XNameAccess > xCellStylesNA( getStyleFamily( false ), UNO_QUERY_THROW ); + mbCreated = xCellStylesNA->hasByName( maFinalName ); + } + catch( Exception& ) + { + } + + // create the style object in the document + if( !mbCreated ) try + { + mbCreated = true; + Reference< XStyle > xStyle( createStyleObject( maFinalName, false ), UNO_SET_THROW ); + // write style formatting properties + PropertySet aPropSet( xStyle ); + getStyles().writeStyleXfToPropertySet( aPropSet, maModel.mnXfId ); + if( !isDefaultStyle() ) + xStyle->setParentStyle( getStyles().getDefaultStyleName() ); } - return maCalcName; + catch( Exception& ) + { + } +} + +void CellStyle::finalizeImport() +{ + if( !isBuiltin() || maModel.mbCustom ) + createCellStyle(); } // ============================================================================ @@ -2906,6 +2855,32 @@ StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) : maDefStyleName( lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ) ), mnDefStyleXf( -1 ) { + /* Reserve style names that are built-in in Calc. This causes that + imported cell styles get different unused names and thus do not try to + overwrite these built-in styles. For BIFF4 workbooks (which contain a + separate list of cell styles per sheet), reserve all existing names if + current sheet is not the first sheet (this styles buffer will be + constructed again for every new sheet). This will create unique names + for styles in different sheets with the same name. */ + bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0); + try + { + Reference< XEnumerationAccess > xCellStylesEA( getStyleFamily( false ), UNO_QUERY_THROW ); + Reference< XEnumeration > xCellStylesEnum( xCellStylesEA->createEnumeration(), UNO_SET_THROW ); + while( xCellStylesEnum->hasMoreElements() ) + { + Reference< XStyle > xCellStyle( xCellStylesEnum->nextElement(), UNO_QUERY_THROW ); + if( bReserveAll || !xCellStyle->isUserDefined() ) + { + Reference< XNamed > xCellStyleName( xCellStyle, UNO_QUERY_THROW ); + // create an empty entry by using ::std::map<>::operator[] + maCellStylesByName[ xCellStyleName->getName() ]; + } + } + } + catch( Exception& ) + { + } } FontRef StylesBuffer::createFont( sal_Int32* opnFontId ) @@ -3075,12 +3050,10 @@ void StylesBuffer::finalizeImport() maDxfs.forEachMem( &Dxf::finalizeImport ); // create the default cell style first - if( CellStyle* pDefStyle = maCellStyles.get( mnDefStyleXf ).get() ) - pDefStyle->createCellStyle( mnDefStyleXf ); - /* Create user-defined and modified builtin cell styles, passing true to - createStyleSheet() skips unchanged builtin styles. */ - for( CellStyleMap::iterator aIt = maCellStyles.begin(), aEnd = maCellStyles.end(); aIt != aEnd; ++aIt ) - aIt->second->createCellStyle( aIt->first, true ); + if( CellStyle* pDefStyle = maCellStylesById.get( mnDefStyleXf ).get() ) + pDefStyle->createCellStyle(); + // create user-defined and modified built-in cell styles + maCellStylesById.forEachMem( &CellStyle::finalizeImport ); } sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const @@ -3136,8 +3109,13 @@ const FontModel& StylesBuffer::getDefaultFontModel() const const OUString& StylesBuffer::createCellStyle( sal_Int32 nXfId ) const { - if( CellStyle* pCellStyle = maCellStyles.get( nXfId ).get() ) - return pCellStyle->createCellStyle( nXfId ); + if( CellStyle* pCellStyle = maCellStylesById.get( nXfId ).get() ) + { + pCellStyle->createCellStyle(); + const OUString& rStyleName = pCellStyle->getFinalStyleName(); + if( rStyleName.getLength() > 0 ) + return rStyleName; + } // on error: fallback to default style return maDefStyleName; } @@ -3150,13 +3128,10 @@ const OUString& StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const return maDefStyleName; } -#if OOX_XLS_USE_DEFAULT_STYLE -#else const OUString& StylesBuffer::getDefaultStyleName() const { return createCellStyle( mnDefStyleXf ); } -#endif void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const { @@ -3207,11 +3182,38 @@ void StylesBuffer::writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 n void StylesBuffer::insertCellStyle( CellStyleRef xCellStyle ) { - if( xCellStyle->getXfId() >= 0 ) + sal_Int32 nXfId = xCellStyle->getXfId(); + OUString aStyleName = xCellStyle->calcInitialStyleName(); + // #i1624# #i1768# ignore unnamed user styles + if( (nXfId >= 0) && (aStyleName.getLength() > 0) ) { - maCellStyles[ xCellStyle->getXfId() ] = xCellStyle; + // insert into the XF identifier map + maCellStylesById[ nXfId ] = xCellStyle; + + // find an unused name + OUString aUnusedName = aStyleName; + sal_Int32 nIndex = 0; + while( maCellStylesByName.count( aUnusedName ) > 0 ) + aUnusedName = OUStringBuffer( aStyleName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear(); + + // move old existing style to new unused name, if new style is built-in + if( xCellStyle->isBuiltin() && (aStyleName != aUnusedName) ) + { + CellStyleRef& rxCellStyle = maCellStylesByName[ aUnusedName ]; + rxCellStyle = maCellStylesByName[ aStyleName ]; + // the entry may be empty if the style name has been reserved in c'tor + if( rxCellStyle.get() ) + rxCellStyle->setFinalStyleName( aUnusedName ); + aUnusedName = aStyleName; + } + + // insert new style + maCellStylesByName[ aUnusedName ] = xCellStyle; + xCellStyle->setFinalStyleName( aUnusedName ); + + // remember XF identifier of default cell style if( xCellStyle->isDefaultStyle() ) - mnDefStyleXf = xCellStyle->getXfId(); + mnDefStyleXf = nXfId; } } diff --git a/oox/source/xls/themebuffer.cxx b/oox/source/xls/themebuffer.cxx index b2baefccd5a5..e089e5fece77 100644 --- a/oox/source/xls/themebuffer.cxx +++ b/oox/source/xls/themebuffer.cxx @@ -117,14 +117,6 @@ sal_Int32 ThemeBuffer::getColorByToken( sal_Int32 nToken ) const return getClrScheme().getColor( nToken, nColor ) ? nColor : API_RGB_TRANSPARENT; } -sal_Int32 ThemeBuffer::getColorByIndex( sal_Int32 nIndex ) const -{ - static const sal_Int32 spnColorTokens[] = { - XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2, - XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink }; - return getColorByToken( STATIC_ARRAY_SELECT( spnColorTokens, nIndex, XML_TOKEN_INVALID ) ); -} - // ============================================================================ } // namespace xls diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx index caeacaf6d45d..2d53541b404c 100644 --- a/oox/source/xls/viewsettings.cxx +++ b/oox/source/xls/viewsettings.cxx @@ -56,7 +56,8 @@ using ::com::sun::star::container::XNameContainer; using ::com::sun::star::container::XIndexContainer; using ::com::sun::star::container::XIndexAccess; using ::com::sun::star::document::XViewDataSupplier; -using ::com::sun::star::table::CellAddress; +using ::com::sun::star::table::CellAddress; +using ::oox::core::FilterBase; namespace oox { namespace xls { @@ -199,6 +200,11 @@ sal_Int32 SheetViewModel::getPageBreakZoom() const return getLimitedValue< sal_Int32 >( nZoom, API_ZOOMVALUE_MIN, API_ZOOMVALUE_MAX ); } +sal_Int32 SheetViewModel::getGridColor( const FilterBase& rFilter ) const +{ + return mbDefGridColor ? API_RGB_TRANSPARENT : maGridColor.getColor( rFilter ); +} + const PaneSelectionModel* SheetViewModel::getPaneSelection( sal_Int32 nPaneId ) const { return maPaneSelMap.get( nPaneId ).get(); @@ -500,7 +506,7 @@ void SheetViewSettings::finalizeImport() } // sheet selected (active sheet must be selected) - bool bSelected = xModel->mbSelected || (getSheetIndex() == getViewSettings().getActiveSheetIndex()); + bool bSelected = xModel->mbSelected || (getSheetIndex() == getViewSettings().getActiveCalcSheet()); // visible area and current cursor position (selection not supported via API) CellAddress aFirstPos = xModel->maFirstPos; @@ -560,10 +566,6 @@ void SheetViewSettings::finalizeImport() break; } - // automatic grid color - if( xModel->mbDefGridColor ) - xModel->maGridColor.setAuto(); - // write the sheet view settings into the property sequence PropertyMap aPropMap; aPropMap[ PROP_TableSelected ] <<= bSelected; @@ -581,7 +583,7 @@ void SheetViewSettings::finalizeImport() aPropMap[ PROP_ZoomType ] <<= API_ZOOMTYPE_PERCENT; aPropMap[ PROP_ZoomValue ] <<= static_cast< sal_Int16 >( xModel->getNormalZoom() ); aPropMap[ PROP_PageViewZoomValue ] <<= static_cast< sal_Int16 >( xModel->getPageBreakZoom() ); - aPropMap[ PROP_GridColor ] <<= xModel->maGridColor.getColor( *this ); + aPropMap[ PROP_GridColor ] <<= xModel->getGridColor( getBaseFilter() ); aPropMap[ PROP_ShowPageBreakPreview ] <<= xModel->isPageBreakPreview(); aPropMap[ PROP_ShowFormulas ] <<= xModel->mbShowFormulas; aPropMap[ PROP_ShowGrid ] <<= xModel->mbShowGrid; @@ -692,7 +694,7 @@ void ViewSettings::importWindow1( BiffInputStream& rStrm ) } } -void ViewSettings::setSheetViewSettings( sal_Int32 nSheet, const SheetViewModelRef& rxSheetView, const Any& rProperties ) +void ViewSettings::setSheetViewSettings( sal_Int16 nSheet, const SheetViewModelRef& rxSheetView, const Any& rProperties ) { maSheetViews[ nSheet ] = rxSheetView; maSheetProps[ nSheet ] = rProperties; @@ -701,7 +703,7 @@ void ViewSettings::setSheetViewSettings( sal_Int32 nSheet, const SheetViewModelR void ViewSettings::finalizeImport() { const WorksheetBuffer& rWorksheets = getWorksheets(); - if( rWorksheets.getSheetCount() <= 0 ) return; + if( rWorksheets.getWorksheetCount() <= 0 ) return; // force creation of workbook view model to get the Excel defaults const WorkbookViewModel& rModel = maBookViews.empty() ? createWorkbookView() : *maBookViews.front(); @@ -716,7 +718,7 @@ void ViewSettings::finalizeImport() ContainerHelper::insertByName( xSheetsNC, rWorksheets.getCalcSheetName( aIt->first ), aIt->second ); // use active sheet to set sheet properties that are document-global in Calc - sal_Int32 nActiveSheet = getActiveSheetIndex(); + sal_Int16 nActiveSheet = getActiveCalcSheet(); SheetViewModelRef& rxActiveSheetView = maSheetViews[ nActiveSheet ]; OSL_ENSURE( rxActiveSheetView.get(), "ViewSettings::finalizeImport - missing active sheet view settings" ); if( !rxActiveSheetView ) @@ -735,7 +737,7 @@ void ViewSettings::finalizeImport() aPropMap[ PROP_ShowObjects ] <<= nShowMode; aPropMap[ PROP_ShowCharts ] <<= nShowMode; aPropMap[ PROP_ShowDrawing ] <<= nShowMode; - aPropMap[ PROP_GridColor ] <<= rxActiveSheetView->maGridColor.getColor( *this ); + aPropMap[ PROP_GridColor ] <<= rxActiveSheetView->getGridColor( getBaseFilter() ); aPropMap[ PROP_ShowPageBreakPreview ] <<= rxActiveSheetView->isPageBreakPreview(); aPropMap[ PROP_ShowFormulas ] <<= rxActiveSheetView->mbShowFormulas; aPropMap[ PROP_ShowGrid ] <<= rxActiveSheetView->mbShowGrid; @@ -754,10 +756,9 @@ void ViewSettings::finalizeImport() } } -sal_Int32 ViewSettings::getActiveSheetIndex() const +sal_Int16 ViewSettings::getActiveCalcSheet() const { - sal_Int32 nSheetCount = getLimitedValue< sal_Int32, sal_Int32 >( getWorksheets().getSheetCount(), 1, SAL_MAX_INT32 ); - return maBookViews.empty() ? 0 : getLimitedValue< sal_Int32, sal_Int32 >( maBookViews.front()->mnActiveSheet, 0, nSheetCount - 1 ); + return maBookViews.empty() ? 0 : ::std::max< sal_Int16 >( getWorksheets().getCalcSheetIndex( maBookViews.front()->mnActiveSheet ), 0 ); } // private -------------------------------------------------------------------- diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 1779cb4a7691..6a78c838838e 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -233,13 +233,15 @@ void OoxWorkbookFragment::finalizeImport() some preprocessing in the fragment constructors, e.g. loading the table fragments for all sheets that are needed before the cell formulas are loaded. */ - typedef ::std::map< sal_Int32, FragmentHandlerRef > SheetFragmentMap; - SheetFragmentMap aSheetFragments; + typedef ::std::vector< FragmentHandlerRef > SheetFragmentVector; + SheetFragmentVector aSheetFragments; WorksheetBuffer& rWorksheets = getWorksheets(); - sal_Int32 nSheetCount = rWorksheets.getSheetCount(); - for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet ) + sal_Int32 nWorksheetCount = rWorksheets.getWorksheetCount(); + for( sal_Int32 nWorksheet = 0; nWorksheet < nWorksheetCount; ++nWorksheet ) { - if( const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getSheetRelId( nSheet ) ) ) + sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); + const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getWorksheetRelId( nWorksheet ) ); + if( (nCalcSheet >= 0) && pRelation ) { // get fragment path of the sheet OUString aFragmentPath = getFragmentPathFromRelation( *pRelation ); @@ -247,33 +249,33 @@ void OoxWorkbookFragment::finalizeImport() if( aFragmentPath.getLength() > 0 ) { ::rtl::Reference< OoxWorksheetFragmentBase > xFragment; - double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet); + double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength ); // create the fragment according to the sheet type if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "worksheet" ) ) { - xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nSheet ) ); + xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nCalcSheet ) ); } else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "chartsheet" ) ) { - xFragment.set( new OoxChartsheetFragment( *this, aFragmentPath, xSheetSegment, nSheet ) ); + xFragment.set( new OoxChartsheetFragment( *this, aFragmentPath, xSheetSegment, nCalcSheet ) ); } else if( (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlMacrosheet" )) || (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlIntlMacrosheet" )) ) { - xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nSheet ) ); + xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nCalcSheet ) ); } else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "dialogsheet" ) ) { - xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nSheet ) ); + xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nCalcSheet ) ); } // insert the fragment into the map OSL_ENSURE( xFragment.is(), "OoxWorkbookFragment::finalizeImport - unknown sheet type" ); OSL_ENSURE( !xFragment.is() || xFragment->isValidSheet(), "OoxWorkbookFragment::finalizeImport - missing sheet in document" ); if( xFragment.is() && xFragment->isValidSheet() ) - aSheetFragments[ nSheet ].set( xFragment.get() ); + aSheetFragments.push_back( xFragment.get() ); } } } @@ -283,17 +285,13 @@ void OoxWorkbookFragment::finalizeImport() getTables().finalizeImport(); // load all worksheets - for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet ) + for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt ) { - SheetFragmentMap::iterator aIt = aSheetFragments.find( nSheet ); - if( aIt != aSheetFragments.end() ) - { - OOX_LOADSAVE_TIMER( IMPORTSHEETFRAGMENT ); - // import the sheet fragment - importOoxFragment( aIt->second ); - // delete fragment object, will free all allocated sheet buffers - aSheetFragments.erase( aIt ); - } + OOX_LOADSAVE_TIMER( IMPORTSHEETFRAGMENT ); + // import the sheet fragment + importOoxFragment( *aIt ); + // delete fragment object, will free all allocated sheet buffers + aIt->clear(); } // final conversions, e.g. calculation settings and view settings @@ -368,13 +366,14 @@ bool BiffWorkbookFragment::importFragment() // load sheet fragments (do not return false in bRet on missing/broken sheets) WorksheetBuffer& rWorksheets = getWorksheets(); bool bNextSheet = bRet; - for( sal_Int32 nSheet = 0, nSheetCount = rWorksheets.getSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet ) + for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet ) { // try to start a new sheet fragment - double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet); + double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); BiffFragmentType eSheetFragment = startFragment( getBiff() ); - bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nSheet ); + sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); + bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet ); } } break; @@ -435,19 +434,19 @@ bool BiffWorkbookFragment::importWorkspaceFragment() // load sheet fragments (do not return false in bRet on missing/broken sheets) bool bNextSheet = bRet; - for( sal_Int32 nSheet = 0, nSheetCount = rWorksheets.getSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet ) + for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet ) { // try to start a new sheet fragment (with leading SHEETHEADER record) bNextSheet = mrStrm.startNextRecord() && (mrStrm.getRecId() == BIFF_ID_SHEETHEADER); if( bNextSheet ) { - double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet); + double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); /* Read current sheet name (sheet substreams may not be in the same order as SHEET records are). */ mrStrm.skip( 4 ); OUString aSheetName = mrStrm.readByteStringUC( false, getTextEncoding() ); - sal_Int32 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName ); + sal_Int16 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName ); // load the sheet fragment records BiffFragmentType eSheetFragment = startFragment( getBiff() ); bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCurrSheet ); @@ -630,8 +629,12 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress return bRet; } -bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int32 nSheet ) +bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int16 nCalcSheet ) { + // no Calc sheet - skip the fragment + if( nCalcSheet < 0 ) + return skipFragment(); + // find the sheet type for this fragment WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET; switch( eFragment ) @@ -646,7 +649,7 @@ bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBa /* #i11183# Clear buffers that are used per-sheet, e.g. external links in BIFF4W and BIFF5 files, or defined names in BIFF4W files. */ - createBuffersPerSheet(); + createBuffersPerSheet( nCalcSheet ); // preprocess some records switch( getBiff() ) @@ -656,8 +659,6 @@ bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBa case BIFF3: case BIFF4: { - // set sheet index in defined names buffer to handle built-in names correctly - getDefinedNames().setLocalSheetIndex( nSheet ); // remember current record to seek back below sal_Int64 nRecHandle = mrStrm.getRecHandle(); // import the global records @@ -695,14 +696,14 @@ bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBa case SHEETTYPE_WORKSHEET: case SHEETTYPE_MACROSHEET: case SHEETTYPE_DIALOGSHEET: - xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nSheet ) ); + xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nCalcSheet ) ); break; case SHEETTYPE_CHARTSHEET: - xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nSheet ) ); + xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nCalcSheet ) ); break; case SHEETTYPE_MODULESHEET: case SHEETTYPE_EMPTYSHEET: - xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nSheet ) ); + xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nCalcSheet ) ); break; } // load the sheet fragment records diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx index 7cce9db80352..2b337050a996 100644 --- a/oox/source/xls/workbookhelper.cxx +++ b/oox/source/xls/workbookhelper.cxx @@ -298,8 +298,8 @@ public: Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const; /** Creates and returns a defined name on-the-fly in the Calc document. */ Reference< XNamedRange > createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const; - /** Creates a com.sun.star.style.Style object and returns its final name. */ - Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting ) const; + /** Creates and returns a com.sun.star.style.Style object for cells or pages. */ + Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle ) const; // buffers ---------------------------------------------------------------- @@ -367,7 +367,7 @@ public: /** Enables workbook file mode, used for BIFF4 workspace files. */ void setIsWorkbookFile(); /** Recreates global buffers that are used per sheet in specific BIFF versions. */ - void createBuffersPerSheet(); + void createBuffersPerSheet( sal_Int16 nSheet ); /** Returns the codec helper that stores the encoder/decoder object. */ inline BiffCodecHelper& getCodecHelper() { return *mxCodecHelper; } @@ -563,14 +563,14 @@ Reference< XNamedRange > WorkbookData::createNamedRangeObject( OUString& orName, return xNamedRange; } -Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting ) const +Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle ) const { Reference< XStyle > xStyle; try { Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW ); xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW ); - orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), bRenameOldExisting ); + orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), false ); } catch( Exception& ) { @@ -605,22 +605,28 @@ void WorkbookData::setIsWorkbookFile() mbWorkbook = true; } -void WorkbookData::createBuffersPerSheet() +void WorkbookData::createBuffersPerSheet( sal_Int16 nSheet ) { + // set mnCurrSheet to enable usage of WorkbookHelper::getCurrentSheetIndex() + mnCurrSheet = nSheet; switch( meBiff ) { case BIFF2: case BIFF3: + OSL_ENSURE( mnCurrSheet == 0, "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); + mxDefNames->setLocalCalcSheet( mnCurrSheet ); break; case BIFF4: - // #i11183# sheets in BIFF4W files have own styles or names - if( mbWorkbook ) + OSL_ENSURE( mbWorkbook || (mnCurrSheet == 0), "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); + // #i11183# sheets in BIFF4W files have own styles and names + if( mbWorkbook && (mnCurrSheet > 0) ) { mxStyles.reset( new StylesBuffer( *this ) ); mxDefNames.reset( new DefinedNamesBuffer( *this ) ); mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); } + mxDefNames->setLocalCalcSheet( mnCurrSheet ); break; case BIFF5: @@ -634,6 +640,7 @@ void WorkbookData::createBuffersPerSheet() case BIFF_UNKNOWN: break; } + mnCurrSheet = -1; } // private -------------------------------------------------------------------- @@ -850,7 +857,7 @@ Reference< XNameAccess > WorkbookHelper::getDdeLinks() const return mrBookData.getDdeLinks(); } -Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int32 nSheet ) const +Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const { Reference< XSpreadsheet > xSheet; try @@ -921,9 +928,9 @@ Reference< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orNam return mrBookData.createNamedRangeObject( orName, nNameFlags ); } -Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting ) const +Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const { - return mrBookData.createStyleObject( orStyleName, bPageStyle, bRenameOldExisting ); + return mrBookData.createStyleObject( orStyleName, bPageStyle ); } // buffers -------------------------------------------------------------------- @@ -1078,9 +1085,9 @@ void WorkbookHelper::setIsWorkbookFile() mrBookData.setIsWorkbookFile(); } -void WorkbookHelper::createBuffersPerSheet() +void WorkbookHelper::createBuffersPerSheet( sal_Int16 nSheet ) { - mrBookData.createBuffersPerSheet(); + mrBookData.createBuffersPerSheet( nSheet ); } BiffCodecHelper& WorkbookHelper::getCodecHelper() const diff --git a/oox/source/xls/worksheetbuffer.cxx b/oox/source/xls/worksheetbuffer.cxx index 64e8acbb6c9c..ee2491880c4e 100644 --- a/oox/source/xls/worksheetbuffer.cxx +++ b/oox/source/xls/worksheetbuffer.cxx @@ -38,7 +38,6 @@ #include #include "properties.hxx" #include "oox/helper/attributelist.hxx" -#include "oox/helper/containerhelper.hxx" #include "oox/helper/propertyset.hxx" #include "oox/helper/recordinputstream.hxx" #include "oox/core/filterbase.hxx" @@ -61,21 +60,6 @@ namespace xls { // ============================================================================ -namespace { - -/** Returns the base file name without path and extension. */ -OUString lclGetBaseFileName( const OUString& rUrl ) -{ - sal_Int32 nFileNamePos = ::std::max< sal_Int32 >( rUrl.lastIndexOf( '/' ) + 1, 0 ); - sal_Int32 nExtPos = rUrl.lastIndexOf( '.' ); - if( nExtPos <= nFileNamePos ) nExtPos = rUrl.getLength(); - return rUrl.copy( nFileNamePos, nExtPos - nFileNamePos ); -} - -} // namespace - -// ============================================================================ - SheetInfoModel::SheetInfoModel() : mnSheetId( -1 ), mnState( XML_visible ) @@ -89,11 +73,19 @@ WorksheetBuffer::WorksheetBuffer( const WorkbookHelper& rHelper ) : { } +/*static*/ OUString WorksheetBuffer::getBaseFileName( const OUString& rUrl ) +{ + sal_Int32 nFileNamePos = ::std::max< sal_Int32 >( rUrl.lastIndexOf( '/' ) + 1, 0 ); + sal_Int32 nExtPos = rUrl.lastIndexOf( '.' ); + if( nExtPos <= nFileNamePos ) nExtPos = rUrl.getLength(); + return rUrl.copy( nFileNamePos, nExtPos - nFileNamePos ); +} + void WorksheetBuffer::initializeSingleSheet() { OSL_ENSURE( maSheetInfos.empty(), "WorksheetBuffer::initializeSingleSheet - invalid call" ); SheetInfoModel aModel; - aModel.maName = lclGetBaseFileName( getBaseFilter().getFileUrl() ); + aModel.maName = getBaseFileName( getBaseFilter().getFileUrl() ); insertSheet( aModel ); } @@ -137,107 +129,132 @@ void WorksheetBuffer::importSheet( BiffInputStream& rStrm ) sal_Int16 WorksheetBuffer::insertEmptySheet( const OUString& rPreferredName, bool bVisible ) { - IndexNamePair aIndexName = insertSheet( rPreferredName, SAL_MAX_INT16, bVisible ); - return aIndexName.first; + return createSheet( rPreferredName, SAL_MAX_INT32, bVisible ).first; } -sal_Int32 WorksheetBuffer::getSheetCount() const +sal_Int32 WorksheetBuffer::getWorksheetCount() const { return static_cast< sal_Int32 >( maSheetInfos.size() ); } -OUString WorksheetBuffer::getSheetRelId( sal_Int32 nSheet ) const +OUString WorksheetBuffer::getWorksheetRelId( sal_Int32 nWorksheet ) const { - OUString aRelId; - if( const SheetInfoModel* pModel = getSheetInfo( nSheet ) ) - aRelId = pModel->maRelId; - return aRelId; + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->maRelId : OUString(); } -OUString WorksheetBuffer::getCalcSheetName( sal_Int32 nSheet ) const +sal_Int16 WorksheetBuffer::getCalcSheetIndex( sal_Int32 nWorksheet ) const { - OUString aName; - if( const SheetInfoModel* pModel = getSheetInfo( nSheet ) ) - aName = pModel->maFinalName; - return aName; + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->mnCalcSheet : -1; } -OUString WorksheetBuffer::getCalcSheetName( const OUString& rModelName ) const +OUString WorksheetBuffer::getCalcSheetName( sal_Int32 nWorksheet ) const { - for( SheetInfoModelVec::const_iterator aIt = maSheetInfos.begin(), aEnd = maSheetInfos.end(); aIt != aEnd; ++aIt ) - // TODO: handle encoded characters - if( aIt->maName.equalsIgnoreAsciiCase( rModelName ) ) - return aIt->maFinalName; - return OUString(); + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->maCalcName : OUString(); } -sal_Int32 WorksheetBuffer::getCalcSheetIndex( const OUString& rModelName ) const +sal_Int16 WorksheetBuffer::getCalcSheetIndex( const OUString& rWorksheetName ) const { - for( SheetInfoModelVec::const_iterator aIt = maSheetInfos.begin(), aEnd = maSheetInfos.end(); aIt != aEnd; ++aIt ) - // TODO: handle encoded characters - if( aIt->maName.equalsIgnoreAsciiCase( rModelName ) ) - return static_cast< sal_Int32 >( aIt - maSheetInfos.begin() ); - return -1; + const SheetInfo* pSheetInfo = maSheetInfosByName.get( rWorksheetName ).get(); + return pSheetInfo ? pSheetInfo->mnCalcSheet : -1; +} + +OUString WorksheetBuffer::getCalcSheetName( const OUString& rWorksheetName ) const +{ + if( const SheetInfo* pSheetInfo = maSheetInfosByName.get( rWorksheetName ).get() ) + { + bool bIsQuoted = pSheetInfo->maName != rWorksheetName; + return bIsQuoted ? pSheetInfo->maCalcQuotedName : pSheetInfo->maCalcName; + } + return OUString(); } // private -------------------------------------------------------------------- -const SheetInfoModel* WorksheetBuffer::getSheetInfo( sal_Int32 nSheet ) const +namespace { + +OUString lclQuoteName( const OUString& rName ) { - return ContainerHelper::getVectorElement( maSheetInfos, nSheet ); + OUStringBuffer aBuffer( rName ); + // duplicate all quote characters + for( sal_Int32 nPos = aBuffer.getLength() - 1; nPos >= 0; --nPos ) + if( aBuffer.charAt( nPos ) == '\'' ) + aBuffer.insert( nPos, sal_Unicode( '\'' ) ); + // add outer quotes and return + return aBuffer.insert( 0, sal_Unicode( '\'' ) ).append( sal_Unicode( '\'' ) ).makeStringAndClear(); } -WorksheetBuffer::IndexNamePair WorksheetBuffer::insertSheet( const OUString& rPreferredName, sal_Int16 nSheet, bool bVisible ) +} // namespace + +WorksheetBuffer::SheetInfo::SheetInfo( const SheetInfoModel& rModel, sal_Int16 nCalcSheet, const OUString& rCalcName ) : + SheetInfoModel( rModel ), + maCalcName( rCalcName ), + maCalcQuotedName( lclQuoteName( rCalcName ) ), + mnCalcSheet( nCalcSheet ) +{ +} + +WorksheetBuffer::IndexNamePair WorksheetBuffer::createSheet( const OUString& rPreferredName, sal_Int32 nSheetPos, bool bVisible ) { - IndexNamePair aIndexName; - aIndexName.first = -1; - aIndexName.second = (rPreferredName.getLength() == 0) ? CREATE_OUSTRING( "Sheet" ) : rPreferredName; try { Reference< XSpreadsheets > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW ); Reference< XIndexAccess > xSheetsIA( xSheets, UNO_QUERY_THROW ); Reference< XNameAccess > xSheetsNA( xSheets, UNO_QUERY_THROW ); + sal_Int16 nCalcSheet = -1; + OUString aSheetName = (rPreferredName.getLength() == 0) ? CREATE_OUSTRING( "Sheet" ) : rPreferredName; PropertySet aPropSet; - if( nSheet < xSheetsIA->getCount() ) + if( nSheetPos < xSheetsIA->getCount() ) { + nCalcSheet = static_cast< sal_Int16 >( nSheetPos ); // existing sheet - try to rename - Reference< XNamed > xSheetName( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW ); - if( xSheetName->getName() != aIndexName.second ) + Reference< XNamed > xSheetName( xSheetsIA->getByIndex( nSheetPos ), UNO_QUERY_THROW ); + if( xSheetName->getName() != aSheetName ) { - aIndexName.second = ContainerHelper::getUnusedName( xSheetsNA, aIndexName.second, ' ' ); - xSheetName->setName( aIndexName.second ); + aSheetName = ContainerHelper::getUnusedName( xSheetsNA, aSheetName, ' ' ); + xSheetName->setName( aSheetName ); } aPropSet.set( xSheetName ); } else { + nCalcSheet = static_cast< sal_Int16 >( xSheetsIA->getCount() ); // new sheet - insert with unused name - aIndexName.second = ContainerHelper::getUnusedName( xSheetsNA, aIndexName.second, ' ' ); - nSheet = static_cast< sal_Int16 >( xSheetsIA->getCount() ); - xSheets->insertNewByName( aIndexName.second, nSheet ); - aPropSet.set( xSheetsIA->getByIndex( nSheet ) ); + aSheetName = ContainerHelper::getUnusedName( xSheetsNA, aSheetName, ' ' ); + xSheets->insertNewByName( aSheetName, nCalcSheet ); + aPropSet.set( xSheetsIA->getByIndex( nCalcSheet ) ); } // sheet properties aPropSet.setProperty( PROP_IsVisible, bVisible ); // return final sheet index if sheet exists - aIndexName.first = nSheet; + return IndexNamePair( nCalcSheet, aSheetName ); } catch( Exception& ) { - OSL_ENSURE( false, "WorksheetBuffer::insertSheet - cannot insert or rename worksheet" ); + OSL_ENSURE( false, "WorksheetBuffer::createSheet - cannot insert or rename worksheet" ); } - return aIndexName; + return IndexNamePair( -1, OUString() ); } void WorksheetBuffer::insertSheet( const SheetInfoModel& rModel ) { - sal_Int16 nSheet = static_cast< sal_Int16 >( maSheetInfos.size() ); - maSheetInfos.push_back( rModel ); - IndexNamePair aIndexName = insertSheet( rModel.maName, nSheet, rModel.mnState == XML_visible ); - if( aIndexName.first >= 0 ) - maSheetInfos.back().maFinalName = aIndexName.second; + sal_Int32 nWorksheet = static_cast< sal_Int32 >( maSheetInfos.size() ); + IndexNamePair aIndexName = createSheet( rModel.maName, nWorksheet, rModel.mnState == XML_visible ); + ::boost::shared_ptr< SheetInfo > xSheetInfo( new SheetInfo( rModel, aIndexName.first, aIndexName.second ) ); + maSheetInfos.push_back( xSheetInfo ); + maSheetInfosByName[ rModel.maName ] = xSheetInfo; + maSheetInfosByName[ lclQuoteName( rModel.maName ) ] = xSheetInfo; +} + +bool WorksheetBuffer::SheetNameCompare::operator()( const OUString& rName1, const OUString& rName2 ) const +{ + // there is no wrapper in rtl::OUString, TODO: compare with collator + return ::rtl_ustr_compareIgnoreAsciiCase_WithLength( + rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0; } // ============================================================================ diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index 4b754114b031..ed8907cb5f03 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -228,7 +228,7 @@ void OoxDataValidationsContext::importDataValidation( RecordInputStream& rStrm ) // ============================================================================ OoxWorksheetFragment::OoxWorksheetFragment( const WorkbookHelper& rHelper, - const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : + const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : OoxWorksheetFragmentBase( rHelper, rFragmentPath, xProgressBar, eSheetType, nSheet ) { // import data tables related to this worksheet @@ -741,7 +741,7 @@ void OoxWorksheetFragment::importEmbeddedOleData( StreamDataSequence& orEmbedded // ============================================================================ -BiffWorksheetFragment::BiffWorksheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : +BiffWorksheetFragment::BiffWorksheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : BiffWorksheetFragmentBase( rParent, xProgressBar, eSheetType, nSheet ) { } diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index be8ac3d359db..ab2d5c1b1946 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -362,7 +362,7 @@ public: const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, - sal_Int32 nSheet ); + sal_Int16 nSheet ); /** Returns true, if this helper refers to an existing Calc sheet. */ inline bool isValidSheet() const { return mxSheet.is(); } @@ -522,8 +522,10 @@ private: /** Inserts all imported hyperlinks into their cell ranges. */ void finalizeHyperlinkRanges() const; + /** Generates the final URL for the passed hyperlink. */ + OUString getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const; /** Inserts a hyperlinks into the specified cell. */ - void finalizeHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const; + void insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const; /** Inserts all imported data validations into their cell ranges. */ void finalizeValidationRanges() const; @@ -593,7 +595,7 @@ private: // ---------------------------------------------------------------------------- -WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : +WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : WorkbookHelper( rHelper ), maTrueFormula( CREATE_OUSTRING( "=TRUE()" ) ), maFalseFormula( CREATE_OUSTRING( "=FALSE()" ) ), @@ -608,10 +610,9 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBar maSheetViewSett( *this ), mxProgressBar( xProgressBar ), meSheetType( eSheetType ), - mnSheet( static_cast< sal_Int16 >( nSheet ) ), + mnSheet( nSheet ), mbHasDefWidth( false ) { - OSL_ENSURE( nSheet <= SAL_MAX_INT16, "WorksheetData::WorksheetData - invalid sheet index" ); mxSheet = getSheetFromDoc( nSheet ); if( !mxSheet.is() ) mnSheet = -1; @@ -978,14 +979,11 @@ void WorksheetData::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, s void WorksheetData::initializeWorksheetImport() { -#if OOX_XLS_USE_DEFAULT_STYLE -#else // set default cell style for unused cells PropertySet aPropSet( mxSheet ); aPropSet.setProperty( PROP_CellStyle, getStyles().getDefaultStyleName() ); -#endif - /* remember current sheet index in global data, needed by some global + /* Remember current sheet index in global data, needed by some global objects, e.g. the chart converter. */ setCurrentSheetIndex( mnSheet ); } @@ -1006,9 +1004,9 @@ void WorksheetData::finalizeWorksheetImport() convertColumns(); convertRows(); lclUpdateProgressBar( mxFinalProgress, 0.75 ); - maComments.finalizeImport(); finalizeDrawing(); finalizeVmlDrawing(); + maComments.finalizeImport(); // after VML drawing lclUpdateProgressBar( mxFinalProgress, 1.0 ); // reset current sheet index in global data @@ -1169,42 +1167,44 @@ void WorksheetData::finalizeHyperlinkRanges() const { for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt ) { - OUStringBuffer aUrlBuffer; - if( aIt->maTarget.getLength() > 0 ) - aUrlBuffer.append( getBaseFilter().getAbsoluteUrl( aIt->maTarget ) ); - if( aIt->maLocation.getLength() > 0 ) - aUrlBuffer.append( sal_Unicode( '#' ) ).append( aIt->maLocation ); - OUString aUrl = aUrlBuffer.makeStringAndClear(); + OUString aUrl = getHyperlinkUrl( *aIt ); + // try to insert URL into each cell of the range if( aUrl.getLength() > 0 ) - { - // convert '#SheetName!A1' to '#SheetName.A1' - if( aUrl[ 0 ] == '#' ) - { - sal_Int32 nSepPos = aUrl.lastIndexOf( '!' ); - if( nSepPos > 0 ) - { - // replace the exclamation mark with a period - aUrl = aUrl.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) ); - // #i66592# convert sheet names that have been renamed on import - bool bQuotedName = (nSepPos > 3) && (aUrl[ 1 ] == '\'') && (aUrl[ nSepPos - 1 ] == '\''); - sal_Int32 nNamePos = bQuotedName ? 2 : 1; - sal_Int32 nNameLen = nSepPos - (bQuotedName ? 3 : 1); - OUString aSheetName = aUrl.copy( nNamePos, nNameLen ); - OUString aCalcName = getWorksheets().getCalcSheetName( aSheetName ); - if( aCalcName.getLength() > 0 ) - aUrl = aUrl.replaceAt( nNamePos, nNameLen, aCalcName ); - } - } - - // try to insert URL into each cell of the range for( CellAddress aAddress( mnSheet, aIt->maRange.StartColumn, aIt->maRange.StartRow ); aAddress.Row <= aIt->maRange.EndRow; ++aAddress.Row ) for( aAddress.Column = aIt->maRange.StartColumn; aAddress.Column <= aIt->maRange.EndColumn; ++aAddress.Column ) - finalizeHyperlink( aAddress, aUrl ); + insertHyperlink( aAddress, aUrl ); + } +} + +OUString WorksheetData::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const +{ + OUStringBuffer aUrlBuffer; + if( rHyperlink.maTarget.getLength() > 0 ) + aUrlBuffer.append( getBaseFilter().getAbsoluteUrl( rHyperlink.maTarget ) ); + if( rHyperlink.maLocation.getLength() > 0 ) + aUrlBuffer.append( sal_Unicode( '#' ) ).append( rHyperlink.maLocation ); + OUString aUrl = aUrlBuffer.makeStringAndClear(); + + // convert '#SheetName!A1' to '#SheetName.A1' + if( (aUrl.getLength() > 0) && (aUrl[ 0 ] == '#') ) + { + sal_Int32 nSepPos = aUrl.lastIndexOf( '!' ); + if( nSepPos > 0 ) + { + // replace the exclamation mark with a period + aUrl = aUrl.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) ); + // #i66592# convert sheet names that have been renamed on import + OUString aSheetName = aUrl.copy( 1, nSepPos - 1 ); + OUString aCalcName = getWorksheets().getCalcSheetName( aSheetName ); + if( aCalcName.getLength() > 0 ) + aUrl = aUrl.replaceAt( 1, nSepPos - 1, aCalcName ); } } + + return aUrl; } -void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const +void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const { Reference< XCell > xCell = getCell( rAddress ); if( xCell.is() ) switch( xCell->getType() ) @@ -1217,7 +1217,7 @@ void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUStri { // create a URL field object and set its properties Reference< XTextContent > xUrlField( getDocumentFactory()->createInstance( maUrlTextField ), UNO_QUERY ); - OSL_ENSURE( xUrlField.is(), "WorksheetData::finalizeHyperlink - cannot create text field" ); + OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" ); if( xUrlField.is() ) { // properties of the URL field @@ -1233,7 +1233,7 @@ void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUStri } catch( const Exception& ) { - OSL_ENSURE( false, "WorksheetData::finalizeHyperlink - cannot insert text field" ); + OSL_ENSURE( false, "WorksheetData::insertHyperlink - cannot insert text field" ); } } } @@ -1246,7 +1246,7 @@ void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUStri case ::com::sun::star::table::CellContentType_VALUE: { Reference< XFormulaTokens > xTokens( xCell, UNO_QUERY ); - OSL_ENSURE( xTokens.is(), "WorksheetHelper::finalizeHyperlink - missing formula interface" ); + OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula interface" ); if( xTokens.is() ) { SimpleFormulaContext aContext( xTokens, false, false ); @@ -2072,7 +2072,7 @@ WorksheetDataOwner::~WorksheetDataOwner() // ---------------------------------------------------------------------------- -WorksheetHelperRoot::WorksheetHelperRoot( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) : +WorksheetHelperRoot::WorksheetHelperRoot( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : prv::WorksheetDataOwner( prv::WorksheetDataRef( new WorksheetData( rHelper, xProgressBar, eSheetType, nSheet ) ) ), WorksheetHelper( *mxSheetData ) { diff --git a/oox/workben/pagesize/excel_pagesize.txt b/oox/workben/pagesize/excel_pagesize.txt deleted file mode 100644 index e6d8a05583cb..000000000000 --- a/oox/workben/pagesize/excel_pagesize.txt +++ /dev/null @@ -1,66 +0,0 @@ -1 = Letter paper (8.5 in. by 11 in.) -2 = Letter small paper (8.5 in. by 11 in.) -3 = Tabloid paper (11 in. by 17 in.) -4 = Ledger paper (17 in. by 11 in.) -5 = Legal paper (8.5 in. by 14 in.) -6 = Statement paper (5.5 in. by 8.5 in.) -7 = Executive paper (7.25 in. by 10.5 in.) -8 = A3 paper (297 mm by 420 mm) -9 = A4 paper (210 mm by 297 mm) -10 = A4 small paper (210 mm by 297 mm) -11 = A5 paper (148 mm by 210 mm) -12 = B4 paper (250 mm by 353 mm) -13 = B5 paper (176 mm by 250 mm) -14 = Folio paper (8.5 in. by 13 in.) -15 = Quarto paper (215 mm by 275 mm) -16 = Standard paper (10 in. by 14 in.) -17 = Standard paper (11 in. by 17 in.) -18 = Note paper (8.5 in. by 11 in.) -19 = #9 envelope (3.875 in. by 8.875 in.) -20 = #10 envelope (4.125 in. by 9.5 in.) -21 = #11 envelope (4.5 in. by 10.375 in.) -22 = #12 envelope (4.75 in. by 11 in.) -23 = #14 envelope (5 in. by 11.5 in.) -24 = C paper (17 in. by 22 in.) -25 = D paper (22 in. by 34 in.) -26 = E paper (34 in. by 44 in.) -27 = DL envelope (110 mm by 220 mm) -28 = C5 envelope (162 mm by 229 mm) -29 = C3 envelope (324 mm by 458 mm) -30 = C4 envelope (229 mm by 324 mm) -31 = C6 envelope (114 mm by 162 mm) -32 = C65 envelope (114 mm by 229 mm) -33 = B4 envelope (250 mm by 353 mm) -34 = B5 envelope (176 mm by 250 mm) -35 = B6 envelope (176 mm by 125 mm) -36 = Italy envelope (110 mm by 230 mm) -37 = Monarch envelope (3.875 in. by 7.5 in.). -38 = 6 3/4 envelope (3.625 in. by 6.5 in.) -39 = US standard fanfold (14.875 in. by 11 in.) -40 = German standard fanfold (8.5 in. by 12 in.) -41 = German legal fanfold (8.5 in. by 13 in.) -42 = ISO B4 (250 mm by 353 mm) -43 = Japanese double postcard (200 mm by 148 mm) -44 = Standard paper (9 in. by 11 in.) -45 = Standard paper (10 in. by 11 in.) -46 = Standard paper (15 in. by 11 in.) -47 = Invite envelope (220 mm by 220 mm) -50 = Letter extra paper (9.275 in. by 12 in.) -51 = Legal extra paper (9.275 in. by 15 in.) -52 = Tabloid extra paper (11.69 in. by 18 in.) -53 = A4 extra paper (236 mm by 322 mm) -54 = Letter transverse paper (8.275 in. by 11 in.) -55 = A4 transverse paper (210 mm by 297 mm) -56 = Letter extra transverse paper (9.275 in. by 12 in.) -57 = SuperA/SuperA/A4 paper (227 mm by 356 mm) -58 = SuperB/SuperB/A3 paper (305 mm by 487 mm) -59 = Letter plus paper (8.5 in. by 12.69 in.) -60 = A4 plus paper (210 mm by 330 mm) -61 = A5 transverse paper (148 mm by 210 mm) -62 = JIS B5 transverse paper (182 mm by 257 mm) -63 = A3 extra paper (322 mm by 445 mm) -64 = A5 extra paper (174 mm by 235 mm) -65 = ISO B5 extra paper (201 mm by 276 mm) -66 = A2 paper (420 mm by 594 mm) -67 = A3 transverse paper (297 mm by 420 mm) -68 = A3 extra transverse paper (322 mm by 445 mm) diff --git a/oox/workben/pagesize/parsePageSize.py b/oox/workben/pagesize/parsePageSize.py deleted file mode 100755 index 8b536baaeba4..000000000000 --- a/oox/workben/pagesize/parsePageSize.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python - -import sys - -class PageSize(object): - def __init__ (self): - self.index = 0 - self.list = [] - - def parseLine (self, line): - lhs, rhs = line.split("=") - name, size = rhs.split("(") - index = int(lhs) - name = name.strip() - size = size[:size.rfind(")")] - words = size.split() - width, height = float(words[0]), float(words[3]) - if words[1] != words[4]: - print "unit mismatch", words[1], words[4] - sys.exit(1) - unit = '' - if words[1] == 'mm': - unit = 'mm' - elif words[1] == 'in.': - unit = 'inches' - else: - print "unknown unit:", words[1] - sys.exit(1) - - item = {'index': index, 'name': name, 'width': width, 'height': height, 'unit': unit} - self.list.append(item) - - def output (self): - print "static const XmlPaperSize PaperSizeTable[] =" - print "{" - line = " { 0, 0 }," - while len(line) <= 60: - line += ' ' - line += "// 0 - (undefined)" - print line - n = len(self.list) - for i in xrange(0, n): - if self.list[i]['unit'] == 'mm': - macro = 'MM2MM100' - elif self.list[i]['unit'] == 'inches': - macro = 'IN2MM100' - else: - print "unknown unit:", self.list[i]['unit'] - sys.exit(1) - line = " " - line += '{ ' + macro + "( %g )"%self.list[i]['width'] + ',' - while len(line) <= 28: - line += ' ' - line += macro + "( %g )"%self.list[i]['height'] - while len(line) <= 48: - line += ' ' - line += '}' - if i != n - 1: - line += "," - while len(line) <= 60: - line += ' ' - if self.list[i]['index'] < 10: - line += "// %d - "%self.list[i]['index'] + self.list[i]['name'] - else: - line += "// %d - "%self.list[i]['index'] + self.list[i]['name'] - - print line - print "};" - return - - -if len(sys.argv) < 2: - sys.exit(1) - -obj = PageSize() -for line in open(sys.argv[1], 'r').readlines(): - obj.parseLine(line) -obj.output() -- cgit