summaryrefslogtreecommitdiff
path: root/oox/source
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source')
-rw-r--r--oox/source/core/fasttokenhandler.cxx95
-rw-r--r--oox/source/core/filterbase.cxx14
-rw-r--r--oox/source/core/makefile.mk1
-rw-r--r--oox/source/core/xmlfilterbase.cxx15
-rw-r--r--oox/source/drawingml/chart/objectformatter.cxx4
-rw-r--r--oox/source/drawingml/clrschemecontext.cxx1
-rw-r--r--oox/source/drawingml/color.cxx582
-rw-r--r--oox/source/drawingml/customshapeproperties.cxx2
-rw-r--r--oox/source/drawingml/fillproperties.cxx60
-rw-r--r--oox/source/drawingml/lineproperties.cxx153
-rw-r--r--oox/source/drawingml/linepropertiescontext.cxx6
-rw-r--r--oox/source/drawingml/shape.cxx6
-rw-r--r--oox/source/drawingml/table/tablecell.cxx3
-rw-r--r--oox/source/drawingml/textcharacterproperties.cxx1
-rw-r--r--oox/source/drawingml/textparagraphproperties.cxx1
-rw-r--r--oox/source/dump/biffdumper.cxx19
-rw-r--r--oox/source/dump/biffdumper.ini22
-rw-r--r--oox/source/helper/propertymap.cxx24
-rw-r--r--oox/source/ole/axcontrolhelper.cxx10
-rw-r--r--oox/source/ppt/animvariantcontext.cxx1
-rw-r--r--oox/source/ppt/pptimport.cxx20
-rw-r--r--oox/source/ppt/slidepersist.cxx4
-rw-r--r--oox/source/ppt/timenodelistcontext.cxx1
-rw-r--r--oox/source/shape/FastTokenHandlerService.hxx19
-rw-r--r--oox/source/shape/ShapeFilterBase.cxx5
-rw-r--r--oox/source/shape/ShapeFilterBase.hxx3
-rw-r--r--oox/source/token/gentoken.pl14
-rw-r--r--oox/source/token/propertylist.cxx14
-rw-r--r--oox/source/token/tokenmap.cxx96
-rw-r--r--oox/source/token/tokens.txt8
-rw-r--r--oox/source/vml/makefile.mk1
-rw-r--r--oox/source/vml/vmldrawing.cxx5
-rw-r--r--oox/source/vml/vmldrawingfragment.cxx4
-rw-r--r--oox/source/vml/vmlformatting.cxx585
-rw-r--r--oox/source/vml/vmlshape.cxx173
-rw-r--r--oox/source/vml/vmlshapecontext.cxx152
-rw-r--r--oox/source/xls/chartsheetfragment.cxx4
-rw-r--r--oox/source/xls/commentsbuffer.cxx39
-rw-r--r--oox/source/xls/defnamesbuffer.cxx146
-rw-r--r--oox/source/xls/drawingfragment.cxx42
-rw-r--r--oox/source/xls/excelfilter.cxx64
-rw-r--r--oox/source/xls/excelhandlers.cxx6
-rw-r--r--oox/source/xls/externallinkbuffer.cxx166
-rw-r--r--oox/source/xls/externallinkfragment.cxx6
-rw-r--r--oox/source/xls/pivotcachebuffer.cxx4
-rw-r--r--oox/source/xls/richstring.cxx12
-rw-r--r--oox/source/xls/stylesbuffer.cxx394
-rw-r--r--oox/source/xls/themebuffer.cxx8
-rw-r--r--oox/source/xls/viewsettings.cxx29
-rw-r--r--oox/source/xls/workbookfragment.cxx69
-rw-r--r--oox/source/xls/workbookhelper.cxx33
-rw-r--r--oox/source/xls/worksheetbuffer.cxx147
-rw-r--r--oox/source/xls/worksheetfragment.cxx4
-rw-r--r--oox/source/xls/worksheethelper.cxx86
54 files changed, 2247 insertions, 1136 deletions
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
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/fasttokenhandler.hxx"
+#include <osl/mutex.hxx>
+#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 <cstdio>
+#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/embed/XRelationshipAccess.hpp>
@@ -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 <algorithm>
#include <math.h>
+#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 <com/sun/star/awt/FontWeight.hpp>
#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 <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#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 <oox/core/fasttokenhandler.hxx>
+#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 <sal/config.h>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#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 ( <TOKENS> )
@@ -17,15 +17,15 @@ while ( <TOKENS> )
}
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 <sal/types.h>\n" );
+print ( HXX "#include <com/sun/star/xml/sax/FastToken.hpp>\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 <rtl/ustring.hxx>
+#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 <string.h>
-#include <osl/mutex.hxx>
+#include "oox/token/tokenmap.hxx"
#include <rtl/strbuf.hxx>
-#include <com/sun/star/xml/sax/FastToken.hpp>
-#include "oox/core/fasttokenhandler.hxx"
+#include <rtl/string.hxx>
#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
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlformatting.hxx"
+#include <rtl/strbuf.hxx>
+#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 <modifier>(<amount>)'
+ 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 <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/PropertyValues.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
-#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
@@ -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 <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp>
#include <com/sun/star/sheet/XSheetAnnotations.hpp>
#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
-#include <com/sun/star/text/XText.hpp>
#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 <rtl/ustrbuf.hxx>
#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/ExternalReference.hpp>
#include <com/sun/star/sheet/NamedRangeFlag.hpp>
#include <com/sun/star/sheet/ReferenceFlags.hpp>
#include <com/sun/star/sheet/SingleReference.hpp>
@@ -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 <rtl/strbuf.hxx>
+#include <com/sun/star/sheet/ComplexReference.hpp>
#include <com/sun/star/sheet/DDELinkInfo.hpp>
#include <com/sun/star/sheet/ExternalLinkType.hpp>
+#include <com/sun/star/sheet/ExternalReference.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/SingleReference.hpp>
#include <com/sun/star/sheet/XDDELinks.hpp>
#include <com/sun/star/sheet/XDDELink.hpp>
#include <com/sun/star/sheet/XDDELinkResults.hpp>
@@ -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 <rtl/ustrbuf.hxx>
#include <com/sun/star/text/XText.hpp>
#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 <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/awt/FontFamily.hpp>
#include <com/sun/star/awt/FontPitch.hpp>
@@ -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 <com/sun/star/sheet/XSheetLinkable.hpp>
#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 )
{