summaryrefslogtreecommitdiff
path: root/oox/source
diff options
context:
space:
mode:
authorRüdiger Timm <rt@openoffice.org>2008-01-17 07:06:10 +0000
committerRüdiger Timm <rt@openoffice.org>2008-01-17 07:06:10 +0000
commit3381981e76873304b171f7df900561dac681d2af (patch)
treef496d5a2006e8719b5783d5a8966a05858ed3014 /oox/source
parent90e7bde2a1f3dd8c81e947578f14f40059961740 (diff)
#i10000# Bring module to HEAD.
Diffstat (limited to 'oox/source')
-rw-r--r--oox/source/core/binarycodec.cxx388
-rw-r--r--oox/source/core/binaryfilterbase.cxx74
-rw-r--r--oox/source/core/facreg.cxx157
-rw-r--r--oox/source/core/filterbase.cxx247
-rw-r--r--oox/source/core/filterdetect.cxx404
-rw-r--r--oox/source/core/fragmenthandler.cxx149
-rw-r--r--oox/source/core/makefile.mk69
-rw-r--r--oox/source/core/recordparser.cxx362
-rw-r--r--oox/source/core/relations.cxx139
-rw-r--r--oox/source/core/relationshandler.cxx106
-rw-r--r--oox/source/core/skipcontext.cxx50
-rw-r--r--oox/source/core/xmlfilterbase.cxx300
-rw-r--r--oox/source/drawingml/clrscheme.cxx104
-rw-r--r--oox/source/drawingml/clrschemecontext.cxx137
-rw-r--r--oox/source/drawingml/color.cxx64
-rw-r--r--oox/source/drawingml/colorchoicecontext.cxx146
-rw-r--r--oox/source/drawingml/connectorshapecontext.cxx89
-rw-r--r--oox/source/drawingml/customshapegeometry.cxx1071
-rw-r--r--oox/source/drawingml/customshapeproperties.cxx156
-rw-r--r--oox/source/drawingml/diagram/datamodelcontext.cxx336
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx130
-rw-r--r--oox/source/drawingml/diagram/diagramdefinitioncontext.cxx124
-rw-r--r--oox/source/drawingml/diagram/diagramdefinitioncontext.hxx60
-rw-r--r--oox/source/drawingml/diagram/diagramfragmenthandler.cxx233
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx149
-rw-r--r--oox/source/drawingml/diagram/layoutnodecontext.cxx368
-rw-r--r--oox/source/drawingml/diagram/layoutnodecontext.hxx61
-rw-r--r--oox/source/drawingml/diagram/makefile.mk61
-rw-r--r--oox/source/drawingml/drawingmltypes.cxx433
-rw-r--r--oox/source/drawingml/embeddedwavaudiofile.cxx64
-rw-r--r--oox/source/drawingml/fillproperties.cxx117
-rw-r--r--oox/source/drawingml/fillpropertiesgroupcontext.cxx457
-rw-r--r--oox/source/drawingml/graphicshapecontext.cxx335
-rw-r--r--oox/source/drawingml/hyperlinkcontext.cxx121
-rw-r--r--oox/source/drawingml/hyperlinkcontext.hxx67
-rw-r--r--oox/source/drawingml/lineproperties.cxx349
-rw-r--r--oox/source/drawingml/linepropertiescontext.cxx157
-rw-r--r--oox/source/drawingml/makefile.mk96
-rw-r--r--oox/source/drawingml/objectdefaultcontext.cxx81
-rw-r--r--oox/source/drawingml/shape.cxx489
-rw-r--r--oox/source/drawingml/shapecontext.cxx130
-rw-r--r--oox/source/drawingml/shapegroupcontext.cxx125
-rw-r--r--oox/source/drawingml/shapepropertiescontext.cxx140
-rw-r--r--oox/source/drawingml/shapestylecontext.cxx148
-rw-r--r--oox/source/drawingml/spdefcontext.cxx83
-rw-r--r--oox/source/drawingml/textbody.cxx86
-rw-r--r--oox/source/drawingml/textbodycontext.cxx224
-rw-r--r--oox/source/drawingml/textbodypropertiescontext.cxx161
-rw-r--r--oox/source/drawingml/textcharacterproperties.cxx135
-rw-r--r--oox/source/drawingml/textcharacterpropertiescontext.cxx282
-rw-r--r--oox/source/drawingml/textfield.cxx196
-rw-r--r--oox/source/drawingml/textfieldcontext.cxx107
-rw-r--r--oox/source/drawingml/textliststyle.cxx78
-rw-r--r--oox/source/drawingml/textliststylecontext.cxx120
-rw-r--r--oox/source/drawingml/textparagraph.cxx127
-rw-r--r--oox/source/drawingml/textparagraphproperties.cxx419
-rw-r--r--oox/source/drawingml/textparagraphpropertiescontext.cxx306
-rw-r--r--oox/source/drawingml/textrun.cxx120
-rw-r--r--oox/source/drawingml/textspacingcontext.cxx87
-rw-r--r--oox/source/drawingml/textspacingcontext.hxx69
-rw-r--r--oox/source/drawingml/texttabstoplistcontext.cxx106
-rw-r--r--oox/source/drawingml/texttabstoplistcontext.hxx69
-rw-r--r--oox/source/drawingml/theme.cxx55
-rw-r--r--oox/source/drawingml/themeelementscontext.cxx234
-rw-r--r--oox/source/drawingml/themefragmenthandler.cxx108
-rw-r--r--oox/source/dump/biffdumper.cxx3195
-rw-r--r--oox/source/dump/biffdumperconfig.dat1782
-rw-r--r--oox/source/dump/dffdumper.cxx212
-rw-r--r--oox/source/dump/dumperbase.cxx2775
-rw-r--r--oox/source/dump/dumperconfig.dat436
-rw-r--r--oox/source/dump/makefile.mk60
-rw-r--r--oox/source/dump/olestoragedumper.cxx449
-rw-r--r--oox/source/dump/xlsbdumper.cxx1920
-rw-r--r--oox/source/dump/xlsbdumperconfig.dat655
-rw-r--r--oox/source/helper/attributelist.cxx111
-rw-r--r--oox/source/helper/binaryinputstream.cxx113
-rw-r--r--oox/source/helper/binaryoutputstream.cxx121
-rw-r--r--oox/source/helper/binarystreambase.cxx91
-rw-r--r--oox/source/helper/containerhelper.cxx173
-rw-r--r--oox/source/helper/makefile.mk68
-rw-r--r--oox/source/helper/olestorage.cxx186
-rw-r--r--oox/source/helper/progressbar.cxx193
-rw-r--r--oox/source/helper/propertymap.cxx286
-rw-r--r--oox/source/helper/propertysequence.cxx164
-rw-r--r--oox/source/helper/propertyset.cxx157
-rw-r--r--oox/source/helper/recordinputstream.cxx104
-rw-r--r--oox/source/helper/storagebase.cxx201
-rw-r--r--oox/source/helper/zipstorage.cxx174
-rw-r--r--oox/source/ppt/animationspersist.cxx210
-rw-r--r--oox/source/ppt/animationtypes.cxx82
-rw-r--r--oox/source/ppt/animationtypes.hxx55
-rw-r--r--oox/source/ppt/animvariantcontext.cxx132
-rw-r--r--oox/source/ppt/animvariantcontext.hxx69
-rw-r--r--oox/source/ppt/backgroundproperties.cxx79
-rw-r--r--oox/source/ppt/buildlistcontext.cxx121
-rw-r--r--oox/source/ppt/buildlistcontext.hxx72
-rw-r--r--oox/source/ppt/commonbehaviorcontext.cxx188
-rw-r--r--oox/source/ppt/commonbehaviorcontext.hxx90
-rw-r--r--oox/source/ppt/commontimenodecontext.cxx717
-rw-r--r--oox/source/ppt/commontimenodecontext.hxx70
-rw-r--r--oox/source/ppt/conditioncontext.cxx222
-rw-r--r--oox/source/ppt/conditioncontext.hxx92
-rw-r--r--oox/source/ppt/customshowlistcontext.cxx129
-rw-r--r--oox/source/ppt/customshowlistcontext.hxx71
-rw-r--r--oox/source/ppt/layoutfragmenthandler.cxx92
-rw-r--r--oox/source/ppt/makefile.mk83
-rw-r--r--oox/source/ppt/pptfilterhelpers.cxx148
-rw-r--r--oox/source/ppt/pptfilterhelpers.hxx112
-rw-r--r--oox/source/ppt/pptimport.cxx135
-rw-r--r--oox/source/ppt/pptshape.cxx179
-rw-r--r--oox/source/ppt/pptshapecontext.cxx209
-rw-r--r--oox/source/ppt/pptshapegroupcontext.cxx123
-rw-r--r--oox/source/ppt/pptshapepropertiescontext.cxx94
-rw-r--r--oox/source/ppt/presentationfragmenthandler.cxx301
-rw-r--r--oox/source/ppt/slidefragmenthandler.cxx193
-rw-r--r--oox/source/ppt/slidemastertextstylescontext.cxx94
-rw-r--r--oox/source/ppt/slidepersist.cxx320
-rw-r--r--oox/source/ppt/slidetimingcontext.cxx113
-rw-r--r--oox/source/ppt/slidetransition.cxx393
-rw-r--r--oox/source/ppt/slidetransitioncontext.cxx213
-rw-r--r--oox/source/ppt/soundactioncontext.cxx144
-rw-r--r--oox/source/ppt/timeanimvaluecontext.cxx113
-rw-r--r--oox/source/ppt/timeanimvaluecontext.hxx72
-rw-r--r--oox/source/ppt/timenode.cxx635
-rw-r--r--oox/source/ppt/timenodelistcontext.cxx1181
-rw-r--r--oox/source/ppt/timetargetelementcontext.cxx185
-rw-r--r--oox/source/ppt/timetargetelementcontext.hxx65
-rw-r--r--oox/source/shape/FastTokenHandlerService.cxx119
-rw-r--r--oox/source/shape/FastTokenHandlerService.hxx89
-rw-r--r--oox/source/shape/ShapeContextHandler.cxx245
-rw-r--r--oox/source/shape/ShapeContextHandler.hxx160
-rw-r--r--oox/source/shape/ShapeFilterBase.cxx69
-rw-r--r--oox/source/shape/ShapeFilterBase.hxx80
-rw-r--r--oox/source/shape/makefile.mk58
-rw-r--r--oox/source/token/gentoken.pl55
-rw-r--r--oox/source/token/makefile.mk66
-rw-r--r--oox/source/token/parsexsd.pl48
-rw-r--r--oox/source/token/tokenmap.cxx105
-rw-r--r--oox/source/token/tokens.txt5569
-rw-r--r--oox/source/vml/makefile.mk58
-rw-r--r--oox/source/vml/vmldrawing.cxx101
-rw-r--r--oox/source/vml/vmldrawingfragmenthandler.cxx226
-rw-r--r--oox/source/vml/vmlshape.cxx72
-rw-r--r--oox/source/xls/addressconverter.cxx772
-rw-r--r--oox/source/xls/autofiltercontext.cxx770
-rw-r--r--oox/source/xls/biffcodec.cxx211
-rw-r--r--oox/source/xls/biffdetector.cxx241
-rw-r--r--oox/source/xls/bifffragmenthandler.cxx169
-rw-r--r--oox/source/xls/biffhelper.cxx296
-rw-r--r--oox/source/xls/biffinputstream.cxx646
-rw-r--r--oox/source/xls/biffoutputstream.cxx191
-rw-r--r--oox/source/xls/condformatbuffer.cxx782
-rw-r--r--oox/source/xls/condformatcontext.cxx114
-rw-r--r--oox/source/xls/connectionsfragment.cxx127
-rw-r--r--oox/source/xls/defnamesbuffer.cxx674
-rw-r--r--oox/source/xls/excelfilter.cxx284
-rw-r--r--oox/source/xls/externallinkbuffer.cxx857
-rw-r--r--oox/source/xls/externallinkfragment.cxx392
-rw-r--r--oox/source/xls/formulabase.cxx1459
-rw-r--r--oox/source/xls/formulaparser.cxx2595
-rw-r--r--oox/source/xls/headerfooterparser.cxx643
-rw-r--r--oox/source/xls/makefile.mk106
-rw-r--r--oox/source/xls/numberformatsbuffer.cxx2124
-rw-r--r--oox/source/xls/pagesettings.cxx641
-rw-r--r--oox/source/xls/pivotcachefragment.cxx160
-rw-r--r--oox/source/xls/pivottablebuffer.cxx275
-rw-r--r--oox/source/xls/pivottablefragment.cxx194
-rw-r--r--oox/source/xls/querytablefragment.cxx82
-rw-r--r--oox/source/xls/richstring.cxx605
-rw-r--r--oox/source/xls/richstringcontext.cxx118
-rw-r--r--oox/source/xls/sharedformulabuffer.cxx220
-rw-r--r--oox/source/xls/sharedstringsbuffer.cxx91
-rw-r--r--oox/source/xls/sharedstringsfragment.cxx110
-rw-r--r--oox/source/xls/sheetcellrangemap.cxx172
-rw-r--r--oox/source/xls/sheetdatacontext.cxx1160
-rw-r--r--oox/source/xls/stylesbuffer.cxx3214
-rw-r--r--oox/source/xls/stylesfragment.cxx316
-rw-r--r--oox/source/xls/stylespropertyhelper.cxx386
-rw-r--r--oox/source/xls/tablebuffer.cxx172
-rw-r--r--oox/source/xls/tablefragment.cxx92
-rw-r--r--oox/source/xls/themebuffer.cxx170
-rw-r--r--oox/source/xls/unitconverter.cxx209
-rw-r--r--oox/source/xls/validationpropertyhelper.cxx174
-rw-r--r--oox/source/xls/viewsettings.cxx789
-rw-r--r--oox/source/xls/webquerybuffer.cxx207
-rw-r--r--oox/source/xls/workbookfragment.cxx756
-rw-r--r--oox/source/xls/workbookhelper.cxx876
-rw-r--r--oox/source/xls/workbooksettings.cxx297
-rw-r--r--oox/source/xls/worksheetbuffer.cxx333
-rw-r--r--oox/source/xls/worksheetfragment.cxx1068
-rw-r--r--oox/source/xls/worksheethelper.cxx1652
-rw-r--r--oox/source/xls/worksheetsettings.cxx270
192 files changed, 68819 insertions, 0 deletions
diff --git a/oox/source/core/binarycodec.cxx b/oox/source/core/binarycodec.cxx
new file mode 100644
index 000000000000..746a555f082d
--- /dev/null
+++ b/oox/source/core/binarycodec.cxx
@@ -0,0 +1,388 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarycodec.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/binarycodec.hxx"
+#include <algorithm>
+#include <osl/diagnose.h>
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+namespace {
+
+/** Rotates rnValue left by nBits bits. */
+template< typename Type >
+inline void lclRotateLeft( Type& rnValue, size_t nBits )
+{
+ OSL_ENSURE( nBits < sizeof( Type ) * 8, "lclRotateLeft - rotation count overflow" );
+ rnValue = static_cast< Type >( (rnValue << nBits) | (rnValue >> (sizeof( Type ) * 8 - nBits)) );
+}
+
+/** Rotates the lower nWidth bits of rnValue left by nBits bits. */
+template< typename Type >
+inline void lclRotateLeft( Type& rnValue, size_t nBits, size_t nWidth )
+{
+ OSL_ENSURE( (nBits < nWidth) && (nWidth < sizeof( Type ) * 8), "lclRotateLeft - rotation count overflow" );
+ Type nMask = static_cast< Type >( (1UL << nWidth) - 1 );
+ rnValue = static_cast< Type >(
+ ((rnValue << nBits) | ((rnValue & nMask) >> (nWidth - nBits))) & nMask );
+}
+
+sal_Int32 lclGetLen( const sal_uInt8* pnPassData, sal_Int32 nBufferSize )
+{
+ sal_Int32 nLen = 0;
+ while( (nLen < nBufferSize) && pnPassData[ nLen ] ) ++nLen;
+ return nLen;
+}
+
+sal_uInt16 lclGetKey( const sal_uInt8* pnPassData, sal_Int32 nBufferSize )
+{
+ sal_Int32 nLen = lclGetLen( pnPassData, nBufferSize );
+ if( nLen <= 0 ) return 0;
+
+ sal_uInt16 nKey = 0;
+ sal_uInt16 nKeyBase = 0x8000;
+ sal_uInt16 nKeyEnd = 0xFFFF;
+ const sal_uInt8* pnChar = pnPassData + nLen - 1;
+ for( sal_Int32 nIndex = 0; nIndex < nLen; ++nIndex, --pnChar )
+ {
+ sal_uInt8 cChar = *pnChar & 0x7F;
+ for( size_t nBit = 0; nBit < 8; ++nBit )
+ {
+ lclRotateLeft( nKeyBase, 1 );
+ if( nKeyBase & 1 ) nKeyBase ^= 0x1020;
+ if( cChar & 1 ) nKey ^= nKeyBase;
+ cChar >>= 1;
+ lclRotateLeft( nKeyEnd, 1 );
+ if( nKeyEnd & 1 ) nKeyEnd ^= 0x1020;
+ }
+ }
+ return nKey ^ nKeyEnd;
+}
+
+sal_uInt16 lclGetHash( const sal_uInt8* pnPassData, sal_Int32 nBufferSize )
+{
+ sal_Int32 nLen = lclGetLen( pnPassData, nBufferSize );
+
+ sal_uInt16 nHash = static_cast< sal_uInt16 >( nLen );
+ if( nLen > 0 )
+ nHash ^= 0xCE4B;
+
+ const sal_uInt8* pnChar = pnPassData;
+ for( sal_Int32 nIndex = 0; nIndex < nLen; ++nIndex, ++pnChar )
+ {
+ sal_uInt16 cChar = *pnChar;
+ size_t nRot = static_cast< size_t >( (nIndex + 1) % 15 );
+ lclRotateLeft( cChar, nRot, 15 );
+ nHash ^= cChar;
+ }
+ return nHash;
+}
+
+} // namespace
+
+// ============================================================================
+
+BinaryCodec_XOR::BinaryCodec_XOR( CodecType eCodecType ) :
+ meCodecType( eCodecType ),
+ mnOffset( 0 ),
+ mnBaseKey( 0 ),
+ mnHash( 0 )
+{
+ (void)memset( mpnKey, 0, sizeof( mpnKey ) );
+}
+
+BinaryCodec_XOR::~BinaryCodec_XOR()
+{
+ (void)memset( mpnKey, 0, sizeof( mpnKey ) );
+ mnBaseKey = mnHash = 0;
+}
+
+void BinaryCodec_XOR::initKey( const sal_uInt8 pnPassData[ 16 ] )
+{
+ // calculate base key and hash from passed password
+ mnBaseKey = lclGetKey( pnPassData, 16 );
+ mnHash = lclGetHash( pnPassData, 16 );
+
+ static const sal_uInt8 spnFillChars[] =
+ {
+ 0xBB, 0xFF, 0xFF, 0xBA,
+ 0xFF, 0xFF, 0xB9, 0x80,
+ 0x00, 0xBE, 0x0F, 0x00,
+ 0xBF, 0x0F, 0x00
+ };
+
+ (void)memcpy( mpnKey, pnPassData, 16 );
+ sal_Int32 nIndex;
+ sal_Int32 nLen = lclGetLen( pnPassData, 16 );
+ const sal_uInt8* pnFillChar = spnFillChars;
+ for( nIndex = nLen; nIndex < static_cast< sal_Int32 >( sizeof( mpnKey ) ); ++nIndex, ++pnFillChar )
+ mpnKey[ nIndex ] = *pnFillChar;
+
+ // rotation of key values is application dependent
+ size_t nRotateSize = 0;
+ switch( meCodecType )
+ {
+ case CODEC_WORD: nRotateSize = 7; break;
+ case CODEC_EXCEL: nRotateSize = 2; break;
+ // compiler will warn, if new codec type is introduced and not handled here
+ }
+
+ // use little-endian base key to create key array
+ sal_uInt8 pnBaseKeyLE[ 2 ];
+ pnBaseKeyLE[ 0 ] = static_cast< sal_uInt8 >( mnBaseKey );
+ pnBaseKeyLE[ 1 ] = static_cast< sal_uInt8 >( mnBaseKey >> 8 );
+ sal_uInt8* pnKeyChar = mpnKey;
+ for( nIndex = 0; nIndex < static_cast< sal_Int32 >( sizeof( mpnKey ) ); ++nIndex, ++pnKeyChar )
+ {
+ *pnKeyChar ^= pnBaseKeyLE[ nIndex & 1 ];
+ lclRotateLeft( *pnKeyChar, nRotateSize );
+ }
+}
+
+bool BinaryCodec_XOR::verifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const
+{
+ return (nKey == mnBaseKey) && (nHash == mnHash);
+}
+
+void BinaryCodec_XOR::startBlock()
+{
+ mnOffset = 0;
+}
+
+bool BinaryCodec_XOR::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int32 nBytes )
+{
+ const sal_uInt8* pnCurrKey = mpnKey + mnOffset;
+ const sal_uInt8* pnKeyLast = mpnKey + 0x0F;
+
+ // switch/case outside of the for loop (performance)
+ const sal_uInt8* pnSrcDataEnd = pnSrcData + nBytes;
+ switch( meCodecType )
+ {
+ case CODEC_WORD:
+ {
+ for( ; pnSrcData < pnSrcDataEnd; ++pnSrcData, ++pnDestData )
+ {
+ sal_uInt8 nData = *pnSrcData ^ *pnCurrKey;
+ if( (*pnSrcData != 0) && (nData != 0) )
+ *pnDestData = nData;
+ if( pnCurrKey < pnKeyLast ) ++pnCurrKey; else pnCurrKey = mpnKey;
+ }
+ }
+ break;
+ case CODEC_EXCEL:
+ {
+ for( ; pnSrcData < pnSrcDataEnd; ++pnSrcData, ++pnDestData )
+ {
+ *pnDestData = *pnSrcData;
+ lclRotateLeft( *pnDestData, 3 );
+ *pnDestData ^= *pnCurrKey;
+ if( pnCurrKey < pnKeyLast ) ++pnCurrKey; else pnCurrKey = mpnKey;
+ }
+ }
+ break;
+ // compiler will warn, if new codec type is introduced and not handled here
+ }
+
+ // update offset and leave
+ return skip( nBytes );
+}
+
+bool BinaryCodec_XOR::skip( sal_Int32 nBytes )
+{
+ mnOffset = static_cast< sal_Int32 >( (mnOffset + nBytes) & 0x0F );
+ return true;
+}
+
+sal_uInt16 BinaryCodec_XOR::getHash( const sal_uInt8* pnPassData, sal_Int32 nSize )
+{
+ return lclGetHash( pnPassData, nSize );
+}
+
+// ============================================================================
+
+BinaryCodec_RCF::BinaryCodec_RCF()
+{
+ mhCipher = rtl_cipher_create( rtl_Cipher_AlgorithmARCFOUR, rtl_Cipher_ModeStream );
+ OSL_ENSURE( mhCipher != 0, "BinaryCodec_RCF::BinaryCodec_RCF - cannot create cipher" );
+
+ mhDigest = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ OSL_ENSURE( mhDigest != 0, "BinaryCodec_RCF::BinaryCodec_RCF - cannot create digest" );
+
+ (void)memset( mpnDigestValue, 0, sizeof( mpnDigestValue ) );
+}
+
+BinaryCodec_RCF::~BinaryCodec_RCF()
+{
+ (void)memset( mpnDigestValue, 0, sizeof( mpnDigestValue ) );
+ rtl_digest_destroy( mhDigest );
+ rtl_cipher_destroy( mhCipher );
+}
+
+void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnUnique[ 16 ] )
+{
+ // create little-endian key data array from password data
+ sal_uInt8 pnKeyData[ 64 ];
+ (void)memset( pnKeyData, 0, sizeof( pnKeyData ) );
+
+ const sal_uInt16* pnCurrPass = pnPassData;
+ const sal_uInt16* pnPassEnd = pnPassData + 16;
+ sal_uInt8* pnCurrKey = pnKeyData;
+ size_t nPassSize = 0;
+ for( ; (pnCurrPass < pnPassEnd) && (*pnCurrPass != 0); ++pnCurrPass, ++nPassSize )
+ {
+ *pnCurrKey++ = static_cast< sal_uInt8 >( *pnCurrPass );
+ *pnCurrKey++ = static_cast< sal_uInt8 >( *pnCurrPass >> 8 );
+ }
+ pnKeyData[ 2 * nPassSize ] = 0x80;
+ pnKeyData[ 56 ] = static_cast< sal_uInt8 >( nPassSize << 4 );
+
+ // fill raw digest of key data into key data
+ (void)rtl_digest_updateMD5( mhDigest, pnKeyData, sizeof( pnKeyData ) );
+ (void)rtl_digest_rawMD5( mhDigest, pnKeyData, RTL_DIGEST_LENGTH_MD5 );
+
+ // update digest with key data and passed unique data
+ for( size_t nIndex = 0; nIndex < 16; ++nIndex )
+ {
+ rtl_digest_updateMD5( mhDigest, pnKeyData, 5 );
+ rtl_digest_updateMD5( mhDigest, pnUnique, 16 );
+ }
+
+ // update digest with padding
+ pnKeyData[ 16 ] = 0x80;
+ (void)memset( pnKeyData + 17, 0, sizeof( pnKeyData ) - 17 );
+ pnKeyData[ 56 ] = 0x80;
+ pnKeyData[ 57 ] = 0x0A;
+ rtl_digest_updateMD5( mhDigest, pnKeyData + 16, sizeof( pnKeyData ) - 16 );
+
+ // fill raw digest of above updates into digest value
+ rtl_digest_rawMD5( mhDigest, mpnDigestValue, sizeof( mpnDigestValue ) );
+
+ // erase key data array and leave
+ (void)memset( pnKeyData, 0, sizeof( pnKeyData ) );
+}
+
+bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnSaltData[ 16 ], const sal_uInt8 pnSaltDigest[ 16 ] )
+{
+ if( !startBlock( 0 ) )
+ return false;
+
+ sal_uInt8 pnDigest[ RTL_DIGEST_LENGTH_MD5 ];
+ sal_uInt8 pnBuffer[ 64 ];
+
+ // decode salt data into buffer
+ rtl_cipher_decode( mhCipher, pnSaltData, 16, pnBuffer, sizeof( pnBuffer ) );
+
+ pnBuffer[ 16 ] = 0x80;
+ (void)memset( pnBuffer + 17, 0, sizeof( pnBuffer ) - 17 );
+ pnBuffer[ 56 ] = 0x80;
+
+ // fill raw digest of buffer into digest
+ rtl_digest_updateMD5( mhDigest, pnBuffer, sizeof( pnBuffer ) );
+ rtl_digest_rawMD5( mhDigest, pnDigest, sizeof( pnDigest ) );
+
+ // decode original salt digest into buffer
+ rtl_cipher_decode( mhCipher, pnSaltDigest, 16, pnBuffer, sizeof( pnBuffer ) );
+
+ // compare buffer with computed digest
+ bool bResult = memcmp( pnBuffer, pnDigest, sizeof( pnDigest ) ) == 0;
+
+ // erase buffer and digest arrays and leave
+ (void)memset( pnBuffer, 0, sizeof( pnBuffer ) );
+ (void)memset( pnDigest, 0, sizeof( pnDigest ) );
+ return bResult;
+}
+
+bool BinaryCodec_RCF::startBlock( sal_Int32 nCounter )
+{
+ // initialize key data array
+ sal_uInt8 pnKeyData[ 64 ];
+ (void)memset( pnKeyData, 0, sizeof( pnKeyData ) );
+
+ // fill 40 bit of digest value into [0..4]
+ (void)memcpy( pnKeyData, mpnDigestValue, 5 );
+
+ // fill little-endian counter into [5..8], static_cast masks out unneeded bits
+ pnKeyData[ 5 ] = static_cast< sal_uInt8 >( nCounter );
+ pnKeyData[ 6 ] = static_cast< sal_uInt8 >( nCounter >> 8 );
+ pnKeyData[ 7 ] = static_cast< sal_uInt8 >( nCounter >> 16 );
+ pnKeyData[ 8 ] = static_cast< sal_uInt8 >( nCounter >> 24 );
+
+ pnKeyData[ 9 ] = 0x80;
+ pnKeyData[ 56 ] = 0x48;
+
+ // fill raw digest of key data into key data
+ (void)rtl_digest_updateMD5( mhDigest, pnKeyData, sizeof( pnKeyData ) );
+ (void)rtl_digest_rawMD5( mhDigest, pnKeyData, RTL_DIGEST_LENGTH_MD5 );
+
+ // initialize cipher with key data (for decoding)
+ rtlCipherError eResult =
+ rtl_cipher_init( mhCipher, rtl_Cipher_DirectionDecode, pnKeyData, RTL_DIGEST_LENGTH_MD5, 0, 0 );
+
+ // rrase key data array and leave
+ (void)memset( pnKeyData, 0, sizeof( pnKeyData ) );
+ return eResult == rtl_Cipher_E_None;
+}
+
+bool BinaryCodec_RCF::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int32 nBytes )
+{
+ rtlCipherError eResult = rtl_cipher_decode( mhCipher,
+ pnSrcData, static_cast< sal_Size >( nBytes ),
+ pnDestData, static_cast< sal_Size >( nBytes ) );
+ return eResult == rtl_Cipher_E_None;
+}
+
+bool BinaryCodec_RCF::skip( sal_Int32 nBytes )
+{
+ // decode dummy data in memory to update internal state of RC4 cipher
+ sal_uInt8 pnDummy[ 1024 ];
+ sal_Int32 nBytesLeft = nBytes;
+ bool bResult = true;
+ while( bResult && (nBytesLeft > 0) )
+ {
+ sal_Int32 nBlockLen = ::std::min( nBytesLeft, static_cast< sal_Int32 >( sizeof( pnDummy ) ) );
+ bResult = decode( pnDummy, pnDummy, nBlockLen );
+ nBytesLeft -= nBlockLen;
+ }
+ return bResult;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/binaryfilterbase.cxx b/oox/source/core/binaryfilterbase.cxx
new file mode 100644
index 000000000000..29348c5468f6
--- /dev/null
+++ b/oox/source/core/binaryfilterbase.cxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binaryfilterbase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/binaryfilterbase.hxx"
+#include "oox/helper/olestorage.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+BinaryFilterBase::BinaryFilterBase( const Reference< XMultiServiceFactory >& rxFactory ) :
+ FilterBase( rxFactory )
+{
+}
+
+BinaryFilterBase::~BinaryFilterBase()
+{
+}
+
+StorageRef BinaryFilterBase::implCreateStorage(
+ Reference< XInputStream >& rxInStream, Reference< XOutputStream >& rxOutStream ) const
+{
+ StorageRef xStorage;
+ if( rxInStream.is() )
+ xStorage.reset( new OleStorage( getServiceFactory(), rxInStream, true ) );
+ else if( rxOutStream.is() )
+ xStorage.reset( new OleStorage( getServiceFactory(), rxOutStream, true ) );
+ return xStorage;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/facreg.cxx b/oox/source/core/facreg.cxx
new file mode 100644
index 000000000000..e8bbb147a480
--- /dev/null
+++ b/oox/source/core/facreg.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: facreg.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/dllapi.h"
+
+#include <string.h>
+
+#include <sal/config.h>
+
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+#include <cppuhelper/factory.hxx>
+#include <uno/lbnames.h>
+
+using namespace rtl;
+using namespace com::sun::star;
+
+#define SERVICE( className ) \
+extern OUString SAL_CALL className##_getImplementationName() throw(); \
+extern uno::Sequence< OUString > SAL_CALL className##_getSupportedServiceNames() throw();\
+extern uno::Reference< uno::XInterface > SAL_CALL className##_createInstance( \
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) \
+ throw( uno::Exception )
+
+namespace oox {
+ namespace core { SERVICE( FilterDetect ); }
+ namespace ppt { SERVICE( PowerPointImport ); }
+ namespace xls { SERVICE( BiffDetector ); }
+ namespace xls { SERVICE( ExcelFilter ); }
+ namespace xls { SERVICE( ExcelBiffFilter ); }
+ namespace shape { SERVICE( ShapeContextHandler ); }
+ namespace shape { SERVICE( FastTokenHandlerService ); }
+}
+
+//
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+OOX_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+void SAL_CALL writeInfo( registry::XRegistryKey * pRegistryKey, const OUString& rImplementationName, const uno::Sequence< OUString >& rServices )
+{
+ uno::Reference< registry::XRegistryKey > xNewKey(
+ pRegistryKey->createKey(
+ OUString( sal_Unicode( '/' ) ) + rImplementationName + OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) ) );
+
+ for( sal_Int32 i = 0; i < rServices.getLength(); i++ )
+ xNewKey->createKey( rServices.getConstArray()[i]);
+}
+
+#define WRITEINFO(className)\
+ writeInfo( pKey, className##_getImplementationName(), className##_getSupportedServiceNames() )
+
+OOX_DLLPUBLIC sal_Bool SAL_CALL component_writeInfo( void * , void * pRegistryKey )
+{
+ if( pRegistryKey )
+ {
+ try
+ {
+ registry::XRegistryKey *pKey = reinterpret_cast< registry::XRegistryKey * >( pRegistryKey );
+
+ WRITEINFO( ::oox::core::FilterDetect );
+ WRITEINFO( ::oox::ppt::PowerPointImport );
+ WRITEINFO( ::oox::xls::BiffDetector );
+ WRITEINFO( ::oox::xls::ExcelFilter );
+ WRITEINFO( ::oox::xls::ExcelBiffFilter );
+ WRITEINFO( ::oox::shape::ShapeContextHandler );
+ WRITEINFO( ::oox::shape::FastTokenHandlerService );
+ }
+ catch (registry::InvalidRegistryException &)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_True;
+}
+
+#define SINGLEFACTORY(classname)\
+ if( classname##_getImplementationName().equalsAsciiL( pImplName, nImplNameLen ) )\
+ {\
+ xFactory = ::cppu::createSingleFactory( xMSF,\
+ classname##_getImplementationName(),\
+ classname##_createInstance,\
+ classname##_getSupportedServiceNames() );\
+ }
+
+OOX_DLLPUBLIC void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+ if( pServiceManager )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF( reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) );
+
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ const sal_Int32 nImplNameLen = strlen( pImplName );
+
+ // impress oasis import
+ SINGLEFACTORY( ::oox::core::FilterDetect )
+ else SINGLEFACTORY( oox::ppt::PowerPointImport )
+ else SINGLEFACTORY( ::oox::xls::BiffDetector )
+ else SINGLEFACTORY( ::oox::xls::ExcelFilter )
+ else SINGLEFACTORY( ::oox::xls::ExcelBiffFilter )
+ else SINGLEFACTORY( ::oox::shape::ShapeContextHandler)
+ else SINGLEFACTORY( ::oox::shape::FastTokenHandlerService)
+
+ if( xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+ return pRet;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx
new file mode 100644
index 000000000000..fa0408203446
--- /dev/null
+++ b/oox/source/core/filterbase.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: filterbase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/filterbase.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <comphelper/mediadescriptor.hxx>
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::lang::XComponent;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::task::XStatusIndicator;
+using ::com::sun::star::task::XInteractionHandler;
+using ::comphelper::MediaDescriptor;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+struct FilterBaseImpl
+{
+ MediaDescriptor maDescriptor;
+ OUString maFileUrl;
+ StorageRef mxStorage;
+
+ Reference< XMultiServiceFactory > mxFactory;
+ Reference< XModel > mxModel;
+ Reference< XInputStream > mxInStream;
+ Reference< XOutputStream > mxOutStream;
+ Reference< XStatusIndicator > mxStatusIndicator;
+ Reference< XInteractionHandler > mxInteractionHandler;
+
+ explicit FilterBaseImpl( const Reference< XMultiServiceFactory >& rxFactory );
+ void setMediaDescriptor( const Sequence< PropertyValue >& rDescriptor );
+};
+
+// ----------------------------------------------------------------------------
+
+FilterBaseImpl::FilterBaseImpl( const Reference< XMultiServiceFactory >& rxFactory ) :
+ mxFactory( rxFactory )
+{
+}
+
+void FilterBaseImpl::setMediaDescriptor( const Sequence< PropertyValue >& rDescriptor )
+{
+ maDescriptor = rDescriptor;
+ maDescriptor.addInputStream();
+
+ maFileUrl = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), maFileUrl );
+ mxInStream = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_INPUTSTREAM(), mxInStream );
+ mxOutStream = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_OUTPUTSTREAM(), mxOutStream );
+ mxStatusIndicator = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_STATUSINDICATOR(), mxStatusIndicator );
+ mxInteractionHandler = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_INTERACTIONHANDLER(), mxInteractionHandler );
+}
+
+// ============================================================================
+
+FilterBase::FilterBase( const Reference< XMultiServiceFactory >& rxFactory ) :
+ mxImpl( new FilterBaseImpl( rxFactory ) )
+{
+}
+
+FilterBase::~FilterBase()
+{
+}
+
+bool FilterBase::isImportFilter() const
+{
+ return mxImpl->mxInStream.is();
+}
+
+bool FilterBase::isExportFilter() const
+{
+ return mxImpl->mxOutStream.is();
+}
+
+// ----------------------------------------------------------------------------
+
+const Reference< XMultiServiceFactory >& FilterBase::getServiceFactory() const
+{
+ return mxImpl->mxFactory;
+}
+
+const Reference< XModel >& FilterBase::getModel() const
+{
+ return mxImpl->mxModel;
+}
+
+const Reference< XStatusIndicator >& FilterBase::getStatusIndicator() const
+{
+ return mxImpl->mxStatusIndicator;
+}
+
+const Reference< XInteractionHandler >& FilterBase::getInteractionHandler() const
+{
+ return mxImpl->mxInteractionHandler;
+}
+
+const OUString& FilterBase::getFileUrl() const
+{
+ return mxImpl->maFileUrl;
+}
+
+OUString FilterBase::getAbsoluteUrl( const OUString& rUrl ) const
+{
+ return rUrl;
+}
+
+StorageRef FilterBase::getStorage() const
+{
+ return mxImpl->mxStorage;
+}
+
+StorageRef FilterBase::openSubStorage( const OUString& rStorageName, bool bCreate )
+{
+ return mxImpl->mxStorage->openSubStorage( rStorageName, bCreate );
+}
+
+Reference< XInputStream > FilterBase::openInputStream( const OUString& rStreamName )
+{
+ return mxImpl->mxStorage->openInputStream( rStreamName );
+}
+
+Reference< XOutputStream > FilterBase::openOutputStream( const OUString& rStreamName )
+{
+ return mxImpl->mxStorage->openOutputStream( rStreamName );
+}
+
+// com.sun.star.lang.XServiceInfo interface -----------------------------------
+
+OUString SAL_CALL FilterBase::getImplementationName() throw( RuntimeException )
+{
+ return implGetImplementationName();
+}
+
+sal_Bool SAL_CALL FilterBase::supportsService( const OUString& rServiceName ) throw( RuntimeException )
+{
+ return
+ (rServiceName == CREATE_OUSTRING( "com.sun.star.document.ImportFilter" )) ||
+ (rServiceName == CREATE_OUSTRING( "com.sun.star.document.ExportFilter" ));
+}
+
+Sequence< OUString > SAL_CALL FilterBase::getSupportedServiceNames() throw( RuntimeException )
+{
+ Sequence< OUString > aServiceNames( 2 );
+ aServiceNames[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
+ aServiceNames[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
+ return aServiceNames;
+}
+
+// com.sun.star.lang.XInitialization interface --------------------------------
+
+void SAL_CALL FilterBase::initialize( const Sequence< Any >& /*rArgs*/ ) throw( Exception, RuntimeException )
+{
+}
+
+// com.sun.star.document.XImporter interface ----------------------------------
+
+void SAL_CALL FilterBase::setTargetDocument( const Reference< XComponent >& rxDocument ) throw( IllegalArgumentException, RuntimeException )
+{
+ mxImpl->mxModel.set( rxDocument, UNO_QUERY );
+ if( !mxImpl->mxModel.is() )
+ throw IllegalArgumentException();
+}
+
+// com.sun.star.document.XExporter interface ----------------------------------
+
+void SAL_CALL FilterBase::setSourceDocument( const Reference< XComponent >& rxDocument ) throw( IllegalArgumentException, RuntimeException )
+{
+ mxImpl->mxModel.set( rxDocument, UNO_QUERY );
+ if( !mxImpl->mxModel.is() )
+ throw IllegalArgumentException();
+}
+
+// com.sun.star.document.XFilter interface ------------------------------------
+
+sal_Bool SAL_CALL FilterBase::filter( const Sequence< PropertyValue >& rDescriptor ) throw( RuntimeException )
+{
+ sal_Bool bRet = sal_False;
+ mxImpl->setMediaDescriptor( rDescriptor );
+ mxImpl->mxStorage = implCreateStorage( mxImpl->mxInStream, mxImpl->mxOutStream );
+ if( mxImpl->mxModel.is() && mxImpl->mxStorage.get() )
+ {
+ mxImpl->mxModel->lockControllers();
+ if( mxImpl->mxInStream.is() )
+ bRet = importDocument();
+ else if( mxImpl->mxOutStream.is() )
+ bRet = exportDocument();
+ mxImpl->mxModel->unlockControllers();
+ }
+ return bRet;
+}
+
+void SAL_CALL FilterBase::cancel() throw( RuntimeException )
+{
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
new file mode 100644
index 000000000000..76d82875ee23
--- /dev/null
+++ b/oox/source/core/filterdetect.cxx
@@ -0,0 +1,404 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: filterdetect.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
+
+#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/helper.hxx"
+#include "oox/core/fasttokenhandler.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+#include <vector>
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using ::comphelper::MediaDescriptor;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+/** Document handler specifically designed for detecting OOXML file formats.
+
+ It takes a reference to the filter string object via its constructor, and
+ puts the name of the detected filter to it if it successfully finds one.
+ */
+class FilterDetectDocHandler : public ::cppu::WeakImplHelper1< XFastDocumentHandler >
+{
+public:
+ explicit FilterDetectDocHandler( OUString& rFilter );
+ virtual ~FilterDetectDocHandler();
+
+ // XFastDocumentHandler
+ virtual void SAL_CALL startDocument() throw (SAXException, RuntimeException);
+ virtual void SAL_CALL endDocument() throw (SAXException, RuntimeException);
+ virtual void SAL_CALL setDocumentLocator( const Reference< XLocator >& xLocator ) throw (SAXException, RuntimeException);
+
+ // XFastContextHandler
+ virtual void SAL_CALL startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL endFastElement( sal_Int32 Element ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) throw (SAXException, RuntimeException);
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+ virtual Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL characters( const OUString& aChars ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const OUString& aWhitespaces ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL processingInstruction( const OUString& aTarget, const OUString& aData ) throw (SAXException, RuntimeException);
+
+private:
+ void parseRelationship( const AttributeList& rAttribs );
+
+ OUString getFilterNameFromContentType( const OUString& rContentType ) const;
+ void parseContentTypesDefault( const AttributeList& rAttribs );
+ void parseContentTypesOverride( const AttributeList& rAttribs );
+
+private:
+ typedef ::std::vector< sal_Int32 > ContextVector;
+
+ OUString& mrFilter;
+ ContextVector maContextStack;
+ const OUString maWordFilterName;
+ const OUString maExcelFilterName;
+ const OUString maExcelBinFilterName;
+ const OUString maPowerPointFilterName;
+ OUString maTargetPath;
+};
+
+// ============================================================================
+
+FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilter ) :
+ mrFilter( rFilter ),
+ maWordFilterName( CREATE_OUSTRING( "MS Word 2007 XML" ) ),
+ maExcelFilterName( CREATE_OUSTRING( "MS Excel 2007 XML" ) ),
+ maExcelBinFilterName( CREATE_OUSTRING( "MS Excel 2007 Binary" ) ),
+ maPowerPointFilterName( CREATE_OUSTRING( "MS PowerPoint 2007 XML" ) )
+{
+ maContextStack.reserve( 2 );
+}
+
+FilterDetectDocHandler::~FilterDetectDocHandler()
+{
+}
+
+void SAL_CALL FilterDetectDocHandler::startDocument()
+ throw (SAXException, RuntimeException)
+{
+}
+
+void SAL_CALL FilterDetectDocHandler::endDocument()
+ throw (SAXException, RuntimeException)
+{
+}
+
+void SAL_CALL FilterDetectDocHandler::setDocumentLocator( const Reference<XLocator>& /*xLocator*/ )
+ throw (SAXException, RuntimeException)
+{
+}
+
+// ===========================================================================
+
+void SAL_CALL FilterDetectDocHandler::startFastElement(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rAttribs )
+ throw (SAXException,RuntimeException)
+{
+ AttributeList aAttribs( rAttribs );
+ switch ( nElement )
+ {
+ // cases for _rels/.rels
+ case NMSP_PACKAGE_RELATIONSHIPS|XML_Relationships:
+ break;
+ case NMSP_PACKAGE_RELATIONSHIPS|XML_Relationship:
+ if( !maContextStack.empty() && (maContextStack.back() == (NMSP_PACKAGE_RELATIONSHIPS|XML_Relationships)) )
+ parseRelationship( aAttribs );
+ break;
+
+ // cases for [Content_Types].xml
+ case NMSP_CONTENT_TYPES|XML_Types:
+ break;
+ case NMSP_CONTENT_TYPES|XML_Default:
+ if( !maContextStack.empty() && (maContextStack.back() == (NMSP_CONTENT_TYPES|XML_Types)) )
+ parseContentTypesDefault( aAttribs );
+ break;
+ case NMSP_CONTENT_TYPES|XML_Override:
+ if( !maContextStack.empty() && (maContextStack.back() == (NMSP_CONTENT_TYPES|XML_Types)) )
+ parseContentTypesOverride( aAttribs );
+ break;
+ }
+ maContextStack.push_back( nElement );
+}
+
+void SAL_CALL FilterDetectDocHandler::startUnknownElement(
+ const OUString& /*Namespace*/, const OUString& /*Name*/, const Reference<XFastAttributeList>& /*Attribs*/ )
+ throw (SAXException, RuntimeException)
+{
+}
+
+void SAL_CALL FilterDetectDocHandler::endFastElement( sal_Int32 /*nElement*/ )
+ throw (SAXException, RuntimeException)
+{
+ maContextStack.pop_back();
+}
+
+void SAL_CALL FilterDetectDocHandler::endUnknownElement(
+ const OUString& /*Namespace*/, const OUString& /*Name*/ ) throw (SAXException, RuntimeException)
+{
+}
+
+Reference<XFastContextHandler> SAL_CALL FilterDetectDocHandler::createFastChildContext(
+ sal_Int32 /*Element*/, const Reference<XFastAttributeList>& /*Attribs*/ )
+ throw (SAXException, RuntimeException)
+{
+ return this;
+}
+
+Reference<XFastContextHandler> SAL_CALL FilterDetectDocHandler::createUnknownChildContext(
+ const OUString& /*Namespace*/, const OUString& /*Name*/, const Reference<XFastAttributeList>& /*Attribs*/)
+ throw (SAXException, RuntimeException)
+{
+ return this;
+}
+
+void SAL_CALL FilterDetectDocHandler::characters( const OUString& /*aChars*/ )
+ throw (SAXException, RuntimeException)
+{
+}
+
+void SAL_CALL FilterDetectDocHandler::ignorableWhitespace( const OUString& /*aWhitespaces*/ )
+ throw (SAXException, RuntimeException)
+{
+}
+
+void SAL_CALL FilterDetectDocHandler::processingInstruction(
+ const OUString& /*aTarget*/, const OUString& /*aData*/ )
+ throw (SAXException, RuntimeException)
+{
+}
+
+// ============================================================================
+
+void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs )
+{
+ OUString aType = rAttribs.getString( XML_Type );
+ if( aType.equalsAscii( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) )
+ maTargetPath = OUString( sal_Unicode( '/' ) ) + rAttribs.getString( XML_Target );
+}
+
+OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType ) const
+{
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" ) )
+ return maWordFilterName;
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" ) )
+ return maExcelFilterName;
+ if( rContentType.equalsAscii( "application/vnd.ms-excel.sheet.binary.macroEnabled.main" ) )
+ return maExcelBinFilterName;
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml" ) )
+ return maPowerPointFilterName;
+ return OUString();
+}
+
+void FilterDetectDocHandler::parseContentTypesDefault( const AttributeList& rAttribs )
+{
+ // only if no overridden part name found
+ if( mrFilter.getLength() == 0 )
+ {
+ // check if target path ends with extension
+ OUString aExtension = rAttribs.getString( XML_Extension );
+ sal_Int32 nExtPos = maTargetPath.getLength() - aExtension.getLength();
+ if( (nExtPos > 0) && (maTargetPath[ nExtPos - 1 ] == '.') && maTargetPath.match( aExtension, nExtPos ) )
+ mrFilter = getFilterNameFromContentType( rAttribs.getString( XML_ContentType ) );
+ }
+}
+
+void FilterDetectDocHandler::parseContentTypesOverride( const AttributeList& rAttribs )
+{
+ if( rAttribs.getString( XML_PartName ).equals( maTargetPath ) )
+ mrFilter = getFilterNameFromContentType( rAttribs.getString( XML_ContentType ) );
+}
+
+// ============================================================================
+
+class FilterDetect : public ::cppu::WeakImplHelper2< XExtendedFilterDetection, XServiceInfo >
+{
+public:
+ explicit FilterDetect( const Reference< XMultiServiceFactory >& xFactory );
+ virtual ~FilterDetect();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) throw( RuntimeException );
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( RuntimeException );
+
+ // XExtendedFilterDetect
+ virtual OUString SAL_CALL detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException );
+
+private:
+ Reference< XMultiServiceFactory > mxFactory;
+};
+
+// ----------------------------------------------------------------------------
+
+/* Helper for XServiceInfo */
+Sequence< OUString > FilterDetect_getSupportedServiceNames()
+{
+ Sequence< OUString > aServiceNames( 1 );
+ aServiceNames[ 0 ] = CREATE_OUSTRING( "com.sun.star.frame.ExtendedTypeDetection" );
+ return aServiceNames;
+}
+
+/* Helper for XServiceInfo */
+OUString FilterDetect_getImplementationName()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.FormatDetector" );
+}
+
+/* Helper for registry */
+Reference< XInterface > SAL_CALL FilterDetect_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( Exception )
+{
+ return Reference< XInterface >( *new FilterDetect( xServiceManager ) );
+}
+
+FilterDetect::FilterDetect( const Reference< XMultiServiceFactory >& xFactory ) :
+ mxFactory( xFactory )
+{
+}
+
+FilterDetect::~FilterDetect()
+{
+}
+
+// com.sun.star.document.XExtendedFilterDetect interface ----------------------
+
+OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException )
+{
+ OUString aFilter;
+
+ Reference< XFastDocumentHandler > xHandler( new FilterDetectDocHandler(aFilter) );
+ Reference< XFastTokenHandler > xTokenHandler( new ::oox::FastTokenHandler );
+
+ try
+ {
+ Reference< XFastParser > xParser( ::comphelper::getProcessServiceFactory()->createInstance(
+ CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW );
+
+ xParser->setFastDocumentHandler( xHandler );
+ xParser->setTokenHandler( xTokenHandler );
+
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ),
+ NMSP_PACKAGE_RELATIONSHIPS );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ),
+ NMSP_RELATIONSHIPS );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/content-types" ),
+ NMSP_CONTENT_TYPES );
+
+ MediaDescriptor aDescriptor( lDescriptor );
+ aDescriptor.addInputStream();
+ Reference< XInputStream > xInputStream(
+ aDescriptor[MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY_THROW );
+
+ Reference< XStorage > xStorage( ::comphelper::OStorageHelper::GetStorageFromInputStream( xInputStream, mxFactory ),
+ UNO_QUERY_THROW );
+
+ // Parse _rels/.rels to get the target path.
+ Reference< XStorage > xRels( xStorage->openStorageElement( CREATE_OUSTRING("_rels"), ElementModes::READ ) );
+ Reference< XInputStream > xStream( xRels->openStreamElement( CREATE_OUSTRING(".rels"), ElementModes::READ ),
+ UNO_QUERY_THROW );
+
+ InputSource aParserInput;
+ aParserInput.sSystemId = CREATE_OUSTRING("_rels/.rels");
+ aParserInput.aInputStream = xStream;
+ xParser->parseStream( aParserInput );
+
+ // Parse [Content_Types].xml to determine the content type of the part at the target path.
+ OUString aContentTypeName = CREATE_OUSTRING("[Content_Types].xml");
+ xStream.set( xStorage->openStreamElement( aContentTypeName, ElementModes::READ ), UNO_QUERY_THROW );
+
+ aParserInput.sSystemId = aContentTypeName;
+ aParserInput.aInputStream = xStream;
+ xParser->parseStream( aParserInput );
+ }
+ catch ( const Exception& )
+ {
+ }
+
+ return aFilter;
+}
+
+// com.sun.star.lang.XServiceInfo interface -----------------------------------
+
+OUString SAL_CALL FilterDetect::getImplementationName() throw( RuntimeException )
+{
+ return FilterDetect_getImplementationName();
+}
+
+sal_Bool SAL_CALL FilterDetect::supportsService( const OUString& rServiceName ) throw( RuntimeException )
+{
+ const Sequence< OUString > aServices = FilterDetect_getSupportedServiceNames();
+ const OUString* pArray = aServices.getConstArray();
+ const OUString* pArrayEnd = pArray + aServices.getLength();
+ return ::std::find( pArray, pArrayEnd, rServiceName ) != pArrayEnd;
+}
+
+Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames() throw( RuntimeException )
+{
+ return FilterDetect_getSupportedServiceNames();
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/fragmenthandler.cxx b/oox/source/core/fragmenthandler.cxx
new file mode 100644
index 000000000000..38b22186165c
--- /dev/null
+++ b/oox/source/core/fragmenthandler.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/fragmenthandler.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::io;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+FragmentHandler::FragmentHandler( const XmlFilterRef& rxFilter, const OUString& rFragmentPath ) :
+ mxFilter( rxFilter ),
+ mxRelations( rxFilter->importRelations( rFragmentPath ) ),
+ maFragmentPath( rFragmentPath ),
+ mpParser( 0 )
+{
+}
+
+FragmentHandler::FragmentHandler( const XmlFilterRef& rxFilter, const OUString& rFragmentPath, RelationsRef xRelations ) :
+ mxFilter( rxFilter ),
+ mxRelations( xRelations ),
+ maFragmentPath( rFragmentPath ),
+ mpParser( 0 )
+{
+}
+
+OUString FragmentHandler::getFragmentPathFromTarget( const OUString& rTarget ) const
+{
+ return Relations::getFragmentPathFromTarget( maFragmentPath, rTarget );
+}
+
+OUString FragmentHandler::getFragmentPathFromRelId( const OUString& rRelId ) const
+{
+ return mxRelations->getFragmentPathFromRelId( maFragmentPath, rRelId );
+}
+
+OUString FragmentHandler::getFragmentPathFromType( const OUString& rType ) const
+{
+ return mxRelations->getFragmentPathFromType( maFragmentPath, rType );
+}
+
+void FragmentHandler::setRecordParser( RecordParser& rParser )
+{
+ mpParser = &rParser;
+}
+
+RecordParser& FragmentHandler::getRecordParser()
+{
+ OSL_ENSURE( mpParser, "FragmentHandler::getRecordParser - not in binary import mode" );
+ return *mpParser;
+}
+
+// com.sun.star.xml.sax.XFastDocumentHandler interface ------------------------
+
+void FragmentHandler::startDocument( ) throw (SAXException, RuntimeException)
+{
+}
+
+void FragmentHandler::endDocument( ) throw (SAXException, RuntimeException)
+{
+}
+
+void FragmentHandler::setDocumentLocator( const Reference< XLocator >& xLocator ) throw (SAXException, RuntimeException)
+{
+ mxLocator = xLocator;
+}
+
+// com.sun.star.xml.sax.XFastContextHandler interface -------------------------
+
+void FragmentHandler::startFastElement( ::sal_Int32, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+}
+
+void FragmentHandler::startUnknownElement( const OUString&, const OUString&, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+}
+
+void FragmentHandler::endFastElement( ::sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+void FragmentHandler::endUnknownElement( const OUString&, const OUString& ) throw (SAXException, RuntimeException)
+{
+}
+
+Reference< XFastContextHandler > FragmentHandler::createFastChildContext( ::sal_Int32, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ return Reference< XFastContextHandler >();
+}
+
+Reference< XFastContextHandler > FragmentHandler::createUnknownChildContext( const OUString&, const OUString&, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ return Reference< XFastContextHandler >();
+}
+
+void FragmentHandler::characters( const OUString& ) throw (SAXException, RuntimeException)
+{
+}
+
+void FragmentHandler::ignorableWhitespace( const OUString& ) throw (SAXException, RuntimeException)
+{
+}
+
+void FragmentHandler::processingInstruction( const OUString&, const OUString& ) throw (SAXException, RuntimeException)
+{
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk
new file mode 100644
index 000000000000..6bfff2d36b8a
--- /dev/null
+++ b/oox/source/core/makefile.mk
@@ -0,0 +1,69 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=core
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/binarycodec.obj \
+ $(SLO)$/binaryfilterbase.obj \
+ $(SLO)$/context.obj \
+ $(SLO)$/facreg.obj \
+ $(SLO)$/filterbase.obj \
+ $(SLO)$/filterdetect.obj \
+ $(SLO)$/fragmenthandler.obj \
+ $(SLO)$/recordcontext.obj \
+ $(SLO)$/recordinfoprovider.obj \
+ $(SLO)$/recordparser.obj \
+ $(SLO)$/relations.obj \
+ $(SLO)$/relationshandler.obj \
+ $(SLO)$/skipcontext.obj \
+ $(SLO)$/xmlfilterbase.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/core/recordparser.cxx b/oox/source/core/recordparser.cxx
new file mode 100644
index 000000000000..185161f9eb4b
--- /dev/null
+++ b/oox/source/core/recordparser.cxx
@@ -0,0 +1,362 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: recordparser.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:50 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/recordparser.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/xml/sax/XLocator.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/core/fragmenthandler.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::lang::DisposedException;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::IOException;
+using ::com::sun::star::xml::sax::SAXException;
+using ::com::sun::star::xml::sax::XLocator;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+namespace prv {
+
+class Locator : public ::cppu::WeakImplHelper1< XLocator >
+{
+public:
+ inline explicit Locator( RecordParser* pParser ) : mpParser( pParser ) {}
+
+ void dispose();
+ void checkDispose() throw( RuntimeException );
+
+ // com.sun.star.sax.XLocator interface
+
+ virtual sal_Int32 SAL_CALL getColumnNumber() throw( RuntimeException );
+ virtual sal_Int32 SAL_CALL getLineNumber() throw( RuntimeException );
+ virtual OUString SAL_CALL getPublicId() throw( RuntimeException );
+ virtual OUString SAL_CALL getSystemId() throw( RuntimeException );
+
+private:
+ RecordParser* mpParser;
+};
+
+// ----------------------------------------------------------------------------
+
+void Locator::dispose()
+{
+ mpParser = 0;
+}
+
+void Locator::checkDispose() throw( RuntimeException )
+{
+ if( !mpParser )
+ throw DisposedException();
+}
+
+sal_Int32 SAL_CALL Locator::getColumnNumber() throw( RuntimeException )
+{
+ return -1;
+}
+
+sal_Int32 SAL_CALL Locator::getLineNumber() throw( RuntimeException )
+{
+ return -1;
+}
+
+OUString SAL_CALL Locator::getPublicId() throw( RuntimeException )
+{
+ checkDispose();
+ return mpParser->getInputSource().maPublicId;
+}
+
+OUString SAL_CALL Locator::getSystemId() throw( RuntimeException )
+{
+ checkDispose();
+ return mpParser->getInputSource().maSystemId;
+}
+
+// ============================================================================
+
+class ContextStack
+{
+public:
+ explicit ContextStack( FragmentHandlerRef xHandler );
+
+ inline bool empty() const { return maStack.empty(); }
+
+ sal_Int32 getCurrentRecId() const;
+ bool hasCurrentEndRecId() const;
+ RecordContextRef getCurrentContext() const;
+
+ void pushContext( const RecordInfo& rRec, const RecordContextRef& rxContext );
+ void popContext();
+
+private:
+ typedef ::std::pair< RecordInfo, RecordContextRef > ContextInfo;
+ typedef ::std::vector< ContextInfo > ContextInfoVec;
+
+ FragmentHandlerRef mxHandler;
+ ContextInfoVec maStack;
+};
+
+// ----------------------------------------------------------------------------
+
+ContextStack::ContextStack( FragmentHandlerRef xHandler ) :
+ mxHandler( xHandler )
+{
+}
+
+sal_Int32 ContextStack::getCurrentRecId() const
+{
+ return maStack.empty() ? -1 : maStack.back().first.mnStartRecId;
+}
+
+bool ContextStack::hasCurrentEndRecId() const
+{
+ return !maStack.empty() && (maStack.back().first.mnEndRecId >= 0);
+}
+
+RecordContextRef ContextStack::getCurrentContext() const
+{
+ if( !maStack.empty() )
+ return maStack.back().second;
+ return mxHandler.get();
+}
+
+void ContextStack::pushContext( const RecordInfo& rRecInfo, const RecordContextRef& rxContext )
+{
+ OSL_ENSURE( (rRecInfo.mnEndRecId >= 0) || maStack.empty() || hasCurrentEndRecId(),
+ "ContextStack::pushContext - nested incomplete context record identifiers" );
+ maStack.push_back( ContextInfo( rRecInfo, rxContext ) );
+}
+
+void ContextStack::popContext()
+{
+ OSL_ENSURE( !maStack.empty(), "ContextStack::popContext - no context on stack" );
+ if( !maStack.empty() )
+ {
+ ContextInfo& rContextInfo = maStack.back();
+ if( rContextInfo.second.is() )
+ rContextInfo.second->endRecord( rContextInfo.first.mnStartRecId );
+ maStack.pop_back();
+ }
+}
+
+} // namespace prv
+
+// ============================================================================
+
+namespace {
+
+/** Reads a byte from the passed stream, returns true on success. */
+inline bool lclReadByte( sal_uInt8& ornByte, BinaryInputStream& rStrm )
+{
+ return rStrm.read( &ornByte, 1 ) == 1;
+}
+
+/** Reads a compressed signed 32-bit integer from the passed stream. */
+bool lclReadCompressedInt( sal_Int32& ornValue, BinaryInputStream& rStrm )
+{
+ ornValue = 0;
+ sal_uInt8 nByte;
+ if( !lclReadByte( nByte, rStrm ) ) return false;
+ ornValue = nByte & 0x7F;
+ if( (nByte & 0x80) == 0 ) return true;
+ if( !lclReadByte( nByte, rStrm ) ) return false;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 7;
+ if( (nByte & 0x80) == 0 ) return true;
+ if( !lclReadByte( nByte, rStrm ) ) return false;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 14;
+ if( (nByte & 0x80) == 0 ) return true;
+ if( !lclReadByte( nByte, rStrm ) ) return false;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 21;
+ return true;
+}
+
+bool lclReadRecordHeader( sal_Int32& ornRecId, sal_Int32& ornRecSize, BinaryInputStream& rStrm )
+{
+ return
+ lclReadCompressedInt( ornRecId, rStrm ) && (ornRecId >= 0) &&
+ lclReadCompressedInt( ornRecSize, rStrm ) && (ornRecSize >= 0);
+}
+
+bool lclReadNextRecord( sal_Int32& ornRecId, RecordDataSequence& orData, BinaryInputStream& rStrm )
+{
+ sal_Int32 nRecSize = 0;
+ bool bValid = lclReadRecordHeader( ornRecId, nRecSize, rStrm );
+ if( bValid )
+ {
+ orData.realloc( nRecSize );
+ bValid = (nRecSize == 0) || (rStrm.read( orData, nRecSize ) == nRecSize);
+ }
+ return bValid;
+}
+
+} // namespace
+
+// ============================================================================
+
+RecordParser::RecordParser()
+{
+ mxLocator.set( new prv::Locator( this ) );
+}
+
+RecordParser::~RecordParser()
+{
+ if( mxLocator.is() )
+ mxLocator->dispose();
+}
+
+void RecordParser::setFragmentHandler( const ::rtl::Reference< FragmentHandler >& rxHandler )
+{
+ mxHandler = rxHandler;
+}
+
+void RecordParser::setRecordInfoProvider( const RecordInfoProviderRef& rxProvider )
+{
+ mxRecInfoProvider = rxProvider;
+}
+
+void RecordParser::parseStream( const RecordInputSource& rInputSource ) throw( SAXException, IOException, RuntimeException )
+{
+ maSource = rInputSource;
+
+ if( !maSource.mxInStream || !maSource.mxInStream->is() )
+ throw IOException();
+ if( !mxHandler.is() )
+ throw SAXException();
+ if( !mxRecInfoProvider )
+ throw RuntimeException();
+
+ // start the document
+ Reference< XLocator > xLocator( mxLocator.get() );
+ mxHandler->setDocumentLocator( xLocator );
+ mxHandler->startDocument();
+
+ // parse the stream
+ mxStack.reset( new prv::ContextStack( mxHandler ) );
+ sal_Int32 nRecId = 0;
+ RecordDataSequence aRecData;
+ while( lclReadNextRecord( nRecId, aRecData, *maSource.mxInStream ) )
+ {
+ // create record stream object from imported record data
+ RecordInputStream aRecStrm( aRecData );
+ // try to leave a context, there may be other incomplete contexts on the stack
+ if( const RecordInfo* pEndRecInfo = mxRecInfoProvider->getEndRecordInfo( nRecId ) )
+ {
+ (void)pEndRecInfo; // shut warning up in non-debug
+ // finalize contexts without record identifier for context end
+ while( !mxStack->empty() && !mxStack->hasCurrentEndRecId() )
+ mxStack->popContext();
+ // finalize the current context and pop context info from stack
+ OSL_ENSURE( mxStack->getCurrentRecId() == pEndRecInfo->mnStartRecId, "RecordParser::parseStream - context records mismatch" );
+ (void)pEndRecInfo; // suppress compiler warning for unused variable
+ RecordContextRef xCurrContext = mxStack->getCurrentContext();
+ if( xCurrContext.is() )
+ {
+ // context end record may contain some data, handle it as simple record
+ aRecStrm.seek( 0 );
+ xCurrContext->startRecord( nRecId, aRecStrm );
+ xCurrContext->endRecord( nRecId );
+ }
+ mxStack->popContext();
+ }
+ else
+ {
+ // end context with incomplete record id, if the same id comes again
+ if( (mxStack->getCurrentRecId() == nRecId) && !mxStack->hasCurrentEndRecId() )
+ mxStack->popContext();
+ // try to start a new context
+ RecordContextRef xCurrContext = mxStack->getCurrentContext();
+ if( xCurrContext.is() )
+ {
+ aRecStrm.seek( 0 );
+ xCurrContext = xCurrContext->createRecordContext( nRecId, aRecStrm );
+ }
+ // track all context identifiers on the stack (do not push simple records)
+ const RecordInfo* pStartRecInfo = mxRecInfoProvider->getStartRecordInfo( nRecId );
+ if( pStartRecInfo )
+ mxStack->pushContext( *pStartRecInfo, xCurrContext );
+ // import the record
+ if( xCurrContext.is() )
+ {
+ // import the record
+ aRecStrm.seek( 0 );
+ xCurrContext->startRecord( nRecId, aRecStrm );
+ // end simple records (context records are finished in ContextStack::popContext)
+ if( !pStartRecInfo )
+ xCurrContext->endRecord( nRecId );
+ }
+ }
+ }
+ // close remaining contexts (missing context end records or stream error)
+ while( !mxStack->empty() )
+ mxStack->popContext();
+ mxStack.reset();
+
+ // finish document
+ mxHandler->endDocument();
+
+ maSource = RecordInputSource();
+}
+
+void RecordParser::pushContext( sal_Int32 nRecId, const RecordContextRef& rxContext )
+{
+ const RecordInfo* pRecInfo = mxRecInfoProvider->getStartRecordInfo( nRecId );
+ OSL_ENSURE( pRecInfo, "RecordParser::pushContext - invalid record identifier" );
+ OSL_ENSURE( (pRecInfo->mnEndRecId >= 0) || mxStack->empty() || mxStack->hasCurrentEndRecId(),
+ "RecordParser::pushContext - nested incomplete context record identifiers" );
+ mxStack->pushContext( *pRecInfo, rxContext );
+ if( rxContext.is() )
+ {
+ RecordDataSequence aEmptyData;
+ RecordInputStream aRecStrm( aEmptyData );
+ rxContext->startRecord( nRecId, aRecStrm );
+ }
+}
+
+void RecordParser::popContext()
+{
+ mxStack->popContext();
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/relations.cxx b/oox/source/core/relations.cxx
new file mode 100644
index 000000000000..6e3aa9cf67bc
--- /dev/null
+++ b/oox/source/core/relations.cxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: relations.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/relations.hxx"
+#include "oox/helper/helper.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+const Relation* Relations::getRelationFromRelId( const OUString& rId ) const
+{
+ const_iterator aIt = find( rId );
+ return (aIt == end()) ? 0 : &aIt->second;
+}
+
+const Relation* Relations::getRelationFromType( const OUString& rType ) const
+{
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ if( aIt->second.maType == rType )
+ return &aIt->second;
+ return 0;
+}
+
+RelationsRef Relations::getRelationsFromType( const OUString& rType ) const
+{
+ RelationsRef xRelations( new Relations );
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ if( aIt->second.maType == rType )
+ (*xRelations)[ aIt->first ] = aIt->second;
+ return xRelations;
+}
+
+OUString Relations::getTargetFromRelId( const OUString& rRelId ) const
+{
+ if( const Relation* pRelation = getRelationFromRelId( rRelId ) )
+ return pRelation->maTarget;
+ return OUString();
+}
+
+OUString Relations::getTargetFromType( const OUString& rType ) const
+{
+ if( const Relation* pRelation = getRelationFromType( rType ) )
+ return pRelation->maTarget;
+ return OUString();
+}
+
+OUString Relations::getFragmentPathFromTarget( const OUString& rParentFragment, const OUString& rTarget )
+{
+ const sal_Unicode cDirSep = '/';
+
+ // no target, no fragment path
+ if( rTarget.getLength() == 0 )
+ return OUString();
+
+ // absolute target, or empty fragment path -> return target
+ if( (rTarget[ 0 ] == cDirSep) || (rParentFragment.getLength() == 0) )
+ return rTarget;
+
+ sal_Int32 nLastSepPos = rParentFragment.lastIndexOf( cDirSep );
+ OUString aPath = (nLastSepPos < 0) ? rParentFragment : rParentFragment.copy( 0, nLastSepPos );
+
+ const OUString sBack = CREATE_OUSTRING( "../" );
+
+ // First, count the number of "../"'s found in relative path string.
+ sal_Int32 nCount = 0, nPos = 0;
+ while ( true )
+ {
+ nPos = rTarget.indexOf(sBack, nCount*3);
+ if ( nPos != nCount*3 )
+ break;
+ ++nCount;
+ }
+
+ // Now, reduce the base path's directory level by the count.
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ sal_Int32 pos = aPath.lastIndexOf(cDirSep);
+ if ( pos < 0 )
+ // This is unexpected. Bail out.
+ return rTarget;
+ aPath = aPath.copy( 0, pos );
+ }
+
+ aPath += OUString( cDirSep );
+ aPath += rTarget.copy( nCount*3 );
+ return aPath;
+}
+
+OUString Relations::getFragmentPathFromRelId( const OUString& rParentFragment, const OUString& rRelId ) const
+{
+ return getFragmentPathFromTarget( rParentFragment, getTargetFromRelId( rRelId ) );
+}
+
+OUString Relations::getFragmentPathFromType( const OUString& rParentFragment, const OUString& rType ) const
+{
+ return getFragmentPathFromTarget( rParentFragment, getTargetFromType( rType ) );
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/relationshandler.cxx b/oox/source/core/relationshandler.cxx
new file mode 100644
index 000000000000..3924605a0dc9
--- /dev/null
+++ b/oox/source/core/relationshandler.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: relationshandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/relationshandler.hxx"
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+namespace {
+
+/* Build path to relations file from passed path, e.g.:
+ 'path/path/file.xml' -> 'path/path/_rels/file.xml.rels'
+ 'file.xml' -> '_rels/file.xml.rels'
+ '' -> '_rels/.rels'
+ */
+OUString lclGetRelationsPath( const OUString& rFragmentPath )
+{
+ sal_Int32 nPathLen = ::std::max< sal_Int32 >( rFragmentPath.lastIndexOf( '/' ) + 1, 0 );
+ return
+ OUStringBuffer( rFragmentPath.copy( 0, nPathLen ) ). // file path including slash
+ appendAscii( "_rels/" ). // additional '_rels/' path
+ append( rFragmentPath.copy( nPathLen ) ). // file name after path
+ appendAscii( ".rels" ). // '.rels' suffix
+ makeStringAndClear();
+}
+
+} // namespace
+
+// ============================================================================
+
+RelationsFragmentHandler::RelationsFragmentHandler( const XmlFilterRef& rxFilter, const OUString& rFragmentPath, RelationsRef xRelations ) :
+ FragmentHandler( rxFilter, lclGetRelationsPath( rFragmentPath ), xRelations ),
+ mrRelations( *xRelations )
+{
+}
+
+Reference< XFastContextHandler > RelationsFragmentHandler::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( nElement )
+ {
+ case NMSP_PACKAGE_RELATIONSHIPS|XML_Relationship:
+ {
+ Relation aRelation;
+ aRelation.maId = rxAttribs->getOptionalValue( XML_Id );
+ aRelation.maType = rxAttribs->getOptionalValue( XML_Type );
+ aRelation.maTarget = rxAttribs->getOptionalValue( XML_Target );
+ if( (aRelation.maId.getLength() > 0) && (aRelation.maType.getLength() > 0) && (aRelation.maTarget.getLength() > 0) )
+ mrRelations[ aRelation.maId ] = aRelation;
+ }
+ break;
+ case NMSP_PACKAGE_RELATIONSHIPS|XML_Relationships:
+ xRet.set( this );
+ break;
+ }
+ return xRet;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/core/skipcontext.cxx b/oox/source/core/skipcontext.cxx
new file mode 100644
index 000000000000..d79186cf6fcf
--- /dev/null
+++ b/oox/source/core/skipcontext.cxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: skipcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/context.hxx"
+#include "oox/core/skipcontext.hxx"
+
+
+
+namespace oox { namespace core {
+
+ SkipContext::SkipContext( const FragmentHandlerRef& xHandler )
+ : Context( xHandler )
+ {
+ OSL_TRACE( "OOX: Skipping Context" );
+ }
+
+
+} }
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
new file mode 100644
index 000000000000..48f93cddec67
--- /dev/null
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -0,0 +1,300 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmlfilterbase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/xmlfilterbase.hxx"
+#include <set>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/zipstorage.hxx"
+#include "oox/core/fasttokenhandler.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/recordparser.hxx"
+#include "oox/core/relationshandler.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::embed::XStorage;
+using ::com::sun::star::embed::XTransactedObject;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::container::XNameContainer;
+using ::com::sun::star::document::XDocumentSubStorageSupplier;
+using ::com::sun::star::xml::sax::XFastParser;
+using ::com::sun::star::xml::sax::XFastTokenHandler;
+using ::com::sun::star::xml::sax::XFastDocumentHandler;
+using ::com::sun::star::xml::sax::InputSource;
+using ::com::sun::star::xml::sax::SAXException;
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+struct XmlFilterBaseImpl
+{
+ typedef RefMap< OUString, Relations > RelationsMap;
+
+ OUString maBinSuffix;
+ Reference< XFastTokenHandler >
+ mxTokenHandler;
+ RelationsMap maRelationsMap;
+ ::std::set< OUString > maPictureSet; /// Already copied picture stream names.
+ Reference< XStorage > mxPictureStorage; /// Target model picture storage.
+ Reference< XNameContainer > mxMarkerTable; /// Table to create new arrow names.
+
+ explicit XmlFilterBaseImpl();
+};
+
+// ----------------------------------------------------------------------------
+
+XmlFilterBaseImpl::XmlFilterBaseImpl() :
+ maBinSuffix( CREATE_OUSTRING( ".bin" ) ),
+ mxTokenHandler( new FastTokenHandler )
+{
+}
+
+// ============================================================================
+
+XmlFilterBase::XmlFilterBase( const Reference< XMultiServiceFactory >& rxFactory ) :
+ FilterBase( rxFactory ),
+ mxImpl( new XmlFilterBaseImpl )
+{
+}
+
+XmlFilterBase::~XmlFilterBase()
+{
+}
+
+RecordInfoProviderRef XmlFilterBase::getRecordInfoProvider()
+{
+ // default: no support for binary streams
+ return RecordInfoProviderRef();
+}
+
+// ----------------------------------------------------------------------------
+
+OUString XmlFilterBase::getFragmentPathFromType( const OUString& rType )
+{
+ return importRelations( OUString() )->getTargetFromType( rType );
+}
+
+bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
+{
+ OSL_ENSURE( rxHandler.is(), "XmlFilterBase::importFragment - missing fragment handler" );
+ if( !rxHandler.is() )
+ return false;
+
+ // fragment handler must contain path to fragment stream
+ OUString aFragmentPath = rxHandler->getFragmentPath();
+ OSL_ENSURE( aFragmentPath.getLength() > 0, "XmlFilterBase::importFragment - missing fragment path" );
+ if( aFragmentPath.getLength() == 0 )
+ return false;
+
+ // try to open the fragment stream (this may fail - do not assert)
+ Reference< XInputStream > xInStrm = openInputStream( aFragmentPath );
+ if( !xInStrm.is() )
+ return false;
+
+ // try to import binary streams (fragment extension must be '.bin')
+ sal_Int32 nBinSuffixPos = aFragmentPath.getLength() - mxImpl->maBinSuffix.getLength();
+ if( (nBinSuffixPos >= 0) && aFragmentPath.match( mxImpl->maBinSuffix, nBinSuffixPos ) )
+ {
+ try
+ {
+ // create the record parser
+ RecordParser aParser;
+ aParser.setFragmentHandler( rxHandler );
+ aParser.setRecordInfoProvider( getRecordInfoProvider() );
+ rxHandler->setRecordParser( aParser );
+
+ // create the input source and parse the stream
+ RecordInputSource aSource;
+ aSource.mxInStream.reset( new BinaryInputStream( xInStrm, true ) );
+ aSource.maSystemId = aFragmentPath;
+ aParser.parseStream( aSource );
+ return true;
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+ }
+
+ // get the XFastDocumentHandler interface from the fragment handler
+ Reference< XFastDocumentHandler > xDocHandler( rxHandler.get() );
+ if( !xDocHandler.is() )
+ return false;
+
+ // try to import XML stream
+ try
+ {
+ // create the fast parser
+ Reference< XFastParser > xParser( getServiceFactory()->createInstance(
+ CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW );
+ xParser->setFastDocumentHandler( xDocHandler );
+ xParser->setTokenHandler( mxImpl->mxTokenHandler );
+
+ // register XML namespaces
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/spreadsheetml/2006/main"), NMSP_EXCEL );
+ xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:office" ), NMSP_OFFICE );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/presentationml/2006/main"), NMSP_PPT );
+ xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:word" ), NMSP_WORD );
+ xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:vml" ), NMSP_VML );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/main" ), NMSP_DRAWINGML );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ), NMSP_PACKAGE_RELATIONSHIPS );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ), NMSP_RELATIONSHIPS );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://www.w3.org/XML/1998/namespace" ), NMSP_XML );
+ xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:powerpoint" ), NMSP_POWERPOINT );
+ xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:activation" ), NMSP_ACTIVATION );
+ xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ), NMSP_DIAGRAM );
+
+ // create the input source and parse the stream
+ InputSource aSource;
+ aSource.aInputStream = xInStrm;
+ aSource.sSystemId = aFragmentPath;
+ xParser->parseStream( aSource );
+ return true;
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+RelationsRef XmlFilterBase::importRelations( const OUString& rFragmentPath )
+{
+ // try to find cached relations
+ RelationsRef& rxRelations = mxImpl->maRelationsMap[ rFragmentPath ];
+ if( !rxRelations )
+ {
+ // import and cache relations
+ rxRelations.reset( new Relations );
+ importFragment( new RelationsFragmentHandler( this, rFragmentPath, rxRelations ) );
+ }
+ return rxRelations;
+}
+
+OUString XmlFilterBase::copyPictureStream( const OUString& rPicturePath )
+{
+ // split source path into source storage path and stream name
+ sal_Int32 nIndex = rPicturePath.lastIndexOf( sal_Unicode( '/' ) );
+ OUString sPictureName;
+ OUString sSourceStorageName;
+ if( nIndex < 0 )
+ {
+ // root stream
+ sPictureName = rPicturePath;
+ }
+ else
+ {
+ // sub stream
+ sPictureName = rPicturePath.copy( nIndex + 1 );
+ sSourceStorageName = rPicturePath.copy( 0, nIndex );
+ }
+
+ // check if we already copied this one!
+ if( mxImpl->maPictureSet.find( rPicturePath ) == mxImpl->maPictureSet.end() ) try
+ {
+ // ok, not yet, copy stream to documents picture storage
+
+ // first get the picture storage from our target model
+ if( !mxImpl->mxPictureStorage.is() )
+ {
+ static const OUString sPictures = CREATE_OUSTRING( "Pictures" );
+ Reference< XDocumentSubStorageSupplier > xDSSS( getModel(), UNO_QUERY_THROW );
+ mxImpl->mxPictureStorage.set( xDSSS->getDocumentSubStorage(
+ sPictures, ::com::sun::star::embed::ElementModes::WRITE ), UNO_QUERY_THROW );
+ }
+
+ StorageRef xSourceStorage = openSubStorage( sSourceStorageName, false );
+ if( xSourceStorage.get() )
+ {
+ Reference< XStorage > xSourceXStorage = xSourceStorage->getXStorage();
+ if( xSourceXStorage.is() )
+ {
+ xSourceXStorage->copyElementTo( sPictureName, mxImpl->mxPictureStorage, sPictureName );
+ Reference< XTransactedObject > xTO( mxImpl->mxPictureStorage, UNO_QUERY_THROW );
+ xTO->commit();
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ static const OUString sUrlPrefix = CREATE_OUSTRING( "vnd.sun.star.Package:Pictures/" );
+ return sUrlPrefix + sPictureName;
+}
+
+Reference< XNameContainer >& XmlFilterBase::getMarkerTable() const
+{
+ if( !mxImpl->mxMarkerTable.is() ) try
+ {
+ mxImpl->mxMarkerTable.set( getServiceFactory()->createInstance(
+ CREATE_OUSTRING( "com.sun.star.drawing.MarkerTable" ) ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ return mxImpl->mxMarkerTable;
+}
+
+StorageRef XmlFilterBase::implCreateStorage(
+ Reference< XInputStream >& rxInStream, Reference< XOutputStream >& rxOutStream ) const
+{
+ StorageRef xStorage;
+ if( rxInStream.is() )
+ xStorage.reset( new ZipStorage( getServiceFactory(), rxInStream ) );
+ else if( rxOutStream.is() )
+ xStorage.reset( new ZipStorage( getServiceFactory(), rxOutStream ) );
+ return xStorage;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
diff --git a/oox/source/drawingml/clrscheme.cxx b/oox/source/drawingml/clrscheme.cxx
new file mode 100644
index 000000000000..50c0ea07d417
--- /dev/null
+++ b/oox/source/drawingml/clrscheme.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: clrscheme.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/clrscheme.hxx"
+#include "tokens.hxx"
+
+namespace oox { namespace drawingml {
+
+sal_Bool ClrMap::getColorMap( sal_Int32& nClrToken )
+{
+ sal_Int32 nMapped = 0;
+ std::map < sal_Int32, sal_Int32 >::const_iterator aIter( maClrMap.find( nClrToken ) );
+ if ( aIter != maClrMap.end() )
+ nMapped = (*aIter).second;
+ if ( nMapped )
+ {
+ nClrToken = nMapped;
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+void ClrMap::setColorMap( sal_Int32 nClrToken, sal_Int32 nMappedClrToken )
+{
+ maClrMap[ nClrToken ] = nMappedClrToken;
+}
+
+//-----------------------------------------------------------------------------------------
+
+ClrScheme::ClrScheme()
+{
+}
+ClrScheme::~ClrScheme()
+{
+}
+
+sal_Bool ClrScheme::getColor( sal_Int32 nSchemeClrToken, sal_Int32& rColor ) const
+{
+ switch( nSchemeClrToken )
+ {
+ case XML_bg1 : nSchemeClrToken = XML_dk1; break;
+ case XML_bg2 : nSchemeClrToken = XML_dk2; break;
+ case XML_tx1 : nSchemeClrToken = XML_lt1; break;
+ case XML_tx2 : nSchemeClrToken = XML_lt2; break;
+ }
+ std::map < sal_Int32, sal_Int32 >::const_iterator aIter( maClrScheme.find( nSchemeClrToken ) );
+ if ( aIter != maClrScheme.end() )
+ rColor = (*aIter).second;
+ return aIter != maClrScheme.end();
+}
+
+void ClrScheme::setColor( sal_Int32 nSchemeClrToken, sal_Int32 nColor )
+{
+ maClrScheme[ nSchemeClrToken ] = nColor;
+}
+
+// static
+bool ClrScheme::getSystemColor( const sal_Int32 nSysClrToken, sal_Int32& rColor )
+{
+ //! TODO: get colors from system
+ switch( nSysClrToken )
+ {
+ case XML_window: rColor = 0xFFFFFF; break;
+ case XML_windowText: rColor = 0x000000; break;
+ //! TODO: more colors to follow... (chapter 5.1.12.58)
+ default: return false;
+ }
+ return true;
+}
+
+} }
diff --git a/oox/source/drawingml/clrschemecontext.cxx b/oox/source/drawingml/clrschemecontext.cxx
new file mode 100644
index 000000000000..a6a5373d772a
--- /dev/null
+++ b/oox/source/drawingml/clrschemecontext.cxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: clrschemecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/clrschemecontext.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+static void setClrMap( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes,
+ oox::drawingml::ClrMap& rClrMap, sal_Int32 nToken )
+{
+ if ( xAttributes->hasAttribute( nToken ) )
+ {
+ sal_Int32 nMappedToken = xAttributes->getOptionalValueToken( nToken, 0 );
+ rClrMap.setColorMap( nToken, nMappedToken );
+ }
+}
+
+clrMapContext::clrMapContext( const FragmentHandlerRef& xHandler,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, oox::drawingml::ClrMap& rClrMap )
+: Context( xHandler )
+{
+ setClrMap( xAttributes, rClrMap, XML_bg1 );
+ setClrMap( xAttributes, rClrMap, XML_tx1 );
+ setClrMap( xAttributes, rClrMap, XML_bg2 );
+ setClrMap( xAttributes, rClrMap, XML_tx2 );
+ setClrMap( xAttributes, rClrMap, XML_accent1 );
+ setClrMap( xAttributes, rClrMap, XML_accent2 );
+ setClrMap( xAttributes, rClrMap, XML_accent3 );
+ setClrMap( xAttributes, rClrMap, XML_accent4 );
+ setClrMap( xAttributes, rClrMap, XML_accent5 );
+ setClrMap( xAttributes, rClrMap, XML_accent6 );
+ setClrMap( xAttributes, rClrMap, XML_hlink );
+ setClrMap( xAttributes, rClrMap, XML_folHlink );
+}
+
+Reference< XFastContextHandler > clrMapContext::createFastChildContext( sal_Int32 /* aElementToken */, const Reference< XFastAttributeList >& /* xAttribs */ )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ return xRet;
+}
+
+clrSchemeContext::clrSchemeContext( const ::oox::core::FragmentHandlerRef& xHandler, const oox::drawingml::ClrSchemePtr pClrSchemePtr )
+: Context( xHandler )
+, mpClrSchemePtr( pClrSchemePtr )
+{
+}
+
+void clrSchemeContext::startFastElement( sal_Int32 /* aElementToken */, const Reference< XFastAttributeList >& /* xAttribs */ ) throw (SAXException, RuntimeException)
+{
+}
+
+void clrSchemeContext::endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_dk1:
+ case NMSP_DRAWINGML|XML_lt1:
+ case NMSP_DRAWINGML|XML_dk2:
+ case NMSP_DRAWINGML|XML_lt2:
+ case NMSP_DRAWINGML|XML_accent1:
+ case NMSP_DRAWINGML|XML_accent2:
+ case NMSP_DRAWINGML|XML_accent3:
+ case NMSP_DRAWINGML|XML_accent4:
+ case NMSP_DRAWINGML|XML_accent5:
+ case NMSP_DRAWINGML|XML_accent6:
+ case NMSP_DRAWINGML|XML_hlink:
+ case NMSP_DRAWINGML|XML_folHlink:
+ {
+ mpClrSchemePtr->setColor( aElementToken & 0xffff, maColor.getColor( *getHandler()->getFilter().get() ) );
+ break;
+ }
+ }
+}
+
+Reference< XFastContextHandler > clrSchemeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& /* xAttribs */ ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_scrgbClr: // CT_ScRgbColor
+ case NMSP_DRAWINGML|XML_srgbClr: // CT_SRgbColor
+ case NMSP_DRAWINGML|XML_hslClr: // CT_HslColor
+ case NMSP_DRAWINGML|XML_sysClr: // CT_SystemColor
+// case NMSP_DRAWINGML|XML_schemeClr: // CT_SchemeColor
+ case NMSP_DRAWINGML|XML_prstClr: // CT_PresetColor
+ {
+ xRet.set( new colorChoiceContext( getHandler(), maColor ) );
+ break;
+ }
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/color.cxx b/oox/source/drawingml/color.cxx
new file mode 100644
index 000000000000..9b27916d83ca
--- /dev/null
+++ b/oox/source/drawingml/color.cxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: color.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/color.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using namespace ::oox::core;
+
+namespace oox { namespace drawingml {
+
+Color::Color()
+: mnColor( 0 )
+, mnAlpha( 0 )
+, mbUsed( sal_False )
+, mbSchemeColor( sal_False )
+, mbAlphaColor( sal_False )
+{
+}
+Color::~Color()
+{
+}
+sal_Int32 Color::getColor( const oox::core::XmlFilterBase& rFilterBase ) const
+{
+ return mbSchemeColor ? rFilterBase.getSchemeClr( mnColor ) : mnColor;
+}
+sal_Int32 Color::getAlpha() const
+{
+ return mnAlpha;
+}
+
+} }
diff --git a/oox/source/drawingml/colorchoicecontext.cxx b/oox/source/drawingml/colorchoicecontext.cxx
new file mode 100644
index 000000000000..6f5572fcaefa
--- /dev/null
+++ b/oox/source/drawingml/colorchoicecontext.cxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: colorchoicecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/drawingml/clrscheme.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+colorChoiceContext::colorChoiceContext( const ::oox::core::FragmentHandlerRef& xHandler, ::oox::drawingml::Color& rColor )
+: Context( xHandler )
+, mrColor( rColor )
+{
+}
+
+void colorChoiceContext::startFastElement( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_scrgbClr: // CT_ScRgbColor
+ {
+ sal_Int32 r = ((xAttribs->getOptionalValue( XML_r ).toInt32() * 256) / 1000) & 0xff;
+ sal_Int32 g = ((xAttribs->getOptionalValue( XML_g ).toInt32() * 256) / 1000) & 0xff;
+ sal_Int32 b = ((xAttribs->getOptionalValue( XML_b ).toInt32() * 256) / 1000) & 0xff;
+ mrColor.mnColor = (r << 16) | (g << 8) | b;
+ mrColor.mbUsed = sal_True;
+ break;
+ }
+ case NMSP_DRAWINGML|XML_srgbClr: // CT_SRgbColor
+ {
+ mrColor.mnColor = xAttribs->getOptionalValue( XML_val ).toInt32( 16 );
+ mrColor.mbUsed = sal_True;
+ break;
+ }
+ case NMSP_DRAWINGML|XML_hslClr: // CT_HslColor
+ // todo
+ break;
+ case NMSP_DRAWINGML|XML_sysClr: // CT_SystemColor
+ sal_Int32 nColor;
+ if( !ClrScheme::getSystemColor( xAttribs->getOptionalValueToken( XML_val, XML_TOKEN_INVALID ), nColor ) )
+ nColor = xAttribs->getOptionalValue( XML_lastClr ).toInt32( 16 );
+ mrColor.mnColor = nColor;
+ mrColor.mbUsed = sal_True;
+ break;
+ case NMSP_DRAWINGML|XML_schemeClr: // CT_SchemeColor
+ {
+ mrColor.mnColor = xAttribs->getOptionalValueToken( XML_val, XML_nothing );
+ mrColor.mbUsed = sal_True;
+ mrColor.mbSchemeColor = sal_True;
+ break;
+ }
+ case NMSP_DRAWINGML|XML_prstClr: // CT_PresetColor
+ // todo
+ break;
+
+ }
+}
+
+Reference< XFastContextHandler > colorChoiceContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ // colorTransformGroup
+
+ // color should be available as rgb in member mnColor already, now modify it depending on
+ // the transformation elements
+
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_tint: // CT_PositiveFixedPercentage
+ case NMSP_DRAWINGML|XML_shade: // CT_PositiveFixedPercentage
+ case NMSP_DRAWINGML|XML_comp: // CT_ComplementTransform
+ case NMSP_DRAWINGML|XML_inv: // CT_InverseTransform
+ case NMSP_DRAWINGML|XML_gray: // CT_GrayscaleTransform
+ break;
+ case NMSP_DRAWINGML|XML_alpha: // CT_PositiveFixedPercentage
+ {
+ mrColor.mbUsed = sal_True;
+ mrColor.mbAlphaColor = sal_True;
+ mrColor.mnAlpha = GetPercent( rxAttribs->getOptionalValue( XML_val ) );
+ }
+ break;
+ case NMSP_DRAWINGML|XML_alphaOff: // CT_FixedPercentage
+ case NMSP_DRAWINGML|XML_alphaMod: // CT_PositivePercentage
+ case NMSP_DRAWINGML|XML_hue: // CT_PositiveFixedAngle
+ case NMSP_DRAWINGML|XML_hueOff: // CT_Angle
+ case NMSP_DRAWINGML|XML_hueMod: // CT_PositivePercentage
+ case NMSP_DRAWINGML|XML_sat: // CT_Percentage
+ case NMSP_DRAWINGML|XML_satOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_satMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_lum: // CT_Percentage
+ case NMSP_DRAWINGML|XML_lumOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_lumMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_red: // CT_Percentage
+ case NMSP_DRAWINGML|XML_redOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_redMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_green: // CT_Percentage
+ case NMSP_DRAWINGML|XML_greenOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_greenMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_blue: // CT_Percentage
+ case NMSP_DRAWINGML|XML_blueOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_blueMod: // CT_Percentage
+ break;
+ }
+ return this;
+}
+
+
+} }
diff --git a/oox/source/drawingml/connectorshapecontext.cxx b/oox/source/drawingml/connectorshapecontext.cxx
new file mode 100644
index 000000000000..447065f56cd9
--- /dev/null
+++ b/oox/source/drawingml/connectorshapecontext.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: connectorshapecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/drawingml/connectorshapecontext.hxx"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+ConnectorShapeContext::ConnectorShapeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 /* aElementToken */, ShapePtr pMasterShapePtr, ShapePtr pGroupShapePtr )
+: ShapeContext( xHandler, pMasterShapePtr, pGroupShapePtr )
+{
+}
+
+ConnectorShapeContext::~ConnectorShapeContext()
+{
+}
+
+Reference< XFastContextHandler > ConnectorShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken &(~NMSP_MASK) )
+ {
+ case XML_nvCxnSpPr :
+ break;
+
+ default:
+ xRet = ShapeContext::createFastChildContext( aElementToken, xAttribs );
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/customshapegeometry.cxx b/oox/source/drawingml/customshapegeometry.cxx
new file mode 100644
index 000000000000..3eeeabd77e0e
--- /dev/null
+++ b/oox/source/drawingml/customshapegeometry.cxx
@@ -0,0 +1,1071 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: customshapegeometry.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "tokens.hxx"
+#ifndef _UTL_STLTYPES_HXX_
+#include <comphelper/stl_types.hxx>
+#endif
+#include <hash_map>
+
+using ::rtl::OUString;
+using ::com::sun::star::beans::NamedValue;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+enum FormularCommand
+{
+ FC_MULDIV = 0,
+ FC_PLUSMINUS,
+ FC_PLUSDIV,
+ FC_IFELSE,
+ FC_ABS,
+ FC_AT2,
+ FC_CAT2,
+ FC_COS,
+ FC_MAX,
+ FC_MIN,
+ FC_MOD,
+ FC_PIN,
+ FC_SAT2,
+ FC_SIN,
+ FC_SQRT,
+ FC_TAN,
+ FC_VAL,
+ FC_LAST
+};
+struct FormularCommandNameTable
+{
+ const char* pS;
+ FormularCommand pE;
+};
+static FormularCommandNameTable pFormularCommandNameTable[] =
+{
+ { "*/", FC_MULDIV },
+ { "+-", FC_PLUSMINUS },
+ { "+/", FC_PLUSDIV },
+ { "ifelse", FC_IFELSE },
+ { "abs", FC_ABS },
+ { "at2", FC_AT2 },
+ { "cat2", FC_CAT2 },
+ { "cos", FC_COS },
+ { "max", FC_MAX },
+ { "min", FC_MIN },
+ { "mod", FC_MOD },
+ { "pin", FC_PIN },
+ { "sat2", FC_SAT2 },
+ { "sin", FC_SIN },
+ { "sqrt", FC_SQRT },
+ { "tan", FC_TAN },
+ { "val", FC_VAL }
+
+};
+typedef std::hash_map< rtl::OUString, FormularCommand, comphelper::UStringHash, comphelper::UStringEqual > FormulaCommandHMap;
+
+static const FormulaCommandHMap* pCommandHashMap;
+
+// ---------------------------------------------------------------------
+// CT_GeomGuideList
+class AdjustmentValueContext : public ::oox::core::Context
+{
+public:
+ AdjustmentValueContext( const ::oox::core::FragmentHandlerRef& xHandler, CustomShapeProperties& rCustomShapeProperties );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ ::oox::drawingml::CustomShapeProperties& mrCustomShapeProperties;
+};
+
+AdjustmentValueContext::AdjustmentValueContext( const FragmentHandlerRef& xHandler, CustomShapeProperties& rCustomShapeProperties )
+: Context( xHandler )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+static rtl::OUString convertToOOEquation( const rtl::OUString& rSource )
+{
+ if ( !pCommandHashMap )
+ {
+ FormulaCommandHMap* pHM = new FormulaCommandHMap();
+ for( sal_Int32 i = 0; i < FC_LAST; i++ )
+ (*pHM)[ OUString::createFromAscii( pFormularCommandNameTable[ i ].pS ) ] = pFormularCommandNameTable[ i ].pE;
+ pCommandHashMap = pHM;
+ }
+
+ std::vector< rtl::OUString > aTokens;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ rtl::OUString aToken( rSource.getToken( 0, ' ', nIndex ) );
+ if ( aToken.getLength() )
+ aTokens.push_back( aToken );
+ }
+ while ( nIndex >= 0 );
+
+ rtl::OUString aEquation;
+ if ( aTokens.size() )
+ {
+ const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
+ if ( aIter != pCommandHashMap->end() )
+ {
+ switch( aIter->second )
+ {
+ case FC_MULDIV :
+ case FC_PLUSMINUS :
+ case FC_PLUSDIV :
+ case FC_IFELSE :
+ case FC_ABS :
+ case FC_AT2 :
+ case FC_CAT2 :
+ case FC_COS :
+ case FC_MAX :
+ case FC_MIN :
+ case FC_MOD :
+ case FC_PIN :
+ case FC_SAT2 :
+ case FC_SIN :
+ case FC_SQRT :
+ case FC_TAN :
+ case FC_VAL :
+ default :
+ break;
+ }
+ }
+ }
+ return aEquation;
+}
+
+Reference< XFastContextHandler > AdjustmentValueContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ if ( aElementToken == ( NMSP_DRAWINGML | XML_gd ) ) // CT_GeomGuide
+ {
+ CustomShapeGuide aGuide;
+ aGuide.maName = xAttribs->getOptionalValue( XML_name );
+ aGuide.maFormula = convertToOOEquation( xAttribs->getOptionalValue( XML_fmla ) );
+ std::vector< CustomShapeGuide >& rAdjustmentValues( mrCustomShapeProperties.getAdjustmentValues() );
+ rAdjustmentValues.push_back( aGuide );
+ }
+ return this;
+}
+
+// ---------------------------------------------------------------------
+
+static OUString GetShapeType( sal_Int32 nType )
+{
+ OUString sType;
+ switch( nType )
+ {
+ case XML_lineInv: // TODO
+ case XML_line: {
+ static const OUString sLine = CREATE_OUSTRING( "mso-spt20" );
+ sType = sLine;
+ } break;
+ case XML_triangle: {
+ static const OUString sTriangle = CREATE_OUSTRING( "isosceles-triangle" );
+ sType = sTriangle;
+ } break;
+ case XML_rtTriangle: {
+ static const OUString sRtTriangle = CREATE_OUSTRING( "right-triangle" );
+ sType = sRtTriangle;
+ } break;
+ case XML_rect: {
+ static const OUString sRectangle = CREATE_OUSTRING( "rectangle" );
+ sType = sRectangle;
+ } break;
+ case XML_diamond: {
+ static const OUString sDiamond = CREATE_OUSTRING( "diamond" );
+ sType = sDiamond;
+ } break;
+ case XML_parallelogram: {
+ static const OUString sParallelogram = CREATE_OUSTRING( "parallelogram" );
+ sType = sParallelogram;
+ } break;
+ case XML_nonIsoscelesTrapezoid: // TODO
+ case XML_trapezoid: {
+ static const OUString sTrapezoid = CREATE_OUSTRING( "trapezoid" );
+ sType = sTrapezoid;
+ } break;
+ case XML_pentagon: {
+ static const OUString sPentagon = CREATE_OUSTRING( "pentagon" );
+ sType = sPentagon;
+ } break;
+ case XML_heptagon: // TODO
+ case XML_hexagon: {
+ static const OUString sHexagon = CREATE_OUSTRING( "hexagon" );
+ sType = sHexagon;
+ } break;
+ case XML_decagon: // TODO
+ case XML_dodecagon: // TODO
+ case XML_octagon: {
+ static const OUString sOctagon = CREATE_OUSTRING( "octagon" );
+ sType = sOctagon;
+ } break;
+ case XML_star4: {
+ static const OUString sStar4 = CREATE_OUSTRING( "star4" );
+ sType = sStar4;
+ } break;
+ case XML_star6: // TODO
+ case XML_star7: // TODO
+ case XML_star5: {
+ static const OUString sStar5 = CREATE_OUSTRING( "star5" );
+ sType = sStar5;
+ } break;
+ case XML_star10: // TODO
+ case XML_star12: // TODO
+ case XML_star16: // TODO
+ case XML_star8: {
+ static const OUString sStar8 = CREATE_OUSTRING( "star8" );
+ sType = sStar8;
+ } break;
+ case XML_star32: // TODO
+ case XML_star24: {
+ static const OUString sStar24 = CREATE_OUSTRING( "star24" );
+ sType = sStar24;
+ } break;
+ case XML_round1Rect: // TODO
+ case XML_round2SameRect: // TODO
+ case XML_round2DiagRect: // TODO
+ case XML_snipRoundRect: // TODO
+ case XML_snip1Rect: // TODO
+ case XML_snip2SameRect: // TODO
+ case XML_snip2DiagRect: // TODO
+ case XML_roundRect: {
+ static const OUString sRoundRect = CREATE_OUSTRING( "round-rectangle" );
+ sType = sRoundRect;
+ } break;
+ case XML_plaque: {
+ static const OUString sPlaque = CREATE_OUSTRING( "mso-spt21" );
+ sType = sPlaque;
+ } break;
+ case XML_teardrop: // TODO
+ case XML_ellipse: {
+ static const OUString sEllipse = CREATE_OUSTRING( "ellipse" );
+ sType = sEllipse;
+ } break;
+ case XML_homePlate: {
+ static const OUString sHomePlate = CREATE_OUSTRING( "pentagon-right" );
+ sType = sHomePlate;
+ } break;
+ case XML_chevron: {
+ static const OUString sChevron = CREATE_OUSTRING( "chevron" );
+ sType = sChevron;
+ } break;
+ case XML_pieWedge: // TODO
+ case XML_pie: // TODO
+ case XML_blockArc: {
+ static const OUString sBlockArc = CREATE_OUSTRING( "block-arc" );
+ sType = sBlockArc;
+ } break;
+ case XML_donut: {
+ static const OUString sDonut = CREATE_OUSTRING( "ring" );
+ sType = sDonut;
+ } break;
+ case XML_noSmoking: {
+ static const OUString sNoSmoking = CREATE_OUSTRING( "forbidden" );
+ sType = sNoSmoking;
+ } break;
+ case XML_rightArrow: {
+ static const OUString sRightArrow = CREATE_OUSTRING( "right-arrow" );
+ sType = sRightArrow;
+ } break;
+ case XML_leftArrow: {
+ static const OUString sLeftArrow = CREATE_OUSTRING( "left-arrow" );
+ sType = sLeftArrow;
+ } break;
+ case XML_upArrow: {
+ static const OUString sUpArrow = CREATE_OUSTRING( "up-arrow" );
+ sType = sUpArrow;
+ } break;
+ case XML_downArrow: {
+ static const OUString sDownArrow = CREATE_OUSTRING( "down-arrow" );
+ sType = sDownArrow;
+ } break;
+ case XML_stripedRightArrow: {
+ static const OUString sStripedRightArrow = CREATE_OUSTRING( "striped-right-arrow" );
+ sType = sStripedRightArrow;
+ } break;
+ case XML_notchedRightArrow: {
+ static const OUString sNotchedRightArrow = CREATE_OUSTRING( "notched-right-arrow" );
+ sType = sNotchedRightArrow;
+ } break;
+ case XML_bentUpArrow: {
+ static const OUString sBentUpArrow = CREATE_OUSTRING( "mso-spt90" );
+ sType = sBentUpArrow;
+ } break;
+ case XML_leftRightArrow: {
+ static const OUString sLeftRightArrow = CREATE_OUSTRING( "left-right-arrow" );
+ sType = sLeftRightArrow;
+ } break;
+ case XML_upDownArrow: {
+ static const OUString sUpDownArrow = CREATE_OUSTRING( "up-down-arrow" );
+ sType = sUpDownArrow;
+ } break;
+ case XML_leftUpArrow: {
+ static const OUString sLeftUpArrow = CREATE_OUSTRING( "mso-spt89" );
+ sType = sLeftUpArrow;
+ } break;
+ case XML_leftRightUpArrow: {
+ static const OUString sLeftRightUpArrow = CREATE_OUSTRING( "mso-spt182" );
+ sType = sLeftRightUpArrow;
+ } break;
+ case XML_quadArrow: {
+ static const OUString sQuadArrow = CREATE_OUSTRING( "quad-arrow" );
+ sType = sQuadArrow;
+ } break;
+ case XML_leftArrowCallout: {
+ static const OUString sLeftArrowCallout = CREATE_OUSTRING( "left-arrow-callout" );
+ sType = sLeftArrowCallout;
+ } break;
+ case XML_rightArrowCallout: {
+ static const OUString sRightArrowCallout = CREATE_OUSTRING( "right-arrow-callout" );
+ sType = sRightArrowCallout;
+ } break;
+ case XML_upArrowCallout: {
+ static const OUString sUpArrowCallout = CREATE_OUSTRING( "up-arrow-callout" );
+ sType = sUpArrowCallout;
+ } break;
+ case XML_downArrowCallout: {
+ static const OUString sDownArrowCallout = CREATE_OUSTRING( "down-arrow-callout" );
+ sType = sDownArrowCallout;
+ } break;
+ case XML_leftRightArrowCallout: {
+ static const OUString sLeftRightArrowCallout = CREATE_OUSTRING( "left-right-arrow-callout" );
+ sType = sLeftRightArrowCallout;
+ } break;
+ case XML_upDownArrowCallout: {
+ static const OUString sUpDownArrowCallout = CREATE_OUSTRING( "up-down-arrow-callout" );
+ sType = sUpDownArrowCallout;
+ } break;
+ case XML_quadArrowCallout: {
+ static const OUString sQuadArrowCallout = CREATE_OUSTRING( "quad-arrow-callout" );
+ sType = sQuadArrowCallout;
+ } break;
+ case XML_bentArrow: {
+ static const OUString sBentArrow = CREATE_OUSTRING( "mso-spt91" );
+ sType = sBentArrow;
+ } break;
+ case XML_uturnArrow: {
+ static const OUString sUTurnArrow = CREATE_OUSTRING( "mso-spt101" );
+ sType = sUTurnArrow;
+ } break;
+ case XML_leftCircularArrow: // TODO
+ case XML_leftRightCircularArrow: // TODO
+ case XML_circularArrow: {
+ static const OUString sCircularArrow = CREATE_OUSTRING( "circular-arrow" );
+ sType = sCircularArrow;
+ } break;
+ case XML_curvedRightArrow: {
+ static const OUString sCurvedRightArrow = CREATE_OUSTRING( "mso-spt102" );
+ sType = sCurvedRightArrow;
+ } break;
+ case XML_curvedLeftArrow: {
+ static const OUString sCurvedLeftArrow = CREATE_OUSTRING( "mso-spt103" );
+ sType = sCurvedLeftArrow;
+ } break;
+ case XML_curvedUpArrow: {
+ static const OUString sCurvedUpArrow = CREATE_OUSTRING( "mso-spt104" );
+ sType = sCurvedUpArrow;
+ } break;
+ case XML_swooshArrow: // TODO
+ case XML_curvedDownArrow: {
+ static const OUString sCurvedDownArrow = CREATE_OUSTRING( "mso-spt105" );
+ sType = sCurvedDownArrow;
+ } break;
+ case XML_cube: {
+ static const OUString sCube = CREATE_OUSTRING( "cube" );
+ sType = sCube;
+ } break;
+ case XML_can: {
+ static const OUString sCan = CREATE_OUSTRING( "can" );
+ sType = sCan;
+ } break;
+ case XML_lightningBolt: {
+ static const OUString sLightningBolt = CREATE_OUSTRING( "lightning" );
+ sType = sLightningBolt;
+ } break;
+ case XML_heart: {
+ static const OUString sHeart = CREATE_OUSTRING( "heart" );
+ sType = sHeart;
+ } break;
+ case XML_sun: {
+ static const OUString sSun = CREATE_OUSTRING( "sun" );
+ sType = sSun;
+ } break;
+ case XML_moon: {
+ static const OUString sMoon = CREATE_OUSTRING( "moon" );
+ sType = sMoon;
+ } break;
+ case XML_smileyFace: {
+ static const OUString sSmileyFace = CREATE_OUSTRING( "smiley" );
+ sType = sSmileyFace;
+ } break;
+ case XML_irregularSeal1: {
+ static const OUString sIrregularSeal1 = CREATE_OUSTRING( "mso-spt71" );
+ sType = sIrregularSeal1;
+ } break;
+ case XML_irregularSeal2: {
+ static const OUString sIrregularSeal2 = CREATE_OUSTRING( "bang" );
+ sType = sIrregularSeal2;
+ } break;
+ case XML_foldedCorner: {
+ static const OUString sFoldedCorner = CREATE_OUSTRING( "paper" );
+ sType = sFoldedCorner;
+ } break;
+ case XML_bevel: {
+ static const OUString sBevel = CREATE_OUSTRING( "quad-bevel" );
+ sType = sBevel;
+ } break;
+ case XML_halfFrame: // TODO
+ case XML_corner: // TODO
+ case XML_diagStripe: // TODO
+ case XML_chord: // TODO
+ case XML_frame: {
+ static const OUString sFrame = CREATE_OUSTRING( "mso-spt75" );
+ sType = sFrame;
+ } break;
+ case XML_arc: {
+ static const OUString sArc = CREATE_OUSTRING( "mso-spt19" );
+ sType = sArc;
+ } break;
+ case XML_leftBracket: {
+ static const OUString sLeftBracket = CREATE_OUSTRING( "left-bracket" );
+ sType = sLeftBracket;
+ } break;
+ case XML_rightBracket: {
+ static const OUString sRightBracket = CREATE_OUSTRING( "right-bracket" );
+ sType = sRightBracket;
+ } break;
+ case XML_leftBrace: {
+ static const OUString sLeftBrace = CREATE_OUSTRING( "left-brace" );
+ sType = sLeftBrace;
+ } break;
+ case XML_rightBrace: {
+ static const OUString sRightBrace = CREATE_OUSTRING( "right-brace" );
+ sType = sRightBrace;
+ } break;
+ case XML_bracketPair: {
+ static const OUString sBracketPair = CREATE_OUSTRING( "bracket-pair" );
+ sType = sBracketPair;
+ } break;
+ case XML_bracePair: {
+ static const OUString sBracePair = CREATE_OUSTRING( "brace-pair" );
+ sType = sBracePair;
+ } break;
+ case XML_straightConnector1: {
+ static const OUString sStraightConnector1 = CREATE_OUSTRING( "mso-spt32" );
+ sType = sStraightConnector1;
+ } break;
+ case XML_bentConnector2: {
+ static const OUString sBentConnector2 = CREATE_OUSTRING( "mso-spt33" );
+ sType = sBentConnector2;
+ } break;
+ case XML_bentConnector3: {
+ static const OUString sBentConnector3 = CREATE_OUSTRING( "mso-spt34" );
+ sType = sBentConnector3;
+ } break;
+ case XML_bentConnector4: {
+ static const OUString sBentConnector4 = CREATE_OUSTRING( "mso-spt35" );
+ sType = sBentConnector4;
+ } break;
+ case XML_bentConnector5: {
+ static const OUString sBentConnector5 = CREATE_OUSTRING( "mso-spt36" );
+ sType = sBentConnector5;
+ } break;
+ case XML_curvedConnector2: {
+ static const OUString sCurvedConnector2 = CREATE_OUSTRING( "mso-spt37" );
+ sType = sCurvedConnector2;
+ } break;
+ case XML_curvedConnector3: {
+ static const OUString sCurvedConnector3 = CREATE_OUSTRING( "mso-spt38" );
+ sType = sCurvedConnector3;
+ } break;
+ case XML_curvedConnector4: {
+ static const OUString sCurvedConnector4 = CREATE_OUSTRING( "mso-spt39" );
+ sType = sCurvedConnector4;
+ } break;
+ case XML_curvedConnector5: {
+ static const OUString sCurvedConnector5 = CREATE_OUSTRING( "mso-spt40" );
+ sType = sCurvedConnector5;
+ } break;
+ case XML_callout1: {
+ static const OUString sCallout1 = CREATE_OUSTRING( "mso-spt41" );
+ sType = sCallout1;
+ } break;
+ case XML_callout2: {
+ static const OUString sCallout2 = CREATE_OUSTRING( "mso-spt42" );
+ sType = sCallout2;
+ } break;
+ case XML_callout3: {
+ static const OUString sCallout3 = CREATE_OUSTRING( "mso-spt43" );
+ sType = sCallout3;
+ } break;
+ case XML_accentCallout1: {
+ static const OUString sAccentCallout1 = CREATE_OUSTRING( "mso-spt44" );
+ sType = sAccentCallout1;
+ } break;
+ case XML_accentCallout2: {
+ static const OUString sAccentCallout2 = CREATE_OUSTRING( "mso-spt45" );
+ sType = sAccentCallout2;
+ } break;
+ case XML_accentCallout3: {
+ static const OUString sAccentCallout3 = CREATE_OUSTRING( "mso-spt46" );
+ sType = sAccentCallout3;
+ } break;
+ case XML_borderCallout1: {
+ static const OUString sBorderCallout1 = CREATE_OUSTRING( "line-callout-1" );
+ sType = sBorderCallout1;
+ } break;
+ case XML_borderCallout2: {
+ static const OUString sBorderCallout2 = CREATE_OUSTRING( "line-callout-2" );
+ sType = sBorderCallout2;
+ } break;
+ case XML_borderCallout3: {
+ static const OUString sBorderCallout3 = CREATE_OUSTRING( "mso-spt49" );
+ sType = sBorderCallout3;
+ } break;
+ case XML_accentBorderCallout1: {
+ static const OUString sAccentBorderCallout1 = CREATE_OUSTRING( "mso-spt50" );
+ sType = sAccentBorderCallout1;
+ } break;
+ case XML_accentBorderCallout2: {
+ static const OUString sAccentBorderCallout2 = CREATE_OUSTRING( "mso-spt51" );
+ sType = sAccentBorderCallout2;
+ } break;
+ case XML_accentBorderCallout3: {
+ static const OUString sAccentBorderCallout3 = CREATE_OUSTRING( "mso-spt52" );
+ sType = sAccentBorderCallout3;
+ } break;
+ case XML_wedgeRectCallout: {
+ static const OUString sWedgeRectCallout = CREATE_OUSTRING( "rectangular-callout" );
+ sType = sWedgeRectCallout;
+ } break;
+ case XML_wedgeRoundRectCallout: {
+ static const OUString sWedgeRoundRectCallout = CREATE_OUSTRING( "round-rectangular-callout" );
+ sType = sWedgeRoundRectCallout;
+ } break;
+ case XML_wedgeEllipseCallout: {
+ static const OUString sWedgeEllipseCallout = CREATE_OUSTRING( "round-callout" );
+ sType = sWedgeEllipseCallout;
+ } break;
+ case XML_cloud: // TODO
+ case XML_cloudCallout: {
+ static const OUString sCloudCallout = CREATE_OUSTRING( "cloud-callout" );
+ sType = sCloudCallout;
+ } break;
+ case XML_ribbon: {
+ static const OUString sRibbon = CREATE_OUSTRING( "mso-spt53" );
+ sType = sRibbon;
+ } break;
+ case XML_ribbon2: {
+ static const OUString sRibbon2 = CREATE_OUSTRING( "mso-spt54" );
+ sType = sRibbon2;
+ } break;
+ case XML_ellipseRibbon: {
+ static const OUString sEllipseRibbon = CREATE_OUSTRING( "mso-spt107" );
+ sType = sEllipseRibbon;
+ } break;
+ case XML_leftRightRibbon: // TODO
+ case XML_ellipseRibbon2: {
+ static const OUString sEllipseRibbon2 = CREATE_OUSTRING( "mso-spt108" );
+ sType = sEllipseRibbon2;
+ } break;
+ case XML_verticalScroll: {
+ static const OUString sVerticalScroll = CREATE_OUSTRING( "vertical-scroll" );
+ sType = sVerticalScroll;
+ } break;
+ case XML_horizontalScroll: {
+ static const OUString sHorizontalScroll = CREATE_OUSTRING( "horizontal-scroll" );
+ sType = sHorizontalScroll;
+ } break;
+ case XML_wave: {
+ static const OUString sWave = CREATE_OUSTRING( "mso-spt64" );
+ sType = sWave;
+ } break;
+ case XML_doubleWave: {
+ static const OUString sDoubleWave = CREATE_OUSTRING( "mso-spt188" );
+ sType = sDoubleWave;
+ } break;
+ case XML_plus: {
+ static const OUString sPlus = CREATE_OUSTRING( "cross" );
+ sType = sPlus;
+ } break;
+ case XML_flowChartProcess: {
+ static const OUString sFlowChartProcess = CREATE_OUSTRING( "flowchart-process" );
+ sType = sFlowChartProcess;
+ } break;
+ case XML_flowChartDecision: {
+ static const OUString sFlowChartDecision = CREATE_OUSTRING( "flowchart-decision" );
+ sType = sFlowChartDecision;
+ } break;
+ case XML_flowChartInputOutput: {
+ static const OUString sFlowChartInputOutput = CREATE_OUSTRING( "flowchart-data" );
+ sType = sFlowChartInputOutput;
+ } break;
+ case XML_flowChartPredefinedProcess: {
+ static const OUString sFlowChartPredefinedProcess = CREATE_OUSTRING( "flowchart-predefined-process" );
+ sType = sFlowChartPredefinedProcess;
+ } break;
+ case XML_flowChartInternalStorage: {
+ static const OUString sFlowChartInternalStorage = CREATE_OUSTRING( "flowchart-internal-storage" );
+ sType = sFlowChartInternalStorage;
+ } break;
+ case XML_flowChartDocument: {
+ static const OUString sFlowChartDocument = CREATE_OUSTRING( "flowchart-document" );
+ sType = sFlowChartDocument;
+ } break;
+ case XML_flowChartMultidocument: {
+ static const OUString sFlowChartMultidocument = CREATE_OUSTRING( "flowchart-multidocument" );
+ sType = sFlowChartMultidocument;
+ } break;
+ case XML_flowChartTerminator: {
+ static const OUString sFlowChartTerminator = CREATE_OUSTRING( "flowchart-terminator" );
+ sType = sFlowChartTerminator;
+ } break;
+ case XML_flowChartPreparation : {
+ static const OUString sFlowChartPreparation = CREATE_OUSTRING( "flowchart-preparation" );
+ sType = sFlowChartPreparation;
+ } break;
+ case XML_flowChartManualInput: {
+ static const OUString sFlowChartManualInput = CREATE_OUSTRING( "flowchart-manual-input" );
+ sType = sFlowChartManualInput;
+ } break;
+ case XML_flowChartManualOperation: {
+ static const OUString sFlowChartManualOperation = CREATE_OUSTRING( "flowchart-manual-operation" );
+ sType = sFlowChartManualOperation;
+ } break;
+ case XML_flowChartConnector: {
+ static const OUString sFlowChartConnector = CREATE_OUSTRING( "flowchart-connector" );
+ sType = sFlowChartConnector;
+ } break;
+ case XML_flowChartPunchedCard: {
+ static const OUString sFlowChartPunchedCard = CREATE_OUSTRING( "flowchart-card" );
+ sType = sFlowChartPunchedCard;
+ } break;
+ case XML_flowChartPunchedTape: {
+ static const OUString sFlowChartPunchedTape = CREATE_OUSTRING( "flowchart-punched-tape" );
+ sType = sFlowChartPunchedTape;
+ } break;
+ case XML_flowChartSummingJunction: {
+ static const OUString sFlowChartSummingJunction = CREATE_OUSTRING( "flowchart-summing-junction" );
+ sType = sFlowChartSummingJunction;
+ } break;
+ case XML_flowChartOr: {
+ static const OUString sFlowChartOr = CREATE_OUSTRING( "flowchart-or" );
+ sType = sFlowChartOr;
+ } break;
+ case XML_flowChartCollate: {
+ static const OUString sFlowChartCollate = CREATE_OUSTRING( "flowchart-collate" );
+ sType = sFlowChartCollate;
+ } break;
+ case XML_flowChartSort: {
+ static const OUString sFlowChartSort = CREATE_OUSTRING( "flowchart-sort" );
+ sType = sFlowChartSort;
+ } break;
+ case XML_flowChartExtract: {
+ static const OUString sFlowChartExtract = CREATE_OUSTRING( "flowchart-extract" );
+ sType = sFlowChartExtract;
+ } break;
+ case XML_flowChartMerge: {
+ static const OUString sFlowChartMerge = CREATE_OUSTRING( "flowchart-merge" );
+ sType = sFlowChartMerge;
+ } break;
+ case XML_flowChartOfflineStorage: {
+ static const OUString sFlowChartOfflineStorage = CREATE_OUSTRING( "mso-spt129" );
+ sType = sFlowChartOfflineStorage;
+ } break;
+ case XML_flowChartOnlineStorage: {
+ static const OUString sFlowChartOnlineStorage = CREATE_OUSTRING( "flowchart-stored-data" );
+ sType = sFlowChartOnlineStorage;
+ } break;
+ case XML_flowChartMagneticTape: {
+ static const OUString sFlowChartMagneticTape = CREATE_OUSTRING( "flowchart-sequential-access" );
+ sType = sFlowChartMagneticTape;
+ } break;
+ case XML_flowChartMagneticDisk: {
+ static const OUString sFlowChartMagneticDisk = CREATE_OUSTRING( "flowchart-magnetic-disk" );
+ sType = sFlowChartMagneticDisk;
+ } break;
+ case XML_flowChartMagneticDrum: {
+ static const OUString sFlowChartMagneticDrum = CREATE_OUSTRING( "flowchart-direct-access-storage" );
+ sType = sFlowChartMagneticDrum;
+ } break;
+ case XML_flowChartDisplay: {
+ static const OUString sFlowChartDisplay = CREATE_OUSTRING( "flowchart-display" );
+ sType = sFlowChartDisplay;
+ } break;
+ case XML_flowChartDelay: {
+ static const OUString sFlowChartDelay = CREATE_OUSTRING( "flowchart-delay" );
+ sType = sFlowChartDelay;
+ } break;
+ case XML_flowChartAlternateProcess: {
+ static const OUString sFlowChartAlternateProcess = CREATE_OUSTRING( "flowchart-alternate-process" );
+ sType = sFlowChartAlternateProcess;
+ } break;
+ case XML_flowChartOffpageConnector: {
+ static const OUString sFlowChartOffpageConnector = CREATE_OUSTRING( "flowchart-off-page-connector" );
+ sType = sFlowChartOffpageConnector;
+ } break;
+ case XML_actionButtonBlank: {
+ static const OUString sActionButtonBlank = CREATE_OUSTRING( "mso-spt189" );
+ sType = sActionButtonBlank;
+ } break;
+ case XML_actionButtonHome: {
+ static const OUString sActionButtonHome = CREATE_OUSTRING( "mso-spt190" );
+ sType = sActionButtonHome;
+ } break;
+ case XML_actionButtonHelp: {
+ static const OUString sActionButtonHelp = CREATE_OUSTRING( "mso-spt191" );
+ sType = sActionButtonHelp;
+ } break;
+ case XML_actionButtonInformation: {
+ static const OUString sActionButtonInformation = CREATE_OUSTRING( "mso-spt192" );
+ sType = sActionButtonInformation;
+ } break;
+ case XML_actionButtonForwardNext: {
+ static const OUString sActionButtonForwardNext = CREATE_OUSTRING( "mso-spt193" );
+ sType = sActionButtonForwardNext;
+ } break;
+ case XML_actionButtonBackPrevious: {
+ static const OUString sActionButtonBackPrevious = CREATE_OUSTRING( "mso-spt194" );
+ sType = sActionButtonBackPrevious;
+ } break;
+ case XML_actionButtonEnd: {
+ static const OUString sActionButtonEnd = CREATE_OUSTRING( "mso-spt195" );
+ sType = sActionButtonEnd;
+ } break;
+ case XML_actionButtonBeginning: {
+ static const OUString sActionButtonBeginning = CREATE_OUSTRING( "mso-spt196" );
+ sType = sActionButtonBeginning;
+ } break;
+ case XML_actionButtonReturn: {
+ static const OUString sActionButtonReturn = CREATE_OUSTRING( "mso-spt197" );
+ sType = sActionButtonReturn;
+ } break;
+ case XML_actionButtonDocument: {
+ static const OUString sActionButtonDocument = CREATE_OUSTRING( "mso-spt198" );
+ sType = sActionButtonDocument;
+ } break;
+ case XML_actionButtonSound: {
+ static const OUString sActionButtonSound = CREATE_OUSTRING( "mso-spt199" );
+ sType = sActionButtonSound;
+ } break;
+ case XML_actionButtonMovie: {
+ static const OUString sActionButtonMovie = CREATE_OUSTRING( "mso-spt200" );
+ sType = sActionButtonMovie;
+ } break;
+ case XML_gear6: // TODO
+ case XML_gear9: // TODO
+ case XML_funnel: // TODO
+ case XML_mathPlus: // TODO
+ case XML_mathMinus: // TODO
+ case XML_mathMultiply: // TODO
+ case XML_mathDivide: // TODO
+ case XML_mathEqual: // TODO
+ case XML_mathNotEqual: // TODO
+ case XML_cornerTabs: // TODO
+ case XML_squareTabs: // TODO
+ case XML_plaqueTabs: // TODO
+ case XML_chartX: // TODO
+ case XML_chartStar: // TODO
+ case XML_chartPlus: { // TODO
+ static const OUString sRectangle = CREATE_OUSTRING( "rectangle" );
+ sType = sRectangle;
+ } break;
+ default:
+ break;
+ }
+ return sType;
+}
+
+static OUString GetTextShapeType( sal_Int32 nType )
+{
+ OUString sType;
+ switch( nType )
+ {
+ case XML_textNoShape: // TODO
+ case XML_textPlain: {
+ static const OUString sTextPlain = CREATE_OUSTRING( "fontwork-plain-text" );
+ sType = sTextPlain;
+ } break;
+ case XML_textStop: {
+ static const OUString sTextStop = CREATE_OUSTRING( "fontwork-stop" );
+ sType = sTextStop;
+ } break;
+ case XML_textTriangle: {
+ static const OUString sTextTriangle = CREATE_OUSTRING( "fontwork-triangle-up" );
+ sType = sTextTriangle;
+ } break;
+ case XML_textTriangleInverted: {
+ static const OUString sTextTriangleInverted = CREATE_OUSTRING( "fontwork-triangle-down" );
+ sType = sTextTriangleInverted;
+ } break;
+ case XML_textChevron: {
+ static const OUString sTextChevron = CREATE_OUSTRING( "fontwork-chevron-up" );
+ sType = sTextChevron;
+ } break;
+ case XML_textChevronInverted: {
+ static const OUString sTextChevronInverted = CREATE_OUSTRING( "fontwork-chevron-down" );
+ sType = sTextChevronInverted;
+ } break;
+ case XML_textRingInside: {
+ static const OUString sTextRingInside = CREATE_OUSTRING( "mso-spt142" );
+ sType = sTextRingInside;
+ } break;
+ case XML_textRingOutside: {
+ static const OUString sTextRingOutside = CREATE_OUSTRING( "mso-spt143" );
+ sType = sTextRingOutside;
+ } break;
+ case XML_textArchUp: {
+ static const OUString sTextArchUp = CREATE_OUSTRING( "fontwork-arch-up-curve" );
+ sType = sTextArchUp;
+ } break;
+ case XML_textArchDown: {
+ static const OUString sTextArchDown = CREATE_OUSTRING( "fontwork-arch-down-curve" );
+ sType = sTextArchDown;
+ } break;
+ case XML_textCircle: {
+ static const OUString sTextCircle = CREATE_OUSTRING( "fontwork-circle-curve" );
+ sType = sTextCircle;
+ } break;
+ case XML_textButton: {
+ static const OUString sTextButton = CREATE_OUSTRING( "fontwork-open-circle-curve" );
+ sType = sTextButton;
+ } break;
+ case XML_textArchUpPour: {
+ static const OUString sTextArchUpPour = CREATE_OUSTRING( "fontwork-arch-up-pour" );
+ sType = sTextArchUpPour;
+ } break;
+ case XML_textArchDownPour: {
+ static const OUString sTextArchDownPour = CREATE_OUSTRING( "fontwork-arch-down-pour" );
+ sType = sTextArchDownPour;
+ } break;
+ case XML_textCirclePour: {
+ static const OUString sTextCirclePour = CREATE_OUSTRING( "fontwork-circle-pour" );
+ sType = sTextCirclePour;
+ } break;
+ case XML_textButtonPour: {
+ static const OUString sTextButtonPour = CREATE_OUSTRING( "fontwork-open-circle-pour" );
+ sType = sTextButtonPour;
+ } break;
+ case XML_textCurveUp: {
+ static const OUString sTextCurveUp = CREATE_OUSTRING( "fontwork-curve-up" );
+ sType = sTextCurveUp;
+ } break;
+ case XML_textCurveDown: {
+ static const OUString sTextCurveDown = CREATE_OUSTRING( "fontwork-curve-down" );
+ sType = sTextCurveDown;
+ } break;
+ case XML_textCanUp: {
+ static const OUString sTextCanUp = CREATE_OUSTRING( "mso-spt174" );
+ sType = sTextCanUp;
+ } break;
+ case XML_textCanDown: {
+ static const OUString sTextCanDown = CREATE_OUSTRING( "mso-spt175" );
+ sType = sTextCanDown;
+ } break;
+ case XML_textWave1: {
+ static const OUString sTextWave1 = CREATE_OUSTRING( "fontwork-wave" );
+ sType = sTextWave1;
+ } break;
+ case XML_textWave2: {
+ static const OUString sTextWave2 = CREATE_OUSTRING( "mso-spt157" );
+ sType = sTextWave2;
+ } break;
+ case XML_textDoubleWave1: {
+ static const OUString sTextDoubleWave1 = CREATE_OUSTRING( "mso-spt158" );
+ sType = sTextDoubleWave1;
+ } break;
+ case XML_textWave4: {
+ static const OUString sTextWave4 = CREATE_OUSTRING( "mso-spt159" );
+ sType = sTextWave4;
+ } break;
+ case XML_textInflate: {
+ static const OUString sTextInflate = CREATE_OUSTRING( "fontwork-inflate" );
+ sType = sTextInflate;
+ } break;
+ case XML_textDeflate: {
+ static const OUString sTextDeflate = CREATE_OUSTRING( "mso-spt161" );
+ sType = sTextDeflate;
+ } break;
+ case XML_textInflateBottom: {
+ static const OUString sTextInflateBottom = CREATE_OUSTRING( "mso-spt162" );
+ sType = sTextInflateBottom;
+ } break;
+ case XML_textDeflateBottom: {
+ static const OUString sTextDeflateBottom = CREATE_OUSTRING( "mso-spt163" );
+ sType = sTextDeflateBottom;
+ } break;
+ case XML_textInflateTop: {
+ static const OUString sTextInflateTop = CREATE_OUSTRING( "mso-spt164" );
+ sType = sTextInflateTop;
+ } break;
+ case XML_textDeflateTop: {
+ static const OUString sTextDeflateTop = CREATE_OUSTRING( "mso-spt165" );
+ sType = sTextDeflateTop;
+ } break;
+ case XML_textDeflateInflate: {
+ static const OUString sTextDeflateInflate = CREATE_OUSTRING( "mso-spt166" );
+ sType = sTextDeflateInflate;
+ } break;
+ case XML_textDeflateInflateDeflate: {
+ static const OUString sTextDeflateInflateDeflate = CREATE_OUSTRING( "mso-spt167" );
+ sType = sTextDeflateInflateDeflate;
+ } break;
+ case XML_textFadeRight: {
+ static const OUString sTextFadeRight = CREATE_OUSTRING( "fontwork-fade-right" );
+ sType = sTextFadeRight;
+ } break;
+ case XML_textFadeLeft: {
+ static const OUString sTextFadeLeft = CREATE_OUSTRING( "fontwork-fade-left" );
+ sType = sTextFadeLeft;
+ } break;
+ case XML_textFadeUp: {
+ static const OUString sTextFadeUp = CREATE_OUSTRING( "fontwork-fade-up" );
+ sType = sTextFadeUp;
+ } break;
+ case XML_textFadeDown: {
+ static const OUString sTextFadeDown = CREATE_OUSTRING( "fontwork-fade-down" );
+ sType = sTextFadeDown;
+ } break;
+ case XML_textSlantUp: {
+ static const OUString sTextSlantUp = CREATE_OUSTRING( "fontwork-slant-up" );
+ sType = sTextSlantUp;
+ } break;
+ case XML_textSlantDown: {
+ static const OUString sTextSlantDown = CREATE_OUSTRING( "fontwork-slant-down" );
+ sType = sTextSlantDown;
+ } break;
+ case XML_textCascadeUp: {
+ static const OUString sTextCascadeUp = CREATE_OUSTRING( "fontwork-fade-up-and-right" );
+ sType = sTextCascadeUp;
+ } break;
+ case XML_textCascadeDown: {
+ static const OUString sTextCascadeDown = CREATE_OUSTRING( "fontwork-fade-up-and-left" );
+ sType = sTextCascadeDown;
+ } break;
+ default:
+ break;
+ }
+ return sType;
+}
+
+// ---------------------------------------------------------------------
+// CT_CustomGeometry2D
+CustomShapeGeometryContext::CustomShapeGeometryContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& /* xAttribs */, CustomShapeProperties& rCustomShapeProperties )
+: Context( xHandler )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+Reference< XFastContextHandler > CustomShapeGeometryContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ // todo
+ case NMSP_DRAWINGML|XML_avLst: // CT_GeomGuideList adjust value list
+ case NMSP_DRAWINGML|XML_gdLst: // CT_GeomGuideList guide list
+ case NMSP_DRAWINGML|XML_ahLst: // CT_AdjustHandleList adjust handle list
+ case NMSP_DRAWINGML|XML_cxnLst: // CT_ConnectionSiteList connection site list
+ case NMSP_DRAWINGML|XML_rect: // CT_GeomRectList geometry rect list
+ case NMSP_DRAWINGML|XML_pathLst: // CT_Path2DList 2d path list
+ break;
+ }
+
+ Reference< XFastContextHandler > xEmpty;
+ return xEmpty;
+}
+
+// ---------------------------------------------------------------------
+// CT_PresetGeometry2D
+PresetShapeGeometryContext::PresetShapeGeometryContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties )
+: Context( xHandler )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+ OUString sShapeType;
+ sal_Int32 nShapeType = xAttribs->getOptionalValueToken( XML_prst, FastToken::DONTKNOW );
+ if ( nShapeType != FastToken::DONTKNOW )
+ sShapeType = GetShapeType( nShapeType );
+ OSL_ENSURE( sShapeType.getLength(), "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
+ mrCustomShapeProperties.setShapePresetType( sShapeType );
+}
+
+Reference< XFastContextHandler > PresetShapeGeometryContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ if ( aElementToken == ( NMSP_DRAWINGML | XML_avLst ) )
+ return new AdjustmentValueContext( getHandler(), mrCustomShapeProperties );
+ else
+ return this;
+}
+
+// ---------------------------------------------------------------------
+// CT_PresetTextShape
+PresetTextShapeContext::PresetTextShapeContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties )
+: Context( xHandler )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+ OUString sShapeType;
+ sal_Int32 nShapeType = xAttribs->getOptionalValueToken( XML_prst, FastToken::DONTKNOW );
+ if ( nShapeType != FastToken::DONTKNOW )
+ sShapeType = GetTextShapeType( nShapeType );
+ OSL_ENSURE( sShapeType.getLength(), "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
+ mrCustomShapeProperties.setShapePresetType( sShapeType );
+}
+
+Reference< XFastContextHandler > PresetTextShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ // todo
+ case NMSP_DRAWINGML|XML_avLst: // CT_GeomGuideList adjust value list
+ case NMSP_DRAWINGML|XML_gdLst: // CT_GeomGuideList guide list
+ case NMSP_DRAWINGML|XML_ahLst: // CT_AdjustHandleList adjust handle list
+ case NMSP_DRAWINGML|XML_cxnLst: // CT_ConnectionSiteList connection site list
+ case NMSP_DRAWINGML|XML_rect: // CT_GeomRectList geometry rect list
+ case NMSP_DRAWINGML|XML_pathLst: // CT_Path2DList 2d path list
+ break;
+ }
+
+ Reference< XFastContextHandler > xEmpty;
+ return xEmpty;
+}
+
+} }
diff --git a/oox/source/drawingml/customshapeproperties.cxx b/oox/source/drawingml/customshapeproperties.cxx
new file mode 100644
index 000000000000..255a986e7336
--- /dev/null
+++ b/oox/source/drawingml/customshapeproperties.cxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: customshapeproperties.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <comphelper/processfactory.hxx>
+#include "oox/drawingml/customshapeproperties.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XGraphicTransformer.hpp>
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::graphic;
+
+namespace oox { namespace drawingml {
+
+CustomShapeProperties::CustomShapeProperties()
+{
+}
+CustomShapeProperties::~CustomShapeProperties()
+{
+}
+
+void CustomShapeProperties::apply( const CustomShapePropertiesPtr& /* rSourceCustomShapeProperties */ )
+{
+ // not sure if this needs to be implemented
+}
+
+void CustomShapeProperties::pushToPropSet( const ::oox::core::XmlFilterBase& /* rFilterBase */,
+ const Reference < XPropertySet >& xPropSet ) const
+{
+ const OUString sType = CREATE_OUSTRING( "Type" );
+ if ( maShapePresetType.getLength() )
+ {
+
+ // XEnhancedCustomShapeDefaulter TODO
+// const uno::Reference < drawing::XShape > xShape( xPropSet, UNO_QUERY ) ; // REMOVE THIS
+// SdrObjCustomShape* pCustoObj = const_cast< SdrObjCustomShape* >( dynamic_cast< SdrObjCustomShape* >( GetSdrObjectFromXShape( xShape ) ) ) ; // REMOVE THIS
+// if ( pCustoObj ) // REMOVE THIS
+// pCustoObj->MergeDefaultAttributes( &sType ); // REMOVE THIS
+
+ const rtl::OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) );
+ uno::Any aGeoPropSet = xPropSet->getPropertyValue( sCustomShapeGeometry );
+ uno::Sequence< beans::PropertyValue > aGeoPropSeq;
+ if ( aGeoPropSet >>= aGeoPropSeq )
+ {
+ sal_Int32 i, nCount = aGeoPropSeq.getLength();
+ for ( i = 0; i < nCount; i++ )
+ {
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM( "AdjustmentValues" ) );
+ if ( aGeoPropSeq[ i ].Name.equals( sAdjustmentValues ) )
+ {
+ uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
+ if ( aGeoPropSeq[ i ].Value >>= aAdjustmentSeq )
+ {
+ sal_uInt32 j, nHighest = 0;
+ for( j = 0; j < maAdjustmentValues.size(); j++ )
+ {
+ const rtl::OUString& rS( maAdjustmentValues[ j ].maName );
+ if ( rS.getLength() > 3 )
+ {
+ sal_uInt32 nVal = rS.copy( 3 ).toInt32();
+ if ( ( nVal < 10 ) && ( nVal > nHighest ) )
+ nHighest = nVal;
+ }
+ }
+ if ( nHighest > static_cast< sal_uInt32 >( aAdjustmentSeq.getLength() ) )
+ aAdjustmentSeq.realloc( nHighest );
+
+ for ( j = 0; j < maAdjustmentValues.size(); j++ )
+ {
+ sal_uInt32 nVal = maAdjustmentValues[ j ].maName.copy( 3 ).toInt32();
+ if ( nVal-- )
+ {
+ double fNewAdj = getValue( maAdjustmentValues, nVal );
+ aAdjustmentSeq[ nVal ].State = beans::PropertyState_DIRECT_VALUE;
+ aAdjustmentSeq[ nVal ].Value <<= fNewAdj;
+ }
+ }
+ aGeoPropSeq[ i ].Value <<= aAdjustmentSeq;
+ xPropSet->setPropertyValue( sCustomShapeGeometry, Any( aGeoPropSeq ) );
+ }
+ }
+ else if ( aGeoPropSeq[ i ].Name.equals( sType ) )
+ {
+ aGeoPropSeq[ i ].Value <<= maShapePresetType;
+ }
+ }
+ }
+ }
+ else
+ {
+ PropertyMap aPropertyMap;
+ OUString sShapeType( CREATE_OUSTRING( "non-primitive" ) );
+ aPropertyMap[ sType ] <<= sShapeType;
+
+
+ // converting the vector to a sequence
+ Sequence< PropertyValue > aSeq;
+ aPropertyMap.makeSequence( aSeq );
+ static const rtl::OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) );
+ xPropSet->setPropertyValue( sCustomShapeGeometry, Any( aSeq ) );
+ }
+}
+
+double CustomShapeProperties::getValue( const std::vector< CustomShapeGuide >& rGuideList, sal_uInt32 nIndex ) const
+{
+ double fRet = 0.0;
+ if ( nIndex < rGuideList.size() )
+ {
+
+ }
+ return fRet;
+}
+
+} }
diff --git a/oox/source/drawingml/diagram/datamodelcontext.cxx b/oox/source/drawingml/diagram/datamodelcontext.cxx
new file mode 100644
index 000000000000..d7502ea4781a
--- /dev/null
+++ b/oox/source/drawingml/diagram/datamodelcontext.cxx
@@ -0,0 +1,336 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: datamodelcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:57 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/diagram/datamodelcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/skipcontext.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml {
+
+
+
+// CL_Cxn
+class CxnContext
+ : public Context
+{
+public:
+ CxnContext( const FragmentHandlerRef& xParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ const dgm::ConnectionPtr & pConnection )
+ : Context( xParent )
+ , mpConnection( pConnection )
+ {
+ pConnection->msModelId = xAttribs->getOptionalValue( XML_modelId );
+ pConnection->msSourceId = xAttribs->getOptionalValue( XML_srcId );
+ pConnection->msDestId = xAttribs->getOptionalValue( XML_destId );
+ pConnection->msPresId = xAttribs->getOptionalValue( XML_presId );
+ pConnection->msSibTransId = xAttribs->getOptionalValue( XML_sibTransId );
+ AttributeList attribs( xAttribs );
+ pConnection->mnSourceOrder = attribs.getInteger( XML_srcOrd, 0 );
+ pConnection->mnDestOrder = attribs.getInteger( XML_destOrd, 0 );
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& /*xAttribs*/ )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DIAGRAM|XML_extLst:
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+private:
+ dgm::ConnectionPtr mpConnection;
+};
+
+
+// CT_CxnList
+class CxnListContext
+ : public Context
+{
+public:
+ CxnListContext( const FragmentHandlerRef& xParent, dgm::Connections & aConnections )
+ : Context( xParent )
+ , maConnections( aConnections )
+ {
+ }
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DIAGRAM|XML_cxn:
+ {
+ dgm::ConnectionPtr pConnection( new dgm::Connection() );
+ maConnections.push_back( pConnection );
+ xRet.set( new CxnContext( getHandler( ), xAttribs, pConnection ) );
+ break;
+ }
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+private:
+ dgm::Connections & maConnections;
+};
+
+
+
+// CL_Pt
+class PtContext
+ : public Context
+{
+public:
+ PtContext( const FragmentHandlerRef& xParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ const dgm::PointPtr & pPoint)
+ : Context( xParent )
+ , mpPoint( pPoint )
+ {
+ // both can be either an int or a uuid
+ mpPoint->setCnxId( xAttribs->getOptionalValue( XML_cxnId ) );
+ mpPoint->setModelId( xAttribs->getOptionalValue( XML_modelId ) );
+ //
+ mpPoint->setType( xAttribs->getOptionalValueToken( XML_type, 0 ) );
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& /*xAttribs*/ )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DIAGRAM|XML_extLst:
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ case NMSP_DIAGRAM|XML_prSet:
+ // TODO
+ // CT_ElemPropSet
+ break;
+ case NMSP_DIAGRAM|XML_spPr:
+ xRet = new ShapePropertiesContext( this, *(mpPoint->getShape().get()) );
+ break;
+ case NMSP_DIAGRAM|XML_t:
+ xRet = new TextBodyContext( getHandler(), *(mpPoint->getShape().get()) );
+ break;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+private:
+ dgm::PointPtr mpPoint;
+};
+
+
+
+// CT_PtList
+class PtListContext
+ : public Context
+{
+public:
+ PtListContext( const FragmentHandlerRef& xParent, dgm::Points & aPoints)
+ : Context( xParent )
+ , maPoints( aPoints )
+ {
+ }
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DIAGRAM|XML_pt:
+ {
+ // CT_Pt
+ dgm::PointPtr pPoint( new dgm::Point() );
+ maPoints.push_back( pPoint );
+ xRet.set( new PtContext( getHandler( ), xAttribs, pPoint ) );
+ break;
+ }
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+private:
+ dgm::Points & maPoints;
+};
+
+// CT_BackgroundFormatting
+class BackgroundFormattingContext
+ : public Context
+{
+public:
+ BackgroundFormattingContext( const FragmentHandlerRef& xParent, DiagramDataPtr & pModel )
+ : Context( xParent )
+ , mpDataModel( pModel )
+ {
+ OSL_ENSURE( pModel, "the data model MUST NOT be NULL" );
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_blipFill:
+ case NMSP_DRAWINGML|XML_gradFill:
+ case NMSP_DRAWINGML|XML_grpFill:
+ case NMSP_DRAWINGML|XML_noFill:
+ case NMSP_DRAWINGML|XML_pattFill:
+ case NMSP_DRAWINGML|XML_solidFill:
+ // EG_FillProperties
+ xRet.set( FillPropertiesGroupContext::StaticCreateContext( getHandler( ),
+ aElementToken,
+ xAttribs,
+ *(mpDataModel->getFillProperties().get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_effectDag:
+ case NMSP_DRAWINGML|XML_effectLst:
+ // TODO
+ // EG_EffectProperties
+ break;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+private:
+ DiagramDataPtr mpDataModel;
+};
+
+
+
+DataModelContext::DataModelContext( const FragmentHandlerRef& xHandler,
+ const DiagramDataPtr & pDataModel )
+ : Context( xHandler )
+ , mpDataModel( pDataModel )
+{
+ OSL_ENSURE( pDataModel, "Data Model must not be NULL" );
+}
+
+
+DataModelContext::~DataModelContext()
+{
+ // some debug
+ mpDataModel->dump();
+}
+
+
+Reference< XFastContextHandler > SAL_CALL
+DataModelContext::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& /*xAttribs*/ )
+ throw ( SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_DIAGRAM|XML_cxnLst:
+ // CT_CxnList
+ xRet.set( new CxnListContext( getHandler( ), mpDataModel->getConnections() ) );
+ break;
+ case NMSP_DIAGRAM|XML_ptLst:
+ // CT_PtList
+ xRet.set( new PtListContext( getHandler( ), mpDataModel->getPoints() ) );
+ break;
+ case NMSP_DIAGRAM|XML_bg:
+ // CT_BackgroundFormatting
+ xRet.set( new BackgroundFormattingContext( getHandler(), mpDataModel ) );
+ break;
+ case NMSP_DIAGRAM|XML_whole:
+ // CT_WholeE2oFormatting
+ // TODO
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ case NMSP_DIAGRAM|XML_extLst:
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
new file mode 100644
index 000000000000..04394b331f4b
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: diagram.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:57 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#include <functional>
+#include <boost/bind.hpp>
+
+#include "oox/drawingml/diagram/diagram.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+
+namespace oox { namespace drawingml {
+
+namespace dgm {
+
+
+void Connection::dump()
+{
+ OSL_TRACE("dgm: cnx modelId %s, srcId %s, dstId %s",
+ OUSTRING_TO_CSTR( msModelId ),
+ OUSTRING_TO_CSTR( msSourceId ),
+ OUSTRING_TO_CSTR( msDestId ) );
+}
+
+Point::Point()
+ : mpShape( new Shape( "com.sun.star.drawing.GroupShape" ) )
+ , mnType( 0 )
+{
+}
+
+void Point::dump()
+{
+ OSL_TRACE( "dgm: pt cnxId %s, modelId %s",
+ OUSTRING_TO_CSTR( msCnxId ),
+ OUSTRING_TO_CSTR( msModelId ) );
+}
+
+
+}
+
+
+DiagramData::DiagramData()
+ : mpFillProperties( new FillProperties( ) )
+{
+}
+
+void DiagramData::dump()
+{
+ OSL_TRACE("Dgm: DiagramData # of cnx: %d", maConnections.size() );
+ std::for_each( maConnections.begin(), maConnections.end(),
+ boost::bind( &dgm::Connection::dump, _1 ) );
+ OSL_TRACE("Dgm: DiagramData # of pt: %d", maPoints.size() );
+ std::for_each( maPoints.begin(), maPoints.end(),
+ boost::bind( &dgm::Point::dump, _1 ) );
+}
+
+
+void Diagram::setData( const DiagramDataPtr & pData)
+{
+ mpData = pData;
+}
+
+
+void Diagram::setLayout( const DiagramLayoutPtr & pLayout)
+{
+ mpLayout = pLayout;
+}
+
+void Diagram::setQStyles( const DiagramQStylesPtr & pStyles)
+{
+ mpQStyles = pStyles;
+}
+
+
+void Diagram::setColors( const DiagramColorsPtr & pColors)
+{
+ mpColors = pColors;
+}
+
+
+void Diagram::addTo( const ShapePtr & pShape )
+{
+ dgm::Points & aPoints( mpData->getPoints( ) );
+ std::for_each( aPoints.begin(), aPoints.end(),
+ boost::bind( &Shape::addChild, boost::ref( pShape ),
+ boost::bind( &dgm::Point::getShape, _1 ) ) );
+
+ OSL_TRACE( "Dgm: addTo() # of childs %d", pShape->getChilds().size() );
+ for( std::vector< ShapePtr >::iterator iter = pShape->getChilds().begin();
+ iter != pShape->getChilds().end(); ++iter)
+ {
+ OSL_TRACE( "Dgm: shape name %s", OUSTRING_TO_CSTR( (*iter)->getName() ) );
+ }
+}
+
+
+} }
diff --git a/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx
new file mode 100644
index 000000000000..d8d246efa3c2
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: diagramdefinitioncontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:57 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/core/skipcontext.hxx"
+#include "layoutnodecontext.hxx"
+#include "diagramdefinitioncontext.hxx"
+#include "oox/drawingml/diagram/datamodelcontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml {
+
+
+// CT_DiagramDefinition
+DiagramDefinitionContext::DiagramDefinitionContext( const FragmentHandlerRef& xHandler,
+ const Reference< XFastAttributeList >& xAttributes,
+ const DiagramLayoutPtr &pLayout )
+ : Context( xHandler )
+ , mpLayout( pLayout )
+{
+ OSL_TRACE( "OOX: DiagramDefinitionContext::DiagramDefinitionContext()" );
+ mpLayout->setDefStyle( xAttributes->getOptionalValue( XML_defStyle ) );
+ OUString sValue = xAttributes->getOptionalValue( XML_minVer );
+ if( sValue.getLength() == 0 )
+ {
+ sValue = CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/diagram" );
+ }
+ mpLayout->setMinVer( sValue );
+ mpLayout->setUniqueId( xAttributes->getOptionalValue( XML_uniqueId ) );
+}
+
+
+DiagramDefinitionContext::~DiagramDefinitionContext()
+{
+ mpLayout->getNode()->dump(0);
+}
+
+void SAL_CALL DiagramDefinitionContext::endFastElement( ::sal_Int32 )
+ throw (SAXException, RuntimeException)
+{
+
+}
+
+
+Reference< XFastContextHandler > SAL_CALL
+DiagramDefinitionContext::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_DIAGRAM|XML_title:
+ mpLayout->setTitle( xAttribs->getOptionalValue( XML_val ) );
+ break;
+ case NMSP_DIAGRAM|XML_desc:
+ mpLayout->setDesc( xAttribs->getOptionalValue( XML_val ) );
+ break;
+ case NMSP_DIAGRAM|XML_layoutNode:
+ mpLayout->getNode().reset( new LayoutNode() );
+ xRet.set( new LayoutNodeContext( getHandler(), xAttribs, mpLayout->getNode() ) );
+ break;
+ case NMSP_DIAGRAM|XML_clrData:
+ // TODO, does not matter for the UI. skip.
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ case NMSP_DIAGRAM|XML_sampData:
+ mpLayout->getSampData().reset( new DiagramData );
+ xRet.set( new DataModelContext( getHandler(), mpLayout->getSampData() ) );
+ break;
+ case NMSP_DIAGRAM|XML_styleData:
+ mpLayout->getStyleData().reset( new DiagramData );
+ xRet.set( new DataModelContext( getHandler(), mpLayout->getStyleData() ) );
+ break;
+ case NMSP_DIAGRAM|XML_cat:
+ case NMSP_DIAGRAM|XML_catLst:
+ // TODO, does not matter for the UI
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+}
+
+
+} }
diff --git a/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx b/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx
new file mode 100644
index 000000000000..7931f5357e45
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: diagramdefinitioncontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:57 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_DIAGRAMDEFINITIONCONTEXT_HXX
+#define OOX_DRAWINGML_DIAGRAMDEFINITIONCONTEXT_HXX
+
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/core/context.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+
+namespace oox { namespace drawingml {
+
+class DiagramDefinitionContext : public ::oox::core::Context
+{
+public:
+ DiagramDefinitionContext( const ::oox::core::FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, const DiagramLayoutPtr &pLayout );
+ virtual ~DiagramDefinitionContext();
+
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ DiagramLayoutPtr mpLayout;
+};
+
+} }
+
+#endif
diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
new file mode 100644
index 000000000000..1a9646323794
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: diagramfragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/diagram/diagramfragmenthandler.hxx"
+#include "oox/drawingml/diagram/datamodelcontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "diagramdefinitioncontext.hxx"
+
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml {
+
+DiagramDataFragmentHandler::DiagramDataFragmentHandler( const XmlFilterRef& xFilter,
+ const OUString& rFragmentPath,
+ const DiagramDataPtr pDataPtr )
+ throw( )
+ : FragmentHandler( xFilter, rFragmentPath )
+ , mpDataPtr( pDataPtr )
+{
+}
+
+DiagramDataFragmentHandler::~DiagramDataFragmentHandler( ) throw ()
+{
+
+}
+
+void SAL_CALL DiagramDataFragmentHandler::endDocument()
+ throw (SAXException, RuntimeException)
+{
+
+}
+
+
+Reference< XFastContextHandler > SAL_CALL
+DiagramDataFragmentHandler::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& )
+ throw ( SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_DIAGRAM|XML_dataModel:
+ xRet.set( new DataModelContext( this, mpDataPtr ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+///////////////////
+
+DiagramLayoutFragmentHandler::DiagramLayoutFragmentHandler( const XmlFilterRef& xFilter,
+ const OUString& rFragmentPath,
+ const DiagramLayoutPtr pDataPtr )
+ throw( )
+ : FragmentHandler( xFilter, rFragmentPath )
+ , mpDataPtr( pDataPtr )
+{
+}
+
+DiagramLayoutFragmentHandler::~DiagramLayoutFragmentHandler( ) throw ()
+{
+
+}
+
+void SAL_CALL DiagramLayoutFragmentHandler::endDocument()
+ throw (SAXException, RuntimeException)
+{
+
+}
+
+
+Reference< XFastContextHandler > SAL_CALL
+DiagramLayoutFragmentHandler::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_DIAGRAM|XML_layoutDef:
+ xRet.set( new DiagramDefinitionContext( this, xAttribs,
+ mpDataPtr ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+///////////////////////
+
+DiagramQStylesFragmentHandler::DiagramQStylesFragmentHandler( const XmlFilterRef& xFilter,
+ const OUString& rFragmentPath,
+ const DiagramQStylesPtr pDataPtr )
+ throw( )
+ : FragmentHandler( xFilter, rFragmentPath )
+ , mpDataPtr( pDataPtr )
+{
+}
+
+DiagramQStylesFragmentHandler::~DiagramQStylesFragmentHandler( ) throw ()
+{
+
+}
+
+void SAL_CALL DiagramQStylesFragmentHandler::endDocument()
+ throw (SAXException, RuntimeException)
+{
+
+}
+
+
+Reference< XFastContextHandler > SAL_CALL
+DiagramQStylesFragmentHandler::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& )
+ throw ( SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_DIAGRAM|XML_styleDef:
+ // TODO
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+/////////////////////
+
+DiagramColorsFragmentHandler::DiagramColorsFragmentHandler( const XmlFilterRef& xFilter,
+ const OUString& rFragmentPath,
+ const DiagramColorsPtr pDataPtr )
+ throw( )
+ : FragmentHandler( xFilter, rFragmentPath )
+ , mpDataPtr( pDataPtr )
+{
+}
+
+DiagramColorsFragmentHandler::~DiagramColorsFragmentHandler( ) throw ()
+{
+
+}
+
+void SAL_CALL DiagramColorsFragmentHandler::endDocument()
+ throw (SAXException, RuntimeException)
+{
+
+}
+
+
+Reference< XFastContextHandler > SAL_CALL
+DiagramColorsFragmentHandler::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& )
+ throw ( SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_DIAGRAM|XML_colorsDef:
+ // TODO
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+
+
+
+} }
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
new file mode 100644
index 000000000000..81d7631befc2
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: diagramlayoutatoms.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/diagram/diagramlayoutatoms.hxx"
+
+#include <functional>
+#include <boost/bind.hpp>
+
+#include "oox/helper/attributelist.hxx"
+#include "layoutnodecontext.hxx"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::oox::core;
+
+namespace oox { namespace drawingml {
+
+
+IteratorAttr::IteratorAttr( )
+ : mnAxis( 0 )
+ , mnCnt( 0 )
+ , mbHideLastTrans( false )
+ , mnPtType( 0 )
+ , mnSt( 0 )
+ , mnStep( 1 )
+{
+}
+
+void IteratorAttr::loadFromXAttr( const Reference< XFastAttributeList >& xAttr )
+{
+ AttributeList attr( xAttr );
+ mnAxis = xAttr->getOptionalValueToken( XML_axis, 0 );
+ mnCnt = attr.getInteger( XML_cnt, 0 );
+ mbHideLastTrans = attr.getBool( XML_hideLastTrans, false );
+ mnPtType = xAttr->getOptionalValueToken( XML_ptType, 0 );
+ mnSt = attr.getInteger( XML_st, 0 );
+ mnStep = attr.getInteger( XML_step, 1 );
+}
+
+
+
+ConditionAttr::ConditionAttr()
+ : mnFunc( 0 )
+ , mnArg( 0 )
+ , mnOp( 0 )
+{
+
+}
+
+
+void ConditionAttr::loadFromXAttr( const Reference< XFastAttributeList >& xAttr )
+{
+ mnFunc = xAttr->getOptionalValueToken( XML_func, 0 );
+ // mnArg will be -1 for "none" or any other unknown value
+ mnArg = LayoutNodeContext::tagToVarIdx( xAttr->getOptionalValueToken( XML_arg, XML_none ) );
+ mnOp = xAttr->getOptionalValueToken( XML_op, 0 );
+ msVal = xAttr->getOptionalValue( XML_val );
+}
+
+
+void LayoutAtom::dump(int level)
+{
+ OSL_TRACE( "level = %d - %s of type %s", level,
+ OUSTRING_TO_CSTR( msName ),
+ typeid(*this).name() );
+ std::for_each( mpChildNodes.begin(), mpChildNodes.end(),
+ boost::bind( &LayoutAtom::dump, _1, level + 1 ) );
+}
+
+
+void ForEachAtom::processAtom()
+{
+ // TODO there is likely some conditions
+ std::for_each( mpChildNodes.begin(), mpChildNodes.end(),
+ boost::bind( &LayoutAtom::processAtom, _1 ) );
+}
+
+/** call ConditionAtom::test() if pAtom is one
+ * if it is not a ConditionAtom, then return false.
+ */
+static bool _test_atom( const LayoutAtomPtr & pAtom)
+{
+ try {
+ bool bResult = false;
+ const ConditionAtomPtr pCond = boost::dynamic_pointer_cast< ConditionAtom >(pAtom);
+ if( pCond )
+ {
+ bResult = pCond->test();
+ }
+ return bResult;
+ }
+ catch(...)
+ {
+ }
+ return false;
+}
+
+void ChooseAtom::processAtom()
+{
+ std::vector< LayoutAtomPtr >::iterator
+ iter = std::find_if( mpChildNodes.begin(), mpChildNodes.end(),
+ boost::bind( &_test_atom, _1 ) );
+ if( iter != mpChildNodes.end() )
+ {
+ // TODO do something
+ (*iter)->processAtom();
+ }
+}
+
+bool ConditionAtom::test()
+{
+ // TODO
+ return false;
+}
+
+
+} }
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx b/oox/source/drawingml/diagram/layoutnodecontext.cxx
new file mode 100644
index 000000000000..eb070fba70f3
--- /dev/null
+++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx
@@ -0,0 +1,368 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutnodecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "layoutnodecontext.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/skipcontext.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+#include "oox/drawingml/shapecontext.hxx"
+#include "diagramdefinitioncontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml {
+
+class IfContext
+ : public LayoutNodeContext
+{
+public:
+ IfContext( const FragmentHandlerRef& xHandler,
+ const Reference< XFastAttributeList >& xAttribs,
+ const LayoutAtomPtr & pNode )
+ : LayoutNodeContext( xHandler, xAttribs, pNode )
+ {
+ ConditionAtomPtr pAtom( boost::dynamic_pointer_cast< ConditionAtom >(pNode) );
+ OSL_ENSURE( pAtom, "Must pass a ConditionAtom" );
+
+ pAtom->iterator().loadFromXAttr( xAttribs );
+ pAtom->cond().loadFromXAttr( xAttribs );
+ }
+};
+
+
+
+class AlgorithmContext
+ : public Context
+{
+public:
+ AlgorithmContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
+ : Context( xHandler )
+ , mnRevision( 0 )
+ , mnType( 0 )
+ , mpNode( pNode )
+ {
+ AttributeList aAttribs( xAttribs );
+ mnRevision = aAttribs.getInteger( XML_rev, 0 );
+ mnType = xAttribs->getOptionalValueToken( XML_type, 0 );
+ }
+
+private:
+ sal_Int32 mnRevision;
+ sal_Int32 mnType;
+ LayoutAtomPtr mpNode;
+};
+
+
+class ChooseContext
+ : public Context
+{
+public:
+ ChooseContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
+ : Context( xHandler )
+ , mbHasElse( false )
+ , mpNode( pNode )
+ {
+ msName = xAttribs->getOptionalValue( XML_name );
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case XML_if:
+ {
+ // CT_When
+ LayoutAtomPtr pAtom( new ConditionAtom( false ) );
+ mpNode->addChild( pAtom );
+ xRet.set( new IfContext( getHandler(), xAttribs, pAtom ) );
+ break;
+ }
+ case XML_else:
+ // CT_Otherwise
+ if( !mbHasElse )
+ {
+ LayoutAtomPtr pAtom( new ConditionAtom( true ) );
+ mpNode->addChild( pAtom );
+ xRet.set( new IfContext( getHandler(), xAttribs, pAtom ) );
+ mbHasElse = true;
+ }
+ else
+ {
+ OSL_TRACE( "ignoring second else clause" );
+ }
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+ }
+private:
+ bool mbHasElse;
+ OUString msName;
+ LayoutAtomPtr mpNode;
+};
+
+
+
+
+class ForEachContext
+ : public LayoutNodeContext
+{
+public:
+ ForEachContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
+ : LayoutNodeContext( xHandler, xAttribs, pNode )
+ {
+ ForEachAtomPtr pAtom( boost::dynamic_pointer_cast< ForEachAtom >(pNode) );
+ OSL_ENSURE( pAtom, "Must pass a ForEachAtom" );
+ xAttribs->getOptionalValue( XML_ref );
+
+ pAtom->iterator().loadFromXAttr( xAttribs );
+ }
+};
+
+
+// CT_LayoutVariablePropertySet
+class LayoutVariablePropertySetContext
+ : public Context
+{
+public:
+ LayoutVariablePropertySetContext( const FragmentHandlerRef& xHandler,
+ LayoutNode::VarMap & aVar )
+ : Context( xHandler )
+ , mVariables( aVar )
+ {
+ }
+
+ virtual ~LayoutVariablePropertySetContext()
+ {
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ sal_Int32 nIdx = LayoutNodeContext::tagToVarIdx( aElement & ( ~NMSP_MASK ) );
+ if( nIdx != -1 )
+ {
+ mVariables[ nIdx ] = makeAny( xAttribs->getOptionalValue( XML_val ) );
+ }
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+ }
+private:
+ LayoutNode::VarMap & mVariables;
+};
+
+
+// CT_LayoutNode
+LayoutNodeContext::LayoutNodeContext( const FragmentHandlerRef& xHandler,
+ const Reference< XFastAttributeList >& xAttribs,
+ const LayoutAtomPtr &pNode )
+ : Context( xHandler )
+ , mpNode( pNode )
+{
+ OSL_ENSURE( pNode, "Node must NOT be NULL" );
+ mpNode->setName( xAttribs->getOptionalValue( XML_name ) );
+ // TODO shall we even bother?
+ // b or t
+// sal_Int32 nChOrder = xAttributes->getOptionalValueToken( XML_chOrder, XML_b );
+// OUString sMoveWith = xAttributes->getOptionalValue( XML_moveWith );
+// OUString sStyleLbl = xAttributes->getOptionalValue( XML_styleLbl );
+}
+
+
+LayoutNodeContext::~LayoutNodeContext()
+{
+}
+
+void SAL_CALL LayoutNodeContext::endFastElement( ::sal_Int32 )
+ throw (SAXException, RuntimeException)
+{
+
+}
+
+/** convert the XML tag to a variable index in the array
+ * @param aTag the tag, wihout namespace
+ * @return the variable index. -1 is an error
+ */
+sal_Int32 LayoutNodeContext::tagToVarIdx( sal_Int32 aTag )
+{
+ sal_Int32 nIdx = -1;
+ switch( aTag )
+ {
+ case NMSP_DIAGRAM|XML_animLvl:
+ nIdx = LayoutNode::VAR_animLvl;
+ break;
+ case NMSP_DIAGRAM|XML_animOne:
+ nIdx = LayoutNode::VAR_animOne;
+ break;
+ case NMSP_DIAGRAM|XML_bulletEnabled:
+ nIdx = LayoutNode::VAR_bulletEnabled;
+ break;
+ case NMSP_DIAGRAM|XML_chMax:
+ nIdx = LayoutNode::VAR_chMax;
+ break;
+ case NMSP_DIAGRAM|XML_chPref:
+ nIdx = LayoutNode::VAR_chPref;
+ break;
+ case NMSP_DIAGRAM|XML_dir:
+ nIdx = LayoutNode::VAR_dir;
+ break;
+ case NMSP_DIAGRAM|XML_hierBranch:
+ nIdx = LayoutNode::VAR_hierBranch;
+ break;
+ case NMSP_DIAGRAM|XML_orgChart:
+ nIdx = LayoutNode::VAR_orgChart;
+ break;
+ case NMSP_DIAGRAM|XML_resizeHandles:
+ nIdx = LayoutNode::VAR_resizeHandles;
+ break;
+ default:
+ break;
+ }
+ return nIdx;
+}
+
+
+Reference< XFastContextHandler > SAL_CALL
+LayoutNodeContext::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_DIAGRAM|XML_layoutNode:
+ {
+ LayoutNodePtr pNode( new LayoutNode() );
+ mpNode->addChild( pNode );
+ xRet.set( new LayoutNodeContext( getHandler(), xAttribs, pNode ) );
+ break;
+ }
+ case NMSP_DIAGRAM|XML_shape:
+ {
+ ShapePtr pShape( new Shape() );
+ xRet.set( new ShapeContext( getHandler(), ShapePtr( ( Shape* )NULL ), pShape ) );
+ break;
+ }
+ case NMSP_DIAGRAM|XML_extLst:
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ case NMSP_DIAGRAM|XML_alg:
+ {
+ // CT_Algorithm
+ LayoutAtomPtr pAtom( new AlgAtom );
+ mpNode->addChild( pAtom );
+ xRet.set( new AlgorithmContext( getHandler(), xAttribs, pAtom ) );
+ break;
+ }
+ case NMSP_DIAGRAM|XML_choose:
+ {
+ // CT_Choose
+ LayoutAtomPtr pAtom( new ChooseAtom );
+ mpNode->addChild( pAtom );
+ xRet.set( new ChooseContext( getHandler(), xAttribs, pAtom ) );
+ break;
+ }
+ case NMSP_DIAGRAM|XML_forEach:
+ {
+ // CT_ForEach
+ LayoutAtomPtr pAtom( new ForEachAtom );
+ mpNode->addChild( pAtom );
+ xRet.set( new ForEachContext( getHandler(), xAttribs, pAtom ) );
+ break;
+ }
+ case NMSP_DIAGRAM|XML_constrLst:
+ // CT_Constraints
+ // TODO
+ break;
+ case NMSP_DIAGRAM|XML_presOf:
+ {
+ // CT_PresentationOf
+ // TODO
+ xAttribs->getOptionalValue( XML_axis );
+ xAttribs->getOptionalValue( XML_cnt );
+ xAttribs->getOptionalValue( XML_hideLastTrans );
+ xAttribs->getOptionalValue( XML_ptType );
+ xAttribs->getOptionalValue( XML_st );
+ xAttribs->getOptionalValue( XML_step );
+ break;
+ }
+ case NMSP_DIAGRAM|XML_ruleLst:
+ // CT_Rules
+ // TODO
+ break;
+ case NMSP_DIAGRAM|XML_varLst:
+ {
+ LayoutNodePtr pNode( boost::dynamic_pointer_cast< LayoutNode >( mpNode ) );
+ if( pNode )
+ {
+ xRet.set( new LayoutVariablePropertySetContext( getHandler(),
+ pNode->variables() ) );
+ }
+ else
+ {
+ OSL_TRACE( "OOX: encountered a varLst in a non layoutNode context" );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+}
+
+
+} }
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.hxx b/oox/source/drawingml/diagram/layoutnodecontext.hxx
new file mode 100644
index 000000000000..90ad860a98f5
--- /dev/null
+++ b/oox/source/drawingml/diagram/layoutnodecontext.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutnodecontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_LAYOUTNODECONTEXT_HXX
+#define OOX_DRAWINGML_LAYOUTNODECONTEXT_HXX
+
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/core/context.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+
+namespace oox { namespace drawingml {
+
+class LayoutNodeContext : public ::oox::core::Context
+{
+public:
+ LayoutNodeContext( const ::oox::core::FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, const LayoutAtomPtr &pNode );
+ virtual ~LayoutNodeContext();
+
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ static ::sal_Int32 tagToVarIdx( ::sal_Int32 aTag );
+private:
+ LayoutAtomPtr mpNode;
+};
+
+} }
+
+#endif
diff --git a/oox/source/drawingml/diagram/makefile.mk b/oox/source/drawingml/diagram/makefile.mk
new file mode 100644
index 000000000000..d2a1bf63d5d8
--- /dev/null
+++ b/oox/source/drawingml/diagram/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=oox
+TARGET=diagram
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/diagram.obj \
+ $(SLO)$/diagramfragmenthandler.obj \
+ $(SLO)$/diagramdefinitioncontext.obj \
+ $(SLO)$/diagramlayoutatoms.obj \
+ $(SLO)$/datamodelcontext.obj \
+ $(SLO)$/layoutnodecontext.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/drawingml/drawingmltypes.cxx b/oox/source/drawingml/drawingmltypes.cxx
new file mode 100644
index 000000000000..7d5f15c899ec
--- /dev/null
+++ b/oox/source/drawingml/drawingmltypes.cxx
@@ -0,0 +1,433 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: drawingmltypes.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/drawingmltypes.hxx"
+
+#include <com/sun/star/awt/FontPitch.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/style/TabAlign.hpp>
+#include <com/sun/star/style/CaseMap.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+
+#include <sax/tools/converter.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/shape.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::style;
+using namespace ::oox::core;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// --------------------------------------------------------------------
+
+/** converts an emu string into 1/100th mmm but constrain as per ST_TextMargin
+ * see 5.1.12.73
+ */
+sal_Int32 GetTextMargin( const ::rtl::OUString& sValue )
+{
+ sal_Int32 nRet = 0;
+ if( !::sax::Converter::convertNumber( nRet, sValue ) )
+ nRet = 0;
+ else if( nRet < 0 )
+ nRet = 0;
+ else if( nRet > 51206400 )
+ nRet = 51206400;
+
+ nRet /= 360;
+ return nRet;
+}
+
+/** converts an emu string into 1/100th mmm */
+sal_Int32 GetCoordinate( const ::rtl::OUString& sValue )
+{
+ sal_Int32 nRet = 0;
+ if( !::sax::Converter::convertNumber( nRet, sValue ) )
+ nRet = 0;
+
+ nRet /= 360;
+ return nRet;
+}
+
+/** converts a ST_Percentage % string into 1/1000th of % */
+sal_Int32 GetPercent( const ::rtl::OUString& sValue )
+{
+ sal_Int32 nRet = 0;
+ if( !::sax::Converter::convertNumber( nRet, sValue ) )
+ nRet = 0;
+
+ return nRet;
+}
+
+double GetPositiveFixedPercentage( const ::rtl::OUString& sValue )
+{
+ double fPercent = sValue.toFloat() / 100000.;
+ return fPercent;
+}
+
+// --------------------------------------------------------------------
+
+/** converts the attributes from an CT_Point2D into an awt Point with 1/100thmm */
+::com::sun::star::awt::Point GetPoint2D( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
+{
+ return ::com::sun::star::awt::Point( GetCoordinate( xAttribs->getOptionalValue( XML_x ) ), GetCoordinate( xAttribs->getOptionalValue( XML_y ) ) );
+}
+
+/** converts the attributes from an CT_TLPoint into an awt Point with 1/1000% */
+::com::sun::star::awt::Point GetPointPercent( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
+{
+ return ::com::sun::star::awt::Point( GetPercent( xAttribs->getOptionalValue( XML_x ) ), GetCoordinate( xAttribs->getOptionalValue( XML_y ) ) );
+}
+
+// --------------------------------------------------------------------
+
+/** converts the ST_TextFontSize to point */
+float GetTextSize( const ::rtl::OUString& sValue )
+{
+ float fRet = 0;
+ sal_Int32 nRet;
+ if( ::sax::Converter::convertNumber( nRet, sValue ) )
+ fRet = static_cast< float >( static_cast< double >( nRet ) / 100.0 );
+ return fRet;
+}
+
+
+/** converts the ST_TextSpacingPoint to 1/100mm */
+sal_Int32 GetTextSpacingPoint( const ::rtl::OUString& sValue )
+{
+ sal_Int32 nRet;
+ if( ::sax::Converter::convertNumber( nRet, sValue ) )
+ nRet = ( nRet * 254 + 360 ) / 720;
+ return nRet;
+}
+
+
+sal_Int16 GetFontUnderline( ::sal_Int32 nToken )
+{
+ sal_Int16 nEnum;
+ switch( nToken )
+ {
+ case XML_none:
+ nEnum = FontUnderline::NONE;
+ break;
+ case XML_dash:
+ nEnum = FontUnderline::DASH;
+ break;
+ case XML_dashHeavy:
+ nEnum = FontUnderline::BOLDDASH;
+ break;
+ case XML_dashLong:
+ nEnum = FontUnderline::LONGDASH;
+ break;
+ case XML_dashLongHeavy:
+ nEnum = FontUnderline::BOLDLONGDASH;
+ break;
+ case XML_dbl:
+ nEnum = FontUnderline::DOUBLE;
+ break;
+ case XML_dotDash:
+ nEnum = FontUnderline::DASHDOT;
+ break;
+ case XML_dotDashHeavy:
+ nEnum = FontUnderline::BOLDDASHDOT;
+ break;
+ case XML_dotDotDash:
+ nEnum = FontUnderline::DASHDOTDOT;
+ break;
+ case XML_dotDotDashHeavy:
+ nEnum = FontUnderline::BOLDDASHDOTDOT;
+ break;
+ case XML_dotted:
+ nEnum = FontUnderline::DOTTED;
+ break;
+ case XML_dottedHeavy:
+ nEnum = FontUnderline::BOLDDOTTED;
+ break;
+ case XML_heavy:
+ nEnum = FontUnderline::BOLD;
+ break;
+ case XML_sng:
+ nEnum = FontUnderline::SINGLE;
+ break;
+ case XML_wavy:
+ nEnum = FontUnderline::WAVE;
+ break;
+ case XML_wavyDbl:
+ nEnum = FontUnderline::DOUBLEWAVE;
+ break;
+ case XML_wavyHeavy:
+ nEnum = FontUnderline::BOLDWAVE;
+ break;
+ case XML_words:
+ // TODO
+ default:
+ nEnum = FontUnderline::DONTKNOW;
+ break;
+ }
+ return nEnum;
+}
+
+sal_Int16 GetFontStrikeout( sal_Int32 nToken )
+{
+ sal_Int16 nEnum;
+ switch( nToken )
+ {
+ case XML_dblStrike:
+ nEnum = FontStrikeout::DOUBLE;
+ break;
+ case XML_noStrike:
+ nEnum = FontStrikeout::NONE;
+ break;
+ case XML_sngStrike:
+ nEnum = FontStrikeout::SINGLE;
+ break;
+ default:
+ nEnum = FontStrikeout::DONTKNOW;
+ break;
+ }
+ return nEnum;
+}
+
+sal_Int16 GetCaseMap( sal_Int32 nToken )
+{
+ sal_Int16 nEnum;
+ switch( nToken )
+ {
+ case XML_all:
+ nEnum = CaseMap::UPPERCASE;
+ break;
+ case XML_small:
+ nEnum = CaseMap::SMALLCAPS;
+ break;
+ case XML_none:
+ // fall through
+ default:
+ nEnum = CaseMap::NONE;
+ break;
+ }
+ return nEnum;
+}
+
+// BEGIN stolen from sd/source/filter/eppt/epptso.cxx
+/* Font Families */
+#define FF_DONTCARE 0x00
+#define FF_ROMAN 0x10
+#define FF_SWISS 0x20
+#define FF_MODERN 0x30
+#define FF_SCRIPT 0x40
+#define FF_DECORATIVE 0x50
+
+/* Font pitches */
+#define DEFAULT_PITCH 0x00
+#define FIXED_PITCH 0x01
+#define VARIABLE_PITCH 0x02
+
+// END
+
+void GetFontPitch( sal_Int32 nOoxValue, sal_Int16 & nPitch, sal_Int16 & nFamily )
+{
+ sal_Int32 oFamily = ( nOoxValue & 0xf0 );
+ sal_Int32 oPitch = ( nOoxValue & 0x0f );
+ switch( oFamily )
+ {
+ case FF_ROMAN:
+ nFamily = FontFamily::ROMAN;
+ break;
+ case FF_SWISS:
+ nFamily = FontFamily::SWISS;
+ break;
+ case FF_MODERN:
+ nFamily = FontFamily::MODERN;
+ break;
+ case FF_SCRIPT:
+ nFamily = FontFamily::SCRIPT;
+ break;
+ case FF_DECORATIVE:
+ nFamily = FontFamily::DECORATIVE;
+ break;
+ default:
+ nFamily = FontFamily::DONTKNOW;
+ break;
+ }
+ switch( oPitch )
+ {
+ case FIXED_PITCH:
+ nPitch = FontPitch::FIXED;
+ break;
+ case VARIABLE_PITCH:
+ nPitch = FontPitch::VARIABLE;
+ break;
+ case DEFAULT_PITCH:
+ default:
+ nPitch = FontPitch::DONTKNOW;
+ break;
+ }
+}
+
+/** converts a paragraph align to a ParaAdjust */
+sal_Int16 GetParaAdjust( sal_Int32 nAlign )
+{
+ sal_Int16 nEnum;
+ switch( nAlign )
+ {
+ case XML_ctr:
+ nEnum = ParagraphAdjust_CENTER;
+ break;
+ case XML_just:
+ case XML_justLow:
+ nEnum = ParagraphAdjust_BLOCK;
+ break;
+ case XML_r:
+ nEnum = ParagraphAdjust_RIGHT;
+ break;
+ case XML_thaiDist:
+ case XML_dist:
+ nEnum = ParagraphAdjust_STRETCH;
+ break;
+ case XML_l:
+ default:
+ nEnum = ParagraphAdjust_LEFT;
+ break;
+ }
+ return nEnum;
+}
+
+
+TabAlign GetTabAlign( sal_Int32 aToken )
+{
+ TabAlign nEnum;
+ switch( aToken )
+ {
+ case XML_ctr:
+ nEnum = TabAlign_CENTER;
+ break;
+ case XML_dec:
+ nEnum = TabAlign_DECIMAL;
+ break;
+ case XML_l:
+ nEnum = TabAlign_LEFT;
+ break;
+ case XML_r:
+ nEnum = TabAlign_RIGHT;
+ break;
+ default:
+ nEnum = TabAlign_DEFAULT;
+ break;
+ }
+ return nEnum;
+}
+
+// --------------------------------------------------------------------
+
+/** converts the attributes from a CT_RelativeRect to an IntegerRectangle2D */
+com::sun::star::geometry::IntegerRectangle2D GetRelativeRect( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
+{
+ com::sun::star::geometry::IntegerRectangle2D r;
+
+ r.X1 = xAttribs->getOptionalValue( XML_l ).toInt32();
+ r.Y1 = xAttribs->getOptionalValue( XML_t ).toInt32();
+ r.X2 = xAttribs->getOptionalValue( XML_r ).toInt32();
+ r.Y2 = xAttribs->getOptionalValue( XML_b ).toInt32();
+
+ return r;
+}
+
+// --------------------------------------------------------------------
+
+/** converts the attributes from an CT_Size2D into an awt Size with 1/100thmm */
+::com::sun::star::awt::Size GetSize2D( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs )
+{
+ return ::com::sun::star::awt::Size( GetCoordinate( xAttribs->getOptionalValue( XML_cx ) ), GetCoordinate( xAttribs->getOptionalValue( XML_cy ) ) );
+}
+
+
+
+
+IndexRange GetIndexRange( const Reference< XFastAttributeList >& xAttributes )
+{
+ IndexRange range;
+ range.start = xAttributes->getOptionalValue( XML_st ).toInt32();
+ range.end = xAttributes->getOptionalValue( XML_end ).toInt32();
+ return range;
+}
+
+
+// --------------------------------------------------------------------
+
+/** context to import a CT_Transform2D */
+Transform2DContext::Transform2DContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs, ::oox::drawingml::Shape& rShape ) throw()
+: Context( xHandler )
+, mrShape( rShape )
+{
+ AttributeList aAttributeList( xAttribs );
+ mrShape.setRotation( aAttributeList.getInteger( XML_rot, 0 ) ); // 60000ths of a degree Positive angles are clockwise; negative angles are counter-clockwise
+ mrShape.setFlip( aAttributeList.getBool( XML_flipH, sal_False ), aAttributeList.getBool( XML_flipV, sal_False ) );
+}
+
+void Transform2DContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+Reference< XFastContextHandler > Transform2DContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_off: // horz/vert translation
+ mrShape.setPosition( Point( xAttribs->getOptionalValue( XML_x ).toInt32(), xAttribs->getOptionalValue( XML_y ).toInt32() ) );
+ break;
+ case NMSP_DRAWINGML|XML_ext: // horz/vert size
+ mrShape.setSize( Size( xAttribs->getOptionalValue( XML_cx ).toInt32(), xAttribs->getOptionalValue( XML_cy ).toInt32() ) );
+ break;
+/* todo: what to do?
+ case NMSP_DRAWINGML|XML_chOff: // horz/vert translation of children
+ case NMSP_DRAWINGML|XML_chExt: // horz/vert size of children
+ break;
+*/
+ }
+
+ Reference< XFastContextHandler > xEmpty;
+ return xEmpty;
+}
+
+
+} }
diff --git a/oox/source/drawingml/embeddedwavaudiofile.cxx b/oox/source/drawingml/embeddedwavaudiofile.cxx
new file mode 100644
index 000000000000..e9631b91c0dd
--- /dev/null
+++ b/oox/source/drawingml/embeddedwavaudiofile.cxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: embeddedwavaudiofile.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/embeddedwavaudiofile.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+
+namespace oox { namespace drawingml {
+
+
+ // CT_EmbeddedWAVAudioFile
+ void getEmbeddedWAVAudioFile( const FragmentHandlerRef &xHandler, const Reference< XFastAttributeList >& xAttribs,
+ EmbeddedWAVAudioFile & aAudio )
+ {
+ AttributeList attribs(xAttribs);
+
+ OUString sId = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_embed );
+ aAudio.msLink = xHandler->getRelations().getTargetFromRelId( sId );
+ aAudio.mbBuiltIn = attribs.getBool( XML_builtIn, false );
+ aAudio.msName = xAttribs->getOptionalValue( XML_name );
+ }
+
+
+} }
diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx
new file mode 100644
index 000000000000..562eb35f22aa
--- /dev/null
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fillproperties.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <comphelper/processfactory.hxx>
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XGraphicTransformer.hpp>
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::graphic;
+
+namespace oox { namespace drawingml {
+
+FillProperties::FillProperties( sal_Int32 nContext )
+: mnContext( nContext )
+, maFillColor( new Color() )
+{
+}
+FillProperties::~FillProperties()
+{
+}
+
+void FillProperties::apply( const FillPropertiesPtr& rSourceFillProperties )
+{
+ maFillProperties.insert( rSourceFillProperties->maFillProperties.begin(), rSourceFillProperties->maFillProperties.end() );
+ if ( rSourceFillProperties->maFillColor->isUsed() )
+ maFillColor = rSourceFillProperties->maFillColor;
+}
+
+void FillProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XPropertySet >& xPropSet ) const
+{
+ PropertySet aPropSet( xPropSet );
+ Sequence< OUString > aNames;
+ Sequence< Any > aValues;
+
+ maFillProperties.makeSequence( aNames, aValues );
+ aPropSet.setProperties( aNames, aValues );
+ if ( maFillColor->isUsed() )
+ {
+ const rtl::OUString sFillColor( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) );
+ xPropSet->setPropertyValue( sFillColor, Any( maFillColor->getColor( rFilterBase ) ) );
+ }
+ createTransformedGraphic( rFilterBase, xPropSet );
+}
+
+void FillProperties::createTransformedGraphic( const oox::core::XmlFilterBase& rFilterBase, const Reference < XPropertySet >& xPropSet ) const
+{
+ if( mxGraphic.is() )
+ {
+ if ( mnContext == XML_pic )
+ {
+ Reference< XGraphic > xGraphic( mxGraphic );
+ if ( maColorChangeFrom.get() && maColorChangeTo.get() )
+ {
+ sal_Int32 nClrChangeFrom = maColorChangeFrom->getColor( rFilterBase );
+ sal_Int32 nClrChangeTo = maColorChangeTo->getColor( rFilterBase );
+ sal_Int32 nAlphaTo = maColorChangeTo->getAlpha();
+ if ( ( nClrChangeFrom != nClrChangeTo ) || ( maColorChangeTo->hasAlpha() && ( nAlphaTo != 1000000 ) ) )
+ {
+ Reference< XGraphicTransformer > xTransformer( xGraphic, UNO_QUERY );
+ if ( xTransformer.is() )
+ xGraphic = xTransformer->colorChange( xGraphic, nClrChangeFrom, 9, nClrChangeTo, static_cast< sal_Int8 >( ( nAlphaTo / 39062 ) ) );
+ }
+ }
+ static const OUString sGraphic( CREATE_OUSTRING( "Graphic" ) );
+ xPropSet->setPropertyValue( sGraphic, Any( xGraphic ) );
+ }
+ else if ( mnContext == XML_spPr )
+ {
+ static const OUString sFillBitmap( CREATE_OUSTRING( "FillBitmap" ) );
+ xPropSet->setPropertyValue( sFillBitmap, Any( mxGraphic ) );
+ }
+ }
+}
+
+} }
diff --git a/oox/source/drawingml/fillpropertiesgroupcontext.cxx b/oox/source/drawingml/fillpropertiesgroupcontext.cxx
new file mode 100644
index 000000000000..351391c7aca7
--- /dev/null
+++ b/oox/source/drawingml/fillpropertiesgroupcontext.cxx
@@ -0,0 +1,457 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fillpropertiesgroupcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::beans::NamedValue;
+using namespace ::oox::core;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// ---------------------------------------------------------------------
+
+class NoFillContext : public FillPropertiesGroupContext
+{
+public:
+ NoFillContext( const oox::core::FragmentHandlerRef& xHandler, ::oox::drawingml::FillProperties& rFillProperties ) throw();
+};
+
+// ---------------------------------------------------------------------
+
+class SolidColorFillPropertiesContext : public FillPropertiesGroupContext
+{
+public:
+ SolidColorFillPropertiesContext( const oox::core::FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, ::oox::drawingml::FillProperties& rFillProperties ) throw();
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+};
+
+// ---------------------------------------------------------------------
+
+class GradFillPropertiesContext : public FillPropertiesGroupContext
+{
+public:
+ GradFillPropertiesContext( const oox::core::FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, ::oox::drawingml::FillProperties& rFillProperties ) throw();
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException);
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+};
+
+// ---------------------------------------------------------------------
+
+class PattFillPropertiesContext : public FillPropertiesGroupContext
+{
+public:
+ PattFillPropertiesContext( const oox::core::FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, ::oox::drawingml::FillProperties& rFillProperties ) throw();
+
+ virtual void SAL_CALL startFastElement( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException);
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+};
+
+// ---------------------------------------------------------------------
+
+class GrpFillPropertiesContext : public FillPropertiesGroupContext
+{
+public:
+ GrpFillPropertiesContext( const oox::core::FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, ::oox::drawingml::FillProperties& rFillProperties ) throw();
+
+ virtual void SAL_CALL startFastElement( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException);
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+};
+
+// ---------------------------------------------------------------------
+
+class clrChangeContext : public ::oox::core::Context
+{
+ oox::drawingml::ColorPtr& mraClrFrom;
+ oox::drawingml::ColorPtr& mraClrTo;
+ sal_Bool mbUseAlpha;
+public:
+ clrChangeContext( const oox::core::FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes,
+ oox::drawingml::ColorPtr& raClrFrom, oox::drawingml::ColorPtr& raClrTo ) throw();
+ ~clrChangeContext();
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+};
+
+// ---------------------------------------------------------------------
+
+FillPropertiesGroupContext::FillPropertiesGroupContext( const FragmentHandlerRef& xHandler, ::com::sun::star::drawing::FillStyle eFillStyle, oox::drawingml::FillProperties& rFillProperties ) throw()
+: ::oox::core::Context( xHandler )
+, mrFillProperties( rFillProperties )
+{
+ static const OUString sFillStyle = CREATE_OUSTRING( "FillStyle" );
+ mrFillProperties.getFillPropertyMap()[ sFillStyle ] <<= eFillStyle;
+}
+
+// ---------------------------------------------------------------------
+
+Reference< XFastContextHandler > FillPropertiesGroupContext::StaticCreateContext( const FragmentHandlerRef& xHandler, sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs, ::oox::drawingml::FillProperties& rFillProperties )
+ throw ( SAXException, RuntimeException )
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_noFill:
+ xRet.set( new NoFillContext( xHandler, rFillProperties ) );
+ break;
+ case NMSP_DRAWINGML|XML_solidFill:
+ xRet.set( new SolidColorFillPropertiesContext( xHandler, xAttribs, rFillProperties ) );
+ break;
+ case NMSP_DRAWINGML|XML_gradFill:
+ xRet.set( new GradFillPropertiesContext( xHandler, xAttribs, rFillProperties ) );
+ break;
+ case NMSP_DRAWINGML|XML_blipFill:
+ xRet.set( new BlipFillPropertiesContext( xHandler, xAttribs, rFillProperties ) );
+ break;
+ case NMSP_DRAWINGML|XML_pattFill:
+ xRet.set( new PattFillPropertiesContext( xHandler, xAttribs, rFillProperties ) );
+ break;
+ case NMSP_DRAWINGML|XML_grpFill:
+ xRet.set( new GrpFillPropertiesContext( xHandler, xAttribs, rFillProperties ) );
+ break;
+ }
+ return xRet;
+}
+
+// ---------------------------------------------------------------------
+
+NoFillContext::NoFillContext( const FragmentHandlerRef& xHandler, oox::drawingml::FillProperties& rFillProperties ) throw()
+: FillPropertiesGroupContext( xHandler, FillStyle_NONE, rFillProperties )
+{
+}
+
+// ---------------------------------------------------------------------
+
+SolidColorFillPropertiesContext::SolidColorFillPropertiesContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >&, ::oox::drawingml::FillProperties& rFillProperties ) throw()
+: FillPropertiesGroupContext( xHandler, FillStyle_SOLID, rFillProperties )
+{
+}
+Reference< XFastContextHandler > SolidColorFillPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ // colorTransformGroup
+
+ // color should be available as rgb in member mnColor already, now modify it depending on
+ // the transformation elements
+
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+
+ case NMSP_DRAWINGML|XML_scrgbClr: // CT_ScRgbColor
+ case NMSP_DRAWINGML|XML_srgbClr: // CT_SRgbColor
+ case NMSP_DRAWINGML|XML_hslClr: // CT_HslColor
+ case NMSP_DRAWINGML|XML_sysClr: // CT_SystemColor
+ case NMSP_DRAWINGML|XML_schemeClr: // CT_SchemeColor
+ case NMSP_DRAWINGML|XML_prstClr: // CT_PresetColor
+ {
+ xRet.set( new colorChoiceContext( getHandler(), *(mrFillProperties.getFillColor().get()) ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_tint: // CT_PositiveFixedPercentage
+ case NMSP_DRAWINGML|XML_shade: // CT_PositiveFixedPercentage
+ case NMSP_DRAWINGML|XML_comp: // CT_ComplementTransform
+ case NMSP_DRAWINGML|XML_inv: // CT_InverseTransform
+ case NMSP_DRAWINGML|XML_gray: // CT_GrayscaleTransform
+ case NMSP_DRAWINGML|XML_alpha: // CT_PositiveFixedPercentage
+ case NMSP_DRAWINGML|XML_alphaOff: // CT_FixedPercentage
+ case NMSP_DRAWINGML|XML_alphaMod: // CT_PositivePercentage
+ case NMSP_DRAWINGML|XML_hue: // CT_PositiveFixedAngle
+ case NMSP_DRAWINGML|XML_hueOff: // CT_Angle
+ case NMSP_DRAWINGML|XML_hueMod: // CT_PositivePercentage
+ case NMSP_DRAWINGML|XML_sat: // CT_Percentage
+ case NMSP_DRAWINGML|XML_satOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_satMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_lum: // CT_Percentage
+ case NMSP_DRAWINGML|XML_lumOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_lumMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_red: // CT_Percentage
+ case NMSP_DRAWINGML|XML_redOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_redMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_green: // CT_Percentage
+ case NMSP_DRAWINGML|XML_greenOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_greenMod: // CT_Percentage
+ case NMSP_DRAWINGML|XML_blue: // CT_Percentage
+ case NMSP_DRAWINGML|XML_blueOff: // CT_Percentage
+ case NMSP_DRAWINGML|XML_blueMod: // CT_Percentage
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// ---------------------------------------------------------------------
+
+GradFillPropertiesContext::GradFillPropertiesContext( const FragmentHandlerRef& xHandler, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >&, ::oox::drawingml::FillProperties& rFillProperties ) throw()
+: FillPropertiesGroupContext( xHandler, FillStyle_GRADIENT, rFillProperties )
+{
+}
+
+void GradFillPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+Reference< XFastContextHandler > GradFillPropertiesContext::createFastChildContext( sal_Int32, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ return this;
+}
+
+// ---------------------------------------------------------------------
+// CT_BlipFill
+// ---------------------------------------------------------------------
+
+BlipFillPropertiesContext::BlipFillPropertiesContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >&,
+ ::oox::drawingml::FillProperties& rFillProperties )
+ throw()
+: FillPropertiesGroupContext( xHandler, FillStyle_BITMAP, rFillProperties )
+, meBitmapMode( BitmapMode_REPEAT )
+, mnWidth( 0 )
+, mnHeight( 0 )
+{
+ /* todo
+ if( xAttribs->hasAttribute( XML_dpi ) )
+ {
+ xsd:unsignedInt
+ DPI (dots per inch) used to calculate the size of the blip. If not present or zero,
+ the DPI in the blip is used.
+
+ }
+ if( xAttribs->hasAttribute( XML_rotWithShape ) )
+ {
+ xsd:boolean
+ fill should rotate with the shape
+ }
+ */
+}
+
+void BlipFillPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+ if( msEmbed.getLength() )
+ {
+ const OUString aFragmentPath = getHandler()->getFragmentPathFromRelId( msEmbed );
+ if( aFragmentPath.getLength() > 0 ) try
+ {
+ // get the input stream for the fill bitmap
+ XmlFilterRef xFilter = getHandler()->getFilter();
+ Reference< XInputStream > xInputStream( xFilter->openInputStream( aFragmentPath ), UNO_QUERY_THROW );
+
+ // load the fill bitmap into an XGraphic with the GraphicProvider
+ static const OUString sGraphicProvider = CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" );
+ Reference< XMultiServiceFactory > xMSFT( xFilter->getServiceFactory(), UNO_QUERY_THROW );
+ Reference< XGraphicProvider > xGraphicProvider( xMSFT->createInstance( sGraphicProvider ), UNO_QUERY_THROW );
+
+ static const OUString sInputStream = CREATE_OUSTRING( "InputStream" );
+ PropertyValues aMediaProperties(1);
+ aMediaProperties[0].Name = sInputStream;
+ aMediaProperties[0].Value <<= xInputStream;
+
+ Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic(aMediaProperties ) );
+ mrFillProperties.mxGraphic = xGraphic;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false,
+ (rtl::OString("oox::drawingml::BlipFillPropertiesContext::EndElement(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+
+ }
+
+ static const OUString sFillBitmapMode = CREATE_OUSTRING( "FillBitmapMode" );
+ mrFillProperties.getFillPropertyMap()[ sFillBitmapMode ] <<= meBitmapMode;
+ }
+}
+
+Reference< XFastContextHandler > BlipFillPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_blip: // CT_Blip
+// mnWidth = xAttribs.getInt32( XML_w );
+// mnHeight = xAttribs.getInt32( XML_h );
+ msEmbed = xAttribs->getOptionalValue(NMSP_RELATIONSHIPS|XML_embed); // relationship identifer for embedded blobs
+ msLink = xAttribs->getOptionalValue(NMSP_RELATIONSHIPS|XML_link); // relationship identifer for linked blobs
+ break;
+ case NMSP_DRAWINGML|XML_alphaBiLevel:
+ case NMSP_DRAWINGML|XML_alphaCeiling:
+ case NMSP_DRAWINGML|XML_alphaFloor:
+ case NMSP_DRAWINGML|XML_alphaInv:
+ case NMSP_DRAWINGML|XML_alphaMod:
+ case NMSP_DRAWINGML|XML_alphaModFix:
+ case NMSP_DRAWINGML|XML_alphaRepl:
+ case NMSP_DRAWINGML|XML_biLevel:
+ case NMSP_DRAWINGML|XML_blur:
+ break;
+ case NMSP_DRAWINGML|XML_clrChange:
+ {
+ xRet = new clrChangeContext( getHandler(), xAttribs, mrFillProperties.getColorChangeFrom(), mrFillProperties.getColorChangeTo() );
+ }
+ break;
+ case NMSP_DRAWINGML|XML_clrRepl:
+ case NMSP_DRAWINGML|XML_duotone:
+ case NMSP_DRAWINGML|XML_extLst:
+ case NMSP_DRAWINGML|XML_fillOverlay:
+ case NMSP_DRAWINGML|XML_grayscl:
+ case NMSP_DRAWINGML|XML_hsl:
+ case NMSP_DRAWINGML|XML_lum:
+ case NMSP_DRAWINGML|XML_tint:
+ break;
+
+ case NMSP_DRAWINGML|XML_srcRect: // CT_RelativeRect
+// todo maSrcRect = GetRelativeRect( xAttribs );
+ break;
+ case NMSP_DRAWINGML|XML_tile: // CT_TileInfo
+ meBitmapMode = BitmapMode_REPEAT;
+/* todo
+ mnTileX = GetCoordinate( xAttribs[ XML_tx ] ); // additional horizontal offset after alignment
+ mnTileY = GetCoordinate( xAttribs[ XML_ty ] ); // additional vertical offset after alignment
+ mnSX = xAttribs.getInt32( XML_sx, 100000 ); // amount to horizontally scale the srcRect
+ mnSX = xAttribs.getInt32( XML_sy, 100000 ); // amount to vertically scale the srcRect
+ mnFlip = xAttribs->getOptionalValueToken( XML_flip ); // ST_TileFlipMode how to flip the tile when it repeats
+ mnAlign = xAttribs->getOptionalValueToken( XML_algn ); // ST_RectAlignment where to align the first tile with respect to the shape; alignment happens after the scaling, but before the additional offset.
+*/
+ break;
+ case NMSP_DRAWINGML|XML_stretch: // CT_StretchInfo
+ meBitmapMode = BitmapMode_STRETCH;
+ break;
+ case NMSP_DRAWINGML|XML_fillRect:
+// todo maFillRect = GetRelativeRect( xAttribs );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// ---------------------------------------------------------------------
+
+PattFillPropertiesContext::PattFillPropertiesContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >&, ::oox::drawingml::FillProperties& rFillProperties ) throw()
+: FillPropertiesGroupContext( xHandler, FillStyle_HATCH, rFillProperties )
+{
+}
+
+void PattFillPropertiesContext::startFastElement( sal_Int32, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+}
+
+void PattFillPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+Reference< XFastContextHandler > PattFillPropertiesContext::createFastChildContext( sal_Int32, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ return this;
+}
+
+// ---------------------------------------------------------------------
+
+GrpFillPropertiesContext::GrpFillPropertiesContext( const FragmentHandlerRef& xHandler,const Reference< XFastAttributeList >&, ::oox::drawingml::FillProperties& rFillProperties ) throw()
+: FillPropertiesGroupContext( xHandler, FillStyle_NONE, rFillProperties )
+{
+}
+
+void GrpFillPropertiesContext::startFastElement( sal_Int32, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+}
+
+void GrpFillPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+Reference< XFastContextHandler > GrpFillPropertiesContext::createFastChildContext( sal_Int32, const Reference< XFastAttributeList >& )
+ throw (SAXException, RuntimeException)
+{
+ return this;
+}
+
+
+// ---------------------------------------------------------------------
+
+clrChangeContext::clrChangeContext( const FragmentHandlerRef& xHandler,const Reference< XFastAttributeList >& xAttributes,
+ ColorPtr& raClrFrom, ColorPtr& raClrTo ) throw()
+: Context( xHandler )
+, mraClrFrom( raClrFrom )
+, mraClrTo( raClrTo )
+, mbUseAlpha( xAttributes->getOptionalValueToken( XML_useA, XML_true ) == XML_true ? sal_True : sal_False )
+{
+ mraClrFrom = ColorPtr( new Color() );
+ mraClrTo = ColorPtr( new Color() );
+}
+clrChangeContext::~clrChangeContext()
+{
+ if ( !mbUseAlpha )
+ mraClrTo->mbAlphaColor = sal_False;
+}
+Reference< XFastContextHandler > clrChangeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_clrFrom: // CT_Color
+ xRet.set( new colorChoiceContext( getHandler(), *mraClrFrom.get() ) );
+ break;
+ case NMSP_DRAWINGML|XML_clrTo: // CT_Color
+ xRet.set( new colorChoiceContext( getHandler(), *mraClrTo.get() ) );
+ break;
+ default:
+ break;
+ }
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx
new file mode 100644
index 000000000000..c9e9de409d88
--- /dev/null
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -0,0 +1,335 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: graphicshapecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/drawingml/diagram/diagramfragmenthandler.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "tokens.hxx"
+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
+#include <comphelper/processfactory.hxx>
+#endif
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/io/XStream.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/document/XEmbeddedObjectResolver.hpp"
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// ====================================================================
+// CT_Picture
+GraphicShapeContext::GraphicShapeContext( const FragmentHandlerRef& xHandler, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
+: ShapeContext( xHandler, pMasterShapePtr, pShapePtr )
+{
+}
+
+Reference< XFastContextHandler > GraphicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken &(~NMSP_MASK) )
+ {
+ // CT_ShapeProperties
+ case XML_xfrm:
+ xRet.set( new Transform2DContext( getHandler(), xAttribs, *(mpShapePtr.get()) ) );
+ break;
+ case XML_blipFill:
+ xRet.set( new BlipFillPropertiesContext( getHandler(), xAttribs, *(mpShapePtr->getGraphicProperties().get()) ) );
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
+
+ return xRet;
+}
+
+// ====================================================================
+// CT_GraphicalObjectFrameContext
+GraphicalObjectFrameContext::GraphicalObjectFrameContext( const FragmentHandlerRef& xHandler, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
+: ShapeContext( xHandler, pMasterShapePtr, pShapePtr )
+{
+}
+
+Reference< XFastContextHandler > GraphicalObjectFrameContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken &(~NMSP_MASK) )
+ {
+ // CT_ShapeProperties
+ case XML_nvGraphicFramePr: // CT_GraphicalObjectFrameNonVisual
+ break;
+ case XML_xfrm: // CT_Transform2D
+ xRet.set( new Transform2DContext( getHandler(), xAttribs, *(mpShapePtr.get()) ) );
+ break;
+ case XML_graphic: // CT_GraphicalObject
+ xRet.set( this );
+ break;
+
+ case XML_graphicData : // CT_GraphicalObjectData
+ {
+ rtl::OUString sUri( xAttribs->getOptionalValue( XML_uri ) );
+ if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/presentationml/2006/ole" ) == 0 )
+ xRet.set( new PresentationOle2006Context( mxHandler, mpShapePtr ) );
+ else if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ) == 0 )
+ xRet.set( new DiagramGraphicDataContext( mxHandler, mpShapePtr ) );
+ else if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/drawingml/2006/table" ) == 0 )
+ // TODO deal with tables too.
+ xRet.set( this );
+ else
+ {
+ OSL_TRACE( "OOX: Ignore graphicsData of %s", OUSTRING_TO_CSTR( sUri ) );
+ return xRet;
+ }
+ }
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
+
+ return xRet;
+}
+
+// ====================================================================
+
+PresentationOle2006Context::PresentationOle2006Context( const FragmentHandlerRef& xHandler, ShapePtr pShapePtr )
+: ShapeContext( xHandler, ShapePtr(), pShapePtr )
+{
+}
+
+PresentationOle2006Context::~PresentationOle2006Context()
+{
+ XmlFilterRef xFilter = getHandler()->getFilter();
+ const OUString aFragmentPath = getHandler()->getFragmentPathFromRelId( msId );
+ if( aFragmentPath.getLength() > 0 )
+ {
+ Reference< ::com::sun::star::io::XInputStream > xInputStream( xFilter->openInputStream( aFragmentPath ), UNO_QUERY_THROW );
+
+ Sequence< sal_Int8 > aData;
+ xInputStream->readBytes( aData, 0x7fffffff );
+ uno::Reference< lang::XMultiServiceFactory > xMSF( xFilter->getModel(), UNO_QUERY );
+ Reference< com::sun::star::document::XEmbeddedObjectResolver > xEmbeddedResolver( xMSF->createInstance( OUString::createFromAscii( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY );
+
+ if ( xEmbeddedResolver.is() )
+ {
+ Reference< com::sun::star::container::XNameAccess > xNA( xEmbeddedResolver, UNO_QUERY );
+ if( xNA.is() )
+ {
+ Reference < XOutputStream > xOLEStream;
+ OUString aURL = CREATE_OUSTRING( "Obj12345678" );
+ Any aAny( xNA->getByName( aURL ) );
+ aAny >>= xOLEStream;
+ if ( xOLEStream.is() )
+ {
+ xOLEStream->writeBytes( aData );
+ xOLEStream->closeOutput();
+
+ const OUString sProtocol = CREATE_OUSTRING( "vnd.sun.star.EmbeddedObject:" );
+ rtl::OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) );
+ aPersistName = aPersistName.copy( sProtocol.getLength() );
+
+ static const OUString sPersistName = CREATE_OUSTRING( "PersistName" );
+ mpShapePtr->getShapeProperties()[ sPersistName ] <<= aPersistName;
+ }
+ }
+ Reference< XComponent > xComp( xEmbeddedResolver, UNO_QUERY );
+ xComp->dispose();
+ }
+ }
+
+ // taking care of the representation graphic
+ if ( msSpid.getLength() )
+ {
+ oox::vml::DrawingPtr pDrawingPtr = xFilter->getDrawings();
+ if ( pDrawingPtr.get() )
+ {
+ rtl::OUString aGraphicURL( pDrawingPtr->getGraphicUrlById( msSpid ) );
+ if ( aGraphicURL.getLength() )
+ {
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
+ Reference< io::XInputStream > xInputStream( xFilter->openInputStream( aGraphicURL ), UNO_QUERY_THROW );
+ Reference< graphic::XGraphicProvider > xGraphicProvider( xMSF->createInstance( OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY_THROW );
+ if ( xInputStream.is() && xGraphicProvider.is() )
+ {
+ Sequence< PropertyValue > aArgs( 1 );
+ const OUString sInputStream = CREATE_OUSTRING( "InputStream" );
+ aArgs[ 0 ].Name = sInputStream;
+ aArgs[ 0 ].Value <<= xInputStream;
+ Reference< graphic::XGraphic > xGraphic = xGraphicProvider->queryGraphic( aArgs );
+ if ( xGraphic.is() )
+ {
+ static const OUString sEmptyGraphicURL;
+ static const OUString sGraphicURL = CREATE_OUSTRING( "GraphicURL" );
+ mpShapePtr->getShapeProperties()[ sGraphicURL ] <<= sEmptyGraphicURL;
+
+ static const OUString sThumbnailGraphic = CREATE_OUSTRING( "Graphic" );
+ mpShapePtr->getShapeProperties()[ sThumbnailGraphic ] <<= xGraphic;
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ }
+}
+
+Reference< XFastContextHandler > PresentationOle2006Context::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken &(~NMSP_MASK) )
+ {
+ case XML_oleObj:
+ {
+ msSpid = xAttribs->getOptionalValue( XML_spid );
+ msName = xAttribs->getOptionalValue( XML_name );
+ msId = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_id );
+ mnWidth = GetCoordinate( xAttribs->getOptionalValue( XML_imgW ) );
+ mnHeight = GetCoordinate( xAttribs->getOptionalValue( XML_imgH ) );
+ msProgId = xAttribs->getOptionalValue( XML_progId );
+ }
+ break;
+
+ case XML_embed:
+ {
+ mnFollowColorSchemeToken = xAttribs->getOptionalValueToken( XML_followColorScheme, XML_full );
+ }
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
+
+ return xRet;
+}
+
+DiagramGraphicDataContext::DiagramGraphicDataContext( const ::oox::core::FragmentHandlerRef& xHandler, ShapePtr pShapePtr )
+: ShapeContext( xHandler, ShapePtr(), pShapePtr )
+{
+}
+
+
+
+DiagramGraphicDataContext::~DiagramGraphicDataContext()
+{
+
+}
+
+DiagramPtr DiagramGraphicDataContext::loadDiagram()
+{
+ DiagramPtr pDiagram( new Diagram() );
+ const oox::core::XmlFilterRef& xFilter( getHandler()->getFilter() );
+
+ // data
+ OUString sDmPath = getHandler()->getFragmentPathFromRelId( msDm );
+ if( sDmPath.getLength() > 0 )
+ {
+ DiagramDataPtr pData( new DiagramData() );
+ pDiagram->setData( pData );
+ xFilter->importFragment( new DiagramDataFragmentHandler( xFilter, sDmPath, pData ) );
+ }
+ // layout
+ OUString sLoPath = getHandler()->getFragmentPathFromRelId( msLo );
+ if( sLoPath.getLength() > 0 )
+ {
+ DiagramLayoutPtr pLayout( new DiagramLayout() );
+ pDiagram->setLayout( pLayout );
+ xFilter->importFragment( new DiagramLayoutFragmentHandler( xFilter, sLoPath, pLayout ) );
+ }
+ // style
+ OUString sQsPath = getHandler()->getFragmentPathFromRelId( msQs );
+ if( sQsPath.getLength() > 0 )
+ {
+ DiagramQStylesPtr pStyles( new DiagramQStyles() );
+ pDiagram->setQStyles( pStyles );
+ xFilter->importFragment( new DiagramQStylesFragmentHandler( xFilter, sQsPath, pStyles ) );
+ }
+ // colors
+ OUString sCsPath = getHandler()->getFragmentPathFromRelId( msCs );
+ if( sCsPath.getLength() > 0 )
+ {
+ DiagramColorsPtr pColors( new DiagramColors() );
+ pDiagram->setColors( pColors );
+ xFilter->importFragment( new DiagramColorsFragmentHandler( xFilter, sCsPath, pColors ) ) ;
+ }
+
+ return pDiagram;
+}
+
+
+Reference< XFastContextHandler > DiagramGraphicDataContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DIAGRAM|XML_relIds:
+ {
+ msDm = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_dm );
+ msLo = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_lo );
+ msQs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_qs );
+ msCs = xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_cs );
+ DiagramPtr pDiagram = loadDiagram();
+ pDiagram->addTo( mpShapePtr );
+ break;
+ }
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/hyperlinkcontext.cxx b/oox/source/drawingml/hyperlinkcontext.cxx
new file mode 100644
index 000000000000..d4c75b83663f
--- /dev/null
+++ b/oox/source/drawingml/hyperlinkcontext.cxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: hyperlinkcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "hyperlinkcontext.hxx"
+
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
+
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/relations.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/skipcontext.hxx"
+#include "oox/drawingml/embeddedwavaudiofile.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+
+ HyperLinkContext::HyperLinkContext( const FragmentHandlerRef& xParent,
+ const Reference< XFastAttributeList >& xAttributes,
+ PropertyMap& aProperties)
+ : Context( xParent )
+ , maProperties(aProperties)
+ {
+ OUString aRelId = xAttributes->getOptionalValue( NMSP_RELATIONSHIPS|XML_id );
+ OSL_TRACE("OOX: URI rId %s", ::rtl::OUStringToOString (aRelId, RTL_TEXTENCODING_UTF8).pData->buffer);
+ const OUString& sHref = getHandler()->getRelations().getTargetFromRelId( aRelId );
+ if( sHref.getLength() > 0 )
+ {
+ OSL_TRACE("OOX: URI href %s", ::rtl::OUStringToOString (sHref, RTL_TEXTENCODING_UTF8).pData->buffer);
+ const OUString sURL( CREATE_OUSTRING( "URL" ) );
+ maProperties[ sURL ] <<= getHandler()->getFilter()->getAbsoluteUrl( sHref );
+ OUString sTooltip = xAttributes->getOptionalValue( NMSP_RELATIONSHIPS|XML_tooltip );
+ const OUString sRepresentation( CREATE_OUSTRING( "Representation" ) );
+ maProperties[ sRepresentation ] <<= sTooltip;
+
+ OUString sFrame = xAttributes->getOptionalValue( NMSP_RELATIONSHIPS|XML_tgtFrame );
+ if( sFrame.getLength() )
+ {
+ const OUString sTargetFrame( CREATE_OUSTRING( "TargetFrame" ) );
+ maProperties[ sTargetFrame ] <<= sFrame;
+ }
+
+// sValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "" ) );
+// const rtl::OUString sUnvisitedCharStyleName( CREATE_OUSTRING( "UnvisitedCharStyleName" ) );
+// maProperties[ sUnvisitedCharStyleName ] <<= sValue;
+// const rtl::OUString sVisitedCharStyleName( CREATE_OUSTRING( "VisitedCharStyleName" ) );
+// maProperties[ sVisitedCharStyleName ] <<= sValue;
+
+ }
+ // TODO unhandled
+ // XML_invalidUrl
+ // XML_history
+ // XML_highlightClick
+ // XML_endSnd
+ // XML_action
+ }
+
+ HyperLinkContext::~HyperLinkContext()
+ {
+ }
+
+ Reference< XFastContextHandler > HyperLinkContext::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+ switch( aElement )
+ {
+ case NMSP_DRAWINGML|XML_extLst:
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ case NMSP_DRAWINGML|XML_snd:
+ EmbeddedWAVAudioFile aAudio;
+ getEmbeddedWAVAudioFile( getHandler(), xAttribs, aAudio );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+} }
diff --git a/oox/source/drawingml/hyperlinkcontext.hxx b/oox/source/drawingml/hyperlinkcontext.hxx
new file mode 100644
index 000000000000..f35261aaad54
--- /dev/null
+++ b/oox/source/drawingml/hyperlinkcontext.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: hyperlinkcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_HYPERLINKCONTEXT_HXX
+#define OOX_DRAWINGML_HYPERLINKCONTEXT_HXX
+
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+
+#include "oox/core/context.hxx"
+#include "oox/core/fragmenthandler.hxx"
+
+namespace oox { class PropertyMap; }
+
+namespace oox { namespace drawingml {
+
+ class HyperLinkContext : public ::oox::core::Context
+ {
+ public:
+ HyperLinkContext( const ::oox::core::FragmentHandlerRef& xParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ PropertyMap& aProperties);
+ ~HyperLinkContext();
+
+// virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ protected:
+ PropertyMap& maProperties;
+ };
+
+
+} }
+
+
+#endif
diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx
new file mode 100644
index 000000000000..ed4261f7154b
--- /dev/null
+++ b/oox/source/drawingml/lineproperties.cxx
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: lineproperties.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include "oox/helper/propertyset.hxx"
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/drawing/FlagSequence.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+namespace oox { namespace drawingml {
+
+LineProperties::LineProperties()
+: maLineColor( new Color() )
+{
+}
+LineProperties::~LineProperties()
+{
+}
+
+void LineProperties::apply( const LinePropertiesPtr& rSourceLineProperties )
+{
+ maLineProperties.insert( rSourceLineProperties->maLineProperties.begin(), rSourceLineProperties->maLineProperties.end() );
+ if ( rSourceLineProperties->maLineColor->isUsed() )
+ maLineColor = rSourceLineProperties->maLineColor;
+ if ( rSourceLineProperties->moLineWidth )
+ moLineWidth = rSourceLineProperties->moLineWidth;
+ if ( rSourceLineProperties->moStartArrow )
+ moStartArrow = rSourceLineProperties->moStartArrow;
+ if ( rSourceLineProperties->moStartArrowWidth )
+ moStartArrowWidth = rSourceLineProperties->moStartArrowWidth;
+ if ( rSourceLineProperties->moStartArrowLength )
+ moStartArrowLength = rSourceLineProperties->moStartArrowLength;
+ if ( rSourceLineProperties->moEndArrow )
+ moEndArrow = rSourceLineProperties->moEndArrow;
+ if ( rSourceLineProperties->moEndArrowWidth )
+ moEndArrowWidth = rSourceLineProperties->moEndArrowWidth;
+ if ( rSourceLineProperties->moEndArrowLength )
+ moEndArrowLength = rSourceLineProperties->moEndArrowLength;
+ if ( rSourceLineProperties->moPresetDash )
+ moPresetDash = rSourceLineProperties->moPresetDash;
+ if ( rSourceLineProperties->moLineCap )
+ moLineCap = rSourceLineProperties->moLineCap;
+}
+
+static com::sun::star::drawing::PolyPolygonBezierCoords GetLineArrow( const sal_Int32 nLineWidth, const sal_Int32 nLineEndToken,
+ const sal_Int32 nArrowWidthToken, const sal_Int32 nArrowLengthToken, sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter, rtl::OUString& rsArrowName )
+{
+ uno::Sequence< awt::Point > aPoly;
+
+ double fLineWidth = nLineWidth < 70 ? 70.0 : nLineWidth;
+ double fLenghtMul, fWidthMul;
+ sal_Int32 nLineNumber;
+ switch( nArrowLengthToken )
+ {
+ default :
+ case XML_med: fLenghtMul = 3.0; nLineNumber = 2; break;
+ case XML_sm : fLenghtMul = 2.0; nLineNumber = 1; break;
+ case XML_lg : fLenghtMul = 5.0; nLineNumber = 3; break;
+ }
+ switch( nArrowWidthToken )
+ {
+ default :
+ case XML_med: fWidthMul = 3.0; nLineNumber += 3; break;
+ case XML_sm : fWidthMul = 2.0; break;
+ case XML_lg : fWidthMul = 5.0; nLineNumber += 6; break;
+ }
+ rbArrowCenter = sal_False;
+ switch ( nLineEndToken )
+ {
+ case XML_triangle :
+ {
+ aPoly.realloc( 4 );
+ aPoly[ 0 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ aPoly[ 1 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 2 ] = awt::Point( 0, static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 3 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ static const OUString sArrowEnd( RTL_CONSTASCII_USTRINGPARAM( "msArrowEnd " ) );
+ rsArrowName = sArrowEnd;
+ }
+ break;
+
+ case XML_arrow :
+ {
+ switch( nArrowLengthToken )
+ {
+ default :
+ case XML_med: fLenghtMul = 4.5; break;
+ case XML_sm : fLenghtMul = 3.5; break;
+ case XML_lg : fLenghtMul = 6.0; break;
+ }
+ switch( nArrowWidthToken )
+ {
+ default :
+ case XML_med: fWidthMul = 4.5; break;
+ case XML_sm : fWidthMul = 3.5; break;
+ case XML_lg : fWidthMul = 6.0; break;
+ }
+ aPoly.realloc( 7 );
+ aPoly[ 0 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ aPoly[ 1 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.91 ) );
+ aPoly[ 2 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.85 ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 3 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.36 ) );
+ aPoly[ 4 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.15 ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 5 ] = awt::Point( 0, static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.91 ) );
+ aPoly[ 6 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ static const OUString sArrowOpenEnd( RTL_CONSTASCII_USTRINGPARAM( "msArrowOpenEnd " ) );
+ rsArrowName = sArrowOpenEnd;
+ }
+ break;
+ case XML_stealth :
+ {
+ aPoly.realloc( 5 );
+ aPoly[ 0 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ aPoly[ 1 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 2 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.60 ) );
+ aPoly[ 3 ] = awt::Point( 0, static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 4 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ static const OUString sArrowStealthEnd( RTL_CONSTASCII_USTRINGPARAM( "msArrowStealthEnd " ) );
+ rsArrowName = sArrowStealthEnd;
+ }
+ break;
+ case XML_diamond :
+ {
+ aPoly.realloc( 5 );
+ aPoly[ 0 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ aPoly[ 1 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.50 ) );
+ aPoly[ 2 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 3 ] = awt::Point( 0, static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.50 ) );
+ aPoly[ 4 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ static const OUString sArrowDiamondEnd( RTL_CONSTASCII_USTRINGPARAM( "msArrowDiamondEnd " ) );
+ rsArrowName = sArrowDiamondEnd;
+ rbArrowCenter = sal_True;
+ }
+ break;
+ case XML_oval :
+ {
+ aPoly.realloc( 5 );
+ aPoly[ 0 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ aPoly[ 1 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.50 ) );
+ aPoly[ 2 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), static_cast< sal_Int32 >( fLenghtMul * fLineWidth ) );
+ aPoly[ 3 ] = awt::Point( 0, static_cast< sal_Int32 >( fLenghtMul * fLineWidth * 0.50 ) );
+ aPoly[ 4 ] = awt::Point( static_cast< sal_Int32 >( fWidthMul * fLineWidth * 0.50 ), 0 );
+ static const OUString sArrowOvalEnd( RTL_CONSTASCII_USTRINGPARAM( "msArrowOvalEnd " ) );
+ rsArrowName = sArrowOvalEnd;
+ rbArrowCenter = sal_True;
+ }
+ break;
+ default: break;
+ }
+ rsArrowName += rtl::OUString::valueOf( nLineNumber );
+ rnArrowWidth = static_cast< sal_Int32 >( fLineWidth * fWidthMul );
+
+ com::sun::star::drawing::PolyPolygonBezierCoords aPolyPolyBezier;
+ aPolyPolyBezier.Coordinates.realloc( 1 );
+ aPolyPolyBezier.Flags.realloc( 1 );
+ ::com::sun::star::drawing::PointSequence* pOuterSequence = aPolyPolyBezier.Coordinates.getArray();
+ ::com::sun::star::drawing::FlagSequence* pOuterFlags = aPolyPolyBezier.Flags.getArray();
+ pOuterSequence[ 0 ] = aPoly;
+ pOuterFlags[ 0 ] = ::com::sun::star::drawing::PolygonFlags( aPoly.getLength() );
+ return aPolyPolyBezier;
+}
+
+void setArrow( const ::oox::core::XmlFilterBase& rFilterBase, rtl::OUString& rName, com::sun::star::drawing::PolyPolygonBezierCoords& rPoly )
+{
+ uno::Reference< container::XNameContainer >& xMarker( rFilterBase.getMarkerTable() );
+ try
+ {
+ if( xMarker.is() )
+ {
+ if( xMarker->hasByName( rName ) )
+ xMarker->replaceByName( rName, Any( rPoly ) );
+ else
+ xMarker->insertByName( rName, Any( rPoly ) );
+ }
+ }
+ catch( container::ElementExistException& )
+ {}
+}
+
+void LineProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XPropertySet >& xPropSet ) const
+{
+ PropertySet aPropSet( xPropSet );
+ Sequence< OUString > aNames;
+ Sequence< Any > aValues;
+
+ maLineProperties.makeSequence( aNames, aValues );
+ aPropSet.setProperties( aNames, aValues );
+ if ( maLineColor->isUsed() )
+ {
+ const rtl::OUString sLineColor( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineColor" ) ) );
+ xPropSet->setPropertyValue( sLineColor, Any( maLineColor->getColor( rFilterBase ) ) );
+ }
+ if ( moLineWidth )
+ {
+ const rtl::OUString sLineWidth( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineWidth" ) ) );
+ xPropSet->setPropertyValue( sLineWidth, Any( *moLineWidth ) );
+ }
+ if ( moStartArrow && ( *moStartArrow != XML_none ) )
+ {
+ sal_Int32 nArrowWidth;
+ sal_Bool bArrowCenter;
+ rtl::OUString aArrowName;
+ com::sun::star::drawing::PolyPolygonBezierCoords aPoly( GetLineArrow( moLineWidth ? *moLineWidth : 70, *moStartArrow,
+ moStartArrowWidth ? *moStartArrowWidth : XML_med, moStartArrowLength ? *moStartArrowLength : XML_med, nArrowWidth, bArrowCenter, aArrowName ) );
+ const rtl::OUString sLineStart( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineStart" ) ) );
+ const rtl::OUString sLineStartName( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineStartName" ) ) );
+ const rtl::OUString sLineStartCenter( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineStartCenter" ) ) );
+ const rtl::OUString sLineStartWidth( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineStartWidth" ) ) );
+// xPropSet->setPropertyValue( sLineStart, Any( aPoly ) );
+ setArrow( rFilterBase, aArrowName, aPoly );
+ xPropSet->setPropertyValue( sLineStartName, Any( aArrowName ) );
+ xPropSet->setPropertyValue( sLineStartCenter, Any( bArrowCenter ) );
+ xPropSet->setPropertyValue( sLineStartWidth, Any( nArrowWidth ) );
+ }
+ if ( moEndArrow && ( *moEndArrow != XML_none ) )
+ {
+ sal_Int32 nArrowWidth;
+ sal_Bool bArrowCenter;
+ rtl::OUString aArrowName;
+ com::sun::star::drawing::PolyPolygonBezierCoords aPoly( GetLineArrow( moLineWidth ? *moLineWidth : 70, *moEndArrow,
+ moEndArrowWidth ? *moEndArrowWidth : XML_med, moEndArrowLength ? *moEndArrowLength : XML_med, nArrowWidth, bArrowCenter, aArrowName ) );
+ const rtl::OUString sLineEnd( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineEnd" ) ) );
+ const rtl::OUString sLineEndName( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineEndName" ) ) );
+ const rtl::OUString sLineEndCenter( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineEndCenter" ) ) );
+ const rtl::OUString sLineEndWidth( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineEndWidth" ) ) );
+// xPropSet->setPropertyValue( sLineEnd, Any( aPoly ) );
+ setArrow( rFilterBase, aArrowName, aPoly );
+ xPropSet->setPropertyValue( sLineEndName, Any( aArrowName ) );
+ xPropSet->setPropertyValue( sLineEndCenter, Any( bArrowCenter ) );
+ xPropSet->setPropertyValue( sLineEndWidth, Any( nArrowWidth ) );
+ }
+ if ( moPresetDash ) // ST_PresetLineDashVal
+ {
+ const rtl::OUString sLineStyle( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineStyle" ) ) );
+ if ( *moPresetDash == XML_solid )
+ xPropSet->setPropertyValue( sLineStyle, Any( drawing::LineStyle_SOLID ) );
+ else
+ {
+ sal_Int32 nLineWidth = moLineWidth ? *moLineWidth : 288;
+ drawing::LineDash aLineDash;
+ aLineDash.Style = drawing::DashStyle_ROUNDRELATIVE;
+ if ( moLineCap )
+ {
+ switch( *moLineCap )
+ {
+ default:
+ case XML_rnd: // Rounded ends. Semi-circle protrudes by half line width.
+ aLineDash.Style = drawing::DashStyle_ROUNDRELATIVE;
+ break;
+ case XML_sq: // Square protrudes by half line width.
+ aLineDash.Style = drawing::DashStyle_RECTRELATIVE;
+ break;
+ case XML_flat: // Line ends at end point.
+ aLineDash.Style = drawing::DashStyle_RECT;
+ break;
+ }
+ }
+ aLineDash.Dots = 1;
+ aLineDash.DotLen = nLineWidth;
+ aLineDash.Dashes = 0;
+ aLineDash.DashLen = ( 8 * nLineWidth );
+ aLineDash.Distance = ( 3 * nLineWidth );
+
+ switch( *moPresetDash )
+ {
+ 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;
+ case XML_dot :
+ case XML_sysDot :
+ aLineDash.Distance = aLineDash.DotLen;
+ break;
+ }
+ const rtl::OUString sLineDash( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "LineDash" ) ) );
+ xPropSet->setPropertyValue( sLineStyle, Any( drawing::LineStyle_DASH ) );
+ xPropSet->setPropertyValue( sLineDash, Any( aLineDash ) );
+ }
+ }
+}
+
+} }
diff --git a/oox/source/drawingml/linepropertiescontext.cxx b/oox/source/drawingml/linepropertiescontext.cxx
new file mode 100644
index 000000000000..5f21b0aa7109
--- /dev/null
+++ b/oox/source/drawingml/linepropertiescontext.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: linepropertiescontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/linepropertiescontext.hxx"
+
+#include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::beans::NamedValue;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+// CT_LineProperties
+
+namespace oox { namespace drawingml {
+// ---------------------------------------------------------------------
+
+LinePropertiesContext::LinePropertiesContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs,
+ oox::drawingml::LineProperties& rLineProperties ) throw()
+: Context( xHandler )
+, mrLineProperties( rLineProperties )
+{
+ // ST_LineWidth
+ if( xAttribs->hasAttribute( XML_w ) )
+ mrLineProperties.getLineWidth() = boost::optional< sal_Int32 >( GetCoordinate( xAttribs->getOptionalValue( XML_w ) ) );
+
+ // "ST_LineCap"
+ if( xAttribs->hasAttribute( XML_cap ) )
+ mrLineProperties.getLineCap() = boost::optional< sal_Int32 >( xAttribs->getOptionalValueToken( XML_cap, 0 ) );
+
+ // if ( xAttribs->hasAttribute( XML_cmpd ) ) ST_CompoundLine
+ // if ( xAttribs->hasAttribute( XML_algn ) ) ST_PenAlignment
+}
+
+LinePropertiesContext::~LinePropertiesContext()
+{
+}
+
+Reference< XFastContextHandler > LinePropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ const rtl::OUString sLineStyle( RTL_CONSTASCII_USTRINGPARAM( "LineStyle" ) );
+ switch( aElementToken )
+ {
+ // LineFillPropertiesGroup, line fillings currently unsuported
+ case NMSP_DRAWINGML|XML_noFill:
+ mrLineProperties.getLinePropertyMap()[ sLineStyle ] <<= LineStyle_NONE;
+ break;
+ case NMSP_DRAWINGML|XML_solidFill:
+ {
+ mrLineProperties.getLinePropertyMap()[ sLineStyle ] <<= LineStyle_SOLID;
+ xRet = new colorChoiceContext( getHandler(), *mrLineProperties.getLineColor().get() );
+ }
+ break;
+ case NMSP_DRAWINGML|XML_gradFill:
+ case NMSP_DRAWINGML|XML_pattFill:
+ mrLineProperties.getLinePropertyMap()[ sLineStyle ] <<= LineStyle_SOLID;
+ break;
+
+ // LineDashPropertiesGroup
+ case NMSP_DRAWINGML|XML_prstDash: // CT_PresetLineDashProperties
+ mrLineProperties.getPresetDash() = boost::optional< sal_Int32 >( xAttribs->getOptionalValueToken( XML_val, XML_solid ) );
+ break;
+ case NMSP_DRAWINGML|XML_custDash: // CT_DashStopList
+ break;
+
+ // LineJoinPropertiesGroup
+ case NMSP_DRAWINGML|XML_round:
+ case NMSP_DRAWINGML|XML_bevel:
+ case NMSP_DRAWINGML|XML_miter:
+ {
+ LineJoint eJoint = (aElementToken == (NMSP_DRAWINGML|XML_round)) ? LineJoint_ROUND :
+ (aElementToken == (NMSP_DRAWINGML|XML_bevel)) ? LineJoint_BEVEL :
+ LineJoint_MITER;
+ static const OUString sLineJoint( RTL_CONSTASCII_USTRINGPARAM( "LineJoint" ) );
+ mrLineProperties.getLinePropertyMap()[ sLineJoint ] <<= eJoint;
+ }
+ break;
+
+ case NMSP_DRAWINGML|XML_headEnd: // CT_LineEndProperties
+ case NMSP_DRAWINGML|XML_tailEnd: // CT_LineEndProperties
+ { // ST_LineEndType
+ if( xAttribs->hasAttribute( XML_type ) )
+ {
+ sal_Int32 nType = xAttribs->getOptionalValueToken( XML_type, 0 );
+ if ( aElementToken == ( NMSP_DRAWINGML|XML_tailEnd ) )
+ mrLineProperties.getStartArrow() = boost::optional< sal_Int32 >( nType );
+ else
+ mrLineProperties.getEndArrow() = boost::optional< sal_Int32 >( nType );
+ }
+ if ( xAttribs->hasAttribute( XML_w ) )
+ {
+ sal_Int32 nW = xAttribs->getOptionalValueToken( XML_w, 0 );
+ if ( aElementToken == ( NMSP_DRAWINGML|XML_tailEnd ) )
+ mrLineProperties.getStartArrowWidth() = boost::optional< sal_Int32 >( nW );
+ else
+ mrLineProperties.getEndArrowWidth() = boost::optional< sal_Int32 >( nW );
+ }
+ if ( xAttribs->hasAttribute( XML_len ) )
+ {
+ sal_Int32 nLen = xAttribs->getOptionalValueToken( XML_len, 0 );
+ if ( aElementToken == ( NMSP_DRAWINGML|XML_tailEnd ) )
+ mrLineProperties.getStartArrowLength() = boost::optional< sal_Int32 >( nLen );
+ else
+ mrLineProperties.getEndArrowLength() = boost::optional< sal_Int32 >( nLen );
+ }
+ }
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/makefile.mk b/oox/source/drawingml/makefile.mk
new file mode 100644
index 000000000000..4df20df79252
--- /dev/null
+++ b/oox/source/drawingml/makefile.mk
@@ -0,0 +1,96 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=drawingml
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/shapecontext.obj\
+ $(SLO)$/shapegroupcontext.obj\
+ $(SLO)$/fillproperties.obj\
+ $(SLO)$/fillpropertiesgroupcontext.obj\
+ $(SLO)$/lineproperties.obj\
+ $(SLO)$/linepropertiescontext.obj\
+ $(SLO)$/drawingmltypes.obj\
+ $(SLO)$/customshapegeometry.obj\
+ $(SLO)$/connectorshapecontext.obj\
+ $(SLO)$/graphicshapecontext.obj\
+ $(SLO)$/textbodycontext.obj\
+ $(SLO)$/textbodypropertiescontext.obj\
+ $(SLO)$/themefragmenthandler.obj\
+ $(SLO)$/objectdefaultcontext.obj\
+ $(SLO)$/themeelementscontext.obj\
+ $(SLO)$/spdefcontext.obj\
+ $(SLO)$/colorchoicecontext.obj\
+ $(SLO)$/clrschemecontext.obj\
+ $(SLO)$/clrscheme.obj\
+ $(SLO)$/color.obj\
+ $(SLO)$/shape.obj\
+ $(SLO)$/shapestylecontext.obj\
+ $(SLO)$/shapepropertiescontext.obj\
+ $(SLO)$/textparagraphproperties.obj\
+ $(SLO)$/textparagraphpropertiescontext.obj\
+ $(SLO)$/textcharacterproperties.obj\
+ $(SLO)$/textcharacterpropertiescontext.obj\
+ $(SLO)$/theme.obj\
+ $(SLO)$/textliststylecontext.obj\
+ $(SLO)$/textrun.obj\
+ $(SLO)$/textbody.obj\
+ $(SLO)$/textparagraph.obj\
+ $(SLO)$/textfontcontext.obj\
+ $(SLO)$/textspacingcontext.obj\
+ $(SLO)$/texttabstoplistcontext.obj\
+ $(SLO)$/textliststyle.obj \
+ $(SLO)$/textfieldcontext.obj\
+ $(SLO)$/textfield.obj\
+ $(SLO)$/hyperlinkcontext.obj\
+ $(SLO)$/embeddedwavaudiofile.obj\
+ $(SLO)$/customshapeproperties.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/drawingml/objectdefaultcontext.cxx b/oox/source/drawingml/objectdefaultcontext.cxx
new file mode 100644
index 000000000000..4e76cf1fb633
--- /dev/null
+++ b/oox/source/drawingml/objectdefaultcontext.cxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: objectdefaultcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/objectdefaultcontext.hxx"
+#include "oox/drawingml/spdefcontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+objectDefaultContext::objectDefaultContext( const ::oox::core::FragmentHandlerRef& xHandler, Theme& rTheme )
+: Context( xHandler )
+, mrTheme( rTheme )
+{
+}
+
+Reference< XFastContextHandler > objectDefaultContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& /* xAttribs */ ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_spDef:
+ {
+ xRet.set( new spDefContext( getHandler(), *(mrTheme.getspDef().get()) ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_lnDef:
+ {
+ xRet.set( new spDefContext( getHandler(), *(mrTheme.getlnDef().get()) ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_txDef:
+ {
+ xRet.set( new spDefContext( getHandler(), *(mrTheme.gettxDef().get()) ) );
+ break;
+ }
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
new file mode 100644
index 000000000000..dabd5a359e7e
--- /dev/null
+++ b/oox/source/drawingml/shape.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: shape.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+#include <tools/solar.h> // for the F_PI180 define
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/drawing/HomogenMatrix3.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::drawing;
+
+namespace oox { namespace drawingml {
+
+Shape::Shape( const sal_Char* pServiceName )
+: mpLinePropertiesPtr( new LineProperties() )
+, mpFillPropertiesPtr( new FillProperties( XML_spPr ) )
+, mpGraphicPropertiesPtr( new FillProperties( XML_pic ) )
+, mpCustomShapePropertiesPtr( new CustomShapeProperties() )
+, mpMasterTextListStyle( new TextListStyle() )
+, mnSubType( 0 )
+, mnIndex( 0 )
+, mnRotation( 0 )
+, mbFlipH( false )
+, mbFlipV( false )
+{
+ if ( pServiceName )
+ msServiceName = OUString::createFromAscii( pServiceName );
+ setDefaults();
+}
+Shape::~Shape()
+{
+}
+
+void Shape::setDefaults()
+{
+ const OUString sTextAutoGrowHeight( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) );
+ const OUString sTextWordWrap( RTL_CONSTASCII_USTRINGPARAM( "TextWordWrap" ) );
+ const OUString sTextLeftDistance( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) );
+ const OUString sTextUpperDistance( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) );
+ const OUString sTextRightDistance( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) );
+ const OUString sTextLowerDistance( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) );
+ maShapeProperties[ sTextAutoGrowHeight ] <<= sal_False;
+ maShapeProperties[ sTextWordWrap ] <<= sal_True;
+ maShapeProperties[ sTextLeftDistance ] <<= static_cast< sal_Int32 >( 250 );
+ maShapeProperties[ sTextUpperDistance ] <<= static_cast< sal_Int32 >( 125 );
+ maShapeProperties[ sTextRightDistance ] <<= static_cast< sal_Int32 >( 250 );
+ maShapeProperties[ sTextLowerDistance ] <<= static_cast< sal_Int32 >( 125 );
+}
+
+void Shape::setServiceName( const sal_Char* pServiceName )
+{
+ if ( pServiceName )
+ msServiceName = OUString::createFromAscii( pServiceName );
+}
+
+
+void Shape::addShape( const oox::core::XmlFilterBase& rFilterBase, const Reference< XModel > &rxModel, const oox::drawingml::ThemePtr pThemePtr,
+ std::map< ::rtl::OUString, ShapePtr > & aShapeMap, const Reference< XShapes >& rxShapes, const awt::Rectangle* pShapeRect )
+{
+ try
+ {
+ rtl::OUString sServiceName( msServiceName );
+ if( sServiceName.getLength() )
+ {
+ Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, rxModel, pThemePtr, rxShapes, pShapeRect ) );
+
+ if( msId.getLength() )
+ {
+ aShapeMap[ msId ] = shared_from_this();
+ }
+
+ // if this is a group shape, we have to add also each child shape
+ Reference< XShapes > xShapes( xShape, UNO_QUERY );
+ if ( xShapes.is() )
+ addChilds( rFilterBase, *this, rxModel, pThemePtr, aShapeMap, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+}
+
+void Shape::applyShapeReference( const oox::drawingml::Shape& rReferencedShape )
+{
+ mpTextBody = TextBodyPtr( new TextBody( *rReferencedShape.mpTextBody.get() ) );
+ maShapeProperties = rReferencedShape.maShapeProperties;
+ mpLinePropertiesPtr = LinePropertiesPtr( new LineProperties( *rReferencedShape.mpLinePropertiesPtr.get() ) );
+ mpFillPropertiesPtr = FillPropertiesPtr( new FillProperties( *rReferencedShape.mpFillPropertiesPtr.get() ) );
+ mpCustomShapePropertiesPtr = CustomShapePropertiesPtr( new CustomShapeProperties( *rReferencedShape.mpCustomShapePropertiesPtr.get() ) );
+ mpMasterTextListStyle = TextListStylePtr( new TextListStyle( *rReferencedShape.mpMasterTextListStyle.get() ) );
+ maShapeStylesColorMap = rReferencedShape.maShapeStylesColorMap;
+ maShapeStylesIndexMap = rReferencedShape.maShapeStylesIndexMap;
+ maSize = rReferencedShape.maSize;
+ maPosition = rReferencedShape.maPosition;
+ mnRotation = rReferencedShape.mnRotation;
+ mbFlipH = rReferencedShape.mbFlipH;
+ mbFlipV = rReferencedShape.mbFlipV;
+}
+
+// for group shapes, the following method is also adding each child
+void Shape::addChilds( const oox::core::XmlFilterBase& rFilterBase, Shape& rMaster, const Reference< XModel > &rxModel, const oox::drawingml::ThemePtr pThemePtr,
+ std::map< ::rtl::OUString, ShapePtr > & aShapeMap, const Reference< XShapes >& rxShapes, const awt::Rectangle& rClientRect )
+{
+ // first the global child union needs to be calculated
+ sal_Int32 nGlobalLeft = SAL_MAX_INT32;
+ sal_Int32 nGlobalRight = SAL_MIN_INT32;
+ sal_Int32 nGlobalTop = SAL_MAX_INT32;
+ sal_Int32 nGlobalBottom= SAL_MIN_INT32;
+ std::vector< ShapePtr >::iterator aIter( rMaster.maChilds.begin() );
+ while( aIter != rMaster.maChilds.end() )
+ {
+ sal_Int32 l = (*aIter)->maPosition.X;
+ sal_Int32 t = (*aIter)->maPosition.Y;
+ sal_Int32 r = l + (*aIter)->maSize.Width;
+ sal_Int32 b = t + (*aIter)->maSize.Height;
+ if ( nGlobalLeft > l )
+ nGlobalLeft = l;
+ if ( nGlobalRight < r )
+ nGlobalRight = r;
+ if ( nGlobalTop > t )
+ nGlobalTop = t;
+ if ( nGlobalBottom < b )
+ nGlobalBottom = b;
+ aIter++;
+ }
+ aIter = rMaster.maChilds.begin();
+ while( aIter != rMaster.maChilds.end() )
+ {
+ Rectangle aShapeRect;
+ Rectangle* pShapeRect = 0;
+ if ( ( nGlobalLeft != SAL_MAX_INT32 ) && ( nGlobalRight != SAL_MIN_INT32 ) && ( nGlobalTop != SAL_MAX_INT32 ) && ( nGlobalBottom != SAL_MIN_INT32 ) )
+ {
+ sal_Int32 nGlobalWidth = nGlobalRight - nGlobalLeft;
+ sal_Int32 nGlobalHeight = nGlobalBottom - nGlobalTop;
+ if ( nGlobalWidth && nGlobalHeight )
+ {
+ double fWidth = (*aIter)->maSize.Width;
+ double fHeight= (*aIter)->maSize.Height;
+ double fXScale = (double)rClientRect.Width / (double)nGlobalWidth;
+ double fYScale = (double)rClientRect.Height / (double)nGlobalHeight;
+ aShapeRect.X = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.X - nGlobalLeft ) * fXScale ) + rClientRect.X );
+ aShapeRect.Y = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.Y - nGlobalTop ) * fYScale ) + rClientRect.Y );
+ fWidth *= fXScale;
+ fHeight *= fYScale;
+ aShapeRect.Width = static_cast< sal_Int32 >( fWidth );
+ aShapeRect.Height = static_cast< sal_Int32 >( fHeight );
+ pShapeRect = &aShapeRect;
+ }
+ }
+ (*aIter++)->addShape( rFilterBase, rxModel, pThemePtr, aShapeMap, rxShapes, pShapeRect );
+ }
+}
+
+void applyPropertyMap( uno::Reference< drawing::XShape >& rxShape, PropertyMap& rPropertyMap )
+{
+ if( !rPropertyMap.empty() )
+ {
+ Reference< XMultiPropertySet > xMSet( rxShape, UNO_QUERY );
+ if( xMSet.is() )
+ {
+ try
+ {
+ Sequence< OUString > aNames;
+ Sequence< Any > aValues;
+ rPropertyMap.makeSequence( aNames, aValues );
+ xMSet->setPropertyValues( aNames, aValues);
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ else
+ {
+ uno::Reference< beans::XPropertySet > xSet( rxShape, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );
+
+ for( PropertyMap::const_iterator aIter( rPropertyMap.begin() ); aIter != rPropertyMap.end(); aIter++ )
+ {
+ if ( xInfo->hasPropertyByName( (*aIter).first ) )
+ xSet->setPropertyValue( (*aIter).first, (*aIter).second );
+ }
+ }
+ }
+}
+
+
+
+Reference< XShape > Shape::createAndInsert( const oox::core::XmlFilterBase& rFilterBase, const rtl::OUString& rServiceName, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > &rxModel,
+ const oox::drawingml::ThemePtr pThemePtr, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const awt::Rectangle* pShapeRect )
+{
+ basegfx::B2DHomMatrix aTransformation;
+
+ awt::Size aSize( pShapeRect ? awt::Size( pShapeRect->Width, pShapeRect->Height ) : maSize );
+ awt::Point aPosition( pShapeRect ? awt::Point( pShapeRect->X, pShapeRect->Y ) : maPosition );
+ if( aSize.Width != 1 || aSize.Height != 1)
+ {
+ // take care there are no zeros used by error
+ aTransformation.scale(
+ aSize.Width ? aSize.Width / 360.0 : 1.0,
+ aSize.Height ? aSize.Height / 360.0 : 1.0 );
+ }
+
+ if( mbFlipH || mbFlipV || mnRotation != 0)
+ {
+ // calculate object's center
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= aTransformation;
+
+ // center object at origin
+ aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
+
+ if( mbFlipH || mbFlipV)
+ {
+ // mirror around object's center
+ aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 );
+ }
+
+ if( mnRotation != 0 )
+ {
+ // rotate around object's center
+ aTransformation.rotate( -F_PI180 * ( (double)mnRotation / 60000.0 ) );
+ }
+
+ // move object back from center
+ aTransformation.translate( aCenter.getX(), aCenter.getY() );
+ }
+
+ if( aPosition.X != 0 || aPosition.Y != 0)
+ {
+ // if global position is used, add it to transformation
+ aTransformation.translate( aPosition.X / 360.0, aPosition.Y / 360.0 );
+ }
+
+ // special for lineshape
+ if ( rServiceName == OUString::createFromAscii( "com.sun.star.drawing.LineShape" ) )
+ {
+ ::basegfx::B2DPolygon aPoly;
+ aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
+ aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
+ aPoly.transform( aTransformation );
+
+ // now creating the corresponding PolyPolygon
+ sal_Int32 i, nNumPoints = aPoly.count();
+ uno::Sequence< awt::Point > aPointSequence( nNumPoints );
+ awt::Point* pPoints = aPointSequence.getArray();
+ for( i = 0; i < nNumPoints; ++i )
+ {
+ const ::basegfx::B2DPoint aPoint( aPoly.getB2DPoint( i ) );
+ pPoints[ i ] = awt::Point( static_cast< sal_Int32 >( aPoint.getX() ), static_cast< sal_Int32 >( aPoint.getY() ) );
+ }
+ uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 );
+ aPolyPolySequence.getArray()[ 0 ] = aPointSequence;
+
+ static const OUString sPolyPolygon(RTL_CONSTASCII_USTRINGPARAM("PolyPolygon"));
+ maShapeProperties[ sPolyPolygon ] <<= aPolyPolySequence;
+ }
+ else if ( rServiceName == OUString::createFromAscii( "com.sun.star.drawing.ConnectorShape" ) )
+ {
+ ::basegfx::B2DPolygon aPoly;
+ aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
+ aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
+ aPoly.transform( aTransformation );
+
+ basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) );
+ basegfx::B2DPoint aEndPosition( aPoly.getB2DPoint( 1 ) );
+ awt::Point aAWTStartPosition( static_cast< sal_Int32 >( aStartPosition.getX() ), static_cast< sal_Int32 >( aStartPosition.getY() ) );
+ awt::Point aAWTEndPosition( static_cast< sal_Int32 >( aEndPosition.getX() ), static_cast< sal_Int32 >( aEndPosition.getY() ) );
+
+ static const OUString sStartPosition(RTL_CONSTASCII_USTRINGPARAM("StartPosition"));
+ maShapeProperties[ sStartPosition ] <<= aAWTStartPosition;
+ static const OUString sEndPosition(RTL_CONSTASCII_USTRINGPARAM("EndPosition"));
+ maShapeProperties[ sEndPosition ] <<= aAWTEndPosition;
+ }
+ else
+ {
+ // now set transformation for this object
+ HomogenMatrix3 aMatrix;
+
+ aMatrix.Line1.Column1 = aTransformation.get(0,0);
+ aMatrix.Line1.Column2 = aTransformation.get(0,1);
+ aMatrix.Line1.Column3 = aTransformation.get(0,2);
+
+ aMatrix.Line2.Column1 = aTransformation.get(1,0);
+ aMatrix.Line2.Column2 = aTransformation.get(1,1);
+ aMatrix.Line2.Column3 = aTransformation.get(1,2);
+
+ aMatrix.Line3.Column1 = aTransformation.get(2,0);
+ aMatrix.Line3.Column2 = aTransformation.get(2,1);
+ aMatrix.Line3.Column3 = aTransformation.get(2,2);
+
+ static const OUString sTransformation(RTL_CONSTASCII_USTRINGPARAM("Transformation"));
+ maShapeProperties[ sTransformation ] <<= aMatrix;
+ }
+ Reference< lang::XMultiServiceFactory > xServiceFact( rxModel, UNO_QUERY_THROW );
+ Reference< drawing::XShape > xShape( xServiceFact->createInstance( rServiceName ), UNO_QUERY_THROW );
+ Reference< XPropertySet > xSet( xShape, UNO_QUERY_THROW );
+ if( xShape.is() && xSet.is() )
+ {
+ if( msName.getLength() )
+ {
+ Reference< container::XNamed > xNamed( xShape, UNO_QUERY );
+ if( xNamed.is() )
+ xNamed->setName( msName );
+ }
+ rxShapes->add( xShape );
+ mxShape = xShape;
+
+ setShapeStyles( pThemePtr, rFilterBase );
+
+ // applying properties
+ if ( rServiceName == OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) )
+ mpGraphicPropertiesPtr->pushToPropSet( rFilterBase, xSet );
+ mpFillPropertiesPtr->pushToPropSet( rFilterBase, xSet );
+ mpLinePropertiesPtr->pushToPropSet( rFilterBase, xSet );
+
+ // applying autogrowheight property before setting shape size, because
+ // the shape size might be changed if currently autogrowheight is true
+ // we must also check that the PropertySet supports the property.
+ Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
+ static const rtl::OUString sTextAutoGrowHeight( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) );
+ if( xSetInfo->hasPropertyByName( sTextAutoGrowHeight ) )
+ {
+ const Any* pAutoGrowHeight = maShapeProperties.getPropertyValue( sTextAutoGrowHeight );
+ if ( pAutoGrowHeight )
+ xSet->setPropertyValue( sTextAutoGrowHeight, Any( sal_False ) );
+ }
+
+ applyPropertyMap( xShape, maShapeProperties );
+
+ if( rServiceName == OUString::createFromAscii( "com.sun.star.drawing.CustomShape" ) )
+ mpCustomShapePropertiesPtr->pushToPropSet( rFilterBase, xSet );
+
+ // in some cases, we don't have any text body.
+ if( getTextBody() )
+ {
+ Reference < XText > xText( xShape, UNO_QUERY );
+ if ( xText.is() ) // not every shape is supporting an XText interface (e.g. GroupShape)
+ {
+ Reference < XTextCursor > xAt = xText->createTextCursor();
+ getTextBody()->insertAt( rFilterBase, xText, xAt, rxModel, mpMasterTextListStyle );
+ }
+ }
+ }
+ return xShape;
+}
+
+// the properties of rSource which are not part of rDest are being put into rDest
+void addMissingProperties( const PropertyMap& rSource, PropertyMap& rDest )
+{
+ PropertyMap::const_iterator aSourceIter( rSource.begin() );
+ while( aSourceIter != rSource.end() )
+ {
+ if ( rDest.find( (*aSourceIter ).first ) == rDest.end() )
+ rDest[ (*aSourceIter).first ] <<= (*aSourceIter).second;
+ aSourceIter++;
+ }
+}
+
+// merging styles, if a shape property is not set, we have to set the shape style property
+void Shape::setShapeStyles( const oox::drawingml::ThemePtr pThemePtr, const oox::core::XmlFilterBase& rFilterBase )
+{
+ std::map< ShapeStyle, ColorPtr >::const_iterator aShapeStylesColorIter( getShapeStylesColor().begin() );
+ std::map< ShapeStyle, rtl::OUString >::const_iterator aShapeStylesIndexIter( getShapeStylesIndex().begin() );
+ while( aShapeStylesColorIter != getShapeStylesColor().end() )
+ {
+ switch( (*aShapeStylesColorIter).first )
+ {
+ case oox::drawingml::SHAPESTYLE_ln :
+ {
+ if ( !mpLinePropertiesPtr->getLineColor()->isUsed() )
+ mpLinePropertiesPtr->getLineColor() = (*aShapeStylesColorIter).second;
+ }
+ break;
+ case oox::drawingml::SHAPESTYLE_fill :
+ {
+ if ( !mpFillPropertiesPtr->getFillColor()->isUsed() )
+ mpFillPropertiesPtr->getFillColor() = (*aShapeStylesColorIter).second;
+ }
+ case oox::drawingml::SHAPESTYLE_effect :
+ break;
+ case oox::drawingml::SHAPESTYLE_font :
+ {
+ const rtl::OUString sCharColor( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ) );
+ if ( maShapeProperties.find( sCharColor ) == maShapeProperties.end() )
+ maShapeProperties[ sCharColor ] <<= ((*aShapeStylesColorIter).second)->getColor( rFilterBase );
+ }
+ break;
+ }
+ aShapeStylesColorIter++;
+ }
+ while( aShapeStylesIndexIter != getShapeStylesIndex().end() )
+ {
+ const rtl::OUString sIndex( (*aShapeStylesIndexIter).second );
+ sal_uInt32 nIndex( sIndex.toInt32() );
+ if ( nIndex-- )
+ {
+ switch( (*aShapeStylesIndexIter).first )
+ {
+ case oox::drawingml::SHAPESTYLE_ln :
+ {
+ const std::vector< oox::drawingml::LinePropertiesPtr >& rThemeLineStyleList( pThemePtr->getLineStyleList() );
+ if ( rThemeLineStyleList.size() > nIndex )
+ mpLinePropertiesPtr->apply( rThemeLineStyleList[ nIndex ] );
+ }
+ break;
+ case oox::drawingml::SHAPESTYLE_fill :
+ {
+ const std::vector< oox::drawingml::FillPropertiesPtr >& rThemeFillStyleList( pThemePtr->getFillStyleList() );
+ if ( rThemeFillStyleList.size() > nIndex )
+ mpFillPropertiesPtr->apply( rThemeFillStyleList[ nIndex ] );
+ }
+ break;
+ case oox::drawingml::SHAPESTYLE_effect :
+ case oox::drawingml::SHAPESTYLE_font :
+ break;
+ }
+ }
+ aShapeStylesIndexIter++;
+ }
+}
+
+void Shape::setTextBody(const TextBodyPtr & pTextBody)
+{
+ mpTextBody = pTextBody;
+}
+
+
+TextBodyPtr Shape::getTextBody()
+{
+ return mpTextBody;
+}
+
+void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle )
+{
+ mpMasterTextListStyle = pMasterTextListStyle;
+}
+
+
+} }
diff --git a/oox/source/drawingml/shapecontext.cxx b/oox/source/drawingml/shapecontext.cxx
new file mode 100644
index 000000000000..5ac0ffc255bf
--- /dev/null
+++ b/oox/source/drawingml/shapecontext.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: shapecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/drawingml/shapecontext.hxx"
+#include "oox/drawingml/shapestylecontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// CT_Shape
+ShapeContext::ShapeContext( const FragmentHandlerRef& xHandler, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
+: Context( xHandler )
+, mpMasterShapePtr( pMasterShapePtr )
+, mpShapePtr( pShapePtr )
+{
+}
+
+ShapeContext::~ShapeContext()
+{
+ if ( mpMasterShapePtr.get() && mpShapePtr.get() )
+ mpMasterShapePtr->addChild( mpShapePtr );
+}
+
+ShapePtr ShapeContext::getShape()
+{
+ return mpShapePtr;
+}
+
+void ShapeContext::endFastElement( sal_Int32 /* aElementToken */ ) throw( SAXException, RuntimeException )
+{
+}
+
+Reference< XFastContextHandler > ShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken &(~NMSP_MASK) )
+ {
+ // nvSpPr CT_ShapeNonVisual begin
+// case XML_drElemPr:
+// break;
+ case XML_cNvPr:
+ mpShapePtr->setId( xAttribs->getOptionalValue( XML_id ) );
+ mpShapePtr->setName( xAttribs->getOptionalValue( XML_name ) );
+ break;
+ case XML_ph:
+ mpShapePtr->setSubType( xAttribs->getOptionalValueToken( XML_type, XML_obj ) );
+ mpShapePtr->setIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
+ break;
+ // nvSpPr CT_ShapeNonVisual end
+
+ case XML_spPr:
+ xRet = new ShapePropertiesContext( this, *(mpShapePtr.get()) );
+ break;
+
+ case XML_style:
+ xRet = new ShapeStyleContext( this, *(mpShapePtr.get()) );
+ break;
+
+ case XML_txBody:
+ {
+ xRet = new TextBodyContext( getHandler(), *(mpShapePtr.get()) );
+ break;
+ }
+ }
+
+ if( !xRet.is() )
+ {
+ uno::Reference<XFastContextHandler> xTmp(this);
+ xRet.set( xTmp );
+ }
+
+ return xRet;
+}
+
+
+} }
diff --git a/oox/source/drawingml/shapegroupcontext.cxx b/oox/source/drawingml/shapegroupcontext.cxx
new file mode 100644
index 000000000000..7e6c7dd0c6ee
--- /dev/null
+++ b/oox/source/drawingml/shapegroupcontext.cxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: shapegroupcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/drawingml/connectorshapecontext.hxx"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+ShapeGroupContext::ShapeGroupContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 /* aElementToken */, ShapePtr pMasterShapePtr, ShapePtr pGroupShapePtr )
+: Context( xHandler )
+, mpGroupShapePtr( pGroupShapePtr )
+, mpMasterShapePtr( pMasterShapePtr )
+{
+}
+
+ShapeGroupContext::~ShapeGroupContext()
+{
+ if ( mpMasterShapePtr.get() && mpGroupShapePtr.get() )
+ mpMasterShapePtr->addChild( mpGroupShapePtr );
+}
+
+Reference< XFastContextHandler > ShapeGroupContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken &(~NMSP_MASK) )
+ {
+ case XML_cNvPr:
+ mpGroupShapePtr->setId( xAttribs->getOptionalValue( XML_id ) );
+ mpGroupShapePtr->setName( xAttribs->getOptionalValue( XML_name ) );
+ break;
+ case XML_ph:
+ mpGroupShapePtr->setSubType( xAttribs->getOptionalValueToken( XML_type, FastToken::DONTKNOW ) );
+ mpGroupShapePtr->setIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
+ break;
+ // nvSpPr CT_ShapeNonVisual end
+
+ case XML_grpSpPr:
+ xRet = new ShapePropertiesContext( this, *(mpGroupShapePtr.get()) );
+ break;
+ case XML_spPr:
+ xRet = new ShapePropertiesContext( this, *(mpGroupShapePtr.get()) );
+ break;
+/*
+ case XML_style:
+ xRet = new ShapeStyleContext( getParser() );
+ break;
+*/
+ case XML_cxnSp: // connector shape
+ xRet.set( new ConnectorShapeContext( getHandler(), aElementToken, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.ConnectorShape" ) ) ) );
+ break;
+ case XML_grpSp: // group shape
+ xRet.set( new ShapeGroupContext( getHandler(), aElementToken, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.GroupShape" ) ) ) );
+ break;
+ case XML_sp: // shape
+ xRet.set( new ShapeContext( getHandler(), mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.CustomShape" ) ) ) );
+ break;
+ case XML_pic: // CT_Picture
+ xRet.set( new GraphicShapeContext( getHandler(), mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ) ) );
+ break;
+ case XML_graphicFrame: // CT_GraphicalObjectFrame
+ xRet.set( new GraphicalObjectFrameContext( getHandler(), mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.OLE2Shape" ) ) ) );
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/shapepropertiescontext.cxx b/oox/source/drawingml/shapepropertiescontext.cxx
new file mode 100644
index 000000000000..a4c6ad5c98c8
--- /dev/null
+++ b/oox/source/drawingml/shapepropertiescontext.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: shapepropertiescontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/linepropertiescontext.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// ====================================================================
+
+// CT_ShapeProperties
+ShapePropertiesContext::ShapePropertiesContext( const ContextRef& xParent, ::oox::drawingml::Shape& rShape )
+: Context( xParent->getHandler() )
+, mxParent( xParent )
+, mrShape( rShape )
+{
+}
+
+// --------------------------------------------------------------------
+
+void ShapePropertiesContext::endFastElement( sal_Int32 aElementToken ) throw( SAXException, RuntimeException )
+{
+ mxParent->endFastElement( aElementToken );
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > ShapePropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ // CT_Transform2D
+ case NMSP_DRAWINGML|XML_xfrm:
+ xRet.set( new Transform2DContext( getHandler(), xAttribs, mrShape ) );
+ break;
+
+ // GeometryGroup
+ case NMSP_DRAWINGML|XML_custGeom: // custom geometry "CT_CustomGeometry2D"
+ xRet.set( new CustomShapeGeometryContext( getHandler(), xAttribs, *(mrShape.getCustomShapeProperties()) ) );
+ break;
+
+
+ case NMSP_DRAWINGML|XML_prstGeom: // preset geometry "CT_PresetGeometry2D"
+ {
+ sal_Int32 nToken = xAttribs->getOptionalValueToken( XML_prst, 0 );
+ if ( nToken == XML_line )
+ {
+ static const OUString sLineShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.LineShape" ) );
+ mrShape.getServiceName() = sLineShape;
+ }
+ xRet.set( new PresetShapeGeometryContext( getHandler(), xAttribs, *(mrShape.getCustomShapeProperties()) ) );
+ }
+ break;
+
+ case NMSP_DRAWINGML|XML_prstTxWarp:
+ xRet.set( new PresetTextShapeContext( getHandler(), xAttribs, *(mrShape.getCustomShapeProperties()) ) );
+ break;
+
+ // CT_LineProperties
+ case NMSP_DRAWINGML|XML_ln:
+ xRet.set( new LinePropertiesContext( getHandler(), xAttribs, *(mrShape.getLineProperties().get()) ) );
+ break;
+
+ // EffectPropertiesGroup
+ // todo not supported by core
+ case NMSP_DRAWINGML|XML_effectLst: // CT_EffectList
+ case NMSP_DRAWINGML|XML_effectDag: // CT_EffectContainer
+ break;
+
+ // todo
+ case NMSP_DRAWINGML|XML_scene3d: // CT_Scene3D
+ case NMSP_DRAWINGML|XML_sp3d: // CT_Shape3D
+ break;
+ }
+
+ // FillPropertiesGroupContext
+ if( !xRet.is() )
+ xRet.set( FillPropertiesGroupContext::StaticCreateContext( getHandler(), aElementToken, xAttribs, *(mrShape.getFillProperties().get()) ) );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/shapestylecontext.cxx b/oox/source/drawingml/shapestylecontext.cxx
new file mode 100644
index 000000000000..bf58ecde8f4a
--- /dev/null
+++ b/oox/source/drawingml/shapestylecontext.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: shapestylecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/shapestylecontext.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// -------------------------
+// CT_StyleMatrixReference
+// -------------------------
+class StyleMatrixReferenceContext : public ::oox::core::Context
+{
+public:
+ StyleMatrixReferenceContext( const ::oox::core::ContextRef& rxParent, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs,
+ const oox::drawingml::ShapeStyle eShapeStyle, oox::drawingml::Shape& rShape );
+ ~StyleMatrixReferenceContext();
+
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ ::oox::drawingml::Shape& mrShape;
+ ::oox::drawingml::ShapeStyle meShapeStyle;
+ ::oox::drawingml::ColorPtr maColor;
+};
+
+StyleMatrixReferenceContext::StyleMatrixReferenceContext( const ::oox::core::ContextRef& rxParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ const oox::drawingml::ShapeStyle eShapeStyle, oox::drawingml::Shape& rShape )
+: Context( rxParent->getHandler() )
+, mrShape( rShape )
+, meShapeStyle( eShapeStyle )
+, maColor( new Color() )
+{
+ mrShape.getShapeStylesIndex()[ meShapeStyle ] = rxAttribs->getOptionalValue( XML_idx );
+}
+
+StyleMatrixReferenceContext::~StyleMatrixReferenceContext()
+{
+
+}
+
+// --------------------------------------------------------------------
+
+void StyleMatrixReferenceContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+ mrShape.getShapeStylesColor()[ meShapeStyle ] = maColor;
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > StyleMatrixReferenceContext::createFastChildContext( sal_Int32 /* aElementToken */, const Reference< XFastAttributeList >& /* rxAttributes */ ) throw (SAXException, RuntimeException)
+{
+ return new colorChoiceContext( getHandler(), *maColor.get() );
+}
+
+// ---------------
+// CT_ShapeStyle
+// ---------------
+ShapeStyleContext::ShapeStyleContext( const ::oox::core::ContextRef& rxParent, oox::drawingml::Shape& rShape )
+: Context( rxParent->getHandler() )
+, mrShape( rShape )
+{
+}
+
+ShapeStyleContext::~ShapeStyleContext()
+{
+}
+
+// --------------------------------------------------------------------
+
+void ShapeStyleContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > ShapeStyleContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& rxAttributes )
+ throw ( SAXException, RuntimeException )
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_lnRef : // CT_StyleMatrixReference
+ xRet.set( new StyleMatrixReferenceContext( this, rxAttributes, oox::drawingml::SHAPESTYLE_ln, mrShape ) );
+ break;
+ case NMSP_DRAWINGML|XML_fillRef : // CT_StyleMatrixReference
+ xRet.set( new StyleMatrixReferenceContext( this, rxAttributes, oox::drawingml::SHAPESTYLE_fill, mrShape ) );
+ break;
+ case NMSP_DRAWINGML|XML_effectRef : // CT_StyleMatrixReference
+ xRet.set( new StyleMatrixReferenceContext( this, rxAttributes, oox::drawingml::SHAPESTYLE_effect, mrShape ) );
+ break;
+ case NMSP_DRAWINGML|XML_fontRef : // CT_FontReference
+ xRet.set( new StyleMatrixReferenceContext( this, rxAttributes, oox::drawingml::SHAPESTYLE_font, mrShape ) );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/spdefcontext.cxx b/oox/source/drawingml/spdefcontext.cxx
new file mode 100644
index 000000000000..55530b3ffefb
--- /dev/null
+++ b/oox/source/drawingml/spdefcontext.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: spdefcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:51 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/spdefcontext.hxx"
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/textbodypropertiescontext.hxx"
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+spDefContext::spDefContext( const ::oox::core::FragmentHandlerRef& xHandler, oox::drawingml::Shape& rDefaultObject )
+: Context( xHandler )
+, mrDefaultObject( rDefaultObject )
+{
+}
+
+Reference< XFastContextHandler > spDefContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_spPr:
+ {
+ xRet = new ShapePropertiesContext( this, mrDefaultObject );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_bodyPr:
+ {
+ xRet = new TextBodyPropertiesContext( this, xAttribs, mrDefaultObject );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_lstStyle:
+ xRet.set( new TextListStyleContext( getHandler(), *(mrDefaultObject.getMasterTextListStyle().get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_style:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/textbody.cxx b/oox/source/drawingml/textbody.cxx
new file mode 100644
index 000000000000..13afccddac2f
--- /dev/null
+++ b/oox/source/drawingml/textbody.cxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textbody.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <algorithm>
+#include <boost/bind.hpp>
+
+#include "oox/drawingml/textbody.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::frame;
+
+namespace oox { namespace drawingml {
+
+
+ TextBody::TextBody()
+ : mpTextListStyle( new TextListStyle() )
+ {
+ }
+
+ TextBody::~TextBody()
+ {
+ }
+
+
+
+ void TextBody::insertAt( const ::oox::core::XmlFilterBase& rFilterBase, const Reference < XText > & xText, const Reference < XTextCursor > & xAt,
+ const Reference < XModel > &xModel, const TextListStylePtr& pMasterTextListStylePtr )
+ {
+ TextListStylePtr aCombinedTextStyle( new TextListStyle( *(pMasterTextListStylePtr.get()) ) );
+ aCombinedTextStyle->apply( mpTextListStyle );
+
+ std::vector< TextParagraphPtr >::iterator begin( maParagraphs.begin() );
+ std::vector< TextParagraphPtr >::iterator end( maParagraphs.end() );
+ // apparently if there is no paragraph, it crashes. this is sort of the
+ // expected behavior.
+ while( begin != end )
+ {
+ (*begin)->insertAt( rFilterBase, xText, xAt, xModel, aCombinedTextStyle, begin == maParagraphs.begin() );
+ begin++;
+/*
+ std::for_each( begin, end,
+ boost::bind( &TextParagraph::insertAt, _1,
+ rFilterBase, xText, xAt, xModel, aCombinedTextStyle,
+ // determine whether it is the first paragraph of not
+ boost::bind( std::equal_to<TextParagraphPtr>(), _1,
+ *maParagraphs.begin() ) ) );
+*/
+ }
+ }
+
+
+} }
diff --git a/oox/source/drawingml/textbodycontext.cxx b/oox/source/drawingml/textbodycontext.cxx
new file mode 100644
index 000000000000..0636ece28713
--- /dev/null
+++ b/oox/source/drawingml/textbodycontext.cxx
@@ -0,0 +1,224 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textbodycontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textbodypropertiescontext.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/textparagraphpropertiescontext.hxx"
+#include "oox/drawingml/textcharacterpropertiescontext.hxx"
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/drawingml/textfieldcontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// --------------------------------------------------------------------
+
+// CT_TextParagraph
+class TextParagraphContext : public Context
+{
+public:
+ TextParagraphContext( const FragmentHandlerRef& xHandler, TextParagraph& rPara );
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException);
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
+
+protected:
+ TextParagraph& mrParagraph;
+};
+
+// --------------------------------------------------------------------
+TextParagraphContext::TextParagraphContext( const FragmentHandlerRef& xHandler, TextParagraph& rPara )
+: Context( xHandler )
+, mrParagraph( rPara )
+{
+}
+
+// --------------------------------------------------------------------
+void TextParagraphContext::endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException)
+{
+ if( aElementToken == (NMSP_DRAWINGML|XML_p) )
+ {
+ }
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextParagraphContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ // EG_TextRun
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_r: // "CT_RegularTextRun" Regular Text Run.
+ {
+ TextRunPtr pRun( new TextRun() );
+ mrParagraph.addRun( pRun );
+ xRet.set( new RegularTextRunContext( getHandler(), pRun ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_br: // "CT_TextLineBreak" Soft return line break (vertical tab).
+ {
+ TextRunPtr pRun( new TextRun() );
+ pRun->setLineBreak();
+ mrParagraph.addRun( pRun );
+ xRet.set( new RegularTextRunContext( getHandler(), pRun ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_fld: // "CT_TextField" Text Field.
+ {
+ TextFieldPtr pField( new TextField() );
+ mrParagraph.addRun( pField );
+ xRet.set( new TextFieldContext( this, xAttribs, pField ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, xAttribs, *(mrParagraph.getProperties().get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_endParaRPr:
+ xRet.set( new TextParagraphPropertiesContext( this, xAttribs, *(mrParagraph.getEndProperties().get()) ) );
+ break;
+ }
+
+ return xRet;
+}
+// --------------------------------------------------------------------
+
+RegularTextRunContext::RegularTextRunContext( const FragmentHandlerRef& xHandler, oox::drawingml::TextRunPtr pRunPtr )
+: Context( xHandler )
+, mpRunPtr( pRunPtr )
+, mbIsInText( false )
+{
+}
+
+// --------------------------------------------------------------------
+
+void RegularTextRunContext::endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_t:
+ {
+ mbIsInText = false;
+ break;
+ }
+ case NMSP_DRAWINGML|XML_r:
+ {
+ break;
+ }
+
+ }
+}
+
+// --------------------------------------------------------------------
+
+void RegularTextRunContext::characters( const OUString& aChars ) throw (SAXException, RuntimeException)
+{
+ if( mbIsInText )
+ {
+ mpRunPtr->text() += aChars;
+ }
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > RegularTextRunContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet( this );
+
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_rPr: // "CT_TextCharPropertyBag" The text char properties of this text run.
+ xRet.set( new TextCharacterPropertiesContext( this, xAttribs, *(mpRunPtr->getTextCharacterProperties().get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_t: // "xsd:string" minOccurs="1" The actual text string.
+ mbIsInText = true;
+ break;
+ }
+
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+TextBodyContext::TextBodyContext( const ::oox::core::FragmentHandlerRef& xHandler, oox::drawingml::Shape& rShape )
+: Context( xHandler )
+, mrShape( rShape )
+, mpBodyPtr( new TextBody() )
+{
+ rShape.setTextBody( mpBodyPtr );
+}
+
+// --------------------------------------------------------------------
+
+void TextBodyContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextBodyContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_bodyPr: // CT_TextBodyPropertyBag
+ xRet.set( new TextBodyPropertiesContext( this, xAttribs, mrShape ) );
+ break;
+ case NMSP_DRAWINGML|XML_lstStyle: // CT_TextListStyle
+ xRet.set( new TextListStyleContext( getHandler(), *(mpBodyPtr->getTextListStyle().get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_p: // CT_TextParagraph
+ TextParagraphPtr pPara( new TextParagraph() );
+ mpBodyPtr->addParagraph( pPara );
+ xRet.set( new TextParagraphContext( getHandler(), *(pPara.get()) ) );
+ break;
+ }
+
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/textbodypropertiescontext.cxx b/oox/source/drawingml/textbodypropertiescontext.cxx
new file mode 100644
index 000000000000..31b0aca30f7c
--- /dev/null
+++ b/oox/source/drawingml/textbodypropertiescontext.cxx
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textbodypropertiescontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textbodypropertiescontext.hxx"
+
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// --------------------------------------------------------------------
+
+// CT_TextBodyProperties
+TextBodyPropertiesContext::TextBodyPropertiesContext( const ::oox::core::ContextRef& xParent,
+ const Reference< XFastAttributeList >& xAttributes, Shape& rShape )
+: Context( xParent->getHandler() )
+, mrShape( rShape )
+{
+ AttributeList attribs(xAttributes);
+
+ // ST_TextWrappingType
+ sal_Int32 nWrappingType = xAttributes->getOptionalValueToken( XML_wrap, XML_square );
+ const OUString sTextWordWrap( RTL_CONSTASCII_USTRINGPARAM( "TextWordWrap" ) );
+ mrShape.getShapeProperties()[ sTextWordWrap ] <<= (nWrappingType == XML_square);
+
+ // ST_Coordinate
+ const OUString sTextLeftDistance( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) );
+ const OUString sTextUpperDistance( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) );
+ const OUString sTextRightDistance( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) );
+ const OUString sTextLowerDistance( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) );
+ OUString sValue;
+ sValue = xAttributes->getOptionalValue( XML_lIns );
+ sal_Int32 nLeftInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 91440 / 360 );
+ mrShape.getShapeProperties()[ sTextLeftDistance ] <<= static_cast< sal_Int32 >( nLeftInset );
+
+ sValue = xAttributes->getOptionalValue( XML_tIns );
+ sal_Int32 nTopInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 91440 / 360 );
+ mrShape.getShapeProperties()[ sTextUpperDistance ] <<= static_cast< sal_Int32 >( nTopInset );
+
+ sValue = xAttributes->getOptionalValue( XML_rIns );
+ sal_Int32 nRightInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 91440 / 360 );
+ mrShape.getShapeProperties()[ sTextRightDistance ] <<= static_cast< sal_Int32 >( nRightInset );
+
+ sValue = xAttributes->getOptionalValue( XML_bIns );
+ sal_Int32 nBottonInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 45720 / 360 );;
+ mrShape.getShapeProperties()[ sTextLowerDistance ] <<= static_cast< sal_Int32 >( nBottonInset );
+
+
+ // ST_TextAnchoringType
+// sal_Int32 nAnchoringType = xAttributes->getOptionalValueToken( XML_anchor, XML_t );
+
+// bool bAnchorCenter = attribs.getBool( XML_anchorCtr, false );
+
+// bool bCompatLineSpacing = attribs.getBool( XML_compatLnSpc, false );
+// bool bForceAA = attribs.getBool( XML_forceAA, false );
+// bool bFromWordArt = attribs.getBool( XML_fromWordArt, false );
+
+ // ST_TextHorzOverflowType
+// sal_Int32 nHorzOverflow = xAttributes->getOptionalValueToken( XML_horzOverflow, XML_overflow );
+ // ST_TextVertOverflowType
+// sal_Int32 nVertOverflow = xAttributes->getOptionalValueToken( XML_vertOverflow, XML_overflow );
+
+ // ST_TextColumnCount
+// sal_Int32 nNumCol = attribs.getInteger( XML_numCol, 1 );
+
+ // ST_Angle
+// sal_Int32 nRot = attribs.getInteger( XML_rot, 0 );
+// bool bRtlCol = attribs.getBool( XML_rtlCol, false );
+ // ST_PositiveCoordinate
+// sal_Int32 nSpcCol = attribs.getInteger( XML_spcCol, 0 );
+// bool bSpcFirstLastPara = attribs.getBool( XML_spcFirstLastPara, 0 );
+// bool bUpRight = attribs.getBool( XML_upright, 0 );
+ // ST_TextVerticalType
+// sal_Int32 nVert = xAttributes->getOptionalValueToken( XML_vert, XML_horz );
+}
+
+// --------------------------------------------------------------------
+
+void TextBodyPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextBodyPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& /*xAttributes*/) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ const OUString sTextAutoGrowHeight( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) );
+ switch( aElementToken )
+ {
+ // Sequence
+ case NMSP_DRAWINGML|XML_prstTxWarp: // CT_PresetTextShape
+ case NMSP_DRAWINGML|XML_prot: // CT_TextProtectionProperty
+ break;
+
+ // EG_TextAutofit
+ case NMSP_DRAWINGML|XML_noAutofit:
+ mrShape.getShapeProperties()[ sTextAutoGrowHeight ] <<= sal_False; // CT_TextNoAutofit
+ break;
+ case NMSP_DRAWINGML|XML_normAutofit: // CT_TextNormalAutofit
+ case NMSP_DRAWINGML|XML_spAutoFit:
+ mrShape.getShapeProperties()[ sTextAutoGrowHeight ] <<= sal_True;
+ break;
+
+ case NMSP_DRAWINGML|XML_scene3d: // CT_Scene3D
+
+ // EG_Text3D
+ case NMSP_DRAWINGML|XML_sp3d: // CT_Shape3D
+ case NMSP_DRAWINGML|XML_flatTx: // CT_FlatText
+
+ break;
+ }
+
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx
new file mode 100644
index 000000000000..999f1e6dccb4
--- /dev/null
+++ b/oox/source/drawingml/textcharacterproperties.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textcharacterproperties.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textcharacterproperties.hxx"
+
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+namespace oox { namespace drawingml {
+
+TextCharacterProperties::TextCharacterProperties()
+: maCharColorPtr( new Color() )
+, maUnderlineColorPtr( new Color() )
+, maHighlightColorPtr( new Color() )
+{
+}
+TextCharacterProperties::~TextCharacterProperties()
+{
+}
+void TextCharacterProperties::apply( const TextCharacterPropertiesPtr& rSourceTextCharacterPropertiesPtr )
+{
+ maTextCharacterPropertyMap.insert( rSourceTextCharacterPropertiesPtr->maTextCharacterPropertyMap.begin(), rSourceTextCharacterPropertiesPtr->maTextCharacterPropertyMap.end() );
+ maHyperlinkPropertyMap.insert( rSourceTextCharacterPropertiesPtr->maHyperlinkPropertyMap.begin(), rSourceTextCharacterPropertiesPtr->maHyperlinkPropertyMap.end() );
+ ColorPtr rSourceCharColor( rSourceTextCharacterPropertiesPtr->getCharColor() );
+ if ( rSourceCharColor->isUsed() )
+ maCharColorPtr = rSourceCharColor;
+ ColorPtr rSourceHighlightColor( rSourceTextCharacterPropertiesPtr->getHighlightColor() );
+ if ( rSourceHighlightColor->isUsed() )
+ maHighlightColorPtr = rSourceHighlightColor;
+ ColorPtr rSourceUnderlineColor( rSourceTextCharacterPropertiesPtr->getUnderlineColor() );
+ if ( rSourceUnderlineColor->isUsed() )
+ maUnderlineColorPtr = rSourceUnderlineColor;
+ Any& rHasUnderline = rSourceTextCharacterPropertiesPtr->getHasUnderline();
+ if ( rHasUnderline.hasValue() )
+ maHasUnderline = rHasUnderline;
+ Any& rUnderlineLineFollowText = rSourceTextCharacterPropertiesPtr->getUnderlineLineFollowText();
+ if ( rUnderlineLineFollowText.hasValue() )
+ maUnderlineLineFollowText = rUnderlineLineFollowText;
+ Any& rUnderlineFillFollowText = rSourceTextCharacterPropertiesPtr->getUnderlineFillFollowText();
+ if ( rUnderlineFillFollowText.hasValue() )
+ maUnderlineFillFollowText = rUnderlineFillFollowText;
+}
+void TextCharacterProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase, const Reference < XPropertySet > & xPropSet ) const
+{
+ PropertySet aPropSet( xPropSet );
+ Sequence< OUString > aNames;
+ Sequence< Any > aValues;
+
+// maTextCharacterPropertyMap.dump_debug("TextCharacter props");
+ maTextCharacterPropertyMap.makeSequence( aNames, aValues );
+ aPropSet.setProperties( aNames, aValues );
+ if ( maCharColorPtr->isUsed() )
+ {
+ const rtl::OUString sCharColor( CREATE_OUSTRING( "CharColor" ) );
+ aPropSet.setProperty( sCharColor, maCharColorPtr->getColor( rFilterBase ) );
+
+ }
+
+ sal_Bool bHasUnderline = sal_False;
+ sal_Bool bUnderlineFillFollowText = sal_False;
+ maHasUnderline >>= bHasUnderline;
+ maUnderlineFillFollowText >>= bUnderlineFillFollowText;
+ if( bHasUnderline )
+ {
+ if( maUnderlineColorPtr.get() && !bUnderlineFillFollowText )
+ {
+ const rtl::OUString sCharUnderlineColor( CREATE_OUSTRING( "CharUnderlineColor" ) );
+ aPropSet.setProperty( sCharUnderlineColor, maUnderlineColorPtr->getColor( rFilterBase ) );
+ const rtl::OUString sCharUnderlineHasColor( CREATE_OUSTRING( "CharUnderlineHasColor" ) );
+ aPropSet.setProperty( sCharUnderlineHasColor, Any( sal_True ) );
+ }
+ }
+}
+
+void TextCharacterProperties::pushToUrlFieldPropSet( const Reference < XPropertySet > & xPropSet ) const
+{
+ PropertySet aPropSet( xPropSet );
+ Sequence< OUString > aNames;
+ Sequence< Any > aValues;
+
+ maHyperlinkPropertyMap.makeSequence( aNames, aValues );
+ aPropSet.setProperties( aNames, aValues );
+}
+
+float TextCharacterProperties::getCharacterSize( float fDefault ) const
+{
+ const rtl::OUString sCharHeight( CREATE_OUSTRING( "CharHeight" ) );
+ float fCharHeight;
+ const Any* pAny = maTextCharacterPropertyMap.getPropertyValue( sCharHeight );
+ if ( pAny && ( *pAny >>= fCharHeight ) )
+ return fCharHeight;
+ else
+ return fDefault;
+}
+
+} }
diff --git a/oox/source/drawingml/textcharacterpropertiescontext.cxx b/oox/source/drawingml/textcharacterpropertiescontext.cxx
new file mode 100644
index 000000000000..21ef91063726
--- /dev/null
+++ b/oox/source/drawingml/textcharacterpropertiescontext.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textcharacterpropertiescontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textcharacterpropertiescontext.hxx"
+
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/relations.hxx"
+#include "textfontcontext.hxx"
+#include "hyperlinkcontext.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::awt;
+
+namespace oox { namespace drawingml {
+
+// --------------------------------------------------------------------
+
+// CT_TextCharacterProperties
+TextCharacterPropertiesContext::TextCharacterPropertiesContext( const ::oox::core::ContextRef& xParent,
+ const Reference< XFastAttributeList >& rXAttributes,
+ oox::drawingml::TextCharacterProperties& rTextCharacterProperties )
+: Context( xParent->getHandler() )
+, mrTextCharacterProperties( rTextCharacterProperties )
+{
+ AttributeList attribs( rXAttributes );
+ PropertyMap& rPropertyMap( mrTextCharacterProperties.getTextCharacterPropertyMap() );
+
+ rtl::OUString aVal( rXAttributes->getOptionalValue( XML_sz ) );
+ if ( aVal.getLength() )
+ {
+ float fTextSize = GetTextSize( aVal );
+ const rtl::OUString sCharHeight( CREATE_OUSTRING( "CharHeight" ) );
+ const rtl::OUString sCharHeightAsian( CREATE_OUSTRING( "CharHeightAsian" ) );
+ const rtl::OUString sCharHeightComplex( CREATE_OUSTRING( "CharHeightComplex" ) );
+ rPropertyMap[ sCharHeight ] <<= fTextSize;
+ rPropertyMap[ sCharHeightAsian ] <<= fTextSize;
+ rPropertyMap[ sCharHeightComplex ] <<= fTextSize;
+ }
+
+ bool bIsBold = attribs.getBool( XML_b, false );
+ const rtl::OUString sCharWeight( CREATE_OUSTRING( "CharWeight" ) );
+ const rtl::OUString sCharWeightAsian( CREATE_OUSTRING( "CharWeightAsian" ) );
+ const rtl::OUString sCharWeightComplex( CREATE_OUSTRING( "CharWeightComplex" ) );
+ rPropertyMap[ sCharWeight ] <<= ( bIsBold ? FontWeight::BOLD : FontWeight::NORMAL );
+ rPropertyMap[ sCharWeightAsian ] <<= ( bIsBold ? FontWeight::BOLD : FontWeight::NORMAL );
+ rPropertyMap[ sCharWeightComplex ] <<= ( bIsBold ? FontWeight::BOLD : FontWeight::NORMAL );
+
+ bool bIsItalic = attribs.getBool( XML_i, false );
+ const rtl::OUString sCharFontPosture( CREATE_OUSTRING( "CharPosture" ) );
+ const rtl::OUString sCharFontPostureAsian( CREATE_OUSTRING( "CharPostureAsian" ) );
+ const rtl::OUString sCharFontPostureComplex( CREATE_OUSTRING( "CharPostureComplex" ) );
+ rPropertyMap[ sCharFontPosture ] <<= ( bIsItalic ? FontSlant_ITALIC : FontSlant_NONE );
+ rPropertyMap[ sCharFontPostureAsian ] <<= ( bIsItalic ? FontSlant_ITALIC : FontSlant_NONE );
+ rPropertyMap[ sCharFontPostureComplex ] <<= ( bIsItalic ? FontSlant_ITALIC : FontSlant_NONE );
+
+ sal_Int32 nFontUnderline( rXAttributes->getOptionalValueToken( XML_u, 0 ) );
+ if ( nFontUnderline )
+ {
+ const rtl::OUString sCharUnderline( CREATE_OUSTRING( "CharUnderline" ) );
+ rPropertyMap[ sCharUnderline ] <<= GetFontUnderline( nFontUnderline );
+ mrTextCharacterProperties.getHasUnderline() <<= sal_True;
+ }
+
+ const rtl::OUString sCharStrikeout( CREATE_OUSTRING( "CharStrikeout" ) );
+ rPropertyMap[ sCharStrikeout ] <<= GetFontStrikeout( rXAttributes->getOptionalValueToken( XML_strike, XML_noStrike ) );
+
+ // ST_TextCapsType
+ const rtl::OUString sCharCaseMap( CREATE_OUSTRING( "CharCaseMap" ) );
+ rPropertyMap[ sCharCaseMap ] <<= GetCaseMap( rXAttributes->getOptionalValueToken( XML_cap, XML_none ) );
+
+
+ OUString sLang = rXAttributes->getOptionalValue( XML_lang );
+ if( sLang.getLength( ) )
+ {
+ const rtl::OUString sCharLocale( CREATE_OUSTRING( "CharLocale" ) );
+ const rtl::OUString sCharLocaleAsian( CREATE_OUSTRING( "CharLocaleAsian" ) );
+ const rtl::OUString sCharLocaleComplex( CREATE_OUSTRING( "CharLocaleComplex" ) );
+
+ com::sun::star::lang::Locale aLocale;
+ OUString aString( sLang );
+ sal_Int32 nSepPos = aString.indexOf( (sal_Unicode)'-', 0 );
+ if ( nSepPos != -1 )
+ {
+ aLocale.Language = aString.copy( 0, nSepPos );
+ aLocale.Country = aString.copy( nSepPos+1 );
+ }
+ else
+ {
+ aLocale.Language = aString;
+ }
+
+ rPropertyMap[ sCharLocale ] <<= aLocale;
+ rPropertyMap[ sCharLocaleAsian ] <<= aLocale;
+ rPropertyMap[ sCharLocaleComplex ] <<= aLocale;
+ }
+
+
+// TODO
+/* todo: we need to be able to iterate over the XFastAttributes
+
+ // ST_TextNonNegativePoint
+ const rtl::OUString sCharKerning( CREATE_OUSTRING( "CharKerning" ) );
+ //case NMSP_DRAWINGML|XML_kern:
+
+ // ST_TextLanguageID
+ OUString sAltLang = rXAttributes->getOptionalValue( XML_altLang );
+
+ case NMSP_DRAWINGML|XML_kumimoji: // xsd:boolean
+ break;
+ case NMSP_DRAWINGML|XML_spc: // ST_TextPoint
+ case NMSP_DRAWINGML|XML_normalizeH: // xsd:boolean
+ case NMSP_DRAWINGML|XML_baseline: // ST_Percentage
+ case NMSP_DRAWINGML|XML_noProof: // xsd:boolean
+ case NMSP_DRAWINGML|XML_dirty: // xsd:boolean
+ case NMSP_DRAWINGML|XML_err: // xsd:boolean
+ case NMSP_DRAWINGML|XML_smtClean: // xsd:boolean
+ case NMSP_DRAWINGML|XML_smtId: // xsd:unsignedInt
+ break;
+*/
+
+}
+
+TextCharacterPropertiesContext::~TextCharacterPropertiesContext()
+{
+ PropertyMap& rPropertyMap( mrTextCharacterProperties.getTextCharacterPropertyMap() );
+
+ sal_Int16 nPitch, nFamily;
+
+ if( maLatinFont.is() )
+ {
+ const rtl::OUString sCharFontName( CREATE_OUSTRING( "CharFontName" ) );
+ const rtl::OUString sCharFontPitch( CREATE_OUSTRING( "CharFontPitch" ) );
+ const rtl::OUString sCharFontFamily( CREATE_OUSTRING( "CharFontFamily" ) );
+ GetFontPitch( maLatinFont.mnPitch, nPitch, nFamily);
+ rPropertyMap[ sCharFontName ] <<= maLatinFont.msTypeface;
+ rPropertyMap[ sCharFontPitch ] <<= nPitch;
+ rPropertyMap[ sCharFontFamily ] <<= nFamily;
+ }
+ if( maAsianFont.is() )
+ {
+ const rtl::OUString sCharFontNameAsian( CREATE_OUSTRING( "CharFontNameAsian" ) );
+ const rtl::OUString sCharFontPitchAsian( CREATE_OUSTRING( "CharFontPitchAsian" ) );
+ const rtl::OUString sCharFontFamilyAsian( CREATE_OUSTRING( "CharFontFamilyAsian" ) );
+ GetFontPitch( maAsianFont.mnPitch, nPitch, nFamily);
+ rPropertyMap[ sCharFontNameAsian ] <<= maAsianFont.msTypeface;
+ rPropertyMap[ sCharFontPitchAsian ] <<= nFamily;
+ rPropertyMap[ sCharFontFamilyAsian ] <<= nPitch;
+ }
+ if( maComplexFont.is() )
+ {
+ const rtl::OUString sCharFontNameComplex( CREATE_OUSTRING( "CharFontNameComplex" ) );
+ const rtl::OUString sCharFontPitchComplex( CREATE_OUSTRING( "CharFontPitchComplex" ) );
+ const rtl::OUString sCharFontFamilyComplex( CREATE_OUSTRING( "CharFontFamilyComplex" ) );
+ GetFontPitch( maComplexFont.mnPitch, nPitch, nFamily );
+ rPropertyMap[ sCharFontNameComplex ] <<= maComplexFont.msTypeface;
+ rPropertyMap[ sCharFontPitchComplex ] <<= nPitch;
+ rPropertyMap[ sCharFontFamilyComplex ] <<= nFamily;
+ }
+}
+
+// --------------------------------------------------------------------
+
+void TextCharacterPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextCharacterPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttributes ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ // not supported.....
+ case NMSP_DRAWINGML|XML_ln: // CT_LineProperties
+// TODO unsupported yet
+// xRet.set( new LinePropertiesContext( getHandler(), xAttributes, maTextOutlineProperties ) );
+ break;
+ // EG_FillProperties
+ case NMSP_DRAWINGML|XML_solidFill:
+ xRet.set( new colorChoiceContext( getHandler(), *(mrTextCharacterProperties.getCharColor().get()) ) );
+ break;
+ // EG_EffectProperties
+ case NMSP_DRAWINGML|XML_effectDag:
+ // CT_EffectContainer 5.1.10.25
+ case NMSP_DRAWINGML|XML_effectLst:
+ // CT_EffectList 5.1.10.26
+ break;
+
+ case NMSP_DRAWINGML|XML_highlight: //CT_Color
+ xRet.set( new colorChoiceContext( getHandler(), *(mrTextCharacterProperties.getHighlightColor().get()) ) );
+ break;
+
+ // EG_TextUnderlineLine
+ case NMSP_DRAWINGML|XML_uLnTx: // CT_TextUnderlineLineFollowText
+ mrTextCharacterProperties.getUnderlineLineFollowText() <<= sal_True;
+ break;
+ case NMSP_DRAWINGML|XML_uLn: // CT_LineProperties
+// TODO unsupported yet
+// xRet.set( new LinePropertiesContext( getHandler(), xAttributes, maUnderlineProperties ) );
+ break;
+
+ // EG_TextUnderlineFill
+ case NMSP_DRAWINGML|XML_uFillTx: // CT_TextUnderlineFillFollowText
+ mrTextCharacterProperties.getUnderlineFillFollowText() <<= sal_True;
+ break;
+ case NMSP_DRAWINGML|XML_uFill: // CT_TextUnderlineFillGroupWrapper->EG_FillProperties (not supported)
+ xRet.set( new colorChoiceContext( getHandler(), *(mrTextCharacterProperties.getUnderlineColor().get()) ) );
+ break;
+
+ case NMSP_DRAWINGML|XML_ea: // CT_TextFont
+ xRet.set( new TextFontContext( getHandler(), aElementToken, xAttributes, maAsianFont ) );
+ break;
+ case NMSP_DRAWINGML|XML_cs: // CT_TextFont
+ xRet.set( new TextFontContext( getHandler(), aElementToken, xAttributes, maComplexFont ) );
+ break;
+ case NMSP_DRAWINGML|XML_sym: // CT_TextFont
+ xRet.set( new TextFontContext( getHandler(), aElementToken, xAttributes, maSymbolFont ) );
+ break;
+ case NMSP_DRAWINGML|XML_latin: // CT_TextFont
+ xRet.set( new TextFontContext( getHandler(), aElementToken, xAttributes, maLatinFont ) );
+ break;
+ case NMSP_DRAWINGML|XML_hlinkClick: // CT_Hyperlink
+ case NMSP_DRAWINGML|XML_hlinkMouseOver: // CT_Hyperlink
+ xRet.set( new HyperLinkContext( getHandler(), xAttributes, mrTextCharacterProperties.getHyperlinkPropertyMap() ) );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/textfield.cxx b/oox/source/drawingml/textfield.cxx
new file mode 100644
index 000000000000..7ae2ba947dd7
--- /dev/null
+++ b/oox/source/drawingml/textfield.cxx
@@ -0,0 +1,196 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textfield.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textfield.hxx"
+
+#include <list>
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+
+#include "oox/helper/helper.hxx"
+#include "oox/drawingml/textparagraphproperties.hxx"
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+
+namespace oox { namespace drawingml {
+
+ TextField::TextField()
+ : mpTextParagraphPropertiesPtr( new TextParagraphProperties())
+ {
+ }
+
+
+ /** intsanciate the textfields. Because of semantics difference between
+ * OpenXML and OpenOffice, some OpenXML field might cause two fields to be created.
+ * @param aFields the created fields. The list is empty if no field has been created.
+ * @param xModel the model
+ * @param sType the OpenXML field type.
+ */
+ static void createTextFields( std::list< Reference< XTextField > > & aFields,
+ const Reference< XModel > & xModel, const OUString & sType )
+ {
+ Reference< XInterface > xIface;
+ Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
+
+ if( sType.compareToAscii( "datetime", 8 ) == 0)
+ {
+ OString s = ::rtl::OUStringToOString( sType, RTL_TEXTENCODING_UTF8);
+ OString p( s.pData->buffer + 8 );
+ try
+ {
+ bool bIsDate = true;
+ int idx = p.toInt32();
+// OSL_TRACE( "OOX: p = %s, %d", p.pData->buffer, idx );
+ xIface = xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.text.TextField.DateTime" ) );
+ aFields.push_back( Reference< XTextField > ( xIface, UNO_QUERY ) );
+ Reference< XPropertySet > xProps( xIface, UNO_QUERY_THROW );
+
+ // here we should format the field properly. waiting after #i81091.
+ switch( idx )
+ {
+ case 1: // Date dd/mm/yyyy
+ // this is the default format...
+ break;
+ case 2: // Date Day, Month dd, yyyy
+ break;
+ case 3: // Date dd Month yyyy
+ break;
+ case 4: // Date Month dd, yyyy
+ break;
+ case 5: // Date dd-Mon-yy
+ break;
+ case 6: // Date Month yy
+ break;
+ case 7: // Date Mon-yy
+ break;
+ case 8: // DateTime dd/mm/yyyy H:MM PM
+ createTextFields( aFields, xModel, CREATE_OUSTRING( "datetime12" ) );
+ break;
+ case 9: // DateTime dd/mm/yy H:MM:SS PM
+ createTextFields( aFields, xModel, CREATE_OUSTRING( "datetime13" ) );
+ break;
+ case 10: // Time H:MM
+ bIsDate = false;
+ break;
+ case 11: // Time H:MM:SS
+ bIsDate = false;
+ // this is the default format
+ break;
+ case 12: // Time H:MM PM
+ bIsDate = false;
+ break;
+ case 13: // Time H:MM:SS PM
+ bIsDate = false;
+ break;
+ }
+ xProps->setPropertyValue( CREATE_OUSTRING( "IsDate" ), makeAny( bIsDate ) );
+ xProps->setPropertyValue( CREATE_OUSTRING( "IsFixed" ), makeAny( false ) );
+ }
+ catch(Exception & e)
+ {
+ OSL_TRACE( "Exception %s", OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+ }
+ else if ( sType.compareToAscii( "slidenum" ) == 0 )
+ {
+ xIface = xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.text.TextField.PageNumber" ) );
+ aFields.push_back( Reference< XTextField > ( xIface, UNO_QUERY ) );
+ }
+ }
+
+ void TextField::insertAt( const ::oox::core::XmlFilterBase& rFilterBase, const Reference < XText > & xText,
+ const Reference < XTextCursor > &xAt,
+ const Reference< XModel > &xModel,
+ const TextCharacterPropertiesPtr& rTextCharacterStyle )
+ {
+ try {
+
+ PropertyMap aioBulletList;
+ Reference< XTextRange > xStart( xAt, UNO_QUERY );
+ Reference< XPropertySet > xProps( xStart, UNO_QUERY);
+ mpTextParagraphPropertiesPtr->pushToPropSet( rFilterBase, xProps, aioBulletList, sal_True );
+
+ if ( rTextCharacterStyle.get() )
+ rTextCharacterStyle->pushToPropSet( rFilterBase, xProps );
+
+ maTextCharacterPropertiesPtr->pushToPropSet( rFilterBase, xProps );
+
+ std::list< Reference< XTextField > > fields;
+ createTextFields( fields, xModel, msType );
+ if( !fields.empty() )
+ {
+ bool bFirst = true;
+ for( std::list< Reference< XTextField > >::iterator iter = fields.begin();
+ iter != fields.end(); ++iter )
+ {
+ if( iter->is() )
+ {
+ Reference< XTextContent > xContent( *iter, UNO_QUERY);
+ if( bFirst)
+ {
+ bFirst = false;
+ }
+ else
+ {
+ xText->insertString( xStart, CREATE_OUSTRING( " " ), sal_False );
+ }
+ xText->insertTextContent( xStart, xContent, sal_False );
+ }
+ }
+ }
+ else
+ {
+ xText->insertString( xStart, text(), sal_False );
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_TRACE("OOX: TextField::insertAt() exception");
+ }
+ }
+
+
+} }
diff --git a/oox/source/drawingml/textfieldcontext.cxx b/oox/source/drawingml/textfieldcontext.cxx
new file mode 100644
index 000000000000..00845ee76862
--- /dev/null
+++ b/oox/source/drawingml/textfieldcontext.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textfieldcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <rtl/ustring.hxx>
+
+#include "oox/drawingml/textparagraphpropertiescontext.hxx"
+#include "oox/drawingml/textcharacterpropertiescontext.hxx"
+#include "oox/drawingml/textfieldcontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+ TextFieldContext::TextFieldContext( const ContextRef& xParent,
+ const Reference< XFastAttributeList >& rXAttributes,
+ const TextFieldPtr & pTextField)
+ : Context( xParent->getHandler() )
+ , mpTextField( pTextField )
+ , mbIsInText( false )
+ {
+ try {
+ pTextField->setUuid( rXAttributes->getValue( XML_id ) );
+ }
+ catch(...)
+ {
+
+ }
+ pTextField->setType( rXAttributes->getOptionalValue( XML_type ) );
+ }
+
+ void TextFieldContext::endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException)
+ {
+ if( aElementToken == (NMSP_DRAWINGML|XML_t) )
+ {
+ mbIsInText = false;
+ }
+ }
+
+ void TextFieldContext::characters( const OUString& aChars ) throw (SAXException, RuntimeException)
+ {
+ if( mbIsInText )
+ {
+ mpTextField->text() += aChars;
+ }
+ }
+
+ Reference< XFastContextHandler > TextFieldContext::createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_rPr:
+ xRet.set( new TextCharacterPropertiesContext( this, xAttribs, *(mpTextField->getTextCharacterProperties().get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, xAttribs, *(mpTextField->getTextParagraphProperties().get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_t:
+ mbIsInText = true;
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+
+} }
diff --git a/oox/source/drawingml/textliststyle.cxx b/oox/source/drawingml/textliststyle.cxx
new file mode 100644
index 000000000000..fec174159497
--- /dev/null
+++ b/oox/source/drawingml/textliststyle.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textliststyle.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textliststyle.hxx"
+
+namespace oox { namespace drawingml {
+
+TextListStyle::TextListStyle()
+ : maListStyle()
+ , maAggregationListStyle()
+{
+ int i;
+ for ( i = 0; i < 9; i++ )
+ maListStyle.push_back( TextParagraphPropertiesPtr( new TextParagraphProperties() ) );
+ for ( i = 0; i < 9; i++ )
+ maAggregationListStyle.push_back( TextParagraphPropertiesPtr( new TextParagraphProperties() ) );
+}
+TextListStyle::~TextListStyle()
+{
+}
+
+void applyStyleList( const std::vector< ::oox::drawingml::TextParagraphPropertiesPtr >& rSourceListStyle,
+ std::vector< ::oox::drawingml::TextParagraphPropertiesPtr >& rDestListStyle )
+{
+ std::vector< ::oox::drawingml::TextParagraphPropertiesPtr >::const_iterator aSourceListStyleIter( rSourceListStyle.begin() );
+ std::vector< ::oox::drawingml::TextParagraphPropertiesPtr >::iterator aDestListStyleIter( rDestListStyle.begin() );
+ while( aSourceListStyleIter != rSourceListStyle.end() )
+ {
+ if ( aDestListStyleIter != rDestListStyle.end() )
+ {
+ (*aDestListStyleIter)->apply( *aSourceListStyleIter );
+ aDestListStyleIter++;
+ }
+ else
+ rDestListStyle.push_back( TextParagraphPropertiesPtr( new oox::drawingml::TextParagraphProperties( *(*aSourceListStyleIter).get() ) ) );
+ aSourceListStyleIter++;
+ }
+}
+
+void TextListStyle::apply( const TextListStylePtr& rTextListStylePtr )
+{
+ applyStyleList( rTextListStylePtr->getAggregationListStyle(), getAggregationListStyle() );
+ applyStyleList( rTextListStylePtr->getListStyle(), getListStyle() );
+}
+
+} }
diff --git a/oox/source/drawingml/textliststylecontext.cxx b/oox/source/drawingml/textliststylecontext.cxx
new file mode 100644
index 000000000000..1e8b33b0fbd1
--- /dev/null
+++ b/oox/source/drawingml/textliststylecontext.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textliststylecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/drawingml/textparagraphpropertiescontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// --------------------------------------------------------------------
+
+// CT_TextListStyle
+TextListStyleContext::TextListStyleContext( const ::oox::core::FragmentHandlerRef& xHandler, oox::drawingml::TextListStyle& rTextListStyle )
+: Context( xHandler )
+, mrTextListStyle( rTextListStyle )
+{
+}
+
+TextListStyleContext::~TextListStyleContext()
+{
+}
+
+// --------------------------------------------------------------------
+
+void TextListStyleContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextListStyleContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& rxAttributes ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_defPPr: // CT_TextParagraphProperties
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 0 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_outline1pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getAggregationListStyle()[ 0 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_outline2pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getAggregationListStyle()[ 1 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl1pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 0 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl2pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 1 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl3pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 2 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl4pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 3 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl5pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 4 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl6pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 5 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl7pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 6 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl8pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 7 ].get()) ) );
+ break;
+ case NMSP_DRAWINGML|XML_lvl9pPr:
+ xRet.set( new TextParagraphPropertiesContext( this, rxAttributes, *(mrTextListStyle.getListStyle()[ 8 ].get()) ) );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/textparagraph.cxx b/oox/source/drawingml/textparagraph.cxx
new file mode 100644
index 000000000000..e078e899282d
--- /dev/null
+++ b/oox/source/drawingml/textparagraph.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textparagraph.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#include <algorithm>
+#include <boost/bind.hpp>
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include "oox/drawingml/textparagraph.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+
+namespace oox { namespace drawingml {
+
+ TextParagraph::TextParagraph()
+ : mpProperties( new TextParagraphProperties( ) )
+ , mpEndProperties( new TextParagraphProperties( ) )
+ {
+ }
+
+
+ TextParagraph::~TextParagraph()
+ {
+ }
+
+
+ void TextParagraph::insertAt( const ::oox::core::XmlFilterBase& rFilterBase, const Reference < XText > &xText, const Reference < XTextCursor > &xAt, const Reference < XModel > &xModel,
+ const TextListStylePtr& rTextStyleList, bool bFirst)
+ {
+ try {
+ sal_Int32 nParagraphSize = 0;
+ Reference< XTextRange > xStart( xAt, UNO_QUERY );
+
+ sal_Int16 nLevel = mpProperties->getLevel();
+ std::vector< ::oox::drawingml::TextParagraphPropertiesPtr >& rListStyle = rTextStyleList->getListStyle();
+ if ( nLevel >= static_cast< sal_Int16 >( rListStyle.size() ) )
+ nLevel = 0;
+ TextParagraphPropertiesPtr pTextParagraphStyle;
+ TextCharacterPropertiesPtr pTextCharacterStyle;
+ if ( rListStyle.size() )
+ pTextParagraphStyle = rListStyle[ nLevel ];
+ if ( pTextParagraphStyle.get() )
+ pTextCharacterStyle = pTextParagraphStyle->getTextCharacterProperties();
+
+ if( !bFirst )
+ {
+ xText->insertControlCharacter( xStart, ControlCharacter::APPEND_PARAGRAPH, sal_False );
+ xAt->gotoEnd(true);
+ }
+
+ std::vector< TextRunPtr >::iterator begin( maRuns.begin() );
+ while( begin != maRuns.end() )
+ {
+ (*begin)->insertAt( rFilterBase, xText, xAt, xModel, pTextCharacterStyle );
+ nParagraphSize += (*begin++)->text().getLength();
+ }
+ xAt->gotoEnd(true);
+
+ PropertyMap aioBulletList;
+ Reference< XPropertySet > xProps( xStart, UNO_QUERY);
+ if ( pTextParagraphStyle.get() )
+ pTextParagraphStyle->pushToPropSet( rFilterBase, xProps, aioBulletList, sal_False );
+
+ mpProperties->pushToPropSet( rFilterBase, xProps, aioBulletList, sal_True );
+
+ // empty paragraphs do not have bullets in ppt
+ if ( !nParagraphSize )
+ {
+ const rtl::OUString sIsNumbering( CREATE_OUSTRING( "IsNumbering" ) );
+ xProps->setPropertyValue( sIsNumbering, Any( sal_False ) );
+ }
+
+// FIXME this is causing a lot of dispruption (ie does not work). I wonder what to do -- Hub
+// Reference< XTextRange > xEnd( xAt, UNO_QUERY );
+// Reference< XPropertySet > xProps2( xEnd, UNO_QUERY );
+// mpEndProperties->pushToPropSet( xProps2 );
+ }
+ catch( Exception & )
+ {
+ OSL_TRACE("OOX: exception in TextParagraph::insertAt");
+ }
+ }
+
+
+} }
+
diff --git a/oox/source/drawingml/textparagraphproperties.cxx b/oox/source/drawingml/textparagraphproperties.cxx
new file mode 100644
index 000000000000..e29cbf823aa2
--- /dev/null
+++ b/oox/source/drawingml/textparagraphproperties.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textparagraphproperties.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textparagraphproperties.hxx"
+
+#include <com/sun/star/text/XNumberingRulesSupplier.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using ::com::sun::star::awt::FontDescriptor;
+
+namespace oox { namespace drawingml {
+
+BulletList::BulletList( )
+: maBulletColorPtr( new Color() )
+{
+}
+
+bool BulletList::is() const
+{
+ return mnNumberingType.hasValue();
+}
+
+void BulletList::setBulletChar( const ::rtl::OUString & sChar )
+{
+ mnNumberingType <<= NumberingType::CHAR_SPECIAL;
+ msBulletChar <<= sChar;
+}
+
+void BulletList::setNone( )
+{
+ mnNumberingType <<= NumberingType::NUMBER_NONE;
+}
+
+void BulletList::setSuffixParenBoth()
+{
+ msNumberingSuffix <<= CREATE_OUSTRING( ")" );
+ msNumberingPrefix <<= CREATE_OUSTRING( "(" );
+}
+
+void BulletList::setSuffixParenRight()
+{
+ msNumberingSuffix <<= CREATE_OUSTRING( ")" );
+ msNumberingPrefix <<= OUString();
+}
+
+void BulletList::setSuffixPeriod()
+{
+ msNumberingSuffix <<= CREATE_OUSTRING( "." );
+ msNumberingPrefix <<= OUString();
+}
+
+void BulletList::setSuffixNone()
+{
+ msNumberingSuffix <<= OUString();
+ msNumberingPrefix <<= OUString();
+}
+
+void BulletList::setSuffixMinusRight()
+{
+ msNumberingSuffix <<= CREATE_OUSTRING( "-" );
+ msNumberingPrefix <<= OUString();
+}
+
+void BulletList::setType( sal_Int32 nType )
+{
+// OSL_TRACE( "OOX: set list numbering type %d", nType);
+ switch( nType )
+ {
+ case XML_alphaLcParenBoth:
+ mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
+ setSuffixParenBoth();
+ break;
+ case XML_alphaLcParenR:
+ mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
+ setSuffixParenRight();
+ break;
+ case XML_alphaLcPeriod:
+ mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
+ setSuffixPeriod();
+ break;
+ case XML_alphaUcParenBoth:
+ mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
+ setSuffixParenBoth();
+ break;
+ case XML_alphaUcParenR:
+ mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
+ setSuffixParenRight();
+ break;
+ case XML_alphaUcPeriod:
+ mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
+ setSuffixPeriod();
+ break;
+ case XML_arabic1Minus:
+ case XML_arabic2Minus:
+ case XML_arabicDbPeriod:
+ case XML_arabicDbPlain:
+ // TODO
+ break;
+ case XML_arabicParenBoth:
+ mnNumberingType <<= NumberingType::ARABIC;
+ setSuffixParenBoth();
+ break;
+ case XML_arabicParenR:
+ mnNumberingType <<= NumberingType::ARABIC;
+ setSuffixParenRight();
+ break;
+ case XML_arabicPeriod:
+ mnNumberingType <<= NumberingType::ARABIC;
+ setSuffixPeriod();
+ break;
+ case XML_arabicPlain:
+ mnNumberingType <<= NumberingType::ARABIC;
+ setSuffixNone();
+ break;
+ case XML_circleNumDbPlain:
+ case XML_circleNumWdBlackPlain:
+ case XML_circleNumWdWhitePlain:
+ mnNumberingType <<= NumberingType::CIRCLE_NUMBER;
+ break;
+ case XML_ea1ChsPeriod:
+ mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
+ setSuffixPeriod();
+ break;
+ case XML_ea1ChsPlain:
+ mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
+ setSuffixNone();
+ break;
+ case XML_ea1ChtPeriod:
+ mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
+ setSuffixPeriod();
+ break;
+ case XML_ea1ChtPlain:
+ mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
+ setSuffixNone();
+ break;
+ case XML_ea1JpnChsDbPeriod:
+ case XML_ea1JpnKorPeriod:
+ case XML_ea1JpnKorPlain:
+ break;
+ case XML_hebrew2Minus:
+ mnNumberingType <<= NumberingType::CHARS_HEBREW;
+ setSuffixMinusRight();
+ break;
+ case XML_hindiAlpha1Period:
+ case XML_hindiAlphaPeriod:
+ case XML_hindiNumParenR:
+ case XML_hindiNumPeriod:
+ // TODO
+ break;
+ case XML_romanLcParenBoth:
+ mnNumberingType <<= NumberingType::ROMAN_LOWER;
+ setSuffixParenBoth();
+ break;
+ case XML_romanLcParenR:
+ mnNumberingType <<= NumberingType::ROMAN_LOWER;
+ setSuffixParenRight();
+ break;
+ case XML_romanLcPeriod:
+ mnNumberingType <<= NumberingType::ROMAN_LOWER;
+ setSuffixPeriod();
+ break;
+ case XML_romanUcParenBoth:
+ mnNumberingType <<= NumberingType::ROMAN_UPPER;
+ setSuffixParenBoth();
+ break;
+ case XML_romanUcParenR:
+ mnNumberingType <<= NumberingType::ROMAN_UPPER;
+ setSuffixParenRight();
+ break;
+ case XML_romanUcPeriod:
+ mnNumberingType <<= NumberingType::ROMAN_UPPER;
+ setSuffixPeriod();
+ break;
+ case XML_thaiAlphaParenBoth:
+ case XML_thaiNumParenBoth:
+ mnNumberingType <<= NumberingType::CHARS_THAI;
+ setSuffixParenBoth();
+ break;
+ case XML_thaiAlphaParenR:
+ case XML_thaiNumParenR:
+ mnNumberingType <<= NumberingType::CHARS_THAI;
+ setSuffixParenRight();
+ break;
+ case XML_thaiAlphaPeriod:
+ case XML_thaiNumPeriod:
+ mnNumberingType <<= NumberingType::CHARS_THAI;
+ setSuffixPeriod();
+ break;
+ }
+}
+
+void BulletList::setBulletSize(sal_Int16 nSize)
+{
+ mnSize <<= nSize;
+}
+
+
+void BulletList::setFontSize(sal_Int16 nSize)
+{
+ mnFontSize <<= nSize;
+}
+
+void BulletList::apply( const BulletList& rSource )
+{
+ if ( rSource.maBulletColorPtr->isUsed() )
+ maBulletColorPtr = rSource.maBulletColorPtr;
+ if ( rSource.mbBulletColorFollowText.hasValue() )
+ mbBulletColorFollowText = rSource.mbBulletColorFollowText;
+ if ( rSource.mbBulletFontFollowText.hasValue() )
+ mbBulletFontFollowText = rSource.mbBulletFontFollowText;
+ if ( rSource.maBulletFont.is() )
+ maBulletFont = rSource.maBulletFont;
+ if ( rSource.msBulletChar.hasValue() )
+ msBulletChar = rSource.msBulletChar;
+ if ( rSource.mnStartAt.hasValue() )
+ mnStartAt = rSource.mnStartAt;
+ if ( rSource.mnNumberingType.hasValue() )
+ mnNumberingType = rSource.mnNumberingType;
+ if ( rSource.msNumberingPrefix.hasValue() )
+ msNumberingPrefix = rSource.msNumberingPrefix;
+ if ( rSource.msNumberingSuffix.hasValue() )
+ msNumberingSuffix = rSource.msNumberingSuffix;
+ if ( rSource.mnSize.hasValue() )
+ mnSize = rSource.mnSize;
+ if ( rSource.mnFontSize.hasValue() )
+ mnFontSize = rSource.mnFontSize;
+ if ( rSource.maStyleName.hasValue() )
+ maStyleName = rSource.maStyleName;
+}
+
+void BulletList::pushToPropMap( const ::oox::core::XmlFilterBase& rFilterBase, PropertyMap& rPropMap ) const
+{
+ if( msNumberingPrefix.hasValue() )
+ {
+// OSL_TRACE( "OOX: numb prefix found");
+ const rtl::OUString sPrefix( CREATE_OUSTRING( "Prefix" ) );
+ rPropMap[ sPrefix ] = msNumberingPrefix;
+ }
+ if( msNumberingSuffix.hasValue() )
+ {
+// OSL_TRACE( "OOX: numb suffix found");
+ const rtl::OUString sSuffix( CREATE_OUSTRING( "Suffix" ) );
+ rPropMap[ sSuffix ] = msNumberingSuffix;
+ }
+ if( mnStartAt.hasValue() )
+ {
+ const rtl::OUString sStartWith( CREATE_OUSTRING( "StartWith" ) );
+ rPropMap[ sStartWith ] = mnStartAt;
+ }
+ const rtl::OUString sAdjust( CREATE_OUSTRING( "Adjust" ) );
+ rPropMap[ sAdjust ] <<= HoriOrientation::LEFT;
+
+ if( mnNumberingType.hasValue() )
+ {
+ const rtl::OUString sNumberingType( CREATE_OUSTRING( "NumberingType" ) );
+ rPropMap[ sNumberingType ] = mnNumberingType;
+ }
+ if( maBulletFont.is() )
+ {
+ FontDescriptor aFontDesc;
+ sal_Int16 nFontSize = 0;
+ if( mnFontSize >>= nFontSize )
+ aFontDesc.Height = nFontSize;
+
+ // TODO move the to the TextFont struct.
+ sal_Int16 nPitch, nFamily;
+ aFontDesc.Name = maBulletFont.msTypeface;
+ GetFontPitch( maBulletFont.mnPitch, nPitch, nFamily);
+ aFontDesc.Pitch = nPitch;
+ aFontDesc.Family = nFamily;
+ const rtl::OUString sBulletFont( CREATE_OUSTRING( "BulletFont" ) );
+ rPropMap[ sBulletFont ] <<= aFontDesc;
+ const rtl::OUString sBulletFontName( CREATE_OUSTRING( "BulletFontName" ) );
+ rPropMap[ sBulletFontName ] <<= maBulletFont.msTypeface;
+ }
+ if ( msBulletChar.hasValue() )
+ {
+ const rtl::OUString sBulletChar( CREATE_OUSTRING( "BulletChar" ) );
+ rPropMap[ sBulletChar ] = msBulletChar;
+ }
+ if( mnSize.hasValue() )
+ {
+ const rtl::OUString sBulletRelSize( CREATE_OUSTRING( "BulletRelSize" ) );
+ rPropMap[ sBulletRelSize ] = mnSize;
+ }
+ if ( maStyleName.hasValue() )
+ {
+ const OUString sCharStyleName( CREATE_OUSTRING( "CharStyleName" ) );
+ rPropMap[ sCharStyleName ] <<= maStyleName;
+ }
+ if ( maBulletColorPtr->isUsed() )
+ {
+ const rtl::OUString sBulletColor( CREATE_OUSTRING( "BulletColor" ) );
+ rPropMap[ sBulletColor ] <<= maBulletColorPtr->getColor( rFilterBase );
+ }
+}
+
+TextParagraphProperties::TextParagraphProperties()
+: maTextCharacterPropertiesPtr( new TextCharacterProperties() )
+, mnLevel( 0 )
+{
+}
+TextParagraphProperties::~TextParagraphProperties()
+{
+}
+void TextParagraphProperties::apply( const TextParagraphPropertiesPtr& rSourceTextParagraphProperties )
+{
+ maTextParagraphPropertyMap.insert( rSourceTextParagraphProperties->maTextParagraphPropertyMap.begin(), rSourceTextParagraphProperties->maTextParagraphPropertyMap.end() );
+ maBulletList.apply( rSourceTextParagraphProperties->maBulletList );
+ maTextCharacterPropertiesPtr->apply( rSourceTextParagraphProperties->maTextCharacterPropertiesPtr );
+ if ( rSourceTextParagraphProperties->maParaTopMargin.bHasValue )
+ maParaTopMargin = rSourceTextParagraphProperties->maParaTopMargin;
+ if ( rSourceTextParagraphProperties->maParaBottomMargin.bHasValue )
+ maParaBottomMargin = rSourceTextParagraphProperties->maParaBottomMargin;
+}
+void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, sal_Bool bApplyBulletMap ) const
+{
+ PropertySet aPropSet( xPropSet );
+ Sequence< OUString > aNames;
+ Sequence< Any > aValues;
+
+// maTextParagraphPropertyMap.dump_debug("TextParagraph paragraph props");
+ maTextParagraphPropertyMap.makeSequence( aNames, aValues );
+ aPropSet.setProperties( aNames, aValues );
+
+ maTextCharacterPropertiesPtr->pushToPropSet( rFilterBase, aPropSet.getXPropertySet() );
+ maBulletList.pushToPropMap( rFilterBase, rioBulletMap );
+
+ if ( maParaTopMargin.bHasValue )
+ {
+ const OUString sParaTopMargin( CREATE_OUSTRING( "ParaTopMargin" ) );
+ //OSL_TRACE( "OOX: ParaTopMargin unit = %d, value = %d", maParaTopMargin.nUnit, maParaTopMargin.nValue );
+ xPropSet->setPropertyValue( sParaTopMargin, Any( maParaTopMargin.toMargin( getCharacterSize( 18 ) ) ) );
+ }
+ if ( maParaBottomMargin.bHasValue )
+ {
+ const OUString sParaBottomMargin( CREATE_OUSTRING( "ParaBottomMargin" ) );
+ //OSL_TRACE( "OOX: ParaBottomMargin unit = %d, value = %d", maParaBottomMargin.nUnit, maParaBottomMargin.nValue );
+ xPropSet->setPropertyValue( sParaBottomMargin, Any( maParaBottomMargin.toMargin( getCharacterSize( 18 ) ) ) );
+ }
+ if ( bApplyBulletMap )
+ {
+ Any aValue;
+ Reference< XIndexReplace > xNumRule;
+ const rtl::OUString sNumberingRules( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "NumberingRules" ) ) );
+ aValue = xPropSet->getPropertyValue( sNumberingRules );
+ aValue >>= xNumRule;
+
+ OSL_ENSURE( xNumRule.is(), "can't get Numbering rules");
+ if( xNumRule.is() )
+ {
+// OSL_TRACE("OOX: BulletList for level %d", getLevel());
+// pProps->getBulletListPropertyMap().dump_debug();
+ Sequence< PropertyValue > aBulletPropSeq;
+ rioBulletMap.makeSequence( aBulletPropSeq );
+ if( aBulletPropSeq.hasElements() )
+ {
+// OSL_TRACE("OOX: bullet props inserted at level %d", getLevel());
+ xNumRule->replaceByIndex( getLevel(), makeAny( aBulletPropSeq ) );
+ }
+ xPropSet->setPropertyValue( sNumberingRules, makeAny( xNumRule ) );
+ }
+ }
+}
+float TextParagraphProperties::getCharacterSize( float fValue ) const
+{
+ if ( maTextCharacterPropertiesPtr.get() )
+ fValue = maTextCharacterPropertiesPtr->getCharacterSize( fValue );
+ return fValue;
+}
+
+} }
diff --git a/oox/source/drawingml/textparagraphpropertiescontext.cxx b/oox/source/drawingml/textparagraphpropertiescontext.cxx
new file mode 100644
index 000000000000..65bd19d22ea7
--- /dev/null
+++ b/oox/source/drawingml/textparagraphpropertiescontext.cxx
@@ -0,0 +1,306 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textparagraphpropertiescontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textparagraphpropertiescontext.hxx"
+
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/drawingml/textcharacterpropertiescontext.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "textspacingcontext.hxx"
+#include "textfontcontext.hxx"
+#include "texttabstoplistcontext.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using ::com::sun::star::awt::FontDescriptor;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::text;
+
+namespace oox { namespace drawingml {
+
+// CT_TextParagraphProperties
+TextParagraphPropertiesContext::TextParagraphPropertiesContext( const ::oox::core::ContextRef& xParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ oox::drawingml::TextParagraphProperties& rTextParagraphProperties )
+: Context( xParent->getHandler() )
+, mrTextParagraphProperties( rTextParagraphProperties )
+, mrSpaceBefore( rTextParagraphProperties.getParaTopMargin() )
+, mrSpaceAfter( rTextParagraphProperties.getParaBottomMargin() )
+, mrBulletList( rTextParagraphProperties.getBulletList() )
+{
+ OUString sValue;
+ AttributeList attribs( xAttribs );
+
+ PropertyMap& rPropertyMap( mrTextParagraphProperties.getTextParagraphPropertyMap() );
+
+ // ST_TextAlignType
+ if ( xAttribs->hasAttribute( XML_algn ) )
+ {
+ sal_Int32 nAlign = xAttribs->getOptionalValueToken( XML_algn, XML_l );
+ const OUString sParaAdjust( CREATE_OUSTRING( "ParaAdjust" ) );
+ rPropertyMap[ sParaAdjust ] <<= GetParaAdjust( nAlign );
+ }
+// OSL_TRACE( "OOX: para adjust %d", GetParaAdjust( nAlign ));
+ // TODO see to do the same with RubyAdjust
+
+ // ST_Coordinate32
+// sValue = xAttribs->getOptionalValue( XML_defTabSz ); SJ: we need to be able to set the default tab size for each text object,
+// this is possible at the moment only for the whole document.
+// sal_Int32 nDefTabSize = ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
+ // TODO
+
+// bool bEaLineBrk = attribs.getBool( XML_eaLnBrk, true );
+ if ( xAttribs->hasAttribute( XML_latinLnBrk ) )
+ {
+ bool bLatinLineBrk = attribs.getBool( XML_latinLnBrk, true );
+ const OUString sParaIsHyphenation( CREATE_OUSTRING( "ParaIsHyphenation" ) );
+ rPropertyMap[ sParaIsHyphenation ] <<= bLatinLineBrk;
+ }
+ // TODO see what to do with Asian hyphenation
+
+ // ST_TextFontAlignType
+ // TODO
+// sal_Int32 nFontAlign = xAttribs->getOptionalValueToken( XML_fontAlgn, XML_base );
+
+ if ( xAttribs->hasAttribute( XML_hangingPunct ) )
+ {
+ bool bHangingPunct = attribs.getBool( XML_hangingPunct, false );
+ const OUString sParaIsHangingPunctuation( CREATE_OUSTRING( "ParaIsHangingPunctuation" ) );
+ rPropertyMap[ sParaIsHangingPunctuation ] <<= bHangingPunct;
+ }
+
+ // ST_Coordinate
+ if ( xAttribs->hasAttribute( XML_indent ) )
+ {
+ sValue = xAttribs->getOptionalValue( XML_indent );
+ const OUString sParaFirstLineIndent( CREATE_OUSTRING( "ParaFirstLineIndent" ) );
+ rPropertyMap[ sParaFirstLineIndent ] <<= ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
+ }
+
+ // ST_TextIndentLevelType
+ // -1 is an invalid value and denote the lack of level
+ sal_Int32 nLevel = attribs.getInteger( XML_lvl, 0 );
+ if( nLevel > 8 || nLevel < 0 )
+ {
+ nLevel = 0;
+ }
+
+ mrTextParagraphProperties.setLevel( static_cast< sal_Int16 >( nLevel ) );
+
+ char name[] = "Outline X";
+ name[8] = static_cast<char>( '1' + nLevel );
+ const OUString sStyleNameValue( rtl::OUString::createFromAscii( name ) );
+ mrBulletList.setStyleName( sStyleNameValue );
+
+ // ST_TextMargin
+ // ParaLeftMargin
+ if ( xAttribs->hasAttribute( XML_marL ) )
+ {
+ sValue = xAttribs->getOptionalValue( XML_marL );
+ sal_Int32 nMarL = ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
+ const OUString sParaLeftMargin( CREATE_OUSTRING( "ParaLeftMargin" ) );
+ rPropertyMap[ sParaLeftMargin ] <<= nMarL;
+ }
+
+ // ParaRightMargin
+ if ( xAttribs->hasAttribute( XML_marR ) )
+ {
+ sValue = xAttribs->getOptionalValue( XML_marR );
+ sal_Int32 nMarR = ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
+ const OUString sParaRightMargin( CREATE_OUSTRING( "ParaRightMargin" ) );
+ rPropertyMap[ sParaRightMargin ] <<= nMarR;
+ }
+
+ if ( xAttribs->hasAttribute( XML_rtl ) )
+ {
+ bool bRtl = attribs.getBool( XML_rtl, false );
+ const OUString sTextWritingMode( CREATE_OUSTRING( "TextWritingMode" ) );
+ rPropertyMap[ sTextWritingMode ] <<= ( bRtl ? WritingMode_RL_TB : WritingMode_LR_TB );
+ }
+}
+
+
+
+TextParagraphPropertiesContext::~TextParagraphPropertiesContext()
+{
+ PropertyMap& rPropertyMap( mrTextParagraphProperties.getTextParagraphPropertyMap() );
+ if ( maLineSpacing.bHasValue )
+ {
+ const OUString sParaLineSpacing( CREATE_OUSTRING( "ParaLineSpacing" ) );
+ //OSL_TRACE( "OOX: ParaLineSpacing unit = %d, value = %d", maLineSpacing.nUnit, maLineSpacing.nValue );
+ rPropertyMap[ sParaLineSpacing ] <<= maLineSpacing.toLineSpacing();
+ }
+ ::std::list< TabStop >::size_type nTabCount = maTabList.size();
+ if( nTabCount != 0 )
+ {
+ Sequence< TabStop > aSeq( nTabCount );
+ TabStop * aArray = aSeq.getArray();
+ OSL_ENSURE( aArray != NULL, "sequence array is NULL" );
+ ::std::copy( maTabList.begin(), maTabList.end(), aArray );
+ const OUString sParaTabStops( CREATE_OUSTRING( "ParaTabStops" ) );
+ rPropertyMap[ sParaTabStops ] <<= aSeq;
+ }
+ if( mrBulletList.is() )
+ {
+ const rtl::OUString sIsNumbering( CREATE_OUSTRING( "IsNumbering" ) );
+ rPropertyMap[ sIsNumbering ] <<= sal_True;
+ }
+ sal_Int16 nLevel = mrTextParagraphProperties.getLevel();
+// OSL_TRACE("OOX: numbering level = %d", nLevel );
+ const OUString sNumberingLevel( CREATE_OUSTRING( "NumberingLevel" ) );
+ rPropertyMap[ sNumberingLevel ] <<= (sal_Int16)nLevel;
+ sal_Bool bTmp = sal_True;
+ const OUString sNumberingIsNumber( CREATE_OUSTRING( "NumberingIsNumber" ) );
+ rPropertyMap[ sNumberingIsNumber ] <<= bTmp;
+}
+
+// --------------------------------------------------------------------
+
+void TextParagraphPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextParagraphPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& rXAttributes ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_lnSpc: // CT_TextSpacing
+ xRet.set( new TextSpacingContext( getHandler(), maLineSpacing ) );
+ break;
+ case NMSP_DRAWINGML|XML_spcBef: // CT_TextSpacing
+ xRet.set( new TextSpacingContext( getHandler(), mrSpaceBefore ) );
+ break;
+ case NMSP_DRAWINGML|XML_spcAft: // CT_TextSpacing
+ xRet.set( new TextSpacingContext( getHandler(), mrSpaceAfter ) );
+ break;
+
+ // EG_TextBulletColor
+ case NMSP_DRAWINGML|XML_buClrTx: // CT_TextBulletColorFollowText ???
+ mrBulletList.mbBulletColorFollowText <<= sal_True;
+ break;
+ case NMSP_DRAWINGML|XML_buClr: // CT_Color
+ xRet.set( new colorChoiceContext( getHandler(), *mrBulletList.maBulletColorPtr.get() ) );
+ break;
+
+ // EG_TextBulletSize
+ case NMSP_DRAWINGML|XML_buSzTx: // CT_TextBulletSizeFollowText
+ mrBulletList.setBulletSize(100);
+ break;
+ case NMSP_DRAWINGML|XML_buSzPct: // CT_TextBulletSizePercent
+ mrBulletList.setBulletSize( static_cast<sal_Int16>( GetPercent( rXAttributes->getOptionalValue( XML_val ) ) / 1000 ) );
+ break;
+ case NMSP_DRAWINGML|XML_buSzPts: // CT_TextBulletSizePoint
+ mrBulletList.setBulletSize(0);
+ mrBulletList.setFontSize( static_cast<sal_Int16>(GetTextSize( rXAttributes->getOptionalValue( XML_val ) ) ) );
+ break;
+
+ // EG_TextBulletTypeface
+ case NMSP_DRAWINGML|XML_buFontTx: // CT_TextBulletTypefaceFollowText
+ mrBulletList.mbBulletFontFollowText <<= sal_True;
+ break;
+ case NMSP_DRAWINGML|XML_buFont: // CT_TextFont
+ xRet.set( new TextFontContext( getHandler(), aElementToken, rXAttributes,
+ mrBulletList.maBulletFont ) );
+ break;
+
+ // EG_TextBullet
+ case NMSP_DRAWINGML|XML_buNone: // CT_TextNoBullet
+ mrBulletList.setNone();
+ break;
+ case NMSP_DRAWINGML|XML_buAutoNum: // CT_TextAutonumberBullet
+ {
+ AttributeList attribs( rXAttributes );
+ try {
+ sal_Int32 nType = rXAttributes->getValueToken( XML_type );
+ sal_Int32 nStartAt = attribs.getInteger( XML_startAt, 1 );
+ if( nStartAt > 32767 )
+ {
+ nStartAt = 32767;
+ }
+ else if( nStartAt < 1 )
+ {
+ nStartAt = 1;
+ }
+ mrBulletList.setStartAt( nStartAt );
+ mrBulletList.setType( nType );
+ }
+ catch(SAXException& /* e */ )
+ {
+ OSL_TRACE("OOX: SAXException in XML_buAutoNum");
+ }
+ break;
+ }
+ case NMSP_DRAWINGML|XML_buChar: // CT_TextCharBullet
+ try {
+ mrBulletList.setBulletChar( rXAttributes->getValue( XML_char ) );
+ }
+ catch(SAXException& /* e */)
+ {
+ OSL_TRACE("OOX: SAXException in XML_buChar");
+ }
+ break;
+ case NMSP_DRAWINGML|XML_buBlip: // CT_TextBlipBullet
+ // TODO
+ break;
+
+ case NMSP_DRAWINGML|XML_tabLst: // CT_TextTabStopList
+ xRet.set( new TextTabStopListContext( this, maTabList ) );
+ break;
+ case NMSP_DRAWINGML|XML_defRPr: // CT_TextCharacterProperties
+ xRet.set( new TextCharacterPropertiesContext( this, rXAttributes, *(mrTextParagraphProperties.getTextCharacterProperties().get()) ) );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/textrun.cxx b/oox/source/drawingml/textrun.cxx
new file mode 100644
index 000000000000..ed3b362014b7
--- /dev/null
+++ b/oox/source/drawingml/textrun.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textrun.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textrun.hxx"
+
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+
+#include "oox/helper/helper.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+
+namespace oox { namespace drawingml {
+
+ TextRun::TextRun()
+ : mbIsLineBreak( false )
+ , maTextCharacterPropertiesPtr( new TextCharacterProperties() )
+ {
+ }
+
+
+ TextRun::~TextRun()
+ {
+ }
+
+ void TextRun::insertAt( const ::oox::core::XmlFilterBase& rFilterBase, const Reference < XText > & xText, const Reference < XTextCursor > &xAt,
+ const Reference < XModel > & xModel, const TextCharacterPropertiesPtr& rTextCharacterStyle )
+ {
+ try {
+ Reference< XTextRange > xStart( xAt, UNO_QUERY );
+
+ Reference< XPropertySet > xProps( xStart, UNO_QUERY);
+ if ( rTextCharacterStyle.get() )
+ rTextCharacterStyle->pushToPropSet( rFilterBase, xProps );
+
+ maTextCharacterPropertiesPtr->pushToPropSet( rFilterBase, xProps );
+
+ if( maTextCharacterPropertiesPtr->getHyperlinkPropertyMap().empty() )
+ {
+ if( mbIsLineBreak )
+ {
+ OSL_TRACE( "OOX: TextRun::insertAt() insert line break" );
+ xText->insertControlCharacter( xStart, ControlCharacter::LINE_BREAK, sal_False );
+ }
+ else
+ {
+ xText->insertString( xStart, text(), sal_False );
+ }
+ }
+ else
+ {
+ OSL_TRACE( "OOX: URL field" );
+ Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY );
+ Reference< XTextField > xField( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ), UNO_QUERY );
+ if( xField.is() )
+ {
+ const rtl::OUString sRepresentation( OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) );
+ maTextCharacterPropertiesPtr->getHyperlinkPropertyMap()[ sRepresentation ] <<= text();
+
+ Reference< XPropertySet > xFieldProps( xField, UNO_QUERY);
+ maTextCharacterPropertiesPtr->pushToUrlFieldPropSet( xFieldProps );
+ Reference< XTextContent > xContent( xField, UNO_QUERY);
+ xText->insertTextContent( xStart, xContent, sal_False );
+ }
+ else
+ {
+ OSL_TRACE( "OOX: URL field couldn't be created" );
+ xText->insertString( xStart, text(), sal_False );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_TRACE("OOX: TextRun::insertAt() exception");
+ }
+ }
+
+
+} }
diff --git a/oox/source/drawingml/textspacingcontext.cxx b/oox/source/drawingml/textspacingcontext.cxx
new file mode 100644
index 000000000000..e222a8d27a8d
--- /dev/null
+++ b/oox/source/drawingml/textspacingcontext.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textspacingcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/textspacing.hxx"
+#include "oox/core/namespaces.hxx"
+#include "textspacingcontext.hxx"
+#include "tokens.hxx"
+
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
+
+namespace oox { namespace drawingml {
+
+ TextSpacingContext::TextSpacingContext( const FragmentHandlerRef& xHandler,
+ TextSpacing & aSpacing )
+ : Context( xHandler )
+ , maSpacing( aSpacing )
+ {
+ maSpacing.bHasValue = sal_True;
+ }
+
+ void TextSpacingContext::endFastElement( sal_Int32 /*nElement*/ )
+ throw ( SAXException, RuntimeException )
+ {
+ }
+
+ Reference< XFastContextHandler > TextSpacingContext::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+ switch( aElement )
+ {
+ case NMSP_DRAWINGML|XML_spcPct:
+ maSpacing.nUnit = TextSpacing::PERCENT;
+ maSpacing.nValue = GetPercent( xAttribs->getValue( XML_val ) );
+ break;
+ case NMSP_DRAWINGML|XML_spcPts:
+ maSpacing.nUnit = TextSpacing::POINTS;
+ maSpacing.nValue = GetTextSpacingPoint( xAttribs->getValue( XML_val ) );
+ break;
+ default:
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+
+} }
diff --git a/oox/source/drawingml/textspacingcontext.hxx b/oox/source/drawingml/textspacingcontext.hxx
new file mode 100644
index 000000000000..615e0541dbdb
--- /dev/null
+++ b/oox/source/drawingml/textspacingcontext.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textspacingcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_DRAWINGML_TEXTSPACINGCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTSPACINGCONTEXT_HXX
+
+#include <rtl/ustring.hxx>
+
+#include "oox/core/context.hxx"
+
+namespace oox { namespace drawingml {
+
+class TextSpacing;
+
+class TextSpacingContext : public ::oox::core::Context
+{
+public:
+ TextSpacingContext( const ::oox::core::FragmentHandlerRef& xHandler, TextSpacing & aSpacing );
+
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ TextSpacing& maSpacing;
+};
+
+
+} }
+
+
+
+
+#endif
+
+
diff --git a/oox/source/drawingml/texttabstoplistcontext.cxx b/oox/source/drawingml/texttabstoplistcontext.cxx
new file mode 100644
index 000000000000..54f6bed012b8
--- /dev/null
+++ b/oox/source/drawingml/texttabstoplistcontext.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: texttabstoplistcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <list>
+#include <algorithm>
+
+#include <rtl/ustring.hxx>
+
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "texttabstoplistcontext.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+ TextTabStopListContext::TextTabStopListContext( const ContextRef& xParent,
+ std::list< TabStop > & aTabList )
+ : Context( *xParent )
+ , maTabList( aTabList )
+ {
+ }
+
+ TextTabStopListContext::~TextTabStopListContext()
+ {
+ }
+
+ void SAL_CALL TextTabStopListContext::endFastElement( ::sal_Int32 /*Element*/ )
+ throw ( SAXException, RuntimeException)
+ {
+ }
+
+
+ Reference< ::XFastContextHandler > TextTabStopListContext::createFastChildContext( ::sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+ switch( aElement )
+ {
+ case NMSP_DRAWINGML|XML_tab:
+ {
+ OUString sValue;
+ TabStop aTabStop;
+ sValue = xAttribs->getOptionalValue( XML_pos );
+ if( sValue.getLength() )
+ {
+ aTabStop.Position = GetCoordinate( sValue );
+ }
+ sal_Int32 aToken = xAttribs->getOptionalValueToken( XML_algn, 0 );
+ if( aToken != 0 )
+ {
+ aTabStop.Alignment = GetTabAlign( aToken );
+ }
+ maTabList.push_back(aTabStop);
+ break;
+ }
+ default:
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+
+} }
+
+
diff --git a/oox/source/drawingml/texttabstoplistcontext.hxx b/oox/source/drawingml/texttabstoplistcontext.hxx
new file mode 100644
index 000000000000..e0faed8f0f88
--- /dev/null
+++ b/oox/source/drawingml/texttabstoplistcontext.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: texttabstoplistcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTTABSTOPLISTCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTTABSTOPLISTCONTEXT_HXX
+
+#include <list>
+
+#include <com/sun/star/style/TabStop.hpp>
+
+
+#ifndef OOX_CORE_CONTEXT_HXX
+#include "oox/core/context.hxx"
+#endif
+
+namespace oox { namespace drawingml {
+
+ class TextTabStopListContext : public ::oox::core::Context
+ {
+ public:
+ TextTabStopListContext( const ::oox::core::ContextRef& xParent,
+ ::std::list< ::com::sun::star::style::TabStop > & aTabList );
+ ~TextTabStopListContext();
+
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ ::std::list< ::com::sun::star::style::TabStop > & maTabList;
+ };
+
+
+} }
+
+
+#endif
+
diff --git a/oox/source/drawingml/theme.cxx b/oox/source/drawingml/theme.cxx
new file mode 100644
index 000000000000..c9b776b941c6
--- /dev/null
+++ b/oox/source/drawingml/theme.cxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: theme.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using namespace ::oox::core;
+
+namespace oox { namespace drawingml {
+
+Theme::Theme()
+: mpClrSchemePtr( new ClrScheme )
+, mpspDefPtr( new Shape )
+, mplnDefPtr( new Shape )
+, mptxDefPtr( new Shape )
+{
+}
+Theme::~Theme()
+{
+}
+
+} }
diff --git a/oox/source/drawingml/themeelementscontext.cxx b/oox/source/drawingml/themeelementscontext.cxx
new file mode 100644
index 000000000000..503e6d4e9514
--- /dev/null
+++ b/oox/source/drawingml/themeelementscontext.cxx
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: themeelementscontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/themeelementscontext.hxx"
+#include "oox/drawingml/clrschemecontext.hxx"
+#include "oox/drawingml/linepropertiescontext.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+class fillStyleListContext : public ::oox::core::Context
+{
+ std::vector< oox::drawingml::FillPropertiesPtr >& mrFillStyleList;
+public:
+ fillStyleListContext( const ::oox::core::FragmentHandlerRef& xHandler, std::vector< oox::drawingml::FillPropertiesPtr >& rFillStyleList );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+};
+fillStyleListContext::fillStyleListContext( const FragmentHandlerRef& xHandler, std::vector< oox::drawingml::FillPropertiesPtr >& rFillStyleList )
+: oox::core::Context( xHandler )
+, mrFillStyleList( rFillStyleList )
+{
+}
+Reference< XFastContextHandler > fillStyleListContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_noFill:
+ case NMSP_DRAWINGML|XML_solidFill:
+ case NMSP_DRAWINGML|XML_gradFill:
+ case NMSP_DRAWINGML|XML_blipFill:
+ case NMSP_DRAWINGML|XML_pattFill:
+ case NMSP_DRAWINGML|XML_grpFill:
+ {
+ mrFillStyleList.push_back( FillPropertiesPtr( new oox::drawingml::FillProperties ) );
+ FillPropertiesGroupContext::StaticCreateContext( getHandler(), aElementToken, xAttribs, *(mrFillStyleList.back().get()) );
+ }
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// ---------------------------------------------------------------------
+
+class lineStyleListContext : public ::oox::core::Context
+{
+ std::vector< oox::drawingml::LinePropertiesPtr >& mrLineStyleList;
+public:
+ lineStyleListContext( const ::oox::core::FragmentHandlerRef& xHandler, std::vector< oox::drawingml::LinePropertiesPtr >& rLineStyleList );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs )
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+};
+lineStyleListContext::lineStyleListContext( const FragmentHandlerRef& xHandler, std::vector< oox::drawingml::LinePropertiesPtr >& rLineStyleList )
+: oox::core::Context( xHandler )
+, mrLineStyleList( rLineStyleList )
+{
+}
+Reference< XFastContextHandler > lineStyleListContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_ln:
+ {
+ mrLineStyleList.push_back( LinePropertiesPtr( new oox::drawingml::LineProperties ) );
+ xRet.set( new LinePropertiesContext( getHandler(), xAttribs, *(mrLineStyleList.back().get()) ) );
+ }
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// ---------------------------------------------------------------------
+
+class effectStyleListContext : public ::oox::core::Context
+{
+ std::vector< PropertyMap >& mrEffectStyleList;
+public:
+ effectStyleListContext( const ::oox::core::FragmentHandlerRef& xHandler, std::vector< PropertyMap >& rEffectStyleList );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+};
+effectStyleListContext::effectStyleListContext( const FragmentHandlerRef& xHandler, std::vector< PropertyMap >& rEffectStyleList )
+: oox::core::Context( xHandler )
+, mrEffectStyleList( rEffectStyleList )
+{
+}
+Reference< XFastContextHandler > effectStyleListContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& /* xAttribs */ ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_effectStyle:
+ {
+ mrEffectStyleList.push_back( PropertyMap() );
+ // todo: last effect list entry needs to be filled/
+ break;
+ }
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// ---------------------------------------------------------------------
+
+class bgFillStyleListContext : public ::oox::core::Context
+{
+ std::vector< oox::drawingml::FillPropertiesPtr >& mrBgFillStyleList;
+public:
+ bgFillStyleListContext( const ::oox::core::FragmentHandlerRef& xHandler, std::vector< oox::drawingml::FillPropertiesPtr >& rBgFillStyleList );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+};
+bgFillStyleListContext::bgFillStyleListContext( const FragmentHandlerRef& xHandler, std::vector< oox::drawingml::FillPropertiesPtr >& rBgFillStyleList )
+: oox::core::Context( xHandler )
+, mrBgFillStyleList( rBgFillStyleList )
+{
+}
+Reference< XFastContextHandler > bgFillStyleListContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_noFill:
+ case NMSP_DRAWINGML|XML_solidFill:
+ case NMSP_DRAWINGML|XML_gradFill:
+ case NMSP_DRAWINGML|XML_blipFill:
+ case NMSP_DRAWINGML|XML_pattFill:
+ case NMSP_DRAWINGML|XML_grpFill:
+ {
+ mrBgFillStyleList.push_back( FillPropertiesPtr( new oox::drawingml::FillProperties ) );
+ FillPropertiesGroupContext::StaticCreateContext( getHandler(), aElementToken, xAttribs, *(mrBgFillStyleList.back().get()) );
+ }
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+// ---------------------------------------------------------------------
+
+themeElementsContext::themeElementsContext( const ::oox::core::FragmentHandlerRef& xHandler, ::oox::drawingml::Theme& rTheme )
+: Context( xHandler )
+, mrTheme( rTheme )
+{
+}
+
+Reference< XFastContextHandler > themeElementsContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ // CT_BaseStyles
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_clrScheme: // CT_ColorScheme
+ {
+ xRet.set( new clrSchemeContext( getHandler(), mrTheme.getClrScheme() ) );
+ break;
+ }
+
+ case NMSP_DRAWINGML|XML_fontScheme: // CT_FontScheme
+ break;
+
+ case NMSP_DRAWINGML|XML_fmtScheme: // CT_StyleMatrix
+ mrTheme.getStyleName() = xAttribs->getOptionalValue( XML_name );
+ break;
+
+ case NMSP_DRAWINGML|XML_fillStyleLst: // CT_FillStyleList
+ xRet.set( new fillStyleListContext( getHandler(), mrTheme.getFillStyleList() ) );
+ break;
+ case NMSP_DRAWINGML|XML_lineStyleLst: // CT_LineStyleList
+ xRet.set( new lineStyleListContext( getHandler(), mrTheme.getLineStyleList() ) );
+ break;
+ case NMSP_DRAWINGML|XML_effectStyleLst: // CT_EffectStyleList
+ xRet.set( new effectStyleListContext( getHandler(), mrTheme.getEffectStyleList() ) );
+ break;
+ case NMSP_DRAWINGML|XML_bgFillStyleLst: // CT_BackgroundFillStyleList
+ xRet.set( new bgFillStyleListContext( getHandler(), mrTheme.getBgFillStyleList() ) );
+ break;
+
+ case NMSP_DRAWINGML|XML_extLst: // CT_OfficeArtExtensionList
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/themefragmenthandler.cxx b/oox/source/drawingml/themefragmenthandler.cxx
new file mode 100644
index 000000000000..bebda788d729
--- /dev/null
+++ b/oox/source/drawingml/themefragmenthandler.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: themefragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:52 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/drawingml/themefragmenthandler.hxx"
+#include "oox/drawingml/objectdefaultcontext.hxx"
+#include "oox/drawingml/themeelementscontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+
+namespace oox { namespace drawingml {
+
+ThemeFragmentHandler::ThemeFragmentHandler( const XmlFilterRef& xFilter, const OUString& rFragmentPath, Theme& rTheme )
+ throw()
+: FragmentHandler( xFilter, rFragmentPath )
+, mrTheme( rTheme )
+{
+}
+ThemeFragmentHandler::~ThemeFragmentHandler()
+ throw()
+{
+
+}
+Reference< XFastContextHandler > ThemeFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& /*xAttribs */ )
+ throw (SAXException, RuntimeException)
+{
+ // CT_OfficeStyleSheet
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML|XML_themeElements: // CT_BaseStyles
+ {
+ xRet.set( new themeElementsContext( this, mrTheme ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_objectDefaults: // CT_ObjectStyleDefaults
+ {
+ xRet.set( new objectDefaultContext( this, mrTheme ) );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_extraClrSchemeLst: // CT_ColorSchemeList
+ break;
+ case NMSP_DRAWINGML|XML_custClrLst: // CustomColorList
+ break;
+ case NMSP_DRAWINGML|XML_ext: // CT_OfficeArtExtension
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+void SAL_CALL ThemeFragmentHandler::endDocument()
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+//--------------------------------------------------------------------------------------------------------------
+
+
+
+} }
+
diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx
new file mode 100644
index 000000000000..92a892a6274a
--- /dev/null
+++ b/oox/source/dump/biffdumper.cxx
@@ -0,0 +1,3195 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: biffdumper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/dump/biffdumper.hxx"
+
+#include <osl/thread.h>
+#include <rtl/tencinfo.h>
+#include <rtl/strbuf.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/biffdetector.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/formulabase.hxx"
+#include "oox/xls/richstring.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::util::DateTime;
+using ::com::sun::star::sheet::XSpreadsheetDocument;
+using ::oox::core::FilterBase;
+
+using namespace ::oox::xls;
+
+namespace oox {
+namespace dump {
+namespace biff {
+
+namespace {
+
+// constants ------------------------------------------------------------------
+
+const sal_uInt16 BIFF_FONTFLAG_BOLD = 0x0001;
+const sal_uInt16 BIFF_FONTFLAG_ITALIC = 0x0002;
+
+const sal_uInt32 BIFF_HYPERLINK_TARGET = 0x00000001; /// File name or URL.
+const sal_uInt32 BIFF_HYPERLINK_ABS = 0x00000002; /// Absolute path.
+const sal_uInt32 BIFF_HYPERLINK_DISPLAY = 0x00000014; /// Display string.
+const sal_uInt32 BIFF_HYPERLINK_LOC = 0x00000008; /// Target location.
+const sal_uInt32 BIFF_HYPERLINK_FRAME = 0x00000080; /// Target frame.
+const sal_uInt32 BIFF_HYPERLINK_UNC = 0x00000100; /// UNC path.
+
+const sal_uInt16 BIFF_OBJPIO_MANUALSIZE = 0x0001;
+const sal_uInt16 BIFF_OBJPIO_LINKED = 0x0002;
+const sal_uInt16 BIFF_OBJPIO_SYMBOL = 0x0008;
+const sal_uInt16 BIFF_OBJPIO_CONTROL = 0x0010; /// Form control.
+const sal_uInt16 BIFF_OBJPIO_CTLSSTREAM = 0x0020; /// Data in Ctls stream.
+const sal_uInt16 BIFF_OBJPIO_AUTOLOAD = 0x0200;
+
+const sal_uInt16 BIFF_OBJCMO_GROUP = 0x0000;
+const sal_uInt16 BIFF_OBJCMO_LINE = 0x0001;
+const sal_uInt16 BIFF_OBJCMO_RECTANGLE = 0x0002;
+const sal_uInt16 BIFF_OBJCMO_ELLIPSE = 0x0003;
+const sal_uInt16 BIFF_OBJCMO_ARC = 0x0004;
+const sal_uInt16 BIFF_OBJCMO_CHART = 0x0005;
+const sal_uInt16 BIFF_OBJCMO_TEXT = 0x0006;
+const sal_uInt16 BIFF_OBJCMO_BUTTON = 0x0007;
+const sal_uInt16 BIFF_OBJCMO_PICTURE = 0x0008;
+const sal_uInt16 BIFF_OBJCMO_POLYGON = 0x0009;
+const sal_uInt16 BIFF_OBJCMO_CHECKBOX = 0x000B;
+const sal_uInt16 BIFF_OBJCMO_OPTIONBUTTON = 0x000C;
+const sal_uInt16 BIFF_OBJCMO_EDIT = 0x000D;
+const sal_uInt16 BIFF_OBJCMO_LABEL = 0x000E;
+const sal_uInt16 BIFF_OBJCMO_DIALOG = 0x000F;
+const sal_uInt16 BIFF_OBJCMO_SPIN = 0x0010;
+const sal_uInt16 BIFF_OBJCMO_SCROLLBAR = 0x0011;
+const sal_uInt16 BIFF_OBJCMO_LISTBOX = 0x0012;
+const sal_uInt16 BIFF_OBJCMO_GROUPBOX = 0x0013;
+const sal_uInt16 BIFF_OBJCMO_COMBOBOX = 0x0014;
+const sal_uInt16 BIFF_OBJCMO_NOTE = 0x0019;
+const sal_uInt16 BIFF_OBJCMO_DRAWING = 0x001E;
+
+const sal_uInt16 BIFF_STYLE_BUILTIN = 0x8000;
+
+const sal_uInt16 BIFF_PT_NOSTRING = 0xFFFF;
+
+} // namespace
+
+// ============================================================================
+// ============================================================================
+
+class BiffStreamInput : public Input
+{
+public:
+ inline explicit BiffStreamInput( BiffInputStream& rStrm ) : mrStrm( rStrm ) {}
+ virtual ~BiffStreamInput();
+
+ virtual sal_Int64 getSize() const;
+ virtual sal_Int64 tell() const;
+ virtual void seek( sal_Int64 nPos );
+ virtual void skip( sal_Int32 nBytes );
+ virtual sal_Int32 read( void* pBuffer, sal_Int32 nBytes );
+
+ virtual BiffStreamInput& operator>>( sal_Int8& rnData );
+ virtual BiffStreamInput& operator>>( sal_uInt8& rnData );
+ virtual BiffStreamInput& operator>>( sal_Int16& rnData );
+ virtual BiffStreamInput& operator>>( sal_uInt16& rnData );
+ virtual BiffStreamInput& operator>>( sal_Int32& rnData );
+ virtual BiffStreamInput& operator>>( sal_uInt32& rnData );
+ virtual BiffStreamInput& operator>>( float& rfData );
+ virtual BiffStreamInput& operator>>( double& rfData );
+
+private:
+ BiffInputStream& mrStrm;
+};
+
+// ----------------------------------------------------------------------------
+
+BiffStreamInput::~BiffStreamInput()
+{
+}
+
+sal_Int64 BiffStreamInput::getSize() const
+{
+ return mrStrm.getRecSize();
+}
+
+sal_Int64 BiffStreamInput::tell() const
+{
+ return mrStrm.getRecPos();
+}
+
+void BiffStreamInput::seek( sal_Int64 nPos )
+{
+ mrStrm.seek( static_cast< sal_uInt32 >( nPos ) );
+}
+
+void BiffStreamInput::skip( sal_Int32 nBytes )
+{
+ mrStrm.skip( static_cast< sal_uInt32 >( nBytes ) );
+}
+
+sal_Int32 BiffStreamInput::read( void* pBuffer, sal_Int32 nSize )
+{
+ return static_cast< sal_Int32 >( mrStrm.read( pBuffer, static_cast< sal_uInt32 >( nSize ) ) );
+}
+
+BiffStreamInput& BiffStreamInput::operator>>( sal_Int8& rnData ) { mrStrm >> rnData; return *this; }
+BiffStreamInput& BiffStreamInput::operator>>( sal_uInt8& rnData ) { mrStrm >> rnData; return *this; }
+BiffStreamInput& BiffStreamInput::operator>>( sal_Int16& rnData ) { mrStrm >> rnData; return *this; }
+BiffStreamInput& BiffStreamInput::operator>>( sal_uInt16& rnData ) { mrStrm >> rnData; return *this; }
+BiffStreamInput& BiffStreamInput::operator>>( sal_Int32& rnData ) { mrStrm >> rnData; return *this; }
+BiffStreamInput& BiffStreamInput::operator>>( sal_uInt32& rnData ) { mrStrm >> rnData; return *this; }
+BiffStreamInput& BiffStreamInput::operator>>( float& rfData ) { mrStrm >> rfData; return *this; }
+BiffStreamInput& BiffStreamInput::operator>>( double& rfData ) { mrStrm >> rfData; return *this; }
+
+// ============================================================================
+// ============================================================================
+
+BiffConfig::BiffConfig( const Config& rParent, BiffType eBiff ) :
+ meBiff( eBiff )
+{
+ Config::construct( rParent );
+}
+
+bool BiffConfig::implIsValid() const
+{
+ return (meBiff != BIFF_UNKNOWN) && Config::implIsValid();
+}
+
+NameListRef BiffConfig::implGetNameList( const OUString& rKey ) const
+{
+ NameListRef xList = Config::implGetNameList( rKey );
+ if( !xList )
+ {
+ OUString aBaseKey = rKey + CREATE_OUSTRING( "-BIFF" );
+ switch( meBiff )
+ {
+ // fall-through intended!
+ case BIFF8: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '8' ) ) );
+ case BIFF5: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '5' ) ) );
+ case BIFF4: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '4' ) ) );
+ case BIFF3: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '3' ) ) );
+ case BIFF2: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '2' ) ) );
+ case BIFF_UNKNOWN: break;
+ }
+ }
+ return xList;
+}
+
+// ============================================================================
+
+BiffSharedData::BiffSharedData( BiffType eBiff ) :
+ meBiff( eBiff ),
+ meTextEnc( osl_getThreadTextEncoding() )
+{
+}
+
+BiffSharedData::~BiffSharedData()
+{
+}
+
+void BiffSharedData::setTextEncoding( rtl_TextEncoding eTextEnc )
+{
+ if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ meTextEnc = eTextEnc;
+}
+
+sal_uInt16 BiffSharedData::getFontCount() const
+{
+ return static_cast< sal_uInt16 >( maFontEncs.size() );
+}
+
+rtl_TextEncoding BiffSharedData::getFontEncoding( sal_uInt16 nFontId ) const
+{
+ return (nFontId < getFontCount()) ? maFontEncs[ nFontId ] : meTextEnc;
+}
+
+void BiffSharedData::appendFontEncoding( rtl_TextEncoding eFontEnc )
+{
+ maFontEncs.push_back( (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? meTextEnc : eFontEnc );
+ if( maFontEncs.size() == 4 )
+ maFontEncs.push_back( meTextEnc );
+}
+
+sal_uInt16 BiffSharedData::getXfCount() const
+{
+ return static_cast< sal_uInt16 >( maXfFontIds.size() );
+}
+
+rtl_TextEncoding BiffSharedData::getXfEncoding( sal_uInt16 nXfId ) const
+{
+ sal_uInt16 nFontId = (nXfId < getXfCount()) ? maXfFontIds[ nXfId ] : 0;
+ return getFontEncoding( nFontId );
+}
+
+void BiffSharedData::appendXfFontId( sal_uInt16 nFontId )
+{
+ maXfFontIds.push_back( nFontId );
+}
+
+bool BiffSharedData::implIsValid() const
+{
+ return meBiff != BIFF_UNKNOWN;
+}
+
+// ============================================================================
+
+BiffObjectBase::BiffObjectBase()
+{
+}
+
+BiffObjectBase::~BiffObjectBase()
+{
+}
+
+void BiffObjectBase::construct( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm, BiffType eBiff )
+{
+ if( eBiff != BIFF_UNKNOWN )
+ {
+ InputStreamObject::construct( rParent, rOutFileName, xStrm );
+ if( InputStreamObject::implIsValid() )
+ {
+ mxBiffData.reset( new BiffSharedData( eBiff ) );
+ mxStrm.reset( new BiffInputStream( getStream() ) );
+ reconstructConfig();
+ reconstructInput();
+ }
+ if( BiffObjectBase::implIsValid() )
+ {
+ const Config& rCfg = cfg();
+ mxErrCodes = rCfg.getNameList( "ERRORCODES" );
+ mxConstType = rCfg.getNameList( "CONSTVALUE-TYPE" );
+ mxResultType = rCfg.getNameList( "FORMULA-RESULTTYPE" );
+ }
+ }
+}
+
+void BiffObjectBase::construct( const BiffObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool BiffObjectBase::implIsValid() const
+{
+ return isValid( mxBiffCfg ) && isValid( mxBiffData ) && mxStrm.get() && InputStreamObject::implIsValid();
+}
+
+ConfigRef BiffObjectBase::implReconstructConfig()
+{
+ mxBiffCfg.reset( new BiffConfig( cfg(), getBiff() ) );
+ return mxBiffCfg;
+}
+
+InputRef BiffObjectBase::implReconstructInput()
+{
+ InputRef xIn;
+ if( mxStrm.get() )
+ xIn.reset( new BiffStreamInput( *mxStrm ) );
+ return xIn;
+}
+
+OUString BiffObjectBase::getErrorName( sal_uInt8 nErrCode ) const
+{
+ return cfg().getName( mxErrCodes, nErrCode );
+}
+
+// ----------------------------------------------------------------------------
+
+sal_Int32 BiffObjectBase::readCol( bool bCol16Bit )
+{
+ return bCol16Bit ? mxStrm->readuInt16() : mxStrm->readuInt8();
+}
+
+sal_Int32 BiffObjectBase::readRow( bool bRow32Bit )
+{
+ return bRow32Bit ? mxStrm->readInt32() : mxStrm->readuInt16();
+}
+
+void BiffObjectBase::readAddress( Address& orAddress, bool bCol16Bit, bool bRow32Bit )
+{
+ orAddress.mnRow = readRow( bRow32Bit );
+ orAddress.mnCol = readCol( bCol16Bit );
+}
+
+void BiffObjectBase::readRange( Range& orRange, bool bCol16Bit, bool bRow32Bit )
+{
+ orRange.maFirst.mnRow = readRow( bRow32Bit );
+ orRange.maLast.mnRow = readRow( bRow32Bit );
+ orRange.maFirst.mnCol = readCol( bCol16Bit );
+ orRange.maLast.mnCol = readCol( bCol16Bit );
+}
+
+void BiffObjectBase::readRangeList( RangeList& orRanges, bool bCol16Bit, bool bRow32Bit )
+{
+ sal_uInt16 nCount;
+ *mxStrm >> nCount;
+ orRanges.resize( nCount );
+ for( RangeList::iterator aIt = orRanges.begin(), aEnd = orRanges.end(); mxStrm->isValid() && (aIt != aEnd); ++aIt )
+ readRange( *aIt, bCol16Bit, bRow32Bit );
+}
+
+// ----------------------------------------------------------------------------
+
+void BiffObjectBase::writeBooleanItem( const sal_Char* pcName, sal_uInt8 nBool )
+{
+ writeDecItem( pcName, nBool, "BOOLEAN" );
+}
+
+void BiffObjectBase::writeErrorCodeItem( const sal_Char* pcName, sal_uInt8 nErrCode )
+{
+ writeHexItem( pcName, nErrCode, mxErrCodes );
+}
+
+void BiffObjectBase::writeFontPortions( const BinFontPortionList& rPortions )
+{
+ if( !rPortions.empty() )
+ {
+ writeDecItem( "font-count", static_cast< sal_uInt32 >( rPortions.size() ) );
+ TableGuard aTabGuard( out(), 14 );
+ for( BinFontPortionList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeDecItem( "char-pos", aIt->mnPos );
+ writeDecItem( "font-idx", aIt->mnFontId, "FONTNAMES" );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+OUString BiffObjectBase::dumpByteString( const sal_Char* pcName, BiffStringFlags nFlags, rtl_TextEncoding eDefaultTextEnc )
+{
+ OSL_ENSURE( !getFlag( nFlags, static_cast< BiffStringFlags >( ~(BIFF_STR_8BITLENGTH | BIFF_STR_EXTRAFONTS) ) ), "BiffObjectBase::dumpByteString - unknown flag" );
+ bool b8BitLength = getFlag( nFlags, BIFF_STR_8BITLENGTH );
+
+ OString aString = mxStrm->readByteString( !b8BitLength );
+ BinFontPortionList aPortions;
+ if( getFlag( nFlags, BIFF_STR_EXTRAFONTS ) )
+ aPortions.importPortions( *mxStrm, false );
+
+ // create string portions
+ OUStringBuffer aBuffer;
+ sal_Int32 nStrLen = aString.getLength();
+ if( nStrLen > 0 )
+ {
+ // add leading and trailing string position to ease the following loop
+ if( aPortions.empty() || (aPortions.front().mnPos > 0) )
+ aPortions.insert( aPortions.begin(), BinFontPortionData( 0, -1 ) );
+ if( aPortions.back().mnPos < nStrLen )
+ aPortions.push_back( BinFontPortionData( nStrLen, -1 ) );
+
+ // use global text encoding, if nothing special is specified
+ if( eDefaultTextEnc == RTL_TEXTENCODING_DONTKNOW )
+ eDefaultTextEnc = getBiffData().getTextEncoding();
+
+ // create all string portions according to the font id vector
+ for( BinFontPortionList::const_iterator aIt = aPortions.begin(); aIt->mnPos < nStrLen; ++aIt )
+ {
+ sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos;
+ if( nPortionLen > 0 )
+ {
+ // convert byte string to unicode string, using current font encoding
+ rtl_TextEncoding eTextEnc = mxBiffData->getFontEncoding( static_cast< sal_uInt16 >( aIt->mnFontId ) );
+ if( eTextEnc == RTL_TEXTENCODING_DONTKNOW )
+ eTextEnc = eDefaultTextEnc;
+ aBuffer.append( OStringToOUString( aString.copy( aIt->mnPos, nPortionLen ), eTextEnc ) );
+ }
+ }
+ }
+
+ OUString aUniStr = aBuffer.makeStringAndClear();
+ writeStringItem( pcName ? pcName : "text", aUniStr );
+ return aUniStr;
+}
+
+OUString BiffObjectBase::dumpUniString( const sal_Char* pcName, BiffStringFlags nFlags )
+{
+ OSL_ENSURE( !getFlag( nFlags, static_cast< BiffStringFlags >( ~(BIFF_STR_8BITLENGTH | BIFF_STR_SMARTFLAGS) ) ), "BiffObjectBase::dumpUniString - unknown flag" );
+ bool b8BitLength = getFlag( nFlags, BIFF_STR_8BITLENGTH );
+
+ // --- string header ---
+ sal_uInt16 nChars = b8BitLength ? mxStrm->readuInt8() : mxStrm->readuInt16();
+ sal_uInt8 nFlagField = 0;
+ if( (nChars > 0) || !getFlag( nFlags, BIFF_STR_SMARTFLAGS ) )
+ *mxStrm >> nFlagField;
+
+ bool b16Bit, bFonts, bPhonetic;
+ sal_uInt16 nFontCount;
+ sal_uInt32 nPhoneticSize;
+ mxStrm->readExtendedUniStringHeader( b16Bit, bFonts, bPhonetic, nFontCount, nPhoneticSize, nFlagField );
+
+ // --- character array ---
+ OUString aString = mxStrm->readRawUniString( nChars, b16Bit );
+ writeStringItem( pcName ? pcName : "text", aString );
+
+ // --- formatting ---
+ // #122185# bRich flag may be set, but format runs may be missing
+ if( nFontCount > 0 )
+ {
+ IndentGuard aIndGuard( out() );
+ BinFontPortionList aPortions;
+ aPortions.importPortions( *mxStrm, nFontCount, true );
+ writeFontPortions( aPortions );
+ }
+
+ // --- phonetic information ---
+ // #122185# bPhonetic flag may be set, but phonetic data may be missing
+ if( nPhoneticSize > 0 )
+ {
+ IndentGuard aIndGuard( out() );
+ dumpBinary( "phonetic-data", nPhoneticSize, false );
+ }
+
+ return aString;
+}
+
+OUString BiffObjectBase::dumpString( const sal_Char* pcName, BiffStringFlags nByteFlags, BiffStringFlags nUniFlags, rtl_TextEncoding eDefaultTextEnc )
+{
+ return (getBiff() == BIFF8) ? dumpUniString( pcName, nUniFlags ) : dumpByteString( pcName, nByteFlags, eDefaultTextEnc );
+}
+
+OUString BiffObjectBase::dumpOleString( const sal_Char* pcName, sal_Int32 nCharCount, bool bUnicode )
+{
+ OUString aString;
+ if( nCharCount > 0 )
+ {
+ sal_uInt16 nReadChars = getLimitedValue< sal_uInt16, sal_Int32 >( nCharCount, 0, SAL_MAX_UINT16 );
+ aString = bUnicode ?
+ mxStrm->readUnicodeArray( nReadChars ) :
+ mxStrm->readCharArray( nReadChars, getBiffData().getTextEncoding() );
+ // skip remaining chars
+ sal_uInt32 nSkip = static_cast< sal_uInt32 >( nCharCount - nReadChars );
+ mxStrm->skip( bUnicode ? (nSkip * 2) : nSkip );
+ }
+ writeStringItem( pcName ? pcName : "text", aString );
+ return aString;
+}
+
+OUString BiffObjectBase::dumpOleString( const sal_Char* pcName, bool bUnicode )
+{
+ return dumpOleString( pcName, mxStrm->readInt32(), bUnicode );
+}
+
+OUString BiffObjectBase::dumpNullString( const sal_Char* pcName, bool bUnicode )
+{
+ OUString aString;
+ if( bUnicode )
+ {
+ OUStringBuffer aBuffer;
+ sal_uInt16 nChar;
+ for( bool bLoop = true; bLoop && mxStrm->isValid(); )
+ {
+ *mxStrm >> nChar;
+ if( (bLoop = (nChar != 0)) == true )
+ aBuffer.append( static_cast< sal_Unicode >( nChar ) );
+ }
+ aString = aBuffer.makeStringAndClear();
+ }
+ else
+ {
+ OStringBuffer aBuffer;
+ sal_uInt8 nChar;
+ for( bool bLoop = true; bLoop && mxStrm->isValid(); )
+ {
+ *mxStrm >> nChar;
+ if( (bLoop = (nChar != 0)) == true )
+ aBuffer.append( static_cast< sal_Char >( nChar ) );
+ }
+ aString = OStringToOUString( aBuffer.makeStringAndClear(), getBiffData().getTextEncoding() );
+ }
+ writeStringItem( pcName ? pcName : "text", aString );
+ return aString;
+}
+
+sal_uInt8 BiffObjectBase::dumpBoolean( const sal_Char* pcName )
+{
+ sal_uInt8 nBool;
+ *mxStrm >> nBool;
+ writeBooleanItem( pcName ? pcName : "boolean", nBool );
+ return nBool;
+}
+
+sal_uInt8 BiffObjectBase::dumpErrorCode( const sal_Char* pcName )
+{
+ sal_uInt8 nErrCode;
+ *mxStrm >> nErrCode;
+ writeErrorCodeItem( pcName ? pcName : "errorcode", nErrCode );
+ return nErrCode;
+}
+
+sal_Int32 BiffObjectBase::dumpRgbColor( const sal_Char* pcName )
+{
+ OoxColor aColor;
+ aColor.importColorRgb( *mxStrm );
+ writeColorItem( pcName ? pcName : "color-rgb", aColor.mnValue );
+ return aColor.mnValue;
+}
+
+rtl_TextEncoding BiffObjectBase::dumpCodePage( const sal_Char* pcName )
+{
+ sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( pcName ? pcName : "codepage", "CODEPAGES" );
+ return BiffHelper::calcTextEncodingFromCodePage( nCodePage );
+}
+
+void BiffObjectBase::dumpFormulaResult( const sal_Char* pcName )
+{
+ MultiItemsGuard aMultiGuard( out() );
+ sal_uInt8 pnResult[ 8 ];
+ mxStrm->read( pnResult, 8 );
+ writeArrayItem( pcName ? pcName : "result", pnResult, 8 );
+ if( (pnResult[ 6 ] == 0xFF) && (pnResult[ 7 ] == 0xFF) )
+ {
+ sal_uInt8 nType = pnResult[ 0 ];
+ sal_uInt8 nData = pnResult[ 2 ];
+ writeHexItem( "type", nType, mxResultType );
+ switch( nType )
+ {
+ case 1: writeBooleanItem( "value", nData ); break;
+ case 2: writeErrorCodeItem( "value", nData ); break;
+ }
+ }
+ else
+ {
+ double* pfValue = reinterpret_cast< double* >( pnResult );
+ ByteOrderConverter::convertLittleEndian( *pfValue );
+ writeDecItem( "value", *pfValue );
+ }
+}
+
+sal_Int32 BiffObjectBase::dumpColIndex( const sal_Char* pcName, bool bCol16Bit )
+{
+ sal_Int32 nCol = readCol( bCol16Bit );
+ writeColIndexItem( pcName ? pcName : "col-idx", nCol );
+ return nCol;
+}
+
+sal_Int32 BiffObjectBase::dumpRowIndex( const sal_Char* pcName, bool bRow32Bit )
+{
+ sal_Int32 nRow = readRow( bRow32Bit );
+ writeRowIndexItem( pcName ? pcName : "row-idx", nRow );
+ return nRow;
+}
+
+sal_Int32 BiffObjectBase::dumpColRange( const sal_Char* pcName, bool bCol16Bit )
+{
+ sal_Int32 nCol1 = readCol( bCol16Bit );
+ sal_Int32 nCol2 = readCol( bCol16Bit );
+ writeColRangeItem( pcName ? pcName : "col-range", nCol1, nCol2 );
+ return nCol2 - nCol1 + 1;
+}
+
+sal_Int32 BiffObjectBase::dumpRowRange( const sal_Char* pcName, bool bRow32Bit )
+{
+ sal_Int32 nRow1 = readRow( bRow32Bit );
+ sal_Int32 nRow2 = readRow( bRow32Bit );
+ writeRowRangeItem( pcName ? pcName : "row-range", nRow1, nRow2 );
+ return nRow2 - nRow1 + 1;
+}
+
+Address BiffObjectBase::dumpAddress( const sal_Char* pcName, bool bCol16Bit, bool bRow32Bit )
+{
+ Address aPos;
+ readAddress( aPos, bCol16Bit, bRow32Bit );
+ writeAddressItem( pcName ? pcName : "addr", aPos );
+ return aPos;
+}
+
+Range BiffObjectBase::dumpRange( const sal_Char* pcName, bool bCol16Bit, bool bRow32Bit )
+{
+ Range aRange;
+ readRange( aRange, bCol16Bit, bRow32Bit );
+ writeRangeItem( pcName ? pcName : "range", aRange );
+ return aRange;
+}
+
+void BiffObjectBase::dumpRangeList( const sal_Char* pcName, bool bCol16Bit, bool bRow32Bit )
+{
+ RangeList aRanges;
+ readRangeList( aRanges, bCol16Bit, bRow32Bit );
+ writeRangeListItem( pcName ? pcName : "range-list", aRanges );
+}
+
+void BiffObjectBase::dumpConstArrayHeader( sal_uInt32& rnCols, sal_uInt32& rnRows )
+{
+ Output& rOut = out();
+ MultiItemsGuard aMultiGuard( rOut );
+ rnCols = dumpDec< sal_uInt8 >( "width" );
+ rnRows = dumpDec< sal_uInt16 >( "height" );
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ case BIFF5: if( rnCols == 0 ) rnCols = 256; break;
+ case BIFF8: ++rnCols; ++rnRows; break;
+ case BIFF_UNKNOWN: break;
+ }
+ ItemGuard aItem( rOut, "size" );
+ rOut.writeDec( rnCols );
+ rOut.writeChar( 'x' );
+ rOut.writeDec( rnRows );
+ aItem.cont();
+ rOut.writeDec( rnCols * rnRows );
+}
+
+OUString BiffObjectBase::dumpConstValue()
+{
+ Output& rOut = out();
+ MultiItemsGuard aMultiGuard( rOut );
+ OUStringBuffer aValue;
+ switch( dumpDec< sal_uInt8 >( "type", mxConstType ) )
+ {
+ case BIFF_DATATYPE_EMPTY:
+ dumpUnused( 8 );
+ aValue.append( OOX_DUMP_EMPTYVALUE );
+ break;
+ case BIFF_DATATYPE_DOUBLE:
+ dumpDec< double >( "value" );
+ aValue.append( rOut.getLastItemValue() );
+ break;
+ case BIFF_DATATYPE_STRING:
+ aValue.append( dumpString( "value", BIFF_STR_8BITLENGTH ) );
+ StringHelper::enclose( aValue, OOX_DUMP_STRQUOTE );
+ break;
+ case BIFF_DATATYPE_BOOL:
+ dumpBoolean( "value" );
+ aValue.append( rOut.getLastItemValue() );
+ dumpUnused( 7 );
+ break;
+ case BIFF_DATATYPE_ERROR:
+ dumpErrorCode( "value" );
+ aValue.append( rOut.getLastItemValue() );
+ dumpUnused( 7 );
+ break;
+ }
+ return aValue.makeStringAndClear();
+}
+
+// ============================================================================
+// ============================================================================
+
+FormulaObject::FormulaObject( const BiffObjectBase& rParent ) :
+ mpcName( 0 ),
+ mnSize( 0 )
+{
+ BiffObjectBase::construct( rParent );
+ constructFmlaObj();
+}
+
+FormulaObject::~FormulaObject()
+{
+}
+
+sal_uInt16 FormulaObject::readFormulaSize()
+{
+ return (getBiff() == BIFF2) ? getBiffStream().readuInt8() : getBiffStream().readuInt16();
+}
+
+sal_uInt16 FormulaObject::dumpFormulaSize( const sal_Char* pcName )
+{
+ if( !pcName ) pcName = "formula-size";
+ sal_uInt16 nSize = readFormulaSize();
+ writeDecItem( pcName, nSize );
+ return nSize;
+}
+
+void FormulaObject::dumpCellFormula( const sal_Char* pcName, sal_uInt16 nSize )
+{
+ dumpFormula( pcName, nSize, false );
+}
+
+void FormulaObject::dumpCellFormula( const sal_Char* pcName )
+{
+ dumpFormula( pcName, false );
+}
+
+void FormulaObject::dumpNameFormula( const sal_Char* pcName, sal_uInt16 nSize )
+{
+ dumpFormula( pcName, nSize, true );
+}
+
+void FormulaObject::dumpNameFormula( const sal_Char* pcName )
+{
+ dumpFormula( pcName, true );
+}
+
+void FormulaObject::implDump()
+{
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( mpcName );
+ writeDecItem( "formula-size", mnSize );
+ }
+ if( mnSize == 0 ) return;
+
+ Input& rIn = in();
+ sal_Int64 nStartPos = rIn.tell();
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, rIn.getSize() );
+
+ bool bValid = mxTokens.get();
+ mxStack.reset( new FormulaStack );
+ maAddData.clear();
+ IndentGuard aIndGuard( out() );
+ {
+ TableGuard aTabGuard( out(), 8, 18 );
+ while( bValid && (rIn.tell() < nEndPos) )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeHexItem( 0, static_cast< sal_uInt16 >( rIn.tell() - nStartPos ) );
+ sal_uInt8 nTokenId = dumpHex< sal_uInt8 >( 0, mxTokens );
+ bValid = mxTokens->hasName( nTokenId );
+ if( bValid )
+ {
+ sal_uInt8 nTokClass = nTokenId & BIFF_TOKCLASS_MASK;
+ sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
+ if( nTokClass == BIFF_TOKCLASS_NONE )
+ {
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_EXP: dumpExpToken( "EXP" ); break;
+ case BIFF_TOKID_TBL: dumpExpToken( "TBL" ); break;
+ case BIFF_TOKID_ADD: dumpBinaryOpToken( "+" ); break;
+ case BIFF_TOKID_SUB: dumpBinaryOpToken( "-" ); break;
+ case BIFF_TOKID_MUL: dumpBinaryOpToken( "*" ); break;
+ case BIFF_TOKID_DIV: dumpBinaryOpToken( "/" ); break;
+ case BIFF_TOKID_POWER: dumpBinaryOpToken( "^" ); break;
+ case BIFF_TOKID_CONCAT: dumpBinaryOpToken( "&" ); break;
+ case BIFF_TOKID_LT: dumpBinaryOpToken( "<" ); break;
+ case BIFF_TOKID_LE: dumpBinaryOpToken( "<=" ); break;
+ case BIFF_TOKID_EQ: dumpBinaryOpToken( "=" ); break;
+ case BIFF_TOKID_GE: dumpBinaryOpToken( ">=" ); break;
+ case BIFF_TOKID_GT: dumpBinaryOpToken( "<" ); break;
+ case BIFF_TOKID_NE: dumpBinaryOpToken( "<>" ); break;
+ case BIFF_TOKID_ISECT: dumpBinaryOpToken( " " ); break;
+ case BIFF_TOKID_LIST: dumpBinaryOpToken( "," ); break;
+ case BIFF_TOKID_RANGE: dumpBinaryOpToken( ":" ); break;
+ case BIFF_TOKID_UPLUS: dumpUnaryOpToken( "+", "" ); break;
+ case BIFF_TOKID_UMINUS: dumpUnaryOpToken( "-", "" ); break;
+ case BIFF_TOKID_PERCENT: dumpUnaryOpToken( "", "%" ); break;
+ case BIFF_TOKID_PAREN: dumpUnaryOpToken( "(", ")" ); break;
+ case BIFF_TOKID_MISSARG: dumpMissArgToken(); break;
+ case BIFF_TOKID_STR: dumpStringToken(); break;
+ case BIFF_TOKID_NLR: bValid = dumpNlrToken(); break;
+ case BIFF_TOKID_ATTR: bValid = dumpAttrToken(); break;
+ case BIFF_TOKID_SHEET: dumpSheetToken(); break;
+ case BIFF_TOKID_ENDSHEET: dumpEndSheetToken(); break;
+ case BIFF_TOKID_ERR: dumpErrorToken(); break;
+ case BIFF_TOKID_BOOL: dumpBoolToken(); break;
+ case BIFF_TOKID_INT: dumpIntToken(); break;
+ case BIFF_TOKID_NUM: dumpDoubleToken(); break;
+ default: bValid = false;
+ }
+ }
+ else
+ {
+ OUString aTokClass = cfg().getName( mxClasses, nTokClass );
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_ARRAY: dumpArrayToken( aTokClass ); break;
+ case BIFF_TOKID_FUNC: dumpFuncToken( aTokClass ); break;
+ case BIFF_TOKID_FUNCVAR: dumpFuncVarToken( aTokClass ); break;
+ case BIFF_TOKID_NAME: dumpNameToken( aTokClass ); break;
+ case BIFF_TOKID_REF: dumpRefToken( aTokClass, false ); break;
+ case BIFF_TOKID_AREA: dumpAreaToken( aTokClass, false ); break;
+ case BIFF_TOKID_MEMAREA: dumpMemAreaToken( aTokClass, true ); break;
+ case BIFF_TOKID_MEMERR: dumpMemAreaToken( aTokClass, false ); break;
+ case BIFF_TOKID_MEMNOMEM: dumpMemAreaToken( aTokClass, false ); break;
+ case BIFF_TOKID_MEMFUNC: dumpMemFuncToken( aTokClass ); break;
+ case BIFF_TOKID_REFERR: dumpRefErrToken( aTokClass, false ); break;
+ case BIFF_TOKID_AREAERR: dumpRefErrToken( aTokClass, true ); break;
+ case BIFF_TOKID_REFN: dumpRefToken( aTokClass, true ); break;
+ case BIFF_TOKID_AREAN: dumpAreaToken( aTokClass, true ); break;
+ case BIFF_TOKID_MEMAREAN: dumpMemFuncToken( aTokClass ); break;
+ case BIFF_TOKID_MEMNOMEMN: dumpMemFuncToken( aTokClass ); break;
+ case BIFF_TOKID_FUNCCE: dumpCmdToken( aTokClass ); break;
+ case BIFF_TOKID_NAMEX: dumpNameXToken( aTokClass ); break;
+ case BIFF_TOKID_REF3D: dumpRef3dToken( aTokClass, mbNameMode ); break;
+ case BIFF_TOKID_AREA3D: dumpArea3dToken( aTokClass, mbNameMode ); break;
+ case BIFF_TOKID_REFERR3D: dumpRefErr3dToken( aTokClass, false ); break;
+ case BIFF_TOKID_AREAERR3D: dumpRefErr3dToken( aTokClass, true ); break;
+ default: bValid = false;
+ }
+ }
+ }
+ }
+ }
+ bValid = nEndPos == rIn.tell();
+ if( bValid )
+ {
+ dumpAddTokenData();
+ writeInfoItem( "formula", mxStack->getFormulaString() );
+ writeInfoItem( "classes", mxStack->getClassesString() );
+ }
+ else
+ dumpBinary( OOX_DUMP_ERRASCII( "formula-error" ), static_cast< sal_Int32 >( nEndPos - rIn.tell() ), false );
+
+ mpcName = 0;
+ mnSize = 0;
+}
+
+void FormulaObject::dumpFormula( const sal_Char* pcName, sal_uInt16 nSize, bool bNameMode )
+{
+ mpcName = pcName ? pcName : "formula";
+ mnSize = nSize;
+ mbNameMode = bNameMode;
+ dump();
+}
+
+void FormulaObject::dumpFormula( const sal_Char* pcName, bool bNameMode )
+{
+ dumpFormula( pcName, readFormulaSize(), bNameMode );
+}
+
+// private --------------------------------------------------------------------
+
+void FormulaObject::constructFmlaObj()
+{
+ if( BiffObjectBase::implIsValid() )
+ {
+ Reference< XSpreadsheetDocument > xDocument( getFilter().getModel(), UNO_QUERY );
+ mxFuncProv.reset( new FunctionProvider( xDocument, getBiff(), true ) );
+
+ Config& rCfg = cfg();
+ mxClasses = rCfg.getNameList( "TOKENCLASSES" );
+ mxRelFlags = rCfg.getNameList( "REFRELFLAGS" );
+ mxNlrTypes = rCfg.getNameList( "NLRTYPES" );
+ mxAttrTypes = rCfg.getNameList( "ATTRTYPES" );
+ mxSpTypes = rCfg.getNameList( "ATTRSPACETYPES" );
+
+ // create classified token names
+ mxTokens = rCfg.createNameList< ConstList >( "TOKENS" );
+ mxTokens->includeList( rCfg.getNameList( "BASETOKENS" ) );
+
+ NameListRef xClassTokens = rCfg.getNameList( "CLASSTOKENS" );
+ if( mxClasses.get() && xClassTokens.get() )
+ for( NameListBase::const_iterator aCIt = mxClasses->begin(), aCEnd = mxClasses->end(); aCIt != aCEnd; ++aCIt )
+ for( NameListBase::const_iterator aTIt = xClassTokens->begin(), aTEnd = xClassTokens->end(); aTIt != aTEnd; ++aTIt )
+ mxTokens->setName( aCIt->first | aTIt->first, aTIt->second + aCIt->second );
+
+ mnColCount = 256;
+ mnRowCount = (getBiff() == BIFF8) ? 65536 : 16384;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+OUString lclCreateName( const OUString& rRef, sal_uInt16 nNameIdx )
+{
+ OUStringBuffer aName( rRef );
+ StringHelper::appendIndexedText( aName, CREATE_OUSTRING( "NAME" ), nNameIdx );
+ return aName.makeStringAndClear();
+}
+
+OUString lclCreateNlr( const OUString& rData, bool bRel = true )
+{
+ OUStringBuffer aNlr;
+ if( !bRel ) aNlr.append( OOX_DUMP_ADDRABS );
+ StringHelper::appendIndexedText( aNlr, CREATE_OUSTRING( "NLR" ), rData );
+ return aNlr.makeStringAndClear();
+}
+
+OUString lclCreateNlr( const TokenAddress& rPos )
+{
+ OUStringBuffer aAddr;
+ StringHelper::appendAddrCol( aAddr, rPos.mnCol, true );
+ StringHelper::appendAddrRow( aAddr, rPos.mnRow, true );
+ return lclCreateNlr( aAddr.makeStringAndClear(), rPos.mbRelRow );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+TokenAddress FormulaObject::createTokenAddress( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelC, bool bRelR, bool bNameMode ) const
+{
+ TokenAddress aPos;
+ aPos.mnCol = nCol;
+ if( bRelC && bNameMode && (nCol >= mnColCount / 2) ) aPos.mnCol -= mnColCount;
+ aPos.mbRelCol = bRelC;
+ aPos.mnRow = nRow;
+ if( bRelR && bNameMode && (nRow >= mnRowCount / 2) ) aPos.mnRow -= mnRowCount;
+ aPos.mbRelRow = bRelR;
+ return aPos;
+}
+
+OUString FormulaObject::createRef( const OUString& rData ) const
+{
+ return maRefPrefix + rData;
+}
+
+OUString FormulaObject::createName( sal_uInt16 nNameIdx ) const
+{
+ return lclCreateName( maRefPrefix, nNameIdx );
+}
+
+OUString FormulaObject::createPlaceHolder( size_t nIdx ) const
+{
+ OUStringBuffer aStr;
+ StringHelper::appendDec( aStr, static_cast< sal_uInt32 >( nIdx ) );
+ StringHelper::enclose( aStr, OOX_DUMP_PLACEHOLDER );
+ return aStr.makeStringAndClear();
+}
+
+OUString FormulaObject::createPlaceHolder() const
+{
+ return createPlaceHolder( maAddData.size() );
+}
+
+sal_uInt16 FormulaObject::readFuncId()
+{
+ return (getBiff() >= BIFF4) ? in().readValue< sal_uInt16 >() : in().readValue< sal_uInt8 >();
+}
+
+OUString FormulaObject::writeFuncIdItem( sal_uInt16 nFuncId, const FunctionInfo** oppFuncInfo )
+{
+ ItemGuard aItemGuard( out(), "func-id" );
+ writeHexItem( 0, nFuncId, "FUNCID" );
+ OUStringBuffer aBuffer;
+ const FunctionInfo* pFuncInfo = mxFuncProv->getFuncInfoFromBiffFuncId( nFuncId );
+ if( pFuncInfo )
+ aBuffer.append( pFuncInfo->maOoxFuncName );
+ else
+ {
+ bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
+ aBuffer.appendAscii( bCmd ? "CMD" : "FUNC" );
+ StringHelper::appendIndex( aBuffer, nFuncId & BIFF_TOK_FUNCVAR_FUNCIDMASK );
+ }
+ OUString aFuncName = aBuffer.makeStringAndClear();
+ aItemGuard.cont();
+ out().writeString( aFuncName );
+ if( oppFuncInfo ) *oppFuncInfo = pFuncInfo;
+ return aFuncName;
+}
+
+sal_uInt16 FormulaObject::dumpTokenCol( const sal_Char* pcName, bool& rbRelC, bool& rbRelR )
+{
+ sal_uInt16 nCol = 0;
+ if( getBiff() == BIFF8 )
+ {
+ nCol = dumpHex< sal_uInt16 >( pcName, mxRelFlags );
+ rbRelC = getFlag( nCol, BIFF_TOK_REF_COLREL );
+ rbRelR = getFlag( nCol, BIFF_TOK_REF_ROWREL );
+ nCol &= BIFF_TOK_REF_COLMASK;
+ }
+ else
+ nCol = dumpDec< sal_uInt8 >( pcName );
+ return nCol;
+}
+
+sal_uInt16 FormulaObject::dumpTokenRow( const sal_Char* pcName, bool& rbRelC, bool& rbRelR )
+{
+ sal_uInt16 nRow = 0;
+ if( getBiff() == BIFF8 )
+ nRow = dumpDec< sal_uInt16 >( pcName );
+ else
+ {
+ nRow = dumpHex< sal_uInt16 >( pcName, mxRelFlags );
+ rbRelC = getFlag( nRow, BIFF_TOK_REF_COLREL );
+ rbRelR = getFlag( nRow, BIFF_TOK_REF_ROWREL );
+ nRow &= BIFF_TOK_REF_ROWMASK;
+ }
+ return nRow;
+}
+
+TokenAddress FormulaObject::dumpTokenAddress( bool bNameMode )
+{
+ bool bRelC = false;
+ bool bRelR = false;
+ sal_uInt16 nRow = dumpTokenRow( "row", bRelC, bRelR );
+ sal_uInt16 nCol = dumpTokenCol( "col", bRelC, bRelR );
+ return createTokenAddress( nCol, nRow, bRelC, bRelR, bNameMode );
+}
+
+TokenRange FormulaObject::dumpTokenRange( bool bNameMode )
+{
+ bool bRelC1 = false;
+ bool bRelR1 = false;
+ bool bRelC2 = false;
+ bool bRelR2 = false;
+ sal_uInt16 nRow1 = dumpTokenRow( "row1", bRelC1, bRelR1 );
+ sal_uInt16 nRow2 = dumpTokenRow( "row2", bRelC2, bRelR2 );
+ sal_uInt16 nCol1 = dumpTokenCol( "col1", bRelC1, bRelR1 );
+ sal_uInt16 nCol2 = dumpTokenCol( "col2", bRelC2, bRelR2 );
+ TokenRange aRange;
+ aRange.maFirst = createTokenAddress( nCol1, nRow1, bRelC1, bRelR1, bNameMode );
+ aRange.maLast = createTokenAddress( nCol2, nRow2, bRelC2, bRelR2, bNameMode );
+ return aRange;
+}
+
+sal_Int16 FormulaObject::readTokenRefIdx()
+{
+ sal_Int16 nRefIdx = dumpDec< sal_Int16 >( "ref-idx" );
+ switch( getBiff() )
+ {
+ case BIFF2: dumpUnused( 1 ); break;
+ case BIFF3: dumpUnused( 2 ); break;
+ case BIFF4: dumpUnused( 2 ); break;
+ case BIFF5: dumpUnused( 8 ); break;
+ case BIFF8: break;
+ case BIFF_UNKNOWN: break;
+ }
+ return nRefIdx;
+}
+
+OUString FormulaObject::dumpTokenRefIdx()
+{
+ OUStringBuffer aRef( CREATE_OUSTRING( "REF" ) );
+ StringHelper::appendIndex( aRef, readTokenRefIdx() );
+ aRef.append( OOX_DUMP_TABSEP );
+ return aRef.makeStringAndClear();
+}
+
+OUString FormulaObject::dumpTokenRefTabIdxs()
+{
+ sal_Int16 nRefIdx = readTokenRefIdx();
+ OUStringBuffer aRef( CREATE_OUSTRING( "REF" ) );
+ StringHelper::appendIndex( aRef, nRefIdx );
+ if( getBiff() == BIFF5 )
+ {
+ dumpDec< sal_Int16 >( "tab1" );
+ sal_Int16 nTab2 = dumpDec< sal_Int16 >( "tab2" );
+ if( (nRefIdx > 0) && (nTab2 > 0) && (nRefIdx != nTab2) )
+ {
+ aRef.append( OOX_DUMP_RANGESEP );
+ aRef.appendAscii( "REF" );
+ StringHelper::appendIndex( aRef, nTab2 );
+ }
+ }
+ aRef.append( OOX_DUMP_TABSEP );
+ return aRef.makeStringAndClear();
+}
+
+void FormulaObject::dumpIntToken()
+{
+ dumpDec< sal_uInt16 >( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpDoubleToken()
+{
+ dumpDec< double >( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpStringToken()
+{
+ OUStringBuffer aValue;
+ aValue.append( dumpString( "value", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH ) );
+ StringHelper::enclose( aValue, OOX_DUMP_FMLASTRQUOTE );
+ mxStack->pushOperand( aValue.makeStringAndClear() );
+}
+
+void FormulaObject::dumpBoolToken()
+{
+ dumpBoolean( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpErrorToken()
+{
+ dumpErrorCode( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpMissArgToken()
+{
+ mxStack->pushOperand( OUString( OOX_DUMP_EMPTYVALUE ) );
+}
+
+void FormulaObject::dumpArrayToken( const OUString& rTokClass )
+{
+ dumpUnused( (getBiff() == BIFF2) ? 6 : 7 );
+ mxStack->pushOperand( createPlaceHolder(), rTokClass );
+ maAddData.push_back( ADDDATA_ARRAY );
+}
+
+void FormulaObject::dumpNameToken( const OUString& rTokClass )
+{
+ sal_uInt16 nNameIdx = dumpDec< sal_uInt16 >( "name-idx" );
+ switch( getBiff() )
+ {
+ case BIFF2: dumpUnused( 5 ); break;
+ case BIFF3:
+ case BIFF4: dumpUnused( 8 ); break;
+ case BIFF5: dumpUnused( 12 ); break;
+ case BIFF8: dumpUnused( 2 ); break;
+ case BIFF_UNKNOWN: break;
+ }
+ mxStack->pushOperand( createName( nNameIdx ), rTokClass );
+}
+
+void FormulaObject::dumpNameXToken( const OUString& rTokClass )
+{
+ OUString aRef = dumpTokenRefIdx();
+ sal_uInt16 nNameIdx = dumpDec< sal_uInt16 >( "name-idx" );
+ dumpUnused( (getBiff() == BIFF8) ? 2 : 12 );
+ mxStack->pushOperand( lclCreateName( aRef, nNameIdx ), rTokClass );
+}
+
+void FormulaObject::dumpRefToken( const OUString& rTokClass, bool bNameMode )
+{
+ TokenAddress aPos = dumpTokenAddress( bNameMode );
+ writeTokenAddressItem( "addr", aPos, bNameMode );
+ mxStack->pushOperand( createRef( out().getLastItemValue() ), rTokClass );
+}
+
+void FormulaObject::dumpAreaToken( const OUString& rTokClass, bool bNameMode )
+{
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRangeItem( "range", aRange, bNameMode );
+ mxStack->pushOperand( createRef( out().getLastItemValue() ), rTokClass );
+}
+
+void FormulaObject::dumpRefErrToken( const OUString& rTokClass, bool bArea )
+{
+ dumpUnused( ((getBiff() == BIFF8) ? 4 : 3) * (bArea ? 2 : 1) );
+ mxStack->pushOperand( createRef( getErrorName( BIFF_ERR_REF ) ), rTokClass );
+}
+
+void FormulaObject::dumpRef3dToken( const OUString& rTokClass, bool bNameMode )
+{
+ OUString aRef = dumpTokenRefTabIdxs();
+ TokenAddress aPos = dumpTokenAddress( bNameMode );
+ writeTokenAddress3dItem( "addr", aRef, aPos, bNameMode );
+ mxStack->pushOperand( out().getLastItemValue(), rTokClass );
+}
+
+void FormulaObject::dumpArea3dToken( const OUString& rTokClass, bool bNameMode )
+{
+ OUString aRef = dumpTokenRefTabIdxs();
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRange3dItem( "range", aRef, aRange, bNameMode );
+ mxStack->pushOperand( out().getLastItemValue(), rTokClass );
+}
+
+void FormulaObject::dumpRefErr3dToken( const OUString& rTokClass, bool bArea )
+{
+ OUString aRef = dumpTokenRefTabIdxs();
+ dumpUnused( ((getBiff() == BIFF8) ? 4 : 3) * (bArea ? 2 : 1) );
+ mxStack->pushOperand( aRef + getErrorName( BIFF_ERR_REF ), rTokClass );
+}
+
+void FormulaObject::dumpMemFuncToken( const OUString& /*rTokClass*/ )
+{
+ dumpDec< sal_uInt16, sal_uInt8 >( getBiff() != BIFF2, "size" );
+}
+
+void FormulaObject::dumpMemAreaToken( const OUString& rTokClass, bool bAddData )
+{
+ dumpUnused( (getBiff() == BIFF2) ? 3 : 4 );
+ dumpMemFuncToken( rTokClass );
+ if( bAddData )
+ maAddData.push_back( ADDDATA_MEMAREA );
+}
+
+void FormulaObject::dumpExpToken( const StringWrapper& rName )
+{
+ Address aPos;
+ aPos.mnRow = dumpDec< sal_uInt16 >( "row" );
+ aPos.mnCol = dumpDec< sal_uInt16, sal_uInt8 >( getBiff() != BIFF2, "col" );
+ writeAddressItem( "base-addr", aPos );
+ OUStringBuffer aOp( rName.getString() );
+ StringHelper::appendIndex( aOp, out().getLastItemValue() );
+ mxStack->pushOperand( aOp.makeStringAndClear() );
+}
+
+void FormulaObject::dumpUnaryOpToken( const StringWrapper& rLOp, const StringWrapper& rROp )
+{
+ mxStack->pushUnaryOp( rLOp, rROp );
+}
+
+void FormulaObject::dumpBinaryOpToken( const StringWrapper& rOp )
+{
+ mxStack->pushBinaryOp( rOp );
+}
+
+void FormulaObject::dumpFuncToken( const OUString& rTokClass )
+{
+ sal_uInt16 nFuncId = readFuncId();
+ const FunctionInfo* pFuncInfo = 0;
+ OUString aFuncName = writeFuncIdItem( nFuncId, &pFuncInfo );
+ if( pFuncInfo && (pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount) )
+ mxStack->pushFuncOp( aFuncName, rTokClass, pFuncInfo->mnMinParamCount );
+ else
+ mxStack->setError();
+}
+
+void FormulaObject::dumpFuncVarToken( const OUString& rTokClass )
+{
+ sal_uInt8 nParamCount;
+ in() >> nParamCount;
+ sal_uInt16 nFuncId = readFuncId();
+ bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
+ if( bCmd )
+ writeHexItem( "param-count", nParamCount, "PARAMCOUNT-CMD" );
+ else
+ writeDecItem( "param-count", nParamCount );
+ OUString aFuncName = writeFuncIdItem( nFuncId );
+ if( bCmd && getFlag( nParamCount, BIFF_TOK_FUNCVAR_CMDPROMPT ) )
+ {
+ aFuncName += OUString( OOX_DUMP_CMDPROMPT );
+ nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
+ }
+ mxStack->pushFuncOp( aFuncName, rTokClass, nParamCount );
+}
+
+void FormulaObject::dumpCmdToken( const OUString& rTokClass )
+{
+ sal_uInt8 nParamCount = dumpDec< sal_uInt8 >( "param-count", "PARAMCOUNT-CMD" );
+ sal_uInt16 nCmdId = readFuncId() | BIFF_TOK_FUNCVAR_CMD;
+ OUString aFuncName = writeFuncIdItem( nCmdId );
+ if( getFlag( nParamCount, BIFF_TOK_FUNCVAR_CMDPROMPT ) )
+ {
+ aFuncName += OUString( OOX_DUMP_CMDPROMPT );
+ nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
+ }
+ mxStack->pushFuncOp( aFuncName, rTokClass, nParamCount );
+}
+
+void FormulaObject::dumpSheetToken()
+{
+ dumpUnused( (getBiff() == BIFF2) ? 4 : 6 );
+ maRefPrefix = dumpTokenRefIdx();
+}
+
+void FormulaObject::dumpEndSheetToken()
+{
+ dumpUnused( (getBiff() == BIFF2) ? 3 : 4 );
+ maRefPrefix = OUString();
+}
+
+bool FormulaObject::dumpAttrToken()
+{
+ bool bValid = true;
+ bool bBiff2 = getBiff() == BIFF2;
+ sal_uInt8 nType = dumpHex< sal_uInt8 >( "type", mxAttrTypes );
+ switch( nType )
+ {
+ case BIFF_TOK_ATTR_VOLATILE:
+ dumpUnused( bBiff2 ? 1 : 2 );
+ break;
+ case BIFF_TOK_ATTR_IF:
+ dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip" );
+ break;
+ case BIFF_TOK_ATTR_CHOOSE:
+ {
+ sal_uInt16 nCount = dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "choices" );
+ out().resetItemIndex();
+ for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
+ dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "#skip" );
+ dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip-err" );
+ }
+ break;
+ case BIFF_TOK_ATTR_SKIP:
+ dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip" );
+ break;
+ case BIFF_TOK_ATTR_SUM:
+ dumpUnused( bBiff2 ? 1 : 2 );
+ mxStack->pushFuncOp( CREATE_OUSTRING( "SUM" ), OUString( OOX_DUMP_BASECLASS ), 1 );
+ break;
+ case BIFF_TOK_ATTR_ASSIGN:
+ dumpUnused( bBiff2 ? 1 : 2 );
+ break;
+ case BIFF_TOK_ATTR_SPACE:
+ case BIFF_TOK_ATTR_SPACE | BIFF_TOK_ATTR_VOLATILE:
+ switch( getBiff() )
+ {
+ case BIFF2:
+ bValid = false;
+ break;
+ case BIFF3:
+ dumpDec< sal_uInt16 >( "leading-spaces" );
+ break;
+ case BIFF4:
+ case BIFF5:
+ case BIFF8:
+ dumpDec< sal_uInt8 >( "char-type", mxSpTypes );
+ dumpDec< sal_uInt8 >( "char-count" );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+ break;
+ default:
+ bValid = false;
+ }
+ return bValid;
+}
+
+bool FormulaObject::dumpNlrToken()
+{
+ const OUString aRefClass = cfg().getName( mxClasses, BIFF_TOKCLASS_REF );
+ const OUString aValClass = cfg().getName( mxClasses, BIFF_TOKCLASS_VAL );
+
+ bool bValid = true;
+ sal_uInt8 nType = dumpHex< sal_uInt8 >( "type", mxNlrTypes );
+ switch( nType )
+ {
+ case BIFF_TOK_NLR_ERR: dumpNlrErrToken(); break;
+ case BIFF_TOK_NLR_ROWR: dumpNlrColRowToken( aRefClass, false ); break;
+ case BIFF_TOK_NLR_COLR: dumpNlrColRowToken( aRefClass, false ); break;
+ case BIFF_TOK_NLR_ROWV: dumpNlrColRowToken( aValClass, false ); break;
+ case BIFF_TOK_NLR_COLV: dumpNlrColRowToken( aValClass, false ); break;
+ case BIFF_TOK_NLR_RANGE: dumpNlrRangeToken( aRefClass, false ); break;
+ case BIFF_TOK_NLR_SRANGE: dumpNlrRangeToken( aRefClass, true ); break;
+ case BIFF_TOK_NLR_SROWR: dumpNlrColRowToken( aRefClass, true ); break;
+ case BIFF_TOK_NLR_SCOLR: dumpNlrColRowToken( aRefClass, true ); break;
+ case BIFF_TOK_NLR_SROWV: dumpNlrColRowToken( aValClass, true ); break;
+ case BIFF_TOK_NLR_SCOLV: dumpNlrColRowToken( aValClass, true ); break;
+ case BIFF_TOK_NLR_RANGEERR: dumpNlrRangeErrToken(); break;
+ default: bValid = false;
+ }
+ return bValid;
+}
+
+void FormulaObject::dumpNlrErrToken()
+{
+ dumpDec< sal_uInt32 >( "delname-idx" );
+ mxStack->pushOperand( lclCreateNlr( getErrorName( BIFF_ERR_NAME ) ) );
+}
+
+void FormulaObject::dumpNlrColRowToken( const OUString& rTokClass, bool bAddData )
+{
+ if( bAddData )
+ {
+ dumpUnused( 4 );
+ mxStack->pushOperand( createPlaceHolder(), rTokClass );
+ maAddData.push_back( ADDDATA_NLR );
+ }
+ else
+ {
+ TokenAddress aPos = dumpTokenAddress( false );
+ writeInfoItem( "addr", lclCreateNlr( aPos ) );
+ mxStack->pushOperand( out().getLastItemValue(), rTokClass );
+ }
+}
+
+void FormulaObject::dumpNlrRangeToken( const OUString& rTokClass, bool bAddData )
+{
+ if( bAddData )
+ {
+ dumpUnused( 4 );
+ mxStack->pushOperand( createPlaceHolder(), rTokClass );
+ maAddData.push_back( ADDDATA_NLR );
+ }
+ else
+ {
+ TokenAddress aPos = dumpTokenAddress( false );
+ writeInfoItem( "addr", lclCreateNlr( aPos ) );
+ mxStack->pushOperand( out().getLastItemValue(), rTokClass );
+ }
+ dumpUnknown( 1 );
+ dumpRange( "target-range" );
+}
+
+void FormulaObject::dumpNlrRangeErrToken()
+{
+ dumpDec< sal_uInt32 >( "delname-idx" );
+ dumpUnused( 9 );
+ mxStack->pushOperand( lclCreateNlr( getErrorName( BIFF_ERR_NAME ) ) );
+}
+
+void FormulaObject::dumpAddTokenData()
+{
+ Output& rOut = out();
+ rOut.resetItemIndex();
+ for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); aIt != aEnd; ++aIt )
+ {
+ AddDataType eType = *aIt;
+
+ {
+ ItemGuard aItem( rOut, "#add-data" );
+ switch( eType )
+ {
+ case ADDDATA_NLR: rOut.writeAscii( "tNlr" ); break;
+ case ADDDATA_ARRAY: rOut.writeAscii( "tArray" ); break;
+ case ADDDATA_MEMAREA: rOut.writeAscii( "tMemArea" ); break;
+ }
+ }
+
+ size_t nIdx = aIt - maAddData.begin();
+ IndentGuard aIndGuard( rOut );
+ switch( eType )
+ {
+ case ADDDATA_NLR: dumpAddDataNlr( nIdx ); break;
+ case ADDDATA_ARRAY: dumpAddDataArray( nIdx ); break;
+ case ADDDATA_MEMAREA: dumpAddDataMemArea( nIdx ); break;
+ }
+ }
+}
+
+void FormulaObject::dumpAddDataNlr( size_t nIdx )
+{
+ sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "flags", "NLRADDFLAGS" );
+ sal_uInt32 nCount = nFlags & BIFF_TOK_NLR_ADDMASK;
+ OUStringBuffer aBuffer;
+ for( sal_uInt32 nPos = 0; nPos < nCount; ++nPos )
+ {
+ Address aPos;
+ readAddress( aPos );
+ OUStringBuffer aAddr;
+ StringHelper::appendAddress( aAddr, aPos );
+ StringHelper::appendToken( aBuffer, aAddr.makeStringAndClear(), OOX_DUMP_LISTSEP );
+ }
+ OUString aAddrList = aBuffer.makeStringAndClear();
+ writeInfoItem( "stacked-positions", aAddrList );
+ mxStack->replaceOnTop( createPlaceHolder( nIdx ), lclCreateNlr( aAddrList ) );
+}
+
+void FormulaObject::dumpAddDataArray( size_t nIdx )
+{
+ sal_uInt32 nCols, nRows;
+ dumpConstArrayHeader( nCols, nRows );
+
+ OUStringBuffer aOp;
+ TableGuard aTabGuard( out(), 17 );
+ for( sal_uInt32 nRow = 0; nRow < nRows; ++nRow )
+ {
+ OUStringBuffer aArrayLine;
+ for( sal_uInt32 nCol = 0; nCol < nCols; ++nCol )
+ StringHelper::appendToken( aArrayLine, dumpConstValue(), OOX_DUMP_LISTSEP );
+ StringHelper::appendToken( aOp, aArrayLine.makeStringAndClear(), OOX_DUMP_ARRAYSEP );
+ }
+ StringHelper::enclose( aOp, '{', '}' );
+ mxStack->replaceOnTop( createPlaceHolder( nIdx ), aOp.makeStringAndClear() );
+}
+
+void FormulaObject::dumpAddDataMemArea( size_t /*nIdx*/ )
+{
+ dumpRangeList( 0, getBiff() == BIFF8 );
+}
+
+// ============================================================================
+// ============================================================================
+
+RecordHeaderObject::RecordHeaderObject( const InputObjectBase& rParent, BiffInputStream& rStrm ) :
+ mrStrm( rStrm )
+{
+ static const RecordHeaderConfigInfo saHeaderCfgInfo =
+ {
+ "REC",
+ "RECORD-NAMES",
+ "show-record-pos",
+ "show-record-size",
+ "show-record-id",
+ "show-record-name",
+ "show-record-body",
+ };
+ RecordHeaderBase< sal_uInt16, sal_uInt32 >::construct( rParent, saHeaderCfgInfo );
+ if( RecordHeaderBase< sal_uInt16, sal_uInt32 >::implIsValid() )
+ mbMergeContRec = cfg().getBoolOption( "merge-continue-record", true );
+}
+
+bool RecordHeaderObject::implReadHeader( sal_Int64& ornRecPos, sal_uInt16& ornRecId, sal_uInt32& ornRecSize )
+{
+ // previous record
+ switch( mrStrm.getRecId() )
+ {
+ case BIFF_ID_CHBEGIN:
+ out().incIndent();
+ break;
+ }
+
+ // start next record
+ bool bValidRec = mrStrm.startNextRecord();
+ ornRecPos = mrStrm.getCoreStreamPos() - 4;
+ ornRecId = mrStrm.getRecId();
+
+ // record specific settings
+ switch( ornRecId )
+ {
+ case BIFF_ID_CHEND:
+ out().decIndent();
+ break;
+ }
+
+ // special CONTINUE handling
+ mrStrm.resetRecord( mbMergeContRec );
+ if( mbMergeContRec ) switch( ornRecId )
+ {
+ case BIFF_ID_OBJ:
+ case BIFF_ID_TXO:
+ case BIFF_ID_EOF:
+ case BIFF_ID_CONT:
+ mrStrm.resetRecord( false );
+ break;
+ case BIFF_ID_MSODRAWINGGROUP:
+ case BIFF_ID_CHESCHERFORMAT:
+ mrStrm.resetRecord( true, ornRecId );
+ break;
+ }
+
+ ornRecSize = mrStrm.getRecSize();
+ return bValidRec;
+}
+
+// ============================================================================
+
+RecordStreamObject::~RecordStreamObject()
+{
+}
+
+void RecordStreamObject::construct( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm, BiffType eBiff )
+{
+ BiffObjectBase::construct( rParent, rOutFileName, xStrm, eBiff );
+ if( BiffObjectBase::implIsValid() )
+ {
+ mxHdrObj.reset( new RecordHeaderObject( *this, getBiffStream() ) );
+ mxFmlaObj.reset( new FormulaObject( *this ) );
+ mxDffObj.reset( new DffDumpObject( *this ) );
+ mxSimpleRecs = cfg().getNameList( "SIMPLE-RECORDS" );
+ }
+}
+
+bool RecordStreamObject::implIsValid() const
+{
+ return isValid( mxHdrObj ) && isValid( mxFmlaObj ) && isValid( mxDffObj ) && BiffObjectBase::implIsValid();
+}
+
+void RecordStreamObject::implDump()
+{
+ while( mxHdrObj->startNextRecord() )
+ {
+ if( mxHdrObj->isShowRecBody() )
+ {
+ IndentGuard aIndGuard( out() );
+ if( mxHdrObj->hasRecName() )
+ dumpRecordBody();
+ else
+ dumpRawBinary( mxHdrObj->getRecSize(), false );
+ if( !getBiffStream().isValid() )
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+ }
+ out().emptyLine();
+ }
+}
+
+void RecordStreamObject::implDumpRecord()
+{
+}
+
+sal_uInt16 RecordStreamObject::dumpRepeatedRecId()
+{
+ return dumpHex< sal_uInt16 >( "repeated-rec-id", mxHdrObj->getRecNames() );
+}
+
+void RecordStreamObject::dumpRecordBody()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ sal_uInt16 nRecId = rStrm.getRecId();
+ if( cfg().hasName( mxSimpleRecs, nRecId ) )
+ dumpSimpleRecord( cfg().getName( mxSimpleRecs, nRecId ) );
+ else
+ implDumpRecord();
+ // remaining undumped data
+ if( rStrm.getRecPos() == 0 )
+ dumpRawBinary( rStrm.getRecSize(), false );
+ else
+ dumpRemaining( rStrm.getRecLeft() );
+}
+
+void RecordStreamObject::dumpSimpleRecord( const OUString& rRecData )
+{
+ ItemFormat aItemFmt;
+ aItemFmt.parse( rRecData );
+ dumpItem( aItemFmt );
+}
+
+// ============================================================================
+
+WorkbookStreamObject::WorkbookStreamObject( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm )
+{
+ construct( rParent, rOutFileName, xStrm );
+}
+
+WorkbookStreamObject::~WorkbookStreamObject()
+{
+ if( WorkbookStreamObject::implIsValid() )
+ {
+ Config& rCfg = cfg();
+ rCfg.eraseNameList( "FONTNAMES" );
+ rCfg.eraseNameList( "FORMATS" );
+ }
+}
+
+void WorkbookStreamObject::construct( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm )
+{
+ if( xStrm.get() )
+ {
+ BiffType eBiff = BiffDetector::detectStreamBiffVersion( *xStrm );
+ RecordStreamObject::construct( rParent, rOutFileName, xStrm, eBiff );
+ if( RecordStreamObject::implIsValid() )
+ {
+ Config& rCfg = cfg();
+ mxColors = rCfg.getNameList( "COLORS" );
+ mxBorderStyles = rCfg.getNameList( "BORDERSTYLES" );
+ mxFillPatterns = rCfg.getNameList( "FILLPATTERNS" );
+ mxFontNames = rCfg.createNameList< ConstList >( "FONTNAMES" );
+ mxFontNames->setName( 0, createFontName( CREATE_OUSTRING( "Arial" ), 200, false, false ) );
+ mxFormats = rCfg.createNameList< ConstList >( "FORMATS" );
+ mxFormats->includeList( rCfg.getNameList( "BUILTIN-FORMATS" ) );
+ mnFormatIdx = 0;
+ mnPTRowFields = 0;
+ mnPTColFields = 0;
+ mnPTSxliIdx = 0;
+ mbHasCodePage = false;
+ }
+ }
+}
+
+void WorkbookStreamObject::implDumpRecord()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ sal_uInt16 nRecId = rStrm.getRecId();
+ sal_Size nRecSize = rStrm.getRecSize();
+ BiffType eBiff = getBiff();
+
+ switch( nRecId )
+ {
+ case BIFF2_ID_ARRAY:
+ case BIFF3_ID_ARRAY:
+ dumpRange( "array-range", false );
+ dumpHex< sal_uInt16, sal_uInt8 >( eBiff != BIFF2, "flags", "ARRAY-FLAGS" );
+ if( eBiff >= BIFF5 ) dumpUnused( 4 );
+ getFormulaDumper().dumpCellFormula();
+ break;
+
+ case BIFF2_ID_BLANK:
+ case BIFF3_ID_BLANK:
+ dumpCellHeader( nRecId == BIFF2_ID_BLANK );
+ break;
+
+ case BIFF2_ID_BOF:
+ case BIFF3_ID_BOF:
+ case BIFF4_ID_BOF:
+ case BIFF5_ID_BOF:
+ dumpHex< sal_uInt16 >( "bof-type", "BOF-BIFFTYPE" );
+ dumpHex< sal_uInt16 >( "sheet-type", "BOF-SHEETTYPE" );
+ if( nRecSize >= 6 ) dumpDec< sal_uInt16 >( "build-id" );
+ if( nRecSize >= 8 ) dumpDec< sal_uInt16 >( "build-year" );
+ if( nRecSize >= 12 ) dumpHex< sal_uInt32 >( "history-flags", "BOF-HISTORY-FLAGS" );
+ if( nRecSize >= 16 ) dumpDec< sal_uInt32 >( "lowest-ver" );
+ break;
+
+ case BIFF2_ID_BOOLERR:
+ case BIFF3_ID_BOOLERR:
+ dumpCellHeader( nRecId == BIFF2_ID_BOOLERR );
+ dumpBoolErr();
+ break;
+
+ case BIFF_ID_CFHEADER:
+ dumpDec< sal_uInt16 >( "rule-count" );
+ dumpBool< sal_uInt16 >( "need-update" );
+ dumpRange( "bounding-range" );
+ dumpRangeList();
+ break;
+
+ case BIFF_ID_CFRULE:
+ {
+ dumpDec< sal_uInt8 >( "type", "CFRULE-TYPE" );
+ dumpDec< sal_uInt8 >( "operator", "CFRULE-OPERATOR" );
+ sal_uInt16 nFmla1Size = dumpDec< sal_uInt16 >( "formula1-size" );
+ sal_uInt16 nFmla2Size = dumpDec< sal_uInt16 >( "formula2-size" );
+ sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "flags", "CFRULE-FLAGS" );
+ dumpUnused( 2 );
+ if( getFlag< sal_uInt32 >( nFlags, 0x04000000 ) )
+ {
+ writeEmptyItem( "font-block" );
+ IndentGuard aIndGuard( out() );
+ sal_uInt32 nRecPos = rStrm.getRecPos();
+ dumpUniString( "name", BIFF_STR_8BITLENGTH );
+ dumpUnused( nRecPos + 64 - rStrm.getRecPos() );
+ dumpDec< sal_Int32 >( "height", "CONV-TWIP-TO-PT" );
+ dumpHex< sal_uInt32 >( "flags", "CFRULE-FONTFLAGS" );
+ dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
+ dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
+ dumpDec< sal_uInt8 >( "underline", "FONT-UNDERLINE" );
+ dumpUnused( 3 ); // family/charset?
+ dumpDec< sal_Int32 >( "color", mxColors );
+ dumpUnused( 4 );
+ dumpHex< sal_uInt32 >( "used-flags", "CFRULE-FONTUSEDFLAGS" );
+ dumpDec< sal_uInt32 >( "escapement-used", "CFRULE-FONTUSED" );
+ dumpDec< sal_uInt32 >( "underline-used", "CFRULE-FONTUSED" );
+ dumpUnused( 18 );
+ }
+ if( getFlag< sal_uInt32 >( nFlags, 0x08000000 ) )
+ {
+ writeEmptyItem( "alignment-block" );
+ IndentGuard aIndGuard( out() );
+ dumpHex< sal_uInt8 >( "alignent", "CFRULE-ALIGNMENT" );
+ dumpHex< sal_uInt8 >( "rotation", "TEXTROTATION" );
+ dumpHex< sal_uInt16 >( "indent", "CFRULE-INDENT" );
+ dumpDec< sal_uInt16 >( "relative-indent" );
+ dumpUnknown( 2 );
+ }
+ if( getFlag< sal_uInt32 >( nFlags, 0x10000000 ) )
+ {
+ writeEmptyItem( "border-block" );
+ IndentGuard aIndGuard( out() );
+ dumpHex< sal_uInt16 >( "border-style", "XF-BORDERSTYLE" );
+ dumpHex< sal_uInt16 >( "border-color1", "XF-BORDERCOLOR1" );
+ dumpHex< sal_uInt32 >( "border-color2", "CFRULE-BORDERCOLOR2" );
+ }
+ if( getFlag< sal_uInt32 >( nFlags, 0x20000000 ) )
+ {
+ writeEmptyItem( "pattern-block" );
+ IndentGuard aIndGuard( out() );
+ dumpHex< sal_uInt32 >( "pattern", "CFRULE-FILLBLOCK" );
+ }
+ if( getFlag< sal_uInt32 >( nFlags, 0x40000000 ) )
+ {
+ writeEmptyItem( "protection-block" );
+ IndentGuard aIndGuard( out() );
+ dumpHex< sal_uInt16 >( "flags", "CFRULE-PROTECTION-FLAGS" );
+ }
+ if( nFmla1Size > 0 )
+ getFormulaDumper().dumpNameFormula( "formula1", nFmla1Size );
+ if( nFmla2Size > 0 )
+ getFormulaDumper().dumpNameFormula( "formula2", nFmla2Size );
+ }
+ break;
+
+ case BIFF_ID_CH3DDATAFORMAT:
+ dumpDec< sal_uInt8 >( "base", "CH3DDATAFORMAT-BASE" );
+ dumpDec< sal_uInt8 >( "top", "CH3DDATAFORMAT-TOP" );
+ break;
+
+ case BIFF_ID_CHAREAFORMAT:
+ dumpRgbColor( "fg-color-rgb" );
+ dumpRgbColor( "bg-color-rgb" );
+ dumpPatternIdx();
+ dumpHex< sal_uInt16 >( "flags", "CHAREAFORMAT-FLAGS" );
+ if( eBiff == BIFF8 ) dumpColorIdx( "fg-color-idx" );
+ if( eBiff == BIFF8 ) dumpColorIdx( "bg-color-idx" );
+ break;
+
+ case BIFF_ID_CHAXESSET:
+ dumpDec< sal_uInt16 >( "axesset-id", "CHAXESSET-ID" );
+ dumpRect< sal_Int32 >( "position", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
+ break;
+
+ case BIFF_ID_CHAXIS:
+ dumpDec< sal_uInt16 >( "axis-type", "CHAXIS-TYPE" );
+ if( eBiff <= BIFF4 )
+ dumpRect< sal_Int32 >( "position", "CONV-TWIP-TO-CM" );
+ else
+ dumpUnused( 16 );
+ break;
+
+ case BIFF_ID_CHBAR:
+ dumpDec< sal_Int16 >( "overlap", "CONV-PERCENT-NEG" );
+ dumpDec< sal_Int16 >( "gap", "CONV-PERCENT" );
+ dumpHex< sal_uInt16 >( "flags", "CHBAR-FLAGS" );
+ break;
+
+ case BIFF_ID_CHCHART:
+ dumpRect< sal_Int32 >( "chart-frame", "CONV-PT1616-TO-CM", FORMATTYPE_FIX );
+ break;
+
+ case BIFF_ID_CHCHART3D:
+ dumpDec< sal_uInt16 >( "rotation-angle", "CONV-DEG" );
+ dumpDec< sal_Int16 >( "elevation-angle", "CONV-DEG" );
+ dumpDec< sal_uInt16 >( "eye-distance" );
+ dumpDec< sal_uInt16 >( "relative-height", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "relative-depth", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "depth-gap", "CONV-PERCENT" );
+ dumpHex< sal_uInt16 >( "flags", "CHCHART3D-FLAGS" );
+ break;
+
+ case BIFF_ID_CHTYPEGROUP:
+ dumpUnused( 16 );
+ dumpHex< sal_uInt16 >( "flags", "CHTYPEGROUP-FLAGS" );
+ if( eBiff >= BIFF5 ) dumpDec< sal_uInt16 >( "group-idx" );
+ break;
+
+ case BIFF_ID_CHDATAFORMAT:
+ dumpDec< sal_Int16 >( "point-idx", "CHDATAFORMAT-POINTIDX" );
+ dumpDec< sal_Int16 >( "series-idx" );
+ if( eBiff >= BIFF5 ) dumpDec< sal_Int16 >( "format-idx", "CHDATAFORMAT-FORMATIDX" );
+ if( eBiff >= BIFF5 ) dumpHex< sal_uInt16 >( "flags", "CHDATAFORMAT-FLAGS" );
+ break;
+
+ case BIFF_ID_CHESCHERFORMAT:
+ getDffDumper().dump();
+ break;
+
+ case BIFF_ID_CHFRAME:
+ dumpDec< sal_uInt16 >( "format", "CHFRAME-FORMAT" );
+ dumpHex< sal_uInt16 >( "flags", "CHFRAME-FLAGS" );
+ break;
+
+ case BIFF_ID_CHFRAMEPOS:
+ dumpDec< sal_uInt16 >( "object-type", "CHFRAMEPOS-OBJTYPE" );
+ dumpDec< sal_uInt16 >( "size-mode", "CHFRAMEPOS-SIZEMODE" );
+ dumpRect< sal_Int32 >( "position", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
+ break;
+
+ case BIFF_ID_CHLABELRANGE:
+ dumpDec< sal_uInt16 >( "axis-crossing" );
+ dumpDec< sal_uInt16 >( "label-frequency" );
+ dumpDec< sal_uInt16 >( "tick-frequency" );
+ dumpHex< sal_uInt16 >( "flags", "CHLABELRANGE-FLAGS" );
+ break;
+
+ case BIFF_ID_CHLABELRANGE2:
+ dumpDec< sal_uInt16 >( "minimum-categ" );
+ dumpDec< sal_uInt16 >( "maximum-categ" );
+ dumpDec< sal_uInt16 >( "major-unit-value" );
+ dumpDec< sal_uInt16 >( "major-unit" );
+ dumpDec< sal_uInt16 >( "minor-unit-value" );
+ dumpDec< sal_uInt16 >( "minor-unit" );
+ dumpDec< sal_uInt16 >( "base-unit" );
+ dumpDec< sal_uInt16 >( "axis-crossing-date" );
+ dumpHex< sal_uInt16 >( "flags", "CHLABELRANGE2-FLAGS" );
+ break;
+
+ case BIFF_ID_CHLEGEND:
+ dumpRect< sal_Int32 >( "position", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
+ dumpDec< sal_uInt8 >( "docked-pos", "CHLEGEND-DOCKPOS" );
+ dumpDec< sal_uInt8 >( "spacing", "CHLEGEND-SPACING" );
+ dumpHex< sal_uInt16 >( "flags", "CHLEGEND-FLAGS" );
+ break;
+
+ case BIFF_ID_CHLINEFORMAT:
+ dumpRgbColor();
+ dumpDec< sal_uInt16 >( "line-type", "CHLINEFORMAT-LINETYPE" );
+ dumpDec< sal_Int16 >( "line-weight", "CHLINEFORMAT-LINEWEIGHT" );
+ dumpHex< sal_uInt16 >( "flags", "CHLINEFORMAT-FLAGS" );
+ if( eBiff == BIFF8 ) dumpColorIdx();
+ break;
+
+ case BIFF_ID_CHMARKERFORMAT:
+ dumpRgbColor( "border-color-rgb" );
+ dumpRgbColor( "fill-color-rgb" );
+ dumpDec< sal_uInt16 >( "marker-type", "CHMARKERFORMAT-TYPE" );
+ dumpHex< sal_uInt16 >( "flags", "CHMARKERFORMAT-FLAGS" );
+ if( eBiff == BIFF8 ) dumpColorIdx( "border-color-idx" );
+ if( eBiff == BIFF8 ) dumpColorIdx( "fill-color-idx" );
+ if( eBiff == BIFF8 ) dumpDec< sal_Int32 >( "marker-size", "CONV-TWIP-TO-PT" );
+ break;
+
+ case BIFF_ID_CHOBJECTLINK:
+ dumpDec< sal_uInt16 >( "link-target", "CHOBJECTLINK-TARGET" );
+ dumpDec< sal_Int16 >( "series-idx" );
+ dumpDec< sal_Int16 >( "point-idx", "CHOBJECTLINK-POINT" );
+ break;
+
+ case BIFF_ID_CHPICFORMAT:
+ dumpDec< sal_uInt16 >( "bitmap-mode", "CHPICFORMAT-BITMAP-MODE" );
+ dumpDec< sal_uInt16 >( "image-format", "CHPICFORMAT-IMAGE-FORMAT" );
+ dumpHex< sal_uInt16 >( "flags", "CHPICFORMAT-FLAGS" );
+ dumpDec< double >( "scaling-factor" );
+ break;
+
+ case BIFF_ID_CHPIE:
+ dumpDec< sal_uInt16 >( "angle", "CONV-DEG" );
+ if( eBiff >= BIFF5 ) dumpDec< sal_uInt16 >( "hole-size" );
+ if( eBiff >= BIFF8 ) dumpHex< sal_uInt16 >( "flags", "CHPIE-FLAGS" );
+ break;
+
+ case BIFF_ID_CHPLOTGROWTH:
+ dumpFix< sal_Int32 >( "horizontal-growth" );
+ dumpFix< sal_Int32 >( "vertical-growth" );
+ break;
+
+ case BIFF_ID_CHPROPERTIES:
+ dumpHex< sal_uInt16 >( "flags", "CHPROPERTIES-FLAGS" );
+ dumpDec< sal_uInt8 >( "empty-cells", "CHPROPERTIES-EMPTYCELLS" );
+ break;
+
+ case BIFF_ID_CHSCATTER:
+ if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "bubble-size", "CONV-PERCENT" );
+ if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "size-type", "CHSCATTER-SIZETYPE" );
+ if( eBiff == BIFF8 ) dumpHex< sal_uInt16 >( "flags", "CHSCATTER-FLAGS" );
+ break;
+
+ case BIFF_ID_CHSERERRORBAR:
+ dumpDec< sal_uInt8 >( "type", "CHSERERRORBAR-TYPE" );
+ dumpDec< sal_uInt8 >( "source", "CHSERERRORBAR-SOURCE" );
+ dumpBool< sal_uInt8 >( "draw-t-shape" );
+ dumpBool< sal_uInt8 >( "draw-line" );
+ dumpDec< double >( "value" );
+ dumpDec< sal_uInt16 >( "custom-count" );
+ break;
+
+ case BIFF_ID_CHSERIES:
+ dumpDec< sal_uInt16 >( "categories-type", "CHSERIES-TYPE" );
+ dumpDec< sal_uInt16 >( "values-type", "CHSERIES-TYPE" );
+ dumpDec< sal_uInt16 >( "categories-count" );
+ dumpDec< sal_uInt16 >( "values-count" );
+ if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "bubbles-type", "CHSERIES-TYPE" );
+ if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "bubbles-count" );
+ break;
+
+ case BIFF_ID_CHSERTRENDLINE:
+ switch( dumpDec< sal_uInt8 >( "type", "CHSERTRENDLINE-TYPE" ) )
+ {
+ case 0: dumpDec< sal_uInt8 >( "order" ); break;
+ case 4: dumpDec< sal_uInt8 >( "average-period" ); break;
+ default: dumpUnused( 1 );
+ }
+ dumpDec< double >( "intercept" );
+ dumpBool< sal_uInt8 >( "show-equation" );
+ dumpBool< sal_uInt8 >( "show-r-sqrare" );
+ dumpDec< double >( "forecast-forward" );
+ dumpDec< double >( "forecast-backward" );
+ break;
+
+ case BIFF_ID_CHSOURCELINK:
+ dumpDec< sal_uInt8 >( "link-target", "CHSOURCELINK-TARGET" );
+ dumpDec< sal_uInt8 >( "link-type", "CHSOURCELINK-TYPE" );
+ dumpHex< sal_uInt16 >( "flags", "CHSOURCELINK-FLAGS" );
+ dumpFormatIdx();
+ getFormulaDumper().dumpNameFormula();
+ break;
+
+ case BIFF_ID_CHSTRING:
+ dumpDec< sal_uInt16 >( "text-type", "CHSTRING-TYPE" );
+ dumpString( "text", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_CHTEXT:
+ dumpDec< sal_uInt8 >( "horizontal-align", "CHTEXT-HORALIGN" );
+ dumpDec< sal_uInt8 >( "vertical-align", "CHTEXT-VERALIGN" );
+ dumpDec< sal_uInt16 >( "fill-mode", "CHTEXT-FILLMODE" );
+ dumpRgbColor();
+ dumpRect< sal_Int32 >( "position", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
+ dumpHex< sal_uInt16 >( "flags", "CHTEXT-FLAGS" );
+ if( eBiff == BIFF8 ) dumpColorIdx();
+ if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "placement", "CHTEXT-PLACEMENT" );
+ if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "rotation", "TEXTROTATION" );
+ break;
+
+ case BIFF_ID_CHTICK:
+ dumpDec< sal_uInt8 >( "major-ticks", "CHTICK-TYPE" );
+ dumpDec< sal_uInt8 >( "minor-ticks", "CHTICK-TYPE" );
+ dumpDec< sal_uInt8 >( "label-position", "CHTICK-LABELPOS" );
+ dumpDec< sal_uInt8 >( "fill-mode", "CHTEXT-FILLMODE" );
+ dumpRgbColor( "label-color-rgb" );
+ dumpUnused( 16 );
+ dumpHex< sal_uInt16 >( "flags", "CHTICK-FLAGS" );
+ if( eBiff == BIFF8 ) dumpColorIdx( "label-color-idx" );
+ if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "label-rotation", "TEXTROTATION" );
+ break;
+
+ case BIFF_ID_CHUNITPROPERTIES:
+ dumpRepeatedRecId();
+ dumpUnused( 2 );
+ dumpDec< sal_Int16 >( "preset", "CHUNITPROPERTIES-PRESET" );
+ dumpDec< double >( "unit" );
+ dumpHex< sal_uInt16 >( "flags", "CHUNITPROPERTIES-FLAGS" );
+ break;
+
+ case BIFF_ID_CHVALUERANGE:
+ dumpDec< double >( "minimum" );
+ dumpDec< double >( "maximum" );
+ dumpDec< double >( "major-inc" );
+ dumpDec< double >( "minor-inc" );
+ dumpDec< double >( "axis-crossing" );
+ dumpHex< sal_uInt16 >( "flags", "CHVALUERANGE-FLAGS" );
+ break;
+
+ case BIFF_ID_CHWRAPPEDRECORD:
+ dumpRepeatedRecId();
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_CODENAME:
+ dumpUniString( "codename" );
+ break;
+
+ case BIFF_ID_CODEPAGE:
+ getBiffData().setTextEncoding( dumpCodePage() );
+ mbHasCodePage = true;
+ break;
+
+ case BIFF_ID_COLINFO:
+ dumpColRange();
+ dumpDec< sal_uInt16 >( "col-width", "CONV-COLWIDTH" );
+ dumpXfIdx( "xf-idx" );
+ dumpHex< sal_uInt16 >( "flags", "COLINFO-FLAGS" );
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_COLUMNDEFAULT:
+ out().resetItemIndex();
+ for( sal_Int32 nCol = 0, nCount = dumpColRange(); nCol < nCount; ++nCol )
+ dumpXfIdx( "#xf-idx", true );
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_COLWIDTH:
+ dumpColRange( 0, false );
+ dumpDec< sal_uInt16 >( "col-width", "CONV-COLWIDTH" );
+ break;
+
+ case BIFF_ID_CRN:
+ {
+ sal_Int32 nCol2 = dumpColIndex( "last-col-idx", false );
+ sal_Int32 nCol1 = dumpColIndex( "first-col-idx", false );
+ sal_Int32 nRow = dumpRowIndex( "row-idx" );
+ TableGuard aTabGuard( out(), 14, 17 );
+ for( Address aPos( nCol1, nRow ); rStrm.isValid() && (aPos.mnCol <= nCol2); ++aPos.mnCol )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeAddressItem( "pos", aPos );
+ dumpConstValue();
+ }
+ }
+ break;
+
+ case BIFF_ID_DCONNAME:
+ dumpString( "source-name", BIFF_STR_8BITLENGTH );
+ dumpString( "source-link", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_DCONREF:
+ dumpRange( "source-range", false );
+ dumpString( "source-link", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF2_ID_DATATABLE:
+ dumpRange( "table-range", false );
+ dumpBoolean( "recalc-always" );
+ dumpBoolean( "row-table" );
+ dumpAddress( "ref1" );
+ break;
+
+ case BIFF3_ID_DATATABLE:
+ dumpRange( "table-range", false );
+ dumpHex< sal_uInt16 >( "flags", "DATATABLE-FLAGS" );
+ dumpAddress( "ref1" );
+ dumpAddress( "ref2" );
+ break;
+
+ case BIFF2_ID_DATATABLE2:
+ dumpRange( "table-range", false );
+ dumpBoolean( "recalc-always" );
+ dumpUnused( 1 );
+ dumpAddress( "ref1" );
+ dumpAddress( "ref2" );
+ break;
+
+ case BIFF_ID_DATAVALIDATION:
+ {
+ dumpHex< sal_uInt32 >( "flags", "DATAVALIDATION-FLAGS" );
+ dumpUniString( "input-title" );
+ dumpUniString( "error-title" );
+ dumpUniString( "input-message" );
+ dumpUniString( "error-message" );
+ sal_uInt16 nFmla1Size = getFormulaDumper().dumpFormulaSize( "formula1-size" );
+ dumpUnused( 2 );
+ if( nFmla1Size > 0 )
+ getFormulaDumper().dumpNameFormula( "formula1", nFmla1Size );
+ sal_uInt16 nFmla2Size = getFormulaDumper().dumpFormulaSize( "formula2-size" );
+ dumpUnused( 2 );
+ if( nFmla2Size > 0 )
+ getFormulaDumper().dumpNameFormula( "formula2", nFmla2Size );
+ dumpRangeList();
+ }
+ break;
+
+ case BIFF_ID_DATAVALIDATIONS:
+ dumpHex< sal_uInt16 >( "flags", "DATAVALIDATIONS-FLAGS" );
+ dumpDec< sal_Int32 >( "input-box-pos-x" );
+ dumpDec< sal_Int32 >( "input-box-pos-y" );
+ dumpDec< sal_Int32 >( "dropdown-object-id" );
+ dumpDec< sal_Int32 >( "dval-entry-count" );
+ break;
+
+ case BIFF2_ID_DEFINEDNAME:
+ case BIFF3_ID_DEFINEDNAME:
+ {
+ dumpHex< sal_uInt16, sal_uInt8 >( eBiff != BIFF2, "flags", "DEFINEDNAME-FLAGS" );
+ if( eBiff == BIFF2 ) dumpDec< sal_uInt8 >( "macro-type", "DEFINEDNAME-MACROTYPE-BIFF2" );
+ dumpHex< sal_uInt8 >( "keyboard-shortcut" );
+ sal_uInt8 nNameLen = dumpDec< sal_uInt8 >( "name-len" );
+ sal_uInt16 nFmlaSize = getFormulaDumper().dumpFormulaSize();
+ rtl_TextEncoding eTextEnc = getBiffData().getTextEncoding();
+ if( eBiff >= BIFF5 )
+ {
+ bool bBiff8 = eBiff == BIFF8;
+ if( bBiff8 ) dumpUnused( 2 ); else dumpDec< sal_uInt16 >( "externsheet-idx", "DEFINEDNAME-SHEETIDX" );
+ dumpDec< sal_uInt16 >( "sheet-idx", "DEFINEDNAME-SHEETIDX" );
+ sal_uInt8 nMenuLen = dumpDec< sal_uInt8 >( "menu-text-len" );
+ sal_uInt8 nDescrLen = dumpDec< sal_uInt8 >( "description-text-len" );
+ sal_uInt8 nHelpLen = dumpDec< sal_uInt8 >( "help-text-len" );
+ sal_uInt8 nStatusLen = dumpDec< sal_uInt8 >( "statusbar-text-len" );
+ writeStringItem( "name", bBiff8 ? rStrm.readUniString( nNameLen ) : rStrm.readCharArray( nNameLen, eTextEnc ) );
+ getFormulaDumper().dumpNameFormula( 0, nFmlaSize );
+ if( nMenuLen > 0 ) writeStringItem( "menu-text", bBiff8 ? rStrm.readUniString( nMenuLen ) : rStrm.readCharArray( nMenuLen, eTextEnc ) );
+ if( nDescrLen > 0 ) writeStringItem( "description-text", bBiff8 ? rStrm.readUniString( nDescrLen ) : rStrm.readCharArray( nDescrLen, eTextEnc ) );
+ if( nHelpLen > 0 ) writeStringItem( "help-text", bBiff8 ? rStrm.readUniString( nHelpLen ) : rStrm.readCharArray( nHelpLen, eTextEnc ) );
+ if( nStatusLen > 0 ) writeStringItem( "statusbar-text", bBiff8 ? rStrm.readUniString( nStatusLen ) : rStrm.readCharArray( nStatusLen, eTextEnc ) );
+ }
+ else
+ {
+ writeStringItem( "name", rStrm.readCharArray( nNameLen, eTextEnc ) );
+ getFormulaDumper().dumpNameFormula( 0, nFmlaSize );
+ if( eBiff == BIFF2 ) getFormulaDumper().dumpFormulaSize();
+ }
+ }
+ break;
+
+ case BIFF3_ID_DEFROWHEIGHT:
+ dumpHex< sal_uInt16 >( "flags", "DEFROWHEIGHT-FLAGS" );
+ dumpDec< sal_uInt16 >( "row-height", "CONV-TWIP-TO-PT" );
+ break;
+
+ case BIFF2_ID_DIMENSION:
+ case BIFF3_ID_DIMENSION:
+ dumpRange( "used-area", true, (nRecId == BIFF3_ID_DIMENSION) && (eBiff == BIFF8) );
+ if( nRecId == BIFF3_ID_DIMENSION ) dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_EXTERNALBOOK:
+ {
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "sheet-count" );
+ if( rStrm.getRecLeft() == 2 )
+ dumpHex< sal_uInt16 >( "special-key", "EXTERNALBOOK-KEY" );
+ else
+ {
+ dumpString( "workbook-url" );
+ out().resetItemIndex();
+ for( sal_uInt16 nSheet = 0; rStrm.isValid() && (nSheet < nCount); ++nSheet )
+ dumpString( "#sheet-name" );
+ }
+ }
+ break;
+
+ case BIFF2_ID_EXTERNALNAME:
+ case BIFF3_ID_EXTERNALNAME:
+ {
+ sal_uInt16 nFlags = (eBiff >= BIFF3) ? dumpHex< sal_uInt16 >( "flags", "EXTERNALNAME-FLAGS" ) : 0;
+ if( eBiff >= BIFF5 )
+ {
+ if( getFlag< sal_uInt16 >( nFlags, 0x0010 ) )
+ {
+ dumpHex< sal_uInt32 >( "storage-id" );
+ }
+ else
+ {
+ dumpDec< sal_uInt16 >( "externsheet-idx" );
+ dumpUnused( 2 );
+ }
+ }
+ OUString aName = dumpString( "name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
+ if( (aName.getLength() > 0) && (aName[ 0 ] == 1) && (rStrm.getRecLeft() >= 2) )
+ getFormulaDumper().dumpNameFormula();
+ }
+ break;
+
+ case BIFF_ID_EXTERNSHEET:
+ if( eBiff == BIFF8 )
+ {
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "ref-count" );
+ TableGuard aTabGuard( out(), 10, 17, 24 );
+ out().resetItemIndex();
+ for( sal_uInt16 nRefId = 0; rStrm.isValid() && (nRefId < nCount); ++nRefId )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( "#ref" );
+ dumpDec< sal_uInt16 >( "extbook-idx" );
+ dumpDec< sal_Int16 >( "first-sheet", "EXTERNSHEET-IDX" );
+ dumpDec< sal_Int16 >( "last-sheet", "EXTERNSHEET-IDX" );
+ }
+ }
+ else
+ {
+ OStringBuffer aUrl( rStrm.readByteString( false ) );
+ if( (aUrl.getLength() > 0) && (aUrl[ 0 ] == '\x03') )
+ aUrl.append( static_cast< sal_Char >( rStrm.readuInt8() ) );
+ writeStringItem( "encoded-url", OStringToOUString( aUrl.makeStringAndClear(), getBiffData().getTextEncoding() ) );
+ }
+ break;
+
+ case BIFF2_ID_FONT:
+ case BIFF3_ID_FONT:
+ dumpFontRec();
+ break;
+
+ case BIFF2_ID_FORMAT:
+ case BIFF4_ID_FORMAT:
+ dumpFormatRec();
+ break;
+
+ case BIFF2_ID_FORMULA:
+ case BIFF3_ID_FORMULA:
+ case BIFF4_ID_FORMULA:
+ dumpCellHeader( eBiff == BIFF2 );
+ dumpFormulaResult();
+ dumpHex< sal_uInt16, sal_uInt8 >( eBiff != BIFF2, "flags", "FORMULA-FLAGS" );
+ if( eBiff >= BIFF5 ) dumpUnused( 4 );
+ getFormulaDumper().dumpCellFormula();
+ break;
+
+ case BIFF_ID_FOOTER:
+ if( rStrm.getRecLeft() > 0 )
+ dumpString( "footer", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_HEADER:
+ if( rStrm.getRecLeft() > 0 )
+ dumpString( "header", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_HYPERLINK:
+ dumpRange();
+ if( cfg().getStringOption( dumpGuid( "guid" ), OUString() ).equalsAscii( "StdHlink" ) )
+ {
+ dumpUnknown( 4 );
+ sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "flags", "HYPERLINK-FLAGS" );
+ if( getFlag( nFlags, BIFF_HYPERLINK_DISPLAY ) )
+ dumpOleString( "display", true );
+ if( getFlag( nFlags, BIFF_HYPERLINK_FRAME ) )
+ dumpOleString( "target-frame", true );
+ if( getFlag( nFlags, BIFF_HYPERLINK_TARGET ) )
+ {
+ if( getFlag( nFlags, BIFF_HYPERLINK_UNC ) )
+ {
+ dumpOleString( "unc-path", true );
+ }
+ else
+ {
+ OUString aGuid = cfg().getStringOption( dumpGuid( "content-type" ), OUString() );
+ if( aGuid.equalsAscii( "FileMoniker" ) )
+ {
+ dumpDec< sal_Int16 >( "up-level" );
+ dumpOleString( "dos-name", false );
+ dumpUnknown( 24 );
+ if( dumpDec< sal_Int32 >( "total-bytes" ) > 0 )
+ {
+ sal_Int32 nBytes = dumpDec< sal_Int32 >( "filename-bytes" );
+ dumpUnknown( 2 );
+ dumpOleString( "filename", nBytes / 2, true );
+ }
+ }
+ else if( aGuid.equalsAscii( "URLMoniker" ) )
+ {
+ sal_Int32 nBytes = dumpDec< sal_Int32 >( "url-bytes" );
+ dumpOleString( "url", nBytes / 2, true );
+ }
+ }
+ }
+ if( getFlag( nFlags, BIFF_HYPERLINK_LOC ) )
+ dumpOleString( "location", true );
+ }
+ break;
+
+ case BIFF2_ID_INTEGER:
+ dumpCellHeader( true );
+ dumpDec< sal_uInt16 >( "value" );
+ break;
+
+ case BIFF2_ID_LABEL:
+ case BIFF3_ID_LABEL:
+ {
+ bool bBiff2 = nRecId == BIFF2_ID_LABEL;
+ sal_uInt16 nXfIdx = dumpCellHeader( bBiff2 );
+ rtl_TextEncoding eOldTextEnc = getBiffData().getTextEncoding();
+ getBiffData().setTextEncoding( getBiffData().getXfEncoding( nXfIdx ) );
+ dumpString( "value", bBiff2 ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT );
+ getBiffData().setTextEncoding( eOldTextEnc );
+ }
+ break;
+
+ case BIFF_ID_LABELRANGES:
+ dumpRangeList( "row-ranges" );
+ dumpRangeList( "col-ranges" );
+ break;
+
+ case BIFF_ID_LABELSST:
+ dumpCellHeader();
+ dumpDec< sal_Int32 >( "sst-idx" );
+ break;
+
+ case BIFF_ID_MSODRAWING:
+ case BIFF_ID_MSODRAWINGGROUP:
+ case BIFF_ID_MSODRAWINGSEL:
+ getDffDumper().dump();
+ break;
+
+ case BIFF_ID_MULTBLANK:
+ {
+ Address aPos = dumpAddress();
+ {
+ TableGuard aTabGuard( out(), 12 );
+ for( ; rStrm.getRecLeft() >= 4; ++aPos.mnCol )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeAddressItem( "pos", aPos );
+ dumpXfIdx();
+ }
+ }
+ dumpColIndex( "last-col-idx" );
+ }
+ break;
+
+ case BIFF_ID_MULTRK:
+ {
+ Address aPos = dumpAddress();
+ {
+ TableGuard aTabGuard( out(), 12, 12 );
+ for( ; rStrm.getRecLeft() >= 8; ++aPos.mnCol )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeAddressItem( "pos", aPos );
+ dumpXfIdx();
+ dumpRk( "value" );
+ }
+ }
+ dumpColIndex( "last-col-idx" );
+ }
+ break;
+
+ case BIFF2_ID_NUMBER:
+ case BIFF3_ID_NUMBER:
+ dumpCellHeader( nRecId == BIFF2_ID_NUMBER );
+ dumpDec< double >( "value" );
+ break;
+
+ case BIFF_ID_OBJ:
+ dumpObjRec();
+ break;
+
+ case BIFF_ID_PAGESETUP:
+ dumpDec< sal_uInt16 >( "paper-size", "PAGESETUP-PAPERSIZE" );
+ dumpDec< sal_uInt16 >( "scaling", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "first-page" );
+ dumpDec< sal_uInt16 >( "scale-to-width", "PAGESETUP-SCALETOPAGES" );
+ dumpDec< sal_uInt16 >( "scale-to-height", "PAGESETUP-SCALETOPAGES" );
+ dumpHex< sal_uInt16 >( "flags", "PAGESETUP-FLAGS" );
+ if( eBiff >= BIFF5 )
+ {
+ dumpDec< sal_uInt16 >( "horizontal-res", "PAGESETUP-DPI" );
+ dumpDec< sal_uInt16 >( "vertical-res", "PAGESETUP-DPI" );
+ dumpDec< double >( "header-margin", "CONV-INCH-TO-CM" );
+ dumpDec< double >( "footer-margin", "CONV-INCH-TO-CM" );
+ dumpDec< sal_uInt16 >( "copies" );
+ }
+ break;
+
+ case BIFF_ID_PANE:
+ dumpDec< sal_uInt16 >( "x-pos", "CONV-TWIP-TO-CM" );
+ dumpDec< sal_uInt16 >( "y-pos", "CONV-TWIP-TO-CM" );
+ dumpAddress( "first-visible-cell" );
+ dumpDec< sal_uInt8 >( "active-pane", "PANE-ID" );
+ break;
+
+ case BIFF_ID_PHONETICPR:
+ dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
+ dumpHex< sal_uInt16 >( "flags", "PHONETICPR-FLAGS" );
+ dumpRangeList( "show-phonetic" );
+ break;
+
+ case BIFF_ID_PROJEXTSHEET:
+ dumpDec< sal_uInt8 >( "sheet-type", "PROJEXTSHEET-TYPE" );
+ dumpUnused( 1 );
+ dumpByteString( "sheet-link", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_RK:
+ dumpCellHeader();
+ dumpRk( "value" );
+ break;
+
+ case BIFF2_ID_ROW:
+ {
+ dumpRowIndex();
+ dumpColIndex( "first-used-col-idx" );
+ dumpColIndex( "first-free-col-idx" );
+ dumpHex< sal_uInt16 >( "height", "ROW-HEIGHT" );
+ dumpUnused( 2 );
+ bool bHasDefXf = dumpBool< sal_uInt8 >( "custom-format" );
+ dumpDec< sal_uInt16 >( "cell-offset" );
+ if( bHasDefXf ) dumpXfIdx( "custom-format", true );
+ if( bHasDefXf ) dumpXfIdx( "custom-xf-idx", false );
+ }
+ break;
+
+ case BIFF3_ID_ROW:
+ dumpRowIndex();
+ dumpColIndex( "first-used-col-idx" );
+ dumpColIndex( "first-free-col-idx" );
+ dumpHex< sal_uInt16 >( "height", "ROW-HEIGHT" );
+ dumpUnused( (eBiff <= BIFF4) ? 2 : 4 );
+ if( eBiff <= BIFF4 ) dumpDec< sal_uInt16 >( "cell-offset" );
+ dumpHex< sal_uInt32 >( "flags", "ROW-FLAGS" );
+ break;
+
+ case BIFF_ID_RSTRING:
+ {
+ sal_uInt16 nXfIdx = dumpCellHeader();
+ rtl_TextEncoding eOldTextEnc = getBiffData().getTextEncoding();
+ getBiffData().setTextEncoding( getBiffData().getXfEncoding( nXfIdx ) );
+ dumpString( "value" );
+ getBiffData().setTextEncoding( eOldTextEnc );
+ BinFontPortionList aPortions;
+ aPortions.importPortions( rStrm, eBiff == BIFF8 );
+ writeFontPortions( aPortions );
+ }
+ break;
+
+ case BIFF_ID_SCL:
+ {
+ sal_uInt16 nNum = dumpDec< sal_uInt16 >( "numerator" );
+ sal_uInt16 nDen = dumpDec< sal_uInt16 >( "denominator" );
+ if( nDen > 0 ) writeDecItem( "current-zoom", static_cast< sal_uInt16 >( nNum * 100 / nDen ), "CONV-PERCENT" );
+ }
+ break;
+
+ case BIFF_ID_SCREENTIP:
+ dumpRepeatedRecId();
+ dumpRange();
+ dumpNullString( "tooltip", true );
+ break;
+
+ case BIFF_ID_SELECTION:
+ dumpDec< sal_uInt8 >( "pane", "PANE-ID" );
+ dumpAddress( "active-cell" );
+ dumpDec< sal_uInt16 >( "list-idx" );
+ dumpRangeList( "selection", false );
+ break;
+
+ case BIFF_ID_SHAREDFMLA:
+ dumpRange( "formula-range", false );
+ dumpUnused( 1 );
+ dumpDec< sal_uInt8 >( "cell-count" );
+ getFormulaDumper().dumpCellFormula();
+ break;
+
+ case BIFF_ID_SHEET:
+ if( eBiff >= BIFF5 ) dumpHex< sal_uInt32 >( "sheet-stream-pos", "CONV-DEC" );
+ if( eBiff >= BIFF5 ) dumpDec< sal_uInt8 >( "sheet-state", "SHEET-STATE" );
+ if( eBiff >= BIFF5 ) dumpDec< sal_uInt8 >( "sheet-type", "SHEET-TYPE" );
+ dumpString( "sheet-name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_SHEETHEADER:
+ dumpHex< sal_uInt32 >( "substream-size", "CONV-DEC" );
+ dumpByteString( "sheet-name", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_SHEETPROTECTION:
+ dumpRepeatedRecId();
+ dumpUnused( 17 );
+ dumpHex< sal_uInt16 >( "allowed-flags", "SHEETPROTECTION-FLAGS" );
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_SST:
+ dumpDec< sal_uInt32 >( "string-cell-count" );
+ dumpDec< sal_uInt32 >( "sst-size" );
+ out().resetItemIndex();
+ while( rStrm.isValid() && (rStrm.getRecLeft() >= 3) )
+ dumpUniString( "#entry" );
+ break;
+
+ case BIFF2_ID_STRING:
+ case BIFF3_ID_STRING:
+ dumpString( "result", ((nRecId == BIFF2_ID_STRING) && (eBiff <= BIFF4)) ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT );
+ break;
+
+ case BIFF_ID_STYLE:
+ {
+ 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" );
+ }
+ else
+ dumpString( "style-name", BIFF_STR_8BITLENGTH );
+ }
+ break;
+
+ case BIFF_ID_SXDI:
+ {
+ dumpDec< sal_uInt16 >( "field-idx" );
+ dumpDec< sal_uInt16 >( "function", "SXDI-FUNC" );
+ dumpDec< sal_uInt16 >( "data-format", "SXDI-FORMAT" );
+ dumpDec< sal_uInt16 >( "format-basefield-idx" );
+ dumpDec< sal_uInt16 >( "format-baseitem-idx", "SXDI-BASEITEM" );
+ dumpFormatIdx();
+ sal_uInt16 nNameLen = dumpDec< sal_uInt16 >( "item-name-len", "SX-NAMELEN" );
+ if( nNameLen != BIFF_PT_NOSTRING )
+ writeStringItem( "item-name", rStrm.readUniString( nNameLen ) );
+ }
+ break;
+
+ case BIFF_ID_SXEXT:
+ if( eBiff == BIFF8 )
+ {
+ dumpHex< sal_uInt16 >( "flags", "SXEXT-FLAGS" );
+ dumpDec< sal_uInt16 >( "param-string-count" );
+ dumpDec< sal_uInt16 >( "sql-statement-string-count" );
+ dumpDec< sal_uInt16 >( "webquery-postmethod-string-count" );
+ dumpDec< sal_uInt16 >( "server-pagefields-string-count" );
+ dumpDec< sal_uInt16 >( "odbc-connection-string-count" );
+ }
+ break;
+
+ case BIFF_ID_SXIVD:
+ out().resetItemIndex();
+ for( sal_Size nIdx = 0, nCount = rStrm.getRecLeft() / 2; nIdx < nCount; ++nIdx )
+ dumpDec< sal_uInt16 >( "#field-idx" );
+ break;
+
+ case BIFF_ID_SXLI:
+ if( mnPTSxliIdx < 2 )
+ {
+ sal_uInt16 nCount = (mnPTSxliIdx == 0) ? mnPTRowFields : mnPTColFields;
+ sal_Size nLineSize = 8 + 2 * nCount;
+ out().resetItemIndex();
+ while( rStrm.getRecLeft() >= nLineSize )
+ {
+ writeEmptyItem( "#line-data" );
+ IndentGuard aIndGuard( out() );
+ MultiItemsGuard aMultiGuard( out() );
+ dumpDec< sal_uInt16 >( "ident-count" );
+ dumpDec< sal_uInt16 >( "item-type", "SXLI-ITEMTYPE" );
+ dumpDec< sal_uInt16 >( "used-count" );
+ dumpHex< sal_uInt16 >( "flags", "SXLI-FLAGS" );
+ OUStringBuffer aItemList;
+ for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
+ StringHelper::appendToken( aItemList, in().readValue< sal_uInt16 >() );
+ writeInfoItem( "item-idxs", aItemList.makeStringAndClear() );
+ }
+ ++mnPTSxliIdx;
+ }
+ break;
+
+ case BIFF_ID_SXSTRING:
+ dumpString( "value" );
+ break;
+
+ case BIFF_ID_SXVD:
+ {
+ dumpDec< sal_uInt16 >( "axis-type", "SXVD-AXISTYPE" );
+ dumpDec< sal_uInt16 >( "subtotal-count" );
+ dumpHex< sal_uInt16 >( "subtotals", "SXVD-SUBTOTALS" );
+ dumpDec< sal_uInt16 >( "item-count" );
+ sal_uInt16 nNameLen = dumpDec< sal_uInt16 >( "field-name-len", "SX-NAMELEN" );
+ if( nNameLen != BIFF_PT_NOSTRING )
+ writeStringItem( "field-name", rStrm.readUniString( nNameLen ) );
+ }
+ break;
+
+ case BIFF_ID_SXVDEX:
+ dumpHex< sal_uInt32 >( "flags", "SXVDEX-FLAGS" );
+ dumpDec< sal_uInt16 >( "autosort-basefield-idx" );
+ dumpDec< sal_uInt16 >( "autoshow-basefield-idx" );
+ dumpFormatIdx();
+ break;
+
+ case BIFF_ID_SXVI:
+ {
+ dumpDec< sal_uInt16 >( "item-type", "SXVI-ITEMTYPE" );
+ dumpHex< sal_uInt16 >( "flags", "SXVI-FLAGS" );
+ dumpDec< sal_uInt16 >( "cache-idx" );
+ sal_uInt16 nNameLen = dumpDec< sal_uInt16 >( "item-name-len", "SX-NAMELEN" );
+ if( nNameLen != BIFF_PT_NOSTRING )
+ writeStringItem( "item-name", rStrm.readUniString( nNameLen ) );
+ }
+ break;
+
+ case BIFF_ID_SXVIEW:
+ {
+ dumpRange( "output-range" );
+ dumpRowIndex( "first-header-row-idx" );
+ dumpAddress( "first-data-pos" );
+ dumpDec< sal_uInt16 >( "cache-idx" );
+ dumpUnused( 2 );
+ dumpDec< sal_uInt16 >( "default-data-axis", "SXVD-AXISTYPE" );
+ dumpDec< sal_Int16 >( "default-data-pos" );
+ dumpDec< sal_uInt16 >( "field-count" );
+ mnPTRowFields = dumpDec< sal_uInt16 >( "row-field-count" );
+ mnPTColFields = dumpDec< sal_uInt16 >( "column-field-count" );
+ dumpDec< sal_uInt16 >( "page-field-count" );
+ dumpDec< sal_uInt16 >( "data-field-count" );
+ dumpDec< sal_uInt16 >( "data-row-count" );
+ dumpDec< sal_uInt16 >( "data-column-count" );
+ dumpHex< sal_uInt16 >( "flags", "SXVIEW-FLAGS" );
+ dumpDec< sal_uInt16 >( "auto-format-idx" );
+ sal_uInt16 nTabNameLen = dumpDec< sal_uInt16 >( "table-name-len" );
+ sal_uInt16 nDataNameLen = dumpDec< sal_uInt16 >( "data-name-len" );
+ writeStringItem( "table-name", rStrm.readUniString( nTabNameLen ) );
+ writeStringItem( "data-name", rStrm.readUniString( nDataNameLen ) );
+ mnPTSxliIdx = 0;
+ }
+ break;
+
+ case BIFF_ID_WINDOW1:
+ dumpDec< sal_uInt16 >( "window-x", "CONV-TWIP-TO-CM" );
+ dumpDec< sal_uInt16 >( "window-y", "CONV-TWIP-TO-CM" );
+ dumpDec< sal_uInt16 >( "window-width", "CONV-TWIP-TO-CM" );
+ dumpDec< sal_uInt16 >( "window-height", "CONV-TWIP-TO-CM" );
+ if( eBiff <= BIFF4 )
+ {
+ dumpBool< sal_uInt8 >( "hidden" );
+ }
+ else
+ {
+ dumpHex< sal_uInt16 >( "flags", "WINDOW1-FLAGS" );
+ dumpDec< sal_uInt16 >( "active-tab" );
+ dumpDec< sal_uInt16 >( "first-visible-tab" );
+ dumpDec< sal_uInt16 >( "selected-tabs" );
+ dumpDec< sal_uInt16 >( "tabbar-ratio", "WINDOW1-TABBARRATIO" );
+ }
+ break;
+
+ case BIFF2_ID_WINDOW2:
+ dumpBool< sal_uInt8 >( "show-formulas" );
+ dumpBool< sal_uInt8 >( "show-gridlines" );
+ dumpBool< sal_uInt8 >( "show-headings" );
+ dumpBool< sal_uInt8 >( "frozen-panes" );
+ dumpBool< sal_uInt8 >( "show-zeros" );
+ dumpAddress( "first-visible-cell" );
+ dumpBool< sal_uInt8 >( "auto-grid-color" );
+ dumpRgbColor( "grid-color-rgb" );
+ break;
+
+ case BIFF3_ID_WINDOW2:
+ dumpHex< sal_uInt16 >( "flags", "WINDOW2-FLAGS" );
+ dumpAddress( "first-visible-cell" );
+ if( eBiff == BIFF8 )
+ {
+ dumpColorIdx( "grid-color-idx" );
+ dumpUnused( 2 );
+ if( rStrm.getRecLeft() >= 8 )
+ {
+ dumpDec< sal_uInt16 >( "pagebreak-zoom", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "normal-zoom", "CONV-PERCENT" );
+ dumpUnused( 4 );
+ }
+ }
+ else
+ dumpRgbColor( "grid-color-rgb" );
+ break;
+
+ case BIFF_ID_XCT:
+ dumpDec< sal_uInt16 >( "crn-count" );
+ if( eBiff == BIFF8 ) dumpDec< sal_Int16 >( "sheet-idx" );
+ break;
+
+ case BIFF2_ID_XF:
+ case BIFF3_ID_XF:
+ case BIFF4_ID_XF:
+ case BIFF5_ID_XF:
+ dumpXfRec();
+ break;
+ }
+}
+
+OUString WorkbookStreamObject::createFontName( const OUString& rName, sal_uInt16 nHeight, bool bBold, bool bItalic ) const
+{
+ OUStringBuffer aName( rName );
+ StringHelper::enclose( aName, OOX_DUMP_STRQUOTE );
+ StringHelper::appendToken( aName, cfg().getName( "CONV-TWIP-TO-PT", nHeight ), ',' );
+ if( bBold )
+ StringHelper::appendToken( aName, CREATE_OUSTRING( "bold" ), ',' );
+ if( bItalic )
+ StringHelper::appendToken( aName, CREATE_OUSTRING( "italic" ), ',' );
+ return aName.makeStringAndClear();
+}
+
+sal_uInt16 WorkbookStreamObject::dumpPatternIdx( const sal_Char* pcName, bool b16Bit )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, pcName ? pcName : "fill-pattern", mxFillPatterns );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpColorIdx( const sal_Char* pcName, bool b16Bit )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, pcName ? pcName : "color-idx", mxColors );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpFontIdx( const sal_Char* pcName, bool b16Bit )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, pcName ? pcName : "font-idx", "FONTNAMES" );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpFormatIdx( const sal_Char* pcName )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( getBiff() >= BIFF5, pcName ? pcName : "fmt-idx", "FORMATS" );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpXfIdx( const sal_Char* pcName, bool bBiff2Style )
+{
+ if( !pcName ) pcName = "xf-idx";
+ sal_uInt16 nXfIdx = 0;
+ if( bBiff2Style )
+ {
+ dumpHex< sal_uInt8 >( pcName, "CELL-XFINDEX" );
+ dumpHex< sal_uInt8 >( "fmt-font-idx", "CELL-XFFORMAT" );
+ dumpHex< sal_uInt8 >( "style", "CELL-XFSTYLE" );
+ }
+ else
+ nXfIdx = dumpDec< sal_uInt16 >( pcName );
+ return nXfIdx;
+}
+
+sal_uInt16 WorkbookStreamObject::dumpCellHeader( bool bBiff2Style )
+{
+ dumpAddress();
+ return dumpXfIdx( 0, bBiff2Style );
+}
+
+void WorkbookStreamObject::dumpBoolErr()
+{
+ MultiItemsGuard aMultiGuard( out() );
+ sal_uInt8 nValue = dumpHex< sal_uInt8 >( "value" );
+ bool bErrCode = dumpBool< sal_uInt8 >( "is-errorcode" );
+ if( bErrCode )
+ writeErrorCodeItem( "errorcode", nValue );
+ else
+ writeBooleanItem( "boolean", nValue );
+}
+
+void WorkbookStreamObject::dumpFontRec()
+{
+ sal_uInt16 nFontId = getBiffData().getFontCount();
+ out().resetItemIndex( nFontId );
+ writeEmptyItem( "#font" );
+ sal_uInt16 nHeight = dumpDec< sal_uInt16 >( "height", "CONV-TWIP-TO-PT" );
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "FONT-FLAGS" );
+ bool bBold = getFlag( nFlags, BIFF_FONTFLAG_BOLD );
+ bool bItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
+ rtl_TextEncoding eFontEnc = RTL_TEXTENCODING_DONTKNOW;
+ if( getBiff() >= BIFF3 )
+ dumpColorIdx();
+ if( getBiff() >= BIFF5 )
+ {
+ bBold = dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" ) > 450;
+ dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
+ dumpDec< sal_uInt8 >( "underline", "FONT-UNDERLINE" );
+ dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
+ sal_uInt8 nCharSet = dumpDec< sal_uInt8 >( "charset", "CHARSET" );
+ eFontEnc = rtl_getTextEncodingFromWindowsCharset( nCharSet );
+ dumpUnused( 1 );
+ }
+ OUString aName = dumpString( "name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
+
+ // append font data to vector
+ mxFontNames->setName( nFontId, createFontName( aName, nHeight, bBold, bItalic ) );
+
+ // store font encoding
+ getBiffData().appendFontEncoding( eFontEnc );
+
+ // set font encoding as default text encoding in case of missing CODEPAGE record
+ if( !mbHasCodePage && (nFontId == 0) )
+ getBiffData().setTextEncoding( eFontEnc );
+}
+
+void WorkbookStreamObject::dumpFormatRec()
+{
+ sal_uInt16 nFormatIdx = 0;
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ nFormatIdx = mnFormatIdx++;
+ out().resetItemIndex( nFormatIdx );
+ writeEmptyItem( "#fmt" );
+ break;
+ case BIFF4:
+ nFormatIdx = mnFormatIdx++;
+ out().resetItemIndex( nFormatIdx );
+ writeEmptyItem( "#fmt" );
+ dumpUnused( 2 );
+ break;
+ case BIFF5:
+ case BIFF8:
+ getBiffStream() >> nFormatIdx;
+ out().resetItemIndex( nFormatIdx );
+ writeEmptyItem( "#fmt" );
+ writeDecItem( "fmt-idx", nFormatIdx );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+ OUString aFormat = dumpString( "format", BIFF_STR_8BITLENGTH );
+ mxFormats->setName( nFormatIdx, aFormat );
+}
+
+void WorkbookStreamObject::dumpXfRec()
+{
+ sal_uInt16 nXfId = getBiffData().getXfCount();
+ out().resetItemIndex( nXfId );
+ writeEmptyItem( "#xf" );
+ sal_uInt16 nFontId = dumpFontIdx( 0, getBiff() >= BIFF5 );
+ switch( getBiff() )
+ {
+ case BIFF2:
+ dumpUnused( 1 );
+ dumpHex< sal_uInt8 >( "type-flags", "XF-TYPEFLAGS" );
+ dumpHex< sal_uInt8 >( "style-flags", "XF-STYLEFLAGS" );
+ break;
+ case BIFF3:
+ dumpFormatIdx();
+ dumpHex< sal_uInt8 >( "type-flags", "XF-TYPEFLAGS" );
+ dumpHex< sal_uInt8 >( "used-attributes", "XF-USEDATTRIBS-FLAGS" );
+ dumpHex< sal_uInt16 >( "alignment", "XF-ALIGNMENT" );
+ dumpHex< sal_uInt16 >( "fill-style", "XF-FILL" );
+ dumpHex< sal_uInt32 >( "border-style", "XF-BORDER" );
+ break;
+ case BIFF4:
+ dumpFormatIdx();
+ dumpHex< sal_uInt16 >( "type-flags", "XF-TYPEFLAGS" );
+ dumpHex< sal_uInt8 >( "alignment", "XF-ALIGNMENT" );
+ dumpHex< sal_uInt8 >( "used-attributes", "XF-USEDATTRIBS-FLAGS" );
+ dumpHex< sal_uInt16 >( "fill-style", "XF-FILL" );
+ dumpHex< sal_uInt32 >( "border-style", "XF-BORDER" );
+ break;
+ case BIFF5:
+ dumpFormatIdx();
+ dumpHex< sal_uInt16 >( "type-flags", "XF-TYPEFLAGS" );
+ dumpHex< sal_uInt8 >( "alignment", "XF-ALIGNMENT" );
+ dumpHex< sal_uInt8 >( "orientation", "XF-ORIENTATTRIBS" );
+ dumpHex< sal_uInt32 >( "fill-style", "XF-FILL" );
+ dumpHex< sal_uInt32 >( "border-style", "XF-BORDER" );
+ break;
+ case BIFF8:
+ dumpFormatIdx();
+ dumpHex< sal_uInt16 >( "type-flags", "XF-TYPEFLAGS" );
+ dumpHex< sal_uInt8 >( "alignment", "XF-ALIGNMENT" );
+ dumpDec< sal_uInt8 >( "rotation", "TEXTROTATION" );
+ dumpHex< sal_uInt8 >( "text-flags", "XF-TEXTFLAGS" );
+ dumpHex< sal_uInt8 >( "used-attributes", "XF-USEDATTRIBS-FLAGS" );
+ dumpHex< sal_uInt16 >( "border-style", "XF-BORDERSTYLE" );
+ dumpHex< sal_uInt16 >( "border-color1", "XF-BORDERCOLOR1" );
+ dumpHex< sal_uInt32 >( "border-color2", "XF-BORDERCOLOR2" );
+ dumpHex< sal_uInt16 >( "fill-color", "XF-FILLCOLOR" );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+ getBiffData().appendXfFontId( nFontId );
+}
+
+void WorkbookStreamObject::dumpObjRec()
+{
+ switch( getBiff() )
+ {
+ case BIFF5: dumpObjRecBiff5(); break;
+ case BIFF8: dumpObjRecBiff8(); break;
+ default:;
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecBiff5()
+{
+ dumpDec< sal_uInt32 >( "obj-count" );
+ sal_uInt16 nObjType = dumpDec< sal_uInt16 >( "obj-type", "OBJ-TYPE" );
+ dumpDec< sal_uInt16 >( "obj-id" );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-FLAGS" );
+ getDffDumper().dumpDffClientRect();
+ dumpDec< sal_uInt16 >( "macro-len" );
+ dumpUnused( 6 );
+ switch( nObjType )
+ {
+ case BIFF_OBJCMO_LINE:
+ dumpColorIdx( "line-color-idx", false );
+ dumpDec< sal_uInt8 >( "line-type", "OBJ-LINETYPE" );
+ dumpDec< sal_uInt8 >( "line-weight", "OBJ-LINEWEIGHT" );
+ dumpHex< sal_uInt8 >( "line-flags", "OBJ-FLAGS-AUTO" );
+ dumpHex< sal_uInt16 >( "line-end", "OBJ-LINEENDS" );
+ dumpDec< sal_uInt8 >( "line-direction", "OBJ-LINEDIR" );
+ dumpUnused( 1 );
+ break;
+ case BIFF_OBJCMO_RECTANGLE:
+ dumpColorIdx( "back-color-idx", false );
+ dumpColorIdx( "patt-color-idx", false );
+ dumpPatternIdx( 0, false );
+ dumpHex< sal_uInt8 >( "area-flags", "OBJ-FLAGS-AUTO" );
+ dumpColorIdx( "line-color-idx", false );
+ dumpDec< sal_uInt8 >( "line-type", "OBJ-LINETYPE" );
+ dumpDec< sal_uInt8 >( "line-weight", "OBJ-LINEWEIGHT" );
+ dumpHex< sal_uInt8 >( "line-flags", "OBJ-FLAGS-AUTO" );
+ dumpHex< sal_uInt16 >( "frame-style", "OBJ-FRAMESTYLE-FLAGS" );
+ break;
+ case BIFF_OBJCMO_CHART:
+ dumpColorIdx( "back-color-idx", false );
+ dumpColorIdx( "patt-color-idx", false );
+ dumpPatternIdx( 0, false );
+ dumpHex< sal_uInt8 >( "area-flags", "OBJ-FLAGS-AUTO" );
+ dumpColorIdx( "line-color-idx", false );
+ dumpDec< sal_uInt8 >( "line-type", "OBJ-LINETYPE" );
+ dumpDec< sal_uInt8 >( "line-weight", "OBJ-LINEWEIGHT" );
+ dumpHex< sal_uInt8 >( "line-flags", "OBJ-FLAGS-AUTO" );
+ dumpHex< sal_uInt16 >( "frame-style", "OBJ-FRAMESTYLE-FLAGS" );
+ dumpHex< sal_uInt16 >( "chart-flags", "OBJ-CHART-FLAGS" );
+ dumpUnused( 16 );
+ break;
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecBiff8()
+{
+ Output& rOut = out();
+ BiffInputStream& rStrm = getBiffStream();
+ NameListRef xRecNames = cfg().getNameList( "OBJ-RECNAMES" );
+ bool bLinked = false;
+ bool bControl = false;
+ bool bCtlsStrm = false;
+ bool bLoop = true;
+ while( bLoop && (rStrm.getRecLeft() >= 4) )
+ {
+ rOut.emptyLine();
+ sal_uInt16 nSubRecId, nSubRecSize;
+ {
+ MultiItemsGuard aMultiGuard( rOut );
+ writeEmptyItem( "OBJREC" );
+ writeHexItem( "pos", rStrm.getRecPos() );
+ rStrm >> nSubRecId >> nSubRecSize;
+ writeHexItem( "size", nSubRecSize );
+ writeHexItem( "id", nSubRecId, xRecNames );
+ }
+
+ sal_uInt32 nSubRecStart = rStrm.getRecPos();
+ // sometimes the last subrecord has an invalid length
+ sal_uInt32 nRealRecSize = ::std::min< sal_uInt32 >( nSubRecSize, rStrm.getRecLeft() );
+ sal_uInt32 nSubRecEnd = nSubRecStart + nRealRecSize;
+
+ IndentGuard aIndGuard( rOut );
+ switch( nSubRecId )
+ {
+ case BIFF_ID_OBJPIOGRBIT:
+ {
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "OBJPIOGRBIT-FLAGS" );
+ bLinked = getFlag( nFlags, BIFF_OBJPIO_LINKED );
+ bControl = getFlag( nFlags, BIFF_OBJPIO_CONTROL );
+ bCtlsStrm = getFlag( nFlags, BIFF_OBJPIO_CTLSSTREAM );
+ }
+ break;
+ case BIFF_ID_OBJPICTFMLA:
+ {
+ sal_uInt16 nLinkDataSize = dumpDec< sal_uInt16 >( "link-data-size" );
+ sal_uInt32 nLinkDataEnd = rStrm.getRecPos() + nLinkDataSize;
+ {
+ IndentGuard aIndGuard2( rOut );
+ sal_uInt16 nFmlaSize = getFormulaDumper().dumpFormulaSize();
+ dumpUnused( 4 );
+ getFormulaDumper().dumpNameFormula( "link", nFmlaSize );
+ if( dumpDec< sal_uInt8 >( "has-class-name", "OBJPICTFMLA-HASCLASSNAME" ) == 3 )
+ {
+ dumpUniString( "class-name", BIFF_STR_SMARTFLAGS );
+ if( ((rStrm.getRecPos() - nSubRecStart) & 1) != 0 )
+ dumpHex< sal_uInt8 >( "padding" );
+ }
+ }
+ if( rStrm.getRecPos() != nLinkDataEnd )
+ writeEmptyItem( OOX_DUMP_ERRASCII( "link-data-size" ) );
+ if( rStrm.getRecPos() < nLinkDataEnd )
+ dumpRemaining( nLinkDataEnd - rStrm.getRecPos() );
+ rStrm.seek( nLinkDataEnd );
+ if( nLinkDataEnd + 4 <= nSubRecEnd )
+ {
+ if( bControl && bCtlsStrm )
+ {
+ sal_uInt32 nPos = dumpHex< sal_uInt32 >( "ctls-stream-pos", "CONV-DEC" );
+ sal_uInt32 nSize = dumpHex< sal_uInt32 >( "ctls-stream-size", "CONV-DEC" );
+ IndentGuard aIndGuard2( rOut );
+ rOut.emptyLine();
+ dumpFormControl( nPos, nSize );
+ rOut.emptyLine();
+ }
+ else
+ dumpHex< sal_uInt32 >( "ole-storage-id" );
+ }
+ if( bControl && (rStrm.getRecPos() + 8 <= nSubRecEnd) )
+ {
+ sal_uInt32 nClassIdSize = dumpDec< sal_uInt32 >( "class-id-size" );
+ if( nClassIdSize > 0 )
+ {
+ IndentGuard aIndGuard2( rOut );
+ sal_uInt32 nClassIdEnd = rStrm.getRecPos() + nClassIdSize;
+ dumpUnicodeArray( "class-id", static_cast< sal_Int32 >( nClassIdSize / 2 ) );
+ rStrm.seek( nClassIdEnd );
+ }
+ sal_uInt16 nCellLinkSize = dumpDec< sal_uInt16 >( "cell-link-size" );
+ if( nCellLinkSize > 0 )
+ {
+ IndentGuard aIndGuard2( rOut );
+ sal_uInt32 nCellLinkEnd = rStrm.getRecPos() + nCellLinkSize;
+ sal_uInt16 nFmlaSize = getFormulaDumper().dumpFormulaSize( "cell-link-fmla-size" );
+ dumpUnused( 4 );
+ getFormulaDumper().dumpNameFormula( "cell-link", nFmlaSize );
+ rStrm.seek( nCellLinkEnd );
+ }
+ sal_uInt16 nSrcRangeSize = dumpDec< sal_uInt16 >( "source-range-size" );
+ if( nSrcRangeSize > 0 )
+ {
+ IndentGuard aIndGuard2( rOut );
+ sal_uInt32 nSrcRangeEnd = rStrm.getRecPos() + nSrcRangeSize;
+ sal_uInt16 nFmlaSize = getFormulaDumper().dumpFormulaSize( "source-range-fmla-size" );
+ dumpUnused( 4 );
+ getFormulaDumper().dumpNameFormula( "source-range", nFmlaSize );
+ rStrm.seek( nSrcRangeEnd );
+ }
+ }
+ }
+ break;
+ case BIFF_ID_OBJCMO:
+ dumpDec< sal_uInt16 >( "type", "OBJCMO-TYPE" );
+ dumpDec< sal_uInt16 >( "id" );
+ dumpHex< sal_uInt16 >( "flags", "OBJCMO-FLAGS" );
+ dumpUnused( 12 );
+ break;
+ }
+ // remaining undumped data
+ if( rStrm.getRecPos() == nSubRecStart )
+ dumpRawBinary( nRealRecSize, false );
+ else
+ dumpRemaining( nSubRecEnd - rStrm.getRecPos() );
+ rStrm.seek( nSubRecStart + nRealRecSize );
+ }
+}
+
+void WorkbookStreamObject::dumpFormControl( sal_uInt32 nStrmPos, sal_uInt32 nStrmSize )
+{
+ writeHexItem( "stream-pos", nStrmPos, "CONV-DEC" );
+ writeHexItem( "stream-size", nStrmSize, "CONV-DEC" );
+}
+
+// ============================================================================
+
+PivotCacheStreamObject::PivotCacheStreamObject( const ObjectBase& rParent, const ::rtl::OUString& rOutFileName, BinaryInputStreamRef xStrm )
+{
+ RecordStreamObject::construct( rParent, rOutFileName, xStrm, BIFF8 );
+}
+
+void PivotCacheStreamObject::implDumpRecord()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ sal_uInt16 nRecId = rStrm.getRecId();
+
+ switch( nRecId )
+ {
+ case BIFF_ID_SXDATETIME:
+ {
+ sal_uInt16 nYear, nMonth;
+ sal_uInt8 nDay, nHour, nMin, nSec;
+ rStrm >> nYear >> nMonth >> nDay >> nHour >> nMin >> nSec;
+ DateTime aDateTime( 0, nSec, nMin, nHour, nDay, nMonth, nYear );
+ writeDateTimeItem( "value", aDateTime );
+ }
+ break;
+
+ case BIFF_ID_SXDB:
+ dumpDec< sal_uInt32 >( "source-records" );
+ dumpHex< sal_uInt16 >( "stream-id" );
+ dumpHex< sal_uInt16 >( "flags", "SXDB-FLAGS" );
+ dumpDec< sal_uInt16 >( "block-records" );
+ dumpDec< sal_uInt16 >( "standard-field-count" );
+ dumpDec< sal_uInt16 >( "total-field-count" );
+ dumpUnused( 2 );
+ dumpDec< sal_uInt16 >( "database-type", "SXDB-TYPE" );
+ dumpUniString( "user-name" );
+ break;
+
+ case BIFF_ID_SXFIELD:
+ dumpHex< sal_uInt16 >( "flags", "SXFIELD-FLAGS" );
+ dumpDec< sal_uInt16 >( "group-child-field" );
+ dumpDec< sal_uInt16 >( "group-base-field" );
+ dumpDec< sal_uInt16 >( "visible-items" );
+ dumpDec< sal_uInt16 >( "group-items" );
+ dumpDec< sal_uInt16 >( "base-items" );
+ dumpDec< sal_uInt16 >( "original-items" );
+ if( rStrm.getRecLeft() >= 3 )
+ dumpUniString( "item-name" );
+ break;
+
+ case BIFF_ID_SXSTRING:
+ dumpUniString( "value" );
+ break;
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+RootStorageObject::RootStorageObject( const DumperBase& rParent )
+{
+ RootStorageObjectBase::construct( rParent );
+}
+
+void RootStorageObject::implDumpStream( BinaryInputStreamRef xStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSystemFileName )
+{
+ if( rStrgPath.getLength() == 0 )
+ {
+ if( (rStrmName == CREATE_OUSTRING( "Book" )) || (rStrmName == CREATE_OUSTRING( "Workbook" )) )
+ WorkbookStreamObject( *this, rSystemFileName, xStrm ).dump();
+ else if( (rStrmName == CREATE_OUSTRING( "\005SummaryInformation" )) || (rStrmName == CREATE_OUSTRING( "\005DocumentSummaryInformation" )) )
+ OlePropertyStreamObject( *this, rSystemFileName, xStrm ).dump();
+ else
+ InputStreamObject( *this, rSystemFileName, xStrm ).dump();
+ }
+ else if( rStrgPath == CREATE_OUSTRING( "_SX_DB_CUR" ) )
+ {
+ PivotCacheStreamObject( *this, rSystemFileName, xStrm ).dump();
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+Dumper::Dumper( const FilterBase& rFilter )
+{
+ ConfigRef xCfg( new Config( "OOO_BIFFDUMPER" ) );
+ DumperBase::construct( rFilter, xCfg );
+}
+
+void Dumper::implDump()
+{
+ WorkbookStreamObject( *this, getFilter().getFileUrl() + CREATE_OUSTRING( ".dump" ), getRootStream() ).dump();
+ RootStorageObject( *this ).dump();
+}
+
+// ============================================================================
+
+} // namespace biff
+} // namespace dump
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/dump/biffdumperconfig.dat b/oox/source/dump/biffdumperconfig.dat
new file mode 100644
index 000000000000..7fbbf7cbcab7
--- /dev/null
+++ b/oox/source/dump/biffdumperconfig.dat
@@ -0,0 +1,1782 @@
+
+# dumper settings ============================================================
+
+# Path to base configuration data, relative to this file.
+include-config-file=dumperconfig.dat
+
+# BIFF record settings -------------------------------------------------------
+
+# Show total stream position of the record (default=on).
+# 0=off, 1=on
+show-record-pos=0
+
+# Show total record size in bytes (including CONTINUE records, if enabled,
+# see 'merge-continue-record' option) (default=on).
+# 0=off, 1=on
+show-record-size=1
+
+# Show record identifier (default=on).
+# 0=off, 1=on
+show-record-id=1
+
+# Show record name, if known (default=on).
+# 0=off, 1=on
+show-record-name=1
+
+# Show record contents (default=on).
+# 0=off, 1=on
+show-record-body=1
+
+# Merge CONTINUE records with leading record (default=on).
+# 0=off - show CONTINUE records separately (hex dump)
+# 1=on - show contents of leading record together with following CONTINUE
+merge-continue-record=1
+
+# name maps ==================================================================
+#
+# List of constants
+# -----------------
+# Defines names for specific values.
+#
+# constlist = <LISTNAME>
+# default = <constname> (default=?err:no-name)
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <value>[,<value>...]
+# quote-names = 0|1|false|true (default=0)
+# <value> = <constname>
+# end
+#
+# List of multiple contants per line
+# ----------------------------------
+# Defines names for contiguous ranges of values.
+#
+# multilist = <LISTNAME>
+# default = <constname> (default=?err:no-name)
+# ignore-empty = 0|1|false|true (default=1)
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <value>[,<value>...]
+# <firstvalue> = <constname>[,<constname>...]
+# end
+#
+# List of multiple contants, shortened format
+# -------------------------------------------
+# Defines names for a contiguous range of values. The entire list definition
+# is given in a single text line.
+#
+# shortlist = <LISTNAME>,<firstvalue>,<constname>[,<constname>...]
+#
+# List of flags
+# -------------
+# Defines names for single bits in a bit field.
+#
+# flagslist = <LISTNAME>
+# ignore = <bitfield> (default=0)
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <bitfield>[,<bitfield>...]
+# <bitmask> = [!]<constname>
+# end
+#
+# List of flags and values in a bitfield
+# --------------------------------------
+# Defines names for single bits and for embedded values in a bit field.
+#
+# combilist = <LISTNAME>
+# ignore = <bitfield> (default=0)
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <bitmask>[,<bitmask>...]
+# <bitmask> = [!]<constname>
+# <bitfield> = <datatype>,<dataformat>,<constname>[,<LISTNAME>]
+# end
+#
+# Unit converter
+# --------------
+# Converts values and appends a unit name.
+#
+# unitconverter = <LISTNAME>,[/]<factor>,<unitname>
+
+# common ---------------------------------------------------------------------
+
+unitconverter=CONV-PERCENT-NEG,-1,%
+unitconverter=CONV-COLWIDTH,/256,chars
+
+shortlist=BIFF,0,biff2,biff3,biff4,biff5,biff8
+
+constlist=ERRORCODES
+ 0x00=#NULL!
+ 0x07=#DIV/0!
+ 0x0F=#VALUE!
+ 0x17=#REF!
+ 0x1D=#NAME?
+ 0x24=#NUM!
+ 0x2A=#N/A
+end
+
+shortlist=EGA-COLORS,0,ega-black,ega-white,ega-red,ega-green,ega-blue,ega-yellow,ega-magenta,ega-cyan
+
+constlist=COLORS-BIFF2
+ include=EGA-COLORS
+ default=
+ 24=sys-window-text
+ 25=sys-window-bg
+ 0x7FFF=sys-window-text
+end
+
+constlist=COLORS-BIFF5
+ include=EGA-COLORS
+ default=
+ 64=sys-window-text
+ 65=sys-window-bg
+ 67=sys-button-face
+ 77=sys-window-text-chart
+ 78=sys-window-bg-chart
+ 79=auto-border-chart
+ 80=sys-tooltip-bg
+ 81=sys-tooltip-text
+ 0x7FFF=sys-window-text
+end
+
+shortlist=BORDERSTYLES-BIFF3,0,none,thin,medium,dash,dot,thick,double,hair
+
+multilist=BORDERSTYLES-BIFF8
+ include=BORDERSTYLES-BIFF3
+ 8=medium-dash,thin-dash-dot,medium-dash-dot,thin-dash-dot-dot,medium-dash-dot-dot,slant-dash-dot
+end
+
+multilist=FILLPATTERNS-BIFF3
+ 0=no-fill,solid-fill,50%-grey,75%-grey,25%-grey
+ 5=hor-stripe,ver-stripe,rev-diag-stripe,diag-stripe,diag-crosshatch
+ 10=thick-diag-crosshatch,thin-hor-stripe,thin-ver-stripe,thin-rev-diag-stripe,thin-diag-stripe
+ 15=thin-hor-crosshatch,thin-diag-crosshatch,12.5%-grey,6.25%-grey
+end
+
+shortlist=TEXTORIENTATION,0,horizontal,stacked,90°-ccw,90°-cw
+
+constlist=TEXTROTATION-BIFF8
+ default=
+ 255=stacked
+end
+
+multilist=BUILTIN-FORMATS
+ quote-names=1
+ 0=General,0,0.00,'#,##0','#,##0.00'
+ 5='"$"#,##0_);\("$"#,##0\)','"$"#,##0_);[Red]\("$"#,##0\)','"$"#,##0.00_);\("$"#,##0.00\)','"$"#,##0.00_);[Red]\("$"#,##0.00\)',0%
+ 10=0.00%,0.00E+00,# ?/?,# ??/??,M/D/YYYY
+ 15=D-MMM-YY,D-MMM,MMM-YY,h:mm AM/PM,h:mm:ss AM/PM
+ 20=h:mm,h:mm:ss,M/D/YYYY h:mm,General,General
+ 25=General,General,M/D/YYYY,M/D/YYYY,M/D/YYYY
+ 30=M/D/YYYY,M/D/YYYY,h:mm:ss,h:mm:ss,h:mm:ss
+ 35=h:mm:ss,M/D/YYYY,'#,##0_);(#,##0)','#,##0_);[Red](#,##0)','#,##0.00_);(#,##0.00)'
+ 40='#,##0.00_);[Red](#,##0.00)'
+ 41='_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)'
+ 42='_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)'
+ 43='_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)'
+ 44='_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'
+ 45=mm:ss,[h]:mm:ss,mm:ss.0,##0.0E+0,@
+ 50=M/D/YYYY,M/D/YYYY,M/D/YYYY,M/D/YYYY,M/D/YYYY
+ 55=M/D/YYYY,M/D/YYYY,M/D/YYYY,M/D/YYYY,0
+ 60=0.00,'#,##0','#,##0.00','$#,##0_);($#,##0)','$#,##0_);[Red]($#,##0)'
+ 65='$#,##0.00_);($#,##0.00)','$#,##0.00_);[Red]($#,##0.00)',0%,0.00%,# ?/?
+ 70=# ??/??,M/D/YYYY,M/D/YYYY,D-MMM-YY,D-MMM
+ 75=MMM-YY,h:mm,h:mm:ss,M/D/YYYY h:mm,mm:ss
+ 80=[h]:mm:ss,mm:ss.0
+end
+
+constlist=CONSTVALUE-TYPE
+ 0=empty
+ 1=number
+ 2=string
+ 4=boolean
+ 16=error
+end
+
+# formulas -------------------------------------------------------------------
+
+multilist=BASETOKENS-BIFF2
+ 0x00=,tExp,tTbl,tAdd,tSub,tMul,tDiv,tPower
+ 0x08=tConcat,tLT,tLE,tEQ,tGE,tGT,tNE,tIsect
+ 0x10=tList,tRange,tUplus,tUminus,tPercent,tParen,tMissArg,tStr
+ 0x18=,tAttr,tSheet,tEndSheet,tErr,tBool,tInt,tNum
+end
+
+constlist=BASETOKENS-BIFF5
+ include=BASETOKENS-BIFF2
+ exclude=0x1A,0x1B
+end
+
+constlist=BASETOKENS-BIFF8
+ include=BASETOKENS-BIFF5
+ 0x18=tNlr
+end
+
+constlist=TOKENCLASSES
+ 0x20=R
+ 0x40=V
+ 0x60=A
+end
+
+multilist=CLASSTOKENS-BIFF2
+ 0x00=tArray,tFunc,tFuncVar,tName,tRef,tArea,tMemArea,tMemErr
+ 0x08=tMemNoMem,tMemFunc,tRefErr,tAreaErr,tRefN,tAreaN,tMemAreaN,tMemNoMemN
+ 0x18=tFuncCE
+end
+
+constlist=CLASSTOKENS-BIFF4
+ include=CLASSTOKENS-BIFF2
+ exclude=0x18
+end
+
+multilist=CLASSTOKENS-BIFF5
+ include=CLASSTOKENS-BIFF4
+ 0x19=tNameX,tRef3d,tArea3d,tRefErr3d,tAreaErr3d
+end
+
+combilist=FUNCID
+ 0x7FFF=uint16,dec,func-id
+ 0x8000=command
+end
+
+combilist=PARAMCOUNT-CMD
+ 0x7F=uint8,dec,count
+ 0x80=prompt
+end
+
+combilist=REFRELFLAGS
+ 0x3FFF=uint16,dec,value
+ 0x4000=col-rel
+ 0x8000=row-rel
+end
+
+multilist=NLRTYPES
+ 0x00=,tNlrErr,tNlrRowR,tNlrColR,,,tNlrRowV,tNlrColV
+ 0x08=,,tNlrRange,tNlrSRange,tNlrSRowR,tNlrSColR,tNlrSRowV,tNlrSColV
+ 0x10=tNlrRangeErr,,,,,,,
+ 0x18=,,,,,tNlrSxName,,
+end
+
+combilist=NLRADDFLAGS
+ 0x3FFFFFFF=uint32,dec,count
+ 0x80000000=rel
+end
+
+flagslist=ATTRTYPES
+ 0x01=volatile
+ 0x02=if
+ 0x04=choose
+ 0x08=skip
+ 0x10=sum
+ 0x20=assign
+ 0x40=space
+end
+
+shortlist=ATTRSPACETYPES,0,space-before-token,cr-before-token,space-before-open,cr-before-open,space-before-close,cr-before-close,leading-space
+
+# record names ---------------------------------------------------------------
+
+multilist=RECORD-NAMES-BIFF2
+ # worksheet records
+ 0x0000=DIMENSION,BLANK,INTEGER,NUMBER,LABEL,BOOLERR,FORMULA,STRING
+ 0x0008=ROW,BOF,EOF,INDEX,CALCCOUNT,CALCMODE,PRECISION,REFMODE
+ 0x0010=DELTA,ITERATION,PROTECT,PASSWORD,HEADER,FOOTER,EXTERNCOUNT,EXTERNSHEET
+ 0x0018=DEFINEDNAME,WINDOWPROTECT,VERTICALPAGEBREAKS,HORIZONTALPAGEBREAKS,NOTE,SELECTION,FORMAT,BUILTINFMTCOUNT
+ 0x0020=COLUMNDEFAULT,ARRAY,DATEMODE,EXTERNALNAME,COLWIDTH,DEFAULTROWHEIGHT,LEFTMARGIN,RIGHTMARGIN
+ 0x0028=TOPMARGIN,BOTTOMMARGIN,PRINTHEADERS,PRINTGRIDLINES,,,,FILEPASS
+ 0x0030=,FONT,FONT2,PRINTSIZE,,INFOOPTS,DATATABLE,DATATABLE2
+ 0x0038=WNDESK,,BEGINPREF,ENDPREF,CONTINUE,WINDOW1,WINDOW2,
+ 0x0040=BACKUP,PANE,CODEPAGE,XF,IXFE,EFONT,SHOWSCROLL,SHOWFORMULA
+ 0x0048=STATUSBAR,SHORTMENUS,DDEENABLED,AUTODEC,MENUKEY,PLS|ZOOM,MENUUND,MOVESEL
+ 0x0050=DCON,DCONREF,DCONNAME,,,DEFCOLWIDTH,,
+ # worksheet records new in BIFF3, but supported in BIFF2 streams
+ 0x0200=DIMENSION,BLANK,,NUMBER,LABEL,BOOLERR,,
+ 0x027E=RK
+ # BIFF5 style BOF
+ 0x0809=BOF
+ # chart records
+ 0x1000=,CHUNITS,CHCHART,CHSERIES,CHSOURCELINK,,CHDATAFORMAT,CHLINEFORMAT
+ 0x1008=,CHMARKERFORMAT,CHAREAFORMAT,CHPIEFORMAT,CHATTACHEDLABEL,CHSTRING,,
+ 0x1010=,,,,CHTYPEGROUP,CHLEGEND,CHSERIESLIST,CHBAR
+ 0x1018=CHLINE,CHPIE,CHAREA,CHSCATTER,CHCHARTLINE,CHAXIS,CHTICK,CHVALUERANGE
+ 0x1020=CHLABELRANGE,CHAXISLINE,CHFORMATLINK,,CHDEFAULTTEXT,CHTEXT,CHFONT,CHOBJECTLINK
+ 0x1028=,,,,,CHARROW,,CHARROWHEAD
+ 0x1030=,,CHFRAME,CHBEGIN,CHEND,CHPLOTFRAME,CHCHARTSIZE,CHRELPOSITION
+ 0x1038=CHARROWRELPOS,,CHCHART3D,,,,,
+end
+
+multilist=RECORD-NAMES-BIFF3
+ include=RECORD-NAMES-BIFF2
+ # worksheet records
+ exclude=0x0006,0x0008,0x0009,0x000B,0x0018,0x0020,0x0021,0x0023,0x0024,0x0025,0x0031,0x0036,0x0037,0x003E,0x0043,0x0044,0x0045
+ 0x0050=,,,,,,BUILTINFMTCOUNT,
+ 0x0058=TOOLBAR,XCT,CRN,FILESHARING,WRITEACCESS,OBJ,UNCALCED,SAFERECALC
+ 0x0060=TEMPLATE,INTL,,OBJECTPROTECT,,,,
+ 0x0068=,,,,,,,
+ 0x0070=,,,,,,,
+ 0x0078=,,,,,COLINFO,,IMDATA
+ 0x0080=GUTS,SHEETPR,GRIDSET,HCENTER,VCENTER,,WRITEPROT,ADDIN
+ 0x0088=EDG,PUB,NOTEOFF,LH,COUNTRY,HIDEOBJ,,
+ 0x0090=SORT,SUB,PALETTE,,LHRECORD,LHNGRAPH,,
+ 0x0200=,,,,,,FORMULA,STRING
+ 0x0208=ROW,BOF,,INDEX,,,,
+ 0x0218=DEFINEDNAME
+ 0x0221=ARRAY
+ 0x0223=EXTERNALNAME
+ 0x0225=DEFAULTROWHEIGHT
+ 0x0231=FONT
+ 0x0236=DATATABLE
+ 0x023E=WINDOW2
+ 0x0243=XF
+ 0x0293=STYLE
+ # chart records
+ 0x103C=CHPICFORMAT
+end
+
+multilist=RECORD-NAMES-BIFF4
+ include=RECORD-NAMES-BIFF3
+ # worksheet/workbook records
+ exclude=0x0206,0x0209,0x001E,0x0243
+ 0x0085=SHEET
+ 0x0088=,,,,,,SHEETSOFFSET,SHEETHEADER
+ 0x0090=,,,,,SOUND,SYNC
+ 0x0098=LPR,STANDARDWIDTH,FNGROUPNAME,,FNGROUPCOUNT,,,
+ 0x00A0=SCL,PAGESETUP,FNPROTO,PROJEXTSHEET,,,,
+ 0x00A8=DRAGDROP,COORDLIST,,GCW,,,,
+ 0x0406=FORMULA
+ 0x0409=BOF
+ 0x041E=FORMAT
+ 0x0443=XF
+ # chart records
+ 0x1038=,,,CHMULTILINK,,CHDROPBAR,CHRADARLINE,CHSURFACE
+end
+
+multilist=RECORD-NAMES-BIFF5
+ include=RECORD-NAMES-BIFF4
+ # worksheet/workbook records
+ exclude=0x0409,0x0218,0x0223,0x0231,0x0443
+ 0x0006=FORMULA
+ 0x0018=DEFINEDNAME
+ 0x0023=EXTERNALNAME
+ 0x0031=FONT
+ 0x0098=,,,FILTERMODE,,AUTOFILTERINFO,AUTOFILTER,
+ 0x00A8=,,,,,,SCENMAN,SCENARIO
+ 0x00B0=SXVIEW,SXVD,SXVI,,SXIVD,SXLI,SXPI,
+ 0x00B8=DOCROUTE,RECIPNAME,,,SHAREDFMLA,MULTRK,MULTBLANK,
+ 0x00C0=,MMS,ADDMENU,DELMENU,,SXDI,SXDB,SXFIELD
+ 0x00C8=SXINDEXLIST,SXDOUBLE,SXBOOLEAN,SXERROR,SXINTEGER,SXSTRING,SXDATETIME,SXEMPTY
+ 0x00D0=SXTBL,SXTBRGITEM,SXTBPG,OBPROJ,,SXIDSTM,RSTRING,DBCELL
+ 0x00D8=SXNUMGROUP,SXGROUPINFO,BOOKBOOL,REVERT,SXEXT|PARAMQRY,SCENPROTECT,OLESIZE,UDDESC
+ 0x00E0=XF,INTERFACEHDR,INTERFACEEND,SXVS,,,,
+ 0x0206=FORMULA
+ # chart records
+ exclude=0x1004,0x102D,0x102F,0x1036,0x1037,0x1038,0x103B
+ 0x1040=CHRADARAREA,CHAXESSET,,CHLEGENDENTRY,CHPROPERTIES,CHSERGROUP,CHUSEDAXESSETS,
+ 0x1048=CHPIVOTREF,,CHSERPARENT,CHSERTRENDLINE,,,CHFORMAT,CHPOS
+ 0x1050=CHFORMATRUNS,CHSOURCELINK,,,,,,
+ 0x1058=,,,CHSERERRORBAR,,CHSERIESFORMAT,,
+end
+
+multilist=RECORD-NAMES-BIFF8
+ include=RECORD-NAMES-BIFF5
+ # worksheet/workbook records
+ 0x00E0=,,,,,CELLMERGING,,
+ 0x00E8=,BITMAP,,MSODRAWINGGROUP,MSODRAWING,MSODRAWINGSELECTION,,PHONETICPR
+ 0x00F0=SXRULE,SXEX,SXFILT,,,,SXNAME,SXSELECT
+ 0x00F8=SXPAIR,SXFMLA,,SXFORMAT,SST,LABELSST,,EXTSST
+ 0x0100=SXVDEX,,,SXFORMULA,,,,
+ 0x0120=,,SXDBEX,,,,,
+ 0x0130=,,,,,,,CHTRINSERT
+ 0x0138=CHTRINFO,,,CHTRCELLCONTENT,,TABID,,
+ 0x0140=CHTRMOVERANGE,,,,,,,
+ 0x0148=,,,,,CHTRINSERTTAB,,
+ 0x0158=,,,,,,,LABELRANGES
+ 0x0160=USESELFS,DSF,XL5MODIFY,,,,,
+ 0x0190=,,,,,,CHTRHEADER,
+ 0x01A8=,USERBVIEW,USERSVIEWBEGIN,USERSVIEWEND,,QSI,EXTERNALBOOK,PROT4REV
+ 0x01B0=CFHEADER,CFRULE,DATAVALIDATIONS,,,DCONBIN,TXO,REFRESHALL
+ 0x01B8=HYPERLINK,NLRDELNAME,CODENAME,SXFDBTYPE,PROT4REVPASS,,DATAVALIDATION,
+ 0x0800=SCREENTIP,,,WEBQRYSETTINGS,WEBQRYTABLES,,,
+ 0x0850=,CHWRAPPEDRECORD,,,,,,CHUNITPROPERTIES
+ 0x0858=CHPIVOTREF,,,,,,,
+ 0x0860=,,SHEETLAYOUT,,,,,SHEETPROTECTION
+ # chart records
+ 0x1058=,,,,,,,CH3DDATAFORMAT
+ 0x1060=CHFONTBASE,CHPIEEXT,CHLABELRANGE2,CHDATATABLE,CHPLOTGROWTH,CHSERINDEX,CHESCHERFORMAT,CHPIEEXTSETT
+end
+
+# simple records -------------------------------------------------------------
+
+constlist=SIMPLE-RECORDS-BIFF2
+ 0x000C=uint16,dec,max-iterations
+ 0x000D=int16,dec,calc-mode,CALCMODE
+ 0x000E=uint16,bool,calc-precise
+ 0x000F=uint16,dec,ref-mode,REFMODE
+ 0x0010=double,dec,epsilon
+ 0x0011=uint16,bool,iterate-recursive
+ 0x0012=uint16,bool,workbook-protected
+ 0x0013=uint16,hex,password-hash
+ 0x0016=uint16,dec,externsheets
+ 0x0019=uint16,bool,window-protected
+ 0x001F=uint16,dec,builtin-fmt-count
+ 0x0022=uint16,dec,null-date,DATEMODE
+ 0x0025=uint16,hex,rowheight-flags,DEFROWHEIGHT-FLAGS
+ 0x0026=double,dec,left-margin,CONV-INCH-TO-CM
+ 0x0027=double,dec,right-margin,CONV-INCH-TO-CM
+ 0x0028=double,dec,top-margin,CONV-INCH-TO-CM
+ 0x0029=double,dec,bottom-margin,CONV-INCH-TO-CM
+ 0x002A=uint16,bool,print-sheet-headers
+ 0x002B=uint16,bool,print-gridlines
+ 0x0040=uint16,bool,backup-on-save
+ 0x0044=uint16,dec,xf-idx
+ 0x0045=uint16,dec,font-color-idx,COLORS
+ 0x0055=uint16,dec,base-col-width
+ 0x100B=uint16,dec,extrusion,CONV-PERCENT
+ 0x100C=uint16,hex,flags,CHATTACHEDLABEL-FLAGS
+ 0x1018=uint16,hex,flags,CHLINE-FLAGS
+ 0x101A=uint16,hex,flags,CHAREA-FLAGS
+ 0x101C=uint16,dec,line-type,CHCHARTLINE-TYPE
+ 0x1021=uint16,dec,axisline-id,CHAXISLINE-ID
+ 0x1024=uint16,dec,text-idx
+ 0x1026=uint16,dec,font-idx,FONTNAMES
+ 0x1045=uint16,dec,group-idx
+ 0x1046=uint16,dec,used-axessets
+ 0x104A=uint16,dec,series-idx
+ 0x104E=uint16,dec,fmt-idx,FORMATS
+end
+
+constlist=SIMPLE-RECORDS-BIFF3
+ include=SIMPLE-RECORDS-BIFF2
+ 0x0056=uint16,dec,builtin-fmt-count
+ 0x005E=uint16,unused
+ 0x005F=uint16,bool,recalc-on-save
+ 0x0063=uint16,bool,objects-protected
+ 0x0081=uint16,hex,flags,SHEETPR-FLAGS
+ 0x0082=uint16,bool,print-gridlines-changed
+ 0x0083=uint16,bool,horizontal-centered
+ 0x0084=uint16,bool,vertical-centered
+ 0x008D=uint16,dec,object-mode,HIDEOBJ
+end
+
+constlist=SIMPLE-RECORDS-BIFF4
+ include=SIMPLE-RECORDS-BIFF3
+ 0x008E=uint32,hex,stream-pos,CONV-DEC
+ 0x0099=uint16,dec,default-col-width,CONV-COLWIDTH
+ 0x009C=uint16,dec,func-group-count
+ 0x103D=uint16,dec,bar-dist
+ 0x103E=uint16,hex,flags,CHRADAR-FLAGS
+ 0x103F=uint16,hex,flags,CHSURFACE-FLAGS
+end
+
+constlist=SIMPLE-RECORDS-BIFF5
+ include=SIMPLE-RECORDS-BIFF4
+ 0x00C9=double,dec,value
+ 0x00CA=uint16,bool,value
+ 0x00CB=uint16,hex,error-code,ERRORCODES
+ 0x00CC=int16,dec,value
+ 0x00D5=uint16,hex,pivotcache-stream-id
+ 0x00D8=uint16,hex,flags,SXNUMGROUP-FLAGS
+ 0x00DA=uint16,bool,strip-cached-values
+ 0x00DD=uint16,bool,scenarios-protected
+ 0x00E3=uint16,dec,source-type,SXVS-TYPE
+ 0x1040=uint16,hex,flags,CHRADAR-FLAGS
+ 0x105D=uint16,hex,flags,CHSERIESFORMAT-FLAGS
+end
+
+constlist=SIMPLE-RECORDS-BIFF8
+ include=SIMPLE-RECORDS-BIFF5
+ 0x00E1=uint16,dec,codepage,CODEPAGES
+ 0x0160=uint16,bool,use-nat-lang-refs
+ 0x0161=uint16,bool,double-stream
+ 0x01AF=uint16,bool,revlog-protected
+ 0x01B7=uint16,bool,refresh-all
+ 0x01BB=uint16,dec,sql-data-type,SXFDBTYPE-DATATYPE
+ 0x01BC=uint16,hex,password-hash
+ 0x1065=uint16,dec,series-idx
+end
+
+# ARRAY ----------------------------------------------------------------------
+
+flagslist=ARRAY-FLAGS-BIFF2
+ 0x0001=recalc-always
+end
+
+flagslist=ARRAY-FLAGS-BIFF3
+ include=ARRAY-FLAGS-BIFF2
+ 0x0002=recalc-onload
+end
+
+# BOF ------------------------------------------------------------------------
+
+constlist=BOF-BIFFTYPE
+ 0x0000=from-id
+ 0x0007=biff2
+ 0x0200=biff2
+ 0x0300=biff3
+ 0x0400=biff4
+ 0x0500=biff5
+ 0x0600=biff8
+end
+
+constlist=BOF-SHEETTYPE
+ 0x0005=globals
+ 0x0006=vb-module
+ 0x0010=sheet
+ 0x0020=chart
+ 0x0040=macro
+ 0x0100=workspace
+end
+
+flagslist=BOF-HISTORY-FLAGS
+ 0x00000001=windows
+ 0x00000002=risc
+ 0x00000004=beta
+ 0x00000008=win-any
+ 0x00000010=mac-any
+ 0x00000020=beta-any
+ 0x00000100=risc-any
+ # missing mac here?
+end
+
+# CALCMODE -------------------------------------------------------------------
+
+shortlist=CALCMODE,-1,automatic-no-table,manual,automatic
+
+# CFRULE ---------------------------------------------------------------------
+
+shortlist=CFRULE-TYPE,1,value,formula
+shortlist=CFRULE-OPERATOR,0,none,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+
+flagslist=CFRULE-FLAGS
+ ignore=0x00380080
+ 0x00000001=!hor-align-used
+ 0x00000002=!vert-align-used
+ 0x00000004=!text-wrap-used
+ 0x00000008=!rotation-used
+ 0x00000010=!justify-lastline-used
+ 0x00000020=!indent-used
+ 0x00000040=!shrinktofit-used
+ 0x00000100=!cell-locked-used
+ 0x00000200=!cell-hidden-used
+ 0x00000400=!left-border-used
+ 0x00000800=!right-border-used
+ 0x00001000=!top-border-used
+ 0x00002000=!bottom-border-used
+ 0x00004000=!tl-to-br-used
+ 0x00008000=!bl-to-tr-used
+ 0x00010000=!fill-pattern-used
+ 0x00020000=!fg-color-idx-used
+ 0x00040000=!bg-color-idx-used
+ 0x04000000=font-block
+ 0x08000000=alignment-block
+ 0x10000000=border-block
+ 0x20000000=pattern-block
+ 0x40000000=protection-block
+ 0x80000000=!text-dir-used
+end
+
+combilist=CFRULE-ALIGNMENT
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=text-wrap
+ 0x70=uint8,dec,ver-align,XF-VERALIGN
+ 0x80=justify-lastline
+end
+
+combilist=CFRULE-INDENT
+ 0x000F=uint8,dec,indent
+ 0x0010=shrink-to-fit
+ 0x00C0=uint8,dec,text-dir,XF-TEXTDIRECTION
+end
+
+flagslist=CFRULE-FONTFLAGS
+ 0x00000002=italic
+ 0x00000008=outline
+ 0x00000010=shadow
+ 0x00000020=condense
+ 0x00000040=extend
+ 0x00000080=strikeout
+end
+
+flagslist=CFRULE-FONTUSEDFLAGS
+ 0x00000002=!italic-used
+ 0x00000008=!outline-used
+ 0x00000010=!shadow-used
+ 0x00000020=!condense-used
+ 0x00000040=!extend-used
+ 0x00000080=!strikeout-used
+end
+
+constlist=CFRULE-FONTUSED
+ 0=used
+ 1=not-used
+end
+
+combilist=CFRULE-BORDERCOLOR2
+ 0x0000007F=uint8,dec,top-color,COLORS
+ 0x00003F80=uint8,dec,bottom-color,COLORS
+ 0x001FC000=uint8,dec,diag-color,COLORS
+ 0x01E00000=uint8,dec,diag-style,BORDERSTYLES
+end
+
+combilist=CFRULE-FILLBLOCK
+ 0x0000FC00=uint8,dec,fill-pattern,FILLPATTERNS
+ 0x007F0000=uint8,dec,fg-color-idx,COLORS
+ 0x3F800000=uint8,dec,bg-color-idx,COLORS
+end
+
+flagslist=CFRULE-PROTECTION-FLAGS
+ 0x0001=locked
+ 0x0002=formula-hidden
+end
+
+# CH3DDATAFORMAT -------------------------------------------------------------
+
+shortlist=CH3DDATAFORMAT-BASE,0,rectangular,circular
+shortlist=CH3DDATAFORMAT-TOP,0,straight,sharp,trunc
+
+# CHAREA ---------------------------------------------------------------------
+
+flagslist=CHAREA-FLAGS
+ 0x0001=stacked
+ 0x0002=percent
+ 0x0004=shadow
+end
+
+# CHAREAFORMAT ---------------------------------------------------------------
+
+flagslist=CHAREAFORMAT-FLAGS
+ 0x0001=auto
+ 0x0002=swap-negative
+end
+
+# CHATTACHEDLABEL ------------------------------------------------------------
+
+flagslist=CHATTACHEDLABEL-FLAGS
+ 0x0001=show-value
+ 0x0002=show-percent
+ 0x0004=show-categ-percent
+ 0x0008=smoothed
+ 0x0010=show-categ
+ 0x0020=show-bubble
+end
+
+# CHAXESSET ------------------------------------------------------------------
+
+shortlist=CHAXESSET-ID,0,primary,secondary
+
+# CHAXIS ---------------------------------------------------------------------
+
+shortlist=CHAXIS-TYPE,0,x-axis,y-axis,z-axis
+
+# CHAXISLINE -----------------------------------------------------------------
+
+shortlist=CHAXISLINE-ID,0,axisline,major-grid,minor-grid,wall
+
+# CHBAR ----------------------------------------------------------------------
+
+flagslist=CHBAR-FLAGS
+ 0x0001=horizontal
+ 0x0002=stacked
+ 0x0004=percent
+ 0x0008=shadow
+end
+
+# CHCHART3D ------------------------------------------------------------------
+
+flagslist=CHCHART3D-FLAGS
+ ignore=0x0010
+ 0x0001=real3d
+ 0x0002=clustered
+ 0x0004=auto-height
+ 0x0020=2d-plotarea
+end
+
+# CHTYPEGROUP ----------------------------------------------------------------
+
+flagslist=CHTYPEGROUP-FLAGS
+ 0x0001=varied-colors
+end
+
+# CHCHARTLINE ----------------------------------------------------------------
+
+shortlist=CHCHARTLINE-TYPE,0,drop-line,hi-lo-line,series-connector
+
+# CHDATAFORMAT ---------------------------------------------------------------
+
+constlist=CHDATAFORMAT-POINTIDX
+ default=
+ -1=all-points
+end
+
+constlist=CHDATAFORMAT-FORMATIDX
+ default=
+ -3=axesset-global
+end
+
+flagslist=CHDATAFORMAT-FLAGS
+ 0x0001=excel4-colors
+end
+
+# CHFRAME --------------------------------------------------------------------
+
+shortlist=CHFRAME-FORMAT,0,standard,,,,shadow
+
+flagslist=CHFRAME-FLAGS
+ 0x0001=auto-size
+ 0x0002=auto-pos
+end
+
+# CHFRAMEPOS -----------------------------------------------------------------
+
+shortlist=CHFRAMEPOS-OBJTYPE,2,any,,,legend
+shortlist=CHFRAMEPOS-SIZEMODE,1,manual,auto
+
+# CHLABELRANGE ---------------------------------------------------------------
+
+flagslist=CHLABELRANGE-FLAGS
+ 0x0001=cross-between-categ
+ 0x0002=maximum-axis-cross
+ 0x0004=reverse-order
+end
+
+# CHLABELRANGE2 --------------------------------------------------------------
+
+flagslist=CHLABELRANGE2-FLAGS
+ 0x0001=auto-minimum
+ 0x0002=auto-maximum
+ 0x0004=auto-major
+ 0x0008=auto-minor
+ 0x0010=date-axis
+ 0x0020=auto-base
+ 0x0040=auto-axis-cross
+ 0x0080=auto-date
+end
+
+# CHLEGEND -------------------------------------------------------------------
+
+shortlist=CHLEGEND-DOCKPOS,0,bottom,top-left,top,right,left,,,manual
+shortlist=CHLEGEND-SPACING,0,close,medium,open
+
+flagslist=CHLEGEND-FLAGS
+ 0x0001=docked
+ 0x0002=auto-series
+ 0x0004=auto-pos-x
+ 0x0008=auto-pos-y
+ 0x0010=stacked
+ 0x0020=data-table
+end
+
+# CHLINE ---------------------------------------------------------------------
+
+flagslist=CHLINE-FLAGS
+ 0x0001=stacked
+ 0x0002=percent
+ 0x0004=shadow
+end
+
+# CHLINEFORMAT ---------------------------------------------------------------
+
+shortlist=CHLINEFORMAT-LINETYPE,0,solid,dash,dot,dash-dot,dash-dot-dot,none,25%-pattern,50%-pattern,75%-pattern
+shortlist=CHLINEFORMAT-LINEWEIGHT,-1,hair,thin,medium,thick
+
+flagslist=CHLINEFORMAT-FLAGS
+ 0x0001=auto
+ 0x0004=axis-enabled
+end
+
+# CHMARKERFORMAT -------------------------------------------------------------
+
+shortlist=CHMARKERFORMAT-TYPE,0,none,square,diamond,triangle,cross,star,dow-jones,std-dev,circle,plus
+
+flagslist=CHMARKERFORMAT-FLAGS
+ 0x0001=auto
+ 0x0010=no-fill
+ 0x0020=no-border
+end
+
+# CHOBJECTLINK ---------------------------------------------------------------
+
+shortlist=CHOBJECTLINK-TARGET,0,none,title,y-axis,x-axis,datapoint,legend,none,z-axis,,,,,axis-unit
+
+constlist=CHOBJECTLINK-POINT
+ default=
+ -2=unknown
+ -1=all-points
+end
+
+# CHPICFORMAT ----------------------------------------------------------------
+
+shortlist=CHPICFORMAT-BITMAP-MODE,1,stretched,stacked,stacked-scaled
+
+constlist=CHPICFORMAT-IMAGE-FORMAT
+ 2=wmf
+ 9=bmp
+ 19=?emf
+end
+
+shortlist=CHPICFORMAT-ENV,1,windows,apple
+
+combilist=CHPICFORMAT-FLAGS
+ 0x00FF=uint16,dec,environment,CHPICFORMAT-ENV
+ 0x0100=format-only
+ 0x0200=top-bottom
+ 0x0400=front-back
+ 0x0800=left-right
+end
+
+# CHPIE ----------------------------------------------------------------------
+
+flagslist=CHPIE-FLAGS
+ 0x0001=shadow
+ 0x0002=connectors
+end
+
+# CHRADAR, CHRADARAREA -------------------------------------------------------
+
+flagslist=CHRADAR-FLAGS
+ 0x0001=axis-labels
+ 0x0002=shadow
+end
+
+# CHPROPERTIES ---------------------------------------------------------------
+
+shortlist=CHPROPERTIES-EMPTYCELLS,0,do-not-plot,as-zero,interpolated
+
+flagslist=CHPROPERTIES-FLAGS
+ 0x0001=manual-format
+ 0x0002=plot-visible-only
+ 0x0004=fixed-size
+ 0x0008=manual-plotarea
+end
+
+# CHSCATTER ------------------------------------------------------------------
+
+shortlist=CHSCATTER-SIZETYPE,0,none,area,width
+
+flagslist=CHSCATTER-FLAGS
+ 0x0001=bubbles
+ 0x0002=show-negative
+ 0x0004=shadow
+end
+
+# CHSERERRORBAR --------------------------------------------------------------
+
+shortlist=CHSERERRORBAR-TYPE,1,x-plus,x-minus,y-plus,y-minus
+shortlist=CHSERERRORBAR-SOURCE,1,percent,fixed,std-deviation,custom,std-error
+
+# CHSERIES -------------------------------------------------------------------
+
+shortlist=CHSERIES-TYPE,0,date,numeric,sequence,text
+
+# CHSERIESFORMAT -------------------------------------------------------------
+
+flagslist=CHSERIESFORMAT-FLAGS
+ 0x0001=spline
+ 0x0002=bubbles-3d
+ 0x0004=shadow
+end
+
+# CHSERTRENDLINE -------------------------------------------------------------
+
+shortlist=CHSERTRENDLINE-TYPE,0,poynomial,exponential,logarithmic,power,moving-average
+
+# CHSOURCELINK ---------------------------------------------------------------
+
+shortlist=CHSOURCELINK-TARGET,0,title,values,category,bubbles
+shortlist=CHSOURCELINK-TYPE,0,default,constant,sheet-link
+
+flagslist=CHSOURCELINK-FLAGS
+ 0x0001=custom-numfmt
+end
+
+# CHSTRING -------------------------------------------------------------------
+
+shortlist=CHSTRING-TYPE,0,text,category-default,value-default,x-prefix,x-postfix,y-prefix,y-postfix,comment
+
+# CHSURFACE ------------------------------------------------------------------
+
+flagslist=CHSURFACE-FLAGS
+ 0x0001=filled
+ 0x0002=shadow
+end
+
+# CHTEXT ---------------------------------------------------------------------
+
+shortlist=CHTEXT-HORALIGN,1,left,center,right,block,distribute
+shortlist=CHTEXT-VERALIGN,1,top,center,bottom,block,distribute
+shortlist=CHTEXT-FILLMODE,1,transparent,opaque
+
+combilist=CHTEXT-FLAGS-BIFF2
+ 0x0001=auto-color
+ 0x0002=show-symbol
+ 0x0004=show-value
+ 0x0008=vertical
+ 0x0010=auto-text
+ 0x0020=default-format
+ 0x0040=deleted
+ 0x0080=auto-fill
+end
+
+combilist=CHTEXT-FLAGS-BIFF3
+ include=CHTEXT-FLAGS-BIFF2
+ 0x0700=uint8,dec,orientation,TEXTORIENTATION
+end
+
+combilist=CHTEXT-FLAGS-BIFF5
+ include=CHTEXT-FLAGS-BIFF3
+ 0x0800=show-categ-percent
+ 0x1000=show-percent
+end
+
+combilist=CHTEXT-FLAGS-BIFF8
+ include=CHTEXT-FLAGS-BIFF5
+ 0x2000=show-bubble-size
+ 0x4000=show-categ
+end
+
+multilist=CHTEXT-PLACEMENT
+ default=
+ 0=context,outside,inside,center,axis,above,below,left,right,auto,manual
+end
+
+# CHTICK ---------------------------------------------------------------------
+
+shortlist=CHTICK-TYPE,0,none,inside,outside,both
+# TODO: really different label positions in BIFF2-BIFF4?
+shortlist=CHTICK-LABELPOS-BIFF2,0,none,near,below,above
+shortlist=CHTICK-LABELPOS-BIFF5,0,none,below,above,near
+
+flagslist=CHTICK-FLAGS-BIFF2
+ 0x0001=auto-color
+ 0x0002=auto-fill
+end
+
+combilist=CHTICK-FLAGS-BIFF3
+ include=CHTICK-FLAGS-BIFF2
+ 0x001C=uint8,dec,orientation,TEXTORIENTATION
+ 0x0020=auto-rotation
+end
+
+# CHUNITPROPERTIES -----------------------------------------------------------
+
+shortlist=CHUNITPROPERTIES-PRESET,-1,manual,none,hundred,thousand,(10000),(100000),million,(10million),(100million),billion,trillion
+
+flagslist=CHUNITPROPERTIES-FLAGS
+ 0x0002=show-unit
+end
+
+# CHVALUERANGE ---------------------------------------------------------------
+
+flagslist=CHVALUERANGE-FLAGS
+ ignore=0x0100
+ 0x0001=auto-minimum
+ 0x0002=auto-maximum
+ 0x0004=auto-major
+ 0x0008=auto-minor
+ 0x0010=auto-axis-cross
+ 0x0020=logarithmic
+ 0x0040=reverse-order
+ 0x0080=maximum-axis-cross
+end
+
+# COLINFO --------------------------------------------------------------------
+
+combilist=COLINFO-FLAGS
+ 0x0001=hidden
+ 0x0002=custom-width
+ 0x0004=best-fit
+ 0x0700=uint8,dec,outline-level
+ 0x1000=outline-collapsed
+end
+
+# DATATABLE ------------------------------------------------------------------
+
+flagslist=DATATABLE-FLAGS-BIFF3
+ 0x0001=recalc-always
+ 0x0002=recalc-on-load
+ 0x0004=row-table
+ 0x0008=table-2d
+end
+
+flagslist=DATATABLE-FLAGS-BIFF8
+ include=DATATABLE-FLAGS-BIFF3
+ 0x0010=ref1-deleted
+ 0x0020=ref2-deleted
+end
+
+# DATAVALIDATION -------------------------------------------------------------
+
+combilist=DATAVALIDATION-FLAGS
+ 0x0000000F=uint8,dec,type,DATAVALIDATION-TYPE
+ 0x00000070=uint8,dec,error-style,DATAVALIDATION-ERRORSTYLE
+ 0x00000080=string-list
+ 0x00000100=ignore-empty
+ 0x00000200=no-dropdown
+ 0x00040000=show-input-box
+ 0x00080000=show-error-box
+ 0x00F00000=uint8,dec,operator,DATAVALIDATION-OPERATOR
+end
+
+shortlist=DATAVALIDATION-TYPE,0,any,whole,decimal,list,date,time,text-length,custom
+shortlist=DATAVALIDATION-OPERATOR,0,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+shortlist=DATAVALIDATION-ERRORSTYLE,0,error,warning,info
+
+# DATAVALIDATIONS ------------------------------------------------------------
+
+flagslist=DATAVALIDATIONS-FLAGS
+ 0x0001=input-box-visible
+ 0x0002=input-box-at-cell
+ 0x0004=cached
+end
+
+# DATEMODE -------------------------------------------------------------------
+
+shortlist=DATEMODE,0,1899-12-31,1904-01-01
+
+# DEFINEDNAME ----------------------------------------------------------------
+
+flagslist=DEFINEDNAME-FLAGS-BIFF2
+ 0x02=macro
+ 0x04=complex
+end
+
+shortlist=DEFINEDNAME-MACROTYPE-BIFF2,0,none,function,procedure
+
+flagslist=DEFINEDNAME-FLAGS-BIFF3
+ 0x0001=hidden
+ 0x0002=function
+ 0x0004=command
+ 0x0008=macro
+ 0x0010=complex
+ 0x0020=builtin
+end
+
+combilist=DEFINEDNAME-FLAGS-BIFF4
+ include=DEFINEDNAME-FLAGS-BIFF3
+ 0x0FC0=uint16,dec,func-group,DEFINEDNAME-FUNCGROUP
+end
+
+combilist=DEFINEDNAME-FLAGS-BIFF5
+ include=DEFINEDNAME-FLAGS-BIFF4
+ 0x0004=vba
+ 0x1000=binary
+end
+
+shortlist=DEFINEDNAME-FUNCGROUP,0,none,financial,date-time,math-trig,statistical,lookup-ref,database,text,logical,information,commands,customizing,macro-control,dde-external,user-definded
+
+constlist=DEFINEDNAME-SHEETIDX
+ default=
+ 0=global
+end
+
+# DEFROWHEIGHT ---------------------------------------------------------------
+
+combilist=DEFROWHEIGHT-FLAGS-BIFF2
+ 0x7FFF=uint16,dec,row-height,CONV-TWIP-TO-PT
+ 0x8000=unchanged
+end
+
+flagslist=DEFROWHEIGHT-FLAGS-BIFF3
+ 0x0001=custom-height
+ 0x0002=hidden
+ 0x0004=thick-top
+ 0x0008=thick-bottom
+end
+
+# EXTERNALBOOK ---------------------------------------------------------------
+
+constlist=EXTERNALBOOK-KEY
+ 0x0401=self-reference
+ 0x3A01=analysis-addin
+end
+
+# EXTERNALNAME ---------------------------------------------------------------
+
+flagslist=EXTERNALNAME-FLAGS-BIFF3
+ 0x0001=builtin
+ 0x0002=automatic
+ 0x0004=pic-link
+end
+
+combilist=EXTERNALNAME-FLAGS-BIFF5
+ include=EXTERNALNAME-FLAGS-BIFF3
+ 0x0008=dde-stddocumentname
+ 0x0010=ole-link
+ 0x7FE0=uint16,dec,clipboard-format
+ 0x8000=iconified
+end
+
+# EXTERNSHEET ----------------------------------------------------------------
+
+constlist=EXTERNSHEET-IDX-BIFF8
+ default=
+ -1=deleted
+ -2=special
+end
+
+# FONT -----------------------------------------------------------------------
+
+flagslist=FONT-FLAGS
+ 0x0001=bold
+ 0x0002=italic
+ 0x0004=underline
+ 0x0008=strikeout
+ 0x0010=outline
+ 0x0020=shadow
+ 0x0040=condense
+ 0x0080=extend
+end
+
+constlist=FONT-WEIGHT
+ 400=normal
+ 700=bold
+end
+
+multilist=FONT-UNDERLINE
+ 0x00=none,single,double
+ 0x21=single-acc,double-acc
+end
+
+shortlist=FONT-ESCAPEMENT,0,none,superscript,subscript
+shortlist=FONT-FAMILY,0,none,roman,swiss,modern,script,decorative
+
+# FORMULA --------------------------------------------------------------------
+
+flagslist=FORMULA-FLAGS-BIFF2
+ 0x0001=recalc-always
+end
+
+flagslist=FORMULA-FLAGS-BIFF3
+ include=FORMULA-FLAGS-BIFF2
+ 0x0002=recalc-onload
+end
+
+flagslist=FORMULA-FLAGS-BIFF5
+ include=FORMULA-FLAGS-BIFF3
+ 0x0008=shared-fmla
+end
+
+shortlist=FORMULA-RESULTTYPE,0,string,boolean,error,empty
+
+# HIDEOBJ --------------------------------------------------------------------
+
+shortlist=HIDEOBJ,0,show,placeholder,hide
+
+# HYPERLINK ------------------------------------------------------------------
+
+79EAC9D0-BAF9-11CE-8C82-00AA004BA90B=StdHlink
+00000303-0000-0000-C000-000000000046=FileMoniker
+79EAC9E0-BAF9-11CE-8C82-00AA004BA90B=URLMoniker
+
+flagslist=HYPERLINK-FLAGS
+ 0x00000001=target
+ 0x00000002=absolute
+ 0x00000004=display-1
+ 0x00000008=location
+ 0x00000010=display-2
+ 0x00000080=frame
+ 0x00000100=unc-path
+end
+
+# OBJ ------------------------------------------------------------------------
+
+multilist=OBJ-TYPE-BIFF5
+ 0=group,line,rect,oval,arc,chart,textbox,button,pic,polygon
+ 10=,checkbox,optbutton,edit,label,dialog,spin,scrollbar,listbox,groupbox
+ 20=dropdown
+end
+
+flagslist=OBJ-FLAGS-BIFF5
+ 0x0001=selected
+ 0x0002=auto-size
+ 0x0004=auto-move
+ 0x0010=protected
+ 0x0080=grouped
+ 0x0100=hidden
+ 0x0200=visible
+ 0x0400=printable
+end
+
+flagslist=OBJ-FLAGS-AUTO-BIFF5
+ 0x0001=auto
+end
+
+shortlist=OBJ-LINETYPE,0,solid,dash,dot,dash-dot,dash-dot-dot,25%-pattern,50%-pattern,75%-pattern
+shortlist=OBJ-LINEWEIGHT,0,hair,thin,medium,thick
+
+shortlist=OBJ-ARROWHEAD-TYPE-BIFF5,0,none,open,filled,double-end-open,double-end-filled
+shortlist=OBJ-ARROWHEAD-WIDTH-BIFF5,0,narrow,medium,wide
+shortlist=OBJ-ARROWHEAD-LENGTH-BIFF5,0,short,medium,long
+
+combilist=OBJ-LINEENDS-BIFF5
+ 0x000F=uint8,dec,arrowhead-type,OBJ-ARROWHEAD-TYPE
+ 0x00F0=uint8,dec,arrowhead-width,OBJ-ARROWHEAD-WIDTH
+ 0x0F00=uint8,dec,arrowhead-length,OBJ-ARROWHEAD-LENGTH
+end
+
+shortlist=OBJ-LINEDIR-BIFF5,0,topleft-to-bottomright,topright-to-bottomleft,bottomright-to-topleft,bottomleft-to-topright
+
+combilist=OBJ-FRAMESTYLE-FLAGS-BIFF5
+ 0x0001=rounded
+ 0x0002=shadow
+ 0x03FC=uint16,dec,rounded-diameter
+end
+
+flagslist=OBJ-CHART-FLAGS-BIFF5
+ 0x0001=linked-to-sheet
+end
+
+multilist=OBJ-RECNAMES-BIFF8
+ 0x0000=OBJEND,,,,OBJMACRO,,OBJGMO,OBJCF
+ 0x0008=OBJPIOGRBIT,OBJPICTFMLA,OBJCBLS,,OBJSBS,,OBJSBSFMLA,OBJGBODATA
+ 0x0010=,,,OBJLBSDATA,OBJCBLSFMLA,OBJCMO,,
+end
+
+flagslist=OBJPIOGRBIT-FLAGS
+ 0x0001=manual-size
+ 0x0002=linked
+ 0x0008=symbol
+ 0x0010=control
+ 0x0020=ctls-stream
+ 0x0200=auto-load
+end
+
+shortlist=OBJPICTFMLA-HASCLASSNAME,0,false,,,true
+
+multilist=OBJCMO-TYPE
+ include=OBJ-TYPE-BIFF5
+ 25=note
+ 30=drawing
+end
+
+flagslist=OBJCMO-FLAGS
+ 0x0001=locked
+ 0x0010=printable
+ 0x2000=auto-line
+ 0x4000=auto-area
+end
+
+# PAGESETUP ------------------------------------------------------------------
+
+multilist=PAGESETUP-PAPERSIZE
+ 0=undefined,letter,letter-small,tabloid,ledger,legal,statement,executive,a3,a4
+ 10=a4-small,a5,b4,b5,folio,quarto,10x14,11x17,note,envelope-9
+ 20=envelope-10,envelope-11,envelope-12,envelope-14,c,d,e,envelope-dl,envelope-c5,envelope-c3
+ 30=envelope-c4,envelope-c6,envelope-c65,envelope-b4,envelope-b5,envelope-b6,envelope-italy,envelope-monarch,envelope-6-3/4,us-standard-fanfold
+ 40=german-standard-fanfold,german-legal-fanfold,b4,japanese-dbl-postcaed,9x11,10x11,15x11,,
+ 50=envelope-invite,letter-extra,legal-extra,tabloid-extra,a4-extra,letter-transverse,a4-transverse,letter-extra-transverse,super-a-a4,super-b-a3,letter-plus
+ 60=a4-plus,a5-transverse,jis-b5-transverse,a3-extra,a5-extra,b5-extra,a2,a3-transverse,a3-extra-transverse
+end
+
+constlist=PAGESETUP-SCALETOPAGES
+ default=
+ 0=automatic
+end
+
+flagslist=PAGESETUP-FLAGS-BIFF4
+ 0x0001=print-in-rows
+ 0x0002=portrait
+ 0x0004=uninitialized
+ 0x0008=black-and-white
+end
+
+flagslist=PAGESETUP-FLAGS-BIFF5
+ include=PAGESETUP-FLAGS-BIFF4
+ 0x0010=draft-quality
+ 0x0020=print-notes
+ 0x0040=default-orientation
+ 0x0080=use-first-page
+end
+
+combilist=PAGESETUP-FLAGS-BIFF8
+ include=PAGESETUP-FLAGS-BIFF5
+ 0x0200=print-notes-at-end
+ 0x0C00=uint8,dec,print-errors,PAGESETUP-PRINTERRORS
+end
+
+shortlist=PAGESETUP-PRINTERRORS,0,displayed,none,as-dashes,as-na
+
+unitconverter=PAGESETUP-DPI,1,dpi
+
+# PANE -----------------------------------------------------------------------
+
+shortlist=PANE-ID,0,bottom-right,top-right,bottom-left,top-left
+
+# PHONETICPR -----------------------------------------------------------------
+
+shortlist=PHONETICPR-TYPE,0,halfwidth-katakana,fullwidth-katakana,hiragana,no-conversion
+shortlist=PHONETICPR-ALIGNMENT,0,no-control,left,center,distributed
+
+combilist=PHONETICPR-FLAGS
+ ignore=0x0030
+ 0x0003=uint8,dec,type,PHONETICPR-TYPE
+ 0x000C=uint8,dec,alignment,PHONETICPR-ALIGNMENT
+end
+
+# PROJEXTSHEET ---------------------------------------------------------------
+
+shortlist=PROJEXTSHEET-TYPE,0,sheet,macro,chart
+
+# REFMODE --------------------------------------------------------------------
+
+shortlist=REFMODE,0,R1C1,A1
+
+# ROW ------------------------------------------------------------------------
+
+combilist=ROW-HEIGHT
+ 0x7FFF=uint16,dec,height,CONV-TWIP-TO-PT
+ 0x8000=default-height
+end
+
+combilist=ROW-FLAGS
+ ignore=0x00000100
+ 0x00000007=uint8,dec,outline-level
+ 0x00000010=outline-collapsed
+ 0x00000020=hidden
+ 0x00000040=custom-height
+ 0x00000080=custom-format
+ 0x0FFF0000=uint16,dec,custom-xf-idx
+ 0x10000000=thick-top
+ 0x20000000=thick-bottom
+ 0x40000000=show-phonetic
+end
+
+# SHEET ----------------------------------------------------------------------
+
+shortlist=SHEET-STATE,0,visible,hidden,very-hidden
+shortlist=SHEET-TYPE,0,worksheet,,chart,,,,vb-module
+
+# SHEETPR --------------------------------------------------------------------
+
+shortlist=SHEETPR-WINDOWPOS,0,tiled,horizontal,vertical,cascaded
+
+flagslist=SHEETPR-FLAGS-BIFF3
+ 0x0001=show-autopagebreaks
+ 0x0010=dialog-sheet
+ 0x0020=outline-auto-style
+ 0x0040=outline-symbols-below
+ 0x0080=outline-symbols-right
+ 0x0100=fit-to-pages
+ 0x0200=skip-linked-values
+ 0x0400=show-row-outline
+ 0x0800=show-column-outline
+end
+
+flagslist=SHEETPR-FLAGS-BIFF4
+ include=SHEETPR-FLAGS-BIFF3
+ 0x3000=uint8,dec,window-pos,SHEETPR-WINDOWPOS
+ 0x4000=lotus-expr-eval
+ 0x8000=lotus-formula-edit
+end
+
+flagslist=SHEETPR-FLAGS-BIFF5
+ include=SHEETPR-FLAGS-BIFF4
+ exclude=0x0200,0x3000
+end
+
+# SHEETPROTECTION ------------------------------------------------------------
+
+flagslist=SHEETPROTECTION-FLAGS
+ 0x0001=edit-object
+ 0x0002=edit-scenario
+ 0x0004=format-cell
+ 0x0008=format-column
+ 0x0010=format-row
+ 0x0020=insert-column
+ 0x0040=insert-row
+ 0x0080=insert-hyperlink
+ 0x0100=delete-column
+ 0x0200=delete-row
+ 0x0400=select-locked
+ 0x0800=sort
+ 0x1000=use-autofilter
+ 0x2000=pivottable-report
+ 0x4000=select-unlocked
+end
+
+# STYLE ----------------------------------------------------------------------
+
+combilist=STYLE-FLAGS
+ 0x0FFF=uint16,dec,xf-idx
+ 0x8000=builtin
+end
+
+shortlist=STYLE-BUILTIN,0,normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink
+
+# common for pivot tables ----------------------------------------------------
+
+constlist=SX-NAMELEN
+ default=
+ 0xFFFF=name-in-cache
+end
+
+# SXDB -----------------------------------------------------------------------
+
+flagslist=SXDB-FLAGS
+ 0x0001=save-data
+ 0x0002=invalid
+ 0x0004=refresh-on-load
+ 0x0008=opt-cache
+ 0x0010=backgr-query
+ 0x0020=enable-refresh
+end
+
+constlist=SXDB-TYPE
+ 1=worksheet
+ 2=external
+ 4=consolidation
+ 8=scenario
+end
+
+# SXDI -----------------------------------------------------------------------
+
+shortlist=SXDI-FUNC,0,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p
+shortlist=SXDI-FORMAT,0,normal,diff-from,percent-of,percent-diff-from,running-total-in,percent-of-row,percent-of-column,percent-of-total,index
+
+multilist=SXDI-BASEITEM
+ default=
+ 0x7FFB=previous-item,next-item
+end
+
+# SXEXT ----------------------------------------------------------------------
+
+combilist=SXEXT-FLAGS
+ 0x0007=uint8,dec,source-type,SXEXT-SOURCETYPE
+ 0x0008=odbc-connection
+ 0x0010=odbc-sql
+ 0x0020=server-pagefields
+ 0x0040=webquery
+ 0x0080=save-password
+ 0x0100=tables-html-only
+end
+
+shortlist=SXEXT-SOURCETYPE,1,odbc,dao,,webquery
+
+# SXFDBTYPE ------------------------------------------------------------------
+
+shortlist=SXFDBTYPE-DATATYPE,0,unknown,char,numeric,decimal,integer,small-int,float,real,double,datetime,,,var-char
+
+# SXFIELD --------------------------------------------------------------------
+
+combilist=SXFIELD-FLAGS
+ 0x0001=has-items
+ 0x0002=postpone-items
+ 0x0004=calculated
+ 0x0008=has-child
+ 0x0010=numeric-group
+ 0x0020=16bit-indexes
+ 0x0DE0=uint16,hex,data-type,SXFIELD-TYPE,noshift
+end
+
+constlist=SXFIELD-TYPE
+ 0x0000=none
+ 0x0480=string-only
+ 0x0520=integer-optdouble
+ 0x0560=double-only
+ 0x05A0=string-integer-optdouble
+ 0x05E0=string-double-only
+ 0x0900=date-only
+ 0x0980=date-empty-only
+ 0x0D00=date-number
+ 0x0D80=date-string-optnumber
+end
+
+# SXLI -----------------------------------------------------------------------
+
+shortlist=SXLI-ITEMTYPE,0,data,default,sum,count-num,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p,grandtotal,blank-line
+
+combilist=SXLI-FLAGS
+ 0x0001=field-name
+ 0x01FE=uint16,dec,data-field-idx
+ 0x0200=subtotal
+ 0x0400=blocktotal
+ 0x0800=grandtotal
+ 0x1000=multi-data
+end
+
+# SXNUMGROUP -----------------------------------------------------------------
+
+combilist=SXNUMGROUP-FLAGS
+ 0x0001=auto-min
+ 0x0002=auto-max
+ 0x003C=uint8,dec,data-type,SXNUMGROUP-TYPE
+end
+
+shortlist=SXNUMGROUP-TYPE,1,second,minute,hour,day,month,quarter,year,numeric
+
+# SXVD -----------------------------------------------------------------------
+
+flagslist=SXVD-AXISTYPE
+ 0x0001=row
+ 0x0002=column
+ 0x0004=page
+ 0x0008=data
+end
+
+flagslist=SXVD-SUBTOTALS
+ 0x0001=default
+ 0x0002=sum
+ 0x0004=count-all
+ 0x0008=average
+ 0x0010=max
+ 0x0020=min
+ 0x0040=product
+ 0x0080=count-num
+ 0x0100=std-dev
+ 0x0200=std-dev-p
+ 0x0400=variance
+ 0x0800=variance-p
+end
+
+# SXVDEX ---------------------------------------------------------------------
+
+combilist=SXVDEX-FLAGS
+ 0x00000001=show-all-items
+ 0x00000002=drag-to-row
+ 0x00000004=drag-to-column
+ 0x00000008=drag-to-page
+ 0x00000010=drag-to-hide
+ 0x00000080=server-based
+ 0x00000200=autosort
+ 0x00000400=autosort-ascending
+ 0x00000800=autoshow
+ 0x00001000=autoshow-top-values
+ 0x00002000=calculated
+ 0x00200000=layout-report
+ 0x00400000=layout-blank
+ 0x00800000=layout-top
+ 0xFF000000=uint8,dec,autoshow-item-count
+end
+
+# SXVI -----------------------------------------------------------------------
+
+multilist=SXVI-ITEMTYPE
+ 0=data,default,sum,count-num,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p,grandtotal
+ 254=page,none
+end
+
+flagslist=SXVI-FLAGS
+ 0x0001=hidden
+ 0x0002=hide-detail
+ 0x0004=calculated
+ 0x0008=missing
+end
+
+# SXVIEW ---------------------------------------------------------------------
+
+flagslist=SXVIEW-FLAGS
+ 0x0001=row-grandtotals
+ 0x0002=column-grandtotals
+ 0x0008=auto-format
+ 0x0010=size-auto-format
+ 0x0020=font-auto-format
+ 0x0040=align-auto-format
+ 0x0080=border-auto-format
+ 0x0100=pattern-auto-format
+ 0x0200=number-auto-format
+end
+
+# SXVS -----------------------------------------------------------------------
+
+flagslist=SXVS-TYPE
+ 0x0001=spreadsheet
+ 0x0002=extern
+ 0x0004=consolidation-area
+ 0x0008=pivot-table
+ 0x0010=scenario
+end
+
+# WINDOW1 --------------------------------------------------------------------
+
+flagslist=WINDOW1-FLAGS
+ 0x0001=hidden
+ 0x0002=minimized
+ 0x0008=show-horizontal-scroll
+ 0x0010=show-vertical-scroll
+ 0x0020=show-tabbar
+end
+
+unitconverter=WINDOW1-TABBARRATIO,/10,%
+
+# WINDOW2 --------------------------------------------------------------------
+
+flagslist=WINDOW2-FLAGS-BIFF3
+ 0x0001=show-formulas
+ 0x0002=show-gridlines
+ 0x0004=show-headings
+ 0x0008=frozen-panes
+ 0x0010=show-zeros
+ 0x0020=default-gridcolor
+ 0x0040=right-to-left
+ 0x0080=show-outline-symbols
+ 0x0100=remove-split-with-freeze
+end
+
+flagslist=WINDOW2-FLAGS-BIFF5
+ include=WINDOW2-FLAGS-BIFF3
+ 0x0200=sheet-selected
+ 0x0400=sheet-active
+end
+
+flagslist=WINDOW2-FLAGS-BIFF8
+ include=WINDOW2-FLAGS-BIFF5
+ 0x0800=pagebreak-mode
+end
+
+# XF -------------------------------------------------------------------------
+
+shortlist=XF-HORALIGN,0,general,left,center,right,fill,block,center-across-sel,distribute
+shortlist=XF-VERALIGN,0,top,center,bottom,justify,distribute
+shortlist=XF-TEXTDIRECTION,0,context,left-to-right,right-to-left
+
+flagslist=XF-PROTECTION-FLAGS
+ 0x01=locked
+ 0x02=formula-hidden
+ 0x04=style-xf
+end
+
+flagslist=XF-USEDATTRIBS-FLAGS
+ 0x04=format
+ 0x08=font
+ 0x10=alignment
+ 0x20=border
+ 0x40=area
+ 0x80=protection
+end
+
+combilist=XF-STYLEFLAGS-BIFF2
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=left-border
+ 0x10=right-border
+ 0x20=top-border
+ 0x40=bottom-border
+ 0x80=fill
+end
+
+combilist=XF-TYPEFLAGS-BIFF2
+ 0x3F=uint8,dec,fmt-idx,FORMATS
+ 0x40=locked
+ 0x80=formula-hidden
+end
+
+flagslist=XF-TYPEFLAGS-BIFF3
+ include=XF-PROTECTION-FLAGS
+end
+
+combilist=XF-TYPEFLAGS-BIFF4
+ include=XF-TYPEFLAGS-BIFF3
+ 0xFFF0=uint16,dec,parent-xf-idx
+end
+
+combilist=XF-ALIGNMENT-BIFF3
+ 0x0007=uint8,dec,hor-align,XF-HORALIGN
+ 0x0008=text-wrap
+ 0xFFF0=uint16,dec,parent-xf-idx
+end
+
+combilist=XF-ALIGNMENT-BIFF4
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=text-wrap
+ 0x30=uint8,dec,ver-align,XF-VERALIGN
+ 0xC0=uint8,dec,orientation,TEXTORIENTATION
+end
+
+combilist=XF-ALIGNMENT-BIFF5
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=text-wrap
+ 0x70=uint8,dec,ver-align,XF-VERALIGN
+ 0x80=justify-lastline
+end
+
+combilist=XF-ORIENTATTRIBS-BIFF5
+ include=XF-USEDATTRIBS-FLAGS
+ 0x03=uint8,dec,orientation,TEXTORIENTATION
+end
+
+combilist=XF-TEXTFLAGS-BIFF8
+ 0x0F=uint8,dec,indent
+ 0x10=shrink-to-fit
+ 0xC0=uint8,dec,text-dir,XF-TEXTDIRECTION
+end
+
+combilist=XF-FILL-BIFF3
+ 0x003F=uint8,dec,fill-pattern,FILLPATTERNS
+ 0x07C0=uint8,dec,fg-color-idx,COLORS
+ 0xF800=uint8,dec,bg-color-idx,COLORS
+end
+
+combilist=XF-BORDER-BIFF3
+ 0x00000007=uint8,dec,top-style,BORDERSTYLES
+ 0x000000F8=uint8,dec,top-color,COLORS
+ 0x00000700=uint8,dec,left-style,BORDERSTYLES
+ 0x0000F800=uint8,dec,left-color,COLORS
+ 0x00070000=uint8,dec,bottom-style,BORDERSTYLES
+ 0x00F80000=uint8,dec,bottom-color,COLORS
+ 0x07000000=uint8,dec,right-style,BORDERSTYLES
+ 0xF8000000=uint8,dec,right-color,COLORS
+end
+
+combilist=XF-FILL-BIFF5
+ 0x0000007F=uint8,dec,fg-color-idx,COLORS
+ 0x00003F80=uint8,dec,bg-color-idx,COLORS
+ 0x003F0000=uint8,dec,fill-pattern,FILLPATTERNS
+ 0x01C00000=uint8,dec,bottom-style,BORDERSTYLES
+ 0xFE000000=uint8,dec,bottom-color,COLORS
+end
+
+combilist=XF-BORDER-BIFF5
+ 0x00000007=uint8,dec,top-style,BORDERSTYLES
+ 0x00000038=uint8,dec,left-style,BORDERSTYLES
+ 0x000001C0=uint8,dec,right-style,BORDERSTYLES
+ 0x0000FE00=uint8,dec,top-color,COLORS
+ 0x007F0000=uint8,dec,left-color,COLORS
+ 0x3F800000=uint8,dec,right-color,COLORS
+end
+
+combilist=XF-BORDERSTYLE-BIFF8
+ 0x000F=uint8,dec,left-style,BORDERSTYLES
+ 0x00F0=uint8,dec,right-style,BORDERSTYLES
+ 0x0F00=uint8,dec,top-style,BORDERSTYLES
+ 0xF000=uint8,dec,bottom-style,BORDERSTYLES
+end
+
+combilist=XF-BORDERCOLOR1-BIFF8
+ 0x007F=uint8,dec,left-color,COLORS
+ 0x3F80=uint8,dec,right-color,COLORS
+ 0x4000=diag-tl-to-br
+ 0x8000=diag-bl-to-tr
+end
+
+combilist=XF-BORDERCOLOR2-BIFF8
+ 0x0000007F=uint8,dec,top-color,COLORS
+ 0x00003F80=uint8,dec,bottom-color,COLORS
+ 0x001FC000=uint8,dec,diag-color,COLORS
+ 0x01E00000=uint8,dec,diag-style,BORDERSTYLES
+ 0xFC000000=uint8,dec,fill-pattern,FILLPATTERNS
+end
+
+combilist=XF-FILLCOLOR-BIFF8
+ 0x007F=uint8,dec,fg-color-idx,COLORS
+ 0x3F80=uint8,dec,bg-color-idx,COLORS
+end
+
+# BIFF2 XF index field -------------------------------------------------------
+
+constlist=XFINDEX-BIFF2
+ default=
+ 63=from-ixfe
+end
+
+combilist=CELL-XFINDEX-BIFF2
+ 0x3F=uint8,dec,xf-idx,XFINDEX-BIFF2
+ 0x40=locked
+ 0x80=formula-hidden
+end
+
+combilist=CELL-XFFORMAT-BIFF2
+ 0x3F=uint8,dec,fmt-idx,FORMATS
+ 0xC0=uint8,dec,font-idx,FONTNAMES
+end
+
+combilist=CELL-XFSTYLE-BIFF2
+ include=XF-STYLEFLAGS-BIFF2
+end
+
+# ============================================================================
+
diff --git a/oox/source/dump/dffdumper.cxx b/oox/source/dump/dffdumper.cxx
new file mode 100644
index 000000000000..cb9d1262efae
--- /dev/null
+++ b/oox/source/dump/dffdumper.cxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dffdumper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/dump/dffdumper.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+
+DffRecordHeaderObject::DffRecordHeaderObject( const InputObjectBase& rParent )
+{
+ static const RecordHeaderConfigInfo saHeaderCfgInfo =
+ {
+ "DFFREC",
+ "DFF-RECORD-NAMES",
+ "show-dff-record-pos",
+ "show-dff-record-size",
+ "show-dff-record-id",
+ "show-dff-record-name",
+ "show-dff-record-body",
+ };
+ RecordHeaderBase< sal_uInt16, sal_uInt32 >::construct( rParent, saHeaderCfgInfo );
+ if( RecordHeaderBase< sal_uInt16, sal_uInt32 >::implIsValid() )
+ {
+ mxRecInst = cfg().getNameList( "DFF-RECORD-INST" );
+ mnBodyStart = mnBodyEnd = 0;
+ mnInstVer = 0;
+ }
+}
+
+bool DffRecordHeaderObject::implIsValid() const
+{
+ return isValid( mxRecInst ) && RecordHeaderBase< sal_uInt16, sal_uInt32 >::implIsValid();
+}
+
+bool DffRecordHeaderObject::implReadHeader( sal_Int64& ornRecPos, sal_uInt16& ornRecId, sal_uInt32& ornRecSize )
+{
+ ornRecPos = in().tell();
+ if( ornRecPos >= in().getSize() ) return false;
+ in() >> mnInstVer >> ornRecId >> ornRecSize;
+ mnBodyStart = in().tell();
+ mnBodyEnd = ::std::min< sal_Int64 >( mnBodyStart + ornRecSize, in().getSize() );
+ return in().isValidPos();
+}
+
+void DffRecordHeaderObject::implWriteExtHeader()
+{
+ writeHexItem( "instance", mnInstVer, mxRecInst );
+}
+
+// ============================================================================
+
+DffDumpObject::DffDumpObject( const InputObjectBase& rParent )
+{
+ InputObjectBase::construct( rParent );
+ if( InputObjectBase::implIsValid() )
+ mxHdrObj.reset( new DffRecordHeaderObject( *this ) );
+}
+
+DffDumpObject::~DffDumpObject()
+{
+}
+
+void DffDumpObject::dumpDffClientPos( const sal_Char* pcName, sal_Int32 nSubScale )
+{
+ MultiItemsGuard aMultiGuard( out() );
+ TableGuard aTabGuard( out(), 17 );
+ dumpDec< sal_uInt16 >( pcName );
+ ItemGuard aItem( out(), "sub-units" );
+ sal_uInt16 nSubUnits;
+ in() >> nSubUnits;
+ out().writeDec( nSubUnits );
+ out().writeChar( '/' );
+ out().writeDec( nSubScale );
+}
+
+void DffDumpObject::dumpDffClientRect()
+{
+ dumpDffClientPos( "start-col", 1024 );
+ dumpDffClientPos( "start-row", 256 );
+ dumpDffClientPos( "end-col", 1024 );
+ dumpDffClientPos( "end-row", 256 );
+}
+
+bool DffDumpObject::implIsValid() const
+{
+ return isValid( mxHdrObj ) && InputObjectBase::implIsValid();
+}
+
+void DffDumpObject::implDump()
+{
+ while( mxHdrObj->startNextRecord() )
+ {
+ if( mxHdrObj->getVer() != 0x0F )
+ {
+ if( mxHdrObj->isShowRecBody() )
+ dumpRecordBody();
+ in().seek( mxHdrObj->getBodyEnd() );
+ }
+ out().emptyLine();
+ }
+}
+
+void DffDumpObject::dumpRecordBody()
+{
+ IndentGuard aIndGuard( out() );
+
+ // record contents
+ if( mxHdrObj->hasRecName() ) switch( mxHdrObj->getRecId() )
+ {
+ case 0xF00B:
+ dumpDffOptRec();
+ break;
+ case 0xF010:
+ dumpHex< sal_uInt16 >( "flags", "DFFCLIENTANCHOR-FLAGS" );
+ dumpDffClientRect();
+ break;
+ }
+
+ // remaining undumped data
+ sal_Int64 nPos = in().tell();
+ if( nPos == mxHdrObj->getBodyStart() )
+ dumpRawBinary( mxHdrObj->getRecSize(), false );
+ else if( nPos < mxHdrObj->getBodyEnd() )
+ dumpRemaining( static_cast< sal_Int32 >( mxHdrObj->getBodyEnd() - nPos ) );
+}
+
+void DffDumpObject::dumpDffOptRec()
+{
+ sal_uInt16 nInst = mxHdrObj->getInst();
+ sal_Int64 nBodyEnd = mxHdrObj->getBodyEnd();
+ out().resetItemIndex();
+ for( sal_uInt16 nIdx = 0; (nIdx < nInst) && (in().tell() < nBodyEnd); ++nIdx )
+ {
+ sal_uInt16 nPropId = dumpDffOptPropHeader();
+ IndentGuard aIndent( out() );
+ dumpDffOptPropValue( nPropId, in().readValue< sal_uInt32 >() );
+ }
+}
+
+sal_uInt16 DffDumpObject::dumpDffOptPropHeader()
+{
+ MultiItemsGuard aMultiGuard( out() );
+ TableGuard aTabGuard( out(), 11 );
+ writeEmptyItem( "#prop" );
+ return dumpHex< sal_uInt16 >( "id", "DFFOPT-PROPERTY-ID" );
+}
+
+void DffDumpObject::dumpDffOptPropValue( sal_uInt16 nPropId, sal_uInt32 nValue )
+{
+ switch( nPropId & 0x3FFF )
+ {
+ case 127: writeHexItem( "flags", nValue, "DFFOPT-LOCK-FLAGS" ); break;
+ case 191: writeHexItem( "flags", nValue, "DFFOPT-TEXT-FLAGS" ); break;
+ case 255: writeHexItem( "flags", nValue, "DFFOPT-TEXTGEO-FLAGS" ); break;
+ case 319: writeHexItem( "flags", nValue, "DFFOPT-PICTURE-FLAGS" ); break;
+ case 383: writeHexItem( "flags", nValue, "DFFOPT-GEO-FLAGS" ); break;
+ case 447: writeHexItem( "flags", nValue, "DFFOPT-FILL-FLAGS" ); break;
+ case 511: writeHexItem( "flags", nValue, "DFFOPT-LINE-FLAGS" ); break;
+ case 575: writeHexItem( "flags", nValue, "DFFOPT-SHADOW-FLAGS" ); break;
+ case 639: writeHexItem( "flags", nValue, "DFFOPT-PERSP-FLAGS" ); break;
+ case 703: writeHexItem( "flags", nValue, "DFFOPT-3DOBJ-FLAGS" ); break;
+ case 767: writeHexItem( "flags", nValue, "DFFOPT-3DSTYLE-FLAGS" ); break;
+ case 831: writeHexItem( "flags", nValue, "DFFOPT-SHAPE1-FLAGS" ); break;
+ case 895: writeHexItem( "flags", nValue, "DFFOPT-CALLOUT-FLAGS" ); break;
+ case 959: writeHexItem( "flags", nValue, "DFFOPT-SHAPE2-FLAGS" ); break;
+ default: writeHexItem( "value", nValue );
+ }
+}
+
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx
new file mode 100644
index 000000000000..0c9cff9ea5f7
--- /dev/null
+++ b/oox/source/dump/dumperbase.cxx
@@ -0,0 +1,2775 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dumperbase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/dump/dumperbase.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/tencinfo.h>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XTextInputStream.hpp>
+#include <com/sun/star/io/XTextOutputStream.hpp>
+#include <comphelper/processfactory.hxx>
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/biffhelper.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::util::DateTime;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::ucb::XSimpleFileAccess;
+using ::com::sun::star::io::XActiveDataSink;
+using ::com::sun::star::io::XActiveDataSource;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XTextInputStream;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::io::XTextOutputStream;
+using ::oox::core::FilterBase;
+
+namespace oox {
+namespace dump {
+
+const sal_Unicode OOX_DUMP_BOM = 0xFEFF;
+const sal_Int32 OOX_DUMP_MAXSTRLEN = 80;
+const sal_Int32 OOX_DUMP_INDENT = 2;
+const sal_Unicode OOX_DUMP_BINDOT = '.';
+const sal_Unicode OOX_DUMP_CFG_LISTSEP = ',';
+const sal_Unicode OOX_DUMP_CFG_QUOTE = '\'';
+const sal_Unicode OOX_DUMP_LF = '\n';
+const sal_Unicode OOX_DUMP_ITEMSEP = '=';
+const sal_Int32 OOX_DUMP_BYTESPERLINE = 16;
+const sal_Int32 OOX_DUMP_MAXARRAY = 16;
+
+// ============================================================================
+// ============================================================================
+
+// file names -----------------------------------------------------------------
+
+OUString InputOutputHelper::convertFileNameToUrl( const OUString& rFileName )
+{
+ OUString aFileUrl;
+ if( ::osl::FileBase::getFileURLFromSystemPath( rFileName, aFileUrl ) == ::osl::FileBase::E_None )
+ return aFileUrl;
+ return OUString();
+}
+
+sal_Int32 InputOutputHelper::getFileNamePos( const OUString& rFileUrl )
+{
+ sal_Int32 nSepPos = rFileUrl.lastIndexOf( '/' );
+ return (nSepPos < 0) ? 0 : (nSepPos + 1);
+}
+
+Reference< XInputStream > InputOutputHelper::openInputStream( const OUString& rFileName )
+{
+ Reference< XInputStream > xInStrm;
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
+ xInStrm = xFileAccess->openFileRead( rFileName );
+ }
+ catch( Exception& )
+ {
+ }
+ return xInStrm;
+}
+
+Reference< XTextInputStream > InputOutputHelper::openTextInputStream( const Reference< XInputStream >& rxInStrm, const OUString& rEncoding )
+{
+ Reference< XTextInputStream > xTextInStrm;
+ if( rxInStrm.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XActiveDataSink > xDataSink( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW );
+ xDataSink->setInputStream( rxInStrm );
+ xTextInStrm.set( xDataSink, UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ if( xTextInStrm.is() )
+ xTextInStrm->setEncoding( rEncoding );
+ return xTextInStrm;
+}
+
+Reference< XTextInputStream > InputOutputHelper::openTextInputStream( const OUString& rFileName, const OUString& rEncoding )
+{
+ return openTextInputStream( openInputStream( rFileName ), rEncoding );
+}
+
+Reference< XOutputStream > InputOutputHelper::openOutputStream( const OUString& rFileName )
+{
+ Reference< XOutputStream > xOutStrm;
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
+ if( !xFileAccess->isFolder( rFileName ) )
+ {
+ try { xFileAccess->kill( rFileName ); } catch( Exception& ) {}
+ xOutStrm = xFileAccess->openFileWrite( rFileName );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ return xOutStrm;
+}
+
+Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( const Reference< XOutputStream >& rxOutStrm, const OUString& rEncoding )
+{
+ Reference< XTextOutputStream > xTextOutStrm;
+ if( rxOutStrm.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XActiveDataSource > xDataSource( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW );
+ xDataSource->setOutputStream( rxOutStrm );
+ xTextOutStrm.set( xDataSource, UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ if( xTextOutStrm.is() )
+ xTextOutStrm->setEncoding( rEncoding );
+ return xTextOutStrm;
+}
+
+Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream( const OUString& rFileName, const OUString& rEncoding )
+{
+ return openTextOutputStream( openOutputStream( rFileName ), rEncoding );
+}
+
+// ============================================================================
+// ============================================================================
+
+ItemFormat::ItemFormat() :
+ meDataType( DATATYPE_VOID ),
+ meFmtType( FORMATTYPE_NONE )
+{
+}
+
+void ItemFormat::set( DataType eDataType, FormatType eFmtType, const OUString& rItemName )
+{
+ meDataType = eDataType;
+ meFmtType = eFmtType;
+ maItemName = rItemName;
+ maListName = OUString();
+}
+
+void ItemFormat::set( DataType eDataType, FormatType eFmtType, const OUString& rItemName, const OUString& rListName )
+{
+ set( eDataType, eFmtType, rItemName );
+ maListName = rListName;
+}
+
+OUStringVector::const_iterator ItemFormat::parse( const OUStringVector& rFormatVec )
+{
+ set( DATATYPE_VOID, FORMATTYPE_NONE, OUString() );
+
+ OUStringVector::const_iterator aIt = rFormatVec.begin(), aEnd = rFormatVec.end();
+ OUString aDataType, aFmtType;
+ if( aIt != aEnd ) aDataType = *aIt++;
+ if( aIt != aEnd ) aFmtType = *aIt++;
+ if( aIt != aEnd ) maItemName = *aIt++;
+ if( aIt != aEnd ) maListName = *aIt++;
+
+ meDataType = StringHelper::convertToDataType( aDataType );
+ meFmtType = StringHelper::convertToFormatType( aFmtType );
+
+ if( meFmtType == FORMATTYPE_NONE )
+ {
+ if( aFmtType.equalsAscii( "unused" ) )
+ set( meDataType, FORMATTYPE_HEX, CREATE_OUSTRING( OOX_DUMP_UNUSED ) );
+ else if( aFmtType.equalsAscii( "unknown" ) )
+ set( meDataType, FORMATTYPE_HEX, CREATE_OUSTRING( OOX_DUMP_UNKNOWN ) );
+ }
+
+ return aIt;
+}
+
+OUStringVector ItemFormat::parse( const OUString& rFormatStr )
+{
+ OUStringVector aFormatVec;
+ StringHelper::convertStringToStringList( aFormatVec, rFormatStr, false );
+ OUStringVector::const_iterator aIt = parse( aFormatVec );
+ return OUStringVector( aIt, const_cast< const OUStringVector& >( aFormatVec ).end() );
+}
+
+// ============================================================================
+// ============================================================================
+
+// append string to string ----------------------------------------------------
+
+void StringHelper::appendChar( ::rtl::OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount )
+{
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ rStr.append( cChar );
+}
+
+void StringHelper::appendString( OUStringBuffer& rStr, const OUString& rData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendChar( rStr, cFill, nWidth - rData.getLength() );
+ rStr.append( rData );
+}
+
+// append decimal -------------------------------------------------------------
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt8 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::valueOf( static_cast< sal_Int32 >( nData ) ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int8 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::valueOf( static_cast< sal_Int32 >( nData ) ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt16 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::valueOf( static_cast< sal_Int32 >( nData ) ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int16 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::valueOf( static_cast< sal_Int32 >( nData ) ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt32 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::valueOf( static_cast< sal_Int64 >( nData ) ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int32 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::valueOf( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt64 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ /* Values greater than biggest signed 64bit integer will change to
+ negative when converting to sal_Int64. Therefore, the trailing digit
+ will be written separately. */
+ OUStringBuffer aBuffer;
+ if( nData > 9 )
+ aBuffer.append( OUString::valueOf( static_cast< sal_Int64 >( nData / 10 ) ) );
+ aBuffer.append( static_cast< sal_Unicode >( '0' + (nData % 10) ) );
+ appendString( rStr, aBuffer.makeStringAndClear(), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int64 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::valueOf( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, double fData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, ::rtl::math::doubleToUString( fData, rtl_math_StringFormat_G, 15, '.', true ), nWidth, cFill );
+}
+
+// append hexadecimal ---------------------------------------------------------
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
+{
+ static const sal_Unicode spcHexDigits[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
+ if( bPrefix )
+ rStr.appendAscii( "0x" );
+ rStr.append( spcHexDigits[ (nData >> 4) & 0x0F ] ).append( spcHexDigits[ nData & 0x0F ] );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bPrefix );
+ appendHex( rStr, static_cast< sal_uInt8 >( nData ), false );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bPrefix );
+ appendHex( rStr, static_cast< sal_uInt16 >( nData ), false );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bPrefix );
+ appendHex( rStr, static_cast< sal_uInt32 >( nData ), false );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, double fData, bool bPrefix )
+{
+ appendHex( rStr, *reinterpret_cast< const sal_uInt64* >( &fData ), bPrefix );
+}
+
+// append shortened hexadecimal -----------------------------------------------
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
+{
+ if( nData != 0 )
+ appendHex( rStr, nData, bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
+{
+ appendShortHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
+{
+ if( nData > 0xFF )
+ appendHex( rStr, nData, bPrefix );
+ else
+ appendShortHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
+{
+ appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
+{
+ if( nData > 0xFFFF )
+ appendHex( rStr, nData, bPrefix );
+ else
+ appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
+{
+ appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
+{
+ if( nData > 0xFFFFFFFF )
+ appendHex( rStr, nData, bPrefix );
+ else
+ appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
+{
+ appendShortHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
+}
+
+// append binary --------------------------------------------------------------
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt8 nData, bool bDots )
+{
+ for( sal_uInt8 nMask = 0x80; nMask != 0; (nMask >>= 1) &= 0x7F )
+ {
+ rStr.append( static_cast< sal_Unicode >( (nData & nMask) ? '1' : '0' ) );
+ if( bDots && (nMask == 0x10) )
+ rStr.append( OOX_DUMP_BINDOT );
+ }
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int8 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt16 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bDots );
+ if( bDots )
+ rStr.append( OOX_DUMP_BINDOT );
+ appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int16 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt32 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bDots );
+ if( bDots )
+ rStr.append( OOX_DUMP_BINDOT );
+ appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int32 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt64 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bDots );
+ if( bDots )
+ rStr.append( OOX_DUMP_BINDOT );
+ appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int64 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt64 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, double fData, bool bDots )
+{
+ appendBin( rStr, *reinterpret_cast< const sal_uInt64* >( &fData ), bDots );
+}
+
+// append formatted value -----------------------------------------------------
+
+void StringHelper::appendBool( OUStringBuffer& rStr, bool bData )
+{
+ rStr.appendAscii( bData ? "true" : "false" );
+}
+
+// append columns, rows, addresses --------------------------------------------
+
+void StringHelper::appendAddrCol( OUStringBuffer& rStr, sal_Int32 nCol, bool bRel )
+{
+ if( !bRel ) rStr.append( OOX_DUMP_ADDRABS );
+ sal_Int32 nPos = rStr.getLength();
+ for( sal_Int32 nTemp = nCol; nTemp >= 0; (nTemp /= 26) -= 1 )
+ rStr.insert( nPos, static_cast< sal_Unicode >( 'A' + (nTemp % 26) ) );
+}
+
+void StringHelper::appendAddrRow( OUStringBuffer& rStr, sal_Int32 nRow, bool bRel )
+{
+ if( !bRel ) rStr.append( OOX_DUMP_ADDRABS );
+ appendDec( rStr, nRow + 1 );
+}
+
+void StringHelper::appendAddrName( OUStringBuffer& rStr, sal_Unicode cPrefix, sal_Int32 nColRow, bool bRel )
+{
+ rStr.append( cPrefix );
+ if( bRel && (nColRow != 0) )
+ {
+ rStr.append( OOX_DUMP_R1C1OPEN );
+ appendDec( rStr, nColRow );
+ rStr.append( OOX_DUMP_R1C1CLOSE );
+ }
+ else if( !bRel )
+ appendDec( rStr, nColRow + 1 );
+}
+
+void StringHelper::appendAddress( OUStringBuffer& rStr, const Address& rPos )
+{
+ appendAddrCol( rStr, rPos.mnCol, true );
+ appendAddrRow( rStr, rPos.mnRow, true );
+}
+
+void StringHelper::appendRange( OUStringBuffer& rStr, const Range& rRange )
+{
+ appendAddress( rStr, rRange.maFirst );
+ rStr.append( OOX_DUMP_RANGESEP );
+ appendAddress( rStr, rRange.maLast );
+}
+
+void StringHelper::appendRangeList( OUStringBuffer& rStr, const RangeList& rRanges )
+{
+ OUStringBuffer aData;
+ for( RangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt )
+ {
+ OUStringBuffer aRange;
+ appendRange( aRange, *aIt );
+ appendToken( aData, aRange.makeStringAndClear(), OOX_DUMP_LISTSEP );
+ }
+ rStr.append( aData.makeStringAndClear() );
+}
+
+void StringHelper::appendAddress( OUStringBuffer& rStr, const TokenAddress& rPos, bool bR1C1 )
+{
+ if( bR1C1 && (rPos.mbRelCol || rPos.mbRelRow) )
+ {
+ appendAddrName( rStr, OOX_DUMP_R1C1ROW, rPos.mnRow, rPos.mbRelRow );
+ appendAddrName( rStr, OOX_DUMP_R1C1COL, rPos.mnCol, rPos.mbRelCol );
+ }
+ else
+ {
+ appendAddrCol( rStr, rPos.mnCol, rPos.mbRelCol );
+ appendAddrRow( rStr, rPos.mnRow, rPos.mbRelRow );
+ }
+}
+
+void StringHelper::appendRange( OUStringBuffer& rStr, const TokenRange& rRange, bool bR1C1 )
+{
+ appendAddress( rStr, rRange.maFirst, bR1C1 );
+ rStr.append( OOX_DUMP_RANGESEP );
+ appendAddress( rStr, rRange.maLast, bR1C1 );
+}
+
+// encoded text output --------------------------------------------------------
+
+void StringHelper::appendCChar( OUStringBuffer& rStr, sal_Unicode cChar, bool bPrefix )
+{
+ if( cChar > 0x00FF )
+ {
+ if( bPrefix )
+ rStr.appendAscii( "\\u" );
+ appendHex( rStr, static_cast< sal_uInt16 >( cChar ), false );
+ }
+ else
+ {
+ if( bPrefix )
+ rStr.appendAscii( "\\x" );
+ appendHex( rStr, static_cast< sal_uInt8 >( cChar ), false );
+ }
+}
+
+void StringHelper::appendEncChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount, bool bPrefix )
+{
+ if( cChar < 0x0020 )
+ {
+ // C-style hex code
+ OUStringBuffer aCode;
+ appendCChar( aCode, cChar, bPrefix );
+ for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
+ rStr.append( aCode );
+ }
+ else
+ {
+ appendChar( rStr, cChar, nCount );
+ }
+}
+
+void StringHelper::appendEncString( OUStringBuffer& rStr, const OUString& rData, bool bPrefix )
+{
+ sal_Int32 nBeg = 0;
+ sal_Int32 nIdx = 0;
+ sal_Int32 nEnd = rData.getLength();
+ while( nIdx < nEnd )
+ {
+ // find next character that needs encoding
+ while( (nIdx < nEnd) && (rData[ nIdx ] >= 0x20) ) ++nIdx;
+ // append portion
+ if( nBeg < nIdx )
+ {
+ if( (nBeg == 0) && (nIdx == nEnd) )
+ rStr.append( rData );
+ else
+ rStr.append( rData.copy( nBeg, nIdx - nBeg ) );
+ }
+ // append characters to be encoded
+ while( (nIdx < nEnd) && (rData[ nIdx ] < 0x20) )
+ {
+ appendCChar( rStr, rData[ nIdx ], bPrefix );
+ ++nIdx;
+ }
+ // adjust limits
+ nBeg = nIdx;
+ }
+}
+
+// token list -----------------------------------------------------------------
+
+void StringHelper::appendToken( OUStringBuffer& rStr, const OUString& rToken, sal_Unicode cSep )
+{
+ if( (rStr.getLength() > 0) && (rToken.getLength() > 0) )
+ rStr.append( cSep );
+ rStr.append( rToken );
+}
+
+void StringHelper::appendToken( OUStringBuffer& rStr, sal_Int64 nToken, sal_Unicode cSep )
+{
+ OUStringBuffer aToken;
+ appendDec( aToken, nToken );
+ appendToken( rStr, aToken.makeStringAndClear(), cSep );
+}
+
+void StringHelper::prependToken( OUStringBuffer& rStr, const OUString& rToken, sal_Unicode cSep )
+{
+ if( (rStr.getLength() > 0) && (rToken.getLength() > 0) )
+ rStr.insert( 0, cSep );
+ rStr.insert( 0, rToken );
+}
+
+void StringHelper::prependToken( OUStringBuffer& rStr, sal_Int64 nToken, sal_Unicode cSep )
+{
+ OUStringBuffer aToken;
+ appendDec( aToken, nToken );
+ prependToken( rStr, aToken.makeStringAndClear(), cSep );
+}
+
+void StringHelper::appendIndex( OUStringBuffer& rStr, const OUString& rIdx )
+{
+ rStr.append( sal_Unicode( '[' ) ).append( rIdx ).append( sal_Unicode( ']' ) );
+}
+
+void StringHelper::appendIndex( OUStringBuffer& rStr, sal_Int64 nIdx )
+{
+ OUStringBuffer aToken;
+ appendDec( aToken, nIdx );
+ appendIndex( rStr, aToken.makeStringAndClear() );
+}
+
+void StringHelper::appendIndexedText( OUStringBuffer& rStr, const OUString& rData, const OUString& rIdx )
+{
+ rStr.append( rData );
+ appendIndex( rStr, rIdx );
+}
+
+void StringHelper::appendIndexedText( OUStringBuffer& rStr, const OUString& rData, sal_Int64 nIdx )
+{
+ rStr.append( rData );
+ appendIndex( rStr, nIdx );
+}
+
+OUString StringHelper::getToken( const OUString& rData, sal_Int32& rnPos, sal_Unicode cSep )
+{
+ return trimSpaces( rData.getToken( 0, cSep, rnPos ) );
+}
+
+void StringHelper::enclose( OUStringBuffer& rStr, sal_Unicode cOpen, sal_Unicode cClose )
+{
+ rStr.insert( 0, cOpen ).append( cClose ? cClose : cOpen );
+}
+
+// string conversion ----------------------------------------------------------
+
+namespace {
+
+sal_Int32 lclIndexOf( const OUString& rStr, sal_Unicode cChar, sal_Int32 nStartPos )
+{
+ sal_Int32 nIndex = rStr.indexOf( cChar, nStartPos );
+ return (nIndex < 0) ? rStr.getLength() : nIndex;
+}
+
+OUString lclTrimQuotedStringList( const OUString& rStr )
+{
+ OUStringBuffer aBuffer;
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = rStr.getLength();
+ while( nPos < nLen )
+ {
+ if( rStr[ nPos ] == OOX_DUMP_CFG_QUOTE )
+ {
+ // quoted string, skip leading quote character
+ ++nPos;
+ // process quoted text and ambedded literal quote characters
+ OUStringBuffer aToken;
+ do
+ {
+ // seek to next quote character and add text portion to token buffer
+ sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_QUOTE, nPos );
+ aToken.append( rStr.copy( nPos, nEnd - nPos ) );
+ // process literal quotes
+ while( (nEnd + 1 < nLen) && (rStr[ nEnd ] == OOX_DUMP_CFG_QUOTE) && (rStr[ nEnd + 1 ] == OOX_DUMP_CFG_QUOTE) )
+ {
+ aToken.append( OOX_DUMP_CFG_QUOTE );
+ nEnd += 2;
+ }
+ // nEnd is start of possible next text portion
+ nPos = nEnd;
+ }
+ while( (nPos < nLen) && (rStr[ nPos ] != OOX_DUMP_CFG_QUOTE) );
+ // add token, seek to list separator, ignore text following closing quote
+ aBuffer.append( aToken.makeStringAndClear() );
+ nPos = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
+ if( nPos < nLen )
+ aBuffer.append( OOX_DUMP_LF );
+ // set current position behind list separator
+ ++nPos;
+ }
+ else
+ {
+ // find list separator, add token text to buffer
+ sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
+ aBuffer.append( rStr.copy( nPos, nEnd - nPos ) );
+ if( nEnd < nLen )
+ aBuffer.append( OOX_DUMP_LF );
+ // set current position behind list separator
+ nPos = nEnd + 1;
+ }
+ }
+
+ return aBuffer.makeStringAndClear();
+}
+
+} // namespace
+
+OUString StringHelper::trimSpaces( const OUString& rStr )
+{
+ sal_Int32 nBeg = 0;
+ while( (nBeg < rStr.getLength()) && ((rStr[ nBeg ] == ' ') || (rStr[ nBeg ] == '\t')) )
+ ++nBeg;
+ sal_Int32 nEnd = rStr.getLength();
+ while( (nEnd > nBeg) && ((rStr[ nEnd - 1 ] == ' ') || (rStr[ nEnd - 1 ] == '\t')) )
+ --nEnd;
+ return rStr.copy( nBeg, nEnd - nBeg );
+}
+
+OString StringHelper::convertToUtf8( const OUString& rStr )
+{
+ return ::rtl::OUStringToOString( rStr, RTL_TEXTENCODING_UTF8 );
+}
+
+DataType StringHelper::convertToDataType( const OUString& rStr )
+{
+ DataType eType = DATATYPE_VOID;
+ if( rStr.equalsAscii( "int8" ) )
+ eType = DATATYPE_INT8;
+ else if( rStr.equalsAscii( "uint8" ) )
+ eType = DATATYPE_UINT8;
+ else if( rStr.equalsAscii( "int16" ) )
+ eType = DATATYPE_INT16;
+ else if( rStr.equalsAscii( "uint16" ) )
+ eType = DATATYPE_UINT16;
+ else if( rStr.equalsAscii( "int32" ) )
+ eType = DATATYPE_INT32;
+ else if( rStr.equalsAscii( "uint32" ) )
+ eType = DATATYPE_UINT32;
+ else if( rStr.equalsAscii( "int64" ) )
+ eType = DATATYPE_INT64;
+ else if( rStr.equalsAscii( "uint64" ) )
+ eType = DATATYPE_UINT64;
+ else if( rStr.equalsAscii( "float" ) )
+ eType = DATATYPE_FLOAT;
+ else if( rStr.equalsAscii( "double" ) )
+ eType = DATATYPE_DOUBLE;
+ return eType;
+}
+
+FormatType StringHelper::convertToFormatType( const OUString& rStr )
+{
+ FormatType eType = FORMATTYPE_NONE;
+ if( rStr.equalsAscii( "dec" ) )
+ eType = FORMATTYPE_DEC;
+ else if( rStr.equalsAscii( "hex" ) )
+ eType = FORMATTYPE_HEX;
+ else if( rStr.equalsAscii( "bin" ) )
+ eType = FORMATTYPE_BIN;
+ else if( rStr.equalsAscii( "fix" ) )
+ eType = FORMATTYPE_FIX;
+ else if( rStr.equalsAscii( "bool" ) )
+ eType = FORMATTYPE_BOOL;
+ return eType;
+}
+
+bool StringHelper::convertFromDec( sal_Int64& ornData, const OUString& rData )
+{
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = rData.getLength();
+ bool bNeg = false;
+ if( (nLen > 0) && (rData[ 0 ] == '-') )
+ {
+ bNeg = true;
+ ++nPos;
+ }
+ ornData = 0;
+ for( ; nPos < nLen; ++nPos )
+ {
+ sal_Unicode cChar = rData[ nPos ];
+ if( (cChar < '0') || (cChar > '9') )
+ return false;
+ (ornData *= 10) += (cChar - '0');
+ }
+ if( bNeg )
+ ornData *= -1;
+ return true;
+}
+
+bool StringHelper::convertFromHex( sal_Int64& ornData, const OUString& rData )
+{
+ ornData = 0;
+ for( sal_Int32 nPos = 0, nLen = rData.getLength(); nPos < nLen; ++nPos )
+ {
+ sal_Unicode cChar = rData[ nPos ];
+ if( ('0' <= cChar) && (cChar <= '9') )
+ cChar -= '0';
+ else if( ('A' <= cChar) && (cChar <= 'F') )
+ cChar -= ('A' - 10);
+ else if( ('a' <= cChar) && (cChar <= 'f') )
+ cChar -= ('a' - 10);
+ else
+ return false;
+ (ornData <<= 4) += cChar;
+ }
+ return true;
+}
+
+bool StringHelper::convertStringToInt( sal_Int64& ornData, const OUString& rData )
+{
+ if( (rData.getLength() > 2) && (rData[ 0 ] == '0') && ((rData[ 1 ] == 'X') || (rData[ 1 ] == 'x')) )
+ return convertFromHex( ornData, rData.copy( 2 ) );
+ return convertFromDec( ornData, rData );
+}
+
+bool StringHelper::convertStringToDouble( double& orfData, const OUString& rData )
+{
+ rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
+ sal_Int32 nSize = 0;
+ orfData = rtl::math::stringToDouble( rData, '.', '\0', &eStatus, &nSize );
+ return (eStatus == rtl_math_ConversionStatus_Ok) && (nSize == rData.getLength());
+}
+
+bool StringHelper::convertStringToBool( const OUString& rData )
+{
+ if( rData.equalsAscii( "true" ) )
+ return true;
+ if( rData.equalsAscii( "false" ) )
+ return false;
+ sal_Int64 nData;
+ return convertStringToInt( nData, rData ) && (nData != 0);
+}
+
+void StringHelper::convertStringToStringList( OUStringVector& orVec, const OUString& rData, bool bIgnoreEmpty )
+{
+ orVec.clear();
+ OUString aUnquotedData = lclTrimQuotedStringList( rData );
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = aUnquotedData.getLength();
+ while( (0 <= nPos) && (nPos < nLen) )
+ {
+ OUString aToken = getToken( aUnquotedData, nPos, OOX_DUMP_LF );
+ if( !bIgnoreEmpty || (aToken.getLength() > 0) )
+ orVec.push_back( aToken );
+ }
+}
+
+void StringHelper::convertStringToIntList( Int64Vector& orVec, const OUString& rData, bool bIgnoreEmpty )
+{
+ orVec.clear();
+ OUString aUnquotedData = lclTrimQuotedStringList( rData );
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = aUnquotedData.getLength();
+ sal_Int64 nData;
+ while( (0 <= nPos) && (nPos < nLen) )
+ {
+ bool bOk = convertStringToInt( nData, getToken( aUnquotedData, nPos, OOX_DUMP_LF ) );
+ if( !bIgnoreEmpty || bOk )
+ orVec.push_back( bOk ? nData : 0 );
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+FormulaStack::FormulaStack() :
+ mbError( false )
+{
+}
+
+void FormulaStack::pushOperand( const StringWrapper& rOp, const OUString& rTokClass )
+{
+ maFmlaStack.push( rOp.getString() );
+ maClassStack.push( rTokClass );
+}
+
+void FormulaStack::pushOperand( const StringWrapper& rOp )
+{
+ pushOperand( rOp, OUString( OOX_DUMP_BASECLASS ) );
+}
+
+void FormulaStack::pushUnaryOp( const StringWrapper& rLOp, const StringWrapper& rROp )
+{
+ pushUnaryOp( maFmlaStack, rLOp.getString(), rROp.getString() );
+ pushUnaryOp( maClassStack, rLOp.getString(), rROp.getString() );
+}
+
+void FormulaStack::pushBinaryOp( const StringWrapper& rOp )
+{
+ pushBinaryOp( maFmlaStack, rOp.getString() );
+ pushBinaryOp( maClassStack, rOp.getString() );
+}
+
+void FormulaStack::pushFuncOp( const StringWrapper& rFunc, const OUString& rTokClass, sal_uInt8 nParamCount )
+{
+ pushFuncOp( maFmlaStack, rFunc.getString(), nParamCount );
+ pushFuncOp( maClassStack, rTokClass, nParamCount );
+}
+
+void FormulaStack::replaceOnTop( const OUString& rOld, const OUString& rNew )
+{
+ if( !maFmlaStack.empty() )
+ {
+ sal_Int32 nPos = maFmlaStack.top().indexOf( rOld );
+ if( nPos >= 0 )
+ maFmlaStack.top() = maFmlaStack.top().copy( 0, nPos ) + rNew + maFmlaStack.top().copy( nPos + rOld.getLength() );
+ }
+}
+
+const OUString& FormulaStack::getString( const StringStack& rStack ) const
+{
+ static const OUString saStackError = OOX_DUMP_ERRSTRING( "stack" );
+ return (mbError || rStack.empty()) ? saStackError : rStack.top();
+}
+
+void FormulaStack::pushUnaryOp( StringStack& rStack, const OUString& rLOp, const OUString& rROp )
+{
+ if( check( !rStack.empty() ) )
+ rStack.top() = rLOp + rStack.top() + rROp;
+}
+
+void FormulaStack::pushBinaryOp( StringStack& rStack, const OUString& rOp )
+{
+ OUString aSecond;
+ if( check( !rStack.empty() ) )
+ {
+ aSecond = rStack.top();
+ rStack.pop();
+ }
+ if( check( !rStack.empty() ) )
+ rStack.top() = rStack.top() + rOp + aSecond;
+}
+
+void FormulaStack::pushFuncOp( StringStack& rStack, const OUString& rOp, sal_uInt8 nParamCount )
+{
+ OUStringBuffer aFunc;
+ for( sal_uInt8 nParam = 0; (nParam < nParamCount) && check( !rStack.empty() ); ++nParam )
+ {
+ StringHelper::prependToken( aFunc, rStack.top(), OOX_DUMP_FUNCSEP );
+ rStack.pop();
+ }
+ StringHelper::enclose( aFunc, '(', ')' );
+ aFunc.insert( 0, rOp );
+ rStack.push( aFunc.makeStringAndClear() );
+}
+
+// ============================================================================
+// ============================================================================
+
+Base::~Base()
+{
+}
+
+// ============================================================================
+// ============================================================================
+
+ConfigItemBase::~ConfigItemBase()
+{
+}
+
+void ConfigItemBase::readConfigBlock( const ConfigInputStreamRef& rxStrm )
+{
+ readConfigBlockContents( rxStrm );
+}
+
+void ConfigItemBase::implProcessConfigItemStr(
+ const ConfigInputStreamRef& /*rxStrm*/, const OUString& /*rKey*/, const OUString& /*rData*/ )
+{
+}
+
+void ConfigItemBase::implProcessConfigItemInt(
+ const ConfigInputStreamRef& /*rxStrm*/, sal_Int64 /*nKey*/, const OUString& /*rData*/ )
+{
+}
+
+void ConfigItemBase::readConfigBlockContents( const ConfigInputStreamRef& rxStrm )
+{
+ bool bLoop = true;
+ while( bLoop && !rxStrm->isEOF() )
+ {
+ OUString aKey, aData;
+ switch( readConfigLine( rxStrm, aKey, aData ) )
+ {
+ case LINETYPE_DATA:
+ processConfigItem( rxStrm, aKey, aData );
+ break;
+ case LINETYPE_END:
+ bLoop = false;
+ break;
+ }
+ }
+}
+
+ConfigItemBase::LineType ConfigItemBase::readConfigLine(
+ const ConfigInputStreamRef& rxStrm, OUString& orKey, OUString& orData ) const
+{
+ OUString aLine;
+ while( !rxStrm->isEOF() && (aLine.getLength() == 0) )
+ {
+ try { aLine = rxStrm->readLine(); } catch( Exception& ) { aLine = OUString(); }
+ if( (aLine.getLength() > 0) && (aLine[ 0 ] == OOX_DUMP_BOM) )
+ aLine = aLine.copy( 1 );
+ aLine = StringHelper::trimSpaces( aLine );
+ if( aLine.getLength() > 0 )
+ {
+ // ignore comments (starting with hash or semicolon)
+ sal_Unicode cChar = aLine[ 0 ];
+ if( (cChar == '#') || (cChar == ';') )
+ aLine = OUString();
+ }
+ }
+
+ LineType eResult = LINETYPE_END;
+ if( aLine.getLength() > 0 )
+ {
+ sal_Int32 nEqPos = aLine.indexOf( '=' );
+ if( nEqPos < 0 )
+ {
+ orKey = aLine;
+ }
+ else
+ {
+ orKey = StringHelper::trimSpaces( aLine.copy( 0, nEqPos ) );
+ orData = StringHelper::trimSpaces( aLine.copy( nEqPos + 1 ) );
+ }
+
+ if( (orKey.getLength() > 0) && ((orData.getLength() > 0) || !orKey.equalsAscii( "end" )) )
+ eResult = LINETYPE_DATA;
+ }
+
+ return eResult;
+}
+
+ConfigItemBase::LineType ConfigItemBase::readConfigLine( const ConfigInputStreamRef& rxStrm ) const
+{
+ OUString aKey, aData;
+ return readConfigLine( rxStrm, aKey, aData );
+}
+
+void ConfigItemBase::processConfigItem(
+ const ConfigInputStreamRef& rxStrm, const OUString& rKey, const OUString& rData )
+{
+ sal_Int64 nKey;
+ if( StringHelper::convertStringToInt( nKey, rKey ) )
+ implProcessConfigItemInt( rxStrm, nKey, rData );
+ else
+ implProcessConfigItemStr( rxStrm, rKey, rData );
+}
+
+// ============================================================================
+
+NameListBase::~NameListBase()
+{
+}
+
+void NameListBase::setName( sal_Int64 nKey, const StringWrapper& rNameWrp )
+{
+ implSetName( nKey, rNameWrp.getString() );
+}
+
+void NameListBase::includeList( NameListRef xList )
+{
+ if( xList.get() )
+ {
+ for( const_iterator aIt = xList->begin(), aEnd = xList->end(); aIt != aEnd; ++aIt )
+ maMap[ aIt->first ] = aIt->second;
+ implIncludeList( *xList );
+ }
+}
+
+bool NameListBase::implIsValid() const
+{
+ return true;
+}
+
+void NameListBase::implProcessConfigItemStr(
+ const ConfigInputStreamRef& rxStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "include" ) )
+ include( rData );
+ else if( rKey.equalsAscii( "exclude" ) )
+ exclude( rData );
+ else
+ ConfigItemBase::implProcessConfigItemStr( rxStrm, rKey, rData );
+}
+
+void NameListBase::implProcessConfigItemInt(
+ const ConfigInputStreamRef& /*rxStrm*/, sal_Int64 nKey, const OUString& rData )
+{
+ implSetName( nKey, rData );
+}
+
+void NameListBase::insertRawName( sal_Int64 nKey, const OUString& rName )
+{
+ maMap[ nKey ] = rName;
+}
+
+const OUString* NameListBase::findRawName( sal_Int64 nKey ) const
+{
+ const_iterator aIt = maMap.find( nKey );
+ return (aIt == end()) ? 0 : &aIt->second;
+}
+
+void NameListBase::include( const OUString& rListKeys )
+{
+ OUStringVector aVec;
+ StringHelper::convertStringToStringList( aVec, rListKeys, true );
+ for( OUStringVector::const_iterator aIt = aVec.begin(), aEnd = aVec.end(); aIt != aEnd; ++aIt )
+ includeList( mrCfgData.getNameList( *aIt ) );
+}
+
+void NameListBase::exclude( const OUString& rKeys )
+{
+ Int64Vector aVec;
+ StringHelper::convertStringToIntList( aVec, rKeys, true );
+ for( Int64Vector::const_iterator aIt = aVec.begin(), aEnd = aVec.end(); aIt != aEnd; ++aIt )
+ maMap.erase( *aIt );
+}
+
+// ============================================================================
+
+ConstList::ConstList( const SharedConfigData& rCfgData ) :
+ NameListBase( rCfgData ),
+ maDefName( OOX_DUMP_ERR_NONAME ),
+ mbQuoteNames( false )
+{
+}
+
+void ConstList::implProcessConfigItemStr(
+ const ConfigInputStreamRef& rxStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "default" ) )
+ setDefaultName( rData );
+ else if( rKey.equalsAscii( "quote-names" ) )
+ setQuoteNames( StringHelper::convertStringToBool( rData ) );
+ else
+ NameListBase::implProcessConfigItemStr( rxStrm, rKey, rData );
+}
+
+void ConstList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ insertRawName( nKey, rName );
+}
+
+OUString ConstList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
+{
+ const OUString* pName = findRawName( nKey );
+ OUString aName = pName ? *pName : maDefName;
+ if( mbQuoteNames )
+ {
+ OUStringBuffer aBuffer( aName );
+ StringHelper::enclose( aBuffer, OOX_DUMP_STRQUOTE );
+ aName = aBuffer.makeStringAndClear();
+ }
+ return aName;
+}
+
+OUString ConstList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
+{
+ return OUString();
+}
+
+void ConstList::implIncludeList( const NameListBase& rList )
+{
+ if( const ConstList* pConstList = dynamic_cast< const ConstList* >( &rList ) )
+ {
+ maDefName = pConstList->maDefName;
+ mbQuoteNames = pConstList->mbQuoteNames;
+ }
+}
+
+// ============================================================================
+
+MultiList::MultiList( const SharedConfigData& rCfgData ) :
+ ConstList( rCfgData ),
+ mbIgnoreEmpty( true )
+{
+}
+
+void MultiList::setNamesFromVec( sal_Int64 nStartKey, const OUStringVector& rNames )
+{
+ sal_Int64 nKey = nStartKey;
+ for( OUStringVector::const_iterator aIt = rNames.begin(), aEnd = rNames.end(); aIt != aEnd; ++aIt, ++nKey )
+ if( !mbIgnoreEmpty || (aIt->getLength() > 0) )
+ insertRawName( nKey, *aIt );
+}
+
+void MultiList::implProcessConfigItemStr(
+ const ConfigInputStreamRef& rxStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "ignore-empty" ) )
+ mbIgnoreEmpty = StringHelper::convertStringToBool( rData );
+ else
+ ConstList::implProcessConfigItemStr( rxStrm, rKey, rData );
+}
+
+void MultiList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ OUStringVector aNames;
+ StringHelper::convertStringToStringList( aNames, rName, false );
+ setNamesFromVec( nKey, aNames );
+}
+
+// ============================================================================
+
+FlagsList::FlagsList( const SharedConfigData& rCfgData ) :
+ NameListBase( rCfgData ),
+ mnIgnore( 0 )
+{
+}
+
+void FlagsList::implProcessConfigItemStr(
+ const ConfigInputStreamRef& rxStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "ignore" ) )
+ {
+ sal_Int64 nIgnore;
+ if( StringHelper::convertStringToInt( nIgnore, rData ) )
+ setIgnoreFlags( nIgnore );
+ }
+ else
+ {
+ NameListBase::implProcessConfigItemStr( rxStrm, rKey, rData );
+ }
+}
+
+void FlagsList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ insertRawName( nKey, rName );
+}
+
+OUString FlagsList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
+{
+ sal_Int64 nFlags = nKey;
+ setFlag( nFlags, mnIgnore, false );
+ sal_Int64 nFound = 0;
+ OUStringBuffer aName;
+ // add known flags
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ {
+ sal_Int64 nMask = aIt->first;
+ const OUString& rFlagName = aIt->second;
+ bool bNegated = (rFlagName.getLength() > 0) && (rFlagName[ 0 ] == '!');
+ if( getFlag( nFlags, nMask ) != bNegated )
+ StringHelper::appendToken( aName, bNegated ? rFlagName.copy( 1 ) : rFlagName );
+ setFlag( nFound, nMask );
+ }
+ // add unknown flags
+ setFlag( nFlags, nFound, false );
+ if( nFlags != 0 )
+ {
+ OUStringBuffer aUnknown( CREATE_OUSTRING( OOX_DUMP_UNKNOWN ) );
+ aUnknown.append( OOX_DUMP_ITEMSEP );
+ StringHelper::appendShortHex( aUnknown, nFlags, true );
+ StringHelper::enclose( aUnknown, '(', ')' );
+ StringHelper::appendToken( aName, aUnknown.makeStringAndClear() );
+ }
+ return aName.makeStringAndClear();
+}
+
+OUString FlagsList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
+{
+ return OUString();
+}
+
+void FlagsList::implIncludeList( const NameListBase& rList )
+{
+ if( const FlagsList* pFlagsList = dynamic_cast< const FlagsList* >( &rList ) )
+ mnIgnore = pFlagsList->mnIgnore;
+}
+
+// ============================================================================
+
+CombiList::CombiList( const SharedConfigData& rCfgData ) :
+ FlagsList( rCfgData )
+{
+}
+
+void CombiList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ if( (nKey & (nKey - 1)) != 0 ) // more than a single bit set?
+ {
+ ExtItemFormat& rItemFmt = maFmtMap[ nKey ];
+ OUStringVector aRemain = rItemFmt.parse( rName );
+ rItemFmt.mbShiftValue = aRemain.empty() || !aRemain.front().equalsAscii( "noshift" );
+ }
+ else
+ {
+ FlagsList::implSetName( nKey, rName );
+ }
+}
+
+OUString CombiList::implGetName( const Config& rCfg, sal_Int64 nKey ) const
+{
+ sal_Int64 nFlags = nKey;
+ sal_Int64 nFound = 0;
+ OUStringBuffer aName;
+ // add known flag fields
+ for( ExtItemFormatMap::const_iterator aIt = maFmtMap.begin(), aEnd = maFmtMap.end(); aIt != aEnd; ++aIt )
+ {
+ sal_Int64 nMask = aIt->first;
+ if( nMask != 0 )
+ {
+ const ExtItemFormat& rItemFmt = aIt->second;
+
+ sal_uInt64 nUFlags = static_cast< sal_uInt64 >( nFlags );
+ sal_uInt64 nUMask = static_cast< sal_uInt64 >( nMask );
+ if( rItemFmt.mbShiftValue )
+ while( (nUMask & 1) == 0 ) { nUFlags >>= 1; nUMask >>= 1; }
+
+ sal_uInt64 nUValue = nUFlags & nUMask;
+ sal_Int64 nSValue = static_cast< sal_Int64 >( nUValue );
+ if( getFlag< sal_uInt64 >( nUValue, (nUMask + 1) >> 1 ) )
+ setFlag( nSValue, static_cast< sal_Int64 >( ~nUMask ) );
+
+ OUStringBuffer aItem( rItemFmt.maItemName );
+ OUStringBuffer aValue;
+ switch( rItemFmt.meDataType )
+ {
+ case DATATYPE_INT8: StringHelper::appendValue( aValue, static_cast< sal_Int8 >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT8: StringHelper::appendValue( aValue, static_cast< sal_uInt8 >( nUValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_INT16: StringHelper::appendValue( aValue, static_cast< sal_Int16 >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT16: StringHelper::appendValue( aValue, static_cast< sal_uInt16 >( nUValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_INT32: StringHelper::appendValue( aValue, static_cast< sal_Int32 >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT32: StringHelper::appendValue( aValue, static_cast< sal_uInt32 >( nUValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_INT64: StringHelper::appendValue( aValue, nSValue, rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT64: StringHelper::appendValue( aValue, nUValue, rItemFmt.meFmtType ); break;
+ case DATATYPE_FLOAT: StringHelper::appendValue( aValue, static_cast< float >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_DOUBLE: StringHelper::appendValue( aValue, static_cast< double >( nSValue ), rItemFmt.meFmtType ); break;
+ default:;
+ }
+ StringHelper::appendToken( aItem, aValue.makeStringAndClear(), OOX_DUMP_ITEMSEP );
+ if( rItemFmt.maListName.getLength() > 0 )
+ {
+ OUString aValueName = rCfg.getName( rItemFmt.maListName, static_cast< sal_Int64 >( nUValue ) );
+ StringHelper::appendToken( aItem, aValueName, OOX_DUMP_ITEMSEP );
+ }
+ StringHelper::enclose( aItem, '(', ')' );
+ StringHelper::appendToken( aName, aItem.makeStringAndClear() );
+ setFlag( nFound, nMask );
+ }
+ }
+ setFlag( nFlags, nFound, false );
+ StringHelper::appendToken( aName, FlagsList::implGetName( rCfg, nFlags ) );
+ return aName.makeStringAndClear();
+}
+
+void CombiList::implIncludeList( const NameListBase& rList )
+{
+ if( const CombiList* pCombiList = dynamic_cast< const CombiList* >( &rList ) )
+ maFmtMap = pCombiList->maFmtMap;
+ FlagsList::implIncludeList( rList );
+}
+
+// ============================================================================
+
+UnitConverter::UnitConverter( const SharedConfigData& rCfgData ) :
+ NameListBase( rCfgData ),
+ mfFactor( 1.0 )
+{
+}
+
+void UnitConverter::implSetName( sal_Int64 /*nKey*/, const OUString& /*rName*/ )
+{
+ // nothing to do
+}
+
+OUString UnitConverter::implGetName( const Config& rCfg, sal_Int64 nKey ) const
+{
+ return implGetNameDbl( rCfg, static_cast< double >( nKey ) );
+}
+
+OUString UnitConverter::implGetNameDbl( const Config& /*rCfg*/, double fValue ) const
+{
+ OUStringBuffer aValue;
+ StringHelper::appendDec( aValue, mfFactor * fValue );
+ aValue.append( maUnitName );
+ return aValue.makeStringAndClear();
+}
+
+void UnitConverter::implIncludeList( const NameListBase& /*rList*/ )
+{
+}
+
+// ============================================================================
+
+NameListRef NameListWrapper::getNameList( const Config& rCfg ) const
+{
+ return mxList.get() ? mxList : (mxList = rCfg.getNameList( maNameWrp.getString() ));
+}
+
+// ============================================================================
+// ============================================================================
+
+SharedConfigData::SharedConfigData( const OUString& rFileName )
+{
+ construct( rFileName );
+}
+
+SharedConfigData::~SharedConfigData()
+{
+}
+
+void SharedConfigData::construct( const OUString& rFileName )
+{
+ mbLoaded = false;
+ OUString aFileUrl = InputOutputHelper::convertFileNameToUrl( rFileName );
+ if( aFileUrl.getLength() > 0 )
+ {
+ sal_Int32 nNamePos = InputOutputHelper::getFileNamePos( aFileUrl );
+ maConfigPath = aFileUrl.copy( 0, nNamePos );
+ mbLoaded = readConfigFile( aFileUrl );
+ }
+}
+
+void SharedConfigData::setOption( const OUString& rKey, const OUString& rData )
+{
+ maConfigData[ rKey ] = rData;
+}
+
+const OUString* SharedConfigData::getOption( const OUString& rKey ) const
+{
+ ConfigDataMap::const_iterator aIt = maConfigData.find( rKey );
+ return (aIt == maConfigData.end()) ? 0 : &aIt->second;
+}
+
+void SharedConfigData::setNameList( const OUString& rListName, NameListRef xList )
+{
+ if( rListName.getLength() > 0 )
+ maNameLists[ rListName ] = xList;
+}
+
+void SharedConfigData::eraseNameList( const OUString& rListName )
+{
+ maNameLists.erase( rListName );
+}
+
+NameListRef SharedConfigData::getNameList( const OUString& rListName ) const
+{
+ NameListRef xList;
+ NameListMap::const_iterator aIt = maNameLists.find( rListName );
+ if( aIt != maNameLists.end() )
+ xList = aIt->second;
+ return xList;
+}
+
+bool SharedConfigData::implIsValid() const
+{
+ return mbLoaded;
+}
+
+void SharedConfigData::implProcessConfigItemStr(
+ const ConfigInputStreamRef& rxStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "include-config-file" ) )
+ readConfigFile( maConfigPath + rData );
+ else if( rKey.equalsAscii( "constlist" ) )
+ readNameList< ConstList >( rxStrm, rData );
+ else if( rKey.equalsAscii( "multilist" ) )
+ readNameList< MultiList >( rxStrm, rData );
+ else if( rKey.equalsAscii( "flagslist" ) )
+ readNameList< FlagsList >( rxStrm, rData );
+ else if( rKey.equalsAscii( "combilist" ) )
+ readNameList< CombiList >( rxStrm, rData );
+ else if( rKey.equalsAscii( "shortlist" ) )
+ createShortList( rData );
+ else if( rKey.equalsAscii( "unitconverter" ) )
+ createUnitConverter( rData );
+ else
+ setOption( rKey, rData );
+}
+
+bool SharedConfigData::readConfigFile( const OUString& rFileUrl )
+{
+ bool bLoaded = false;
+ Reference< XTextInputStream > xTextInStrm =
+ InputOutputHelper::openTextInputStream( rFileUrl, CREATE_OUSTRING( "UTF-8" ) );
+ if( xTextInStrm.is() )
+ {
+ readConfigBlockContents( xTextInStrm );
+ bLoaded = true;
+ }
+ return bLoaded;
+}
+
+void SharedConfigData::createShortList( const OUString& rData )
+{
+ OUStringVector aDataVec;
+ StringHelper::convertStringToStringList( aDataVec, rData, false );
+ if( aDataVec.size() >= 3 )
+ {
+ sal_Int64 nStartKey;
+ if( StringHelper::convertStringToInt( nStartKey, aDataVec[ 1 ] ) )
+ {
+ ::boost::shared_ptr< MultiList > xList = createNameList< MultiList >( aDataVec[ 0 ] );
+ if( xList.get() )
+ {
+ aDataVec.erase( aDataVec.begin(), aDataVec.begin() + 2 );
+ xList->setNamesFromVec( nStartKey, aDataVec );
+ }
+ }
+ }
+}
+
+void SharedConfigData::createUnitConverter( const OUString& rData )
+{
+ OUStringVector aDataVec;
+ StringHelper::convertStringToStringList( aDataVec, rData, false );
+ if( aDataVec.size() >= 2 )
+ {
+ OUString aFactor = aDataVec[ 1 ];
+ bool bRecip = (aFactor.getLength() > 0) && (aFactor[ 0 ] == '/');
+ if( bRecip )
+ aFactor = aFactor.copy( 1 );
+ double fFactor;
+ if( StringHelper::convertStringToDouble( fFactor, aFactor ) && (fFactor != 0.0) )
+ {
+ ::boost::shared_ptr< UnitConverter > xList = createNameList< UnitConverter >( aDataVec[ 0 ] );
+ if( xList.get() )
+ {
+ xList->setFactor( bRecip ? (1.0 / fFactor) : fFactor );
+ if( aDataVec.size() >= 3 )
+ xList->setUnitName( aDataVec[ 2 ] );
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+Config::Config( const Config& rParent ) :
+ Base() // c'tor needs to be called explicitly to avoid compiler warning
+{
+ construct( rParent );
+}
+
+Config::Config( const OUString& rFileName )
+{
+ construct( rFileName );
+}
+
+Config::Config( const sal_Char* pcEnvVar )
+{
+ construct( pcEnvVar );
+}
+
+Config::~Config()
+{
+}
+
+void Config::construct( const Config& rParent )
+{
+ *this = rParent;
+}
+
+void Config::construct( const OUString& rFileName )
+{
+ mxCfgData.reset( new SharedConfigData( rFileName ) );
+}
+
+void Config::construct( const sal_Char* pcEnvVar )
+{
+ if( pcEnvVar )
+ if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) )
+ construct( OUString::createFromAscii( pcFileName ) );
+}
+
+void Config::setStringOption( const StringWrapper& rKey, const StringWrapper& rData )
+{
+ mxCfgData->setOption( rKey.getString(), rData.getString() );
+}
+
+const OUString& Config::getStringOption( const StringWrapper& rKey, const OUString& rDefault ) const
+{
+ const OUString* pData = implGetOption( rKey.getString() );
+ return pData ? *pData : rDefault;
+}
+
+bool Config::getBoolOption( const StringWrapper& rKey, bool bDefault ) const
+{
+ const OUString* pData = implGetOption( rKey.getString() );
+ return pData ? StringHelper::convertStringToBool( *pData ) : bDefault;
+}
+
+bool Config::isDumperEnabled() const
+{
+ return getBoolOption( "enable-dumper", false );
+}
+
+bool Config::isImportEnabled() const
+{
+ return getBoolOption( "enable-import", true );
+}
+
+void Config::setNameList( const StringWrapper& rListName, NameListRef xList )
+{
+ mxCfgData->setNameList( rListName.getString(), xList );
+}
+
+void Config::eraseNameList( const StringWrapper& rListName )
+{
+ mxCfgData->eraseNameList( rListName.getString() );
+}
+
+NameListRef Config::getNameList( const StringWrapper& rListName ) const
+{
+ return implGetNameList( rListName.getString() );
+}
+
+bool Config::implIsValid() const
+{
+ return isValid( mxCfgData );
+}
+
+const OUString* Config::implGetOption( const OUString& rKey ) const
+{
+ return mxCfgData->getOption( rKey );
+}
+
+NameListRef Config::implGetNameList( const OUString& rListName ) const
+{
+ return mxCfgData->getNameList( rListName );
+}
+
+// ============================================================================
+// ============================================================================
+
+bool Input::implIsValid() const
+{
+ return true;
+}
+
+Input& operator>>( Input& rIn, sal_Int64& rnData )
+{
+ return rIn >> *reinterpret_cast< double* >( &rnData );
+}
+
+Input& operator>>( Input& rIn, sal_uInt64& rnData )
+{
+ return rIn >> *reinterpret_cast< double* >( &rnData );
+}
+
+// ============================================================================
+
+BinaryInput::BinaryInput( BinaryInputStream& rStrm ) :
+ mrStrm( rStrm )
+{
+}
+
+sal_Int64 BinaryInput::getSize() const
+{
+ return mrStrm.getLength();
+}
+
+sal_Int64 BinaryInput::tell() const
+{
+ return mrStrm.tell();
+}
+
+void BinaryInput::seek( sal_Int64 nPos )
+{
+ mrStrm.seek( nPos );
+}
+
+void BinaryInput::skip( sal_Int32 nBytes )
+{
+ mrStrm.skip( nBytes );
+}
+
+sal_Int32 BinaryInput::read( void* pBuffer, sal_Int32 nBytes )
+{
+ return mrStrm.read( pBuffer, nBytes );
+}
+
+bool BinaryInput::implIsValid() const
+{
+ return mrStrm.is() && Input::implIsValid();
+}
+
+BinaryInput& BinaryInput::operator>>( sal_Int8& rnData ) { mrStrm >> rnData; return *this; }
+BinaryInput& BinaryInput::operator>>( sal_uInt8& rnData ) { mrStrm >> rnData; return *this; }
+BinaryInput& BinaryInput::operator>>( sal_Int16& rnData ) { mrStrm >> rnData; return *this; }
+BinaryInput& BinaryInput::operator>>( sal_uInt16& rnData ) { mrStrm >> rnData; return *this; }
+BinaryInput& BinaryInput::operator>>( sal_Int32& rnData ) { mrStrm >> rnData; return *this; }
+BinaryInput& BinaryInput::operator>>( sal_uInt32& rnData ) { mrStrm >> rnData; return *this; }
+BinaryInput& BinaryInput::operator>>( float& rfData ) { mrStrm >> rfData; return *this; }
+BinaryInput& BinaryInput::operator>>( double& rfData ) { mrStrm >> rfData; return *this; }
+
+// ============================================================================
+// ============================================================================
+
+Output::Output( const Reference< XTextOutputStream >& rxStrm )
+{
+ construct( rxStrm );
+}
+
+Output::Output( const ::rtl::OUString& rFileName )
+{
+ construct( InputOutputHelper::openTextOutputStream( rFileName, CREATE_OUSTRING( "UTF-8" ) ) );
+}
+
+// ----------------------------------------------------------------------------
+
+void Output::newLine()
+{
+ if( maLine.getLength() > 0 )
+ {
+ mxStrm->writeString( maIndent );
+ maLine.append( sal_Unicode( '\n' ) );
+ mxStrm->writeString( maLine.makeStringAndClear() );
+ mnCol = 0;
+ mnLastItem = 0;
+ }
+}
+
+void Output::emptyLine( size_t nCount )
+{
+ for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
+ mxStrm->writeString( OUString( sal_Unicode( '\n' ) ) );
+}
+
+void Output::incIndent()
+{
+ OUStringBuffer aBuffer( maIndent );
+ StringHelper::appendChar( aBuffer, ' ', OOX_DUMP_INDENT );
+ maIndent = aBuffer.makeStringAndClear();
+}
+
+void Output::decIndent()
+{
+ if( maIndent.getLength() >= OOX_DUMP_INDENT )
+ maIndent = maIndent.copy( OOX_DUMP_INDENT );
+}
+
+void Output::resetIndent()
+{
+ maIndent = OUString();
+}
+
+void Output::startTable( sal_Int32 nW1 )
+{
+ startTable( 1, &nW1 );
+}
+
+void Output::startTable( sal_Int32 nW1, sal_Int32 nW2 )
+{
+ sal_Int32 pnColWidths[ 2 ];
+ pnColWidths[ 0 ] = nW1;
+ pnColWidths[ 1 ] = nW2;
+ startTable( 2, pnColWidths );
+}
+
+void Output::startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3 )
+{
+ sal_Int32 pnColWidths[ 3 ];
+ pnColWidths[ 0 ] = nW1;
+ pnColWidths[ 1 ] = nW2;
+ pnColWidths[ 2 ] = nW3;
+ startTable( 3, pnColWidths );
+}
+
+void Output::startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 )
+{
+ sal_Int32 pnColWidths[ 4 ];
+ pnColWidths[ 0 ] = nW1;
+ pnColWidths[ 1 ] = nW2;
+ pnColWidths[ 2 ] = nW3;
+ pnColWidths[ 3 ] = nW4;
+ startTable( 4, pnColWidths );
+}
+
+void Output::startTable( size_t nColCount, const sal_Int32* pnColWidths )
+{
+ maColPos.clear();
+ maColPos.push_back( 0 );
+ sal_Int32 nColPos = 0;
+ for( size_t nCol = 0; nCol < nColCount; ++nCol )
+ {
+ nColPos = nColPos + pnColWidths[ nCol ];
+ maColPos.push_back( nColPos );
+ }
+}
+
+void Output::tab()
+{
+ tab( mnCol + 1 );
+}
+
+void Output::tab( size_t nCol )
+{
+ mnCol = nCol;
+ if( mnCol < maColPos.size() )
+ {
+ sal_Int32 nColPos = maColPos[ mnCol ];
+ if( maLine.getLength() >= nColPos )
+ maLine.setLength( ::std::max< sal_Int32 >( nColPos - 1, 0 ) );
+ StringHelper::appendChar( maLine, ' ', nColPos - maLine.getLength() );
+ }
+ else
+ {
+ StringHelper::appendChar( maLine, ' ', 2 );
+ }
+}
+
+void Output::endTable()
+{
+ maColPos.clear();
+}
+
+void Output::resetItemIndex( sal_Int64 nIdx )
+{
+ mnItemIdx = nIdx;
+}
+
+void Output::startItem( const sal_Char* pcName )
+{
+ if( mnItemLevel == 0 )
+ {
+ if( (mnMultiLevel > 0) && (maLine.getLength() > 0) )
+ tab();
+ if( pcName )
+ {
+ writeItemName( pcName );
+ writeChar( OOX_DUMP_ITEMSEP );
+ }
+ }
+ ++mnItemLevel;
+ mnLastItem = maLine.getLength();
+}
+
+void Output::contItem()
+{
+ if( mnItemLevel > 0 )
+ {
+ if( (maLine.getLength() == 0) || (maLine[ maLine.getLength() - 1 ] != OOX_DUMP_ITEMSEP) )
+ writeChar( OOX_DUMP_ITEMSEP );
+ mnLastItem = maLine.getLength();
+ }
+}
+
+void Output::endItem()
+{
+ if( mnItemLevel > 0 )
+ {
+ maLastItem = OUString( maLine.getStr() + mnLastItem );
+ if( (maLastItem.getLength() == 0) && (mnLastItem > 0) && (maLine[ mnLastItem - 1 ] == OOX_DUMP_ITEMSEP) )
+ maLine.setLength( mnLastItem - 1 );
+ --mnItemLevel;
+ }
+ if( mnItemLevel == 0 )
+ {
+ if( mnMultiLevel == 0 )
+ newLine();
+ }
+ else
+ contItem();
+}
+
+void Output::startMultiItems()
+{
+ ++mnMultiLevel;
+}
+
+void Output::endMultiItems()
+{
+ if( mnMultiLevel > 0 )
+ --mnMultiLevel;
+ if( mnMultiLevel == 0 )
+ newLine();
+}
+
+// ----------------------------------------------------------------------------
+
+void Output::writeChar( sal_Unicode cChar, sal_Int32 nCount )
+{
+ StringHelper::appendEncChar( maLine, cChar, nCount );
+}
+
+void Output::writeAscii( const sal_Char* pcStr )
+{
+ if( pcStr )
+ maLine.appendAscii( pcStr );
+}
+
+void Output::writeString( const OUString& rStr )
+{
+ StringHelper::appendEncString( maLine, rStr );
+}
+
+void Output::writeArray( const sal_uInt8* pnData, sal_Size nSize, sal_Unicode cSep )
+{
+ const sal_uInt8* pnEnd = pnData ? (pnData + nSize) : 0;
+ for( const sal_uInt8* pnByte = pnData; pnByte < pnEnd; ++pnByte )
+ {
+ if( pnByte > pnData )
+ writeChar( cSep );
+ writeHex( *pnByte, false );
+ }
+}
+
+void Output::writeBool( bool bData )
+{
+ StringHelper::appendBool( maLine, bData );
+}
+
+void Output::writeColor( sal_Int32 nColor )
+{
+ writeChar( 'a' );
+ writeDec( static_cast< sal_uInt8 >( nColor >> 24 ) );
+ writeAscii( ",r" );
+ writeDec( static_cast< sal_uInt8 >( nColor >> 16 ) );
+ writeAscii( ",g" );
+ writeDec( static_cast< sal_uInt8 >( nColor >> 8 ) );
+ writeAscii( ",b" );
+ writeDec( static_cast< sal_uInt8 >( nColor ) );
+}
+
+void Output::writeDateTime( const DateTime& rDateTime )
+{
+ writeDec( rDateTime.Year, 4, '0' );
+ writeChar( '-' );
+ writeDec( rDateTime.Month, 2, '0' );
+ writeChar( '-' );
+ writeDec( rDateTime.Day, 2, '0' );
+ writeChar( 'T' );
+ writeDec( rDateTime.Hours, 2, '0' );
+ writeChar( ':' );
+ writeDec( rDateTime.Minutes, 2, '0' );
+ writeChar( ':' );
+ writeDec( rDateTime.Seconds, 2, '0' );
+}
+
+void Output::writeColIndex( sal_Int32 nCol )
+{
+ StringHelper::appendAddrCol( maLine, nCol, true );
+}
+
+void Output::writeRowIndex( sal_Int32 nRow )
+{
+ StringHelper::appendAddrRow( maLine, nRow, true );
+}
+
+void Output::writeColRowRange( sal_Int32 nColRow1, sal_Int32 nColRow2 )
+{
+ writeDec( nColRow1 );
+ writeChar( OOX_DUMP_RANGESEP );
+ writeDec( nColRow2 );
+}
+
+void Output::writeColRange( sal_Int32 nCol1, sal_Int32 nCol2 )
+{
+ writeColIndex( nCol1 );
+ writeChar( OOX_DUMP_RANGESEP );
+ writeColIndex( nCol2 );
+}
+
+void Output::writeRowRange( sal_Int32 nRow1, sal_Int32 nRow2 )
+{
+ writeRowIndex( nRow1 );
+ writeChar( OOX_DUMP_RANGESEP );
+ writeRowIndex( nRow2 );
+}
+
+void Output::writeAddress( const Address& rPos )
+{
+ StringHelper::appendAddress( maLine, rPos );
+}
+
+void Output::writeRange( const Range& rRange )
+{
+ StringHelper::appendRange( maLine, rRange );
+}
+
+void Output::writeRangeList( const RangeList& rRanges )
+{
+ StringHelper::appendRangeList( maLine, rRanges );
+}
+
+// ----------------------------------------------------------------------------
+
+void Output::construct( const Reference< XTextOutputStream >& rxStrm )
+{
+ mxStrm = rxStrm;
+ mnCol = mnItemLevel = mnMultiLevel = 0;
+ mnItemIdx = 0;
+ mnLastItem = 0;
+ if( mxStrm.is() )
+ {
+ writeChar( OOX_DUMP_BOM );
+ writeAscii( "OpenOffice.org binary file dumper v2.0" );
+ newLine();
+ emptyLine();
+ }
+}
+
+bool Output::implIsValid() const
+{
+ return mxStrm.is();
+}
+
+void Output::writeItemName( const sal_Char* pcName )
+{
+ if( pcName && (*pcName == '#') )
+ {
+ writeAscii( pcName + 1 );
+ StringHelper::appendIndex( maLine, mnItemIdx++ );
+ }
+ else
+ writeAscii( pcName );
+}
+
+// ============================================================================
+// ============================================================================
+
+ObjectBase::~ObjectBase()
+{
+}
+
+void ObjectBase::construct( const FilterBase& rFilter, ConfigRef xConfig )
+{
+ mpFilter = &rFilter;
+ mxConfig = xConfig;
+}
+
+void ObjectBase::construct( const ObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+void ObjectBase::dump()
+{
+ if( isValid() )
+ implDump();
+}
+
+bool ObjectBase::implIsValid() const
+{
+ return mpFilter && mpFilter->isImportFilter() && isValid( mxConfig );
+}
+
+ConfigRef ObjectBase::implReconstructConfig()
+{
+ return mxConfig;
+}
+
+void ObjectBase::implDump()
+{
+}
+
+void ObjectBase::reconstructConfig()
+{
+ mxConfig = implReconstructConfig();
+}
+
+// ============================================================================
+// ============================================================================
+
+RootStorageObjectBase::~RootStorageObjectBase()
+{
+}
+
+void RootStorageObjectBase::construct( const ObjectBase& rParent )
+{
+ ObjectBase::construct( rParent );
+}
+
+void RootStorageObjectBase::implDump()
+{
+ StorageRef xStrg = getFilter().getStorage();
+ if( xStrg.get() && xStrg->isStorage() )
+ extractStorage( xStrg, getFilter().getFileUrl() + CREATE_OUSTRING( ".dump" ) );
+}
+
+void RootStorageObjectBase::implDumpStream( BinaryInputStreamRef, const OUString&, const OUString&, const OUString& )
+{
+}
+
+void RootStorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrmName, const OUString& rSystemFileName )
+{
+ BinaryInputStream aInStrm( rStrg.openInputStream( rStrmName ), true );
+ if( aInStrm.is() )
+ {
+ BinaryOutputStream aOutStrm( InputOutputHelper::openOutputStream( rSystemFileName ), true );
+ if( aOutStrm.is() )
+ aOutStrm.copy( aInStrm );
+ }
+ BinaryInputStreamRef xDumpStrm( new BinaryInputStream( InputOutputHelper::openInputStream( rSystemFileName ), true ) );
+ if( xDumpStrm->is() )
+ implDumpStream( xDumpStrm, rStrg.getPath(), rStrmName, rSystemFileName + CREATE_OUSTRING( ".dump" ) );
+}
+
+void RootStorageObjectBase::extractStorage( StorageRef xStrg, const OUString& rSystemPath )
+{
+ // create directory in file system
+ ::osl::FileBase::RC eRes = ::osl::Directory::create( rSystemPath );
+ if( (eRes == ::osl::FileBase::E_None) || (eRes == ::osl::FileBase::E_EXIST) )
+ {
+ // process children of the storage
+ for( StorageIterator aIt( xStrg ); aIt.isValid(); ++aIt )
+ {
+ // encode all characters < 0x20
+ OUStringBuffer aBuffer;
+ StringHelper::appendEncString( aBuffer, aIt.getName(), false );
+
+ // replace all characters reserved in file system
+ OUString aSystemName = aBuffer.makeStringAndClear();
+ static const sal_Unicode spcReserved[] = { '/', '\\', ':', '*', '?', '<', '>', '|' };
+ for( const sal_Unicode* pcChar = spcReserved; pcChar < STATIC_ARRAY_END( spcReserved ); ++pcChar )
+ aSystemName = aSystemName.replace( *pcChar, '_' );
+
+ // build full path
+ OUString aFullSystemName = rSystemPath + OUString( sal_Unicode( '/' ) ) + aSystemName;
+
+ // handle storages and streams
+ if( aIt.isStorage() )
+ extractStorage( xStrg->openSubStorage( aIt.getName(), false ), aFullSystemName );
+ else if( aIt.isStream() )
+ extractStream( *xStrg, aIt.getName(), aFullSystemName );
+ }
+ }
+}
+
+// ============================================================================
+
+StorageIterator::StorageIterator( StorageRef xStrg ) :
+ mxStrg( xStrg )
+{
+ if( mxStrg.get() )
+ mxStrg->getElementNames( maNames );
+ maIt = maNames.begin();
+}
+
+StorageIterator::~StorageIterator()
+{
+}
+
+size_t StorageIterator::getElementCount() const
+{
+ return maNames.size();
+}
+
+StorageIterator& StorageIterator::operator++()
+{
+ if( maIt != maNames.end() )
+ ++maIt;
+ return *this;
+}
+
+OUString StorageIterator::getName() const
+{
+ OUString aName;
+ if( maIt != maNames.end() )
+ aName = *maIt;
+ return aName;
+}
+
+bool StorageIterator::isStream() const
+{
+ return isValid() && mxStrg->openInputStream( *maIt ).is();
+}
+
+bool StorageIterator::isStorage() const
+{
+ if( !isValid() )
+ return false;
+ StorageRef xStrg = mxStrg->openSubStorage( *maIt, false );
+ return xStrg.get() && xStrg->isStorage();
+}
+
+bool StorageIterator::implIsValid() const
+{
+ return mxStrg.get() && mxStrg->isStorage() && (maIt != maNames.end());
+}
+
+// ============================================================================
+// ============================================================================
+
+OutputObjectBase::~OutputObjectBase()
+{
+}
+
+void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rOutFileName )
+{
+ ObjectBase::construct( rParent );
+ mxOut.reset( new Output( rOutFileName ) );
+}
+
+void OutputObjectBase::construct( const ObjectBase& rParent, OutputRef xOut )
+{
+ ObjectBase::construct( rParent );
+ mxOut = xOut;
+}
+
+void OutputObjectBase::construct( const OutputObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool OutputObjectBase::implIsValid() const
+{
+ return isValid( mxOut ) && ObjectBase::implIsValid();
+}
+
+OutputRef OutputObjectBase::implReconstructOutput()
+{
+ return mxOut;
+}
+
+void OutputObjectBase::reconstructOutput()
+{
+ mxOut = implReconstructOutput();
+}
+
+void OutputObjectBase::writeEmptyItem( const sal_Char* pcName )
+{
+ ItemGuard aItem( *mxOut, pcName );
+}
+
+void OutputObjectBase::writeInfoItem( const sal_Char* pcName, const StringWrapper& rData )
+{
+ ItemGuard aItem( *mxOut, pcName );
+ mxOut->writeString( rData.getString() );
+}
+
+void OutputObjectBase::writeStringItem( const sal_Char* pcName, const ::rtl::OUString& rData )
+{
+ ItemGuard aItem( *mxOut, pcName );
+ mxOut->writeAscii( "(len=" );
+ mxOut->writeDec( rData.getLength() );
+ mxOut->writeAscii( ")," );
+ OUStringBuffer aValue( rData.copy( 0, ::std::min( rData.getLength(), OOX_DUMP_MAXSTRLEN ) ) );
+ StringHelper::enclose( aValue, OOX_DUMP_STRQUOTE );
+ mxOut->writeString( aValue.makeStringAndClear() );
+ if( rData.getLength() > OOX_DUMP_MAXSTRLEN )
+ mxOut->writeAscii( ",cut" );
+}
+
+void OutputObjectBase::writeArrayItem( const sal_Char* pcName, const sal_uInt8* pnData, sal_Size nSize, sal_Unicode cSep )
+{
+ ItemGuard aItem( *mxOut, pcName );
+ mxOut->writeArray( pnData, nSize, cSep );
+}
+
+void OutputObjectBase::writeBoolItem( const sal_Char* pcName, bool bData )
+{
+ ItemGuard aItem( *mxOut, pcName );
+ mxOut->writeBool( bData );
+}
+
+double OutputObjectBase::writeRkItem( const sal_Char* pcName, sal_Int32 nRk )
+{
+ MultiItemsGuard aMultiGuard( out() );
+ writeHexItem( pcName, static_cast< sal_uInt32 >( nRk ), "RK-FLAGS" );
+ double fValue = ::oox::xls::BiffHelper::calcDoubleFromRk( nRk );
+ writeDecItem( "decoded", fValue );
+ return fValue;
+}
+
+void OutputObjectBase::writeColorItem( const sal_Char* pcName, sal_Int32 nColor )
+{
+ ItemGuard aItem( *mxOut, pcName );
+ writeHexItem( pcName, nColor );
+ mxOut->writeColor( nColor );
+}
+
+void OutputObjectBase::writeDateTimeItem( const sal_Char* pcName, const DateTime& rDateTime )
+{
+ ItemGuard aItem( *mxOut, pcName );
+ mxOut->writeDateTime( rDateTime );
+}
+
+void OutputObjectBase::writeGuidItem( const sal_Char* pcName, const OUString& rGuid )
+{
+ ItemGuard aItem( *mxOut, pcName );
+ mxOut->writeString( rGuid );
+ aItem.cont();
+ mxOut->writeString( cfg().getStringOption( rGuid, OUString() ) );
+}
+
+void OutputObjectBase::writeColIndexItem( const sal_Char* pcName, sal_Int32 nCol )
+{
+ Output& rOut = out();
+ ItemGuard aItem( rOut, pcName );
+ rOut.writeDec( nCol );
+ aItem.cont();
+ rOut.writeColIndex( nCol );
+}
+
+void OutputObjectBase::writeRowIndexItem( const sal_Char* pcName, sal_Int32 nRow )
+{
+ Output& rOut = out();
+ ItemGuard aItem( rOut, pcName );
+ rOut.writeDec( nRow );
+ aItem.cont();
+ rOut.writeRowIndex( nRow );
+}
+
+void OutputObjectBase::writeColRangeItem( const sal_Char* pcName, sal_Int32 nCol1, sal_Int32 nCol2 )
+{
+ Output& rOut = out();
+ ItemGuard aItem( rOut, pcName );
+ rOut.writeColRowRange( nCol1, nCol2 );
+ aItem.cont();
+ rOut.writeColRange( nCol1, nCol2 );
+}
+
+void OutputObjectBase::writeRowRangeItem( const sal_Char* pcName, sal_Int32 nRow1, sal_Int32 nRow2 )
+{
+ Output& rOut = out();
+ ItemGuard aItem( rOut, pcName );
+ rOut.writeColRowRange( nRow1, nRow2 );
+ aItem.cont();
+ rOut.writeRowRange( nRow1, nRow2 );
+}
+
+void OutputObjectBase::writeAddressItem( const sal_Char* pcName, const Address& rPos )
+{
+ ItemGuard aItem( out(), pcName );
+ StringHelper::appendAddress( out().getLine(), rPos );
+}
+
+void OutputObjectBase::writeRangeItem( const sal_Char* pcName, const Range& rRange )
+{
+ ItemGuard aItem( out(), pcName );
+ StringHelper::appendRange( out().getLine(), rRange );
+}
+
+void OutputObjectBase::writeRangeListItem( const sal_Char* pcName, const RangeList& rRanges )
+{
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( pcName );
+ writeDecItem( "count", static_cast< sal_uInt16 >( rRanges.size() ) );
+ ItemGuard aItem( out(), "ranges" );
+ StringHelper::appendRangeList( out().getLine(), rRanges );
+}
+
+void OutputObjectBase::writeTokenAddressItem( const sal_Char* pcName, const TokenAddress& rPos, bool bNameMode )
+{
+ ItemGuard aItem( out(), pcName );
+ StringHelper::appendAddress( out().getLine(), rPos, bNameMode );
+}
+
+void OutputObjectBase::writeTokenAddress3dItem( const sal_Char* pcName, const OUString& rRef, const TokenAddress& rPos, bool bNameMode )
+{
+ ItemGuard aItem( out(), pcName );
+ out().writeString( rRef );
+ StringHelper::appendAddress( out().getLine(), rPos, bNameMode );
+}
+
+void OutputObjectBase::writeTokenRangeItem( const sal_Char* pcName, const TokenRange& rRange, bool bNameMode )
+{
+ ItemGuard aItem( out(), pcName );
+ StringHelper::appendRange( out().getLine(), rRange, bNameMode );
+}
+
+void OutputObjectBase::writeTokenRange3dItem( const sal_Char* pcName, const OUString& rRef, const TokenRange& rRange, bool bNameMode )
+{
+ ItemGuard aItem( out(), pcName );
+ out().writeString( rRef );
+ StringHelper::appendRange( out().getLine(), rRange, bNameMode );
+}
+
+// ============================================================================
+// ============================================================================
+
+InputObjectBase::~InputObjectBase()
+{
+}
+
+void InputObjectBase::construct( const ObjectBase& rParent, const ::rtl::OUString& rOutFileName, InputRef xIn )
+{
+ OutputObjectBase::construct( rParent, rOutFileName );
+ mxIn = xIn;
+}
+
+void InputObjectBase::construct( const ObjectBase& rParent, OutputRef xOut, InputRef xIn )
+{
+ OutputObjectBase::construct( rParent, xOut );
+ mxIn = xIn;
+}
+
+void InputObjectBase::construct( const OutputObjectBase& rParent, InputRef xIn )
+{
+ OutputObjectBase::construct( rParent );
+ mxIn = xIn;
+}
+
+void InputObjectBase::construct( const InputObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool InputObjectBase::implIsValid() const
+{
+ return isValid( mxIn ) && OutputObjectBase::implIsValid();
+}
+
+InputRef InputObjectBase::implReconstructInput()
+{
+ return mxIn;
+}
+
+void InputObjectBase::reconstructInput()
+{
+ mxIn = implReconstructInput();
+}
+
+void InputObjectBase::skipBlock( sal_Int32 nBytes, bool bShowSize )
+{
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxIn->tell() + nBytes, mxIn->getSize() );
+ if( mxIn->tell() < nEndPos )
+ {
+ if( bShowSize )
+ writeDecItem( "skipped-data-size", static_cast< sal_uInt64 >( nEndPos - mxIn->tell() ) );
+ mxIn->seek( nEndPos );
+ }
+}
+
+void InputObjectBase::dumpRawBinary( sal_Int32 nBytes, bool bShowOffset, bool bStream )
+{
+ Output& rOut = out();
+ TableGuard aTabGuard( rOut,
+ bShowOffset ? 12 : 0,
+ 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
+ 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
+ OOX_DUMP_BYTESPERLINE / 2 + 1 );
+
+ sal_Int32 nMaxShowSize = cfg().getIntOption< sal_Int32 >(
+ bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT32 );
+
+ bool bSeekable = mxIn->getSize() >= 0;
+ sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxIn->tell() + nBytes, mxIn->getSize() ) : 0;
+ sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxIn->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize;
+ sal_Int64 nPos = bSeekable ? mxIn->tell() : 0;
+ bool bLoop = true;
+
+ while( bLoop && (nPos < nDumpEnd) )
+ {
+ rOut.writeHex( static_cast< sal_uInt32 >( nPos ) );
+ rOut.tab();
+
+ sal_uInt8 pnLineData[ OOX_DUMP_BYTESPERLINE ];
+ sal_Int32 nLineSize = bSeekable ? ::std::min( static_cast< sal_Int32 >( nDumpEnd - mxIn->tell() ), OOX_DUMP_BYTESPERLINE ) : OOX_DUMP_BYTESPERLINE;
+ sal_Int32 nReadSize = mxIn->read( pnLineData, nLineSize );
+ bLoop = nReadSize == nLineSize;
+ nPos += nReadSize;
+
+ if( nReadSize > 0 )
+ {
+ const sal_uInt8* pnByte = 0;
+ const sal_uInt8* pnEnd = 0;
+ for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
+ {
+ if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) rOut.tab();
+ rOut.writeHex( *pnByte, false );
+ rOut.writeChar( ' ' );
+ }
+
+ aTabGuard.tab( 3 );
+ for( pnByte = pnLineData, pnEnd = pnLineData + nLineSize; pnByte != pnEnd; ++pnByte )
+ {
+ if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) rOut.tab();
+ rOut.writeChar( static_cast< sal_Unicode >( (*pnByte < 0x20) ? '.' : *pnByte ) );
+ }
+ rOut.newLine();
+ }
+ }
+
+ // skip undumped data
+ if( bSeekable )
+ skipBlock( static_cast< sal_Int32 >( nEndPos - mxIn->tell() ) );
+}
+
+void InputObjectBase::dumpBinary( const sal_Char* pcName, sal_Int32 nBytes, bool bShowOffset )
+{
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( pcName );
+ writeDecItem( "size", nBytes );
+ }
+ IndentGuard aIndGuard( out() );
+ dumpRawBinary( nBytes, bShowOffset );
+}
+
+void InputObjectBase::dumpArray( const sal_Char* pcName, sal_Int32 nBytes, sal_Unicode cSep )
+{
+ sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxIn->getSize() - mxIn->tell(), 0, nBytes );
+ if( nDumpSize > OOX_DUMP_MAXARRAY )
+ {
+ dumpBinary( pcName, nBytes, false );
+ }
+ else if( nDumpSize > 1 )
+ {
+ sal_uInt8 pnData[ OOX_DUMP_MAXARRAY ];
+ mxIn->read( pnData, nDumpSize );
+ writeArrayItem( pcName, pnData, nDumpSize, cSep );
+ }
+ else if( nDumpSize == 1 )
+ dumpHex< sal_uInt8 >( pcName );
+}
+
+void InputObjectBase::dumpRemaining( sal_Int32 nBytes )
+{
+ if( nBytes > 0 )
+ {
+ if( cfg().getBoolOption( "show-trailing-unknown", true ) )
+ dumpBinary( "remaining-data", nBytes, false );
+ else
+ skipBlock( nBytes );
+ }
+}
+
+OUString InputObjectBase::dumpCharArray( const sal_Char* pcName, sal_Int32 nSize, rtl_TextEncoding eTextEnc )
+{
+ sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxIn->getSize() - mxIn->tell(), 0, nSize );
+ OUString aString;
+ if( nDumpSize > 0 )
+ {
+ ::std::vector< sal_Char > aBuffer( static_cast< sal_Size >( nSize ) + 1 );
+ sal_Int32 nCharsRead = mxIn->read( &aBuffer.front(), nSize );
+ aBuffer[ nCharsRead ] = 0;
+ aString = OStringToOUString( OString( &aBuffer.front() ), eTextEnc );
+ }
+ writeStringItem( pcName, aString );
+ return aString;
+}
+
+OUString InputObjectBase::dumpUnicodeArray( const sal_Char* pcName, sal_Int32 nSize )
+{
+ OUStringBuffer aBuffer;
+ for( sal_Int32 nIndex = 0; mxIn->isValidPos() && (nIndex < nSize); ++nIndex )
+ aBuffer.append( static_cast< sal_Unicode >( mxIn->readValue< sal_uInt16 >() ) );
+ OUString aString = aBuffer.makeStringAndClear();
+ writeStringItem( pcName, aString );
+ return aString;
+}
+
+double InputObjectBase::dumpRk( const sal_Char* pcName )
+{
+ sal_Int32 nRk;
+ *mxIn >> nRk;
+ return writeRkItem( pcName ? pcName : "rk-value", nRk );
+}
+
+OUString InputObjectBase::dumpGuid( const sal_Char* pcName )
+{
+ OUStringBuffer aBuffer;
+ sal_uInt32 nData32;
+ sal_uInt16 nData16;
+ sal_uInt8 nData8;
+
+ *mxIn >> nData32;
+ StringHelper::appendHex( aBuffer, nData32, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ *mxIn >> nData16;
+ StringHelper::appendHex( aBuffer, nData16, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ *mxIn >> nData16;
+ StringHelper::appendHex( aBuffer, nData16, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ *mxIn >> nData8;
+ StringHelper::appendHex( aBuffer, nData8, false );
+ *mxIn >> nData8;
+ StringHelper::appendHex( aBuffer, nData8, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ for( int nIndex = 0; nIndex < 6; ++nIndex )
+ {
+ *mxIn >> nData8;
+ StringHelper::appendHex( aBuffer, nData8, false );
+ }
+ OUString aGuid = aBuffer.makeStringAndClear();
+ writeGuidItem( pcName ? pcName : "guid", aGuid );
+ return aGuid;
+}
+
+void InputObjectBase::dumpItem( const ItemFormat& rItemFmt )
+{
+ switch( rItemFmt.meDataType )
+ {
+ case DATATYPE_VOID: break;
+ case DATATYPE_INT8: dumpValue< sal_Int8 >( rItemFmt ); break;
+ case DATATYPE_UINT8: dumpValue< sal_uInt8 >( rItemFmt ); break;
+ case DATATYPE_INT16: dumpValue< sal_Int16 >( rItemFmt ); break;
+ case DATATYPE_UINT16: dumpValue< sal_uInt16 >( rItemFmt ); break;
+ case DATATYPE_INT32: dumpValue< sal_Int32 >( rItemFmt ); break;
+ case DATATYPE_UINT32: dumpValue< sal_uInt32 >( rItemFmt ); break;
+ case DATATYPE_INT64: dumpValue< sal_Int64 >( rItemFmt ); break;
+ case DATATYPE_UINT64: dumpValue< sal_uInt64 >( rItemFmt ); break;
+ case DATATYPE_FLOAT: dumpValue< float >( rItemFmt ); break;
+ case DATATYPE_DOUBLE: dumpValue< double >( rItemFmt ); break;
+ default:;
+ }
+}
+
+// ============================================================================
+
+InputStreamObject::InputStreamObject( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm )
+{
+ construct( rParent, rOutFileName, xStrm );
+}
+
+InputStreamObject::~InputStreamObject()
+{
+}
+
+void InputStreamObject::construct( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm )
+{
+ mxStrm = xStrm;
+ if( mxStrm.get() )
+ InputObjectBase::construct( rParent, rOutFileName, InputRef( new BinaryInput( *mxStrm ) ) );
+}
+
+sal_Int64 InputStreamObject::getStreamSize() const
+{
+ return mxStrm.get() ? mxStrm->getLength() : -1;
+}
+
+void InputStreamObject::dumpBinaryStream( bool bShowOffset )
+{
+ in().seek( 0 );
+ dumpRawBinary( getLimitedValue< sal_Int32, sal_Int64 >( in().getSize(), 0, SAL_MAX_INT32 ), bShowOffset, true );
+ out().emptyLine();
+}
+
+bool InputStreamObject::implIsValid() const
+{
+ return mxStrm.get() && mxStrm->is() && InputObjectBase::implIsValid();
+}
+
+void InputStreamObject::implDump()
+{
+ dumpBinaryStream();
+}
+
+// ============================================================================
+
+TextStreamObject::TextStreamObject( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm ) :
+ InputStreamObject( rParent, rOutFileName, xStrm )
+{
+}
+
+void TextStreamObject::implDump()
+{
+ dumpTextStream( osl_getThreadTextEncoding() );
+}
+
+void TextStreamObject::dumpTextStream( rtl_TextEncoding eTextEnc, bool bShowLines )
+{
+ Output& rOut = out();
+ TableGuard aTabGuard( rOut, bShowLines ? 8 : 0 );
+
+ const sal_Char* pcTextEnc = rtl_getBestUnixCharsetFromTextEncoding( eTextEnc );
+ OUString aEncoding = OUString::createFromAscii( pcTextEnc ? pcTextEnc : "UTF-8" );
+ Reference< XTextInputStream > xTextStrm = InputOutputHelper::openTextInputStream( getStream().getXInputStream(), aEncoding );
+ if( xTextStrm.is() )
+ {
+ sal_uInt32 nLine = 0;
+ while( !xTextStrm->isEOF() )
+ {
+ rOut.writeDec( ++nLine, 6 );
+ rOut.tab();
+ try { rOut.writeString( xTextStrm->readLine() ); } catch( Exception& ) {}
+ rOut.newLine();
+ }
+ }
+ rOut.emptyLine();
+}
+
+// ============================================================================
+// ============================================================================
+
+RecordHeaderImplBase::~RecordHeaderImplBase()
+{
+}
+
+void RecordHeaderImplBase::construct( const InputObjectBase& rParent, const RecordHeaderConfigInfo& rCfgInfo )
+{
+ InputObjectBase::construct( rParent );
+ if( InputObjectBase::implIsValid() )
+ {
+ const Config& rCfg = cfg();
+ mpcTitle = rCfgInfo.mpcTitle;
+ mxRecNames = rCfg.getNameList( rCfgInfo.mpcRecNames );
+ mbShowRecPos = rCfg.getBoolOption( rCfgInfo.mpcShowRecPos, true );
+ mbShowRecSize = rCfg.getBoolOption( rCfgInfo.mpcShowRecSize, true );
+ mbShowRecId = rCfg.getBoolOption( rCfgInfo.mpcShowRecId, true );
+ mbShowRecName = rCfg.getBoolOption( rCfgInfo.mpcShowRecName, true );
+ mbShowRecBody = rCfg.getBoolOption( rCfgInfo.mpcShowRecBody, true );
+ }
+}
+
+bool RecordHeaderImplBase::implIsValid() const
+{
+ return isValid( mxRecNames ) && InputObjectBase::implIsValid();
+}
+
+// ============================================================================
+// ============================================================================
+
+DumperBase::~DumperBase()
+{
+}
+
+bool DumperBase::isImportEnabled() const
+{
+ return !isValid() || cfg().isImportEnabled();
+}
+
+StorageRef DumperBase::getRootStorage() const
+{
+ return getFilter().getStorage();
+}
+
+BinaryInputStreamRef DumperBase::getRootStream() const
+{
+ BinaryInputStreamRef xStrm;
+ if( StorageBase* pStrg = getRootStorage().get() )
+ xStrm.reset( new BinaryInputStream( pStrg->openInputStream( OUString() ), false ) );
+ return xStrm;
+}
+
+void DumperBase::construct( const FilterBase& rFilter, ConfigRef xConfig )
+{
+ if( rFilter.isImportFilter() && isValid( xConfig ) && xConfig->isDumperEnabled() )
+ ObjectBase::construct( rFilter, xConfig );
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/dump/dumperconfig.dat b/oox/source/dump/dumperconfig.dat
new file mode 100644
index 000000000000..b3920e210090
--- /dev/null
+++ b/oox/source/dump/dumperconfig.dat
@@ -0,0 +1,436 @@
+
+# dumper settings ============================================================
+
+# Enable entire dumper (default=off). If dumper is disabled, no output into
+# a text file is done. This option does not affect the options 'enable-import'
+# and 'extract-storage-streams'.
+# 0=off, 1=on
+enable-dumper=1
+
+# Enable import after dumping (default=on). Disabling this option allows
+# to dump a file without loading it. This option is independent from the
+# 'enable-dumper' option.
+# 0=off, 1=on
+enable-import=1
+
+# Maximum size of binary stream dumps (default=infinite).
+max-binary-stream-size=0x1000
+
+# Maximum size of binary data blocks in content dumps (default=infinite).
+max-binary-data-size=0x0200
+
+# Shows unknown trailing data as binary dump (default=on).
+# 0=off, 1=on
+show-trailing-unknown=1
+
+# DFF record settings --------------------------------------------------------
+
+# Show total stream position of the DFF record (default=on).
+# 0=off, 1=on
+show-dff-record-pos=0
+
+# Show total DFF record size in bytes (default=on).
+# 0=off, 1=on
+show-dff-record-size=1
+
+# Show DFF record identifier (default=on).
+# 0=off, 1=on
+show-dff-record-id=1
+
+# Show DFF record name, if known (default=on).
+# 0=off, 1=on
+show-dff-record-name=1
+
+# Show DFF record contents (default=on).
+# 0=off, 1=on
+show-dff-record-body=1
+
+# name lists =================================================================
+
+unitconverter=CONV-DEC,1
+unitconverter=CONV-PERCENT,1,%
+unitconverter=CONV-DEG,1,°
+unitconverter=CONV-INCH-TO-CM,2.54,cm
+unitconverter=CONV-TWIP-TO-PT,/20,pt
+unitconverter=CONV-PT-TO-CM,/28.346457,cm
+unitconverter=CONV-PT1616-TO-CM,/1857713.4,cm
+unitconverter=CONV-TWIP-TO-CM,/566.92913,cm
+
+constlist=BOOLEAN
+ 0=FALSE
+ default=TRUE
+end
+
+combilist=RK-FLAGS
+ 0x00000001=div-100
+ 0x00000002=integer
+ 0xFFFFFFFC=int32,dec,value
+end
+
+constlist=CHARSET
+ 0=win-1252-latin-1
+ 1=system-default
+ 2=symbol
+ 77=apple-roman
+ 128=win-932-japanese-shift-jis
+ 129=win-949-korean-hangul
+ 130=win-1361-korean-johab
+ 134=win-936-chinese-simplified-gbk
+ 136=win-950-chinese-traditional-big5
+ 161=win-1253-greek
+ 162=win-1254-turkish
+ 163=win-1258-vietnamese
+ 177=win-1255-hebrew
+ 178=win-1256-arabic
+ 186=win-1257-baltic
+ 204=win-1251-cyrillic
+ 222=win-874-thai
+ 238=win-1250-latin-2-central-european
+ 255=ibm-850-latin-1
+end
+
+constlist=CODEPAGES
+ 367=ascii
+ 437=ibm-437-us
+ 708=iso-8859-6
+ 720=ibm-720-arabic
+ 737=ibm-737-greek
+ 775=ibm-775-baltic
+ 850=ibm-850-latin-1
+ 852=ibm-852-latin-2-central-european
+ 855=ibm-855-cyrillic
+ 857=ibm-857-turkish
+ 858=ibm-858-multilingual-latin-1-with-euro
+ 860=ibm-860-portuguese
+ 861=ibm-861-icelandic
+ 862=ibm-862-hebrew
+ 863=ibm-863-canadian-french
+ 864=ibm-864-arabic
+ 865=ibm-865-nordic
+ 866=ibm-866-cyrillic-russian
+ 869=ibm-869-greek-modern
+ 874=win-874-thai
+ 932=win-932-japanese-shift-jis
+ 936=win-936-chinese-simplified-gbk
+ 949=win-949-korean-wansung
+ 950=win-950-chinese-traditional-big5
+ 1200=utf-16
+ 1250=win-1250-latin-2-central-european
+ 1251=win-1251-cyrillic
+ 1252=win-1252-latin-1
+ 1253=win-1253-greek
+ 1254=win-1254-turkish
+ 1255=win-1255-hebrew
+ 1256=win-1256-arabic
+ 1257=win-1257-baltic
+ 1258=win-1258-vietnamese
+ 1361=win-1361-korean-johab
+ 10000=apple-roman
+ 10001=apple-japanese
+ 10002=apple-chinese-traditional
+ 10003=apple-korean
+ 10004=apple-arabic
+ 10005=apple-hebrew
+ 10006=apple-greek
+ 10007=apple-cyrillic
+ 10008=apple-chinese-simplified
+ 10010=apple-romanian
+ 10017=apple-ukrainian
+ 10029=apple-central-european-with-euro
+ 10079=apple-icelandic
+ 10081=apple-turkish
+ 10082=apple-croatian
+ 20127=ascii
+ 20866=koi8-r
+ 21866=koi8-u
+ 28591=iso-8859-1
+ 28592=iso-8859-2
+ 28593=iso-8859-3
+ 28594=iso-8859-4
+ 28595=iso-8859-5
+ 28596=iso-8859-6
+ 28597=iso-8859-7
+ 28598=iso-8859-8
+ 28599=iso-8859-9
+ 28605=iso-8859-15
+ 32768=apple-romanian
+ 32769=win-1252-latin-1
+ 50220=iso-2022-jp
+ 50225=iso-2022-kr
+ 51932=euc-jp
+ 51936=euc-cn
+ 51949=euc-kr
+ 65000=utf-7
+ 65001=utf-8
+end
+
+# DFF stream -----------------------------------------------------------------
+
+multilist=DFF-RECORD-NAMES
+ 0xF000=DFFDGGCONTAINER,DFFBSTORECONTAINER,DFFDGCONTAINER,DFFSPGRCONTAINER,DFFSPCONTAINER,DFFSOLVERCONTAINER,DFFDGG,DFFBSE
+ 0xF008=DFFDG,DFFSPGR,DFFSP,DFFOPT,DFFTEXTBOX,DFFCLIENTTEXTBOX,DFFANCHOR,DFFCHILDANCHOR
+ 0xF010=DFFCLIENTANCHOR,DFFCLIENTDATA,DFFCONNECTORRULE,DFFALIGNRULE,DFFARCRULE,DFFCLIENTRULE,DFFCLASSID,DFFCALLOUTRULE
+ # 0xF018-0xF117 reserved for pictures
+ 0xF118=DFFREGROUPITEM,DFFSELECTION,DFFCOLORMRU,,,DFFDELETEDPSPL,DFFSPLITMENUCOLORS,DFFOLEOBJECT
+ 0xF120=DFFCOLORSCHEME,,DFFUSERDEFPROP
+end
+
+combilist=DFF-RECORD-INST
+ 0x000F=uint8,hex,version,DFF-RECORD-VERSION
+ 0xFFF0=uint16,dec,instance
+end
+
+constlist=DFF-RECORD-VERSION
+ default=
+ 15=container
+end
+
+flagslist=DFFCLIENTANCHOR-FLAGS
+ 0x0001=pos-locked
+ 0x0002=size-locked
+end
+
+combilist=DFFOPT-PROPERTY-ID
+ 0x3FFF=uint16,dec,id,DFFOPT-PROPERTY-NAMES
+ 0x4000=picture
+ 0x8000=complex
+end
+
+multilist=DFFOPT-PROPERTY-NAMES
+ # transform
+ 0x0004=rotation
+ # protection
+ 0x007F=lock-flags
+ # text
+ 0x0080=text-id,text-left,text-top,text-right,text-bottom,text-wrap-mode,text-scale,text-anchor-mode
+ 0x0088=text-flow,text-font-rotation,text-next-shape,text-bidi
+ 0x00BF=text-flags
+ # text geometry
+ 0x00C0=text-unicode-string,text-rtf-string,text-curve-align,text-def-size,text-spacing,text-font-family
+ 0x00FF=text-geometry-flags
+ # picture
+ 0x0100=pic-crop-top,pic-crop-bottom,pic-crop-left,pic-crop-right,pic-data,pic-file-name,pic-flags,pic-transparency-color
+ 0x0108=pic-contrast,pic-brightness,pic-gamma,pic-id,pic-double-cr-mod,pic-fill-cr-mod,pic-line-cr-mod,pic-data-print
+ 0x0110=pic-name-print,pic-flags-print
+ 0x013F=pic-flags
+ # geometry
+ 0x0140=geo-left,geo-top,geo-right,geo-bottom,geo-shape-path,geo-vertices,geo-segment-info,geo-adjust-1
+ 0x0148=geo-adjust-2,geo-adjust-3,geo-adjust-4,geo-adjust-5,geo-adjust-6,geo-adjust-7,geo-adjust-8,geo-adjust-9
+ 0x0150=geo-adjust-10,geo-connect-points,geo-stretch-x,geo-stretch-y,geo-handles,geo-formulas,geo-text-recs
+ 0x0158=geo-connector-type
+ 0x017F=geo-flags
+ # fill style
+ 0x0180=fill-type,fill-color,fill-opacity,fill-back-color,fill-back-opacity,fill-cr-mod,fill-blip,fill-blip-name
+ 0x0188=fill-blip-flags,fill-width,fill-height,fill-angle,fill-focus,fill-to-left,fill-to-top,fill-to-right
+ 0x0190=fill-to-bottom,fill-rect-left,fill-rect-top,fill-rect-right,fill-rect-bottom,fill-dz-type,fill-shade-preset,fill-shade-colors
+ 0x0198=fill-origin-x,fill-origin-y,fill-shape-origin-x,fill-shape-origin-y,fill-shade-type
+ 0x01BF=fill-flags
+ # line style
+ 0x01C0=line-color,line-opacity,line-back-color,line-cr-mod,line-type,line-fill-blip,line-fill-blip-name,line-fill-blip-flags
+ 0x01C8=line-fill-width,line-fill-height,line-fill-dz-type,line-width,line-miter-limit,line-style,line-dash,line-dash-style
+ 0x01D0=line-start-arrow-head,line-end-arrow-head,line-start-arrow-width,line-start-arrow-length,line-end-arrow-width,line-end-arrow-length,line-join-style,line-end-cap-style
+ 0x01FF=line-flags
+ # shadow style
+ 0x0200=shadow-type,shadow-color,shadow-highlight,shadow-cr-mod,shadow-opacity,shadow-offset-x,shadow-offset-y,shadow-2nd-offset-x
+ 0x0208=shadow-2nd-offset-y,shadow-scale-x-to-x,shadow-scale-y-to-x,shadow-scale-x-to-y,shadow-scale-y-to-y,shadow-persp-x,shadow-persp-y,shadow-weight
+ 0x0210=shadow-origin-x,shadow-origin-y
+ 0x023F=shadow-flags
+ # perspective
+ 0x0240=persp-type,persp-offset-x,persp-offsety,persp-scale-x-to-x,persp-scale-y-to-x,persp-scale-x-to-y,persp-scale-y-to-y,persp-persp-x
+ 0x0248=persp-persp-y,persp-weight,persp-origin-x,persp-origin-y
+ 0x027F=persp-flags
+ # 3d object
+ 0x0280=3dobj-specular-amt,3dobj-diffuse-amt,3dobj-shininess,3dobj-edge-thickness,3dobj-extrude-forward,3dobj-extrude-backward,3dobj-extrude-plane,3dobj-extrusion-color
+ 0x0288=3dobj-cr-mod
+ 0x02BF=3dobj-flags
+ # 3d style
+ 0x02C0=3dstyle-y-rotation,3dstyle-x-rotation,3dstyle-rotation-axis-x,3dstyle-rotation-axis-y,3dstyle-rotation-axis-z,3dstyle-rotation,3dstyle-rotation-center-x,3dstyle-rotation-center-y
+ 0x02C8=3dstyle-rotation-center-z,3dstyle-render-mode,3dstyle-tolerance,3dstyle-view-point-x,3dstyle-view-point-y,3dstyle-view-point-z,3dstyle-origin-x,3dstyle-origin-y
+ 0x02D0=3dstyle-skew-angle,3dstyle-skew-amount,3dstyle-ambient-intensity,3dstyle-key-light-x,3dstyle-key-light-y,3dstyle-key-light-z,3dstyle-key-light-intensity,3dstyle-fill-light-x
+ 0x02D8=3dstyle-fill-light-y,3dstyle-fill-light-z,3dstyle-fill-light-intensity
+ 0x02FF=3dstyle-flags
+ # shape 1
+ 0x0301=,shape-master,,shape-connect-style,shape-bw-mod,shape-bw-mode-pure-bw,shape-bw-mode-bw
+ 0x033F=shape1-flags
+ # callout
+ 0x0340=callout-type,callout-box-distance,callout-angle,callout-drop-type,callout-drop-distance,callout-length
+ 0x037F=callout-flags
+ # shape 2
+ 0x0380=shape-name,shape-description,shape-hyperlink,shape-wrap-polygon-vertices,shape-wrap-left,shape-wrap-top,shape-wrap-right,shape-wrap-bottom
+ 0x0388=shape-regroup-id
+ 0x03BF=shape2-flags
+end
+
+flagslist=DFFOPT-LOCK-FLAGS
+ 0x00000001=lock-against-grouping
+ 0x00000002=lock-adjust-handles
+ 0x00000004=lock-text
+ 0x00000008=lock-vertices
+ 0x00000010=lock-cropping
+ 0x00000020=lock-against-select
+ 0x00000040=lock-position
+ 0x00000080=lock-aspect-ratio
+ 0x00000100=lock-rotation
+end
+
+flagslist=DFFOPT-TEXT-FLAGS
+ 0x00000001=fit-text-to-shape
+ 0x00000002=fit-shape-to-text
+ 0x00000004=rotate-text
+ 0x00000008=auto-text-margin
+ 0x00000010=select-text
+end
+
+flagslist=DFFOPT-TEXTGEO-FLAGS
+ 0x00000001=strike-through
+ 0x00000002=small-caps
+ 0x00000004=shadow
+ 0x00000008=underline
+ 0x00000010=italic
+ 0x00000020=bold
+ 0x00000040=no-measure-along-path
+ 0x00000080=stretch-height
+ 0x00000100=scale-on-path
+ 0x00000200=shrink-to-fit
+ 0x00000400=stretch-to-fit
+ 0x00000800=tightening
+ 0x00001000=kerning
+ 0x00002000=vertical
+ 0x00004000=has-effect
+ 0x00008000=reverse-rows
+end
+
+flagslist=DFFOPT-PICTURE-FLAGS
+ 0x00000001=ole-alive
+ 0x00000002=bi-level-display
+ 0x00000004=grayscale
+ 0x00000008=no-hit-test
+end
+
+flagslist=DFFOPT-GEO-FLAGS
+ 0x00000001=fill-support
+ 0x00000002=fill-shade-shape-support
+ 0x00000004=fontwork-support
+ 0x00000008=line-support
+ 0x00000010=3d-support
+ 0x00000020=shadow-support
+end
+
+flagslist=DFFOPT-FILL-FLAGS
+ 0x00000001=no-fill-hit-test
+ 0x00000002=use-large-rect
+ 0x00000004=register-pattern
+ 0x00000008=hit-test-fill
+ 0x00000010=has-fill
+end
+
+flagslist=DFFOPT-LINE-FLAGS
+ 0x00000001=draw-dash-for-invisible
+ 0x00000002=register-pattern
+ 0x00000004=hit-test-line
+ 0x00000008=has-line
+ 0x00000010=arrowhead-support
+end
+
+flagslist=DFFOPT-SHADOW-FLAGS
+ 0x00000001=excel5-style
+ 0x00000002=has-shadow
+end
+
+flagslist=DFFOPT-PERSP-FLAGS
+ 0x00000001=has-perspective
+end
+
+flagslist=DFFOPT-3DOBJ-FLAGS
+ 0x00000001=light-face
+ 0x00000002=extrusion-color
+ 0x00000004=metallic
+ 0x00000008=has-3d
+end
+
+flagslist=DFFOPT-3DSTYLE-FLAGS
+ 0x00000001=fill-color-harsh
+ 0x00000002=key-color-harsh
+ 0x00000004=parallel
+ 0x00000008=rotation-center-auto
+ 0x00000010=constrain-rotation
+end
+
+flagslist=DFFOPT-SHAPE1-FLAGS
+ 0x00000001=background
+ 0x00000002=delete-attached-object
+ 0x00000008=lock-shape-type
+ 0x00000010=prefer-rel-resize
+ 0x00000020=ole-iconified
+end
+
+flagslist=DFFOPT-CALLOUT-FLAGS
+ 0x00000001=length-specified
+ 0x00000002=drop-auto
+ 0x00000004=minus-y
+ 0x00000008=minus-x
+ 0x00000010=has-text-border
+ 0x00000020=has-accent-bar
+ 0x00000040=is-callout
+end
+
+flagslist=DFFOPT-SHAPE2-FLAGS
+ 0x00000001=print
+ 0x00000002=hidden
+ 0x00000004=1d-adjustment
+ 0x00000008=action-attached
+ 0x00000010=notify-double-click
+ 0x00000020=behind-text
+ 0x00000040=wrap-edited
+end
+
+# OLE property stream --------------------------------------------------------
+
+F29F85E0-4FF9-1068-AB91-08002B27B3D9=GlobalDocProp
+D5CDD502-2E9C-101B-9397-08002B2CF9AE=BuiltinDocProp
+D5CDD505-2E9C-101B-9397-08002B2CF9AE=CustomDocProp
+
+constlist=OLEPROP-BYTE-ORDER
+ 0xFEFF=big-endian
+ 0xFFFE=little-endian
+end
+
+shortlist=OLEPROP-OSTYPE,0,dos,mac,win32,unix
+
+multilist=OLEPROP-BASEIDS
+ quote-names=1
+ default=
+ 0=dictionary,codepage
+end
+
+multilist=OLEPROP-GLOBALIDS
+ include=OLEPROP-BASEIDS
+ 2=title,subject,author,keywords,comments,template,last-author,rev-number
+ 10=edit-time,last-printed,create-time,last-saved,page-count,word-count,char-count,thumbnail,appname,security
+end
+
+multilist=OLEPROP-BUILTINIDS
+ include=OLEPROP-BASEIDS
+ 2=category,pres-target,byte-count,line-count,para-count,slide-count,note-count,hidden-slide-count
+ 10=clips,scale-crop,heading-pairs,part-titles,manager,company,links-uptodate
+end
+
+multilist=OLEPROP-TYPE-SIMPLE
+ 0=empty,null,int16,int32,float,double,fixed,date,string8,dispatch
+ 10=error,bool,variant,unknown,decimal,int8,uint8,uint16,uint32
+ 20=int64,uint64,int,uint,void,hresult,ptr,savearray,c-array,userdef
+ 30=string8,string16
+ 64=time-stamp,blob,stream,storage,stream-obj,storage-obj
+ 70=blob-obj,clip-fmt,guid,vers-stream
+ 0x0FFF=str8-blob
+end
+
+combilist=OLEPROP-TYPE
+ 0x0FFF=int32,dec,base-type,OLEPROP-TYPE-SIMPLE
+ 0x1000=vector
+ 0x2000=array
+ 0x4000=byref
+end
+
+# ============================================================================
+
diff --git a/oox/source/dump/makefile.mk b/oox/source/dump/makefile.mk
new file mode 100644
index 000000000000..c960b2099838
--- /dev/null
+++ b/oox/source/dump/makefile.mk
@@ -0,0 +1,60 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=dump
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/biffdumper.obj \
+ $(SLO)$/dffdumper.obj \
+ $(SLO)$/dumperbase.obj \
+ $(SLO)$/olestoragedumper.obj \
+ $(SLO)$/xlsbdumper.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/dump/olestoragedumper.cxx b/oox/source/dump/olestoragedumper.cxx
new file mode 100644
index 000000000000..9b3ef531b3e8
--- /dev/null
+++ b/oox/source/dump/olestoragedumper.cxx
@@ -0,0 +1,449 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: olestoragedumper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:58 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/dump/olestoragedumper.hxx"
+#include <osl/thread.h>
+#include <osl/file.hxx>
+#include <rtl/tencinfo.h>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/core/filterbase.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OString;
+using ::rtl::OStringToOUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::util::DateTime;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 OLEPROP_ID_DICTIONARY = 0;
+const sal_Int32 OLEPROP_ID_CODEPAGE = 1;
+
+const sal_Int32 OLEPROP_TYPE_INT16 = 2;
+const sal_Int32 OLEPROP_TYPE_INT32 = 3;
+const sal_Int32 OLEPROP_TYPE_FLOAT = 4;
+const sal_Int32 OLEPROP_TYPE_DOUBLE = 5;
+const sal_Int32 OLEPROP_TYPE_DATE = 7;
+const sal_Int32 OLEPROP_TYPE_STRING = 8;
+const sal_Int32 OLEPROP_TYPE_STATUS = 10;
+const sal_Int32 OLEPROP_TYPE_BOOL = 11;
+const sal_Int32 OLEPROP_TYPE_VARIANT = 12;
+const sal_Int32 OLEPROP_TYPE_INT8 = 16;
+const sal_Int32 OLEPROP_TYPE_UINT8 = 17;
+const sal_Int32 OLEPROP_TYPE_UINT16 = 18;
+const sal_Int32 OLEPROP_TYPE_UINT32 = 19;
+const sal_Int32 OLEPROP_TYPE_INT64 = 20;
+const sal_Int32 OLEPROP_TYPE_UINT64 = 21;
+const sal_Int32 OLEPROP_TYPE_STRING8 = 30;
+const sal_Int32 OLEPROP_TYPE_STRING16 = 31;
+const sal_Int32 OLEPROP_TYPE_FILETIME = 64;
+const sal_Int32 OLEPROP_TYPE_BLOB = 65;
+const sal_Int32 OLEPROP_TYPE_STREAM = 66;
+const sal_Int32 OLEPROP_TYPE_STORAGE = 67;
+const sal_Int32 OLEPROP_TYPE_CLIPFMT = 71;
+
+const sal_uInt16 CODEPAGE_UNICODE = 1200;
+
+} // namespace
+
+// ============================================================================
+
+OlePropertyStreamObject::OlePropertyStreamObject( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm ) :
+ InputStreamObject( rParent, rOutFileName, xStrm )
+{
+}
+
+void OlePropertyStreamObject::implDump()
+{
+ Input& rIn = in();
+ Output& rOut = out();
+
+ OUStringVector aGuidVec;
+ ::std::vector< sal_uInt32 > aStartPosVec;
+
+ // dump header
+ writeEmptyItem( "HEADER" );
+ {
+ IndentGuard aIndGuard( rOut );
+ dumpHex< sal_uInt16 >( "byte-order", "OLEPROP-BYTE-ORDER" );
+ dumpDec< sal_uInt16 >( "version" );
+ dumpDec< sal_uInt16 >( "os-minor" );
+ dumpDec< sal_uInt16 >( "os-type", "OLEPROP-OSTYPE" );
+ dumpGuid( "guid" );
+ sal_Int32 nSectCount = dumpDec< sal_Int32 >( "section-count" );
+
+ // dump table of section positions
+ {
+ TableGuard aTabGuard( rOut, 15, 60 );
+ rOut.resetItemIndex();
+ for( sal_Int32 nSectIdx = 0; (nSectIdx < nSectCount) && rIn.isValidPos(); ++nSectIdx )
+ {
+ MultiItemsGuard aMultiGuard( rOut );
+ writeEmptyItem( "#section" );
+ aGuidVec.push_back( dumpGuid( "guid" ) );
+ aStartPosVec.push_back( dumpHex< sal_uInt32 >( "start-pos" ) );
+ }
+ }
+ }
+ rOut.emptyLine();
+
+ // dump sections
+ for( size_t nSectIdx = 0; (nSectIdx < aStartPosVec.size()) && rIn.isValidPos(); ++nSectIdx )
+ dumpSection( aGuidVec[ nSectIdx ], aStartPosVec[ nSectIdx ] );
+}
+
+void OlePropertyStreamObject::dumpSection( const OUString& rGuid, sal_uInt32 nStartPos )
+{
+ Input& rIn = in();
+ Output& rOut = out();
+
+ // property ID names
+ mxPropIds = cfg().createNameList< ConstList >( "OLEPROP-IDS" );
+ OUString aGuidName = cfg().getStringOption( rGuid, OUString() );
+ if( aGuidName.equalsAscii( "GlobalDocProp" ) )
+ mxPropIds->includeList( cfg().getNameList( "OLEPROP-GLOBALIDS" ) );
+ else if( aGuidName.equalsAscii( "BuiltinDocProp" ) )
+ mxPropIds->includeList( cfg().getNameList( "OLEPROP-BUILTINIDS" ) );
+ else
+ mxPropIds->includeList( cfg().getNameList( "OLEPROP-BASEIDS" ) );
+
+ // property ID/position map
+ typedef ::std::map< sal_Int32, sal_uInt32 > PropertyPosMap;
+ PropertyPosMap aPropMap;
+
+ // dump section header line
+ writeSectionHeader( rGuid, nStartPos );
+
+ // seek to section
+ IndentGuard aIndGuard( rOut );
+ if( startElement( nStartPos ) )
+ {
+ // dump section header
+ dumpDec< sal_Int32 >( "size" );
+ sal_Int32 nPropCount = dumpDec< sal_Int32 >( "property-count" );
+
+ // dump table of property positions
+ {
+ TableGuard aTabGuard( rOut, 15, 25 );
+ rOut.resetItemIndex();
+ for( sal_Int32 nPropIdx = 0; (nPropIdx < nPropCount) && rIn.isValidPos(); ++nPropIdx )
+ {
+ MultiItemsGuard aMultiGuard( rOut );
+ writeEmptyItem( "#property" );
+ sal_Int32 nPropId = dumpDec< sal_Int32 >( "id", mxPropIds );
+ sal_uInt32 nPropPos = nStartPos + dumpHex< sal_uInt32 >( "start-pos" );
+ aPropMap[ nPropId ] = nPropPos;
+ }
+ }
+ }
+ rOut.emptyLine();
+
+ // code page property
+ meTextEnc = osl_getThreadTextEncoding();
+ mbIsUnicode = false;
+ PropertyPosMap::iterator aCodePageIt = aPropMap.find( OLEPROP_ID_CODEPAGE );
+ if( aCodePageIt != aPropMap.end() )
+ {
+ dumpCodePageProperty( aCodePageIt->second );
+ aPropMap.erase( aCodePageIt );
+ }
+
+ // dictionary property
+ PropertyPosMap::iterator aDictIt = aPropMap.find( OLEPROP_ID_DICTIONARY );
+ if( aDictIt != aPropMap.end() )
+ {
+ dumpDictionaryProperty( aDictIt->second );
+ aPropMap.erase( aDictIt );
+ }
+
+ // other properties
+ for( PropertyPosMap::const_iterator aIt = aPropMap.begin(), aEnd = aPropMap.end(); aIt != aEnd; ++aIt )
+ dumpProperty( aIt->first, aIt->second );
+
+ // remove the user defined list of property ID names
+ cfg().eraseNameList( "OLEPROP-IDS" );
+}
+
+void OlePropertyStreamObject::dumpProperty( sal_Int32 nPropId, sal_uInt32 nStartPos )
+{
+ writePropertyHeader( nPropId, nStartPos );
+ IndentGuard aIndGuard( out() );
+ if( startElement( nStartPos ) )
+ dumpPropertyContents( nPropId );
+ out().emptyLine();
+}
+
+void OlePropertyStreamObject::dumpCodePageProperty( sal_uInt32 nStartPos )
+{
+ writePropertyHeader( OLEPROP_ID_CODEPAGE, nStartPos );
+ IndentGuard aIndGuard( out() );
+ if( startElement( nStartPos ) )
+ {
+ sal_Int32 nType = dumpPropertyType();
+ if( nType == OLEPROP_TYPE_INT16 )
+ {
+ sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" );
+ rtl_TextEncoding nNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
+ if( nNewTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ meTextEnc = nNewTextEnc;
+ mbIsUnicode = nCodePage == CODEPAGE_UNICODE;
+ }
+ else
+ dumpPropertyContents( OLEPROP_ID_CODEPAGE );
+ }
+ out().emptyLine();
+}
+
+void OlePropertyStreamObject::dumpDictionaryProperty( sal_uInt32 nStartPos )
+{
+ writePropertyHeader( OLEPROP_ID_DICTIONARY, nStartPos );
+ IndentGuard aIndGuard( out() );
+ if( startElement( nStartPos ) )
+ {
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "count" );
+ for( sal_Int32 nIdx = 0; (nIdx < nCount) && in().isValidPos(); ++nIdx )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ TableGuard aTabGuard( out(), 10, 20 );
+ sal_Int32 nId = dumpDec< sal_Int32 >( "id" );
+ OUString aName = dumpString8( "name" );
+ if( mxPropIds.get() )
+ mxPropIds->setName( nId, aName );
+ }
+ }
+ out().emptyLine();
+}
+
+void OlePropertyStreamObject::dumpPropertyContents( sal_Int32 nPropId )
+{
+ sal_Int32 nType = dumpPropertyType();
+ if( getFlag< sal_Int32 >( nType, 0x1000 ) ) // vector
+ {
+ sal_Int32 nBaseType = nType & 0x0FFF;
+ sal_Int32 nElemCount = dumpDec< sal_Int32 >( "element-count" );
+ for( sal_Int32 nElemIdx = 0; (nElemIdx < nElemCount) && in().isValidPos(); ++nElemIdx )
+ {
+ out().resetItemIndex( nElemIdx );
+ writeEmptyItem( "#element" );
+ IndentGuard aIndGuard( out() );
+ dumpPropertyValue( nPropId, nBaseType );
+ }
+ }
+ else if( !getFlag< sal_Int32 >( nType, 0x7000 ) )
+ {
+ dumpPropertyValue( nPropId, nType );
+ }
+}
+
+void OlePropertyStreamObject::dumpPropertyValue( sal_Int32 nPropId, sal_Int32 nBaseType )
+{
+ switch( nBaseType )
+ {
+ case OLEPROP_TYPE_INT16: dumpDec< sal_Int16 >( "value" ); break;
+ case OLEPROP_TYPE_INT32: dumpDec< sal_Int32 >( "value" ); break;
+ case OLEPROP_TYPE_FLOAT: dumpDec< float >( "value" ); break;
+ case OLEPROP_TYPE_DOUBLE: dumpDec< double >( "value" ); break;
+ case OLEPROP_TYPE_DATE: dumpDec< double >( "date" ); break;
+ case OLEPROP_TYPE_STRING: dumpString8( "value" ); break;
+ case OLEPROP_TYPE_STATUS: dumpHex< sal_Int32 >( "status" ); break;
+ case OLEPROP_TYPE_BOOL: dumpBool< sal_Int16 >( "value" ); break;
+ case OLEPROP_TYPE_VARIANT: dumpPropertyContents( nPropId ); break;
+ case OLEPROP_TYPE_INT8: dumpDec< sal_Int8 >( "value" ); break;
+ case OLEPROP_TYPE_UINT8: dumpDec< sal_uInt8 >( "value" ); break;
+ case OLEPROP_TYPE_UINT16: dumpDec< sal_uInt16 >( "value" ); break;
+ case OLEPROP_TYPE_UINT32: dumpDec< sal_uInt32 >( "value" ); break;
+ case OLEPROP_TYPE_INT64: dumpDec< sal_Int64 >( "value" ); break;
+ case OLEPROP_TYPE_UINT64: dumpDec< sal_uInt64 >( "value" ); break;
+ case OLEPROP_TYPE_STRING8: dumpString8( "value" ); break;
+ case OLEPROP_TYPE_STRING16: dumpString16( "value" ); break;
+ case OLEPROP_TYPE_FILETIME: dumpFileTime( "file-time" ); break;
+ case OLEPROP_TYPE_BLOB: dumpBlob( "data" ); break;
+ case OLEPROP_TYPE_STREAM: dumpString8( "stream-name" ); break;
+ case OLEPROP_TYPE_STORAGE: dumpString8( "storage-name" ); break;
+ case OLEPROP_TYPE_CLIPFMT: dumpBlob( "clip-data" ); break;
+ }
+}
+
+sal_Int32 OlePropertyStreamObject::dumpPropertyType()
+{
+ return dumpHex< sal_Int32 >( "type", "OLEPROP-TYPE" );
+}
+
+void OlePropertyStreamObject::dumpBlob( const sal_Char* pcName )
+{
+ sal_Int32 nSize = dumpDec< sal_Int32 >( "data-size" );
+ if( nSize > 0 )
+ dumpBinary( pcName, nSize );
+}
+
+OUString OlePropertyStreamObject::dumpString8( const sal_Char* pcName )
+{
+ sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
+ return mbIsUnicode ? dumpCharArray16( pcName, nLen ) : dumpCharArray8( pcName, nLen );
+}
+
+OUString OlePropertyStreamObject::dumpCharArray8( const sal_Char* pcName, sal_Int32 nCharCount )
+{
+ OUString aData;
+ size_t nLen = getLimitedValue< size_t, sal_Int32 >( nCharCount, 0, 1024 );
+ if( nLen > 0 )
+ {
+ ::std::vector< sal_Char > aBuffer( nLen + 1 );
+ in().read( &aBuffer.front(), nLen );
+ aBuffer[ nLen ] = 0;
+ aData = OStringToOUString( OString( &aBuffer.front() ), meTextEnc );
+ }
+ writeStringItem( pcName, aData );
+ return aData;
+}
+
+OUString OlePropertyStreamObject::dumpString16( const sal_Char* pcName )
+{
+ sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
+ return dumpCharArray16( pcName, nLen );
+}
+
+OUString OlePropertyStreamObject::dumpCharArray16( const sal_Char* pcName, sal_Int32 nCharCount )
+{
+ size_t nLen = getLimitedValue< size_t, sal_Int32 >( nCharCount, 0, 1024 );
+ ::std::vector< sal_Unicode > aBuffer;
+ aBuffer.reserve( nLen + 1 );
+ for( size_t nIdx = 0; nIdx < nLen; ++nIdx )
+ aBuffer.push_back( static_cast< sal_Unicode >( in().readValue< sal_uInt16 >() ) );
+ aBuffer.push_back( 0 );
+ OUString aData( &aBuffer.front() );
+ writeStringItem( pcName, aData );
+ if( nLen & 1 ) dumpUnused( 2 ); // always padding to 32bit
+ return aData;
+}
+
+DateTime OlePropertyStreamObject::dumpFileTime( const sal_Char* pcName )
+{
+ DateTime aDateTime;
+
+ ItemGuard aItem( out(), pcName );
+ sal_Int64 nFileTime = dumpDec< sal_Int64 >( 0 );
+ // file time is in 10^-7 seconds (100 nanoseconds), convert to 1/100 seconds
+ nFileTime /= 100000;
+ // entire days
+ sal_Int64 nDays = nFileTime / sal_Int64( 360000 * 24 );
+ // number of entire years
+ sal_Int64 nYears = (nDays - (nDays / (4 * 365)) + (nDays / (100 * 365)) - (nDays / (400 * 365))) / 365;
+ // remaining days in the year
+ sal_Int64 nDaysInYear = nDays - (nYears * 365 + nYears / 4 - nYears / 100 + nYears / 400);
+ // the year (file dates start from 1601-01-01)
+ aDateTime.Year = static_cast< sal_uInt16 >( 1601 + nYears );
+ // leap year?
+ bool bLeap = ((aDateTime.Year % 4 == 0) && (aDateTime.Year % 100 != 0)) || (aDateTime.Year % 400 == 0);
+ // static arrays with number of days in month
+ static const sal_Int64 spnDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ static const sal_Int64 spnDaysInMonthL[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ const sal_Int64* pnDaysInMonth = bLeap ? spnDaysInMonthL : spnDaysInMonth;
+ // the month
+ aDateTime.Month = 1;
+ while( nDaysInYear >= *pnDaysInMonth )
+ {
+ nDaysInYear -= *pnDaysInMonth++;
+ ++aDateTime.Month;
+ }
+ // the day
+ aDateTime.Day = static_cast< sal_uInt16 >( nDaysInYear + 1 );
+ // number of 1/100 seconds in the day
+ sal_Int64 nTimeInDay = nFileTime % sal_Int64( 360000 * 24 );
+ // 1/100 seconds
+ aDateTime.HundredthSeconds = static_cast< sal_uInt16 >( nTimeInDay % 100 );
+ nTimeInDay /= 100;
+ // seconds
+ aDateTime.Seconds = static_cast< sal_uInt16 >( nTimeInDay % 60 );
+ nTimeInDay /= 60;
+ // minutes
+ aDateTime.Minutes = static_cast< sal_uInt16 >( nTimeInDay % 60 );
+ nTimeInDay /= 60;
+ // hours
+ aDateTime.Hours = static_cast< sal_uInt16 >( nTimeInDay );
+
+// aDateTime.convertToLocalTime();
+ writeDateTimeItem( 0, aDateTime );
+ return aDateTime;
+}
+
+bool OlePropertyStreamObject::startElement( sal_uInt32 nStartPos )
+{
+ sal_Int64 nStartPos64 = static_cast< sal_Int64>( nStartPos );
+ bool bPosOk = nStartPos64 < in().getSize();
+ if( bPosOk )
+ in().seek( nStartPos64 );
+ else
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+ return bPosOk;
+}
+
+void OlePropertyStreamObject::writeSectionHeader( const OUString& rGuid, sal_uInt32 nStartPos )
+{
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( "SECTION" );
+ writeGuidItem( "guid", rGuid );
+ writeHexItem( "pos", nStartPos );
+}
+
+void OlePropertyStreamObject::writePropertyHeader( sal_Int32 nPropId, sal_uInt32 nStartPos )
+{
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( "PROPERTY" );
+ writeDecItem( "id", nPropId, mxPropIds );
+ writeHexItem( "pos", nStartPos );
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx
new file mode 100644
index 000000000000..3dd2e66cdb77
--- /dev/null
+++ b/oox/source/dump/xlsbdumper.cxx
@@ -0,0 +1,1920 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xlsbdumper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/dump/xlsbdumper.hxx"
+#include <com/sun/star/io/XTextInputStream.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/formulabase.hxx"
+#include "oox/xls/ooxtokens.hxx"
+#include "oox/xls/richstring.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::sheet::XSpreadsheetDocument;
+using ::oox::core::FilterBase;
+
+using namespace ::oox::xls;
+
+namespace oox {
+namespace dump {
+namespace xlsb {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt8 OOBIN_STRINGFLAG_FONTS = 0x01;
+const sal_uInt8 OOBIN_STRINGFLAG_PHONETICS = 0x02;
+
+const sal_uInt8 OOBIN_TOK_ARRAY_DOUBLE = 0;
+const sal_uInt8 OOBIN_TOK_ARRAY_STRING = 1;
+const sal_uInt8 OOBIN_TOK_ARRAY_BOOL = 2;
+const sal_uInt8 OOBIN_TOK_ARRAY_ERROR = 4;
+
+} // namespace
+
+// ============================================================================
+
+RecordStreamInput::RecordStreamInput() :
+ mxStrm( new RecordInputStream( RecordDataSequence() ) )
+{
+}
+
+RecordStreamInput::~RecordStreamInput()
+{
+}
+
+bool RecordStreamInput::implIsValid() const
+{
+ return mxStrm.get() && Input::implIsValid();
+}
+
+void RecordStreamInput::createStream( const RecordDataSequence& rData )
+{
+ mxStrm.reset( new RecordInputStream( rData ) );
+}
+
+sal_Int64 RecordStreamInput::getSize() const
+{
+ return mxStrm->getRecSize();
+}
+
+sal_Int64 RecordStreamInput::tell() const
+{
+ return mxStrm->getRecPos();
+}
+
+void RecordStreamInput::seek( sal_Int64 nPos )
+{
+ mxStrm->seek( static_cast< sal_Int32 >( nPos ) );
+}
+
+void RecordStreamInput::skip( sal_Int32 nBytes )
+{
+ mxStrm->skip( nBytes );
+}
+
+sal_Int32 RecordStreamInput::read( void* pBuffer, sal_Int32 nSize )
+{
+ return mxStrm->read( pBuffer, nSize );
+}
+
+RecordStreamInput& RecordStreamInput::operator>>( sal_Int8& rnData ) { *mxStrm >> rnData; return *this; }
+RecordStreamInput& RecordStreamInput::operator>>( sal_uInt8& rnData ) { *mxStrm >> rnData; return *this; }
+RecordStreamInput& RecordStreamInput::operator>>( sal_Int16& rnData ) { *mxStrm >> rnData; return *this; }
+RecordStreamInput& RecordStreamInput::operator>>( sal_uInt16& rnData ) { *mxStrm >> rnData; return *this; }
+RecordStreamInput& RecordStreamInput::operator>>( sal_Int32& rnData ) { *mxStrm >> rnData; return *this; }
+RecordStreamInput& RecordStreamInput::operator>>( sal_uInt32& rnData ) { *mxStrm >> rnData; return *this; }
+RecordStreamInput& RecordStreamInput::operator>>( float& rfData ) { *mxStrm >> rfData; return *this; }
+RecordStreamInput& RecordStreamInput::operator>>( double& rfData ) { *mxStrm >> rfData; return *this; }
+
+// ============================================================================
+
+RecordObjectBase::RecordObjectBase()
+{
+}
+
+RecordObjectBase::~RecordObjectBase()
+{
+}
+
+void RecordObjectBase::construct( const OutputObjectBase& rParent )
+{
+ mxStrmIn.reset( new RecordStreamInput );
+ InputObjectBase::construct( rParent, mxStrmIn );
+ constructRecObjBase();
+}
+
+void RecordObjectBase::construct( const RecordObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool RecordObjectBase::implIsValid() const
+{
+ return isValid( mxStrmIn ) && InputObjectBase::implIsValid();
+}
+
+void RecordObjectBase::createRecordStream( const RecordDataSequence& rData )
+{
+ mxStrmIn->createStream( rData );
+}
+
+OUString RecordObjectBase::getErrorName( sal_uInt8 nErrCode ) const
+{
+ return cfg().getName( mxErrCodes, nErrCode );
+}
+
+// ------------------------------------------------------------------------
+
+void RecordObjectBase::readAddress( Address& orAddress )
+{
+ in() >> orAddress.mnRow >> orAddress.mnCol;
+}
+
+void RecordObjectBase::readRange( Range& orRange )
+{
+ in() >> orRange.maFirst.mnRow >> orRange.maLast.mnRow >> orRange.maFirst.mnCol >> orRange.maLast.mnCol;
+}
+
+void RecordObjectBase::readRangeList( RangeList& orRanges )
+{
+ sal_Int32 nCount;
+ in() >> nCount;
+ if( nCount >= 0 )
+ {
+ orRanges.resize( getLimitedValue< size_t, sal_Int32 >( nCount, 0, SAL_MAX_UINT16 ) );
+ for( RangeList::iterator aIt = orRanges.begin(), aEnd = orRanges.end(); in().isValidPos() && (aIt != aEnd); ++aIt )
+ readRange( *aIt );
+ }
+ else
+ orRanges.clear();
+}
+
+// ----------------------------------------------------------------------------
+
+void RecordObjectBase::writeBooleanItem( const sal_Char* pcName, sal_uInt8 nBool )
+{
+ writeDecItem( pcName, nBool, "BOOLEAN" );
+}
+
+void RecordObjectBase::writeErrorCodeItem( const sal_Char* pcName, sal_uInt8 nErrCode )
+{
+ writeHexItem( pcName, nErrCode, mxErrCodes );
+}
+
+void RecordObjectBase::writeFontPortions( const BinFontPortionList& rPortions )
+{
+ if( !rPortions.empty() )
+ {
+ writeDecItem( "font-count", static_cast< sal_uInt32 >( rPortions.size() ) );
+ IndentGuard aIndGuard( out() );
+ TableGuard aTabGuard( out(), 14 );
+ for( BinFontPortionList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeDecItem( "char-pos", aIt->mnPos );
+ writeDecItem( "font-id", aIt->mnFontId, "FONTNAMES" );
+ }
+ }
+}
+
+void RecordObjectBase::writePhoneticPortions( const BinPhoneticPortionList& rPortions )
+{
+ if( !rPortions.empty() )
+ {
+ writeDecItem( "portion-count", static_cast< sal_uInt32 >( rPortions.size() ) );
+ IndentGuard aIndGuard( out() );
+ TableGuard aTabGuard( out(), 14, 21 );
+ for( BinPhoneticPortionList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeDecItem( "char-pos", aIt->mnPos );
+ writeDecItem( "base-text-start", aIt->mnBasePos );
+ writeDecItem( "base-text-length", aIt->mnBaseLen );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+sal_uInt8 RecordObjectBase::dumpBoolean( const sal_Char* pcName )
+{
+ sal_uInt8 nBool;
+ in() >> nBool;
+ writeBooleanItem( pcName ? pcName : "boolean", nBool );
+ return nBool;
+}
+
+sal_uInt8 RecordObjectBase::dumpErrorCode( const sal_Char* pcName )
+{
+ sal_uInt8 nErrCode;
+ in() >> nErrCode;
+ writeErrorCodeItem( pcName ? pcName : "errorcode", nErrCode );
+ return nErrCode;
+}
+
+OUString RecordObjectBase::dumpString( const sal_Char* pcName, bool bRich, bool b32BitLen )
+{
+ sal_uInt8 nFlags = bRich ? dumpHex< sal_uInt8 >( "flags", "STRING-FLAGS" ) : 0;
+
+ OUString aString = getRecordStream().readString( b32BitLen );
+ writeStringItem( pcName ? pcName : "text", aString );
+
+ // --- formatting ---
+ if( getFlag( nFlags, OOBIN_STRINGFLAG_FONTS ) )
+ {
+ IndentGuard aIndGuard( out() );
+ BinFontPortionList aPortions;
+ aPortions.importPortions( getRecordStream() );
+ writeFontPortions( aPortions );
+ }
+
+ // --- phonetic text ---
+ if( getFlag( nFlags, OOBIN_STRINGFLAG_PHONETICS ) )
+ {
+ IndentGuard aIndGuard( out() );
+ dumpString( "phonetic-text" );
+ BinPhoneticPortionList aPortions;
+ aPortions.importPortions( getRecordStream() );
+ writePhoneticPortions( aPortions );
+ dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
+ dumpHex< sal_uInt16 >( "flags", "PHONETIC-FLAGS" );
+ }
+
+ return aString;
+}
+
+void RecordObjectBase::dumpColor( const sal_Char* pcName )
+{
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( pcName ? pcName : "color" );
+ switch( dumpDec< sal_uInt8 >( "type", "COLOR-TYPE" ) )
+ {
+ case 0:
+ case 1:
+ case 3: dumpDec< sal_uInt8 >( "index", "PALETTE-COLORS" ); break;
+ case 5: dumpUnused( 1 ); break;
+ case 7: dumpDec< sal_uInt8 >( "theme-id" ); break;
+ default: dumpUnknown( 1 );
+ }
+ dumpDec< sal_Int16 >( "tint", "CONV-TINT" );
+ sal_uInt8 nR, nG, nB, nA;
+ in() >> nR >> nG >> nB >> nA;
+ writeColorItem( "rgb", (((((static_cast< sal_Int32 >( nA ) << 8) | nR) << 8) | nG) << 8) | nB );
+}
+
+sal_Int32 RecordObjectBase::dumpColIndex( const sal_Char* pcName )
+{
+ sal_Int32 nCol;
+ in() >> nCol;
+ writeColIndexItem( pcName ? pcName : "col-idx", nCol );
+ return nCol;
+}
+
+sal_Int32 RecordObjectBase::dumpRowIndex( const sal_Char* pcName )
+{
+ sal_Int32 nRow;
+ in() >> nRow;
+ writeRowIndexItem( pcName ? pcName : "row-idx", nRow );
+ return nRow;
+}
+
+sal_Int32 RecordObjectBase::dumpColRange( const sal_Char* pcName )
+{
+ sal_Int32 nCol1, nCol2;
+ in() >> nCol1 >> nCol2;
+ writeColRangeItem( pcName ? pcName : "col-range", nCol1, nCol2 );
+ return nCol2 - nCol1 + 1;
+}
+
+sal_Int32 RecordObjectBase::dumpRowRange( const sal_Char* pcName )
+{
+ sal_Int32 nRow1, nRow2;
+ in() >> nRow1 >> nRow2;
+ writeRowRangeItem( pcName ? pcName : "row-range", nRow1, nRow2 );
+ return nRow2 - nRow1 + 1;
+}
+
+Address RecordObjectBase::dumpAddress( const sal_Char* pcName )
+{
+ Address aPos;
+ readAddress( aPos );
+ writeAddressItem( pcName ? pcName : "addr", aPos );
+ return aPos;
+}
+
+Range RecordObjectBase::dumpRange( const sal_Char* pcName )
+{
+ Range aRange;
+ readRange( aRange );
+ writeRangeItem( pcName ? pcName : "range", aRange );
+ return aRange;
+}
+
+void RecordObjectBase::dumpRangeList( const sal_Char* pcName )
+{
+ RangeList aRanges;
+ readRangeList( aRanges );
+ writeRangeListItem( pcName ? pcName : "range-list", aRanges );
+}
+
+// ----------------------------------------------------------------------------
+
+void RecordObjectBase::constructRecObjBase()
+{
+ if( RecordObjectBase::implIsValid() )
+ mxErrCodes = cfg().getNameList( "ERRORCODES" );
+}
+
+// ============================================================================
+
+FormulaObject::FormulaObject( const RecordObjectBase& rParent ) :
+ mpcName( 0 ),
+ mnSize( 0 )
+{
+ RecordObjectBase::construct( rParent );
+ constructFmlaObj();
+}
+
+FormulaObject::~FormulaObject()
+{
+}
+
+void FormulaObject::dumpCellFormula( const sal_Char* pcName )
+{
+ dumpFormula( pcName, false );
+}
+
+void FormulaObject::dumpNameFormula( const sal_Char* pcName )
+{
+ dumpFormula( pcName, true );
+}
+
+void FormulaObject::implDump()
+{
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( mpcName );
+ writeDecItem( "formula-size", mnSize );
+ }
+ if( mnSize < 0 ) return;
+
+ Input& rIn = in();
+ sal_Int64 nStartPos = rIn.tell();
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, rIn.getSize() );
+
+ bool bValid = mxTokens.get();
+ mxStack.reset( new FormulaStack );
+ maAddData.clear();
+ IndentGuard aIndGuard( out() );
+ {
+ TableGuard aTabGuard( out(), 8, 18 );
+ while( bValid && (rIn.tell() < nEndPos) )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeHexItem( 0, static_cast< sal_uInt16 >( rIn.tell() - nStartPos ) );
+ sal_uInt8 nTokenId = dumpHex< sal_uInt8 >( 0, mxTokens );
+ bValid = mxTokens->hasName( nTokenId );
+ if( bValid )
+ {
+ sal_uInt8 nTokClass = nTokenId & BIFF_TOKCLASS_MASK;
+ sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
+ if( nTokClass == BIFF_TOKCLASS_NONE )
+ {
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_EXP: dumpExpToken( "EXP" ); break;
+ case BIFF_TOKID_ADD: dumpBinaryOpToken( "+" ); break;
+ case BIFF_TOKID_SUB: dumpBinaryOpToken( "-" ); break;
+ case BIFF_TOKID_MUL: dumpBinaryOpToken( "*" ); break;
+ case BIFF_TOKID_DIV: dumpBinaryOpToken( "/" ); break;
+ case BIFF_TOKID_POWER: dumpBinaryOpToken( "^" ); break;
+ case BIFF_TOKID_CONCAT: dumpBinaryOpToken( "&" ); break;
+ case BIFF_TOKID_LT: dumpBinaryOpToken( "<" ); break;
+ case BIFF_TOKID_LE: dumpBinaryOpToken( "<=" ); break;
+ case BIFF_TOKID_EQ: dumpBinaryOpToken( "=" ); break;
+ case BIFF_TOKID_GE: dumpBinaryOpToken( ">=" ); break;
+ case BIFF_TOKID_GT: dumpBinaryOpToken( "<" ); break;
+ case BIFF_TOKID_NE: dumpBinaryOpToken( "<>" ); break;
+ case BIFF_TOKID_ISECT: dumpBinaryOpToken( " " ); break;
+ case BIFF_TOKID_LIST: dumpBinaryOpToken( "," ); break;
+ case BIFF_TOKID_RANGE: dumpBinaryOpToken( ":" ); break;
+ case BIFF_TOKID_UPLUS: dumpUnaryOpToken( "+", "" ); break;
+ case BIFF_TOKID_UMINUS: dumpUnaryOpToken( "-", "" ); break;
+ case BIFF_TOKID_PERCENT: dumpUnaryOpToken( "", "%" ); break;
+ case BIFF_TOKID_PAREN: dumpUnaryOpToken( "(", ")" ); break;
+ case BIFF_TOKID_MISSARG: dumpMissArgToken(); break;
+ case BIFF_TOKID_STR: dumpStringToken(); break;
+ case BIFF_TOKID_NLR: bValid = dumpTableToken(); break;
+ case BIFF_TOKID_ATTR: bValid = dumpAttrToken(); break;
+ case BIFF_TOKID_ERR: dumpErrorToken(); break;
+ case BIFF_TOKID_BOOL: dumpBoolToken(); break;
+ case BIFF_TOKID_INT: dumpIntToken(); break;
+ case BIFF_TOKID_NUM: dumpDoubleToken(); break;
+ default: bValid = false;
+ }
+ }
+ else
+ {
+ OUString aTokClass = cfg().getName( mxClasses, nTokClass );
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_ARRAY: dumpArrayToken( aTokClass ); break;
+ case BIFF_TOKID_FUNC: dumpFuncToken( aTokClass ); break;
+ case BIFF_TOKID_FUNCVAR: dumpFuncVarToken( aTokClass ); break;
+ case BIFF_TOKID_NAME: dumpNameToken( aTokClass ); break;
+ case BIFF_TOKID_REF: dumpRefToken( aTokClass, false ); break;
+ case BIFF_TOKID_AREA: dumpAreaToken( aTokClass, false ); break;
+ case BIFF_TOKID_MEMAREA: dumpMemAreaToken( aTokClass, true ); break;
+ case BIFF_TOKID_MEMERR: dumpMemAreaToken( aTokClass, false ); break;
+ case BIFF_TOKID_MEMNOMEM: dumpMemAreaToken( aTokClass, false ); break;
+ case BIFF_TOKID_MEMFUNC: dumpMemFuncToken( aTokClass ); break;
+ case BIFF_TOKID_REFERR: dumpRefErrToken( aTokClass, false ); break;
+ case BIFF_TOKID_AREAERR: dumpRefErrToken( aTokClass, true ); break;
+ case BIFF_TOKID_REFN: dumpRefToken( aTokClass, true ); break;
+ case BIFF_TOKID_AREAN: dumpAreaToken( aTokClass, true ); break;
+ case BIFF_TOKID_MEMAREAN: dumpMemFuncToken( aTokClass ); break;
+ case BIFF_TOKID_MEMNOMEMN: dumpMemFuncToken( aTokClass ); break;
+ case BIFF_TOKID_NAMEX: dumpNameXToken( aTokClass ); break;
+ case BIFF_TOKID_REF3D: dumpRef3dToken( aTokClass, mbNameMode ); break;
+ case BIFF_TOKID_AREA3D: dumpArea3dToken( aTokClass, mbNameMode ); break;
+ case BIFF_TOKID_REFERR3D: dumpRefErr3dToken( aTokClass, false ); break;
+ case BIFF_TOKID_AREAERR3D: dumpRefErr3dToken( aTokClass, true ); break;
+ default: bValid = false;
+ }
+ }
+ }
+ }
+ }
+
+ if( nEndPos == rIn.tell() )
+ {
+ dumpAddTokenData();
+ if( mnSize > 0 )
+ {
+ writeInfoItem( "formula", mxStack->getFormulaString() );
+ writeInfoItem( "classes", mxStack->getClassesString() );
+ }
+ }
+ else
+ {
+ dumpBinary( OOX_DUMP_ERRASCII( "formula-error" ), static_cast< sal_Int32 >( nEndPos - rIn.tell() ), false );
+ sal_Int32 nAddDataSize = dumpDec< sal_Int32 >( "add-data-size" );
+ dumpBinary( "add-data", nAddDataSize, false );
+ }
+
+ mpcName = 0;
+ mnSize = 0;
+}
+
+void FormulaObject::dumpFormula( const sal_Char* pcName, bool bNameMode )
+{
+ mpcName = pcName ? pcName : "formula";
+ in() >> mnSize;
+ mbNameMode = bNameMode;
+ dump();
+}
+
+// private --------------------------------------------------------------------
+
+void FormulaObject::constructFmlaObj()
+{
+ if( RecordObjectBase::implIsValid() )
+ {
+ Reference< XSpreadsheetDocument > xDocument( getFilter().getModel(), UNO_QUERY );
+ mxFuncProv.reset( new FunctionProvider( xDocument, true ) );
+
+ Config& rCfg = cfg();
+ mxClasses = rCfg.getNameList( "TOKENCLASSES" );
+ mxRelFlags = rCfg.getNameList( "REFRELFLAGS" );
+ mxAttrTypes = rCfg.getNameList( "ATTRTYPES" );
+ mxSpTypes = rCfg.getNameList( "ATTRSPACETYPES" );
+
+ // create classified token names
+ mxTokens = rCfg.createNameList< ConstList >( "TOKENS" );
+ mxTokens->includeList( rCfg.getNameList( "BASETOKENS" ) );
+
+ NameListRef xClassTokens = rCfg.getNameList( "CLASSTOKENS" );
+ if( mxClasses.get() && xClassTokens.get() )
+ for( NameListBase::const_iterator aCIt = mxClasses->begin(), aCEnd = mxClasses->end(); aCIt != aCEnd; ++aCIt )
+ for( NameListBase::const_iterator aTIt = xClassTokens->begin(), aTEnd = xClassTokens->end(); aTIt != aTEnd; ++aTIt )
+ mxTokens->setName( aCIt->first | aTIt->first, aTIt->second + aCIt->second );
+
+ mnColCount = 16384;
+ mnRowCount = 1024 * 1024;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+OUString lclCreateName( const OUString& rRef, sal_Int32 nNameId )
+{
+ OUStringBuffer aName( rRef );
+ StringHelper::appendIndexedText( aName, CREATE_OUSTRING( "NAME" ), nNameId );
+ return aName.makeStringAndClear();
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+TokenAddress FormulaObject::createTokenAddress( sal_Int32 nCol, sal_Int32 nRow, bool bRelC, bool bRelR, bool bNameMode ) const
+{
+ TokenAddress aPos;
+ aPos.mnCol = nCol;
+ if( bRelC && bNameMode && (nCol >= mnColCount / 2) ) aPos.mnCol -= mnColCount;
+ aPos.mbRelCol = bRelC;
+ aPos.mnRow = nRow;
+ if( bRelR && bNameMode && (nRow >= mnRowCount / 2) ) aPos.mnRow -= mnRowCount;
+ aPos.mbRelRow = bRelR;
+ return aPos;
+}
+
+OUString FormulaObject::createRef( const OUString& rData ) const
+{
+ return maRefPrefix + rData;
+}
+
+OUString FormulaObject::createName( sal_Int32 nNameId ) const
+{
+ return lclCreateName( maRefPrefix, nNameId );
+}
+
+OUString FormulaObject::createPlaceHolder( size_t nIdx ) const
+{
+ OUStringBuffer aStr;
+ StringHelper::appendDec( aStr, static_cast< sal_uInt32 >( nIdx ) );
+ StringHelper::enclose( aStr, OOX_DUMP_PLACEHOLDER );
+ return aStr.makeStringAndClear();
+}
+
+OUString FormulaObject::createPlaceHolder() const
+{
+ return createPlaceHolder( maAddData.size() );
+}
+
+OUString FormulaObject::writeFuncIdItem( sal_uInt16 nFuncId, const FunctionInfo** oppFuncInfo )
+{
+ ItemGuard aItemGuard( out(), "func-id" );
+ writeHexItem( 0, nFuncId, "FUNCID" );
+ OUStringBuffer aBuffer;
+ const FunctionInfo* pFuncInfo = mxFuncProv->getFuncInfoFromOobFuncId( nFuncId );
+ if( pFuncInfo )
+ aBuffer.append( pFuncInfo->maOoxFuncName );
+ else
+ {
+ bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
+ aBuffer.appendAscii( bCmd ? "CMD" : "FUNC" );
+ StringHelper::appendIndex( aBuffer, nFuncId & BIFF_TOK_FUNCVAR_FUNCIDMASK );
+ }
+ OUString aFuncName = aBuffer.makeStringAndClear();
+ aItemGuard.cont();
+ out().writeString( aFuncName );
+ if( oppFuncInfo ) *oppFuncInfo = pFuncInfo;
+ return aFuncName;
+}
+
+sal_Int32 FormulaObject::dumpTokenCol( const sal_Char* pcName, bool& rbRelC, bool& rbRelR )
+{
+ sal_uInt16 nCol = dumpHex< sal_uInt16 >( pcName, mxRelFlags );
+ rbRelC = getFlag( nCol, OOBIN_TOK_REF_COLREL );
+ rbRelR = getFlag( nCol, OOBIN_TOK_REF_ROWREL );
+ nCol &= OOBIN_TOK_REF_COLMASK;
+ return nCol;
+}
+
+sal_Int32 FormulaObject::dumpTokenRow( const sal_Char* pcName )
+{
+ return dumpDec< sal_Int32 >( pcName );
+}
+
+TokenAddress FormulaObject::dumpTokenAddress( bool bNameMode )
+{
+ bool bRelC = false;
+ bool bRelR = false;
+ sal_Int32 nRow = dumpTokenRow( "row" );
+ sal_Int32 nCol = dumpTokenCol( "col", bRelC, bRelR );
+ return createTokenAddress( nCol, nRow, bRelC, bRelR, bNameMode );
+}
+
+TokenRange FormulaObject::dumpTokenRange( bool bNameMode )
+{
+ bool bRelC1 = false;
+ bool bRelR1 = false;
+ bool bRelC2 = false;
+ bool bRelR2 = false;
+ sal_Int32 nRow1 = dumpTokenRow( "row1" );
+ sal_Int32 nRow2 = dumpTokenRow( "row2" );
+ sal_Int32 nCol1 = dumpTokenCol( "col1", bRelC1, bRelR1 );
+ sal_Int32 nCol2 = dumpTokenCol( "col2", bRelC2, bRelR2 );
+ TokenRange aRange;
+ aRange.maFirst = createTokenAddress( nCol1, nRow1, bRelC1, bRelR1, bNameMode );
+ aRange.maLast = createTokenAddress( nCol2, nRow2, bRelC2, bRelR2, bNameMode );
+ return aRange;
+}
+
+sal_Int16 FormulaObject::readTokenRefId()
+{
+ return dumpDec< sal_Int16 >( "ref-id" );
+}
+
+OUString FormulaObject::dumpTokenRefId()
+{
+ OUStringBuffer aRef( CREATE_OUSTRING( "REF" ) );
+ StringHelper::appendIndex( aRef, readTokenRefId() );
+ aRef.append( OOX_DUMP_TABSEP );
+ return aRef.makeStringAndClear();
+}
+
+void FormulaObject::dumpIntToken()
+{
+ dumpDec< sal_uInt16 >( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpDoubleToken()
+{
+ dumpDec< double >( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpStringToken()
+{
+ OUStringBuffer aBuffer( dumpString( "value", false, false ) );
+ StringHelper::enclose( aBuffer, OOX_DUMP_FMLASTRQUOTE );
+ mxStack->pushOperand( aBuffer.makeStringAndClear() );
+}
+
+void FormulaObject::dumpBoolToken()
+{
+ dumpBoolean( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpErrorToken()
+{
+ dumpErrorCode( "value" );
+ mxStack->pushOperand( out().getLastItemValue() );
+}
+
+void FormulaObject::dumpMissArgToken()
+{
+ mxStack->pushOperand( OUString( OOX_DUMP_EMPTYVALUE ) );
+}
+
+void FormulaObject::dumpArrayToken( const OUString& rTokClass )
+{
+ dumpUnused( 14 );
+ mxStack->pushOperand( createPlaceHolder(), rTokClass );
+ maAddData.push_back( ADDDATA_ARRAY );
+}
+
+void FormulaObject::dumpNameToken( const OUString& rTokClass )
+{
+ sal_Int32 nNameId = dumpDec< sal_Int32 >( "name-id" );
+ mxStack->pushOperand( createName( nNameId ), rTokClass );
+}
+
+void FormulaObject::dumpNameXToken( const OUString& rTokClass )
+{
+ OUString aRef = dumpTokenRefId();
+ sal_Int32 nNameId = dumpDec< sal_Int32 >( "name-id" );
+ mxStack->pushOperand( lclCreateName( aRef, nNameId ), rTokClass );
+}
+
+void FormulaObject::dumpRefToken( const OUString& rTokClass, bool bNameMode )
+{
+ TokenAddress aPos = dumpTokenAddress( bNameMode );
+ writeTokenAddressItem( "addr", aPos, bNameMode );
+ mxStack->pushOperand( createRef( out().getLastItemValue() ), rTokClass );
+}
+
+void FormulaObject::dumpAreaToken( const OUString& rTokClass, bool bNameMode )
+{
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRangeItem( "range", aRange, bNameMode );
+ mxStack->pushOperand( createRef( out().getLastItemValue() ), rTokClass );
+}
+
+void FormulaObject::dumpRefErrToken( const OUString& rTokClass, bool bArea )
+{
+ dumpUnused( 4 * (bArea ? 2 : 1) );
+ mxStack->pushOperand( createRef( getErrorName( BIFF_ERR_REF ) ), rTokClass );
+}
+
+void FormulaObject::dumpRef3dToken( const OUString& rTokClass, bool bNameMode )
+{
+ OUString aRef = dumpTokenRefId();
+ TokenAddress aPos = dumpTokenAddress( bNameMode );
+ writeTokenAddress3dItem( "addr", aRef, aPos, bNameMode );
+ mxStack->pushOperand( out().getLastItemValue(), rTokClass );
+}
+
+void FormulaObject::dumpArea3dToken( const OUString& rTokClass, bool bNameMode )
+{
+ OUString aRef = dumpTokenRefId();
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRange3dItem( "range", aRef, aRange, bNameMode );
+ mxStack->pushOperand( out().getLastItemValue(), rTokClass );
+}
+
+void FormulaObject::dumpRefErr3dToken( const OUString& rTokClass, bool bArea )
+{
+ OUString aRef = dumpTokenRefId();
+ dumpUnused( 4 * (bArea ? 2 : 1) );
+ mxStack->pushOperand( aRef + getErrorName( BIFF_ERR_REF ), rTokClass );
+}
+
+void FormulaObject::dumpMemFuncToken( const OUString& /*rTokClass*/ )
+{
+ dumpDec< sal_uInt16 >( "size" );
+}
+
+void FormulaObject::dumpMemAreaToken( const OUString& rTokClass, bool bAddData )
+{
+ dumpUnused( 4 );
+ dumpMemFuncToken( rTokClass );
+ if( bAddData )
+ maAddData.push_back( ADDDATA_MEMAREA );
+}
+
+void FormulaObject::dumpExpToken( const StringWrapper& rName )
+{
+ Address aPos;
+ dumpRowIndex( "base-row" );
+ OUStringBuffer aOp( rName.getString() );
+ StringHelper::appendIndex( aOp, createPlaceHolder() + out().getLastItemValue() );
+ mxStack->pushOperand( aOp.makeStringAndClear() );
+ maAddData.push_back( ADDDATA_EXP );
+}
+
+void FormulaObject::dumpUnaryOpToken( const StringWrapper& rLOp, const StringWrapper& rROp )
+{
+ mxStack->pushUnaryOp( rLOp, rROp );
+}
+
+void FormulaObject::dumpBinaryOpToken( const StringWrapper& rOp )
+{
+ mxStack->pushBinaryOp( rOp );
+}
+
+void FormulaObject::dumpFuncToken( const OUString& rTokClass )
+{
+ sal_uInt16 nFuncId;
+ in() >> nFuncId;
+ const FunctionInfo* pFuncInfo = 0;
+ OUString aFuncName = writeFuncIdItem( nFuncId, &pFuncInfo );
+ if( pFuncInfo && (pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount) )
+ mxStack->pushFuncOp( aFuncName, rTokClass, pFuncInfo->mnMinParamCount );
+ else
+ mxStack->setError();
+}
+
+void FormulaObject::dumpFuncVarToken( const OUString& rTokClass )
+{
+ sal_uInt8 nParamCount;
+ sal_uInt16 nFuncId;
+ in() >> nParamCount >> nFuncId;
+ bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
+ if( bCmd )
+ writeHexItem( "param-count", nParamCount, "PARAMCOUNT-CMD" );
+ else
+ writeDecItem( "param-count", nParamCount );
+ OUString aFuncName = writeFuncIdItem( nFuncId );
+ if( bCmd && getFlag( nParamCount, BIFF_TOK_FUNCVAR_CMDPROMPT ) )
+ {
+ aFuncName += OUString( OOX_DUMP_CMDPROMPT );
+ nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
+ }
+ mxStack->pushFuncOp( aFuncName, rTokClass, nParamCount );
+}
+
+bool FormulaObject::dumpTableToken()
+{
+ Output& rOut = out();
+ dumpUnused( 3 );
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "TABLEFLAGS" );
+ sal_uInt16 nTabId = dumpDec< sal_uInt16 >( "table-id" );
+ dumpUnused( 2 );
+ {
+ sal_uInt16 nCol1, nCol2;
+ in() >> nCol1 >> nCol2;
+ ItemGuard aItem( rOut, "cols" );
+ rOut.writeDec( nCol1 );
+ if( nCol1 != nCol2 )
+ {
+ rOut.writeChar( OOX_DUMP_RANGESEP );
+ rOut.writeDec( nCol2 );
+ }
+ }
+ OUStringBuffer aColRange;
+ StringHelper::appendIndex( aColRange, rOut.getLastItemValue() );
+ OUStringBuffer aParams;
+ size_t nParams = 0;
+ if( getFlag( nFlags, OOBIN_TOK_TABLE_ALL ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#All]" ) );
+ if( getFlag( nFlags, OOBIN_TOK_TABLE_HEADERS ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Headers]" ) );
+ if( getFlag( nFlags, OOBIN_TOK_TABLE_DATA ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Data]" ) );
+ if( getFlag( nFlags, OOBIN_TOK_TABLE_TOTALS ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Totals]" ) );
+ if( getFlag( nFlags, OOBIN_TOK_TABLE_THISROW ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#This Row]" ) );
+ if( (getFlag( nFlags, OOBIN_TOK_TABLE_COLUMN ) || getFlag( nFlags, OOBIN_TOK_TABLE_COLRANGE )) && ++nParams )
+ StringHelper::appendToken( aParams, aColRange.makeStringAndClear() );
+ OUStringBuffer aOp;
+ StringHelper::appendIndexedText( aOp, CREATE_OUSTRING( "TABLE" ), nTabId );
+ if( nParams > 1 )
+ StringHelper::appendIndex( aOp, aParams.makeStringAndClear() );
+ else if( nParams == 1 )
+ aOp.append( aParams.makeStringAndClear() );
+ mxStack->pushOperand( aOp.makeStringAndClear() );
+ return true;
+}
+
+bool FormulaObject::dumpAttrToken()
+{
+ bool bValid = true;
+ sal_uInt8 nType = dumpHex< sal_uInt8 >( "type", mxAttrTypes );
+ switch( nType )
+ {
+ case OOBIN_TOK_ATTR_VOLATILE:
+ dumpUnused( 2 );
+ break;
+ case OOBIN_TOK_ATTR_IF:
+ dumpDec< sal_uInt16 >( "skip" );
+ break;
+ case OOBIN_TOK_ATTR_CHOOSE:
+ {
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "choices" );
+ out().resetItemIndex();
+ for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
+ dumpDec< sal_uInt16 >( "#skip" );
+ dumpDec< sal_uInt16 >( "skip-err" );
+ }
+ break;
+ case OOBIN_TOK_ATTR_SKIP:
+ dumpDec< sal_uInt16 >( "skip" );
+ break;
+ case OOBIN_TOK_ATTR_SUM:
+ dumpUnused( 2 );
+ mxStack->pushFuncOp( CREATE_OUSTRING( "SUM" ), OUString( OOX_DUMP_BASECLASS ), 1 );
+ break;
+ case OOBIN_TOK_ATTR_ASSIGN:
+ dumpUnused( 2 );
+ break;
+ case OOBIN_TOK_ATTR_SPACE:
+ case OOBIN_TOK_ATTR_SPACE | BIFF_TOK_ATTR_VOLATILE:
+ dumpDec< sal_uInt8 >( "char-type", mxSpTypes );
+ dumpDec< sal_uInt8 >( "char-count" );
+ break;
+ case OOBIN_TOK_ATTR_IFERROR:
+ dumpDec< sal_uInt16 >( "skip" );
+ break;
+ default:
+ bValid = false;
+ }
+ return bValid;
+}
+
+void FormulaObject::dumpAddTokenData()
+{
+ Output& rOut = out();
+ rOut.resetItemIndex();
+ Input& rIn = in();
+ sal_Int32 nAddDataSize = (in().getSize() - in().tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0;
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( rIn.tell() + nAddDataSize, rIn.getSize() );
+ for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); (aIt != aEnd) && rIn.isValidPos() && (rIn.tell() < nEndPos); ++aIt )
+ {
+ AddDataType eType = *aIt;
+
+ {
+ ItemGuard aItem( rOut, "#add-data" );
+ switch( eType )
+ {
+ case ADDDATA_EXP: rOut.writeAscii( "tExp" ); break;
+ case ADDDATA_ARRAY: rOut.writeAscii( "tArray" ); break;
+ case ADDDATA_MEMAREA: rOut.writeAscii( "tMemArea" ); break;
+ }
+ }
+
+ size_t nIdx = aIt - maAddData.begin();
+ IndentGuard aIndGuard( rOut );
+ switch( eType )
+ {
+ case ADDDATA_EXP: dumpAddDataExp( nIdx ); break;
+ case ADDDATA_ARRAY: dumpAddDataArray( nIdx ); break;
+ case ADDDATA_MEMAREA: dumpAddDataMemArea( nIdx ); break;
+ default:;
+ }
+ }
+}
+
+void FormulaObject::dumpAddDataExp( size_t nIdx )
+{
+ dumpColIndex( "base-col" );
+ mxStack->replaceOnTop( createPlaceHolder( nIdx ), out().getLastItemValue() );
+}
+
+void FormulaObject::dumpAddDataArray( size_t nIdx )
+{
+ sal_Int32 nCols, nRows;
+ dumpaddDataArrayHeader( nCols, nRows );
+
+ OUStringBuffer aOp;
+ TableGuard aTabGuard( out(), 17 );
+ for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
+ {
+ OUStringBuffer aArrayLine;
+ for( sal_Int32 nCol = 0; nCol < nCols; ++nCol )
+ StringHelper::appendToken( aArrayLine, dumpaddDataArrayValue(), OOX_DUMP_LISTSEP );
+ StringHelper::appendToken( aOp, aArrayLine.makeStringAndClear(), OOX_DUMP_ARRAYSEP );
+ }
+ StringHelper::enclose( aOp, '{', '}' );
+ mxStack->replaceOnTop( createPlaceHolder( nIdx ), aOp.makeStringAndClear() );
+}
+
+void FormulaObject::dumpAddDataMemArea( size_t /*nIdx*/ )
+{
+ dumpRangeList();
+}
+
+void FormulaObject::dumpaddDataArrayHeader( sal_Int32& rnCols, sal_Int32& rnRows )
+{
+ Output& rOut = out();
+ MultiItemsGuard aMultiGuard( rOut );
+ rnRows = dumpDec< sal_Int32 >( "height" );
+ rnCols = dumpDec< sal_Int32 >( "width" );
+ ItemGuard aItem( rOut, "size" );
+ rOut.writeDec( rnCols );
+ rOut.writeChar( 'x' );
+ rOut.writeDec( rnRows );
+ aItem.cont();
+ rOut.writeDec( rnCols * rnRows );
+}
+
+OUString FormulaObject::dumpaddDataArrayValue()
+{
+ Output& rOut = out();
+ MultiItemsGuard aMultiGuard( rOut );
+ OUStringBuffer aValue;
+ switch( dumpDec< sal_uInt8 >( "type", "ARRAYVALUE-TYPE" ) )
+ {
+ case OOBIN_TOK_ARRAY_DOUBLE:
+ dumpDec< double >( "value" );
+ aValue.append( rOut.getLastItemValue() );
+ break;
+ case OOBIN_TOK_ARRAY_STRING:
+ aValue.append( dumpString( "value", false, false ) );
+ StringHelper::enclose( aValue, OOX_DUMP_STRQUOTE );
+ break;
+ case OOBIN_TOK_ARRAY_BOOL:
+ dumpBoolean( "value" );
+ aValue.append( rOut.getLastItemValue() );
+ break;
+ case OOBIN_TOK_ARRAY_ERROR:
+ dumpErrorCode( "value" );
+ aValue.append( rOut.getLastItemValue() );
+ dumpUnused( 3 );
+ break;
+ }
+ return aValue.makeStringAndClear();
+}
+
+// ============================================================================
+
+RecordObject::RecordObject( OutputObjectBase& rParent )
+{
+ RecordObjectBase::construct( rParent );
+ if( RecordObjectBase::implIsValid() )
+ {
+ mxFmlaObj.reset( new FormulaObject( *this ) );
+ mxSimpleRecs = cfg().getNameList( "SIMPLE-RECORDS" );
+ }
+}
+
+void RecordObject::dumpRecord( const RecordDataSequence& rData, sal_Int32 nRecId )
+{
+ createRecordStream( rData );
+ mnRecId = nRecId;
+ dump();
+}
+
+bool RecordObject::implIsValid() const
+{
+ return isValid( mxFmlaObj ) && RecordObjectBase::implIsValid();
+}
+
+void RecordObject::implDump()
+{
+ if( cfg().hasName( mxSimpleRecs, mnRecId ) )
+ dumpSimpleRecord( cfg().getName( mxSimpleRecs, mnRecId ) );
+ else
+ dumpRecordBody();
+
+ // remaining undumped data
+ RecordInputStream& rStrm = getRecordStream();
+ if( rStrm.getRecPos() == 0 )
+ dumpRawBinary( rStrm.getRecSize(), false );
+ else
+ dumpRemaining( rStrm.getRecLeft() );
+ if( !rStrm.isValid() )
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+}
+
+void RecordObject::dumpCellHeader()
+{
+ dumpColIndex();
+ dumpDec< sal_uInt16 >( "xf-id" );
+ dumpHex< sal_uInt16 >( "flags", "CELL-FLAGS" );
+}
+
+void RecordObject::dumpSimpleRecord( const OUString& rRecData )
+{
+ ItemFormat aItemFmt;
+ aItemFmt.parse( rRecData );
+ dumpItem( aItemFmt );
+}
+
+void RecordObject::dumpRecordBody()
+{
+ switch( mnRecId )
+ {
+ case OOBIN_ID_ARRAY:
+ dumpRange( "array-range" );
+ dumpHex< sal_uInt8 >( "flags", "ARRAY-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case OOBIN_ID_BORDER:
+ dumpHex< sal_uInt8 >( "flags", "BORDER-FLAGS" );
+ dumpDec< sal_uInt16 >( "top-style", "BORDERSTYLES" );
+ dumpColor( "top-color" );
+ dumpDec< sal_uInt16 >( "bottom-style", "BORDERSTYLES" );
+ dumpColor( "bottom-color" );
+ dumpDec< sal_uInt16 >( "left-style", "BORDERSTYLES" );
+ dumpColor( "left-color" );
+ dumpDec< sal_uInt16 >( "right-style", "BORDERSTYLES" );
+ dumpColor( "right-color" );
+ dumpDec< sal_uInt16 >( "diag-style", "BORDERSTYLES" );
+ dumpColor( "diag-color" );
+ break;
+
+ case OOBIN_ID_BRK:
+ dumpDec< sal_Int32 >( "id" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpHex< sal_uInt32 >( "flags", "BRK-FLAGS" );
+ break;
+
+ case OOBIN_ID_CALCPR:
+ dumpDec< sal_Int32 >( "calc-id" );
+ dumpDec< sal_Int32 >( "calc-mode", "CALCPR-CALCMODE" );
+ dumpDec< sal_Int32 >( "iteration-count" );
+ dumpDec< double >( "iteration-delta" );
+ dumpDec< sal_Int32 >( "processor-count" );
+ dumpHex< sal_uInt16 >( "flags", "CALCPR-FLAGS" );
+ break;
+
+ case OOBIN_ID_CELL_BLANK:
+ dumpCellHeader();
+ break;
+
+ case OOBIN_ID_CELL_BOOL:
+ dumpCellHeader();
+ dumpBoolean();
+ break;
+
+ case OOBIN_ID_CELL_DOUBLE:
+ dumpCellHeader();
+ dumpDec< double >( "value" );
+ break;
+
+ case OOBIN_ID_CELL_ERROR:
+ dumpCellHeader();
+ dumpErrorCode();
+ break;
+
+ case OOBIN_ID_CELL_RK:
+ dumpCellHeader();
+ dumpRk( "value" );
+ break;
+
+ case OOBIN_ID_CELL_RSTRING:
+ dumpCellHeader();
+ dumpString( "value", true );
+ break;
+
+ case OOBIN_ID_CELL_SI:
+ dumpCellHeader();
+ dumpDec< sal_Int32 >( "string-id" );
+ break;
+
+ case OOBIN_ID_CELL_STRING:
+ dumpCellHeader();
+ dumpString( "value" );
+ break;
+
+ case OOBIN_ID_CELLSTYLE:
+ dumpDec< sal_Int32 >( "xf-id" );
+ dumpHex< sal_uInt16 >( "flags", "CELLSTYLE-FLAGS" );
+ dumpDec< sal_uInt8 >( "builtin-id", "CELLSTYLE-BUILTIN" );
+ dumpDec< sal_uInt8 >( "outline-level" );
+ dumpString( "name" );
+ break;
+
+ case OOBIN_ID_CFCOLOR:
+ dumpColor();
+ break;
+
+ case OOBIN_ID_CFRULE:
+ {
+ // type/subtype/operator is a mess...
+ dumpDec< sal_Int32 >( "type", "CFRULE-TYPE" );
+ sal_Int32 nSubType = dumpDec< sal_Int32 >( "sub-type", "CFRULE-SUBTYPE" );
+ dumpDec< sal_Int32 >( "dxf-id" );
+ dumpDec< sal_Int32 >( "priority" );
+ switch( nSubType )
+ {
+ case 0: dumpDec< sal_Int32 >( "operator", "CFRULE-CELL-OPERATOR" ); break;
+ case 5: dumpDec< sal_Int32 >( "rank" ); break;
+ case 8: dumpDec< sal_Int32 >( "operator", "CFRULE-TEXT-OPERATOR" ); break;
+ case 15: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 16: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 17: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 18: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 19: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 20: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 21: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 22: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 23: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 24: dumpDec< sal_Int32 >( "operator", "CFRULE-TIME-OPERATOR" ); break;
+ case 25: dumpDec< sal_Int32 >( "std-dev" ); break;
+ case 26: dumpDec< sal_Int32 >( "std-dev" ); break;
+ case 29: dumpDec< sal_Int32 >( "std-dev" ); break;
+ case 30: dumpDec< sal_Int32 >( "std-dev" ); break;
+ default: dumpDec< sal_Int32 >( "operator", "CFRULE-OTHER-OPERATOR" );
+ }
+ dumpUnknown( 8 );
+ dumpHex< sal_uInt16 >( "flags", "CFRULE-FLAGS" );
+ // for no obvious reason the formula sizes occur twice
+ dumpDec< sal_Int32 >( "formula1-size" );
+ dumpDec< sal_Int32 >( "formula2-size" );
+ dumpDec< sal_Int32 >( "formula3-size" );
+ dumpString( "text" );
+ if( in().getSize() - in().tell() >= 8 )
+ mxFmlaObj->dumpNameFormula( "formula1" );
+ if( in().getSize() - in().tell() >= 8 )
+ mxFmlaObj->dumpNameFormula( "formula2" );
+ if( in().getSize() - in().tell() >= 8 )
+ mxFmlaObj->dumpNameFormula( "formula3" );
+ }
+ break;
+
+ case OOBIN_ID_COL:
+ dumpColRange();
+ dumpDec< sal_uInt16 >( "col-width", "CONV-COLWIDTH" );
+ dumpUnknown( 2 );
+ dumpDec< sal_Int32 >( "custom-xf-id" );
+ dumpHex< sal_uInt16 >( "flags", "COL-FLAGS" );
+ break;
+
+ case OOBIN_ID_COLBREAKS:
+ dumpDec< sal_Int32 >( "count" );
+ dumpDec< sal_Int32 >( "manual-count" );
+ break;
+
+ case OOBIN_ID_COLOR:
+ dumpColor();
+ break;
+
+ case OOBIN_ID_CONDFORMATTING:
+ dumpDec< sal_Int32 >( "cfrule-count" );
+ dumpUnknown( 4 );
+ dumpRangeList();
+ break;
+
+ case OOBIN_ID_DATATABLE:
+ dumpRange( "table-range" );
+ dumpAddress( "ref1" );
+ dumpAddress( "ref2" );
+ dumpHex< sal_uInt8 >( "flags", "DATATABLE-FLAGS" );
+ break;
+
+ case OOBIN_ID_DATAVALIDATION:
+ dumpHex< sal_uInt32 >( "flags", "DATAVALIDATION-FLAGS" );
+ dumpRangeList();
+ dumpString( "error-title" );
+ dumpString( "error-message" );
+ dumpString( "input-title" );
+ dumpString( "input-message" );
+ mxFmlaObj->dumpNameFormula( "formula1" );
+ mxFmlaObj->dumpNameFormula( "formula2" );
+ break;
+
+ case OOBIN_ID_DATAVALIDATIONS:
+ dumpUnknown( 14 ); // flags, xWindow, yWindow
+ dumpDec< sal_Int32 >( "count" );
+ break;
+
+ case OOBIN_ID_DDEITEMVALUES:
+ dumpDec< sal_Int32 >( "rows" );
+ dumpDec< sal_Int32 >( "columns" );
+ break;
+
+ case OOBIN_ID_DDEITEM_STRING:
+ dumpString( "value" );
+ break;
+
+ case OOBIN_ID_DEFINEDNAME:
+ dumpHex< sal_uInt16 >( "flags", "DEFINEDNAME-FLAGS" );
+ dumpUnknown( 2 );
+ dumpHex< sal_uInt8 >( "keyboard-shortcut" );
+ dumpDec< sal_Int32 >( "sheet-id", "DEFINEDNAME-SHEETID" );
+ dumpString( "name" );
+ mxFmlaObj->dumpNameFormula();
+ dumpString( "comment" );
+ if( in().getSize() - in().tell() >= 4 ) dumpString( "menu-text" );
+ if( in().getSize() - in().tell() >= 4 ) dumpString( "description-text" );
+ if( in().getSize() - in().tell() >= 4 ) dumpString( "help-text" );
+ if( in().getSize() - in().tell() >= 4 ) dumpString( "statusbar-text" );
+ break;
+
+ case OOBIN_ID_DIMENSION:
+ dumpRange( "used-range" );
+ break;
+
+ case OOBIN_ID_DRAWING:
+ dumpString( "rel-id" );
+ break;
+
+ case OOBIN_ID_DXF:
+ dumpHex< sal_uInt32 >( "flags", "DXF-FLAGS" );
+ for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "subrec-count" ); in().isValidPos() && (nIndex < nCount); ++nIndex )
+ {
+ out().startMultiItems();
+ sal_Int64 nStartPos = in().tell();
+ writeEmptyItem( "SUBREC" );
+ sal_uInt16 nSubRecId = dumpDec< sal_uInt16 >( "id", "DXF-SUBREC" );
+ sal_uInt16 nSubRecSize = dumpDec< sal_uInt16 >( "size" );
+ sal_Int64 nEndPos = nStartPos + nSubRecSize;
+ out().endMultiItems();
+ IndentGuard aIndGuard( out() );
+ switch( nSubRecId )
+ {
+ case 0:
+ dumpDec< sal_uInt8 >( "pattern", "FILLPATTERNS" );
+ break;
+ case 1:
+ case 2:
+ dumpColor();
+ break;
+ case 3:
+ dumpDec< sal_Int32 >( "gradient-type", "FILL-GRADIENTTYPE" );
+ dumpDec< double >( "linear-angle" );
+ dumpDec< double >( "pos-left" );
+ dumpDec< double >( "pos-right" );
+ dumpDec< double >( "pos-top" );
+ dumpDec< double >( "pos-bottom" );
+ break;
+ case 4:
+ dumpDec< sal_uInt16 >( "index" );
+ dumpDec< double >( "stop-position" );
+ dumpColor( "stop-color" );
+ break;
+ case 5:
+ dumpColor();
+ break;
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ dumpColor( "color" );
+ dumpDec< sal_uInt16 >( "style", "BORDERSTYLES" );
+ break;
+ case 13:
+ case 14:
+ dumpBoolean( "value" );
+ break;
+ case 15:
+ dumpDec< sal_uInt8 >( "alignment", "XF-HORALIGN" );
+ break;
+ case 16:
+ dumpDec< sal_uInt8 >( "alignment", "XF-VERALIGN" );
+ break;
+ case 17:
+ dumpDec< sal_uInt8 >( "rotation", "TEXTROTATION" );
+ break;
+ case 18:
+ dumpDec< sal_uInt16 >( "indent" );
+ break;
+ case 19:
+ dumpDec< sal_uInt8 >( "text-dir", "XF-TEXTDIRECTION" );
+ break;
+ case 20:
+ case 21:
+ case 22:
+ dumpBoolean( "value" );
+ break;
+ case 24:
+ dumpString( "name", false, false );
+ break;
+ case 25:
+ dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
+ break;
+ case 26:
+ dumpDec< sal_uInt16 >( "underline", "FONT-UNDERLINE" );
+ break;
+ case 27:
+ dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
+ break;
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ dumpBoolean( "value" );
+ break;
+ case 36:
+ dumpDec< sal_Int32 >( "height", "CONV-TWIP-TO-PT" );
+ break;
+ case 37:
+ dumpDec< sal_uInt8 >( "scheme", "FONT-SCHEME" );
+ break;
+ case 38:
+ dumpString( "numfmt", false, false );
+ break;
+ case 41:
+ dumpDec< sal_uInt16 >( "numfmt-id" );
+ break;
+ case 42:
+ dumpDec< sal_uInt16 >( "relative-indent" );
+ break;
+ case 43:
+ case 44:
+ dumpBoolean( "value" );
+ break;
+ }
+ if( in().tell() < nEndPos )
+ dumpRemaining( static_cast< sal_Int32 >( nEndPos - in().tell() ) );
+ in().seek( nEndPos );
+ }
+ break;
+
+ case OOBIN_ID_EXTCELL_BOOL:
+ dumpColIndex();
+ dumpBoolean();
+ break;
+
+ case OOBIN_ID_EXTCELL_DOUBLE:
+ dumpColIndex();
+ dumpDec< double >( "value" );
+ break;
+
+ case OOBIN_ID_EXTCELL_ERROR:
+ dumpColIndex();
+ dumpErrorCode();
+ break;
+
+ case OOBIN_ID_EXTCELL_STRING:
+ dumpColIndex();
+ dumpString( "value" );
+ break;
+
+ case OOBIN_ID_EXTERNALBOOK:
+ switch( dumpDec< sal_uInt16 >( "type", "EXTERNALBOOK-TYPE" ) )
+ {
+ case 0:
+ dumpString( "rel-id" );
+ dumpDec< sal_Int32 >( "unused" );
+ break;
+ case 1:
+ dumpString( "dde-service" );
+ dumpString( "dde-topic" );
+ break;
+ case 2:
+ dumpString( "rel-id" );
+ dumpString( "prog-id" );
+ break;
+ }
+ break;
+
+ case OOBIN_ID_EXTERNALNAME:
+ dumpString( "name" );
+ break;
+
+ case OOBIN_ID_EXTERNALNAMEFLAGS:
+ dumpHex< sal_uInt16 >( "flags", "EXTERNALNAMEFLAGS-FLAGS" );
+ dumpDec< sal_Int32 >( "sheet-id" );
+ dumpUnknown( 1 );
+ break;
+
+ case OOBIN_ID_EXTERNALREF:
+ dumpString( "rel-id" );
+ break;
+
+ case OOBIN_ID_EXTERNALSHEETS:
+ {
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "ref-count" );
+ TableGuard aTabGuard( out(), 13, 17, 24 );
+ out().resetItemIndex();
+ for( sal_Int32 nRefId = 0; in().isValidPos() && (nRefId < nCount); ++nRefId )
+ {
+ MultiItemsGuard aMultiGuard( out() );
+ writeEmptyItem( "#ref" );
+ dumpDec< sal_Int32 >( "extref-id" );
+ dumpDec< sal_Int32 >( "first-sheet", "EXTERNALSHEETS-ID" );
+ dumpDec< sal_Int32 >( "last-sheet", "EXTERNALSHEETS-ID" );
+ }
+ }
+ break;
+
+ case OOBIN_ID_EXTROW:
+ dumpRowIndex();
+ break;
+
+ case OOBIN_ID_EXTSHEETDATA:
+ dumpDec< sal_Int32 >( "sheet-id" );
+ dumpHex< sal_uInt8 >( "flags", "EXTSHEETDATA-FLAGS" );
+ break;
+
+ case OOBIN_ID_EXTSHEETNAMES:
+ out().resetItemIndex();
+ for( sal_Int32 nSheet = 0, nCount = dumpDec< sal_Int32 >( "sheet-count" ); in().isValidPos() && (nSheet < nCount); ++nSheet )
+ dumpString( "#sheet-name" );
+ break;
+
+ case OOBIN_ID_FILL:
+ dumpDec< sal_Int32 >( "fill-pattern", "FILLPATTERNS" );
+ dumpColor( "fg-color" );
+ dumpColor( "bg-color" );
+ dumpDec< sal_Int32 >( "gradient-type", "FILL-GRADIENTTYPE" );
+ dumpDec< double >( "linear-angle" );
+ dumpDec< double >( "pos-left" );
+ dumpDec< double >( "pos-right" );
+ dumpDec< double >( "pos-top" );
+ dumpDec< double >( "pos-bottom" );
+ out().resetItemIndex();
+ for( sal_Int32 nStop = 0, nStopCount = dumpDec< sal_Int32 >( "stop-count" ); (nStop < nStopCount) && in().isValidPos(); ++nStop )
+ {
+ writeEmptyItem( "#stop" );
+ IndentGuard aIndGuard( out() );
+ dumpColor( "stop-color" );
+ dumpDec< double >( "stop-position" );
+ }
+ break;
+
+ case OOBIN_ID_FILEVERSION:
+ dumpGuid( "codename" );
+ dumpString( "app-name" );
+ dumpString( "last-edited" );
+ dumpString( "lowest-edited" );
+ dumpString( "build-version" );
+ break;
+
+ case OOBIN_ID_FONT:
+ dumpDec< sal_uInt16 >( "height", "CONV-TWIP-TO-PT" );
+ dumpHex< sal_uInt16 >( "flags", "FONT-FLAGS" );
+ dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
+ dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
+ dumpDec< sal_uInt8 >( "underline", "FONT-UNDERLINE" );
+ dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
+ dumpDec< sal_uInt8 >( "charset", "CHARSET" );
+ dumpUnknown( 1 );
+ dumpColor();
+ dumpDec< sal_uInt8 >( "scheme", "FONT-SCHEME" );
+ dumpString( "name" );
+ break;
+
+ case OOBIN_ID_FORMULA_BOOL:
+ dumpCellHeader();
+ dumpBoolean();
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case OOBIN_ID_FORMULA_DOUBLE:
+ dumpCellHeader();
+ dumpDec< double >( "value" );
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case OOBIN_ID_FORMULA_ERROR:
+ dumpCellHeader();
+ dumpErrorCode();
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case OOBIN_ID_FORMULA_STRING:
+ dumpCellHeader();
+ dumpString( "value" );
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case OOBIN_ID_HEADERFOOTER:
+ dumpHex< sal_uInt16 >( "flags", "HEADERFOOTER-FLAGS" );
+ dumpString( "odd-header" );
+ dumpString( "odd-footer" );
+ dumpString( "even-header" );
+ dumpString( "even-footer" );
+ dumpString( "first-header" );
+ dumpString( "first-footer" );
+ break;
+
+ case OOBIN_ID_HYPERLINK:
+ dumpRange();
+ dumpString( "rel-id" );
+ dumpString( "location" );
+ dumpString( "tooltip" );
+ dumpString( "display" );
+ break;
+
+ case OOBIN_ID_MERGECELL:
+ dumpRange();
+ break;
+
+ case OOBIN_ID_NUMFMT:
+ dumpDec< sal_uInt16 >( "numfmt-id" );
+ dumpString( "format" );
+ break;
+
+ case OOBIN_ID_PAGEMARGINS:
+ dumpDec< double >( "left-margin" );
+ dumpDec< double >( "right-margin" );
+ dumpDec< double >( "top-margin" );
+ dumpDec< double >( "bottom-margin" );
+ dumpDec< double >( "header-margin" );
+ dumpDec< double >( "footer-margin" );
+ break;
+
+ case OOBIN_ID_PAGESETUP:
+ dumpDec< sal_Int32 >( "paper-size", "PAGESETUP-PAPERSIZE" );
+ dumpDec< sal_Int32 >( "scaling", "CONV-PERCENT" );
+ dumpDec< sal_Int32 >( "horizontal-res", "PAGESETUP-DPI" );
+ dumpDec< sal_Int32 >( "vertical-res", "PAGESETUP-DPI" );
+ dumpDec< sal_Int32 >( "copies" );
+ dumpDec< sal_Int32 >( "first-page" );
+ dumpDec< sal_Int32 >( "scale-to-width", "PAGESETUP-SCALETOPAGES" );
+ dumpDec< sal_Int32 >( "scale-to-height", "PAGESETUP-SCALETOPAGES" );
+ dumpHex< sal_uInt16 >( "flags", "PAGESETUP-FLAGS" );
+ dumpString( "printer-settings-rel-id" );
+ break;
+
+ case OOBIN_ID_PANE:
+ dumpDec< double >( "x-split-pos" );
+ dumpDec< double >( "y-split-pos" );
+ dumpAddress( "second-top-left" );
+ dumpDec< sal_Int32 >( "active-pane", "PANE-ID" );
+ dumpHex< sal_uInt8 >( "flags", "PANE-FLAGS" );
+ break;
+
+ case OOBIN_ID_PHONETICPR:
+ dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
+ dumpDec< sal_Int32 >( "type", "PHONETICPR-TYPE" );
+ dumpDec< sal_Int32 >( "alignment", "PHONETICPR-ALIGNMENT" );
+ break;
+
+ case OOBIN_ID_ROW:
+ dumpRowIndex();
+ dumpDec< sal_Int32 >( "custom-xf-id" );
+ dumpDec< sal_uInt16 >( "height", "CONV-TWIP-TO-PT" );
+ dumpHex< sal_uInt16 >( "flags", "ROW-FLAGS" );
+ dumpUnknown( 5 );
+ if( getRecordStream().getRecLeft() >= 8 )
+ dumpRowRange( "row-spans" );
+ break;
+
+ case OOBIN_ID_ROWBREAKS:
+ dumpDec< sal_Int32 >( "count" );
+ dumpDec< sal_Int32 >( "manual-count" );
+ break;
+
+ case OOBIN_ID_SELECTION:
+ dumpDec< sal_Int32 >( "pane", "PANE-ID" );
+ dumpAddress( "active-cell" );
+ dumpDec< sal_Int32 >( "active-cell-id" );
+ dumpRangeList( "selection" );
+ break;
+
+ case OOBIN_ID_SHAREDFMLA:
+ dumpRange( "formula-range" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case OOBIN_ID_SHEET:
+ dumpDec< sal_Int32 >( "sheet-state", "SHEET-STATE" );
+ dumpDec< sal_Int32 >( "sheet-id" );
+ dumpString( "rel-id" );
+ dumpString( "sheet-name" );
+ break;
+
+ case OOBIN_ID_SHEETFORMATPR:
+ dumpDec< sal_Int32 >( "default-col-width", "CONV-COLWIDTH" );
+ dumpDec< sal_uInt16 >( "base-col-width" );
+ dumpDec< sal_uInt16 >( "default-row-height", "CONV-TWIP-TO-PT" );
+ dumpHex< sal_uInt16 >( "flags", "SHEETFORMATPR-FLAGS" );
+ dumpDec< sal_uInt8 >( "max-row-outline" );
+ dumpDec< sal_uInt8 >( "max-col-outline" );
+ break;
+
+ case OOBIN_ID_SHEETPR:
+ dumpHex< sal_uInt16 >( "flags", "SHEETPR-FLAGS" );
+ dumpUnknown( 1 );
+ dumpColor( "tab-color" );
+ dumpUnknown( 8 );
+ dumpString( "codename" );
+ break;
+
+ case OOBIN_ID_SHEETPROTECTION:
+ dumpHex< sal_uInt16 >( "password-hash" );
+ // no flags field for all these boolean flags?!?
+ dumpDec< sal_Int32 >( "sheet-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "objects-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "scenarios-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "format-cells-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "format-columns-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "format-rows-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "insert-columns-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "insert-rows-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "insert-hyperlinks-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "delete-columns-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "delete-rows-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "select-locked-cells-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "sort-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "autofilter-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "pivot-tables-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "select-unlocked-cells-locked", "BOOLEAN" );
+ break;
+
+ case OOBIN_ID_SHEETVIEW:
+ dumpHex< sal_uInt16 >( "flags", "SHEETVIEW-FLAGS" );
+ dumpDec< sal_Int32 >( "view-type", "SHEETVIEW-TYPE" );
+ dumpAddress( "top-left" );
+ dumpDec< sal_Int32 >( "gridcolor-id", "PALETTE-COLORS" );
+ dumpDec< sal_uInt16 >( "zoom-scale", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "zoom-scale-normal", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "zoom-scale-sheet-layout", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "zoom-scale-page-layout", "CONV-PERCENT" );
+ dumpDec< sal_Int32 >( "workbookview-id" );
+ break;
+
+ case OOBIN_ID_SI:
+ dumpString( "string", true );
+ break;
+
+ case OOBIN_ID_SST:
+ dumpDec< sal_Int32 >( "string-cell-count" );
+ dumpDec< sal_Int32 >( "sst-size" );
+ break;
+
+ case OOBIN_ID_TABLE:
+ dumpRange();
+ dumpDec< sal_Int32 >( "type", "TABLE-TYPE" );
+ dumpDec< sal_Int32 >( "id" );
+ dumpDec< sal_Int32 >( "header-rows" );
+ dumpDec< sal_Int32 >( "totals-rows" );
+ dumpHex< sal_uInt32 >( "flags", "TABLE-FLAGS" );
+ dumpDec< sal_Int32 >( "headerrow-dxf-id" );
+ dumpDec< sal_Int32 >( "data-dxf-id" );
+ dumpDec< sal_Int32 >( "totalsrow-dxf-id" );
+ dumpDec< sal_Int32 >( "table-border-dxf-id" );
+ dumpDec< sal_Int32 >( "headerrow-border-dxf-id" );
+ dumpDec< sal_Int32 >( "totalsrow-border-dxf-id" );
+ dumpDec< sal_Int32 >( "connection-id" );
+ dumpString( "name" );
+ dumpString( "display-name" );
+ dumpString( "comment" );
+ dumpString( "headerrow-cell-style" );
+ dumpString( "data-cell-style" );
+ dumpString( "totalsrow-cell-style" );
+ break;
+
+ case OOBIN_ID_TABLEPART:
+ dumpString( "rel-id" );
+ break;
+
+ case OOBIN_ID_TABLESTYLEINFO:
+ dumpHex< sal_uInt16 >( "flags" );
+ dumpString( "style-name" );
+ break;
+
+ case OOBIN_ID_VOLTYPEMAIN:
+ dumpString( "first" );
+ break;
+
+ case OOBIN_ID_VOLTYPESTP:
+ dumpString( "topic-value" );
+ break;
+
+ case OOBIN_ID_VOLTYPETR:
+ dumpAddress( "ref" );
+ dumpDec< sal_Int32 >( "sheet-id" );
+ break;
+
+ case OOBIN_ID_WORKBOOKPR:
+ dumpHex< sal_uInt32 >( "flags", "WORKBBOKPR-FLAGS" );
+ dumpDec< sal_Int32 >( "default-theme-version" );
+ dumpString( "codename" );
+ break;
+
+ case OOBIN_ID_WORKBOOKVIEW:
+ dumpDec< sal_Int32 >( "x-window" );
+ dumpDec< sal_Int32 >( "y-window" );
+ dumpDec< sal_Int32 >( "win-width" );
+ dumpDec< sal_Int32 >( "win-height" );
+ dumpDec< sal_Int32 >( "tabbar-ratio" );
+ dumpDec< sal_Int32 >( "first-sheet" );
+ dumpDec< sal_Int32 >( "active-sheet" );
+ dumpHex< sal_uInt8 >( "flags", "WORKBOOKVIEW-FLAGS" );
+ break;
+
+ case OOBIN_ID_XF:
+ dumpDec< sal_uInt16 >( "parent-xf-id" );
+ dumpDec< sal_uInt16 >( "numfmt-id" );
+ dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
+ dumpDec< sal_uInt16 >( "fill-id" );
+ dumpDec< sal_uInt16 >( "border-id" );
+ dumpHex< sal_uInt32 >( "alignment", "XF-ALIGNMENT" );
+ dumpHex< sal_uInt16 >( "used-flags", "XF-USEDFLAGS" );
+ break;
+ }
+}
+
+// ============================================================================
+
+RecordHeaderObject::RecordHeaderObject( const InputObjectBase& rParent )
+{
+ static const RecordHeaderConfigInfo saHeaderCfgInfo =
+ {
+ "REC",
+ "RECORD-NAMES",
+ "show-record-pos",
+ "show-record-size",
+ "show-record-id",
+ "show-record-name",
+ "show-record-body",
+ };
+ RecordHeaderBase< sal_Int32, sal_Int32 >::construct( rParent, saHeaderCfgInfo );
+}
+
+RecordHeaderObject::~RecordHeaderObject()
+{
+}
+
+bool RecordHeaderObject::implReadHeader( sal_Int64& ornRecPos, sal_Int32& ornRecId, sal_Int32& ornRecSize )
+{
+ bool bValidRec = readCompressedInt( ornRecPos, ornRecId ) && (ornRecId >= 0) && readCompressedInt( ornRecPos, ornRecSize ) && (ornRecSize >= 0);
+ if( bValidRec )
+ {
+ maData.realloc( ornRecSize );
+ bValidRec = (ornRecSize == 0) || (in().read( maData.getArray(), ornRecSize ) == ornRecSize);
+ ornRecPos += ornRecSize;
+ }
+ return bValidRec;
+}
+
+bool RecordHeaderObject::readByte( sal_Int64& ornRecPos, sal_uInt8& ornByte )
+{
+ ++ornRecPos;
+ return in().read( &ornByte, 1 ) == 1;
+}
+
+bool RecordHeaderObject::readCompressedInt( sal_Int64& ornRecPos, sal_Int32& ornValue )
+{
+ ornValue = 0;
+ sal_uInt8 nByte;
+ if( !readByte( ornRecPos, nByte ) ) return false;
+ ornValue = nByte & 0x7F;
+ if( (nByte & 0x80) == 0 ) return true;
+ if( !readByte( ornRecPos, nByte ) ) return false;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 7;
+ if( (nByte & 0x80) == 0 ) return true;
+ if( !readByte( ornRecPos, nByte ) ) return false;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 14;
+ if( (nByte & 0x80) == 0 ) return true;
+ if( !readByte( ornRecPos, nByte ) ) return false;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 21;
+ return true;
+}
+
+// ============================================================================
+
+RecordStreamObject::RecordStreamObject( const ObjectBase& rParent, const OUString& rOutFileName, BinaryInputStreamRef xStrm )
+{
+ InputStreamObject::construct( rParent, rOutFileName, xStrm );
+ if( InputStreamObject::implIsValid() )
+ {
+ mxHdrObj.reset( new RecordHeaderObject( *this ) );
+ mxRecObj.reset( new RecordObject( *this ) );
+ }
+}
+
+bool RecordStreamObject::implIsValid() const
+{
+ return isValid( mxHdrObj ) && isValid( mxRecObj ) && InputStreamObject::implIsValid();
+}
+
+void RecordStreamObject::implDump()
+{
+ while( mxHdrObj->startNextRecord() )
+ {
+ if( mxHdrObj->isShowRecBody() )
+ {
+ IndentGuard aIndGuard( out() );
+ mxRecObj->dumpRecord( mxHdrObj->getRecordData(), mxHdrObj->getRecId() );
+ }
+ out().emptyLine();
+ }
+}
+
+// ============================================================================
+
+RootStorageObject::RootStorageObject( const DumperBase& rParent )
+{
+ RootStorageObjectBase::construct( rParent );
+}
+
+void RootStorageObject::implDumpStream( BinaryInputStreamRef xStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSystemFileName )
+{
+ if( (rStrgPath == CREATE_OUSTRING( "xl" )) ||
+ (rStrgPath == CREATE_OUSTRING( "xl/externalLinks" )) ||
+ (rStrgPath == CREATE_OUSTRING( "xl/macrosheets" )) ||
+ (rStrgPath == CREATE_OUSTRING( "xl/tables" )) ||
+ (rStrgPath == CREATE_OUSTRING( "xl/worksheets" )) )
+ {
+ const OUString aBinSuffix = CREATE_OUSTRING( ".bin" );
+ sal_Int32 nBinSuffixPos = rStrmName.getLength() - aBinSuffix.getLength();
+ if( (nBinSuffixPos >= 0) && rStrmName.match( aBinSuffix, nBinSuffixPos ) )
+ RecordStreamObject( *this, rSystemFileName, xStrm ).dump();
+ }
+}
+
+// ============================================================================
+
+Dumper::Dumper( const FilterBase& rFilter )
+{
+ ConfigRef xCfg( new Config( "OOO_XLSBDUMPER" ) );
+ DumperBase::construct( rFilter, xCfg );
+}
+
+void Dumper::implDump()
+{
+ RootStorageObject( *this ).dump();
+}
+
+// ============================================================================
+
+} // namespace xlsb
+} // namespace dump
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/dump/xlsbdumperconfig.dat b/oox/source/dump/xlsbdumperconfig.dat
new file mode 100644
index 000000000000..7c80a680745e
--- /dev/null
+++ b/oox/source/dump/xlsbdumperconfig.dat
@@ -0,0 +1,655 @@
+
+# dumper settings ============================================================
+
+# Path to base configuration data, relative to this file.
+include-config-file=dumperconfig.dat
+
+# XLSB record settings -------------------------------------------------------
+
+# Show total stream position of the record (default=on).
+# 0=off, 1=on
+show-record-pos=0
+
+# Show total record size in bytes (default=on).
+# 0=off, 1=on
+show-record-size=1
+
+# Show record identifier (default=on).
+# 0=off, 1=on
+show-record-id=1
+
+# Show record name, if known (default=on).
+# 0=off, 1=on
+show-record-name=1
+
+# Show record contents (default=on).
+# 0=off, 1=on
+show-record-body=1
+
+# common ---------------------------------------------------------------------
+
+unitconverter=CONV-TINT,/327.67,%
+unitconverter=CONV-COLWIDTH,/256,chars
+
+constlist=ERRORCODES
+ 0x00=#NULL!
+ 0x07=#DIV/0!
+ 0x0F=#VALUE!
+ 0x17=#REF!
+ 0x1D=#NAME?
+ 0x24=#NUM!
+ 0x2A=#N/A
+end
+
+flagslist=STRING-FLAGS
+ 0x01=rich-string
+ 0x02=phonetic-text
+end
+
+flagslist=CELL-FLAGS
+ 0x0100=show-phonetic
+end
+
+combilist=PHONETIC-FLAGS
+ ignore=0x0030
+ 0x0003=uint8,dec,type,PHONETICPR-TYPE
+ 0x000C=uint8,dec,alignment,PHONETICPR-ALIGNMENT
+end
+
+shortlist=COLOR-TYPE,0,none,auto,,indexed,,rgb,,theme
+
+multilist=PALETTE-COLORS
+ default=
+ 0=ega-black,ega-white,ega-red,ega-green,ega-blue,ega-yellow,ega-magenta,ega-cyan
+ 64=sys-window-text
+ 65=sys-window-bg
+ 67=sys-button-face
+ 77=sys-window-text-chart
+ 78=sys-window-bg-chart
+ 79=auto-border-chart
+ 80=sys-tooltip-bg
+ 81=sys-tooltip-text
+end
+
+constlist=TEXTROTATION
+ default=
+ 255=stacked
+end
+
+multilist=BORDERSTYLES
+ 0=none,thin,medium,dash,dot
+ 5=thick,double,hair,medium-dash,thin-dash-dot
+ 10=medium-dash-dot,thin-dash-dot-dot,medium-dash-dot-dot,slant-dash-dot
+end
+
+multilist=FILLPATTERNS
+ 0=no-fill,solid-fill,50%-grey,75%-grey,25%-grey
+ 5=hor-stripe,ver-stripe,rev-diag-stripe,diag-stripe,diag-crosshatch
+ 10=thick-diag-crosshatch,thin-hor-stripe,thin-ver-stripe,thin-rev-diag-stripe,thin-diag-stripe
+ 15=thin-hor-crosshatch,thin-diag-crosshatch,12.5%-grey,6.25%-grey
+ 40=gradient
+end
+
+# formulas -------------------------------------------------------------------
+
+flagslist=FORMULA-FLAGS
+ 0x0002=recalc-always
+end
+
+multilist=BASETOKENS
+ 0x00=,tExp,tTbl,tAdd,tSub,tMul,tDiv,tPower
+ 0x08=tConcat,tLT,tLE,tEQ,tGE,tGT,tNE,tIsect
+ 0x10=tList,tRange,tUplus,tUminus,tPercent,tParen,tMissArg,tStr
+ 0x18=tTable,tAttr,,,tErr,tBool,tInt,tNum
+end
+
+constlist=TOKENCLASSES
+ 0x20=R
+ 0x40=V
+ 0x60=A
+end
+
+multilist=CLASSTOKENS
+ 0x00=tArray,tFunc,tFuncVar,tName,tRef,tArea,tMemArea,tMemErr
+ 0x08=tMemNoMem,tMemFunc,tRefErr,tAreaErr,tRefN,tAreaN,tMemAreaN,tMemNoMemN
+ 0x18=,tNameX,tRef3d,tArea3d,tRefErr3d,tAreaErr3d
+end
+
+combilist=FUNCID
+ 0x7FFF=uint16,dec,func-id
+ 0x8000=command
+end
+
+combilist=PARAMCOUNT-CMD
+ 0x7F=uint8,dec,count
+ 0x80=prompt
+end
+
+combilist=REFRELFLAGS
+ 0x3FFF=uint16,dec,value
+ 0x4000=col-rel
+ 0x8000=row-rel
+end
+
+flagslist=TABLEFLAGS
+ 0x0001=single-column
+ 0x0002=column-range
+ 0x0004=#all
+ 0x0008=#headers
+ 0x0010=#data
+ 0x0020=#totals
+ 0x0040=#this-row
+ 0x0080=bracket-spaces
+ 0x0100=sep-spaces
+ 0x0200=single-row
+ 0x0400=single-cell
+end
+
+flagslist=ATTRTYPES
+ 0x01=volatile
+ 0x02=if
+ 0x04=choose
+ 0x08=skip
+ 0x10=sum
+ 0x20=assign
+ 0x40=space
+ 0x80=iferror
+end
+
+shortlist=ATTRSPACETYPES,0,space-before-token,cr-before-token,space-before-open,cr-before-open,space-before-close,cr-before-close,leading-space
+
+shortlist=ARRAYVALUE-TYPE,0,number,string,boolean,,error
+
+# record names ---------------------------------------------------------------
+
+multilist=RECORD-NAMES
+ 0x0000=ROW,CELL_BLANK,CELL_RK,CELL_ERROR,CELL_BOOL,CELL_DOUBLE,CELL_STRING,CELL_SI
+ 0x0008=FORMULA_STRING,FORMULA_DOUBLE,FORMULA_BOOL,FORMULA_ERROR,,,,
+ 0x0010=,,,SI,,,,
+
+ 0x0020=,,,,,,,DEFINEDNAME
+ 0x0028=,,,FONT,NUMFMT,FILL,BORDER,XF
+ 0x0030=CELLSTYLE,,,,,,,
+ 0x0038=,,,,COL,,CELL_RSTRING,CALCCHAINCELL
+ 0x0040=DATAVALIDATION,,,,,,,
+
+ 0x0080=FILEVERSION,WORKSHEET,WORKSHEET_END,WORKBOOK,WORKBOOK_END,SHEETVIEWS,SHEETVIEWS_END,BOOKVIEWS
+ 0x0088=BOOKVIEWS_END,SHEETVIEW,SHEETVIEW_END,,,,,SHEETS
+ 0x0090=SHEETS_END,SHEETDATA,SHEETDATA_END,SHEETPR,DIMENSION,,,PANE
+ 0x0098=SELECTION,WORKBOOKPR,,,SHEET,CALCPR,WORKBOOKVIEW,SST
+ 0x00A0=SST_END,AUTOFILTER,AUTOFILTER_END,FILTERCOLUMN,FILTERCOLUMN_END,,,
+
+ 0x00B0=,MERGECELLS,MERGECELLS_END,,,,,
+
+ 0x0110=,,,,,,STYLESHEET,STYLESHEET_END
+
+ 0x0150=,,,,,,,TABLE
+ 0x0158=TABLE_END,TABLECOLUMNS,TABLECOLUMNS_END,TABLECOLUMN,TABLECOLUMN_END,,,CALCEDCOLUMNFMLA
+ 0x0160=,EXTERNALREFS,EXTERNALREFS_END,EXTERNALREF,,EXTERNALSELF,EXTERNALSAME,EXTSHEETNAMES
+ 0x0168=EXTERNALBOOK,,EXTERNALSHEETS,EXTSHEETDATA,EXTSHEETDATA_END,,EXTROW,
+ 0x0170=EXTCELL_DOUBLE,EXTCELL_BOOL,EXTCELL_ERROR,EXTCELL_STRING,,,,
+
+ 0x0180=,,,,,,COLS,COLS_END
+ 0x0188=ROWBREAKS,ROWBREAKS_END,COLBREAKS,COLBREAKS_END,BRK,,,
+
+ 0x01A8=,,ARRAY,SHAREDFMLA,DATATABLE,,,
+
+ 0x01C8=,,,,,CONDFORMATTING,CONDFORMATTING_END,CFRULE
+ 0x01D0=CFRULE_END,ICONSET,ICONSET_END,DATABAR,DATABAR_END,COLORSCALE,COLORSCALE_END,CFVO
+ 0x01D8=,COLORS,COLORS_END,RGBCOLOR,PAGEMARGINS,PRINTOPTIONS,PAGESETUP,HEADERFOOTER
+ 0x01E0=HEADERFOOTER_END,,,,,SHEETFORMATPR,,
+ 0x01E8=,,,,,,HYPERLINK,
+
+ 0x01F8=,DXFS,DXFS_END,DXF,TABLESTYLES,TABLESTYLES_END,,
+ 0x0200=,TABLESTYLEINFO,VOLTYPES,VOLTYPES_END,VOLTYPE,VOLTYPE_END,VOLTYPEMAIN,VOLTYPEMAIN_END
+ 0x0208=VOLTYPETP,VOLTYPETP_END,VOLTYPESTP,VOLTYPETR,,VOLTYPE_ERROR,,
+ 0x0210=CALCCHAIN,CALCCHAIN_END,,,,,,SHEETPROTECTION
+ 0x0218=,PHONETICPR,,,,,,
+ 0x0220=,,,,,,DRAWING,LEGACYDRAWING
+
+ 0x0230=,,,,CFCOLOR,INDEXEDCOLORS,INDEXEDCOLORS_END,
+ 0x0238=,MRUCOLORS,MRUCOLORS_END,,COLOR,DATAVALIDATIONS,DATAVALIDATIONS_END,
+ 0x0240=,EXTERNALNAME,DDEITEMVALUES,DDEITEMVALUES_END,DDEITEM_DOUBLE,DDEITEM_ERROR,DDEITEM_STRING,DDEITEM_EMPTY
+ 0x0248=DDEITEM_BOOL,EXTERNALNAMEREF,EXTERNALNAMEFLAGS,SHEETDATASET|EXTERNALNAME_END,SHEETDATASET_END,,,
+
+ 0x0258=,,,FILLS,FILLS_END,,,
+ 0x0260=,,,FONTS,FONTS_END,BORDERS,BORDERS_END,NUMFMTS
+ 0x0268=NUMFMTS_END,CELLXFS,CELLXFS_END,CELLSTYLES,CELLSTYLES_END,,,
+ 0x0270=,,CELLSTYLEXFS,CELLSTYLEXFS_END
+ 0x0278=,,,,,,,OLEOBJECT
+
+ 0x0290=,,,,TABLEPARTS,TABLEPART,TABLEPARTS_END,
+end
+
+# simple records -------------------------------------------------------------
+
+constlist=SIMPLE-RECORDS
+ 0x0159=int32,dec,count
+ 0x01DD=uint16,hex,flags,PRINTOPTIONS-FLAGS
+ 0x01F9=int32,dec,count
+ 0x0204=int32,dec,type,VOLTYPE-TYPE
+ 0x020D=uint8,dec,error-code,ERRORCODES
+ 0x0244=double,dec,value
+ 0x0245=uint8,dec,error-code,ERRORCODES
+ 0x0248=uint8,dec,value,BOOLEAN
+ 0x025B=int32,dec,count
+ 0x0263=int32,dec,count
+ 0x0265=int32,dec,count
+ 0x0267=int32,dec,count
+ 0x0269=int32,dec,count
+ 0x026B=int32,dec,count
+ 0x0272=int32,dec,count
+ 0x0294=int32,dec,count
+end
+
+# ARRAY ----------------------------------------------------------------------
+
+flagslist=ARRAY-FLAGS
+ 0x01=recalc-always
+end
+
+# BORDER ---------------------------------------------------------------------
+
+flagslist=BORDER-FLAGS
+ 0x01=diag-tl-to-br
+ 0x02=diag-bl-to-tr
+end
+
+# BRK ------------------------------------------------------------------------
+
+flagslist=BRK-FLAGS
+ 0x00000001=manual
+end
+
+# CALCPR ---------------------------------------------------------------------
+
+shortlist=CALCPR-CALCMODE,0,manual,auto,auto-no-tables
+
+flagslist=CALCPR-FLAGS
+ 0x0002=a1
+ 0x0004=iterate
+ 0x0008=full-precision
+ 0x0010=calc-complete
+ 0x0020=calc-on-save
+ 0x0040=concurrent
+ 0x0080=manual-processors
+ 0x0100=force-full-calc
+end
+
+# CELLSTYLE ------------------------------------------------------------------
+
+flagslist=CELLSTYLE-FLAGS
+ 0x0001=builtin
+ 0x0002=hidden
+ 0x0004=custom
+end
+
+multilist=CELLSTYLE-BUILTIN
+ 0=normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink
+ 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
+
+# CFRULE ---------------------------------------------------------------------
+
+shortlist=CFRULE-TYPE,1,cell-is,expression,color-scale,data-bar,top-ten,icon-set
+
+multilist=CFRULE-SUBTYPE
+ 0=cell-is,expression,color-scale,data-bar,icon-set,top-ten,,unique-values,contains-text,contains-blanks
+ 10=not-contains-blanks,contains-errors,not-contains-errors,,,today,tomorrow,yesterday,last-7-days,last-month
+ 20=next-month,this-week,next-week,last-week,this-month,above-average,below-average,duplicate-values,,equal-above-average
+ 30=equal-below-average
+end
+
+shortlist=CFRULE-CELL-OPERATOR,1,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+shortlist=CFRULE-TEXT-OPERATOR,0,contains,not-contains,begins-with,ends-with
+shortlist=CFRULE-TIME-OPERATOR,0,today,yesterday,last-7-days,this-week,last-week,last-month,tomorrow,next-week,next-month,this-month
+shortlist=CFRULE-OTHER-OPERATOR,0,none
+
+flagslist=CFRULE-FLAGS
+ 0x0002=stop-if-true
+ 0x0004=avove-average
+ 0x0008=bottom
+ 0x0010=percent
+end
+
+# COL ------------------------------------------------------------------------
+
+combilist=COL-FLAGS
+ 0x0001=hidden
+ 0x0002=custom-width
+ 0x0004=best-fit
+ 0x0700=uint8,dec,outline-level
+ 0x1000=outline-collapsed
+end
+
+# DATATABLE ------------------------------------------------------------------
+
+flagslist=DATATABLE-FLAGS
+ 0x01=row-table
+ 0x02=table-2d
+ 0x04=ref1-deleted
+ 0x08=ref2-deleted
+end
+
+# DATAVALIDATION -------------------------------------------------------------
+
+combilist=DATAVALIDATION-FLAGS
+ 0x0000000F=uint8,dec,type,DATAVALIDATION-TYPE
+ 0x00000070=uint8,dec,error-style,DATAVALIDATION-ERRORSTYLE
+ 0x00000080=string-list
+ 0x00000100=ignore-empty
+ 0x00000200=no-dropdown
+ 0x00040000=show-input-box
+ 0x00080000=show-error-box
+ 0x00F00000=uint8,dec,operator,DATAVALIDATION-OPERATOR
+end
+
+shortlist=DATAVALIDATION-TYPE,0,any,whole,decimal,list,date,time,text-length,custom
+shortlist=DATAVALIDATION-OPERATOR,0,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+shortlist=DATAVALIDATION-ERRORSTYLE,0,error,warning,info
+
+# DEFINEDNAME ----------------------------------------------------------------
+
+combilist=DEFINEDNAME-FLAGS
+ 0x0001=hidden
+ 0x0002=function
+ 0x0004=command
+ 0x0008=macro
+ 0x0020=built-in
+ 0x0FC0=uint16,dec,func-group,DEFINEDNAME-FUNCGROUP
+end
+
+shortlist=DEFINEDNAME-FUNCGROUP,0,none,financial,date-time,math-trig,statistical,lookup-ref,database,text,logical,information,commands,customizing,macro-control,dde-external,user-definded
+
+constlist=DEFINEDNAME-SHEETID
+ default=
+ -1=global
+end
+
+# DXF ------------------------------------------------------------------------
+
+flagslist=DXF-FLAGS
+ 0x00008000=border-outline
+end
+
+multilist=DXF-SUBREC
+ 0=FILL-PATTERN,FILL-FGCOLOR,FILL-BGCOLOR,FILL-GRADIENT,FILL-STOP
+ 5=FONT-COLOR,BORDER-TOP,BORDER-BOTTOM,BORDER-LEFT,BORDER-RIGHT
+ 10=BORDER-DIAGONAL,BORDER-VERTICAL,BORDER-HORIZONTAL,BORDER-DIAGUP,BORDER-DIAGDOWN
+ 15=ALIGN-HORIZONTAL,ALIGN-VERTICAL,ALIGN-ROTATION,ALIGN-INDENT,ALIGN-READINGORDER
+ 20=ALIGN-WRAPTEXT,ALIGN-JUSTLASTLINE,ALIGN-SHRINKTOFIT,,FONT-NAME
+ 25=FONT-WEIGHT,FONT-UNDERLINE,FONT-ESCAPEMENT,FONT-ITALIC,FONT-STRIKE
+ 30=FONT-OUTLINE,FONT-SHADOW,FONT-CONDENSE,FONT-EXTEND,
+ 35=,FONT-HEIGHT,FONT-SCHEME,NUMFMT-CODE,
+ 40=,NUMFMT-ID,ALIGN-RELINDENT,PROT-LOCKED,PROT-HIDDEN
+end
+
+# EXTERNALBOOK ---------------------------------------------------------------
+
+shortlist=EXTERNALBOOK-TYPE,0,book,dde-link,ole-link
+
+# EXTERNALNAMEFLAGS ----------------------------------------------------------
+
+flagslist=EXTERNALNAMEFLAGS-FLAGS
+ 0x0002=automatic
+ 0x0004=pic-link
+ 0x0008=dde-stddocumentname
+ 0x0010=ole-link
+ 0x0020=iconified
+end
+
+# EXTERNALSHEETS -------------------------------------------------------------
+
+constlist=EXTERNALSHEETS-ID
+ default=
+ -1=deleted
+ -2=special
+end
+
+# EXTSHEETDATA ---------------------------------------------------------------
+
+flagslist=EXTSHEETDATA-FLAGS
+ 0x01=refresh-error
+end
+
+# FILL -----------------------------------------------------------------------
+
+shortlist=FILL-GRADIENTTYPE,0,linear,path
+
+# FONT -----------------------------------------------------------------------
+
+flagslist=FONT-FLAGS
+ 0x0001=bold
+ 0x0002=italic
+ 0x0008=strikeout
+ 0x0010=outline
+ 0x0020=shadow
+ 0x0040=condense
+ 0x0080=extend
+end
+
+constlist=FONT-WEIGHT
+ 400=normal
+ 700=bold
+end
+
+multilist=FONT-UNDERLINE
+ 0x00=none,single,double
+ 0x21=single-acc,double-acc
+end
+
+shortlist=FONT-SCHEME,0,none,major,minor
+shortlist=FONT-ESCAPEMENT,0,none,superscript,subscript
+shortlist=FONT-FAMILY,0,none,roman,swiss,modern,script,decorative
+
+# HEADERFOOTER ---------------------------------------------------------------
+
+flagslist=HEADERFOOTER-FLAGS
+ 0x0001=diff-odd-even
+ 0x0002=diff-dirst
+ 0x0004=scale-with-doc
+ 0x0008=align-with-margins
+end
+
+# PAGESETUP ------------------------------------------------------------------
+
+multilist=PAGESETUP-PAPERSIZE
+ 0=undefined,letter,letter-small,tabloid,ledger,legal,statement,executive,a3,a4
+ 10=a4-small,a5,b4,b5,folio,quarto,10x14,11x17,note,envelope-9
+ 20=envelope-10,envelope-11,envelope-12,envelope-14,c,d,e,envelope-dl,envelope-c5,envelope-c3
+ 30=envelope-c4,envelope-c6,envelope-c65,envelope-b4,envelope-b5,envelope-b6,envelope-italy,envelope-monarch,envelope-6-3/4,us-standard-fanfold
+ 40=german-standard-fanfold,german-legal-fanfold,b4,japanese-dbl-postcaed,9x11,10x11,15x11,,
+ 50=envelope-invite,letter-extra,legal-extra,tabloid-extra,a4-extra,letter-transverse,a4-transverse,letter-extra-transverse,super-a-a4,super-b-a3,letter-plus
+ 60=a4-plus,a5-transverse,jis-b5-transverse,a3-extra,a5-extra,b5-extra,a2,a3-transverse,a3-extra-transverse
+end
+
+constlist=PAGESETUP-SCALETOPAGES
+ default=
+ 0=automatic
+end
+
+combilist=PAGESETUP-FLAGS
+ 0x0001=print-in-rows
+ 0x0002=landscape
+ 0x0004=uninitialized
+ 0x0008=black-and-white
+ 0x0010=draft-quality
+ 0x0020=print-notes
+ 0x0040=default-orientation
+ 0x0080=use-first-page
+ 0x0100=print-notes-at-end
+ 0x0600=uint8,dec,print-errors,PAGESETUP-PRINTERRORS
+end
+
+shortlist=PAGESETUP-PRINTERRORS,0,displayed,none,as-dashes,as-na
+
+unitconverter=PAGESETUP-DPI,1,dpi
+
+# PANE -----------------------------------------------------------------------
+
+shortlist=PANE-ID,0,bottom-right,top-right,bottom-left,top-left
+
+flagslist=PANE-FLAGS
+ 0x01=frozen
+ 0x02=remove-split-with-freeze
+end
+
+# PHONETICPR -----------------------------------------------------------------
+
+shortlist=PHONETICPR-TYPE,0,halfwidth-katakana,fullwidth-katakana,hiragana,no-conversion
+shortlist=PHONETICPR-ALIGNMENT,0,no-control,left,center,distributed
+
+# PRINTOPTIONS ---------------------------------------------------------------
+
+flagslist=PRINTOPTIONS-FLAGS
+ 0x0001=horizontal-centered
+ 0x0002=vertical-centered
+ 0x0004=print-headings
+ 0x0008=print-gridlines
+ 0x0010=gridlines-set
+end
+
+# ROW ------------------------------------------------------------------------
+
+combilist=ROW-FLAGS
+ 0x0001=thick-top
+ 0x0002=thick-bottom
+ 0x0700=uint8,dec,outline-level
+ 0x0800=outline-collapsed
+ 0x1000=hidden
+ 0x2000=custom-height
+ 0x4000=custom-format
+end
+
+# SHEET ----------------------------------------------------------------------
+
+shortlist=SHEET-STATE,0,visible,hidden,very-hidden
+
+# SHEETFORMATPR --------------------------------------------------------------
+
+flagslist=SHEETFORMATPR-FLAGS
+ 0x0001=custom-row-height
+ 0x0002=rows-hidden
+end
+
+# SHEETPR --------------------------------------------------------------------
+
+flagslist=SHEETPR-FLAGS
+ 0x0001=show-autopagebreaks
+ 0x0020=outline-auto-style
+ 0x0040=row-symbols-below
+ 0x0080=column-symbols-right
+ 0x0100=fit-to-pages
+ 0x0400=show-outline-symbols
+end
+
+# SHEETVIEW ------------------------------------------------------------------
+
+flagslist=SHEETVIEW-FLAGS
+ 0x0001=window-protected
+ 0x0002=show-formulas
+ 0x0004=show-gridlines
+ 0x0008=show-headings
+ 0x0010=show-zeros
+ 0x0020=right-to-left
+ 0x0040=selected
+ 0x0080=show-ruler
+ 0x0100=show-outline-symbols
+ 0x0200=default-gridcolor
+ 0x0400=show-whitespace
+end
+
+shortlist=SHEETVIEW-TYPE,0,normal,pagebreak-preview,page-layout
+
+# TABLE ----------------------------------------------------------------------
+
+shortlist=TABLE-TYPE,0,worksheet,,,query-table
+
+flagslist=TABLE-FLAGS
+ 0x00000001=totals-row-shown
+ 0x00000002=published
+ 0x00000004=insert-row
+ 0x00000008=insert-row-shift
+end
+
+# TABLESTYLEINFO -------------------------------------------------------------
+
+flagslist=TABLESTYLEINFO-FLAGS
+ 0x0001=show-first-column
+ 0x0002=show-last-column
+ 0x0004=show-row-stripes
+ 0x0008=show-column-stripes
+end
+
+# VOLTYPE --------------------------------------------------------------------
+
+shortlist=VOLTYPE-TYPE,0,realtime-data,olap-functions
+
+# WORKBBOKPR -----------------------------------------------------------------
+
+combilist=WORKBBOKPR-FLAGS
+ 0x00000001=date-1904
+ 0x00000004=hide-border-unsel-tables
+ 0x00000008=filter-privacy
+ 0x00000010=prompted-solutions
+ 0x00000020=show-ink-annotation
+ 0x00000040=backup-file
+ 0x00000080=strip-extlink-values
+ 0x00000300=uint8,dec,update-links,WORKBBOKPR-UPDATELINKS
+ 0x00000400=hide-pivot-fieldlist
+ 0x00000800=publish-items
+ 0x00001000=check-compatibility
+ 0x00006000=uint8,dec,show-objects,WORKBBOKPR-SHOWOBJECTS
+ 0x00008000=show-pivotchart-filter
+ 0x00010000=autocompress-pic
+end
+
+shortlist=WORKBBOKPR-UPDATELINKS,0,ask-user,never,always
+shortlist=WORKBBOKPR-SHOWOBJECTS,0,show,placeholder,hide
+
+# WORKBOOKVIEW ---------------------------------------------------------------
+
+flagslist=WORKBOOKVIEW-FLAGS
+ 0x01=hidden
+ 0x02=minimized
+ 0x08=show-horizontal-scroll
+ 0x10=show-vertical-scroll
+ 0x20=show-tabbar
+ 0x40=autofilter-date-grouping
+end
+
+# XF -------------------------------------------------------------------------
+
+shortlist=XF-HORALIGN,0,general,left,center,right,fill,block,center-across-sel,distribute
+shortlist=XF-VERALIGN,0,top,center,bottom,justify,distribute
+shortlist=XF-TEXTDIRECTION,0,context,left-to-right,right-to-left
+
+combilist=XF-ALIGNMENT
+ 0x000000FF=uint8,dec,rotation,TEXTROTATION
+ 0x0000FF00=uint8,dec,indent
+ 0x00070000=uint8,dec,hor-align,XF-HORALIGN
+ 0x00380000=uint8,dec,ver-align,XF-VERALIGN
+ 0x00400000=text-wrap
+ 0x00800000=justify-lastline
+ 0x01000000=shrink-to-fit
+ 0x0C000000=uint8,dec,text-dir,XF-TEXTDIRECTION
+ 0x10000000=locked
+ 0x20000000=formula-hidden
+ 0x80000000=quote-prefix
+end
+
+flagslist=XF-USEDFLAGS
+ 0x0001=format
+ 0x0002=font
+ 0x0004=alignment
+ 0x0008=border
+ 0x0010=fill
+ 0x0020=protection
+end
+
+# ============================================================================
+
diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx
new file mode 100644
index 000000000000..499e27e0751e
--- /dev/null
+++ b/oox/source/helper/attributelist.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: attributelist.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/attributelist.hxx"
+#include <osl/diagnose.h>
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XFastAttributeList;
+
+namespace oox {
+
+// ============================================================================
+
+AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) :
+ mxAttribs( rxAttribs )
+{
+ OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" );
+}
+
+bool AttributeList::hasAttribute( sal_Int32 nElement ) const
+{
+ return mxAttribs->hasAttribute( nElement );
+}
+
+sal_Int32 AttributeList::getToken( sal_Int32 nElement, sal_Int32 nDefault ) const
+{
+ return mxAttribs->getOptionalValueToken( nElement, nDefault );
+}
+
+OUString AttributeList::getString( sal_Int32 nElement ) const
+{
+ return mxAttribs->getOptionalValue( nElement );
+}
+
+double AttributeList::getDouble( sal_Int32 nElement, double fDefault ) const
+{
+ OUString aValue = getString( nElement );
+ return (aValue.getLength() == 0) ? fDefault : aValue.toDouble();
+}
+
+sal_Int32 AttributeList::getInteger( sal_Int32 nElement, sal_Int32 nDefault ) const
+{
+ OUString aValue = getString( nElement );
+ return (aValue.getLength() == 0) ? nDefault : aValue.toInt32();
+}
+
+sal_uInt32 AttributeList::getUnsignedInteger( sal_Int32 nElement, sal_uInt32 nDefault ) const
+{
+ OUString aValue = getString( nElement );
+ if( aValue.getLength() == 0 )
+ return nDefault;
+ sal_Int64 nValue = aValue.toInt64();
+ return static_cast< sal_uInt32 >( ((nValue < 0) || (nValue > SAL_MAX_UINT32)) ? 0 : nValue );
+}
+
+sal_Int32 AttributeList::getHex( sal_Int32 nElement, sal_Int32 nDefault ) const
+{
+ OUString aValue = getString( nElement );
+ return (aValue.getLength() == 0) ? nDefault : aValue.toInt32( 16 );
+}
+
+bool AttributeList::getBool( sal_Int32 nElement, bool bDefault ) const
+{
+ // boolean attributes may be "true", "false", "on", "off", "1", or "0"
+ switch( getToken( nElement ) )
+ {
+ case XML_true: return true;
+ case XML_on: return true;
+ case XML_false: return false;
+ case XML_off: return false;
+ }
+ return getInteger( nElement, bDefault ? 1 : 0 ) != 0;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx
new file mode 100644
index 000000000000..d8eaae3ac163
--- /dev/null
+++ b/oox/source/helper/binaryinputstream.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binaryinputstream.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/binaryinputstream.hxx"
+#include <com/sun/star/io/XInputStream.hpp>
+#include <osl/diagnose.h>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::io::XInputStream;
+
+namespace oox {
+
+// ============================================================================
+
+BinaryInputStream::BinaryInputStream( const Reference< XInputStream >& rxInStrm, bool bAutoClose ) :
+ BinaryStreamBase( rxInStrm ),
+ mxInStrm( rxInStrm ),
+ mbAutoClose( bAutoClose )
+{
+}
+
+BinaryInputStream::~BinaryInputStream()
+{
+ if( mbAutoClose )
+ close();
+}
+
+void BinaryInputStream::skip( sal_Int32 nBytes )
+{
+ try
+ {
+ OSL_ENSURE( mxInStrm.is(), "BinaryInputStream::skip - invalid call" );
+ mxInStrm->skipBytes( nBytes );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryInputStream::skip - exception caught" );
+ }
+}
+
+sal_Int32 BinaryInputStream::read( Sequence< sal_Int8 >& orBuffer, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = 0;
+ try
+ {
+ OSL_ENSURE( mxInStrm.is(), "BinaryInputStream::read - invalid call" );
+ nRet = mxInStrm->readBytes( orBuffer, nBytes );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryInputStream::read - stream read error" );
+ }
+ return nRet;
+}
+
+sal_Int32 BinaryInputStream::read( void* opBuffer, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = read( maBuffer, nBytes );
+ if( nRet > 0 )
+ memcpy( opBuffer, maBuffer.getConstArray(), static_cast< size_t >( nRet ) );
+ return nRet;
+}
+
+void BinaryInputStream::close()
+{
+ if( mxInStrm.is() ) try
+ {
+ mxInStrm->closeInput();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryInputStream::close - closing input stream failed" );
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx
new file mode 100644
index 000000000000..c6e4bb2c9ad5
--- /dev/null
+++ b/oox/source/helper/binaryoutputstream.cxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binaryoutputstream.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/binaryoutputstream.hxx"
+#include <osl/diagnose.h>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include "oox/helper/binaryinputstream.hxx"
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::io::XOutputStream;
+
+namespace oox {
+
+// ============================================================================
+
+BinaryOutputStream::BinaryOutputStream( const Reference< XOutputStream >& rxOutStrm, bool bAutoClose ) :
+ BinaryStreamBase( rxOutStrm ),
+ mxOutStrm( rxOutStrm ),
+ mbAutoClose( bAutoClose )
+{
+}
+
+BinaryOutputStream::~BinaryOutputStream()
+{
+ if( mbAutoClose )
+ close();
+}
+
+void BinaryOutputStream::write( const Sequence< sal_Int8 >& rBuffer )
+{
+ try
+ {
+ OSL_ENSURE( mxOutStrm.is(), "BinaryOutputStream::write - invalid call" );
+ mxOutStrm->writeBytes( rBuffer );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryOutputStream::write - stream read error" );
+ }
+}
+
+void BinaryOutputStream::write( const void* pBuffer, sal_Int32 nBytes )
+{
+ if( nBytes > 0 )
+ {
+ maBuffer.realloc( nBytes );
+ memcpy( maBuffer.getArray(), pBuffer, static_cast< size_t >( nBytes ) );
+ write( maBuffer );
+ }
+}
+
+void BinaryOutputStream::copy( BinaryInputStream& rInStrm, sal_Int64 nBytes )
+{
+ if( rInStrm.is() && (nBytes > 0) )
+ {
+ sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, 0x8000 );
+ Sequence< sal_Int8 > aBuffer( nBufferSize );
+ while( nBytes > 0 )
+ {
+ sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, nBufferSize );
+ sal_Int32 nBytesRead = rInStrm.read( aBuffer, nReadSize );
+ write( aBuffer );
+ if( nReadSize == nBytesRead )
+ nBytes -= nReadSize;
+ else
+ nBytes = 0;
+ }
+ }
+}
+
+void BinaryOutputStream::close()
+{
+ if( mxOutStrm.is() ) try
+ {
+ mxOutStrm->flush();
+ mxOutStrm->closeOutput();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryOutputStream::close - closing output stream failed" );
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/binarystreambase.cxx b/oox/source/helper/binarystreambase.cxx
new file mode 100644
index 000000000000..4eb0bf45f645
--- /dev/null
+++ b/oox/source/helper/binarystreambase.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarystreambase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/binarystreambase.hxx"
+#include <osl/diagnose.h>
+
+using ::com::sun::star::uno::Exception;
+
+namespace oox {
+
+// ============================================================================
+
+BinaryStreamBase::~BinaryStreamBase()
+{
+}
+
+sal_Int64 BinaryStreamBase::getLength() const
+{
+ try
+ {
+ return mxSeekable.is() ? mxSeekable->getLength() : -1;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryStreamBase::getLength - exception caught" );
+ }
+ return -1;
+}
+
+sal_Int64 BinaryStreamBase::tell() const
+{
+ try
+ {
+ return mxSeekable.is() ? mxSeekable->getPosition() : -1;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryStreamBase::tell - exception caught" );
+ }
+ return -1;
+}
+
+void BinaryStreamBase::seek( sal_Int64 nPos )
+{
+ try
+ {
+ if( mxSeekable.is() )
+ mxSeekable->seek( nPos );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryStreamBase::seek - exception caught" );
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx
new file mode 100644
index 000000000000..bb45b86ea561
--- /dev/null
+++ b/oox/source/helper/containerhelper.cxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: containerhelper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/containerhelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <comphelper/processfactory.hxx>
+#include "oox/helper/helper.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+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 ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::container::XIndexContainer;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::container::XNameContainer;
+
+namespace oox {
+
+// ============================================================================
+
+Reference< XIndexContainer > ContainerHelper::createIndexContainer()
+{
+ Reference< XIndexContainer > xContainer;
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xContainer.is(), "ContainerHelper::createIndexContainer - cannot create container" );
+ return xContainer;
+}
+
+bool ContainerHelper::insertByIndex(
+ const Reference< XIndexContainer >& rxIndexContainer,
+ sal_Int32 nIndex, const Any& rObject )
+{
+ OSL_ENSURE( rxIndexContainer.is(), "ContainerHelper::insertByIndex - missing XIndexContainer interface" );
+ bool bRet = false;
+ try
+ {
+ rxIndexContainer->insertByIndex( nIndex, rObject );
+ bRet = true;
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( bRet, "ContainerHelper::insertByIndex - cannot insert object" );
+ return bRet;
+}
+
+Reference< XNameContainer > ContainerHelper::createNameContainer()
+{
+ Reference< XNameContainer > xContainer;
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xContainer.is(), "ContainerHelper::createNameContainer - cannot create container" );
+ return xContainer;
+}
+
+OUString ContainerHelper::getUnusedName(
+ const Reference< XNameAccess >& rxNameAccess, const OUString& rSuggestedName,
+ sal_Unicode cSeparator, sal_Int32 nFirstIndexToAppend )
+{
+ OSL_ENSURE( rxNameAccess.is(), "ContainerHelper::getUnusedName - missing XNameAccess interface" );
+
+ OUString aNewName = rSuggestedName;
+ sal_Int32 nIndex = nFirstIndexToAppend;
+ while( rxNameAccess->hasByName( aNewName ) )
+ aNewName = OUStringBuffer( rSuggestedName ).append( cSeparator ).append( nIndex++ ).makeStringAndClear();
+ return aNewName;
+}
+
+bool ContainerHelper::insertByName(
+ const Reference< XNameContainer >& rxNameContainer,
+ const OUString& rName, const Any& rObject )
+{
+ OSL_ENSURE( rxNameContainer.is(), "ContainerHelper::insertByName - missing XNameContainer interface" );
+ bool bRet = false;
+ try
+ {
+ rxNameContainer->insertByName( rName, rObject );
+ bRet = true;
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( bRet, "ContainerHelper::insertByName - cannot insert object" );
+ return bRet;
+}
+
+OUString ContainerHelper::insertByUnusedName(
+ const Reference< XNameContainer >& rxNameContainer, const Any& rObject,
+ const OUString& rSuggestedName, sal_Unicode cSeparator, bool bRenameOldExisting )
+{
+ OSL_ENSURE( rxNameContainer.is(), "ContainerHelper::insertByUnusedName - missing XNameContainer interface" );
+
+ // find an unused name
+ Reference< XNameAccess > xNameAccess( rxNameContainer, UNO_QUERY );
+ OUString aNewName = getUnusedName( xNameAccess, rSuggestedName, cSeparator );
+
+ // rename existing object
+ if( bRenameOldExisting && rxNameContainer->hasByName( rSuggestedName ) )
+ {
+ try
+ {
+ Any aOldObject = rxNameContainer->getByName( rSuggestedName );
+ rxNameContainer->removeByName( rSuggestedName );
+ rxNameContainer->insertByName( aNewName, aOldObject );
+ aNewName = rSuggestedName;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "ContainerHelper::insertByUnusedName - cannot rename old object" );
+ }
+ }
+
+ // insert the new object and return its resulting name
+ insertByName( rxNameContainer, aNewName, rObject );
+ return aNewName;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/makefile.mk b/oox/source/helper/makefile.mk
new file mode 100644
index 000000000000..d35a5ca1ef45
--- /dev/null
+++ b/oox/source/helper/makefile.mk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=helper
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/attributelist.obj \
+ $(SLO)$/binaryinputstream.obj \
+ $(SLO)$/binaryoutputstream.obj \
+ $(SLO)$/binarystreambase.obj \
+ $(SLO)$/containerhelper.obj \
+ $(SLO)$/olestorage.obj \
+ $(SLO)$/progressbar.obj \
+ $(SLO)$/propertymap.obj \
+ $(SLO)$/propertysequence.obj \
+ $(SLO)$/propertyset.obj \
+ $(SLO)$/recordinputstream.obj \
+ $(SLO)$/storagebase.obj \
+ $(SLO)$/zipstorage.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/helper/olestorage.cxx b/oox/source/helper/olestorage.cxx
new file mode 100644
index 000000000000..f68a9647697c
--- /dev/null
+++ b/oox/source/helper/olestorage.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: olestorage.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/olestorage.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include "oox/helper/helper.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::embed::XStorage;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+
+namespace oox {
+
+// ============================================================================
+
+OleStorage::OleStorage(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XInputStream >& rxInStream,
+ bool bBaseStreamAccess ) :
+ StorageBase( rxInStream, bBaseStreamAccess )
+{
+ OSL_ENSURE( rxFactory.is(), "OleStorage::OleStorage - missing service factory" );
+ // create base storage object
+ Sequence< Any > aArgs( 2 );
+ aArgs[ 0 ] <<= rxInStream;
+ aArgs[ 1 ] <<= true; // true = do not create a copy of the input stream
+ mxStorage.set( rxFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY );
+ mxElements.set( mxStorage, UNO_QUERY );
+}
+
+OleStorage::OleStorage(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XOutputStream >& rxOutStream,
+ bool bBaseStreamAccess ) :
+ StorageBase( rxOutStream, bBaseStreamAccess )
+{
+ OSL_ENSURE( rxFactory.is(), "OleStorage::OleStorage - missing service factory" );
+ (void)rxFactory; // prevent compiler warning
+ OSL_ENSURE( false, "OleStorage::OleStorage - not implemented" );
+ mxElements.set( mxStorage, UNO_QUERY );
+}
+
+OleStorage::OleStorage( const OleStorage& rParentStorage, const Reference< XNameAccess >& rxElementsAccess, const OUString& rElementName ) :
+ StorageBase( rParentStorage, rElementName ),
+ mxStorage( rParentStorage.mxStorage ),
+ mxElements( rxElementsAccess )
+{
+ OSL_ENSURE( mxElements.is(), "OleStorage::OleStorage - missing elements access" );
+}
+
+OleStorage::~OleStorage()
+{
+}
+
+// StorageBase interface ------------------------------------------------------
+
+bool OleStorage::implIsStorage() const
+{
+ if( mxStorage.is() && mxElements.is() ) try
+ {
+ /* If this is not a storage, hasElements() throws an exception. But we
+ do not return the result of hasElements(), because an empty storage
+ is a valid storage too. */
+ mxElements->hasElements();
+ return true;
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+Reference< XStorage > OleStorage::implGetXStorage() const
+{
+ OSL_ENSURE( false, "OleStorage::getXStorage - not implemented" );
+ return Reference< XStorage >();
+}
+
+void OleStorage::implGetElementNames( ::std::vector< OUString >& orElementNames ) const
+{
+ Sequence< OUString > aNames;
+ if( mxStorage.is() ) try
+ {
+ aNames = mxElements->getElementNames();
+ if( aNames.getLength() > 0 )
+ orElementNames.insert( orElementNames.end(), aNames.getConstArray(), aNames.getConstArray() + aNames.getLength() );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+StorageRef OleStorage::implOpenSubStorage( const OUString& rElementName, bool bCreate )
+{
+ OSL_ENSURE( !bCreate, "OleStorage::implOpenSubStorage - creating substorages not implemented" );
+ (void)bCreate; // prevent compiler warning
+ StorageRef xSubStorage;
+ if( mxElements.is() ) try
+ {
+ Reference< XNameAccess > xSubElements( mxElements->getByName( rElementName ), UNO_QUERY_THROW );
+ xSubStorage.reset( new OleStorage( *this, xSubElements, rElementName ) );
+ }
+ catch( Exception& )
+ {
+ }
+ return xSubStorage;
+}
+
+Reference< XInputStream > OleStorage::implOpenInputStream( const OUString& rElementName )
+{
+ Reference< XInputStream > xInStream;
+ if( mxElements.is() ) try
+ {
+ xInStream.set( mxElements->getByName( rElementName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xInStream;
+}
+
+Reference< XOutputStream > OleStorage::implOpenOutputStream( const OUString& rElementName )
+{
+ Reference< XOutputStream > xOutStream;
+ if( mxElements.is() && (rElementName.getLength() > 0) ) try
+ {
+ (void)rElementName; // prevent compiler warning
+ OSL_ENSURE( false, "OleStorage::implOpenOutputStream - not implemented" );
+ }
+ catch( Exception& )
+ {
+ }
+ return xOutStream;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/progressbar.cxx b/oox/source/helper/progressbar.cxx
new file mode 100644
index 000000000000..b811eca2b3e9
--- /dev/null
+++ b/oox/source/helper/progressbar.cxx
@@ -0,0 +1,193 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: progressbar.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/progressbar.hxx"
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include "oox/helper/helper.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::task::XStatusIndicator;
+
+namespace oox {
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 PROGRESS_RANGE = 1000000;
+
+} // namespace
+
+// ============================================================================
+
+IProgressBar::~IProgressBar()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ISegmentProgressBar::~ISegmentProgressBar()
+{
+}
+
+// ============================================================================
+// ============================================================================
+
+ProgressBar::ProgressBar( const Reference< XStatusIndicator >& rxIndicator, const OUString& rText ) :
+ mxIndicator( rxIndicator ),
+ mfPosition( 0 )
+{
+ if( mxIndicator.is() )
+ mxIndicator->start( rText, PROGRESS_RANGE );
+}
+
+ProgressBar::~ProgressBar()
+{
+ if( mxIndicator.is() )
+ mxIndicator->end();
+}
+
+double ProgressBar::getPosition() const
+{
+ return mfPosition;
+}
+
+void ProgressBar::setPosition( double fPosition )
+{
+ OSL_ENSURE( (mfPosition <= fPosition) && (fPosition <= 1.0), "ProgressBar::setPosition - invalid position" );
+ mfPosition = getLimitedValue< double >( fPosition, mfPosition, 1.0 );
+ if( mxIndicator.is() )
+ mxIndicator->setValue( static_cast< sal_Int32 >( mfPosition * PROGRESS_RANGE ) );
+}
+
+// ============================================================================
+
+namespace prv {
+
+class SubSegment : public ISegmentProgressBar
+{
+public:
+ explicit SubSegment( IProgressBar& rParentProgress, double fStartPos, double fLength );
+
+ virtual double getPosition() const;
+ virtual void setPosition( double fPosition );
+
+ virtual double getFreeLength() const;
+ virtual ISegmentProgressBarRef createSegment( double fLength );
+
+private:
+ IProgressBar& mrParentProgress;
+ double mfStartPos;
+ double mfLength;
+ double mfPosition;
+ double mfFreeStart;
+};
+
+// ----------------------------------------------------------------------------
+
+SubSegment::SubSegment( IProgressBar& rParentProgress, double fStartPos, double fLength ) :
+ mrParentProgress( rParentProgress ),
+ mfStartPos( fStartPos ),
+ mfLength( fLength ),
+ mfPosition( 0.0 ),
+ mfFreeStart( 0.0 )
+{
+}
+
+double SubSegment::getPosition() const
+{
+ return mfPosition;
+}
+
+void SubSegment::setPosition( double fPosition )
+{
+ OSL_ENSURE( (mfPosition <= fPosition) && (fPosition <= 1.0), "SubSegment::setPosition - invalid position" );
+ mfPosition = getLimitedValue< double >( fPosition, mfPosition, 1.0 );
+ mrParentProgress.setPosition( mfStartPos + mfPosition * mfLength );
+}
+
+double SubSegment::getFreeLength() const
+{
+ return 1.0 - mfFreeStart;
+}
+
+ISegmentProgressBarRef SubSegment::createSegment( double fLength )
+{
+ OSL_ENSURE( (0.0 < fLength) && (fLength <= getFreeLength()), "SubSegment::createSegment - invalid length" );
+ fLength = getLimitedValue< double >( fLength, 0.0, getFreeLength() );
+ ISegmentProgressBarRef xSegment( new prv::SubSegment( *this, mfFreeStart, fLength ) );
+ mfFreeStart += fLength;
+ return xSegment;
+}
+
+} // namespace prv
+
+// ============================================================================
+
+SegmentProgressBar::SegmentProgressBar( const Reference< XStatusIndicator >& rxIndicator, const OUString& rText ) :
+ maProgress( rxIndicator, rText ),
+ mfFreeStart( 0.0 )
+{
+}
+
+double SegmentProgressBar::getPosition() const
+{
+ return maProgress.getPosition();
+}
+
+void SegmentProgressBar::setPosition( double fPosition )
+{
+ maProgress.setPosition( fPosition );
+}
+
+double SegmentProgressBar::getFreeLength() const
+{
+ return 1.0 - mfFreeStart;
+}
+
+ISegmentProgressBarRef SegmentProgressBar::createSegment( double fLength )
+{
+ OSL_ENSURE( (0.0 < fLength) && (fLength <= getFreeLength()), "SegmentProgressBar::createSegment - invalid length" );
+ fLength = getLimitedValue< double >( fLength, 0.0, getFreeLength() );
+ ISegmentProgressBarRef xSegment( new prv::SubSegment( maProgress, mfFreeStart, fLength ) );
+ mfFreeStart += fLength;
+ return xSegment;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/propertymap.cxx b/oox/source/helper/propertymap.cxx
new file mode 100644
index 000000000000..d6c8dd0b1cec
--- /dev/null
+++ b/oox/source/helper/propertymap.cxx
@@ -0,0 +1,286 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertymap.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/propertymap.hxx"
+
+#include <string>
+#include <stdio.h>
+#include <osl/mutex.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+using ::rtl::OUString;
+using ::osl::MutexGuard;
+using ::osl::Mutex;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+
+namespace oox {
+
+bool PropertyMap::hasProperty( const ::rtl::OUString& rName ) const
+{
+ return find( rName ) != end();
+}
+
+const Any* PropertyMap::getPropertyValue( const ::rtl::OUString& rName ) const
+{
+ PropertyMapBase::const_iterator aIter( find( rName ) );
+ return aIter != end() ? &((*aIter).second) : NULL;
+}
+
+void PropertyMap::makeSequence( Sequence< NamedValue >& rSequence ) const
+{
+ rSequence.realloc( size() );
+ NamedValue* pValues = rSequence.getArray();
+ const_iterator aIter( begin() );
+ const_iterator aEnd( end() );
+
+ for( ; aIter != aEnd; aIter++, pValues++ )
+ {
+ pValues->Name = (*aIter).first;
+ pValues->Value = (*aIter).second;
+ }
+}
+
+
+void PropertyMap::makeSequence( Sequence< PropertyValue >& rSequence ) const
+{
+ rSequence.realloc( size() );
+ PropertyValue* pValues = rSequence.getArray();
+ const_iterator aIter( begin() );
+ const_iterator aEnd( end() );
+
+ for( ; aIter != aEnd; aIter++, pValues++ )
+ {
+ pValues->Name = (*aIter).first;
+ pValues->Value = (*aIter).second;
+ pValues->State = PropertyState_DIRECT_VALUE;
+ }
+}
+
+void PropertyMap::makeSequence( Sequence< OUString >& rNames, Sequence< Any >& rValues ) const
+{
+ rNames.realloc( size() );
+ rValues.realloc( size() );
+ OUString* pNames = rNames.getArray();
+ Any* pValues = rValues.getArray();
+ const_iterator aIter( begin() );
+ const_iterator aEnd( end() );
+
+ for( ; aIter != aEnd; aIter++, pNames++, pValues++ )
+ {
+ *pNames = (*aIter).first;
+ *pValues = (*aIter).second;
+ }
+}
+
+
+void PropertyMap::dump_debug(const char *pMessage)
+{
+ const_iterator aIter( begin() );
+ const_iterator aEnd( end() );
+
+ if( pMessage != NULL)
+ {
+ OSL_TRACE("OOX: %s", pMessage);
+ }
+
+ if(aIter == aEnd)
+ {
+ OSL_TRACE("OOX: Properties empty");
+ return;
+ }
+
+ OSL_TRACE("OOX: Properties");
+
+ for( ; aIter != aEnd; aIter++ )
+ {
+ std::string value;
+ const Any & any = (*aIter).second;
+ try {
+ char buffer[256];
+ if(!any.hasValue() )
+ {
+ value = "*empty*";
+ }
+ else if(any.has<OUString>() )
+ {
+ OUString aStr;
+ any >>= aStr;
+ value = OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US ).getStr();
+ }
+ else if(any.has<sal_Int16>())
+ {
+ sal_Int16 v = 0;
+ any >>= v;
+ sprintf(buffer, "%d", (int)v);
+ value = buffer;
+ }
+ else if(any.has<sal_Int32>())
+ {
+ sal_Int32 v = 0;
+ any >>= v;
+ sprintf(buffer, "%d", (int)v);
+ value = buffer;
+ }
+ else if(any.has<sal_Bool>())
+ {
+ sal_Bool v = sal_False;
+ any >>= v;
+ sprintf(buffer, "%d", (int)v);
+ value = buffer;
+ }
+ else
+ {
+ value = "contains a: ";
+ value += OUStringToOString(any.getValueTypeName(), RTL_TEXTENCODING_ASCII_US ).getStr();
+ }
+ }
+ catch( ... )
+ {
+ value = "unable to convert from ";
+ value += OUStringToOString(any.getValueTypeName(), RTL_TEXTENCODING_ASCII_US ).getStr();
+ }
+ OSL_TRACE("OOX: -> %s = %s", OUStringToOString( (*aIter).first, RTL_TEXTENCODING_ASCII_US ).getStr(),
+ value.c_str());
+ }
+}
+
+/** this class implements a generic XPropertySet
+ Properties of all names and types can be set and later retrieved
+ TODO: move this to comphelper or better find an existing implementation */
+class GenericPropertySet : public ::cppu::WeakImplHelper2< XPropertySet, XPropertySetInfo >,
+ private PropertyMapBase,
+ private Mutex
+{
+public:
+ GenericPropertySet();
+ GenericPropertySet( const PropertyMapBase& rProperties );
+
+ // XPropertySet
+ virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (RuntimeException);
+ virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
+ virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
+
+ // XPropertySetInfo
+ virtual Sequence< Property > SAL_CALL getProperties( ) throw (RuntimeException);
+ virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException);
+};
+
+GenericPropertySet::GenericPropertySet()
+{
+}
+
+GenericPropertySet::GenericPropertySet( const PropertyMapBase& rProperties )
+: PropertyMapBase( rProperties )
+{
+}
+
+Reference< XPropertySetInfo > SAL_CALL GenericPropertySet::getPropertySetInfo() throw (RuntimeException)
+{
+ return this;
+}
+
+void SAL_CALL GenericPropertySet::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ MutexGuard aGuard( *this );
+ (*this)[ aPropertyName ] = aValue;
+}
+
+Any SAL_CALL GenericPropertySet::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ iterator aIter( find( PropertyName ) );
+ if( aIter == end() )
+ throw UnknownPropertyException();
+
+ return (*aIter).second;
+}
+
+void SAL_CALL GenericPropertySet::addPropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
+void SAL_CALL GenericPropertySet::removePropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
+void SAL_CALL GenericPropertySet::addVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
+void SAL_CALL GenericPropertySet::removeVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
+
+// XPropertySetInfo
+Sequence< Property > SAL_CALL GenericPropertySet::getProperties( ) throw (RuntimeException)
+{
+ Sequence< Property > aRet( size() );
+ Property* pProperty = aRet.getArray();
+
+ for( iterator aIter = begin(); aIter != end(); aIter++, pProperty++ )
+ {
+ pProperty->Name = (*aIter).first;
+ pProperty->Handle = 0;
+ pProperty->Type = (*aIter).second.getValueType();
+ pProperty->Attributes = 0;
+ }
+
+ return aRet;
+}
+
+Property SAL_CALL GenericPropertySet::getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException)
+{
+ iterator aIter( find( aName ) );
+ if( aIter == end() )
+ throw UnknownPropertyException();
+
+ Property aProperty;
+ aProperty.Name = (*aIter).first;
+ aProperty.Handle = 0;
+ aProperty.Type = (*aIter).second.getValueType();
+ aProperty.Attributes = 0;
+
+ return aProperty;
+}
+
+::sal_Bool SAL_CALL GenericPropertySet::hasPropertyByName( const OUString& Name ) throw (RuntimeException)
+{
+ return find( Name ) != end();
+}
+
+
+Reference< XPropertySet > PropertyMap::makePropertySet() const
+{
+ Reference< XPropertySet > xSet( new GenericPropertySet(*this) );
+ return xSet;
+}
+
+}
+
diff --git a/oox/source/helper/propertysequence.cxx b/oox/source/helper/propertysequence.cxx
new file mode 100644
index 000000000000..becf2549f757
--- /dev/null
+++ b/oox/source/helper/propertysequence.cxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertysequence.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/propertysequence.hxx"
+#include "oox/helper/propertyset.hxx"
+#include <algorithm>
+#include <osl/diagnose.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::beans::PropertyValue;
+
+namespace oox {
+
+// ============================================================================
+
+PropertySequence::PropertySequence( const sal_Char* const* ppcPropNames,
+ const sal_Char* const* ppcPropNames2, const sal_Char* const* ppcPropNames3 ) :
+ mnNextIndex( 0 )
+{
+ OSL_ENSURE( ppcPropNames, "PropertySequence::PropertySequence - no strings found" );
+
+ // create OUStrings from ASCII property names
+ typedef ::std::pair< OUString, size_t > IndexedOUString;
+ typedef ::std::vector< IndexedOUString > IndexedOUStringVec;
+ IndexedOUStringVec aPropNameVec;
+ size_t nVecIdx = 0;
+ while( *ppcPropNames )
+ {
+ OUString aPropName = OUString::createFromAscii( *ppcPropNames++ );
+ aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx++ ) );
+ }
+ if( ppcPropNames2 ) while( *ppcPropNames2 )
+ {
+ OUString aPropName = OUString::createFromAscii( *ppcPropNames2++ );
+ aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx++ ) );
+ }
+ if( ppcPropNames3 ) while( *ppcPropNames3 )
+ {
+ OUString aPropName = OUString::createFromAscii( *ppcPropNames3++ );
+ aPropNameVec.push_back( IndexedOUString( aPropName, nVecIdx++ ) );
+ }
+
+ // sorts the pairs, which will be sorted by first component (the property name)
+ ::std::sort( aPropNameVec.begin(), aPropNameVec.end() );
+
+ // resize member sequences
+ size_t nSize = aPropNameVec.size();
+ maNameSeq.realloc( static_cast< sal_Int32 >( nSize ) );
+ maValueSeq.realloc( static_cast< sal_Int32 >( nSize ) );
+ maNameOrder.resize( nSize );
+
+ // fill the property name sequence and store original sort order
+ sal_Int32 nSeqIdx = 0;
+ for( IndexedOUStringVec::const_iterator aIt = aPropNameVec.begin(),
+ aEnd = aPropNameVec.end(); aIt != aEnd; ++aIt, ++nSeqIdx )
+ {
+ maNameSeq[ nSeqIdx ] = aIt->first;
+ maNameOrder[ aIt->second ] = nSeqIdx;
+ }
+}
+
+void PropertySequence::clearAllAnys()
+{
+ for( sal_Int32 nIdx = 0, nLen = maValueSeq.getLength(); nIdx < nLen; ++nIdx )
+ maValueSeq[ nIdx ].clear();
+}
+
+// read properties ------------------------------------------------------------
+
+void PropertySequence::readFromPropertySet( const PropertySet& rPropSet )
+{
+ rPropSet.getProperties( maValueSeq, maNameSeq );
+ mnNextIndex = 0;
+}
+
+bool PropertySequence::readValue( Any& rAny )
+{
+ Any* pAny = getNextAny();
+ if( pAny ) rAny = *pAny;
+ return pAny != 0;
+}
+
+// write properties -----------------------------------------------------------
+
+void PropertySequence::writeValue( const Any& rAny )
+{
+ if( Any* pAny = getNextAny() )
+ *pAny = rAny;
+}
+
+void PropertySequence::writeToPropertySet( PropertySet& rPropSet )
+{
+ OSL_ENSURE( mnNextIndex == maNameOrder.size(), "PropertySequence::writeToPropertySet - sequence not complete" );
+ rPropSet.setProperties( maNameSeq, maValueSeq );
+ mnNextIndex = 0;
+}
+
+Sequence< PropertyValue > PropertySequence::createPropertySequence()
+{
+ OSL_ENSURE( mnNextIndex == maNameOrder.size(), "PropertySequence::createPropertySequence - sequence not complete" );
+ Sequence< PropertyValue > aPropSeq( maNameSeq.getLength() );
+ PropertyValue* pProp = aPropSeq.getArray();
+ PropertyValue* pPropEnd = pProp + aPropSeq.getLength();
+ const OUString* pName = maNameSeq.getConstArray();
+ const Any* pValue = maValueSeq.getConstArray();
+ for( ; pProp != pPropEnd; ++pProp, ++pName, ++pValue )
+ {
+ pProp->Name = *pName;
+ pProp->Value = *pValue;
+ }
+ mnNextIndex = 0;
+ return aPropSeq;
+}
+
+// private --------------------------------------------------------------------
+
+Any* PropertySequence::getNextAny()
+{
+ OSL_ENSURE( mnNextIndex < maNameOrder.size(), "PropertySequence::getNextAny - sequence overflow" );
+ Any* pAny = 0;
+ if( mnNextIndex < maNameOrder.size() )
+ pAny = &maValueSeq[ maNameOrder[ mnNextIndex++ ] ];
+ return pAny;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx
new file mode 100644
index 000000000000..0b5af8269e6d
--- /dev/null
+++ b/oox/source/helper/propertyset.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertyset.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/propertyset.hxx"
+#include <rtl/strbuf.hxx>
+#include <osl/diagnose.h>
+
+using ::rtl::OUString;
+using ::rtl::OStringBuffer;
+using ::rtl::OUStringToOString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+
+namespace oox {
+
+// ============================================================================
+
+void PropertySet::set( const Reference< XPropertySet >& rxPropSet )
+{
+ mxPropSet = rxPropSet;
+ mxMultiPropSet.set( mxPropSet, UNO_QUERY );
+}
+
+// Get properties -------------------------------------------------------------
+
+bool PropertySet::getAnyProperty( Any& orValue, const OUString& rPropName ) const
+{
+ bool bHasValue = false;
+ try
+ {
+ if( mxPropSet.is() )
+ {
+ orValue = mxPropSet->getPropertyValue( rPropName );
+ bHasValue = true;
+ }
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, OStringBuffer( "PropertySet::getAnyProperty - cannot get property \"" ).
+ append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() );
+ }
+ return bHasValue;
+}
+
+bool PropertySet::getBoolProperty( const OUString& rPropName ) const
+{
+ Any aAny;
+ bool bValue = false;
+ return getAnyProperty( aAny, rPropName ) && (aAny >>= bValue) && bValue;
+}
+
+void PropertySet::getProperties( Sequence< Any >& orValues, const Sequence< OUString >& rPropNames ) const
+{
+ try
+ {
+ if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
+ {
+ orValues = mxMultiPropSet->getPropertyValues( rPropNames );
+ }
+ else if( mxPropSet.is() )
+ {
+ sal_Int32 nLen = rPropNames.getLength();
+ const OUString* pPropName = rPropNames.getConstArray();
+ const OUString* pPropNameEnd = pPropName + nLen;
+ orValues.realloc( nLen );
+ Any* pValue = orValues.getArray();
+ for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
+ *pValue = mxPropSet->getPropertyValue( *pPropName );
+ }
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "PropertySet::getProperties - cannot get all property values" );
+ }
+}
+
+// Set properties -------------------------------------------------------------
+
+void PropertySet::setAnyProperty( const OUString& rPropName, const Any& rValue )
+{
+ try
+ {
+ if( mxPropSet.is() )
+ mxPropSet->setPropertyValue( rPropName, rValue );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, OStringBuffer( "PropertySet::setAnyProperty - cannot set property \"" ).
+ append( OUStringToOString( rPropName, RTL_TEXTENCODING_ASCII_US ) ).append( '"' ).getStr() );
+ }
+}
+
+void PropertySet::setProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
+{
+ OSL_ENSURE( rPropNames.getLength() == rValues.getLength(),
+ "PropertySet::setProperties - length of sequences different" );
+ try
+ {
+ if( mxMultiPropSet.is() ) // first try the XMultiPropertySet
+ {
+ mxMultiPropSet->setPropertyValues( rPropNames, rValues );
+ }
+ else if( mxPropSet.is() )
+ {
+ const OUString* pPropName = rPropNames.getConstArray();
+ const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
+ const Any* pValue = rValues.getConstArray();
+ for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
+ mxPropSet->setPropertyValue( *pPropName, *pValue );
+ }
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "PropertySet::setAnyProperty - cannot set all property values" );
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/recordinputstream.cxx b/oox/source/helper/recordinputstream.cxx
new file mode 100644
index 000000000000..66f414b36de5
--- /dev/null
+++ b/oox/source/helper/recordinputstream.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: recordinputstream.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/recordinputstream.hxx"
+#include <vector>
+
+using ::rtl::OUString;
+
+namespace oox {
+
+// ============================================================================
+
+RecordInputStream::RecordInputStream( const RecordDataSequence& rData ) :
+ maData( rData ),
+ mnRecSize( rData.getLength() ),
+ mnRecPos( 0 ),
+ mbValid( true )
+{
+}
+
+sal_Int32 RecordInputStream::read( void* opData, sal_Int32 nBytes )
+{
+ sal_Int32 nReadSize = ::std::min( nBytes, getRecLeft() );
+ OSL_ENSURE( !mbValid || (nReadSize == nBytes), "RecordInputStream::read - buffer overflow" );
+ mbValid = nReadSize == nBytes;
+ if( mbValid && opData && (nReadSize > 0) )
+ memcpy( opData, maData.getConstArray() + mnRecPos, nReadSize );
+ mnRecPos += nReadSize;
+ return nReadSize;
+}
+
+OUString RecordInputStream::readString( bool b32BitLen )
+{
+ OUString aString;
+ sal_Int32 nCharCount = b32BitLen ? readValue< sal_Int32 >() : readValue< sal_Int16 >();
+ // string length -1 is often used to indicate a missing string
+ OSL_ENSURE( !mbValid || (nCharCount >= -1), "RecordInputStream::readString - invalid string length" );
+ if( mbValid && (nCharCount >= 0) )
+ {
+ ::std::vector< sal_Unicode > aBuffer;
+ aBuffer.reserve( getLimitedValue< size_t, sal_Int32 >( nCharCount + 1, 0, 0xFFFF ) );
+ for( sal_Int32 nCharIdx = 0; mbValid && (nCharIdx < nCharCount); ++nCharIdx )
+ {
+ sal_uInt16 nChar;
+ readValue( nChar );
+ aBuffer.push_back( static_cast< sal_Unicode >( nChar ) );
+ }
+ aBuffer.push_back( 0 );
+ aString = OUString( &aBuffer.front() );
+ }
+ return aString;
+}
+
+void RecordInputStream::seek( sal_Int32 nRecPos )
+{
+ mnRecPos = getLimitedValue< sal_Int32, sal_Int32 >( nRecPos, 0, mnRecSize );
+ OSL_ENSURE( !mbValid || (nRecPos == mnRecPos), "RecordInputStream::seek - invalid position" );
+ mbValid = nRecPos == mnRecPos;
+}
+
+void RecordInputStream::skip( sal_Int32 nBytes )
+{
+ sal_Int32 nSkipSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, getRecLeft() );
+ OSL_ENSURE( !mbValid || (nSkipSize == nBytes), "RecordInputStream::skip - buffer overflow" );
+ mbValid = nSkipSize == nBytes;
+ mnRecPos += nSkipSize;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/storagebase.cxx b/oox/source/helper/storagebase.cxx
new file mode 100644
index 000000000000..8fd7f1c25e80
--- /dev/null
+++ b/oox/source/helper/storagebase.cxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: storagebase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/storagebase.hxx"
+#include <rtl/ustrbuf.hxx>
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::embed::XStorage;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+
+namespace oox {
+
+// ============================================================================
+
+namespace {
+
+void lclSplitFirstElement( OUString& orElement, OUString& orRemainder, const OUString& rFullName )
+{
+ sal_Int32 nSlashPos = rFullName.indexOf( '/' );
+ if( (0 <= nSlashPos) && (nSlashPos < rFullName.getLength()) )
+ {
+ orElement = rFullName.copy( 0, nSlashPos );
+ orRemainder = rFullName.copy( nSlashPos + 1 );
+ }
+ else
+ {
+ orElement = rFullName;
+ }
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+StorageBase::StorageBase( const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) :
+ mxInStream( rxInStream ),
+ mpParentStorage( 0 ),
+ mbBaseStreamAccess( bBaseStreamAccess )
+{
+ OSL_ENSURE( mxInStream.is(), "StorageBase::StorageBase - missing base input stream" );
+}
+
+StorageBase::StorageBase( const Reference< XOutputStream >& rxOutStream, bool bBaseStreamAccess ) :
+ mxOutStream( rxOutStream ),
+ mpParentStorage( 0 ),
+ mbBaseStreamAccess( bBaseStreamAccess )
+{
+ OSL_ENSURE( mxOutStream.is(), "StorageBase::StorageBase - missing base output stream" );
+}
+
+StorageBase::StorageBase( const StorageBase& rParentStorage, const OUString& rStorageName ) :
+ maStorageName( rStorageName ),
+ mpParentStorage( &rParentStorage ),
+ mbBaseStreamAccess( false )
+{
+}
+
+StorageBase::~StorageBase()
+{
+}
+
+bool StorageBase::isStorage() const
+{
+ return implIsStorage();
+}
+
+Reference< XStorage > StorageBase::getXStorage() const
+{
+ return implGetXStorage();
+}
+
+const OUString& StorageBase::getName() const
+{
+ return maStorageName;
+}
+
+OUString StorageBase::getPath() const
+{
+ OUStringBuffer aBuffer;
+ if( mpParentStorage )
+ aBuffer.append( mpParentStorage->getPath() );
+ if( aBuffer.getLength() > 0 )
+ aBuffer.append( sal_Unicode( '/' ) );
+ aBuffer.append( maStorageName );
+ return aBuffer.makeStringAndClear();
+}
+
+void StorageBase::getElementNames( ::std::vector< OUString >& orElementNames ) const
+{
+ orElementNames.clear();
+ implGetElementNames( orElementNames );
+}
+
+StorageRef StorageBase::openSubStorage( const OUString& rStorageName, bool bCreate )
+{
+ StorageRef xSubStorage;
+ OUString aElement, aRemainder;
+ lclSplitFirstElement( aElement, aRemainder, rStorageName );
+ if( aElement.getLength() > 0 )
+ xSubStorage = getSubStorage( aElement, bCreate );
+ if( xSubStorage.get() && (aRemainder.getLength() > 0) )
+ xSubStorage = xSubStorage->openSubStorage( aRemainder, bCreate );
+ return xSubStorage;
+}
+
+Reference< XInputStream > StorageBase::openInputStream( const OUString& rStreamName )
+{
+ Reference< XInputStream > xInStream;
+ OUString aElement, aRemainder;
+ lclSplitFirstElement( aElement, aRemainder, rStreamName );
+ if( aElement.getLength() > 0 )
+ {
+ if( aRemainder.getLength() > 0 )
+ {
+ StorageRef xSubStorage = getSubStorage( aElement, false );
+ if( xSubStorage.get() )
+ xInStream = xSubStorage->openInputStream( aRemainder );
+ }
+ else
+ {
+ xInStream = implOpenInputStream( aElement );
+ }
+ }
+ else if( mbBaseStreamAccess )
+ {
+ xInStream = mxInStream;
+ }
+ return xInStream;
+}
+
+Reference< XOutputStream > StorageBase::openOutputStream( const OUString& rStreamName )
+{
+ Reference< XOutputStream > xOutStream;
+ OUString aElement, aRemainder;
+ lclSplitFirstElement( aElement, aRemainder, rStreamName );
+ if( aElement.getLength() > 0 )
+ {
+ if( aRemainder.getLength() > 0 )
+ {
+ StorageRef xSubStorage = getSubStorage( aElement, true );
+ if( xSubStorage.get() )
+ xOutStream = xSubStorage->openOutputStream( aRemainder );
+ }
+ else
+ {
+ xOutStream = implOpenOutputStream( aElement );
+ }
+ }
+ else if( mbBaseStreamAccess )
+ {
+ xOutStream = mxOutStream;
+ }
+ return xOutStream;
+}
+
+StorageRef StorageBase::getSubStorage( const OUString& rElementName, bool bCreate )
+{
+ SubStorageMap::iterator aIt = maSubStorages.find( rElementName );
+ return (aIt == maSubStorages.end()) ?
+ (maSubStorages[ rElementName ] = implOpenSubStorage( rElementName, bCreate )) : aIt->second;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/zipstorage.cxx b/oox/source/helper/zipstorage.cxx
new file mode 100644
index 000000000000..f9a11da3196b
--- /dev/null
+++ b/oox/source/helper/zipstorage.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: zipstorage.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/helper/zipstorage.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <comphelper/storagehelper.hxx>
+#include "oox/helper/helper.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::embed::XStorage;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+
+namespace oox {
+
+// ============================================================================
+
+ZipStorage::ZipStorage(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XInputStream >& rxInStream ) :
+ StorageBase( rxInStream, false )
+{
+ OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" );
+ // create base storage object
+ try
+ {
+ mxStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream( rxInStream, rxFactory );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "ZipStorage::ZipStorage - cannot open input storage" );
+ }
+}
+
+ZipStorage::ZipStorage(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XOutputStream >& rxOutStream ) :
+ StorageBase( rxOutStream, false )
+{
+ OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" );
+ (void)rxFactory; // prevent compiler warning
+ OSL_ENSURE( false, "ZipStorage::ZipStorage - not implemented" );
+}
+
+ZipStorage::ZipStorage( const ZipStorage& rParentStorage, const Reference< XStorage >& rxStorage, const OUString& rElementName ) :
+ StorageBase( rParentStorage, rElementName ),
+ mxStorage( rxStorage )
+{
+ OSL_ENSURE( mxStorage.is(), "ZipStorage::ZipStorage - missing storage" );
+}
+
+ZipStorage::~ZipStorage()
+{
+}
+
+bool ZipStorage::implIsStorage() const
+{
+ return mxStorage.is();
+}
+
+Reference< XStorage > ZipStorage::implGetXStorage() const
+{
+ return mxStorage;
+}
+
+void ZipStorage::implGetElementNames( ::std::vector< OUString >& orElementNames ) const
+{
+ Sequence< OUString > aNames;
+ if( mxStorage.is() ) try
+ {
+ aNames = mxStorage->getElementNames();
+ if( aNames.getLength() > 0 )
+ orElementNames.insert( orElementNames.end(), aNames.getConstArray(), aNames.getConstArray() + aNames.getLength() );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+StorageRef ZipStorage::implOpenSubStorage( const OUString& rElementName, bool bCreate )
+{
+ OSL_ENSURE( !bCreate, "ZipStorage::implOpenSubStorage - creating new sub storages not implemented" );
+ (void)bCreate; // prevent compiler warning
+
+ Reference< XStorage > xSubXStorage;
+ try
+ {
+ // XStorage::isStorageElement may throw various exceptions...
+ if( mxStorage->isStorageElement( rElementName ) )
+ xSubXStorage = mxStorage->openStorageElement(
+ rElementName, ::com::sun::star::embed::ElementModes::READ );
+ }
+ catch( Exception& )
+ {
+ }
+
+ StorageRef xSubStorage;
+ if( xSubXStorage.is() )
+ xSubStorage.reset( new ZipStorage( *this, xSubXStorage, rElementName ) );
+ return xSubStorage;
+}
+
+Reference< XInputStream > ZipStorage::implOpenInputStream( const OUString& rElementName )
+{
+ Reference< XInputStream > xInStream;
+ if( mxStorage.is() ) try
+ {
+ xInStream.set( mxStorage->openStreamElement( rElementName, ::com::sun::star::embed::ElementModes::READ ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xInStream;
+}
+
+Reference< XOutputStream > ZipStorage::implOpenOutputStream( const OUString& rElementName )
+{
+ Reference< XOutputStream > xOutStream;
+ if( mxStorage.is() ) try
+ {
+ (void)rElementName;
+ OSL_ENSURE( false, "ZipStorage::implOpenOutputStream - not implemented" );
+ }
+ catch( Exception& )
+ {
+ }
+ return xOutStream;
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/ppt/animationspersist.cxx b/oox/source/ppt/animationspersist.cxx
new file mode 100644
index 000000000000..3094d7eee513
--- /dev/null
+++ b/oox/source/ppt/animationspersist.cxx
@@ -0,0 +1,210 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: animationspersist.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:05:59 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#include "oox/ppt/animationspersist.hxx"
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/presentation/ParagraphTarget.hpp>
+#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
+
+#include "oox/drawingml/shape.hxx"
+
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::text;
+
+namespace oox { namespace ppt {
+
+ void ShapeTargetElement::convert( ::com::sun::star::uno::Any & rTarget, sal_Int16 & rSubType ) const
+ {
+ switch(mnType)
+ {
+ case XML_subSp:
+ rSubType = ShapeAnimationSubType::AS_WHOLE;
+ break;
+ case XML_bg:
+ rSubType = ShapeAnimationSubType::ONLY_BACKGROUND;
+ break;
+ case XML_txEl:
+ {
+ ParagraphTarget aParaTarget;
+ Reference< XShape > xShape;
+ rTarget >>= xShape;
+ aParaTarget.Shape = xShape;
+ rSubType = ShapeAnimationSubType::ONLY_TEXT;
+
+ Reference< XText > xText( xShape, UNO_QUERY );
+ if( xText.is() )
+ {
+ switch(mnRangeType)
+ {
+ case XML_charRg:
+ // TODO calculate the corresponding paragraph for the text range....
+ OSL_TRACE( "OOX: TODO calculate the corresponding paragraph for the text range..." );
+ break;
+ case XML_pRg:
+ aParaTarget.Paragraph = static_cast< sal_Int16 >( maRange.start );
+ // TODO what to do with more than one.
+ OSL_TRACE( "OOX: TODO what to do with more than one" );
+ break;
+ }
+ rTarget = makeAny( aParaTarget );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+
+ Any AnimTargetElement::convert(const SlidePersistPtr & pSlide, sal_Int16 & nSubType) const
+ {
+ Any aTarget;
+ // see sd/source/files/ppt/pptinanimations.cxx:3191 (in importTargetElementContainer())
+ switch(mnType)
+ {
+ case XML_inkTgt:
+ // TODO
+ OSL_TRACE( "OOX: TODO inkTgt" );
+ break;
+ case XML_sldTgt:
+ // TODO
+ OSL_TRACE( "OOX: TODO sldTgt" );
+ break;
+ case XML_sndTgt:
+ aTarget = makeAny(msValue);
+ break;
+ case XML_spTgt:
+ {
+ Any rTarget;
+ ::oox::drawingml::ShapePtr pShape = pSlide->getShape(msValue);
+ OSL_ENSURE( pShape, "failed to locate Shape");
+ if( pShape )
+ {
+ Reference< XShape > xShape( pShape->getXShape() );
+ OSL_ENSURE( xShape.is(), "fail to get XShape from shape" );
+ if( xShape.is() )
+ {
+ rTarget <<= xShape;
+ maShapeTarget.convert(rTarget, nSubType);
+ aTarget = rTarget;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return aTarget;
+ }
+
+
+// BEGIN CUT&PASTE from sd/source/filter/ppt/pptinanimations.cxx
+/** this adds an any to another any.
+ if rNewValue is empty, rOldValue is returned.
+ if rOldValue is empty, rNewValue is returned.
+ if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned.
+ if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned.
+*/
+ static Any addToSequence( const Any& rOldValue, const Any& rNewValue )
+ {
+ if( !rNewValue.hasValue() )
+ {
+ return rOldValue;
+ }
+ else if( !rOldValue.hasValue() )
+ {
+ return rNewValue;
+ }
+ else
+ {
+ Sequence< Any > aNewSeq;
+ if( rOldValue >>= aNewSeq )
+ {
+ sal_Int32 nSize = aNewSeq.getLength();
+ aNewSeq.realloc(nSize+1);
+ aNewSeq[nSize] = rNewValue;
+ }
+ else
+ {
+ aNewSeq.realloc(2);
+ aNewSeq[0] = rOldValue;
+ aNewSeq[1] = rNewValue;
+ }
+ return makeAny( aNewSeq );
+ }
+ }
+// END
+
+ Any AnimationCondition::convert(const SlidePersistPtr & pSlide) const
+ {
+ Any aAny;
+ if( mpTarget )
+ {
+ sal_Int16 nSubType;
+ aAny = mpTarget->convert( pSlide, nSubType );
+ }
+ else
+ {
+ aAny = maValue;
+ }
+ return aAny;
+ }
+
+
+ Any AnimationCondition::convertList(const SlidePersistPtr & pSlide, const AnimationConditionList & l)
+ {
+ Any aAny;
+ for( AnimationConditionList::const_iterator iter = l.begin();
+ iter != l.end(); iter++)
+ {
+ aAny = addToSequence( aAny, iter->convert(pSlide) );
+ }
+ return aAny;
+ }
+
+} }
+
+
diff --git a/oox/source/ppt/animationtypes.cxx b/oox/source/ppt/animationtypes.cxx
new file mode 100644
index 000000000000..4f81d118ff81
--- /dev/null
+++ b/oox/source/ppt/animationtypes.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: animationtypes.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#include "animationtypes.hxx"
+
+#include <com/sun/star/animations/Timing.hpp>
+
+#include "oox/helper/attributelist.hxx"
+
+#include "tokens.hxx"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+// ST_TLTime
+Any GetTime( const ::rtl::OUString & val )
+{
+ Any aDuration;
+ if( val.compareToAscii( "indefinite" ) == 0 )
+ {
+ aDuration <<= Timing_INDEFINITE;
+ }
+ else
+ {
+ aDuration <<= val.toFloat() / 1000.0;
+ }
+ return aDuration;
+}
+
+
+// ST_TLTimeAnimateValueTime
+Any GetTimeAnimateValueTime( const ::rtl::OUString & val )
+{
+ Any aPercent;
+ if( val.compareToAscii( "indefinite" ) == 0 )
+ {
+ aPercent <<= Timing_INDEFINITE;
+ }
+ else
+ {
+ aPercent <<= val.toFloat() / 100000.0;
+ }
+ return aPercent;
+}
+
+} }
diff --git a/oox/source/ppt/animationtypes.hxx b/oox/source/ppt/animationtypes.hxx
new file mode 100644
index 000000000000..a242fcde7c70
--- /dev/null
+++ b/oox/source/ppt/animationtypes.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: animationtypes.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_POWERPOINT_ANIMATIONTYPES_HXX
+#define OOX_POWERPOINT_ANIMATIONTYPES_HXX
+
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+
+
+namespace oox { namespace ppt {
+
+// ST_TLTime
+::com::sun::star::uno::Any GetTime( const ::rtl::OUString & val );
+// ST_TLTimeAnimateValueTime
+::com::sun::star::uno::Any GetTimeAnimateValueTime( const ::rtl::OUString & val );
+
+} }
+
+#endif
diff --git a/oox/source/ppt/animvariantcontext.cxx b/oox/source/ppt/animvariantcontext.cxx
new file mode 100644
index 000000000000..85fc20f55b75
--- /dev/null
+++ b/oox/source/ppt/animvariantcontext.cxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: animvariantcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "animvariantcontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include <osl/diagnose.h>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <rtl/ustring.hxx>
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "pptfilterhelpers.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+ AnimVariantContext::AnimVariantContext( const FragmentHandlerRef & xHandler, sal_Int32 aElement,
+ Any & aValue )
+ : Context( xHandler )
+ , mnElement( aElement )
+ , maValue( aValue )
+ {
+ }
+
+ AnimVariantContext::~AnimVariantContext( ) throw( )
+ {
+ }
+
+ void SAL_CALL AnimVariantContext::endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ if( ( aElement == mnElement ) && maColor.isUsed() )
+ {
+ maValue = makeAny( maColor.getColor( *getHandler()->getFilter().get() ) );
+ }
+ }
+
+
+ Reference< XFastContextHandler >
+ SAL_CALL AnimVariantContext::createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+ AttributeList attribs(xAttribs);
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_boolVal:
+ {
+ bool val = attribs.getBool( XML_val, false );
+ maValue = makeAny( val );
+ break;
+ }
+ case NMSP_PPT|XML_clrVal:
+ xRet.set( new ::oox::drawingml::colorChoiceContext( getHandler(), maColor ) );
+ // we'll defer setting the Any until the end.
+ break;
+ case NMSP_PPT|XML_fltVal:
+ {
+ double val = attribs.getDouble( XML_val, 0.0 );
+ maValue = makeAny( val );
+ break;
+ }
+ case NMSP_PPT|XML_intVal:
+ {
+ sal_Int32 val = attribs.getInteger( XML_val, 0 );
+ maValue = makeAny( val );
+ break;
+ }
+ case NMSP_PPT|XML_strVal:
+ {
+ OUString val = attribs.getString( XML_val );
+ convertMeasure( val ); // ignore success or failure if it fails, use as is
+ maValue = makeAny( val );
+ break;
+ }
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+
+
+} }
diff --git a/oox/source/ppt/animvariantcontext.hxx b/oox/source/ppt/animvariantcontext.hxx
new file mode 100644
index 000000000000..8b88e33944d9
--- /dev/null
+++ b/oox/source/ppt/animvariantcontext.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: animvariantcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_ANIMVARIANTCONTEXT
+#define OOX_PPT_ANIMVERIANTCONTEXT
+
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include "oox/core/context.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/drawingml/color.hxx"
+
+namespace oox { namespace ppt {
+
+ /** context CT_TLAnimVariant */
+ class AnimVariantContext
+ : public ::oox::core::Context
+ {
+ public:
+ AnimVariantContext( const ::oox::core::FragmentHandlerRef & xHandler, ::sal_Int32 aElement, ::com::sun::star::uno::Any & aValue );
+ ~AnimVariantContext( ) throw( );
+ virtual void SAL_CALL endFastElement( sal_Int32 /*aElement*/ ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ private:
+ ::sal_Int32 mnElement;
+ ::com::sun::star::uno::Any& maValue;
+ ::oox::drawingml::Color maColor;
+ };
+
+} }
+
+
+#endif
diff --git a/oox/source/ppt/backgroundproperties.cxx b/oox/source/ppt/backgroundproperties.cxx
new file mode 100644
index 000000000000..e039a17ccb41
--- /dev/null
+++ b/oox/source/ppt/backgroundproperties.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backgroundproperties.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/backgroundproperties.hxx"
+
+#include <comphelper/propertysethelper.hxx>
+
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::beans::XPropertySet;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+// ---------------------------------------------------------------------
+
+BackgroundPropertiesContext::BackgroundPropertiesContext( const FragmentHandlerRef& xHandler, FillPropertiesPtr pFillPropertiesPtr ) throw()
+: Context( xHandler )
+, mpFillPropertiesPtr( pFillPropertiesPtr )
+{
+}
+
+Reference< XFastContextHandler > BackgroundPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_fill: // a:CT_FillEffect
+ break;
+ }
+
+ // FillPropertiesGroupContext
+ if( !xRet.is() )
+ xRet = FillPropertiesGroupContext::StaticCreateContext( getHandler(), aElementToken, xAttribs, *(mpFillPropertiesPtr.get()) );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/ppt/buildlistcontext.cxx b/oox/source/ppt/buildlistcontext.cxx
new file mode 100644
index 000000000000..dcff9e1b1b30
--- /dev/null
+++ b/oox/source/ppt/buildlistcontext.cxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: buildlistcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "buildlistcontext.hxx"
+#include <rtl/ustring.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace ppt {
+
+ BuildListContext::BuildListContext( const FragmentHandlerRef& xHandler,
+ const Reference< XFastAttributeList >& /*xAttribs*/,
+ TimeNodePtrList & aTimeNodeList)
+ : Context( xHandler )
+ , maTimeNodeList( aTimeNodeList )
+ , mbInBldGraphic( false )
+ , mbBuildAsOne( false )
+ {
+ }
+
+ BuildListContext::~BuildListContext( )
+ {
+ }
+
+ void SAL_CALL BuildListContext::endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException)
+ {
+ switch( aElement )
+ {
+ case NMSP_PPT|XML_bldGraphic:
+ mbInBldGraphic = false;
+ break;
+ default:
+ break;
+ }
+ }
+
+ Reference< XFastContextHandler > SAL_CALL BuildListContext::createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_bldAsOne:
+ if( mbInBldGraphic )
+ {
+ mbBuildAsOne = true;
+ }
+ break;
+ case NMSP_PPT|XML_bldSub:
+ if( mbInBldGraphic )
+ {
+ }
+ break;
+ case NMSP_PPT|XML_bldGraphic:
+ {
+ mbInBldGraphic = true;
+ AttributeList attribs( xAttribs );
+ OUString sShapeId = xAttribs->getOptionalValue( XML_spid );
+// TODO
+// bool uiExpand = attribs.getBool( XML_uiExpand, true );
+ /* this is unsigned */
+// sal_uInt32 nGroupId = attribs.getUnsignedInteger( XML_grpId, 0 );
+ break;
+ }
+ case NMSP_DRAWINGML|XML_bldDgm:
+ case NMSP_DRAWINGML|XML_bldOleChart:
+ case NMSP_DRAWINGML|XML_bldP:
+
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+ }
+
+
+} }
diff --git a/oox/source/ppt/buildlistcontext.hxx b/oox/source/ppt/buildlistcontext.hxx
new file mode 100644
index 000000000000..82d10b0ae91a
--- /dev/null
+++ b/oox/source/ppt/buildlistcontext.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: buildlistcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_BUILDLISTCONTEXT
+#define OOX_PPT_BUILDLISTCONTEXT
+
+#include "oox/ppt/timenode.hxx"
+#include "oox/core/context.hxx"
+
+namespace oox { namespace ppt {
+
+
+ /** CT_BuildList */
+ class BuildListContext
+ : public ::oox::core::Context
+ {
+ public:
+ BuildListContext( const ::oox::core::FragmentHandlerRef& xHandler,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ TimeNodePtrList & aTimeNodeList);
+
+ ~BuildListContext( );
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& /*xAttribs*/ ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+ private:
+ TimeNodePtrList & maTimeNodeList;
+ bool mbInBldGraphic;
+ bool mbBuildAsOne;
+ };
+
+
+
+
+} }
+
+#endif
diff --git a/oox/source/ppt/commonbehaviorcontext.cxx b/oox/source/ppt/commonbehaviorcontext.cxx
new file mode 100644
index 000000000000..0d4f570df348
--- /dev/null
+++ b/oox/source/ppt/commonbehaviorcontext.cxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: commonbehaviorcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <com/sun/star/animations/XTimeContainer.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <com/sun/star/animations/XAnimate.hpp>
+
+#include "oox/core/namespaces.hxx"
+#include "oox/core/fragmenthandler.hxx"
+
+#include "commonbehaviorcontext.hxx"
+#include "commontimenodecontext.hxx"
+#include "timetargetelementcontext.hxx"
+#include "pptfilterhelpers.hxx"
+#include "tokens.hxx"
+
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::animations;
+
+namespace oox { namespace ppt {
+
+ CommonBehaviorContext::CommonBehaviorContext( const FragmentHandlerRef& xHandler,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( xHandler, NMSP_PPT|XML_cBhvr, xAttribs, pNode )
+ , mbInAttrList( false )
+ , mbIsInAttrName( false )
+ {
+ }
+
+
+ CommonBehaviorContext::~CommonBehaviorContext( ) throw( )
+ {
+ }
+
+
+
+ void SAL_CALL CommonBehaviorContext::endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ switch( aElement )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ {
+ if( !maAttributes.empty() )
+ {
+ OUStringBuffer sAttributes;
+ std::list< Attribute >::const_iterator iter;
+ for(iter = maAttributes.begin(); iter != maAttributes.end(); iter++)
+ {
+ if( sAttributes.getLength() )
+ {
+ sAttributes.appendAscii( ";" );
+ }
+ sAttributes.append( iter->name );
+ }
+ OUString sTmp( sAttributes.makeStringAndClear() );
+ mpNode->getNodeProperties()[ NP_ATTRIBUTENAME ] = makeAny( sTmp );
+ }
+ break;
+ }
+ case NMSP_PPT|XML_attrNameLst:
+ mbInAttrList = false;
+ break;
+ case NMSP_PPT|XML_attrName:
+ if( mbIsInAttrName )
+ {
+ const ImplAttributeNameConversion *attrConv = gImplConversionList;
+ while( attrConv->mpMSName != NULL )
+ {
+ if(msCurrentAttribute.compareToAscii( attrConv->mpMSName ) == 0 )
+ {
+ Attribute attr;
+ attr.name = ::rtl::OUString::intern( attrConv->mpAPIName,
+ strlen(attrConv->mpAPIName),
+ RTL_TEXTENCODING_ASCII_US );
+ attr.type = attrConv->meAttribute;
+ maAttributes.push_back( attr );
+ OSL_TRACE( "OOX: attrName is %s -> %s",
+ OUSTRING_TO_CSTR( msCurrentAttribute ),
+ attrConv->mpAPIName );
+ break;
+ }
+ attrConv++;
+ }
+ mbIsInAttrName = false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ void CommonBehaviorContext::characters( const OUString& aChars )
+ throw( SAXException, RuntimeException )
+ {
+ if( mbIsInAttrName )
+ {
+ msCurrentAttribute += aChars;
+ }
+ }
+
+
+ Reference< XFastContextHandler > SAL_CALL CommonBehaviorContext::createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cTn:
+ xRet.set( new CommonTimeNodeContext( getHandler(), aElementToken, xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_tgtEl:
+ xRet.set( new TimeTargetElementContext( getHandler(), mpNode->getTarget() ) );
+ break;
+ case NMSP_PPT|XML_attrNameLst:
+ mbInAttrList = true;
+ break;
+ case NMSP_PPT|XML_attrName:
+ {
+ if( mbInAttrList )
+ {
+ mbIsInAttrName = true;
+ msCurrentAttribute = OUString();
+ }
+ else
+ {
+ OSL_TRACE( "OOX: Attribute Name outside an Attribute List" );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+} }
diff --git a/oox/source/ppt/commonbehaviorcontext.hxx b/oox/source/ppt/commonbehaviorcontext.hxx
new file mode 100644
index 000000000000..375495e19e3c
--- /dev/null
+++ b/oox/source/ppt/commonbehaviorcontext.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: commonbehaviorcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_PPT_COMMONBEHAVIORCONTEXT
+#define OOX_PPT_COMMONBEHAVIORCONTEXT
+
+#include <rtl/ustring.hxx>
+#include "oox/ppt/timenodelistcontext.hxx"
+#include "oox/ppt/animationspersist.hxx"
+#include "conditioncontext.hxx"
+#include "pptfilterhelpers.hxx"
+
+namespace oox { namespace ppt {
+
+ struct Attribute
+ {
+ ::rtl::OUString name;
+ MS_AttributeNames type;
+ };
+
+
+ /** CT_TLCommonBehaviorData */
+ class CommonBehaviorContext
+ : public TimeNodeContext
+ {
+ public:
+ CommonBehaviorContext( const ::oox::core::FragmentHandlerRef& xHandler,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode );
+ ~CommonBehaviorContext( )
+ throw( );
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement )
+ throw ( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars )
+ throw ( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& /*xAttribs*/ )
+ throw ( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ private:
+ bool mbInAttrList;
+ bool mbIsInAttrName;
+ std::list< Attribute > maAttributes;
+ ::rtl::OUString msCurrentAttribute;
+ };
+
+
+} }
+
+
+#endif
diff --git a/oox/source/ppt/commontimenodecontext.cxx b/oox/source/ppt/commontimenodecontext.cxx
new file mode 100644
index 000000000000..232d59cb8d81
--- /dev/null
+++ b/oox/source/ppt/commontimenodecontext.cxx
@@ -0,0 +1,717 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: commontimenodecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "commontimenodecontext.hxx"
+
+#include <algorithm>
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include <osl/diagnose.h>
+
+#include <com/sun/star/animations/XTimeContainer.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <com/sun/star/animations/AnimationFill.hpp>
+#include <com/sun/star/animations/AnimationRestart.hpp>
+#include <com/sun/star/presentation/TextAnimationType.hpp>
+#include <com/sun/star/presentation/EffectPresetClass.hpp>
+#include <com/sun/star/presentation/EffectNodeType.hpp>
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/ppt/pptimport.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+
+#include "animationtypes.hxx"
+#include "tokens.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::xml::sax;
+
+
+using ::rtl::OUString;
+using ::com::sun::star::beans::NamedValue;
+
+namespace oox { namespace ppt {
+
+// BEGIN CUT&PASTE from sd/source/filter/ppt/pptanimations.hxx
+struct convert_subtype
+{
+ sal_Int32 mnID;
+ const sal_Char* mpStrSubType;
+};
+static const convert_subtype gConvertArray[] =
+{
+ // fly in
+ { 1, "from-top" },
+ { 2, "from-right" },
+ { 3, "from-top-right" },
+ { 4, "from-bottom" },
+ { 5, "horizontal" },
+ { 6, "from-bottom-right" },
+ { 8, "from-left" },
+ { 9, "from-top-left" },
+ { 10, "vertical" },
+ { 12, "from-bottom-left" },
+ { 16, "in" },
+ { 21, "vertical-in" },
+ { 26, "horizontal-in" },
+ { 32, "out" },
+ { 36, "out-from-screen-center" },
+ { 37, "vertical-out" },
+ { 42, "horizontal-out" },
+ { 272, "in-slightly" },
+ { 288, "out-slightly" },
+ { 528, "in-from-screen-center" },
+ { 0, 0 }
+};
+
+
+struct preset_maping
+{
+ sal_Int32 mnPresetClass;
+ sal_Int32 mnPresetId;
+ const sal_Char* mpStrPresetId;
+};
+
+static const preset_maping gPresetMaping[] =
+{
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 1 ,"ooo-entrance-appear" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 2 ,"ooo-entrance-fly-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 3 ,"ooo-entrance-venetian-blinds" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 4 ,"ooo-entrance-box" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 5 ,"ooo-entrance-checkerboard" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 6 ,"ooo-entrance-circle" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 7 ,"ooo-entrance-fly-in-slow" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 8 ,"ooo-entrance-diamond" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 9 ,"ooo-entrance-dissolve-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 10 ,"ooo-entrance-fade-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 11 ,"ooo-entrance-flash-once" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 12 ,"ooo-entrance-peek-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 13 ,"ooo-entrance-plus" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 14 ,"ooo-entrance-random-bars" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 15 ,"ooo-entrance-spiral-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 16 ,"ooo-entrance-split" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 17 ,"ooo-entrance-stretchy" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 18 ,"ooo-entrance-diagonal-squares" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 19 ,"ooo-entrance-swivel" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 20 ,"ooo-entrance-wedge" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 21 ,"ooo-entrance-wheel" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 22 ,"ooo-entrance-wipe" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 23 ,"ooo-entrance-zoom" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 24 ,"ooo-entrance-random" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 25 ,"ooo-entrance-boomerang" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 26 ,"ooo-entrance-bounce" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 27 ,"ooo-entrance-colored-lettering" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 28 ,"ooo-entrance-movie-credits" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 29 ,"ooo-entrance-ease-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 30 ,"ooo-entrance-float" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 31 ,"ooo-entrance-turn-and-grow" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 34 ,"ooo-entrance-breaks" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 35 ,"ooo-entrance-pinwheel" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 37 ,"ooo-entrance-rise-up" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 38 ,"ooo-entrance-falling-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 39 ,"ooo-entrance-thread" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 40 ,"ooo-entrance-unfold" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 41 ,"ooo-entrance-whip" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 42 ,"ooo-entrance-ascend" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 43 ,"ooo-entrance-center-revolve" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 45 ,"ooo-entrance-fade-in-and-swivel" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 47 ,"ooo-entrance-descend" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 48 ,"ooo-entrance-sling" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 49 ,"ooo-entrance-spin-in" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 50 ,"ooo-entrance-compress" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 51 ,"ooo-entrance-magnify" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 52 ,"ooo-entrance-curve-up" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 53 ,"ooo-entrance-fade-in-and-zoom" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 54 ,"ooo-entrance-glide" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 55 ,"ooo-entrance-expand" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 56 ,"ooo-entrance-flip" },
+ { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 58 ,"ooo-entrance-fold" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 1 ,"ooo-emphasis-fill-color" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 2 ,"ooo-emphasis-font" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 3 ,"ooo-emphasis-font-color" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 4 ,"ooo-emphasis-font-size" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 5 ,"ooo-emphasis-font-style" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 6 ,"ooo-emphasis-grow-and-shrink" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 7 ,"ooo-emphasis-line-color" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 8 ,"ooo-emphasis-spin" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 9 ,"ooo-emphasis-transparency" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 10 ,"ooo-emphasis-bold-flash" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 14 ,"ooo-emphasis-blast" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 15 ,"ooo-emphasis-bold-reveal" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 16 ,"ooo-emphasis-color-over-by-word" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 18 ,"ooo-emphasis-reveal-underline" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 19 ,"ooo-emphasis-color-blend" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 20 ,"ooo-emphasis-color-over-by-letter" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 21 ,"ooo-emphasis-complementary-color" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 22 ,"ooo-emphasis-complementary-color-2" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 23 ,"ooo-emphasis-contrasting-color" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 24 ,"ooo-emphasis-darken" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 25 ,"ooo-emphasis-desaturate" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 26 ,"ooo-emphasis-flash-bulb" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 27 ,"ooo-emphasis-flicker" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 28 ,"ooo-emphasis-grow-with-color" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 30 ,"ooo-emphasis-lighten" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 31 ,"ooo-emphasis-style-emphasis" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 32 ,"ooo-emphasis-teeter" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 33 ,"ooo-emphasis-vertical-highlight" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 34 ,"ooo-emphasis-wave" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 35 ,"ooo-emphasis-blink" },
+ { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 36 ,"ooo-emphasis-shimmer" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 1 ,"ooo-exit-disappear" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 2 ,"ooo-exit-fly-out" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 3 ,"ooo-exit-venetian-blinds" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 4 ,"ooo-exit-box" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 5 ,"ooo-exit-checkerboard" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 6 ,"ooo-exit-circle" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 7 ,"ooo-exit-crawl-out" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 8 ,"ooo-exit-diamond" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 9 ,"ooo-exit-dissolve" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 10 ,"ooo-exit-fade-out" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 11 ,"ooo-exit-flash-once" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 12 ,"ooo-exit-peek-out" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 13 ,"ooo-exit-plus" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 14 ,"ooo-exit-random-bars" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 15 ,"ooo-exit-spiral-out" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 16 ,"ooo-exit-split" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 17 ,"ooo-exit-collapse" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 18 ,"ooo-exit-diagonal-squares" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 19 ,"ooo-exit-swivel" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 20 ,"ooo-exit-wedge" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 21 ,"ooo-exit-wheel" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 22 ,"ooo-exit-wipe" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 23 ,"ooo-exit-zoom" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 24 ,"ooo-exit-random" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 25 ,"ooo-exit-boomerang" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 26 ,"ooo-exit-bounce" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 27 ,"ooo-exit-colored-lettering" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 28 ,"ooo-exit-movie-credits" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 29 ,"ooo-exit-ease-out" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 30 ,"ooo-exit-float" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 31 ,"ooo-exit-turn-and-grow" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 34 ,"ooo-exit-breaks" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 35 ,"ooo-exit-pinwheel" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 37 ,"ooo-exit-sink-down" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 38 ,"ooo-exit-swish" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 39 ,"ooo-exit-thread" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 40 ,"ooo-exit-unfold" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 41 ,"ooo-exit-whip" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 42 ,"ooo-exit-descend" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 43 ,"ooo-exit-center-revolve" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 45 ,"ooo-exit-fade-out-and-swivel" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 47 ,"ooo-exit-ascend" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 48 ,"ooo-exit-sling" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 53 ,"ooo-exit-fade-out-and-zoom" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 55 ,"ooo-exit-contract" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 49 ,"ooo-exit-spin-out" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 50 ,"ooo-exit-stretchy" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 51 ,"ooo-exit-magnify" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 52 ,"ooo-exit-curve-down" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 54 ,"ooo-exit-glide" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 56 ,"ooo-exit-flip" },
+ { ::com::sun::star::presentation::EffectPresetClass::EXIT, 58 ,"ooo-exit-fold" },
+
+
+
+
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 16 ,"ooo-motionpath-4-point-star" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 5 ,"ooo-motionpath-5-point-star" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 11 ,"ooo-motionpath-6-point-star" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 17 ,"ooo-motionpath-8-point-star" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 1 ,"ooo-motionpath-circle" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 6 ,"ooo-motionpath-crescent-moon" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 3 ,"ooo-motionpath-diamond" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 13 ,"ooo-motionpath-equal-triangle" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 12 ,"ooo-motionpath-oval" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 9 ,"ooo-motionpath-heart" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 4 ,"ooo-motionpath-hexagon" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 10 ,"ooo-motionpath-octagon" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 14 ,"ooo-motionpath-parallelogram" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 15 ,"ooo-motionpath-pentagon" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 2 ,"ooo-motionpath-right-triangle" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 7 ,"ooo-motionpath-square" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 18 ,"ooo-motionpath-teardrop" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 8 ,"ooo-motionpath-trapezoid" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 37 ,"ooo-motionpath-arc-down" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 51 ,"ooo-motionpath-arc-left" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 58 ,"ooo-motionpath-arc-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 44 ,"ooo-motionpath-arc-up" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 41 ,"ooo-motionpath-bounce-left" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 54 ,"ooo-motionpath-bounce-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 48 ,"ooo-motionpath-curvy-left" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 61 ,"ooo-motionpath-curvy-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 60 ,"ooo-motionpath-decaying-wave" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 49 ,"ooo-motionpath-diagonal-down-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 56 ,"ooo-motionpath-diagonal-up-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 42 ,"ooo-motionpath-down" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 52 ,"ooo-motionpath-funnel" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 53 ,"ooo-motionpath-spring" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 62 ,"ooo-motionpath-stairs-down" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 50 ,"ooo-motionpath-turn-down" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 36 ,"ooo-motionpath-turn-down-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 43 ,"ooo-motionpath-turn-up" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 57 ,"ooo-motionpath-turn-up-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 64 ,"ooo-motionpath-up" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 47 ,"ooo-motionpath-wave" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 38 ,"ooo-motionpath-zigzag" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 31 ,"ooo-motionpath-bean" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 25 ,"ooo-motionpath-buzz-saw" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 20 ,"ooo-motionpath-curved-square" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 21 ,"ooo-motionpath-curved-x" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 23 ,"ooo-motionpath-curvy-star" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 28 ,"ooo-motionpath-figure-8-four" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 26 ,"ooo-motionpath-horizontal-figure-8" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 34 ,"ooo-motionpath-inverted-square" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 33 ,"ooo-motionpath-inverted-triangle" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 24 ,"ooo-motionpath-loop-de-loop" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 29 ,"ooo-motionpath-neutron" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 27 ,"ooo-motionpath-peanut" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 32 ,"ooo-motionpath-clover" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 19 ,"ooo-motionpath-pointy-star" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 30 ,"ooo-motionpath-swoosh" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 22 ,"ooo-motionpath-vertical-figure-8" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 35 ,"ooo-motionpath-left" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 63 ,"ooo-motionpath-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 55 ,"ooo-motionpath-spiral-left" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 46 ,"ooo-motionpath-spiral-right" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 40 ,"ooo-motionpath-sine-wave" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 59 ,"ooo-motionpath-s-curve-1" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 39 ,"ooo-motionpath-s-curve-2" },
+ { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 45 ,"ooo-motionpath-heartbeat" },
+
+
+ { 0,0,0 }
+};
+
+// from sd/source/filter/ppt/pptinanimations.cxx
+static OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType )
+{
+ const sal_Char* pStr = 0;
+
+ if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) )
+ {
+ // skip wheel effect
+ if( nPresetId != 21 )
+ {
+ if( nPresetId == 5 )
+ {
+ // checkerboard
+ switch( nPresetSubType )
+ {
+ case 5: pStr = "downward"; break;
+ case 10: pStr = "across"; break;
+ }
+ }
+ else if( nPresetId == 17 )
+ {
+ // stretch
+ if( nPresetSubType == 10 )
+ pStr = "across";
+ }
+ else if( nPresetId == 18 )
+ {
+ // strips
+ switch( nPresetSubType )
+ {
+ case 3: pStr = "right-to-top"; break;
+ case 6: pStr = "right-to-bottom"; break;
+ case 9: pStr = "left-to-top"; break;
+ case 12: pStr = "left-to-bottom"; break;
+ }
+ }
+
+ if( pStr == 0 )
+ {
+ const convert_subtype* p = gConvertArray;
+
+ while( p->mpStrSubType )
+ {
+ if( p->mnID == nPresetSubType )
+ {
+ pStr = p->mpStrSubType;
+ break;
+ }
+ p++;
+ }
+ }
+ }
+ }
+
+ if( pStr )
+ return OUString::createFromAscii( pStr );
+ else
+ return OUString::valueOf( nPresetSubType );
+}
+
+// END
+
+ CommonTimeNodeContext::CommonTimeNodeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ , mbIterate( false )
+ {
+ AttributeList attribs( xAttribs );
+ sal_Int32 nInt; // some temporary int value for float conversions
+
+ NodePropertyMap & aProps = pNode->getNodeProperties();
+ PropertyMap & aUserData = pNode->getUserData();
+
+ if( attribs.hasAttribute( XML_accel ) )
+ {
+ double dPercent = ::oox::drawingml::GetPositiveFixedPercentage( xAttribs->getOptionalValue( XML_accel ) );
+ aProps[ NP_ACCELERATION ] <<= dPercent;
+ }
+
+ if( attribs.hasAttribute( XML_afterEffect ) )
+ {
+ aUserData[ CREATE_OUSTRING( "after-effect" ) ]
+ = makeAny( attribs.getBool( XML_afterEffect, false ) );
+ }
+ aProps[ NP_AUTOREVERSE ] = makeAny( attribs.getBool( XML_autoRev, false ) );
+
+ // TODO
+ if( attribs.hasAttribute( XML_bldLvl ) )
+ {
+ attribs.getInteger( XML_bldLvl, 0 );
+ }
+ if( attribs.hasAttribute( XML_decel ) )
+ {
+ double dPercent = ::oox::drawingml::GetPositiveFixedPercentage( xAttribs->getOptionalValue( XML_decel ) );
+ aProps[ NP_DECELERATE ] <<= dPercent;
+ }
+ // TODO
+ if( attribs.hasAttribute( XML_display ) )
+ {
+ aProps[ NP_DISPLAY ] <<= attribs.getBool( XML_display, true );
+ }
+ if( attribs.hasAttribute( XML_dur ) )
+ {
+ aProps[ NP_DURATION ] = GetTime( xAttribs->getOptionalValue( XML_dur) );
+ }
+ // TODO
+ if( attribs.hasAttribute( XML_evtFilter ) )
+ {
+ xAttribs->getOptionalValue( XML_evtFilter );
+ }
+ // ST_TLTimeNodeFillType
+ if( attribs.hasAttribute( XML_fill ) )
+ {
+ nInt = xAttribs->getOptionalValueToken( XML_fill, 0 );
+ if( nInt != 0 )
+ {
+ sal_Int16 nEnum;
+ switch( nInt )
+ {
+ case XML_remove:
+ nEnum = AnimationFill::REMOVE;
+ break;
+ case XML_freeze:
+ nEnum = AnimationFill::FREEZE;
+ break;
+ case XML_hold:
+ nEnum = AnimationFill::HOLD;
+ break;
+ case XML_transition:
+ nEnum = AnimationFill::TRANSITION;
+ break;
+ default:
+ nEnum = AnimationFill::DEFAULT;
+ break;
+ }
+ aProps[ NP_FILL ] <<= (sal_Int16)nEnum;
+ }
+ }
+ if( attribs.hasAttribute( XML_grpId ) )
+ {
+ attribs.getUnsignedInteger( XML_grpId, 0 );
+ }
+ // ST_TLTimeNodeID
+ if( attribs.hasAttribute( XML_id ) )
+ {
+ sal_uInt32 nId = attribs.getUnsignedInteger( XML_id, 0 );
+ pNode->setId( nId );
+ }
+ // ST_TLTimeNodeMasterRelation
+ nInt = xAttribs->getOptionalValueToken( XML_masterRel, 0 );
+ if( nInt )
+ {
+ // TODO
+ switch(nInt)
+ {
+ case XML_sameClick:
+ case XML_lastClick:
+ case XML_nextClick:
+ break;
+ }
+ }
+
+ // TODO
+ if( attribs.hasAttribute( XML_nodePh ) )
+ {
+ attribs.getBool( XML_nodePh, false );
+ }
+ // ST_TLTimeNodeType
+ nInt = xAttribs->getOptionalValueToken( XML_nodeType, 0 );
+ if( nInt != 0 )
+ {
+ sal_Int16 nEnum;
+ switch( nInt )
+ {
+ case XML_clickEffect:
+ case XML_clickPar:
+ nEnum = EffectNodeType::ON_CLICK;
+ break;
+ case XML_withEffect:
+ case XML_withGroup:
+ nEnum = EffectNodeType::WITH_PREVIOUS;
+ break;
+ case XML_mainSeq:
+ nEnum = EffectNodeType::MAIN_SEQUENCE;
+ break;
+ case XML_interactiveSeq:
+ nEnum = EffectNodeType::INTERACTIVE_SEQUENCE;
+ break;
+ case XML_afterGroup:
+ case XML_afterEffect:
+ nEnum = EffectNodeType::AFTER_PREVIOUS;
+ break;
+ case XML_tmRoot:
+ nEnum = EffectNodeType::TIMING_ROOT;
+ break;
+ default:
+ nEnum = EffectNodeType::DEFAULT;
+ break;
+ }
+ aUserData[ CREATE_OUSTRING( "node-type" ) ] <<= nEnum;
+ }
+
+ // ST_TLTimeNodePresetClassType
+ nInt = xAttribs->getOptionalValueToken( XML_presetClass, 0 );
+ sal_Int16 nEffectPresetClass = 0;
+ sal_Int32 nPresetId = 0;
+ sal_Int32 nPresetSubType = 0;
+ if( nInt != 0 )
+ {
+ // TODO put that in a function
+ switch( nInt )
+ {
+ case XML_entr:
+ nEffectPresetClass = EffectPresetClass::ENTRANCE;
+ break;
+ case XML_exit:
+ nEffectPresetClass = EffectPresetClass::EXIT;
+ break;
+ case XML_emph:
+ nEffectPresetClass = EffectPresetClass::EMPHASIS;
+ break;
+ case XML_path:
+ nEffectPresetClass = EffectPresetClass::MOTIONPATH;
+ break;
+ case XML_verb:
+ // TODO check that the value below is correct
+ nEffectPresetClass = EffectPresetClass::OLEACTION;
+ break;
+ case XML_mediacall:
+ nEffectPresetClass = EffectPresetClass::MEDIACALL;
+ break;
+ default:
+ nEffectPresetClass = 0;
+ break;
+ }
+ aUserData[ CREATE_OUSTRING( "preset-class" ) ] = makeAny( nEffectPresetClass );
+ if( attribs.hasAttribute( XML_presetID ) )
+ {
+ nPresetId = attribs.getInteger( XML_presetID, 0 );
+ const preset_maping* p = gPresetMaping;
+ while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) )
+ p++;
+
+ aUserData[ CREATE_OUSTRING( "preset-id" ) ]
+ = makeAny( OUString::createFromAscii( p->mpStrPresetId ) );
+ nPresetSubType = attribs.getInteger( XML_presetSubtype, 0 );
+ if( nPresetSubType )
+ {
+ aUserData[ CREATE_OUSTRING( "preset-sub-type" ) ]
+ = makeAny( getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType ) );
+ }
+ }
+ }
+ if( attribs.hasAttribute( XML_repeatCount ) )
+ {
+ aProps[ NP_REPEATCOUNT ] = GetTime( xAttribs->getOptionalValue( XML_repeatCount ) );
+ }
+ /* see pptinanimation */
+// aProps[ NP_REPEATCOUNT ] <<= (fCount < ((float)3.40282346638528860e+38)) ? makeAny( (double)fCount ) : makeAny( Timing_INDEFINITE );
+ if( attribs.hasAttribute( XML_repeatDur ) )
+ {
+ aProps[ NP_REPEATDURATION ] = GetTime( xAttribs->getOptionalValue( XML_repeatDur ) );
+ }
+ // TODO repeatDur is otherwise the same as dur. What shall we do? -- Hub
+
+ // ST_TLTimeNodeRestartType
+ nInt = xAttribs->getOptionalValueToken( XML_restart, 0 );
+ if( nInt != 0 )
+ {
+ // TODO put that in a function
+ sal_Int16 nEnum;
+ switch( nInt )
+ {
+ case XML_always:
+ nEnum = AnimationRestart::ALWAYS;
+ break;
+ case XML_whenNotActive:
+ nEnum = AnimationRestart::WHEN_NOT_ACTIVE;
+ break;
+ case XML_never:
+ nEnum = AnimationRestart::NEVER;
+ break;
+ default:
+ nEnum = AnimationRestart::DEFAULT;
+ break;
+ }
+ aProps[ NP_RESTART ] <<= (sal_Int16)nEnum;
+ }
+ // ST_Percentage TODO
+ xAttribs->getOptionalValue( XML_spd /*"10000" */ );
+ // ST_TLTimeNodeSyncType TODO
+ xAttribs->getOptionalValue( XML_syncBehavior );
+ // TODO (string)
+ xAttribs->getOptionalValue( XML_tmFilter );
+ }
+
+
+ CommonTimeNodeContext::~CommonTimeNodeContext( ) throw ( )
+ {
+ }
+
+
+ void SAL_CALL CommonTimeNodeContext::endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException)
+ {
+ if( aElement == ( NMSP_PPT|XML_iterate ) )
+ {
+ mbIterate = false;
+ }
+ }
+
+
+ Reference< XFastContextHandler > SAL_CALL CommonTimeNodeContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_childTnLst:
+ case NMSP_PPT|XML_subTnLst:
+ xRet.set( new TimeNodeListContext( getHandler(), mpNode->getChilds() ) );
+ break;
+
+ case NMSP_PPT|XML_stCondLst:
+ xRet.set( new CondListContext( getHandler(), aElementToken, xAttribs, mpNode, mpNode->getStartCondition() ) );
+ break;
+ case NMSP_PPT|XML_endCondLst:
+ xRet.set( new CondListContext( getHandler(), aElementToken, xAttribs, mpNode, mpNode->getEndCondition() ) );
+ break;
+
+ case NMSP_PPT|XML_endSync:
+ xRet.set( new CondContext( getHandler(), xAttribs, mpNode, mpNode->getEndSyncValue() ) );
+ break;
+ case NMSP_PPT|XML_iterate:
+ {
+ sal_Int32 nVal = xAttribs->getOptionalValueToken( XML_type, XML_el );
+ if( nVal != 0 )
+ {
+ // TODO put that in a function
+ sal_Int16 nEnum;
+ switch( nVal )
+ {
+ case XML_el:
+ nEnum = TextAnimationType::BY_PARAGRAPH;
+ break;
+ case XML_lt:
+ nEnum = TextAnimationType::BY_LETTER;
+ break;
+ case XML_wd:
+ nEnum = TextAnimationType::BY_WORD;
+ break;
+ default:
+ // default is BY_WORD. See Ppt97Animation::GetTextAnimationType()
+ // in sd/source/filter/ppt/ppt97animations.cxx:297
+ nEnum = TextAnimationType::BY_WORD;
+ break;
+ }
+ mpNode->getNodeProperties()[ NP_ITERATETYPE ] <<= nEnum;
+ }
+ // in case of exception we ignore the whole tag.
+ AttributeList attribs( xAttribs );
+ // TODO what to do with this
+ /*bool bBackwards =*/ attribs.getBool( XML_backwards, false );
+ mbIterate = true;
+ break;
+ }
+ case NMSP_PPT|XML_tmAbs:
+ if( mbIterate )
+ {
+ AttributeList attribs( xAttribs );
+ double fTime = attribs.getUnsignedInteger( XML_val, 0 );
+ // time in ms. property is in % TODO
+ mpNode->getNodeProperties()[ NP_ITERATEINTERVAL ] <<= fTime;
+ }
+ break;
+ case NMSP_PPT|XML_tmPct:
+ if( mbIterate )
+ {
+ AttributeList attribs( xAttribs );
+ double fPercent = (double)attribs.getUnsignedInteger( XML_val, 0 ) / 100000.0;
+ mpNode->getNodeProperties()[ NP_ITERATEINTERVAL ] <<= fPercent;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+} }
diff --git a/oox/source/ppt/commontimenodecontext.hxx b/oox/source/ppt/commontimenodecontext.hxx
new file mode 100644
index 000000000000..245a96d5d3d9
--- /dev/null
+++ b/oox/source/ppt/commontimenodecontext.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: commontimenodecontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_PPT_COMMONTIMENODECONTEXT
+#define OOX_PPT_COMMONTIMENODECONTEXT
+
+
+#include <com/sun/star/animations/XIterateContainer.hpp>
+#include "oox/ppt/timenode.hxx"
+#include "oox/ppt/timenodelistcontext.hxx"
+#include "conditioncontext.hxx"
+
+
+namespace oox { namespace ppt {
+
+ /** CT_TLCommonTimeNodeData */
+ class CommonTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ CommonTimeNodeContext( const ::oox::core::FragmentHandlerRef& xHandler, sal_Int32 aElement, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs, const TimeNodePtr & pNode);
+ ~CommonTimeNodeContext( ) throw( );
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& /*xAttribs*/ ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ private:
+ bool mbIterate;
+ ::com::sun::star::uno::Reference< ::com::sun::star::animations::XIterateContainer > mxIter;
+ };
+
+
+} }
+
+
+#endif
diff --git a/oox/source/ppt/conditioncontext.cxx b/oox/source/ppt/conditioncontext.cxx
new file mode 100644
index 000000000000..59234c7f80e0
--- /dev/null
+++ b/oox/source/ppt/conditioncontext.cxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: conditioncontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "conditioncontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include <osl/diagnose.h>
+
+#include <com/sun/star/animations/XTimeContainer.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <com/sun/star/animations/AnimationEndSync.hpp>
+#include <com/sun/star/animations/EventTrigger.hpp>
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/core/context.hxx"
+#include "oox/ppt/animationspersist.hxx"
+#include "animationtypes.hxx"
+
+#include "timetargetelementcontext.hxx"
+#include "tokens.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::animations;
+
+namespace oox { namespace ppt {
+
+ CondContext::CondContext( const FragmentHandlerRef & xHandler, const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode, AnimationCondition & aValue )
+ : TimeNodeContext( xHandler, NMSP_PPT|XML_cond, xAttribs, pNode )
+ , maCond( aValue )
+ {
+ maEvent.Trigger = EventTrigger::NONE;
+ maEvent.Repeat = 0;
+
+ AttributeList attribs( xAttribs );
+ if( attribs.hasAttribute( XML_evt ) )
+ {
+ sal_Int32 nEvent = xAttribs->getOptionalValueToken( XML_evt, 0 );
+ switch( nEvent )
+ {
+ case XML_onBegin:
+ maEvent.Trigger = EventTrigger::ON_BEGIN;
+ break;
+ case XML_onEnd:
+ maEvent.Trigger = EventTrigger::ON_END;
+ break;
+ case XML_begin:
+ maEvent.Trigger = EventTrigger::BEGIN_EVENT;
+ break;
+ case XML_end:
+ maEvent.Trigger = EventTrigger::END_EVENT;
+ break;
+ case XML_onClick:
+ maEvent.Trigger = EventTrigger::ON_CLICK;
+ break;
+ case XML_onDblClick:
+ maEvent.Trigger = EventTrigger::ON_DBL_CLICK;
+ break;
+ case XML_onMouseOver:
+ maEvent.Trigger = EventTrigger::ON_MOUSE_ENTER;
+ break;
+ case XML_onMouseOut:
+ maEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE;
+ break;
+ case XML_onNext:
+ maEvent.Trigger = EventTrigger::ON_NEXT;
+ break;
+ case XML_onPrev:
+ maEvent.Trigger = EventTrigger::ON_PREV;
+ break;
+ case XML_onStopAudio:
+ maEvent.Trigger = EventTrigger::ON_STOP_AUDIO;
+ break;
+ default:
+ break;
+ }
+ }
+ if( attribs.hasAttribute( XML_delay ) || ( maEvent.Trigger == EventTrigger::NONE ) )
+ {
+ maEvent.Offset = GetTime( xAttribs->getOptionalValue( XML_delay ) );
+ }
+ }
+
+ CondContext::~CondContext( ) throw( )
+ {
+ if( maCond.mnType == 0 )
+ {
+ maCond.maValue = (maEvent.Trigger == EventTrigger::NONE) ? maEvent.Offset : makeAny( maEvent );
+ }
+ }
+
+ Reference< XFastContextHandler > SAL_CALL CondContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_rtn:
+ {
+ // ST_TLTriggerRuntimeNode { first, last, all }
+ sal_Int32 aTok;
+ sal_Int16 nEnum;
+ aTok = xAttribs->getOptionalValueToken( XML_val, XML_first );
+ switch( aTok )
+ {
+ case XML_first:
+ nEnum = AnimationEndSync::FIRST;
+ break;
+ case XML_last:
+ nEnum = AnimationEndSync::LAST;
+ break;
+ case XML_all:
+ nEnum = AnimationEndSync::ALL;
+ break;
+ default:
+ break;
+ }
+ maCond.mnType = aElementToken;
+ maCond.maValue = makeAny( nEnum );
+ break;
+ }
+ case NMSP_PPT|XML_tn:
+ {
+ maCond.mnType = aElementToken;
+ AttributeList attribs( xAttribs );
+ sal_uInt32 nId = attribs.getUnsignedInteger( XML_val, 0 );
+ maCond.maValue = makeAny( nId );
+ break;
+ }
+ case NMSP_PPT|XML_tgtEl:
+ // CT_TLTimeTargetElement
+ xRet.set( new TimeTargetElementContext( getHandler(), maCond.getTarget() ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+
+ }
+
+
+
+ /** CT_TLTimeConditionList */
+ CondListContext::CondListContext( const FragmentHandlerRef & xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode,
+ AnimationConditionList & aCond )
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ , maConditions( aCond )
+ {
+ }
+
+ CondListContext::~CondListContext( )
+ throw( )
+ {
+ }
+
+ Reference< XFastContextHandler > CondListContext::createFastChildContext( ::sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElement )
+ {
+ case NMSP_PPT|XML_cond:
+ // add a condition to the list
+ maConditions.push_back( AnimationCondition() );
+ xRet.set( new CondContext( getHandler(), xAttribs, mpNode, maConditions.back() ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+
+} }
+
diff --git a/oox/source/ppt/conditioncontext.hxx b/oox/source/ppt/conditioncontext.hxx
new file mode 100644
index 000000000000..c0e3dc139ddf
--- /dev/null
+++ b/oox/source/ppt/conditioncontext.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: conditioncontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_PPT_CONDITIONCONTEXT
+#define OOX_PPT_CONDITIONCONTEXT
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/animations/Event.hpp>
+
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/ppt/timenode.hxx"
+#include "oox/ppt/timenodelistcontext.hxx"
+#include "oox/ppt/animationspersist.hxx"
+
+namespace oox { namespace ppt {
+
+
+ /** CT_TLTimeCondition */
+ class CondContext
+ : public TimeNodeContext
+ {
+ public:
+ CondContext( const ::oox::core::FragmentHandlerRef & xHandler,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode, AnimationCondition & aCond );
+ ~CondContext( ) throw( );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ private:
+// ::com::sun::star::uno::Any & maCond;
+ ::com::sun::star::animations::Event maEvent;
+// AnimTargetElementPtr mpTarget;
+ AnimationCondition & maCond;
+ };
+
+
+
+ /** CT_TLTimeConditionList */
+ class CondListContext
+ : public TimeNodeContext
+ {
+ public:
+ CondListContext( const ::oox::core::FragmentHandlerRef & xHandler,
+ sal_Int32 aElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode, AnimationConditionList & aCondList );
+ ~CondListContext( ) throw( );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& /*xAttribs*/ ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ private:
+ AnimationConditionList & maConditions;
+ };
+
+
+} }
+
+
+#endif
diff --git a/oox/source/ppt/customshowlistcontext.cxx b/oox/source/ppt/customshowlistcontext.cxx
new file mode 100644
index 000000000000..01d57cee5c8c
--- /dev/null
+++ b/oox/source/ppt/customshowlistcontext.cxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: customshowlistcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "customshowlistcontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+class CustomShowContext : public ::oox::core::Context
+{
+ CustomShow mrCustomShow;
+
+public:
+ CustomShowContext( const ::oox::core::FragmentHandlerRef& xHandler,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ CustomShow& rCustomShow );
+ ~CustomShowContext( );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& /*xAttribs*/ )
+ throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+};
+
+CustomShowContext::CustomShowContext( const FragmentHandlerRef& xHandler,
+ const Reference< XFastAttributeList >& rxAttribs,
+ CustomShow& rCustomShow )
+: Context( xHandler )
+, mrCustomShow( rCustomShow )
+{
+ mrCustomShow.maName = rxAttribs->getOptionalValue( XML_name );
+ mrCustomShow.mnId = rxAttribs->getOptionalValue( XML_id );
+}
+
+CustomShowContext::~CustomShowContext( )
+{
+}
+
+Reference< XFastContextHandler > SAL_CALL CustomShowContext::createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_sld :
+ mrCustomShow.maSldLst.push_back( xAttribs->getOptionalValue( NMSP_RELATIONSHIPS | XML_id ) );
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+//---------------------------------------------------------------------------
+
+CustomShowListContext::CustomShowListContext( const FragmentHandlerRef& xHandler,
+ std::vector< CustomShow >& rCustomShowList )
+: Context( xHandler )
+, mrCustomShowList( rCustomShowList )
+{
+}
+
+CustomShowListContext::~CustomShowListContext( )
+{
+}
+
+Reference< XFastContextHandler > SAL_CALL CustomShowListContext::createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_custShow :
+ {
+ CustomShow aCustomShow;
+ mrCustomShowList.push_back( aCustomShow );
+ xRet = new CustomShowContext( getHandler(), xAttribs, mrCustomShowList.back() );
+ }
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+
+} }
diff --git a/oox/source/ppt/customshowlistcontext.hxx b/oox/source/ppt/customshowlistcontext.hxx
new file mode 100644
index 000000000000..6cebe9acfe1d
--- /dev/null
+++ b/oox/source/ppt/customshowlistcontext.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: customshowlistcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_POWERPOINT_CUSTOMSHOWLISTCONTEXT_HXX
+#define OOX_POWERPOINT_CUSTOMSHOWLISTCONTEXT_HXX
+
+#include "oox/core/context.hxx"
+#include <vector>
+
+namespace oox { namespace ppt {
+
+
+ struct CustomShow
+ {
+ ::rtl::OUString maName;
+ ::rtl::OUString mnId;
+ std::vector< rtl::OUString >maSldLst;
+ };
+
+ /** CT_ */
+ class CustomShowListContext : public ::oox::core::Context
+ {
+ std::vector< CustomShow >& mrCustomShowList;
+
+ public:
+ CustomShowListContext( const ::oox::core::FragmentHandlerRef& xHandler,
+ std::vector< CustomShow >& rCustomShowList );
+
+ ~CustomShowListContext( );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& /*xAttribs*/ )
+ throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+ };
+
+} }
+
+#endif
diff --git a/oox/source/ppt/layoutfragmenthandler.cxx b/oox/source/ppt/layoutfragmenthandler.cxx
new file mode 100644
index 000000000000..2f2bdf83db81
--- /dev/null
+++ b/oox/source/ppt/layoutfragmenthandler.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutfragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/ppt/layoutfragmenthandler.hxx"
+#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+
+namespace oox { namespace ppt {
+
+// CT_SlideLayout
+
+LayoutFragmentHandler::LayoutFragmentHandler( const oox::core::XmlFilterRef& xFilter, const ::rtl::OUString& rFragmentPath, oox::ppt::SlidePersistPtr pMasterPersistPtr )
+ throw()
+: SlideFragmentHandler( xFilter, rFragmentPath, pMasterPersistPtr, Layout )
+{
+}
+
+LayoutFragmentHandler::~LayoutFragmentHandler()
+ throw()
+{
+
+}
+
+Reference< XFastContextHandler > LayoutFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet( this );
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_sldLayout: // CT_SlideLayout
+ mpSlidePersistPtr->setLayoutValueToken( xAttribs->getOptionalValueToken( XML_type, 0 ) ); // CT_SlideLayoutType
+ break;
+ default:
+ xRet.set( SlideFragmentHandler::createFastChildContext( aElementToken, xAttribs ) );
+ }
+ return xRet;
+}
+
+void SAL_CALL LayoutFragmentHandler::endDocument()
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+} }
+
diff --git a/oox/source/ppt/makefile.mk b/oox/source/ppt/makefile.mk
new file mode 100644
index 000000000000..3614459118a7
--- /dev/null
+++ b/oox/source/ppt/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=ppt
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/pptimport.obj\
+ $(SLO)$/presentationfragmenthandler.obj\
+ $(SLO)$/slidefragmenthandler.obj\
+ $(SLO)$/layoutfragmenthandler.obj\
+ $(SLO)$/backgroundproperties.obj\
+ $(SLO)$/slidetransitioncontext.obj\
+ $(SLO)$/slidetransition.obj\
+ $(SLO)$/slidetimingcontext.obj\
+ $(SLO)$/slidepersist.obj\
+ $(SLO)$/slidemastertextstylescontext.obj \
+ $(SLO)$/timenode.obj\
+ $(SLO)$/pptfilterhelpers.obj\
+ $(SLO)$/soundactioncontext.obj \
+ $(SLO)$/commontimenodecontext.obj \
+ $(SLO)$/commonbehaviorcontext.obj \
+ $(SLO)$/conditioncontext.obj \
+ $(SLO)$/timetargetelementcontext.obj \
+ $(SLO)$/timenodelistcontext.obj \
+ $(SLO)$/animationspersist.obj \
+ $(SLO)$/animvariantcontext.obj \
+ $(SLO)$/timeanimvaluecontext.obj \
+ $(SLO)$/pptshape.obj \
+ $(SLO)$/pptshapegroupcontext.obj \
+ $(SLO)$/pptshapecontext.obj \
+ $(SLO)$/pptshapepropertiescontext.obj \
+ $(SLO)$/buildlistcontext.obj \
+ $(SLO)$/animationtypes.obj \
+ $(SLO)$/customshowlistcontext.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/ppt/pptfilterhelpers.cxx b/oox/source/ppt/pptfilterhelpers.cxx
new file mode 100644
index 000000000000..18db5912686b
--- /dev/null
+++ b/oox/source/ppt/pptfilterhelpers.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pptfilterhelpers.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#include <com/sun/star/animations/TransitionType.hpp>
+#include <com/sun/star/animations/TransitionSubType.hpp>
+
+#include "pptfilterhelpers.hxx"
+
+
+using rtl::OUString;
+
+#include "pptfilterhelpers.hxx"
+
+namespace oox { namespace ppt {
+
+ // BEGIN CUT&PASTE from sd pptanimations.hxx
+
+
+ static const transition gTransitions[] =
+ {
+ { "wipe(up)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::TOPTOBOTTOM, sal_True },
+ { "wipe(right)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::LEFTTORIGHT, sal_False },
+ { "wipe(left)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::LEFTTORIGHT, sal_True },
+ { "wipe(down)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::TOPTOBOTTOM, sal_False },
+ { "wheel(1)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::ONEBLADE, sal_True },
+ { "wheel(2)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::TWOBLADEVERTICAL, sal_True },
+ { "wheel(3)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::THREEBLADE, sal_True },
+ { "wheel(4)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::FOURBLADE, sal_True },
+ { "wheel(8)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::EIGHTBLADE, sal_True },
+ { "strips(downLeft)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALRIGHT, sal_True },
+ { "strips(upLeft)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALLEFT, sal_False },
+ { "strips(downRight)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALLEFT, sal_True },
+ { "strips(upRight)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALRIGHT, sal_False },
+ { "barn(inVertical)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_False },
+ { "barn(outVertical)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True },
+ { "barn(inHorizontal)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_False },
+ { "barn(outHorizontal)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True },
+ { "randombar(vertical)", ::com::sun::star::animations::TransitionType::RANDOMBARWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True},
+ { "randombar(horizontal)", ::com::sun::star::animations::TransitionType::RANDOMBARWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True },
+ { "checkerboard(down)", ::com::sun::star::animations::TransitionType::CHECKERBOARDWIPE, ::com::sun::star::animations::TransitionSubType::DOWN, sal_True},
+ { "checkerboard(across)", ::com::sun::star::animations::TransitionType::CHECKERBOARDWIPE, ::com::sun::star::animations::TransitionSubType::ACROSS, sal_True },
+ { "plus(out)", ::com::sun::star::animations::TransitionType::FOURBOXWIPE, ::com::sun::star::animations::TransitionSubType::CORNERSIN, sal_False },
+ { "plus(in)", ::com::sun::star::animations::TransitionType::FOURBOXWIPE, ::com::sun::star::animations::TransitionSubType::CORNERSIN, sal_True },
+ { "diamond(out)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::DIAMOND, sal_True },
+ { "diamond(in)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::DIAMOND, sal_False },
+ { "circle(out)", ::com::sun::star::animations::TransitionType::ELLIPSEWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True },
+ { "circle(in)", ::com::sun::star::animations::TransitionType::ELLIPSEWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_False },
+ { "box(out)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::RECTANGLE, sal_True },
+ { "box(in)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::RECTANGLE, sal_False },
+ { "wedge", ::com::sun::star::animations::TransitionType::FANWIPE, ::com::sun::star::animations::TransitionSubType::CENTERTOP, sal_True },
+ { "blinds(vertical)", ::com::sun::star::animations::TransitionType::BLINDSWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True },
+ { "blinds(horizontal)", ::com::sun::star::animations::TransitionType::BLINDSWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True },
+ { "fade", ::com::sun::star::animations::TransitionType::FADE, ::com::sun::star::animations::TransitionSubType::CROSSFADE, sal_True },
+ { "slide(fromTop)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMTOP, sal_True },
+ { "slide(fromRight)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMRIGHT, sal_True },
+ { "slide(fromLeft)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMLEFT, sal_True },
+ { "slide(fromBottom)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMBOTTOM, sal_True },
+ { "dissolve", ::com::sun::star::animations::TransitionType::DISSOLVE, ::com::sun::star::animations::TransitionSubType::DEFAULT, sal_True },
+ { "image", ::com::sun::star::animations::TransitionType::DISSOLVE, ::com::sun::star::animations::TransitionSubType::DEFAULT, sal_True }, // TODO
+ { NULL, 0, 0, sal_False }
+ };
+
+ const transition* transition::find( const OUString& rName )
+ {
+ const transition* p = gTransitions;
+
+ while( p->mpName )
+ {
+ if( rName.compareToAscii( p->mpName ) == 0 )
+ return p;
+
+ p++;
+ }
+
+ return NULL;
+ }
+
+
+ bool convertMeasure( OUString& rString )
+ {
+ bool bRet = false;
+
+ const sal_Char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", NULL };
+ const sal_Char* pDest[] = { "x", "y", "width", "height", NULL };
+ sal_Int32 nIndex = 0;
+
+ const sal_Char** ps = pSource;
+ const sal_Char** pd = pDest;
+
+ while( *ps )
+ {
+ const OUString aSearch( OUString::createFromAscii( *ps ) );
+ while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 )
+ {
+ sal_Int32 nLength = aSearch.getLength();
+ if( nIndex && (rString.getStr()[nIndex-1] == '#' ) )
+ {
+ nIndex--;
+ nLength++;
+ }
+
+ const OUString aNew( OUString::createFromAscii( *pd ) );
+ rString = rString.replaceAt( nIndex, nLength, aNew );
+ nIndex += aNew.getLength();
+ bRet = true;
+ }
+ ps++;
+ pd++;
+ }
+
+ return bRet;
+ }
+
+
+} }
diff --git a/oox/source/ppt/pptfilterhelpers.hxx b/oox/source/ppt/pptfilterhelpers.hxx
new file mode 100644
index 000000000000..82b301bccae3
--- /dev/null
+++ b/oox/source/ppt/pptfilterhelpers.hxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pptfilterhelpers.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_PPT_PPTFILTERHELPERS
+#define OOX_PPT_PPTFILTERHELPERS
+
+#include <rtl/ustring.hxx>
+
+namespace oox { namespace ppt {
+
+
+//BEGIN CUT&PASTE from sd pptanimations.hxx
+ // conversion of MS to OOo attributes.
+ enum MS_AttributeNames
+ {
+ MS_PPT_X, MS_PPT_Y, MS_PPT_W, MS_PPT_H, MS_PPT_C, MS_R, MS_XSHEAR, MS_FILLCOLOR, MS_FILLTYPE,
+ MS_STROKECOLOR, MS_STROKEON, MS_STYLECOLOR, MS_STYLEROTATION, MS_FONTWEIGHT,
+ MS_STYLEUNDERLINE, MS_STYLEFONTFAMILY, MS_STYLEFONTSIZE, MS_STYLEFONTSTYLE,
+ MS_STYLEVISIBILITY, MS_STYLEOPACITY, MS_UNKNOWN
+ };
+
+ struct ImplAttributeNameConversion
+ {
+ MS_AttributeNames meAttribute;
+ const char* mpMSName;
+ const char* mpAPIName;
+ };
+
+ static const ImplAttributeNameConversion gImplConversionList[] =
+ {
+ { MS_PPT_X, "ppt_x", "X" },
+ { MS_PPT_Y, "ppt_y", "Y" },
+ { MS_PPT_W, "ppt_w", "Width" },
+ { MS_PPT_H, "ppt_h", "Height" },
+ { MS_PPT_C, "ppt_c", "DimColor" },
+ { MS_R, "r", "Rotate" },
+ { MS_XSHEAR, "xshear", "SkewX" },
+ { MS_FILLCOLOR, "fillColor", "FillColor" },
+ { MS_FILLCOLOR, "fillcolor", "FillColor" },
+ { MS_FILLTYPE, "fill.type", "FillStyle" },
+ { MS_STROKECOLOR, "stroke.color", "LineColor" },
+ { MS_STROKEON, "stroke.on", "LineStyle" },
+ { MS_STYLECOLOR, "style.color", "CharColor" },
+ { MS_STYLEROTATION, "style.rotation", "Rotate" },
+ { MS_FONTWEIGHT, "style.fontWeight", "CharWeight" },
+ { MS_STYLEUNDERLINE, "style.textDecorationUnderline","CharUnderline" },
+ { MS_STYLEFONTFAMILY, "style.fontFamily", "CharFontName" },
+ { MS_STYLEFONTSIZE, "style.fontSize", "CharHeight" },
+ { MS_STYLEFONTSTYLE, "style.fontStyle", "CharPosture" },
+ { MS_STYLEVISIBILITY, "style.visibility", "Visibility" },
+ { MS_STYLEOPACITY, "style.opacity", "Opacity" },
+ { MS_UNKNOWN, NULL, NULL }
+ };
+ //END CUT&PASTE
+
+
+ // BEGIN CUT&PASTE from sd pptanimations.hxx
+ struct transition
+ {
+ const sal_Char* mpName;
+ sal_Int16 mnType;
+ sal_Int16 mnSubType;
+ sal_Bool mbDirection; // true: default geometric direction
+
+ static const transition* find( const rtl::OUString& rName );
+ static const sal_Char* find( const sal_Int16 mnType, const sal_Int16 mnSubType, const sal_Bool bDirection );
+ };
+ // END CUT&PASTE
+
+
+ // BEGIN CUT&PASTE from sd pptinanimation.cxx
+ bool convertMeasure( ::rtl::OUString& rString );
+ // END CUT&PASTE from sd pptinanimation.cxx
+
+
+} }
+
+
+#endif
diff --git a/oox/source/ppt/pptimport.cxx b/oox/source/ppt/pptimport.cxx
new file mode 100644
index 000000000000..4752f1bdb83a
--- /dev/null
+++ b/oox/source/ppt/pptimport.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pptimport.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/pptimport.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace oox::core;
+
+namespace oox { namespace ppt {
+
+OUString SAL_CALL PowerPointImport_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.Impress.oox.PowerPointImport" );
+}
+
+uno::Sequence< OUString > SAL_CALL PowerPointImport_getSupportedServiceNames() throw()
+{
+ const OUString aServiceName = CREATE_OUSTRING( "com.sun.star.comp.ooxpptx" );
+ const Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL PowerPointImport_createInstance(const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new PowerPointImport( rSMgr );
+}
+
+PowerPointImport::PowerPointImport( const uno::Reference< lang::XMultiServiceFactory > & rSMgr )
+ : XmlFilterBase( rSMgr )
+{
+}
+
+PowerPointImport::~PowerPointImport()
+{
+}
+
+bool PowerPointImport::importDocument() throw()
+{
+ OUString aFragmentPath = getFragmentPathFromType( CREATE_RELATIONS_TYPE( "officeDocument" ) );
+ return importFragment( new PresentationFragmentHandler( this, aFragmentPath ) );
+}
+
+bool PowerPointImport::exportDocument() throw()
+{
+ return false;
+}
+
+sal_Int32 PowerPointImport::getSchemeClr( sal_Int32 nColorSchemeToken ) const
+{
+ sal_Int32 nColor = 0;
+ if ( mpActualSlidePersist )
+ {
+ sal_Bool bColorMapped = sal_False;
+ oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() );
+ if ( pClrMapPtr )
+ bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken );
+
+ if ( !bColorMapped ) // try masterpage mapping
+ {
+ SlidePersistPtr pMasterPersist = mpActualSlidePersist->getMasterPersist();
+ if ( pMasterPersist )
+ {
+ pClrMapPtr = pMasterPersist->getClrMap();
+ if ( pClrMapPtr )
+ bColorMapped = pClrMapPtr->getColorMap( nColorSchemeToken );
+ }
+ }
+ oox::drawingml::ClrSchemePtr pClrSchemePtr( mpActualSlidePersist->getClrScheme() );
+ if ( pClrSchemePtr )
+ pClrSchemePtr->getColor( nColorSchemeToken, nColor );
+ else
+ {
+ drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme();
+ if( pTheme )
+ {
+ pTheme->getClrScheme()->getColor( nColorSchemeToken, nColor );
+ }
+ else
+ {
+ OSL_TRACE("OOX: PowerPointImport::mpThemePtr is NULL");
+ }
+ }
+ }
+ return nColor;
+}
+
+const oox::vml::DrawingPtr PowerPointImport::getDrawings()
+{
+ oox::vml::DrawingPtr xRet;
+ if ( mpActualSlidePersist )
+ xRet = mpActualSlidePersist->getDrawing();
+ return xRet;
+}
+
+OUString PowerPointImport::implGetImplementationName() const
+{
+ return PowerPointImport_getImplementationName();
+}
+
+}}
diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
new file mode 100644
index 000000000000..8335ba57c408
--- /dev/null
+++ b/oox/source/ppt/pptshape.cxx
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pptshape.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/pptshape.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/drawing/HomogenMatrix3.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include "oox/ppt/slidepersist.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::drawing;
+
+namespace oox { namespace ppt {
+
+PPTShape::PPTShape( const oox::ppt::ShapeLocation eShapeLocation, const sal_Char* pServiceName )
+: Shape( pServiceName )
+, meShapeLocation( eShapeLocation )
+, mbReferenced( sal_False )
+{
+}
+
+PPTShape::~PPTShape()
+{
+}
+
+void PPTShape::addShape( const oox::core::XmlFilterBase& rFilterBase, const Reference< XModel > &rxModel, const oox::ppt::SlidePersist& rSlidePersist, const oox::drawingml::ThemePtr pThemePtr,
+ std::map< OUString, ::oox::drawingml::ShapePtr > & aShapeMap, const Reference< XShapes >& rxShapes, const awt::Rectangle* pShapeRect )
+{
+ // only placeholder from layout are being inserted
+ if ( mnSubType && ( meShapeLocation == Master ) )
+ return;
+ try
+ {
+ rtl::OUString sServiceName( msServiceName );
+ if( sServiceName.getLength() )
+ {
+ oox::drawingml::TextListStylePtr aMasterTextListStyle;
+ Reference< lang::XMultiServiceFactory > xServiceFact( rxModel, UNO_QUERY_THROW );
+ switch( mnSubType )
+ {
+ case XML_ctrTitle :
+ case XML_title :
+ {
+ const rtl::OUString sTitleShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.TitleTextShape" ) );
+ sServiceName = sTitleShapeService;
+ aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
+ }
+ break;
+ case XML_obj :
+ {
+ const rtl::OUString sOutlinerShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.OutlinerShape" ) );
+ sServiceName = sOutlinerShapeService;
+ aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
+ }
+ break;
+ case XML_body :
+ {
+ const rtl::OUString sNotesShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.NotesShape" ) );
+ const rtl::OUString sOutlinerShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.OutlinerShape" ) );
+ if ( rSlidePersist.isNotesPage() )
+ {
+ sServiceName = sNotesShapeService;
+ aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
+ }
+ else
+ {
+ sServiceName = sOutlinerShapeService;
+ aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
+ }
+ }
+ break;
+ case XML_dt :
+ {
+ const rtl::OUString sDateTimeShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.DateTimeShape" ) );
+ sServiceName = sDateTimeShapeService;
+ }
+ break;
+ case XML_hdr :
+ {
+ const rtl::OUString sHeaderShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.HeaderShape" ) );
+ sServiceName = sHeaderShapeService;
+ }
+ break;
+ case XML_ftr :
+ {
+ const rtl::OUString sFooterShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.FooterShape" ) );
+ sServiceName = sFooterShapeService;
+ }
+ break;
+ case XML_sldNum :
+ {
+ const rtl::OUString sSlideNumberShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.SlideNumberShape" ) );
+ sServiceName = sSlideNumberShapeService;
+ }
+ break;
+ case XML_sldImg :
+ {
+ const rtl::OUString sPageShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PageShape" ) );
+ sServiceName = sPageShapeService;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+ if ( !aMasterTextListStyle.get() )
+ aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getOtherTextStyle() : rSlidePersist.getOtherTextStyle();
+ setMasterTextListStyle( aMasterTextListStyle );
+
+ Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, rxModel, pThemePtr, rxShapes, pShapeRect ) );
+
+ if( msId.getLength() )
+ {
+ aShapeMap[ msId ] = shared_from_this();
+ }
+
+ // if this is a group shape, we have to add also each child shape
+ Reference< XShapes > xShapes( xShape, UNO_QUERY );
+ if ( xShapes.is() )
+ addChilds( rFilterBase, *this, rxModel, pThemePtr, aShapeMap, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+}
+
+void PPTShape::applyShapeReference( const oox::drawingml::Shape& rReferencedShape )
+{
+ Shape::applyShapeReference( rReferencedShape );
+}
+
+} }
diff --git a/oox/source/ppt/pptshapecontext.cxx b/oox/source/ppt/pptshapecontext.cxx
new file mode 100644
index 000000000000..00631845d63b
--- /dev/null
+++ b/oox/source/ppt/pptshapecontext.cxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pptshapecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/ppt/pptshape.hxx"
+#include "oox/ppt/pptshapecontext.hxx"
+#include "oox/ppt/pptshapepropertiescontext.hxx"
+#include "oox/ppt/slidepersist.hxx"
+#include "oox/drawingml/shapestylecontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+// CT_Shape
+PPTShapeContext::PPTShapeContext( const oox::ppt::SlidePersistPtr pSlidePersistPtr, const FragmentHandlerRef& xHandler,
+ oox::drawingml::ShapePtr pMasterShapePtr, oox::drawingml::ShapePtr pShapePtr )
+: oox::drawingml::ShapeContext( xHandler, pMasterShapePtr, pShapePtr )
+, mpSlidePersistPtr( pSlidePersistPtr )
+{
+}
+
+oox::drawingml::ShapePtr findPlaceholder( const sal_Int32 nMasterPlaceholder, std::vector< oox::drawingml::ShapePtr >& rShapes )
+{
+ oox::drawingml::ShapePtr aShapePtr;
+ std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
+ while( aRevIter != rShapes.rend() )
+ {
+ if ( (*aRevIter)->getSubType() == nMasterPlaceholder )
+ {
+ aShapePtr = *aRevIter;
+ break;
+ }
+ std::vector< oox::drawingml::ShapePtr >& rChilds = (*aRevIter)->getChilds();
+ aShapePtr = findPlaceholder( nMasterPlaceholder, rChilds );
+ if ( aShapePtr.get() )
+ break;
+ aRevIter++;
+ }
+ return aShapePtr;
+}
+
+// if nFirstPlaceholder can't be found, it will be searched for nSecondPlaceholder
+oox::drawingml::ShapePtr findPlaceholder( sal_Int32 nFirstPlaceholder, sal_Int32 nSecondPlaceholder, std::vector< oox::drawingml::ShapePtr >& rShapes )
+{
+ oox::drawingml::ShapePtr pPlaceholder = findPlaceholder( nFirstPlaceholder, rShapes );
+ return !nSecondPlaceholder || pPlaceholder.get() ? pPlaceholder : findPlaceholder( nSecondPlaceholder, rShapes );
+}
+
+Reference< XFastContextHandler > PPTShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ // nvSpPr CT_ShapeNonVisual begin
+// case NMSP_PPT|XML_drElemPr:
+// break;
+ case NMSP_PPT|XML_cNvPr:
+ mpShapePtr->setId( xAttribs->getOptionalValue( XML_id ) );
+ mpShapePtr->setName( xAttribs->getOptionalValue( XML_name ) );
+ break;
+ case NMSP_PPT|XML_ph:
+ {
+ sal_Int32 nSubType( xAttribs->getOptionalValueToken( XML_type, XML_obj ) );
+ mpShapePtr->setSubType( nSubType );
+ mpShapePtr->setIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
+ if ( nSubType )
+ {
+ PPTShape* pPPTShapePtr = dynamic_cast< PPTShape* >( mpShapePtr.get() );
+ if ( pPPTShapePtr )
+ {
+ oox::ppt::ShapeLocation eShapeLocation = pPPTShapePtr->getShapeLocation();
+ if ( ( eShapeLocation == Slide ) || ( eShapeLocation == Layout ) )
+ {
+ // inheriting properties from placeholder objects by cloning shape
+
+ sal_Int32 nFirstPlaceholder = 0;
+ sal_Int32 nSecondPlaceholder = 0;
+ switch( nSubType )
+ {
+ case XML_ctrTitle : // slide/layout
+ nFirstPlaceholder = XML_ctrTitle;
+ nSecondPlaceholder = XML_title;
+ break;
+ case XML_subTitle : // slide/layout
+ nFirstPlaceholder = XML_subTitle;
+ nSecondPlaceholder = XML_title;
+ break;
+ case XML_obj : // slide/layout
+ nFirstPlaceholder = XML_body;
+ break;
+ case XML_dt : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_sldNum : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_ftr : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_hdr : // notes/notesmaster/handoutmaster
+ case XML_body : // slide/layout/master/notes/notesmaster
+ case XML_title : // slide/layout/master/
+ case XML_chart : // slide/layout
+ case XML_tbl : // slide/layout
+ case XML_clipArt : // slide/layout
+ case XML_dgm : // slide/layout
+ case XML_media : // slide/layout
+ case XML_sldImg : // notes/notesmaster
+ case XML_pic : // slide/layout
+ nFirstPlaceholder = nSubType;
+ default:
+ break;
+ }
+ if ( nFirstPlaceholder )
+ {
+ oox::drawingml::ShapePtr pPlaceholder;
+ if ( eShapeLocation == Layout ) // for layout objects the referenced object can be found within the same shape tree
+ pPlaceholder = findPlaceholder( nFirstPlaceholder, nSecondPlaceholder, mpSlidePersistPtr->getShapes()->getChilds() );
+ else if ( eShapeLocation == Slide ) // normal slide shapes have to search within the corresponding master tree for referenced objects
+ {
+ SlidePersistPtr pMasterPersist( mpSlidePersistPtr->getMasterPersist() );
+ if ( pMasterPersist.get() )
+ pPlaceholder = findPlaceholder( nFirstPlaceholder, nSecondPlaceholder, pMasterPersist->getShapes()->getChilds() );
+ }
+ if ( pPlaceholder.get() )
+ {
+ mpShapePtr->applyShapeReference( *pPlaceholder.get() );
+ PPTShape* pPPTShape = dynamic_cast< PPTShape* >( pPlaceholder.get() );
+ if ( pPPTShape )
+ pPPTShape->setReferenced( sal_True );
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ // nvSpPr CT_ShapeNonVisual end
+
+ case NMSP_PPT|XML_spPr:
+ xRet = new PPTShapePropertiesContext( this, *(mpShapePtr.get()) );
+ break;
+
+ case NMSP_PPT|XML_style:
+ xRet = new oox::drawingml::ShapeStyleContext( this, *(mpShapePtr.get()) );
+ break;
+
+ case NMSP_PPT|XML_txBody:
+ {
+ xRet = new oox::drawingml::TextBodyContext( getHandler(), *(mpShapePtr.get()) );
+ break;
+ }
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+
+} }
diff --git a/oox/source/ppt/pptshapegroupcontext.cxx b/oox/source/ppt/pptshapegroupcontext.cxx
new file mode 100644
index 000000000000..f5b7a0703237
--- /dev/null
+++ b/oox/source/ppt/pptshapegroupcontext.cxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pptshapegroupcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/ppt/pptshape.hxx"
+#include "oox/ppt/pptshapecontext.hxx"
+#include "oox/ppt/pptshapegroupcontext.hxx"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/connectorshapecontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+PPTShapeGroupContext::PPTShapeGroupContext( const oox::ppt::SlidePersistPtr pSlidePersistPtr, const ShapeLocation eShapeLocation,
+ const FragmentHandlerRef& xHandler, sal_Int32 aElementToken,
+ oox::drawingml::ShapePtr pMasterShapePtr, oox::drawingml::ShapePtr pGroupShapePtr )
+: ShapeGroupContext( xHandler, aElementToken, pMasterShapePtr, pGroupShapePtr )
+, mpSlidePersistPtr( pSlidePersistPtr )
+, meShapeLocation( eShapeLocation )
+{
+}
+
+Reference< XFastContextHandler > PPTShapeGroupContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_cNvPr:
+ mpGroupShapePtr->setId( xAttribs->getOptionalValue( XML_id ) );
+ mpGroupShapePtr->setName( xAttribs->getOptionalValue( XML_name ) );
+ break;
+ case NMSP_PPT|XML_ph:
+ mpGroupShapePtr->setSubType( xAttribs->getOptionalValueToken( XML_type, FastToken::DONTKNOW ) );
+ mpGroupShapePtr->setIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
+ break;
+ // nvSpPr CT_ShapeNonVisual end
+
+ case NMSP_PPT|XML_grpSpPr:
+ xRet = new oox::drawingml::ShapePropertiesContext( this, *(mpGroupShapePtr.get()) );
+ break;
+ case NMSP_PPT|XML_spPr:
+ xRet = new oox::drawingml::ShapePropertiesContext( this, *(mpGroupShapePtr.get()) );
+ break;
+/*
+ case NMSP_PPT|XML_style:
+ xRet = new ShapeStyleContext( getParser() );
+ break;
+*/
+ case NMSP_PPT|XML_cxnSp: // connector shape
+ xRet.set( new oox::drawingml::ConnectorShapeContext( getHandler(), aElementToken, mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.ConnectorShape" ) ) ) );
+ break;
+ case NMSP_PPT|XML_grpSp: // group shape
+ xRet.set( new PPTShapeGroupContext( mpSlidePersistPtr, meShapeLocation, getHandler(), aElementToken, mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.GroupShape" ) ) ) );
+ break;
+ case NMSP_PPT|XML_sp: // Shape
+ xRet.set( new oox::ppt::PPTShapeContext( mpSlidePersistPtr, getHandler(), mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.CustomShape" ) ) ) );
+ break;
+ case NMSP_PPT|XML_pic: // CT_Picture
+ xRet.set( new oox::drawingml::GraphicShapeContext( getHandler(), mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.GraphicObjectShape" ) ) ) );
+ break;
+ case NMSP_PPT|XML_graphicFrame: // CT_GraphicalObjectFrame
+ xRet.set( new oox::drawingml::GraphicalObjectFrameContext( getHandler(), mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.OLE2Shape" ) ) ) );
+ break;
+
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/ppt/pptshapepropertiescontext.cxx b/oox/source/ppt/pptshapepropertiescontext.cxx
new file mode 100644
index 000000000000..c4455fd310c5
--- /dev/null
+++ b/oox/source/ppt/pptshapepropertiescontext.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pptshapepropertiescontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/ppt/pptshape.hxx"
+#include "oox/ppt/pptshapepropertiescontext.hxx"
+#include "oox/ppt/slidepersist.hxx"
+#include "oox/drawingml/shapestylecontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+// CT_Shape
+PPTShapePropertiesContext::PPTShapePropertiesContext( const ContextRef& xParent, ::oox::drawingml::Shape& rShape )
+: ShapePropertiesContext( xParent, rShape )
+{
+}
+
+Reference< XFastContextHandler > PPTShapePropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_DRAWINGML | XML_xfrm:
+ {
+ static const OUString sIsPlaceholderDependent( RTL_CONSTASCII_USTRINGPARAM( "IsPlaceholderDependent" ) );
+ mrShape.getShapeProperties()[ sIsPlaceholderDependent ] <<= Any( sal_False );
+
+ xRet = ShapePropertiesContext::createFastChildContext( aElementToken, xAttribs );
+ }
+ break;
+
+ default:
+ xRet = ShapePropertiesContext::createFastChildContext( aElementToken, xAttribs );
+ break;
+ }
+ return xRet;
+}
+
+} }
diff --git a/oox/source/ppt/presentationfragmenthandler.cxx b/oox/source/ppt/presentationfragmenthandler.cxx
new file mode 100644
index 000000000000..b511f2705eb7
--- /dev/null
+++ b/oox/source/ppt/presentationfragmenthandler.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: presentationfragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPageTarget.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+
+#include "oox/drawingml/theme.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/themefragmenthandler.hxx"
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/ppt/pptshape.hxx"
+#include "oox/ppt/presentationfragmenthandler.hxx"
+#include "oox/ppt/slidefragmenthandler.hxx"
+#include "oox/ppt/layoutfragmenthandler.hxx"
+#include "oox/ppt/pptimport.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+PresentationFragmentHandler::PresentationFragmentHandler( const XmlFilterRef& xFilter, const OUString& rFragmentPath ) throw()
+: FragmentHandler( xFilter, rFragmentPath )
+, mpTextListStyle( new TextListStyle())
+{
+}
+
+PresentationFragmentHandler::~PresentationFragmentHandler() throw()
+{
+
+}
+void PresentationFragmentHandler::startDocument() throw (SAXException, RuntimeException)
+{
+}
+
+void PresentationFragmentHandler::endDocument() throw (SAXException, RuntimeException)
+{
+ try
+ {
+ Reference< frame::XModel > xModel( getFilter()->getModel() );
+ Reference< drawing::XDrawPage > xSlide;
+ sal_uInt32 nSlide;
+
+ // importing slide pages and its corresponding notes page
+ Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
+ Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );
+
+ for( nSlide = 0; nSlide < maSlidesVector.size(); nSlide++ )
+ {
+ if( nSlide == 0 )
+ xDrawPages->getByIndex( 0 ) >>= xSlide;
+ else
+ xSlide = xDrawPages->insertNewByIndex( nSlide );
+
+ OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
+ if( aSlideFragmentPath.getLength() > 0 )
+ {
+ SlidePersistPtr pMasterPersistPtr;
+ SlidePersistPtr pSlidePersistPtr( new SlidePersist( sal_False, sal_False, xSlide,
+ ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
+
+ FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( getFilter(), aSlideFragmentPath, pSlidePersistPtr, Slide ) );
+
+ // importing the corresponding masterpage/layout
+ OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromType( CREATE_RELATIONS_TYPE( "slideLayout" ) );
+ if ( aLayoutFragmentPath.getLength() > 0 )
+ {
+ // importing layout
+ RelationsRef xLayoutRelations = getFilter()->importRelations( aLayoutFragmentPath );
+ if( const Relation* pMaster = xLayoutRelations->getRelationFromType( CREATE_RELATIONS_TYPE( "slideMaster" ) ) )
+ {
+ OUString aMasterFragmentPath = Relations::getFragmentPathFromTarget( aLayoutFragmentPath, pMaster->maTarget );
+ if ( aMasterFragmentPath.getLength() )
+ {
+ // check if the corresponding masterpage+layout has already been imported
+ std::vector< SlidePersistPtr >& rMasterPages( (dynamic_cast< PowerPointImport& >( *getFilter() )).getMasterPages() );
+ std::vector< SlidePersistPtr >::iterator aIter( rMasterPages.begin() );
+ while( aIter != rMasterPages.end() )
+ {
+ if ( ( (*aIter)->getPath() == aMasterFragmentPath ) && ( (*aIter)->getLayoutPath() == aLayoutFragmentPath ) )
+ {
+ pMasterPersistPtr = *aIter;
+ break;
+ }
+ aIter++;
+ }
+ if ( aIter == rMasterPages.end() )
+ { // masterpersist not found, we have to load it
+ Reference< drawing::XDrawPage > xMasterPage;
+ Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
+ Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_QUERY_THROW );
+
+ if( !((dynamic_cast< PowerPointImport& >( *getFilter() )).getMasterPages().size() ))
+ xMasterPages->getByIndex( 0 ) >>= xMasterPage;
+ else
+ xMasterPage = xMasterPages->insertNewByIndex( xMasterPages->getCount() );
+
+ pMasterPersistPtr = SlidePersistPtr( new SlidePersist( sal_True, sal_False, xMasterPage,
+ ShapePtr( new PPTShape( Master, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
+ pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
+ (dynamic_cast< PowerPointImport& >( *getFilter() )).getMasterPages().push_back( pMasterPersistPtr );
+ (dynamic_cast< PowerPointImport& >( *getFilter() )).setActualSlidePersist( pMasterPersistPtr );
+ FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( getFilter(), aMasterFragmentPath, pMasterPersistPtr, Master ) );
+
+ // set the correct theme
+ OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromType( CREATE_RELATIONS_TYPE( "theme" ) );
+ if( aThemeFragmentPath.getLength() > 0 )
+ {
+ std::map< OUString, oox::drawingml::ThemePtr >& rThemes( (dynamic_cast< PowerPointImport& >( *getFilter() )).getThemes() );
+ std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
+ if( aIter2 == rThemes.end() )
+ {
+ oox::drawingml::ThemePtr pThemePtr( new oox::drawingml::Theme() );
+ pMasterPersistPtr->setTheme( pThemePtr );
+ getFilter()->importFragment( new ThemeFragmentHandler( getFilter(), aThemeFragmentPath, *(pThemePtr.get()) ) );
+ rThemes[ aThemeFragmentPath ] = pThemePtr;
+ }
+ else
+ {
+ pMasterPersistPtr->setTheme( (*aIter2).second );
+ }
+ }
+ importSlide( xMasterFragmentHandler, pMasterPersistPtr );
+ getFilter()->importFragment( new LayoutFragmentHandler( getFilter(), aLayoutFragmentPath, pMasterPersistPtr ) );
+ pMasterPersistPtr->createBackground( *getFilter() );
+ pMasterPersistPtr->createXShapes( *getFilter(), xModel );
+ }
+ }
+ }
+ }
+
+ // importing slide page
+ pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
+ pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
+ Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
+ if( xMasterPageTarget.is() )
+ xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
+ (dynamic_cast< PowerPointImport& >( *getFilter() )).getDrawPages().push_back( pSlidePersistPtr );
+ (dynamic_cast< PowerPointImport& >( *getFilter() )).setActualSlidePersist( pSlidePersistPtr );
+ importSlide( xSlideFragmentHandler, pSlidePersistPtr );
+ pSlidePersistPtr->createBackground( *getFilter() );
+ pSlidePersistPtr->createXShapes( *getFilter(), xModel );
+
+ // now importing the notes page
+ OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromType( CREATE_RELATIONS_TYPE( "notesSlide" ) );
+ if( aNotesFragmentPath.getLength() > 0 )
+ {
+ Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
+ if ( xPresentationPage.is() )
+ {
+ Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
+ if ( xNotesPage.is() )
+ {
+ SlidePersistPtr pNotesPersistPtr( new SlidePersist( sal_False, sal_True, xNotesPage,
+ ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
+ FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
+ (dynamic_cast< PowerPointImport& >( *getFilter() )).getNotesPages().push_back( pNotesPersistPtr );
+ (dynamic_cast< PowerPointImport& >( *getFilter() )).setActualSlidePersist( pNotesPersistPtr );
+ importSlide( xNotesFragmentHandler, pNotesPersistPtr );
+ pNotesPersistPtr->createBackground( *getFilter() );
+ pNotesPersistPtr->createXShapes( *getFilter(), xModel );
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( false,
+ (rtl::OString("oox::ppt::PresentationFragmentHandler::EndDocument(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+
+ }
+
+ // todo error handling;
+}
+
+// CT_Presentation
+Reference< XFastContextHandler > PresentationFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_presentation:
+ case NMSP_PPT|XML_sldMasterIdLst:
+ case NMSP_PPT|XML_notesMasterIdLst:
+ case NMSP_PPT|XML_sldIdLst:
+ break;
+ case NMSP_PPT|XML_sldMasterId:
+ maSlideMasterVector.push_back( xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_id ) );
+ break;
+ case NMSP_PPT|XML_sldId:
+ maSlidesVector.push_back( xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_id ) );
+ break;
+ case NMSP_PPT|XML_notesMasterId:
+ maNotesMasterVector.push_back( xAttribs->getOptionalValue(NMSP_RELATIONSHIPS|XML_id ) );
+ break;
+ case NMSP_PPT|XML_sldSz:
+ maSlideSize = GetSize2D( xAttribs );
+ break;
+ case NMSP_PPT|XML_notesSz:
+ maNotesSize = GetSize2D( xAttribs );
+ break;
+ case NMSP_PPT|XML_custShowLst:
+ xRet.set( new CustomShowListContext( this , maCustomShowList ) );
+ break;
+ case NMSP_PPT|XML_defaultTextStyle:
+ xRet.set( new TextListStyleContext( this, *(mpTextListStyle.get()) ) );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+bool PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
+ const SlidePersistPtr pSlidePersistPtr )
+{
+ Reference< drawing::XDrawPage > xSlide( pSlidePersistPtr->getPage() );
+ SlidePersistPtr pMasterPersistPtr( pSlidePersistPtr->getMasterPersist() );
+ if ( pMasterPersistPtr.get() )
+ {
+ const OUString sLayout = CREATE_OUSTRING( "Layout" );
+ uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
+ xSet->setPropertyValue( sLayout, Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
+ }
+ while( xSlide->getCount() )
+ {
+ Reference< drawing::XShape > xShape;
+ xSlide->getByIndex(0) >>= xShape;
+ xSlide->remove( xShape );
+ }
+
+ Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
+ if ( xPropertySet.is() )
+ {
+ static const OUString sWidth = CREATE_OUSTRING( "Width" );
+ static const OUString sHeight = CREATE_OUSTRING( "Height" );
+ awt::Size& rPageSize( pSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
+ xPropertySet->setPropertyValue( sWidth, Any( rPageSize.Width ) );
+ xPropertySet->setPropertyValue( sHeight, Any( rPageSize.Height ) );
+ }
+ pSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
+ return getFilter()->importFragment( rxSlideFragmentHandler );
+}
+
+} }
+
diff --git a/oox/source/ppt/slidefragmenthandler.cxx b/oox/source/ppt/slidefragmenthandler.cxx
new file mode 100644
index 000000000000..1740144cff5f
--- /dev/null
+++ b/oox/source/ppt/slidefragmenthandler.cxx
@@ -0,0 +1,193 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: slidefragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "tokens.hxx"
+#include "oox/core/namespaces.hxx"
+#include <oox/ppt/backgroundproperties.hxx>
+#include "oox/ppt/slidefragmenthandler.hxx"
+#include "oox/ppt/slidetimingcontext.hxx"
+#include "oox/ppt/slidetransitioncontext.hxx"
+#include "oox/ppt/slidemastertextstylescontext.hxx"
+#include "oox/ppt/pptshapegroupcontext.hxx"
+#include "oox/ppt/pptshape.hxx"
+#include "oox/drawingml/clrschemecontext.hxx"
+
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+
+namespace oox { namespace ppt {
+
+SlideFragmentHandler::SlideFragmentHandler( const oox::core::XmlFilterRef& xFilter, const ::rtl::OUString& rFragmentPath, oox::ppt::SlidePersistPtr pPersistPtr, const oox::ppt::ShapeLocation eShapeLocation ) throw()
+: FragmentHandler( xFilter, rFragmentPath )
+, mpSlidePersistPtr( pPersistPtr )
+, meShapeLocation( eShapeLocation )
+{
+ OUString aVMLDrawingFragmentPath = getFragmentPathFromType( CREATE_RELATIONS_TYPE( "vmlDrawing" ) );
+ if( aVMLDrawingFragmentPath.getLength() > 0 )
+ {
+ getFilter()->importFragment( new oox::vml::DrawingFragmentHandler(
+ getFilter(), aVMLDrawingFragmentPath, pPersistPtr->getDrawing() ) );
+ }
+}
+
+SlideFragmentHandler::~SlideFragmentHandler() throw()
+{
+}
+
+Reference< XFastContextHandler > SlideFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_sldMaster: // CT_SlideMaster
+ case NMSP_PPT|XML_handoutMaster: // CT_HandoutMaster
+ case NMSP_PPT|XML_sld: // CT_CommonSlideData
+ case NMSP_PPT|XML_notes: // CT_NotesSlide
+ case NMSP_PPT|XML_notesMaster: // CT_NotesMaster
+ break;
+ case NMSP_PPT|XML_cSld: // CT_CommonSlideData
+ maSlideName = xAttribs->getOptionalValue(XML_name);
+ break;
+
+ case NMSP_PPT|XML_spTree: // CT_GroupShape
+ {
+ xRet.set( new PPTShapeGroupContext( mpSlidePersistPtr, meShapeLocation, this, aElementToken, mpSlidePersistPtr->getShapes(),
+ oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.GroupShape" ) ) ) );
+ }
+ break;
+
+ case NMSP_PPT|XML_timing: // CT_SlideTiming
+ xRet.set( new SlideTimingContext( this, mpSlidePersistPtr->getTimeNodeList() ) );
+ break;
+ case NMSP_PPT|XML_transition: // CT_SlideTransition
+ xRet.set( new SlideTransitionContext( this, xAttribs, maSlideProperties ) );
+ break;
+
+ // BackgroundGroup
+ case NMSP_PPT|XML_bgPr: // CT_BackgroundProperties
+ {
+ FillPropertiesPtr pFillPropertiesPtr( new FillProperties() );
+ xRet.set( new BackgroundPropertiesContext( this, pFillPropertiesPtr ) );
+ mpSlidePersistPtr->setBackgroundProperties( pFillPropertiesPtr );
+ }
+ break;
+ case NMSP_PPT|XML_bgRef: // a:CT_StyleMatrixReference
+ break;
+
+ case NMSP_PPT|XML_clrMap: // CT_ColorMapping
+ {
+ oox::drawingml::ClrMapPtr pClrMapPtr( new oox::drawingml::ClrMap() );
+ xRet.set( new oox::drawingml::clrMapContext( this, xAttribs, *pClrMapPtr.get() ) );
+ mpSlidePersistPtr->setClrMap( pClrMapPtr );
+ }
+ break;
+ case NMSP_PPT|XML_clrMapOvr: // CT_ColorMappingOverride
+ case NMSP_PPT|XML_sldLayoutIdLst: // CT_SlideLayoutIdList
+ break;
+ case NMSP_PPT|XML_txStyles: // CT_SlideMasterTextStyles
+ xRet.set( new SlideMasterTextStylesContext( this, mpSlidePersistPtr ) );
+ break;
+ case NMSP_PPT|XML_custDataLst: // CT_CustomerDataList
+ case NMSP_PPT|XML_tagLst: // CT_TagList
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+}
+
+void SAL_CALL SlideFragmentHandler::endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
+{
+ try
+ {
+ Reference< XDrawPage > xSlide( mpSlidePersistPtr->getPage() );
+ if( !maSlideProperties.empty() )
+ {
+ uno::Reference< beans::XMultiPropertySet > xMSet( xSlide, uno::UNO_QUERY );
+ if( xMSet.is() )
+ {
+ uno::Sequence< OUString > aNames;
+ uno::Sequence< uno::Any > aValues;
+ maSlideProperties.makeSequence( aNames, aValues );
+ xMSet->setPropertyValues( aNames, aValues);
+ }
+ else
+ {
+ uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );
+
+ for( PropertyMap::const_iterator aIter( maSlideProperties.begin() ); aIter != maSlideProperties.end(); aIter++ )
+ {
+ if ( xInfo->hasPropertyByName( (*aIter).first ) )
+ xSet->setPropertyValue( (*aIter).first, (*aIter).second );
+ }
+ }
+ }
+ if ( maSlideName.getLength() )
+ {
+ Reference< XNamed > xNamed( xSlide, UNO_QUERY );
+ if( xNamed.is() )
+ xNamed->setName( maSlideName );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( false,
+ (rtl::OString("oox::ppt::SlideFragmentHandler::EndElement(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+}
+
+} }
+
diff --git a/oox/source/ppt/slidemastertextstylescontext.cxx b/oox/source/ppt/slidemastertextstylescontext.cxx
new file mode 100644
index 000000000000..6a389131eb03
--- /dev/null
+++ b/oox/source/ppt/slidemastertextstylescontext.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: slidemastertextstylescontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textliststyle.hxx"
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/ppt/slidemastertextstylescontext.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+SlideMasterTextStylesContext::SlideMasterTextStylesContext( const ::oox::core::FragmentHandlerRef& xHandler, SlidePersistPtr pSlidePersistPtr )
+: Context( xHandler )
+, mpSlidePersistPtr( pSlidePersistPtr )
+{
+}
+
+SlideMasterTextStylesContext::~SlideMasterTextStylesContext()
+{
+}
+
+Reference< XFastContextHandler > SlideMasterTextStylesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& /* xAttribs */ ) throw (SAXException, RuntimeException)
+{
+ oox::drawingml::TextListStylePtr aTextListStylePtr;
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_titleStyle:
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getTitleTextStyle();
+ break;
+ }
+ case NMSP_PPT|XML_bodyStyle:
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getBodyTextStyle();
+ break;
+ }
+ case NMSP_PPT|XML_notesStyle:
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getNotesTextStyle();
+ break;
+ }
+ case NMSP_PPT|XML_otherStyle:
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getOtherTextStyle();
+ break;
+ }
+ }
+ if ( aTextListStylePtr )
+ xRet.set( new oox::drawingml::TextListStyleContext( getHandler(), *(aTextListStylePtr.get()) ) );
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx
new file mode 100644
index 000000000000..b397b4cb3d59
--- /dev/null
+++ b/oox/source/ppt/slidepersist.cxx
@@ -0,0 +1,320 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: slidepersist.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <boost/bind.hpp>
+#include "oox/ppt/timenode.hxx"
+#include "oox/ppt/pptshape.hxx"
+#include "oox/ppt/slidepersist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::animations;
+
+namespace oox { namespace ppt {
+
+SlidePersist::SlidePersist( sal_Bool bMaster, sal_Bool bNotes,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& rxPage,
+ oox::drawingml::ShapePtr pShapesPtr, const drawingml::TextListStylePtr & pDefaultTextStyle )
+: mpDrawingPtr( new oox::vml::Drawing )
+, mxPage( rxPage )
+, maShapesPtr( pShapesPtr )
+, mnLayoutValueToken( 0 )
+, mbMaster( bMaster )
+, mbNotes ( bNotes )
+, maDefaultTextStylePtr( pDefaultTextStyle )
+, maTitleTextStylePtr( new oox::drawingml::TextListStyle )
+, maBodyTextStylePtr( new oox::drawingml::TextListStyle )
+, maNotesTextStylePtr( new oox::drawingml::TextListStyle )
+, maOtherTextStylePtr( new oox::drawingml::TextListStyle )
+{
+}
+
+SlidePersist::~SlidePersist()
+{
+
+}
+
+sal_Int16 SlidePersist::getLayoutFromValueToken()
+{
+ sal_Int16 nLayout = 20; // 20 == blanc (so many magic numbers :-( the description at com.sun.star.presentation.DrawPage.Layout does not help)
+ switch( mnLayoutValueToken )
+ {
+ case XML_blank: nLayout = 20; break;
+ case XML_chart: nLayout = 2; break;
+ case XML_chartAndTx: nLayout = 7; break;
+ case XML_clipArtAndTx: nLayout = 9; break;
+ case XML_clipArtAndVertTx: nLayout = 24; break;
+ case XML_fourObj: nLayout = 18; break;
+ case XML_obj: nLayout = 11; break;
+ case XML_objAndTx: nLayout = 13; break;
+ case XML_objOverTx: nLayout = 14; break;
+ case XML_tbl: nLayout = 8; break;
+ case XML_title: nLayout = 0; break;
+ case XML_titleOnly: nLayout = 19; break;
+ case XML_twoObj:
+ case XML_twoColTx: nLayout = 3; break;
+ case XML_twoObjAndTx: nLayout = 15; break;
+ case XML_twoObjOverTx: nLayout = 16; break;
+ case XML_tx: nLayout = 1; break;
+ case XML_txAndChart: nLayout = 4; break;
+ case XML_txAndClipArt: nLayout = 6; break;
+ case XML_txAndMedia: nLayout = 6; break;
+ case XML_txAndObj: nLayout = 10; break;
+ case XML_txAndTwoObj: nLayout = 12; break;
+ case XML_txOverObj: nLayout = 17; break;
+ case XML_vertTitleAndTx: nLayout = 22; break;
+ case XML_vertTitleAndTxOverChart: nLayout = 21; break;
+ case XML_vertTx: nLayout = 23; break;
+
+ case XML_twoTxTwoObj:
+ case XML_twoObjAndObj:
+ case XML_objTx:
+ case XML_picTx:
+ case XML_secHead:
+ case XML_objOnly:
+ case XML_objAndTwoObj:
+ case XML_mediaAndTx:
+ case XML_dgm:
+ case XML_cust:
+ default:
+ nLayout = 20;
+ }
+ return nLayout;
+}
+
+void SlidePersist::createXShapes( const oox::core::XmlFilterBase& rFilterBase, Reference< frame::XModel > xModel )
+{
+ applyTextStyles( xModel );
+
+ Reference< XShapes > xShapes( getPage(), UNO_QUERY );
+
+ std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChilds() );
+ std::vector< oox::drawingml::ShapePtr >::iterator aShapesIter( rShapes.begin() );
+ while( aShapesIter != rShapes.end() )
+ {
+ std::vector< oox::drawingml::ShapePtr >& rChilds( (*aShapesIter++)->getChilds() );
+ std::vector< oox::drawingml::ShapePtr >::iterator aChildIter( rChilds.begin() );
+ while( aChildIter != rChilds.end() )
+ {
+ PPTShape* pPPTShape = dynamic_cast< PPTShape* >( (*aChildIter).get() );
+ if ( pPPTShape )
+ pPPTShape->addShape( rFilterBase, xModel, *this, getTheme(), getShapeMap(), xShapes, NULL );
+ else
+ (*aChildIter)->addShape( rFilterBase, xModel, getTheme(), getShapeMap(), xShapes, NULL );
+
+ aChildIter++;
+ }
+ }
+
+ Reference< XAnimationNodeSupplier > xNodeSupplier( getPage(), UNO_QUERY);
+ if( xNodeSupplier.is() )
+ {
+ Reference< XAnimationNode > xNode( xNodeSupplier->getAnimationNode() );
+ if( xNode.is() && !maTimeNodeList.empty() )
+ {
+ SlidePersistPtr pSlidePtr( shared_from_this() );
+ TimeNodePtr pNode(maTimeNodeList.front());
+ OSL_ENSURE( pNode, "pNode" );
+
+ pNode->setNode( xModel, xNode, pSlidePtr );
+ }
+ }
+}
+
+void SlidePersist::createBackground( const oox::core::XmlFilterBase& rFilterBase )
+{
+ if ( mpBackgroundPropertiesPtr )
+ {
+ try
+ {
+ PropertyMap aPropMap;
+ static const rtl::OUString sBackground( RTL_CONSTASCII_USTRINGPARAM( "Background" ) );
+ uno::Reference< beans::XPropertySet > xPagePropSet( mxPage, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xPropertySet( aPropMap.makePropertySet() );
+ mpBackgroundPropertiesPtr->pushToPropSet( rFilterBase, xPropertySet );
+ xPagePropSet->setPropertyValue( sBackground, Any( xPropertySet ) );
+ }
+ catch( Exception )
+ {
+ }
+ }
+}
+
+void setTextStyle( Reference< beans::XPropertySet >& rxPropSet,
+ oox::drawingml::TextListStylePtr& pTextListStylePtr, int nLevel )
+{
+ ::oox::drawingml::TextParagraphPropertiesPtr pTextParagraphPropertiesPtr( pTextListStylePtr->getListStyle()[ nLevel ] );
+ if( pTextParagraphPropertiesPtr == NULL )
+ {
+ // no properties. return
+ return;
+ }
+ ::oox::drawingml::TextCharacterPropertiesPtr pTextCharacterPropertiesPtr( pTextParagraphPropertiesPtr->getTextCharacterProperties() );
+ if( pTextCharacterPropertiesPtr == NULL )
+ {
+ // no properties. return
+ return;
+ }
+ PropertyMap& rParagraphProperties( pTextParagraphPropertiesPtr->getTextParagraphPropertyMap() );
+ PropertyMap& rCharacterProperties( pTextCharacterPropertiesPtr->getTextCharacterPropertyMap() );
+
+ int i;
+ Sequence< rtl::OUString > aNames;
+ Sequence< Any > aValues;
+ rParagraphProperties.makeSequence( aNames, aValues );
+ for( i = 0; i < aNames.getLength(); i++ )
+ rxPropSet->setPropertyValue( aNames[ i ], aValues[ i ] );
+ rCharacterProperties.makeSequence( aNames, aValues );
+ for( i = 0; i < aNames.getLength(); i++ )
+ rxPropSet->setPropertyValue( aNames[ i ], aValues[ i ] );
+}
+
+void SlidePersist::applyTextStyles( Reference< frame::XModel > xModel )
+{
+ if ( mbMaster )
+ {
+ try
+ {
+ Reference< style::XStyleFamiliesSupplier > aXStyleFamiliesSupplier( xModel, UNO_QUERY_THROW );
+ Reference< container::XNameAccess > aXNameAccess( aXStyleFamiliesSupplier->getStyleFamilies() );
+ Reference< container::XNamed > aXNamed( mxPage, UNO_QUERY_THROW );
+
+ if ( aXNameAccess.is() && aXNamed.is() )
+ {
+ oox::drawingml::TextListStylePtr pTextListStylePtr;
+ rtl::OUString aStyle;
+ rtl::OUString aFamily;
+
+ const rtl::OUString sOutline( RTL_CONSTASCII_USTRINGPARAM( "outline1" ) );
+ const rtl::OUString sTitle( RTL_CONSTASCII_USTRINGPARAM( "title" ) );
+ const rtl::OUString sStandard( RTL_CONSTASCII_USTRINGPARAM( "standard" ) );
+ const rtl::OUString sSubtitle( RTL_CONSTASCII_USTRINGPARAM( "subtitle" ) );
+
+ for( int i = 0; i < 4; i++ ) // todo: aggregation of bodystyle (subtitle)
+ {
+ switch( i )
+ {
+ case 0 : // title style
+ {
+ pTextListStylePtr = maTitleTextStylePtr;
+ aStyle = sTitle;
+ aFamily= aXNamed->getName();
+ break;
+ }
+ case 1 : // body style
+ {
+ pTextListStylePtr = maBodyTextStylePtr;
+ aStyle = sOutline;
+ aFamily= aXNamed->getName();
+ break;
+ }
+ case 3 : // notes style
+ {
+ pTextListStylePtr = maNotesTextStylePtr;
+ aStyle = sTitle;
+ aFamily= aXNamed->getName();
+ break;
+ }
+ case 4 : // standard style
+ {
+ pTextListStylePtr = maOtherTextStylePtr;
+ aStyle = sStandard;
+ aFamily = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "graphics" ) );
+ break;
+ }
+ case 5 : // subtitle
+ {
+ pTextListStylePtr = maBodyTextStylePtr;
+ aStyle = sSubtitle;
+ aFamily = aXNamed->getName();
+ break;
+ }
+ }
+ Reference< container::XNameAccess > xFamilies;
+ if ( aXNameAccess->hasByName( aFamily ) )
+ {
+ if( aXNameAccess->getByName( aFamily ) >>= xFamilies )
+ {
+ if ( xFamilies->hasByName( aStyle ) )
+ {
+ Reference< style::XStyle > aXStyle;
+ if ( xFamilies->getByName( aStyle ) >>= aXStyle )
+ {
+ Reference< beans::XPropertySet > xPropSet( aXStyle, UNO_QUERY_THROW );
+ setTextStyle( xPropSet, maDefaultTextStylePtr, 0 );
+ setTextStyle( xPropSet, pTextListStylePtr, 0 );
+ for ( int nLevel = 1; nLevel < 5; nLevel++ )
+ {
+ if ( i == 1 /* BodyStyle */ )
+ {
+ sal_Char pOutline[ 9 ] = "outline1";
+ pOutline[ 7 ] = static_cast< sal_Char >( '1' + i );
+ rtl::OUString sOutlineStyle( rtl::OUString::createFromAscii( pOutline ) );
+ if ( xFamilies->hasByName( sOutlineStyle ) )
+ {
+ xFamilies->getByName( sOutlineStyle ) >>= aXStyle;
+ if( aXStyle.is() )
+ xPropSet = Reference< beans::XPropertySet >( aXStyle, UNO_QUERY_THROW );
+ }
+ }
+ setTextStyle( xPropSet, maDefaultTextStylePtr, nLevel );
+ setTextStyle( xPropSet, pTextListStylePtr, nLevel );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+} }
+
diff --git a/oox/source/ppt/slidetimingcontext.cxx b/oox/source/ppt/slidetimingcontext.cxx
new file mode 100644
index 000000000000..a0c15363b27c
--- /dev/null
+++ b/oox/source/ppt/slidetimingcontext.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: slidetimingcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/slidetimingcontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include "oox/ppt/backgroundproperties.hxx"
+#include "oox/ppt/slidefragmenthandler.hxx"
+#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/skipcontext.hxx"
+#include "oox/ppt/timenodelistcontext.hxx"
+#include "buildlistcontext.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+
+namespace oox { namespace ppt {
+
+SlideTimingContext::SlideTimingContext( const ::oox::core::FragmentHandlerRef& xHandler, TimeNodePtrList & aTimeNodeList ) throw()
+ : Context( xHandler )
+ , maTimeNodeList( aTimeNodeList )
+{
+}
+
+SlideTimingContext::~SlideTimingContext() throw()
+{
+
+}
+
+void SlideTimingContext::endFastElement( sal_Int32 /*aElement*/ ) throw ( SAXException, RuntimeException)
+{
+}
+
+
+Reference< XFastContextHandler > SlideTimingContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_bldLst:
+ xRet.set( new BuildListContext( getHandler(), xAttribs, maTimeNodeList ) );
+ break;
+ case NMSP_PPT|XML_extLst:
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ case NMSP_PPT|XML_tnLst:
+ // timing nodes
+ {
+ xRet.set( new TimeNodeListContext( getHandler(), maTimeNodeList ) );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+}
+
+void SAL_CALL SlideTimingContext::endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException)
+{
+
+}
+
+} }
+
diff --git a/oox/source/ppt/slidetransition.cxx b/oox/source/ppt/slidetransition.cxx
new file mode 100644
index 000000000000..04f325d4113f
--- /dev/null
+++ b/oox/source/ppt/slidetransition.cxx
@@ -0,0 +1,393 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: slidetransition.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/slidetransition.hxx"
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/presentation/AnimationSpeed.hpp>
+#include <com/sun/star/animations/TransitionType.hpp>
+#include <com/sun/star/animations/TransitionSubType.hpp>
+
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/namespaces.hxx"
+#include "pptfilterhelpers.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+
+namespace oox { namespace ppt {
+
+
+ SlideTransition::SlideTransition()
+ : mnTransitionType( 0 )
+ , mnTransitionSubType( 0 )
+ , mbTransitionDirectionNormal( true )
+ , mnAnimationSpeed( AnimationSpeed_FAST )
+ , mnFadeColor( 0 )
+ , mbMode( true )
+ {
+
+ }
+
+
+ SlideTransition::SlideTransition(const OUString & sFilterName)
+ : mnTransitionType( 0 )
+ , mnTransitionSubType( 0 )
+ , mbTransitionDirectionNormal( true )
+ , mnAnimationSpeed( AnimationSpeed_FAST )
+ , mnFadeColor( 0 )
+ , mbMode( true )
+ {
+ const transition *p = transition::find( sFilterName );
+ if( p )
+ {
+ mnTransitionType = p->mnType;
+ mnTransitionSubType = p->mnSubType;
+ mbTransitionDirectionNormal = p->mbDirection;
+ }
+ }
+
+
+ void SlideTransition::setSlideProperties( PropertyMap & aProps )
+ {
+ try
+ {
+ aProps[ CREATE_OUSTRING( "TransitionType" ) ] = Any( mnTransitionType );
+ aProps[ CREATE_OUSTRING( "TransitionSubtype" ) ] = Any( mnTransitionSubType );
+ aProps[ CREATE_OUSTRING( "TransitionDirection" ) ] = Any( mbTransitionDirectionNormal );
+ aProps[ CREATE_OUSTRING( "Speed" ) ] = Any( mnAnimationSpeed );
+ aProps[ CREATE_OUSTRING( "TransitionFadeColor" ) ] = Any( mnFadeColor );
+ }
+ catch( Exception& )
+ {
+ // should not happen
+ OSL_ENSURE( false, "exception raised" );
+ }
+ }
+
+ void SlideTransition::setTransitionFilterProperties( const Reference< XTransitionFilter > & xFilter )
+ {
+ try
+ {
+ xFilter->setTransition( mnTransitionType );
+ xFilter->setSubtype( mnTransitionSubType );
+ xFilter->setDirection( mbTransitionDirectionNormal );
+ xFilter->setFadeColor( mnFadeColor );
+ xFilter->setMode( mbMode );
+ }
+ catch( Exception& )
+ {
+ // should not happen
+ OSL_ENSURE( false, "exception raised" );
+ }
+ }
+
+
+ void SlideTransition::setOoxTransitionSpeed( sal_Int32 nToken)
+ {
+ switch( nToken )
+ {
+ /* In case you want to use time values in second,
+ * the speed values are located in the PPT97 importer
+ * sd/source/filter/ppt/ppt97animations.cxx:664
+ * (void Ppt97Animation::UpdateCacheData() const)
+ */
+ case XML_fast:
+ mnAnimationSpeed = AnimationSpeed_FAST;
+ break;
+ case XML_med:
+ mnAnimationSpeed = AnimationSpeed_MEDIUM;
+ break;
+ case XML_slow:
+ mnAnimationSpeed = AnimationSpeed_SLOW;
+ break;
+ default:
+ // should not happen. just ignore
+ break;
+ }
+ }
+
+
+
+ sal_Int16 SlideTransition::ooxToOdpEightDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ nOdpDirection = ooxToOdpBorderDirections( nOoxType );
+ if( nOdpDirection == 0 )
+ {
+ nOdpDirection = ooxToOdpCornerDirections( nOoxType );
+ }
+ return nOdpDirection;
+ }
+
+
+ sal_Int16 SlideTransition::ooxToOdpBorderDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ switch( nOoxType )
+ {
+ case XML_d:
+ nOdpDirection = TransitionSubType::FROMTOP;
+ break;
+ case XML_l:
+ nOdpDirection = TransitionSubType::FROMLEFT;
+ break;
+ case XML_r:
+ nOdpDirection = TransitionSubType::FROMRIGHT;
+ break;
+ case XML_u:
+ nOdpDirection = TransitionSubType::FROMBOTTOM;
+ break;
+ default:
+ nOdpDirection= 0;
+ break;
+ }
+ return nOdpDirection;
+ }
+
+ sal_Int16 SlideTransition::ooxToOdpCornerDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ switch( nOoxType )
+ {
+ case XML_lu:
+ nOdpDirection = TransitionSubType::FROMBOTTOMRIGHT;
+ break;
+ case XML_ru:
+ nOdpDirection = TransitionSubType::FROMBOTTOMLEFT;
+ break;
+ case XML_ld:
+ nOdpDirection = TransitionSubType::FROMTOPRIGHT;
+ break;
+ case XML_rd:
+ nOdpDirection = TransitionSubType::FROMTOPLEFT;
+ break;
+ default:
+ nOdpDirection = 0;
+ break;
+ }
+ return nOdpDirection;
+ }
+
+
+ sal_Int16 SlideTransition::ooxToOdpDirection( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDir;
+ switch( nOoxType )
+ {
+ case XML_vert:
+ nOdpDir = TransitionSubType::VERTICAL;
+ break;
+ case XML_horz:
+ nOdpDir = TransitionSubType::HORIZONTAL;
+ break;
+ default:
+ nOdpDir = 0;
+ break;
+ }
+ return nOdpDir;
+ }
+
+ void SlideTransition::setOoxTransitionType( ::sal_Int32 OoxType, ::sal_Int32 param1, ::sal_Int32 param2 )
+ {
+ switch( OoxType )
+ {
+ case NMSP_PPT|XML_blinds:
+ mnTransitionType = TransitionType::BLINDSWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ break;
+ case NMSP_PPT|XML_checker:
+ mnTransitionType = TransitionType::CHECKERBOARDWIPE;
+ switch ( param1 )
+ {
+ case XML_vert:
+ mnTransitionSubType = TransitionSubType::DOWN;
+ break;
+ case XML_horz:
+ mnTransitionSubType = TransitionSubType::ACROSS;
+ break;
+ default:
+ break;
+ }
+ break;
+ case NMSP_PPT|XML_comb:
+ mnTransitionType = TransitionType::PUSHWIPE;
+ switch( param1 )
+ {
+ case XML_vert:
+ mnTransitionSubType = TransitionSubType::COMBVERTICAL;
+ break;
+ case XML_horz:
+ mnTransitionSubType = TransitionSubType::COMBHORIZONTAL;
+ break;
+ default:
+ break;
+ }
+ break;
+ case NMSP_PPT|XML_cover:
+ mnTransitionType = TransitionType::SLIDEWIPE;
+ mnTransitionSubType = ooxToOdpEightDirections( param1 );
+ break;
+ case NMSP_PPT|XML_pull: // uncover
+ mnTransitionType = TransitionType::SLIDEWIPE;
+ mnTransitionSubType = ooxToOdpEightDirections( param1 );
+ mbTransitionDirectionNormal = false;
+ break;
+ case NMSP_PPT|XML_cut:
+ // The binfilter seems to ignore this transition.
+ // Fade to black instead if thrBlk is true.
+ if( param1 )
+ {
+ mnTransitionType = TransitionType::FADE;
+ mnTransitionSubType = TransitionSubType::FADEOVERCOLOR;
+ }
+ OSL_TRACE( "OOX: cut transition fallback." );
+ break;
+ case NMSP_PPT|XML_fade:
+ mnTransitionType = TransitionType::FADE;
+ if( param1 )
+ {
+ mnTransitionSubType = TransitionSubType::FADEOVERCOLOR;
+ }
+ else
+ {
+ mnTransitionSubType = TransitionSubType::CROSSFADE;
+ }
+ break;
+ case NMSP_PPT|XML_push:
+ mnTransitionType = TransitionType::PUSHWIPE;
+ mnTransitionSubType = ooxToOdpBorderDirections( param1 );
+ break;
+ case NMSP_PPT|XML_wipe:
+ mnTransitionType = TransitionType::BARWIPE;
+ mnTransitionSubType = ooxToOdpBorderDirections( param1 );
+ break;
+ case NMSP_PPT|XML_split:
+ mnTransitionType = TransitionType::BARNDOORWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ if( param2 == XML_in )
+ {
+ // reverse
+ mbTransitionDirectionNormal = false;
+ }
+ break;
+ case NMSP_PPT|XML_wheel:
+ mnTransitionType = TransitionType::PINWHEELWIPE;
+ switch( param1 )
+ {
+ case 1:
+ mnTransitionSubType = TransitionSubType::ONEBLADE;
+ break;
+ case 2:
+ mnTransitionSubType = TransitionSubType::TWOBLADEVERTICAL;
+ break;
+ case 3:
+ mnTransitionSubType = TransitionSubType::THREEBLADE;
+ break;
+ case 4:
+ mnTransitionSubType = TransitionSubType::FOURBLADE;
+ break;
+ case 8:
+ mnTransitionSubType = TransitionSubType::EIGHTBLADE;
+ break;
+ default:
+ OSL_TRACE( "OOX: strange number of blades for thw wheel-wipe %d", param1 );
+ if( param1 > 8 )
+ {
+ mnTransitionSubType = TransitionSubType::EIGHTBLADE;
+ }
+ else if( param1 > 4 )
+ {
+ mnTransitionSubType = TransitionSubType::FOURBLADE;
+ }
+ else if( param1 == 0)
+ {
+ mnTransitionSubType = TransitionSubType::ONEBLADE;
+ }
+ break;
+ }
+ break;
+ case NMSP_PPT|XML_randomBar:
+ mnTransitionType = TransitionType::RANDOMBARWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ break;
+ case NMSP_PPT|XML_circle:
+ mnTransitionType = TransitionType::ELLIPSEWIPE;
+ mnTransitionSubType = TransitionSubType::CIRCLE;
+ break;
+ case NMSP_PPT|XML_diamond:
+ mnTransitionType = TransitionType::IRISWIPE;
+ mnTransitionSubType = TransitionSubType::DIAMOND;
+ break;
+ case NMSP_PPT|XML_dissolve:
+ mnTransitionType = TransitionType::DISSOLVE;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ case NMSP_PPT|XML_newsflash:
+ // this is what the PPT binary filter does.... not sure I agree.
+ mnTransitionType = TransitionType::FOURBOXWIPE;
+ mnTransitionSubType = TransitionSubType::CORNERSOUT;
+ break;
+ case NMSP_PPT|XML_plus:
+ mnTransitionType = TransitionType::FOURBOXWIPE;
+ mnTransitionSubType = TransitionSubType::CORNERSOUT;
+ break;
+ case NMSP_PPT|XML_random:
+ mnTransitionType = TransitionType::RANDOM;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ case NMSP_PPT|XML_wedge:
+ mnTransitionType = TransitionType::FANWIPE;
+ mnTransitionSubType = TransitionSubType::CENTERTOP;
+ break;
+ case NMSP_PPT|XML_zoom:
+ mnTransitionType = TransitionType::ZOOM;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ default:
+ mnTransitionType = 0;
+ break;
+ }
+ }
+
+
+} }
diff --git a/oox/source/ppt/slidetransitioncontext.cxx b/oox/source/ppt/slidetransitioncontext.cxx
new file mode 100644
index 000000000000..c26067b9fa69
--- /dev/null
+++ b/oox/source/ppt/slidetransitioncontext.cxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: slidetransitioncontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/slidetransitioncontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include <oox/ppt/backgroundproperties.hxx>
+#include "oox/ppt/slidefragmenthandler.hxx"
+#include "oox/ppt/soundactioncontext.hxx"
+#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/skipcontext.hxx"
+
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+
+namespace oox { namespace ppt {
+
+
+SlideTransitionContext::SlideTransitionContext( const FragmentHandlerRef& xHandler, const Reference< XFastAttributeList >& xAttribs, PropertyMap & aProperties ) throw()
+: Context( xHandler )
+, maSlideProperties( aProperties )
+, mbHasTransition( sal_False )
+{
+ AttributeList attribs(xAttribs);
+
+ // ST_TransitionSpeed
+ maTransition.setOoxTransitionSpeed( xAttribs->getOptionalValueToken( XML_spd, XML_fast ) );
+
+ // TODO
+ attribs.getBool( XML_advClick, true );
+
+ // careful. if missing, no auto advance... 0 looks like a valid value
+ // for auto advance
+ if(attribs.hasAttribute( XML_advTm ))
+ {
+ // TODO
+ xAttribs->getOptionalValue( XML_advTm );
+ }
+}
+
+SlideTransitionContext::~SlideTransitionContext() throw()
+{
+
+}
+
+Reference< XFastContextHandler > SlideTransitionContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_blinds:
+ case NMSP_PPT|XML_checker:
+ case NMSP_PPT|XML_comb:
+ case NMSP_PPT|XML_randomBar:
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, xAttribs->getOptionalValueToken( XML_dir, XML_horz ), 0);
+ // ST_Direction { XML_horz, XML_vert }
+ }
+ break;
+ case NMSP_PPT|XML_cover:
+ case NMSP_PPT|XML_pull:
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, xAttribs->getOptionalValueToken( XML_dir, XML_l ), 0 );
+ // ST_TransitionEightDirectionType { ST_TransitionSideDirectionType {
+ // XML_d, XML_d, XML_r, XML_u },
+ // ST_TransitionCornerDirectionType {
+ // XML_ld, XML_lu, XML_rd, XML_ru }
+ }
+ break;
+ case NMSP_PPT|XML_cut:
+ case NMSP_PPT|XML_fade:
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ AttributeList attribs(xAttribs);
+ // CT_OptionalBlackTransition xdb:bool
+ maTransition.setOoxTransitionType( aElementToken, attribs.getBool( XML_thruBlk, false ), 0);
+ }
+ break;
+ case NMSP_PPT|XML_push:
+ case NMSP_PPT|XML_wipe:
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, xAttribs->getOptionalValueToken( XML_dir, XML_l ), 0 );
+ // ST_TransitionSideDirectionType { XML_d, XML_l, XML_r, XML_u }
+ }
+ break;
+ case NMSP_PPT|XML_split:
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, xAttribs->getOptionalValueToken( XML_orient, XML_horz ), xAttribs->getOptionalValueToken( XML_dir, XML_out ) );
+ // ST_Direction { XML_horz, XML_vert }
+ // ST_TransitionInOutDirectionType { XML_out, XML_in }
+ }
+ break;
+ case NMSP_PPT|XML_zoom:
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, xAttribs->getOptionalValueToken( XML_dir, XML_out ), 0 );
+ // ST_TransitionInOutDirectionType { XML_out, XML_in }
+ }
+ break;
+ case NMSP_PPT|XML_wheel:
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ AttributeList attribs(xAttribs);
+ maTransition.setOoxTransitionType( aElementToken, attribs.getUnsignedInteger( XML_spokes, 4 ), 0 );
+ // unsignedInt
+ }
+ break;
+ case NMSP_PPT|XML_circle:
+ case NMSP_PPT|XML_diamond:
+ case NMSP_PPT|XML_dissolve:
+ case NMSP_PPT|XML_newsflash:
+ case NMSP_PPT|XML_plus:
+ case NMSP_PPT|XML_random:
+ case NMSP_PPT|XML_wedge:
+ // CT_Empty
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, 0, 0 );
+ }
+ break;
+
+
+ case NMSP_PPT|XML_sndAc: // CT_TransitionSoundAction
+ //"Sound"
+ xRet.set( new SoundActionContext ( this->getHandler(), maSlideProperties ) );
+ break;
+ case NMSP_PPT|XML_extLst: // CT_OfficeArtExtensionList
+ xRet.set( new SkipContext( getHandler() ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+}
+
+void SlideTransitionContext::endFastElement( sal_Int32 aElement ) throw (::com::sun::star::xml::sax::SAXException, RuntimeException)
+{
+ if( aElement == (NMSP_PPT|XML_transition) )
+ {
+ if( mbHasTransition )
+ {
+ maTransition.setSlideProperties( maSlideProperties );
+ mbHasTransition = false;
+ }
+ }
+}
+
+
+} }
+
diff --git a/oox/source/ppt/soundactioncontext.cxx b/oox/source/ppt/soundactioncontext.cxx
new file mode 100644
index 000000000000..b5e8c3dbd84d
--- /dev/null
+++ b/oox/source/ppt/soundactioncontext.cxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: soundactioncontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/soundactioncontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/embeddedwavaudiofile.hxx"
+#include "tokens.hxx"
+
+using rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
+
+namespace oox { namespace ppt {
+
+
+ SoundActionContext::SoundActionContext( const FragmentHandlerRef& xHandler, PropertyMap & aProperties ) throw()
+ : Context( xHandler )
+ , maSlideProperties( aProperties )
+ , mbHasStartSound( false )
+ , mbLoopSound( false )
+ , mbStopSound( false )
+ {
+ }
+
+
+ SoundActionContext::~SoundActionContext() throw()
+ {
+ }
+
+
+ void SoundActionContext::endFastElement( sal_Int32 aElement ) throw (SAXException, RuntimeException)
+ {
+ if ( aElement == ( NMSP_PPT|XML_sndAc ) )
+ {
+ if( mbHasStartSound )
+ {
+ OUString url;
+ // TODO this is very wrong
+ if ( msSndName.getLength() != 0 )
+ {
+ // try the builtIn version
+ url = msSndName;
+ }
+#if 0 // OOo does not support embedded data yet
+ else if ( msEmbedded.getLength() != 0 )
+ {
+ RelationsRef xRel = getHandler()->getRelations();
+ url = xRel->getRelationById( msEmbedded )->msTarget;
+ }
+ else if ( msLink.getLength() != 0 )
+ {
+ url = msLink;
+ }
+#endif
+ if ( url.getLength() != 0 )
+ {
+ maSlideProperties[ CREATE_OUSTRING( "Sound" ) ] = Any( url );
+ maSlideProperties[ CREATE_OUSTRING( "SoundOn" ) ] = Any( sal_True );
+ }
+ }
+// else if( mbStopSound )
+// {
+// maSlideProperties[ CREATE_OUSTRING( "" ) ] = Any( sal_True );
+// }
+ }
+ }
+
+
+ Reference< XFastContextHandler > SoundActionContext::createFastChildContext( ::sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+ AttributeList attribs(xAttribs);
+
+ switch( aElement )
+ {
+ case NMSP_PPT|XML_snd:
+ if( mbHasStartSound )
+ {
+ drawingml::EmbeddedWAVAudioFile aAudio;
+ drawingml::getEmbeddedWAVAudioFile( getHandler(), xAttribs, aAudio);
+
+ msSndName = ( aAudio.mbBuiltIn ? aAudio.msName : aAudio.msLink );
+ }
+ break;
+ case NMSP_PPT|XML_endSnd:
+ // CT_Empty
+ mbStopSound = true;
+ break;
+ case NMSP_PPT|XML_stSnd:
+ mbHasStartSound = true;
+ mbLoopSound = attribs.getBool( XML_loop, false );
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+
+
+} }
diff --git a/oox/source/ppt/timeanimvaluecontext.cxx b/oox/source/ppt/timeanimvaluecontext.cxx
new file mode 100644
index 000000000000..1fc6b462690a
--- /dev/null
+++ b/oox/source/ppt/timeanimvaluecontext.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timeanimvaluecontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:00 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+
+#include "timeanimvaluecontext.hxx"
+
+#include "oox/core/namespaces.hxx"
+#include "animvariantcontext.hxx"
+
+#include "tokens.hxx"
+
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+ TimeAnimValueListContext::TimeAnimValueListContext( const FragmentHandlerRef& xHandler,
+ const Reference< XFastAttributeList >& /*xAttribs*/,
+ TimeAnimationValueList & aTavList )
+ : Context( xHandler )
+ , maTavList( aTavList )
+ , mbInValue( false )
+ {
+ }
+
+
+ TimeAnimValueListContext::~TimeAnimValueListContext( )
+ {
+ }
+
+
+ void SAL_CALL TimeAnimValueListContext::endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ if( aElement == ( NMSP_PPT|XML_tav ) )
+ {
+ mbInValue = false;
+ }
+ }
+
+
+ Reference< XFastContextHandler > SAL_CALL TimeAnimValueListContext::createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_tav:
+ {
+ mbInValue = true;
+ TimeAnimationValue val;
+ val.msFormula = xAttribs->getOptionalValue( XML_fmla );
+ val.msTime = xAttribs->getOptionalValue( XML_tm );
+ maTavList.push_back( val );
+ break;
+ }
+ case NMSP_PPT|XML_val:
+ if( mbInValue )
+ {
+ // CT_TLAnimVariant
+ xRet.set( new AnimVariantContext( getHandler(), aElementToken, maTavList.back().maValue ) );
+ }
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+
+} }
diff --git a/oox/source/ppt/timeanimvaluecontext.hxx b/oox/source/ppt/timeanimvaluecontext.hxx
new file mode 100644
index 000000000000..912a5c8176dd
--- /dev/null
+++ b/oox/source/ppt/timeanimvaluecontext.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timeanimvaluecontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:01 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_TIMEANIMVALUELISTCONTEXT
+#define OOX_PPT_TIMEANIMVALUELISTCONTEXT
+
+#include "oox/core/context.hxx"
+#include "oox/ppt/animationspersist.hxx"
+
+namespace oox { namespace ppt {
+
+ /** CT_TLTimeAnimateValueList */
+ class TimeAnimValueListContext
+ : public ::oox::core::Context
+ {
+ public:
+ TimeAnimValueListContext( const ::oox::core::FragmentHandlerRef& xHandler,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ TimeAnimationValueList & aTavList );
+
+ ~TimeAnimValueListContext( );
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& /*xAttribs*/ ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+
+ private:
+ TimeAnimationValueList & maTavList;
+ bool mbInValue;
+ };
+
+
+
+
+} }
+
+#endif
diff --git a/oox/source/ppt/timenode.cxx b/oox/source/ppt/timenode.cxx
new file mode 100644
index 000000000000..b14e02d8487c
--- /dev/null
+++ b/oox/source/ppt/timenode.cxx
@@ -0,0 +1,635 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timenode.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:01 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/timenode.hxx"
+
+#include <boost/bind.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/animations/XAnimateColor.hpp>
+#include <com/sun/star/animations/XAnimateMotion.hpp>
+#include <com/sun/star/animations/XAnimateTransform.hpp>
+#include <com/sun/star/animations/XCommand.hpp>
+#include <com/sun/star/animations/XIterateContainer.hpp>
+#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+#include <com/sun/star/animations/XTimeContainer.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
+#include <com/sun/star/animations/Event.hpp>
+#include <com/sun/star/animations/EventTrigger.hpp>
+#include <com/sun/star/presentation/EffectNodeType.hpp>
+
+#include "oox/helper/helper.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::presentation;
+
+namespace oox { namespace ppt {
+
+ OUString TimeNode::getServiceName( sal_Int16 nNodeType )
+ {
+ OUString sServiceName;
+ switch( nNodeType )
+ {
+ case AnimationNodeType::PAR:
+// sServiceName = CREATE_OUSTRING("com.sun.star.animations.IterateContainer");
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.ParallelTimeContainer");
+ break;
+ case AnimationNodeType::SEQ:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.SequenceTimeContainer");
+ break;
+ case AnimationNodeType::ANIMATE:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.Animate");
+ break;
+ case AnimationNodeType::ANIMATECOLOR:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateColor");
+ break;
+ case AnimationNodeType::TRANSITIONFILTER:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.TransitionFilter");
+ break;
+ case AnimationNodeType::ANIMATEMOTION:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateMotion");
+ break;
+ case AnimationNodeType::ANIMATETRANSFORM:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateTransform");
+ break;
+ case AnimationNodeType::COMMAND:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.Command");
+ break;
+ case AnimationNodeType::SET:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateSet");
+ break;
+ case AnimationNodeType::AUDIO:
+ sServiceName = CREATE_OUSTRING("com.sun.star.animations.Audio");
+ break;
+ default:
+ OSL_TRACE( "OOX: uhandled type %x", nNodeType );
+ break;
+ }
+ return sServiceName;
+ }
+
+
+
+ TimeNode::TimeNode( sal_Int16 nNodeType )
+ : mnNodeType( nNodeType )
+ , mbHasEndSyncValue( false )
+ {
+ }
+
+
+ TimeNode::~TimeNode()
+ {
+ }
+
+// BEGIN CUT&PASTE from sd/source/filter/ppt/pptinanimations.hxx
+// --------------------------------------------------------------------
+ static void fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
+ {
+ try
+ {
+ bool bFirst = true;
+ Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
+ while( xE->hasMoreElements() )
+ {
+ // click node
+ Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
+
+ Event aEvent;
+ aEvent.Trigger = EventTrigger::ON_NEXT;
+ aEvent.Repeat = 0;
+ xClickNode->setBegin( makeAny( aEvent ) );
+
+ if( bFirst )
+ {
+ bFirst = false;
+ Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW );
+ if( xE2->hasMoreElements() )
+ {
+ // with node
+ xE2->nextElement() >>= xEA2;
+ if( xEA2.is() )
+ xE2.query( xEA2->createEnumeration() );
+ else
+ xE2.clear();
+
+ if( xE2.is() && xE2->hasMoreElements() )
+ {
+ Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
+ const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
+ const NamedValue* p = aUserData.getConstArray();
+ sal_Int32 nLength = aUserData.getLength();
+ while( nLength-- )
+ {
+ if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) )
+ {
+ sal_Int16 nNodeType = 0;
+ p->Value >>= nNodeType;
+ if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK )
+ {
+ // first effect does not start on click, so correct
+ // first click nodes begin to 0s
+ xClickNode->setBegin( makeAny( (double)0.0 ) );
+ break;
+ }
+ }
+ p++;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ OSL_TRACE("fixMainSequenceTiming(), exception caught!" );
+ }
+ }
+
+// --------------------------------------------------------------------
+
+ static void fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
+ {
+ try
+ {
+ Any aBegin( xNode->getBegin() );
+ Any aEmpty;
+ xNode->setBegin( aEmpty );
+
+ Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
+ while( xE->hasMoreElements() )
+ {
+ // click node
+ Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
+ xClickNode->setBegin( aBegin );
+ }
+ }
+ catch( Exception& e )
+ {
+ (void)e;
+ OSL_TRACE("fixInteractiveSequenceTiming(), exception caught!" );
+ }
+ }
+
+// END CUT&PASTE
+
+ void TimeNode::addNode( const Reference< XModel > &rxModel,
+ const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide )
+ {
+ try {
+ OUString sServiceName = getServiceName( mnNodeType );
+ Reference< XAnimationNode > xNode = createAndInsert(sServiceName, rxModel, rxNode );
+ setNode( rxModel, xNode, pSlide );
+ }
+ catch( const Exception& e )
+ {
+ OSL_TRACE( "OOX: exception raised in TimeNode::addNode() - %s",
+ OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+ }
+
+ void TimeNode::setNode( const Reference< XModel > &rxModel,
+ const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide )
+ {
+ OSL_ENSURE( xNode.is(), "null node passed" );
+
+ try {
+ if( msId.getLength() )
+ {
+ pSlide->getAnimNodesMap()[ msId ] = xNode;
+ }
+
+ if( mpTarget )
+ {
+ sal_Int16 nSubType;
+ maNodeProperties[ NP_TARGET ] = mpTarget->convert( pSlide, nSubType );
+ if( mpTarget->mnType == XML_spTgt )
+ {
+ maNodeProperties[ NP_SUBITEM ] <<= nSubType;
+ }
+ }
+
+ if( !maStCondList.empty() )
+ {
+ Any aAny = AnimationCondition::convertList( pSlide, maStCondList );
+ if( aAny.hasValue() )
+ {
+ xNode->setBegin( aAny );
+ }
+
+ }
+ if( !maEndCondList.empty() )
+ {
+ Any aAny = AnimationCondition::convertList( pSlide, maEndCondList );
+ if( aAny.hasValue() )
+ {
+ xNode->setEnd( aAny );
+ }
+ }
+#if 0 // FIXME even the binary filter has this disabled.
+ if( !maNextCondList.empty() )
+ {
+ Any aAny = AnimationCondition::convertList( pSlide, maNextCondList );
+ if( aAny.hasValue() )
+ {
+ xNode->setNext( aAny );
+ }
+ }
+ if( !maPrevCondList.empty() )
+ {
+ Any aAny = AnimationCondition::convertList( pSlide, maPrevCondList );
+ if( aAny.hasValue() )
+ {
+ xNode->setPrev( aAny );
+ }
+ }
+#endif
+ if( mbHasEndSyncValue )
+ {
+ Any aValue = maEndSyncValue.convert( pSlide );
+ xNode->setEndSync(aValue);
+ }
+
+ Sequence< NamedValue > aUserDataSeq;
+ maUserData.makeSequence(aUserDataSeq);
+ if( aUserDataSeq.getLength() )
+ {
+ maNodeProperties[ NP_USERDATA ] = makeAny(aUserDataSeq);
+ }
+
+ Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
+ Reference< XAnimateColor > xAnimateColor( xNode, UNO_QUERY );
+ Reference< XAnimateMotion > xAnimateMotion( xNode, UNO_QUERY );
+ Reference< XAnimateTransform > xAnimateTransform( xNode, UNO_QUERY );
+ Reference< XCommand > xCommand( xNode, UNO_QUERY );
+ Reference< XIterateContainer > xIterateContainer( xNode, UNO_QUERY );
+ sal_Int16 nInt16 = 0;
+ sal_Bool bBool = sal_False;
+ double fDouble = 0;
+ OUString sString;
+ Sequence< NamedValue > aSeq;
+
+ for( int i = 0; i < _NP_SIZE; i++)
+ {
+ Any & aValue( maNodeProperties[ i ] );
+ if( aValue.hasValue() )
+ {
+ switch( i )
+ {
+ case NP_TO:
+ if( xAnimate.is() )
+ xAnimate->setTo( aValue );
+ break;
+ case NP_FROM:
+ if( xAnimate.is() )
+ xAnimate->setFrom( aValue );
+ break;
+ case NP_BY:
+ if( xAnimate.is() )
+ xAnimate->setBy( aValue );
+ break;
+ case NP_TARGET:
+ if( xAnimate.is() )
+ xAnimate->setTarget( aValue );
+ break;
+ case NP_SUBITEM:
+ if( xAnimate.is() )
+ {
+ if( aValue >>= nInt16 )
+ xAnimate->setSubItem( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_ATTRIBUTENAME:
+ if( xAnimate.is() )
+ {
+ if( aValue >>= sString )
+ xAnimate->setAttributeName( sString );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_CALCMODE:
+ if( xAnimate.is() )
+ {
+ if( aValue >>= nInt16 )
+ xAnimate->setCalcMode( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_KEYTIMES:
+ if( xAnimate.is() )
+ {
+ Sequence<double> aKeyTimes;
+ if( aValue >>= aKeyTimes )
+ xAnimate->setKeyTimes(aKeyTimes);
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_VALUES:
+ if( xAnimate.is() )
+ {
+ Sequence<Any> aValues;
+ if( aValue >>= aValues )
+ xAnimate->setValues(aValues);
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_FORMULA:
+ if( xAnimate.is() )
+ {
+ if( aValue >>= sString )
+ xAnimate->setFormula(sString);
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_COLORINTERPOLATION:
+ if( xAnimateColor.is() )
+ {
+ if( aValue >>= nInt16 )
+ xAnimateColor->setColorInterpolation( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_DIRECTION:
+ if( xAnimateColor.is() )
+ {
+ if( aValue >>= bBool )
+ xAnimateColor->setDirection( bBool );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_PATH:
+ if( xAnimateMotion.is() )
+ xAnimateMotion->setPath( aValue );
+ break;
+ case NP_TRANSFORMTYPE:
+ if( xAnimateTransform.is() )
+ {
+ if( aValue >>= nInt16 )
+ xAnimateTransform->setTransformType( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_USERDATA:
+ if( aValue >>= aSeq )
+ xNode->setUserData( aSeq );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ break;
+ case NP_ACCELERATION:
+ if( aValue >>= fDouble )
+ xNode->setAcceleration( fDouble );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ break;
+ case NP_DECELERATE:
+ if( aValue >>= fDouble )
+ xNode->setDecelerate( fDouble );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ break;
+ case NP_AUTOREVERSE:
+ if( aValue >>= bBool )
+ xNode->setAutoReverse( bBool );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ break;
+ case NP_DURATION:
+ xNode->setDuration( aValue );
+ break;
+ case NP_FILL:
+ if( aValue >>= nInt16 )
+ xNode->setFill( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ break;
+ case NP_REPEATCOUNT:
+ xNode->setRepeatCount( aValue );
+ break;
+ case NP_REPEATDURATION:
+ xNode->setRepeatDuration( aValue );
+ break;
+ case NP_RESTART:
+ if( aValue >>= nInt16 )
+ xNode->setRestart( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ break;
+ case NP_COMMAND:
+ if( xCommand.is() )
+ {
+ if( aValue >>= nInt16 )
+ xCommand->setCommand( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_PARAMETER:
+ if( xCommand.is() )
+ xCommand->setParameter( aValue );
+ break;
+ case NP_ITERATETYPE:
+ if( xIterateContainer.is() )
+ {
+ if( aValue >>= nInt16 )
+ xIterateContainer->setIterateType( nInt16 );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ case NP_ITERATEINTERVAL:
+ if( xIterateContainer.is() )
+ {
+ if( aValue >>= fDouble )
+ xIterateContainer->setIterateInterval( fDouble );
+ else
+ {
+ OSL_TRACE( "any >>= failed %d", __LINE__ );
+ }
+ }
+ break;
+ default:
+ OSL_TRACE( "ERR-OOX: unknown prop index %d", i );
+ break;
+ }
+ }
+ }
+
+ if( mnNodeType == AnimationNodeType::TRANSITIONFILTER )
+ {
+
+ Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
+ maTransitionFilter.setTransitionFilterProperties( xFilter );
+ }
+
+ std::for_each( maChilds.begin(), maChilds.end(),
+ boost::bind(&TimeNode::addNode, _1, rxModel, boost::ref(xNode),
+ boost::ref(pSlide) ) );
+
+ switch( mnNodeType )
+ {
+ case AnimationNodeType::SEQ:
+ {
+ sal_Int16 nEnum = 0;
+ if( maUserData[ CREATE_OUSTRING( "node-type" ) ] >>= nEnum )
+ {
+ if( nEnum == EffectNodeType::MAIN_SEQUENCE )
+ {
+ fixMainSequenceTiming( xNode );
+ }
+ else if( nEnum == EffectNodeType::INTERACTIVE_SEQUENCE )
+ {
+ fixInteractiveSequenceTiming( xNode );
+ }
+ }
+ break;
+ }
+ case AnimationNodeType::PAR:
+ // some other cut&paste... from AnimationImporter::importAnimationContainer()
+ break;
+ }
+ }
+ catch( const Exception& e )
+ {
+ OSL_TRACE( "OOX: exception raised in TimeNode::setNode() - %s",
+ OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+ }
+
+
+ Reference< XAnimationNode > TimeNode::createAndInsert( const OUString& rServiceName, const Reference< XModel > &/*rxModel*/,
+ const Reference< XAnimationNode >& rxNode )
+ {
+ try {
+ Reference< XAnimationNode > xNode ( ::comphelper::getProcessServiceFactory()->createInstance(rServiceName ),
+ UNO_QUERY_THROW );
+ Reference< XTimeContainer > xParentContainer( rxNode, UNO_QUERY_THROW );
+
+ xParentContainer->appendChild( xNode );
+ return xNode;
+ }
+ catch( const Exception& e )
+ {
+ OSL_TRACE( "OOX: exception raised in TimeNode::createAndInsert() trying to create a service %s = %s",
+ OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ).getStr(),
+ OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+
+ return Reference< XAnimationNode >();
+ }
+
+
+ void TimeNode::setId( sal_Int32 nId )
+ {
+ msId = OUString::valueOf(nId);
+ }
+
+ void TimeNode::setTo( const Any & aTo )
+ {
+ maNodeProperties[ NP_TO ] = aTo;
+ }
+
+
+ void TimeNode::setFrom( const Any & aFrom )
+ {
+ maNodeProperties[ NP_FROM ] = aFrom;
+ }
+
+ void TimeNode::setBy( const Any & aBy )
+ {
+ maNodeProperties[ NP_BY ] = aBy;
+ }
+
+
+} }
diff --git a/oox/source/ppt/timenodelistcontext.cxx b/oox/source/ppt/timenodelistcontext.cxx
new file mode 100644
index 000000000000..af5822711645
--- /dev/null
+++ b/oox/source/ppt/timenodelistcontext.cxx
@@ -0,0 +1,1181 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timenodelistcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:01 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/ppt/timenodelistcontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+#include <rtl/math.hxx>
+
+#include <com/sun/star/animations/XTimeContainer.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <com/sun/star/animations/XAnimateColor.hpp>
+#include <com/sun/star/animations/XAnimateSet.hpp>
+#include <com/sun/star/animations/XAnimateTransform.hpp>
+#include <com/sun/star/animations/AnimationTransformType.hpp>
+#include <com/sun/star/animations/AnimationCalcMode.hpp>
+#include <com/sun/star/animations/AnimationColorSpace.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
+#include <com/sun/star/animations/XCommand.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/presentation/EffectCommands.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/ppt/slidetransition.hxx"
+#include "tokens.hxx"
+
+#include "animvariantcontext.hxx"
+#include "commonbehaviorcontext.hxx"
+#include "conditioncontext.hxx"
+#include "commontimenodecontext.hxx"
+#include "timeanimvaluecontext.hxx"
+#include "animationtypes.hxx"
+
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::awt;
+using ::com::sun::star::beans::NamedValue;
+
+using ::rtl::OUString;
+
+namespace oox { namespace ppt {
+
+ struct AnimColor
+ {
+ AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
+ : colorSpace( cs ), one( o ), two( t ), three( th )
+ {
+ }
+
+ sal_Int32 get()
+ {
+ sal_Int32 nColor;
+
+ switch( colorSpace )
+ {
+ case AnimationColorSpace::HSL:
+ nColor = ( ( ( one * 128 ) / 360 ) & 0xff ) << 16
+ | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
+ | ( ( ( three * 128 ) / 1000 ) & 0xff );
+ break;
+ case AnimationColorSpace::RGB:
+ nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
+ | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
+ | ( ( ( three * 128 ) / 1000 ) & 0xff );
+ break;
+ default:
+ nColor = 0;
+ break;
+ }
+ return nColor;
+ }
+
+ sal_Int16 colorSpace;
+ sal_Int32 one;
+ sal_Int32 two;
+ sal_Int32 three;
+ };
+
+
+ /** CT_TLMediaNodeAudio
+ CT_TLMediaNodeVideo */
+ class MediaNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ MediaNodeContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ , mbIsNarration( false )
+ , mbFullScrn( false )
+ {
+ AttributeList attribs( xAttribs );
+
+ switch( aElement )
+ {
+ case NMSP_PPT|XML_audio:
+ mbIsNarration = attribs.getBool( XML_isNarration, false );
+ break;
+ case NMSP_PPT|XML_video:
+ mbFullScrn = attribs.getBool( XML_fullScrn, false );
+ break;
+ default:
+ break;
+ }
+ }
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ if( aElement == ( NMSP_PPT|XML_audio ) )
+ {
+ // TODO deal with mbIsNarration
+ }
+ else if( aElement == ( NMSP_PPT|XML_video ) )
+ {
+ // TODO deal with mbFullScrn
+ }
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+ private:
+ bool mbIsNarration;
+ bool mbFullScrn;
+ };
+
+
+ /** CT_TLSetBehavior
+ */
+ class SetTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ SetTimeNodeContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ {
+
+ }
+
+ ~SetTimeNodeContext() throw ()
+ {
+ if( maTo.hasValue() )
+ {
+ // TODO
+ // HACK !!! discard and refactor
+ OUString aString;
+ if( maTo >>= aString )
+ {
+ OSL_TRACE( "Magic conversion %s", OUSTRING_TO_CSTR( aString ) );
+ maTo = makeAny( aString.equalsAscii( "visible" ) ? sal_True : sal_False );
+ if( !maTo.has<sal_Bool>() )
+ OSL_TRACE( "conversion failed" );
+ }
+ mpNode->setTo( maTo );
+ }
+
+ }
+
+ virtual void SAL_CALL endFastElement( sal_Int32 /*aElement*/ )
+ throw ( SAXException, RuntimeException)
+ {
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_to:
+ // CT_TLAnimVariant
+ xRet.set( new AnimVariantContext( getHandler(), aElementToken, maTo ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ private:
+ Any maTo;
+ };
+
+ /** CT_TLCommandBehavior
+ */
+ class CmdTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ CmdTimeNodeContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ , maType(0)
+ {
+ switch ( aElement )
+ {
+ case NMSP_PPT|XML_cmd:
+ msCommand = xAttribs->getOptionalValue( XML_cmd );
+ maType = xAttribs->getOptionalValueToken( XML_type, 0 );
+ break;
+ default:
+ break;
+ }
+ }
+
+ ~CmdTimeNodeContext() throw ()
+ {
+ }
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ if( aElement == ( NMSP_PPT|XML_cmd ) )
+ {
+ try {
+ // see sd/source/filter/ppt/pptinanimations.cxx
+ // in AnimationImporter::importCommandContainer()
+ // REFACTOR?
+ // a good chunk of this code has been copied verbatim *sigh*
+ sal_Int16 nCommand = EffectCommands::CUSTOM;
+ NamedValue aParamValue;
+
+ switch( maType )
+ {
+ case XML_verb:
+ aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb"));
+ // TODO make sure msCommand has what we want
+ aParamValue.Value <<= msCommand.toInt32();
+ nCommand = EffectCommands::VERB;
+ break;
+ case XML_evt:
+ case XML_call:
+ if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) )
+ {
+ nCommand = EffectCommands::STOPAUDIO;
+ }
+ else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) )
+ {
+ nCommand = EffectCommands::PLAY;
+ }
+ else if( msCommand.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 )
+ {
+ const OUString aMediaTime( msCommand.copy( 9, msCommand.getLength() - 10 ) );
+ rtl_math_ConversionStatus eStatus;
+ double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
+ if( eStatus == rtl_math_ConversionStatus_Ok )
+ {
+ aParamValue.Name = CREATE_OUSTRING("MediaTime");
+ aParamValue.Value <<= fMediaTime;
+ }
+ nCommand = EffectCommands::PLAY;
+ }
+ else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) )
+ {
+ nCommand = EffectCommands::TOGGLEPAUSE;
+ }
+ else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) )
+ {
+ nCommand = EffectCommands::STOP;
+ }
+ break;
+ }
+ mpNode->getNodeProperties()[ NP_COMMAND ] = makeAny((sal_Int16)nCommand);
+ if( nCommand == EffectCommands::CUSTOM )
+ {
+ OSL_TRACE("OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
+ aParamValue.Name = CREATE_OUSTRING("UserDefined");
+ aParamValue.Value <<= msCommand;
+ }
+ if( aParamValue.Value.hasValue() )
+ {
+ Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
+ mpNode->getNodeProperties()[ NP_PARAMETER ] = makeAny( aParamSeq );
+ }
+ }
+ catch( RuntimeException& )
+ {
+ OSL_TRACE( "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
+ }
+ }
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+ private:
+ OUString msCommand;
+ sal_Int32 maType;
+ };
+
+
+ /** CT_TLTimeNodeSequence
+ */
+ class SequenceTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ SequenceTimeNodeContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ , mnNextAc(0)
+ , mnPrevAc(0)
+ {
+ AttributeList attribs(xAttribs);
+ mbConcurrent = attribs.getBool( XML_concurrent, false );
+ // ST_TLNextActionType { none, seek }
+ mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
+ // ST_TLPreviousActionType { none, skipTimed }
+ mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
+ }
+
+ ~SequenceTimeNodeContext() throw()
+ {
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cTn:
+ xRet.set( new CommonTimeNodeContext( getHandler(), aElementToken, xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_nextCondLst:
+ xRet.set( new CondListContext( getHandler(), aElementToken, xAttribs, mpNode,
+ mpNode->getNextCondition() ) );
+ break;
+ case NMSP_PPT|XML_prevCondLst:
+ xRet.set( new CondListContext( getHandler(), aElementToken, xAttribs, mpNode,
+ mpNode->getPrevCondition() ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ private:
+ bool mbConcurrent;
+ sal_Int32 mnNextAc, mnPrevAc;
+ };
+
+
+ /** CT_TLTimeNodeParallel
+ * CT_TLTimeNodeExclusive
+ */
+ class ParallelExclTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ ParallelExclTimeNodeContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ {
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cTn:
+ xRet.set( new CommonTimeNodeContext( getHandler(), aElementToken, xAttribs, mpNode ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+ protected:
+
+ };
+
+
+ /** CT_TLAnimateColorBehavior */
+ class AnimColorContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimColorContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ // ST_TLAnimateColorSpace ( XML_rgb, XML_hsl }
+ , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
+ // ST_TLAnimateColorDirection { XML_cw, XML_ccw }
+ , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
+ , mbHasByColor( false )
+ , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
+ {
+ }
+ ~AnimColorContext() throw()
+ {
+ }
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException)
+ {
+ //xParentNode
+ if( aElement == mnElement )
+ {
+ NodePropertyMap & pProps(mpNode->getNodeProperties());
+ pProps[ NP_DIRECTION ] = makeAny( mnDir == XML_cw );
+ pProps[ NP_COLORINTERPOLATION ] = makeAny( mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
+ if( maToClr.isUsed() )
+ {
+ mpNode->setTo( Any( maToClr.getColor( *getHandler()->getFilter().get() ) ) );
+ }
+ if( maFromClr.isUsed() )
+ {
+ mpNode->setFrom( Any( maFromClr.getColor( *getHandler()->getFilter().get() ) ) );
+ }
+ if( mbHasByColor )
+ {
+ mpNode->setBy( Any ( m_byColor.get() ) );
+ }
+
+ }
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_hsl:
+ // CT_TLByHslColorTransform
+ {
+ if( mbHasByColor )
+ {
+ m_byColor.colorSpace = AnimationColorSpace::HSL;
+ m_byColor.one = xAttribs->getOptionalValue( XML_h ).toInt32( );
+ m_byColor.two = xAttribs->getOptionalValue( XML_s ).toInt32( );
+ m_byColor.three = xAttribs->getOptionalValue( XML_l ).toInt32( );
+ }
+ xRet.set(this);
+ break;
+ }
+ case NMSP_PPT|XML_rgb:
+ {
+ if( mbHasByColor )
+ {
+ // CT_TLByRgbColorTransform
+ m_byColor.colorSpace = AnimationColorSpace::RGB;
+ m_byColor.one = xAttribs->getOptionalValue( XML_r ).toInt32();
+ m_byColor.two = xAttribs->getOptionalValue( XML_g ).toInt32();
+ m_byColor.three = xAttribs->getOptionalValue( XML_b ).toInt32();
+ }
+ xRet.set(this);
+ break;
+ }
+ case NMSP_PPT|XML_by:
+ // CT_TLByAnimateColorTransform
+ mbHasByColor = true;
+ xRet.set(this);
+ break;
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_to:
+ // CT_Color
+ xRet.set( new colorChoiceContext( getHandler(), maToClr ) );
+ break;
+ case NMSP_PPT|XML_from:
+ // CT_Color
+ xRet.set( new colorChoiceContext( getHandler(), maFromClr ) );
+ break;
+
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+
+ private:
+ sal_Int32 mnColorSpace;
+ sal_Int32 mnDir;
+ bool mbHasByColor;
+ AnimColor m_byColor;
+ oox::drawingml::Color maToClr;
+ oox::drawingml::Color maFromClr;
+ };
+
+
+ /** CT_TLAnimateBehavior */
+ class AnimContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ {
+ NodePropertyMap & aProps( pNode->getNodeProperties() );
+ sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
+ if(nCalcMode)
+ {
+ sal_Int16 nEnum = 0;
+ switch(nCalcMode)
+ {
+ case XML_discrete:
+ nEnum = AnimationCalcMode::DISCRETE;
+ break;
+ case XML_lin:
+ nEnum = AnimationCalcMode::LINEAR;
+ break;
+ case XML_fmla:
+ default:
+ // TODO what value is good ?
+ nEnum = AnimationCalcMode::DISCRETE;
+ break;
+ }
+ aProps[ NP_CALCMODE ] = makeAny(nEnum);
+ }
+ OUString aStr;
+ aStr = xAttribs->getOptionalValue( XML_from );
+ if( aStr.getLength() )
+ {
+ pNode->setFrom( makeAny( aStr ) );
+ }
+ aStr = xAttribs->getOptionalValue( XML_by );
+ if( aStr.getLength() )
+ {
+ pNode->setBy( makeAny( aStr ) );
+ }
+ aStr = xAttribs->getOptionalValue( XML_to );
+ if( aStr.getLength() )
+ {
+ pNode->setTo( makeAny( aStr ) );
+ }
+ mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
+ }
+
+
+ ~AnimContext() throw ()
+ {
+ ::std::list< TimeAnimationValue >::iterator iter, end;
+ int nKeyTimes = maTavList.size();
+ if( nKeyTimes > 0)
+ {
+ int i;
+ Sequence< double > aKeyTimes( nKeyTimes );
+ Sequence< Any > aValues( nKeyTimes );
+
+ NodePropertyMap & aProps( mpNode->getNodeProperties() );
+ end = maTavList.end();
+ for(iter = maTavList.begin(), i=0; iter != end; iter++,i++)
+ {
+ // TODO what to do if it is Timing_INFINITE ?
+ Any aTime = GetTimeAnimateValueTime( iter->msTime );
+ aTime >>= aKeyTimes[i];
+ aValues[i] = iter->maValue;
+
+ OUString aTest;
+ iter->maValue >>= aTest;
+ if( aTest.getLength() != 0 )
+ {
+ aValues[i] = iter->maValue;
+ }
+ else
+ {
+ aProps[ NP_FORMULA ] <<= iter->msFormula;
+ }
+ }
+ aProps[ NP_VALUES ] <<= aValues;
+ aProps[ NP_KEYTIMES ] <<= aKeyTimes;
+ }
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_tavLst:
+ xRet.set( new TimeAnimValueListContext ( getHandler(), xAttribs, maTavList ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ private:
+ sal_Int32 mnValueType;
+ TimeAnimationValueList maTavList;
+ };
+
+
+ /** CT_TLAnimateScaleBehavior */
+ class AnimScaleContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimScaleContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ , mbZoomContents( false )
+ {
+ AttributeList attribs( xAttribs );
+ // TODO what to do with mbZoomContents
+ mbZoomContents = attribs.getBool( XML_zoomContents, false );
+ pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
+ = makeAny((sal_Int16)AnimationTransformType::SCALE);
+ }
+
+ ~AnimScaleContext( ) throw( )
+ {
+ }
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException)
+ {
+ if( aElement == mnElement )
+ {
+ if( maTo.hasValue() )
+ {
+ mpNode->setTo( maTo );
+ }
+ if( maBy.hasValue() )
+ {
+ mpNode->setBy( maBy );
+ }
+ if( maFrom.hasValue() )
+ {
+ mpNode->setFrom( maFrom );
+ }
+ }
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_to:
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ maTo <<= p.X;
+ maTo <<= p.Y;
+ break;
+ }
+ case NMSP_PPT|XML_from:
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ maFrom <<= p.X;
+ maFrom <<= p.Y;
+ break;
+ }
+ case NMSP_PPT|XML_by:
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ maBy <<= p.X;
+ maBy <<= p.Y;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ private:
+ Any maBy;
+ Any maFrom;
+ Any maTo;
+ bool mbZoomContents;
+ };
+
+
+ /** CT_TLAnimateRotationBehavior */
+ class AnimRotContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimRotContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ {
+ AttributeList attribs( xAttribs );
+
+ pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
+ = makeAny((sal_Int16)AnimationTransformType::ROTATE);
+ // TODO make sure the units are OK
+ if(attribs.hasAttribute( XML_by ) )
+ {
+ sal_Int32 nBy = attribs.getInteger( XML_by, 0 );
+ pNode->setBy( makeAny( nBy ) );
+ }
+ if(attribs.hasAttribute( XML_from ) )
+ {
+ sal_Int32 nFrom = attribs.getInteger( XML_from, 0 );
+ pNode->setFrom( makeAny( nFrom ) );
+ }
+ if(attribs.hasAttribute( XML_to ) )
+ {
+ sal_Int32 nTo = attribs.getInteger( XML_to, 0 );
+ pNode->setTo( makeAny( nTo ) );
+ }
+ }
+
+ ~AnimRotContext( ) throw( )
+ {
+ }
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ };
+
+
+
+ /** CT_TLAnimateMotionBehavior */
+ class AnimMotionContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimMotionContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ {
+ pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
+ = makeAny((sal_Int16)AnimationTransformType::TRANSLATE);
+
+ AttributeList attribs( xAttribs );
+ // ST_TLAnimateMotionBehaviorOrigin { parent, layour }
+ sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
+ if( nOrigin != 0 )
+ {
+ switch(nOrigin)
+ {
+ case XML_layout:
+ case XML_parent:
+ break;
+ }
+ // TODO
+ }
+
+ OUString aStr = xAttribs->getOptionalValue( XML_path );
+ aStr = aStr.replace( 'E', ' ' );
+ aStr = aStr.trim();
+ pNode->getNodeProperties()[ NP_PATH ] = makeAny(aStr);
+
+ // ST_TLAnimateMotionPathEditMode{ fixed, relative }
+ mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
+ msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
+ mnAngle = attribs.getInteger( XML_rAng, 0 );
+ // TODO make sure the units are right. Likely not.
+ }
+
+ ~AnimMotionContext( ) throw()
+ {
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_to:
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setTo( rAny );
+ break;
+ }
+ case NMSP_PPT|XML_from:
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setFrom( rAny );
+ break;
+ }
+ case NMSP_PPT|XML_by:
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setBy( rAny );
+ break;
+ }
+ case NMSP_PPT|XML_rCtr:
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ // TODO push
+ break;
+ }
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ private:
+ OUString msPtsTypes;
+ sal_Int32 mnPathEditMode;
+ sal_Int32 mnAngle;
+ };
+
+
+ /** CT_TLAnimateEffectBehavior */
+ class AnimEffectContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimEffectContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( xHandler, aElement, xAttribs, pNode )
+ {
+ sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
+ OUString sFilter = xAttribs->getOptionalValue( XML_filter );
+ // TODO
+// OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
+
+ if( sFilter.getLength() )
+ {
+ SlideTransition aFilter( sFilter );
+ aFilter.setMode( nDir == XML_out ? false : true );
+ pNode->setTransitionFilter( aFilter );
+ }
+ }
+
+
+ ~AnimEffectContext( ) throw()
+ {
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch ( aElementToken )
+ {
+ case NMSP_PPT|XML_cBhvr:
+ xRet.set( new CommonBehaviorContext ( getHandler(), xAttribs, mpNode ) );
+ break;
+ case NMSP_PPT|XML_progress:
+ xRet.set( new AnimVariantContext( getHandler(), aElementToken, maProgress ) );
+ // TODO handle it.
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ private:
+ Any maProgress;
+ OUString msFilter;
+ OUString msPrList;
+ };
+
+
+
+ TimeNodeContext * TimeNodeContext::makeContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ {
+ TimeNodeContext *pCtx = NULL;
+ switch( aElement )
+ {
+ case NMSP_PPT|XML_animClr:
+ pCtx = new AnimColorContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_par:
+ pCtx = new ParallelExclTimeNodeContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_seq:
+ pCtx = new SequenceTimeNodeContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_excl:
+ pCtx = new ParallelExclTimeNodeContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_anim:
+ pCtx = new AnimContext ( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_animEffect:
+ pCtx = new AnimEffectContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_animMotion:
+ pCtx = new AnimMotionContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_animRot:
+ pCtx = new AnimRotContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_animScale:
+ pCtx = new AnimScaleContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_cmd:
+ pCtx = new CmdTimeNodeContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_set:
+ pCtx = new SetTimeNodeContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ case NMSP_PPT|XML_audio:
+ case NMSP_PPT|XML_video:
+ pCtx = new MediaNodeContext( xHandler, aElement, xAttribs, pNode );
+ break;
+ default:
+ break;
+ }
+ return pCtx;
+ }
+
+
+ TimeNodeContext::TimeNodeContext( const FragmentHandlerRef& xHandler, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& /*xAttribs*/,
+ const TimeNodePtr & pNode ) throw()
+ : Context( xHandler )
+ , mnElement( aElement )
+ , mpNode( pNode )
+ {
+ }
+
+
+ TimeNodeContext::~TimeNodeContext( ) throw()
+ {
+
+ }
+
+
+ TimeNodeListContext::TimeNodeListContext( const FragmentHandlerRef& xHandler, TimeNodePtrList & aList )
+ throw()
+ : Context( xHandler )
+ , maList( aList )
+ {
+ }
+
+
+ TimeNodeListContext::~TimeNodeListContext( ) throw()
+ {
+ }
+
+
+ Reference< XFastContextHandler > SAL_CALL TimeNodeListContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ sal_Int16 nNodeType;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_par:
+ nNodeType = AnimationNodeType::PAR;
+ break;
+ case NMSP_PPT|XML_seq:
+ nNodeType = AnimationNodeType::SEQ;
+ break;
+ case NMSP_PPT|XML_excl:
+ // TODO pick the right type. We choose parallel for now as
+ // there does not seem to be an "Exclusive"
+ nNodeType = AnimationNodeType::PAR;
+ break;
+ case NMSP_PPT|XML_anim:
+ nNodeType = AnimationNodeType::ANIMATE;
+ break;
+ case NMSP_PPT|XML_animClr:
+ nNodeType = AnimationNodeType::ANIMATECOLOR;
+ break;
+ case NMSP_PPT|XML_animEffect:
+ nNodeType = AnimationNodeType::TRANSITIONFILTER;
+ break;
+ case NMSP_PPT|XML_animMotion:
+ nNodeType = AnimationNodeType::ANIMATEMOTION;
+ break;
+ case NMSP_PPT|XML_animRot:
+ case NMSP_PPT|XML_animScale:
+ nNodeType = AnimationNodeType::ANIMATETRANSFORM;
+ break;
+ case NMSP_PPT|XML_cmd:
+ nNodeType = AnimationNodeType::COMMAND;
+ break;
+ case NMSP_PPT|XML_set:
+ nNodeType = AnimationNodeType::SET;
+ break;
+ case NMSP_PPT|XML_audio:
+ nNodeType = AnimationNodeType::AUDIO;
+ break;
+ case NMSP_PPT|XML_video:
+ nNodeType = AnimationNodeType::AUDIO;
+ OSL_TRACE( "OOX: video requested, gave Audio instead" );
+ break;
+
+ default:
+ nNodeType = AnimationNodeType::CUSTOM;
+ OSL_TRACE( "OOX: uhandled token %x", aElementToken );
+ break;
+ }
+
+ TimeNodePtr pNode(new TimeNode(nNodeType));
+ maList.push_back( pNode );
+ Context * pContext = TimeNodeContext::makeContext( getHandler(), aElementToken, xAttribs, pNode );
+ xRet.set( ( pContext != NULL ? pContext : this ) );
+
+ if( !xRet.is() )
+ xRet.set(this);
+
+ return xRet;
+ }
+
+
+} }
diff --git a/oox/source/ppt/timetargetelementcontext.cxx b/oox/source/ppt/timetargetelementcontext.cxx
new file mode 100644
index 000000000000..19d941619e46
--- /dev/null
+++ b/oox/source/ppt/timetargetelementcontext.cxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timetargetelementcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:01 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "timetargetelementcontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include <osl/diagnose.h>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/drawingml/embeddedwavaudiofile.hxx"
+#include "tokens.hxx"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+namespace oox { namespace ppt {
+
+
+
+ // CT_TLShapeTargetElement
+ class ShapeTargetElementContext
+ : public Context
+ {
+ public:
+ ShapeTargetElementContext( const ::oox::core::Context & xParent, ShapeTargetElement & aValue )
+ : Context( xParent )
+ , bTargetSet(false)
+ , maShapeTarget(aValue)
+ {
+ }
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_bg:
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_bg;
+ break;
+ case NMSP_PPT|XML_txEl:
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_txEl;
+ break;
+ case NMSP_PPT|XML_subSp:
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_subSp;
+ maShapeTarget.msSubShapeId = xAttribs->getOptionalValue( XML_spid );
+ break;
+ case NMSP_PPT|XML_graphicEl:
+ case NMSP_PPT|XML_oleChartEl:
+ bTargetSet = true;
+ // TODO
+ break;
+ case NMSP_PPT|XML_charRg:
+ case NMSP_PPT|XML_pRg:
+ if( bTargetSet && maShapeTarget.mnType == XML_txEl )
+ {
+ maShapeTarget.mnRangeType = (aElementToken & ~NMSP_MASK);
+ maShapeTarget.maRange = drawingml::GetIndexRange( xAttribs );
+ }
+ break;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+ private:
+ bool bTargetSet;
+ ShapeTargetElement & maShapeTarget;
+ };
+
+
+
+ TimeTargetElementContext::TimeTargetElementContext( const FragmentHandlerRef & xHandler,
+ const AnimTargetElementPtr & pValue )
+ : Context( xHandler ),
+ mpTarget( pValue )
+ {
+ OSL_ENSURE( mpTarget, "no valid target passed" );
+ }
+
+
+ TimeTargetElementContext::~TimeTargetElementContext( ) throw( )
+ {
+ }
+
+ void SAL_CALL TimeTargetElementContext::endFastElement( sal_Int32 /*aElement*/ ) throw ( SAXException, RuntimeException)
+ {
+ }
+
+ Reference< XFastContextHandler > SAL_CALL TimeTargetElementContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case NMSP_PPT|XML_inkTgt:
+ {
+ mpTarget->mnType = XML_inkTgt;
+ OUString aId = xAttribs->getOptionalValue( XML_spid );
+ if( aId.getLength() )
+ {
+ mpTarget->msValue = aId;
+ }
+ break;
+ }
+ case NMSP_PPT|XML_sldTgt:
+ mpTarget->mnType = XML_sldTgt;
+ break;
+ case NMSP_PPT|XML_sndTgt:
+ {
+ mpTarget->mnType = XML_sndTgt;
+ drawingml::EmbeddedWAVAudioFile aAudio;
+ drawingml::getEmbeddedWAVAudioFile( getHandler(), xAttribs, aAudio);
+
+ OUString sSndName = ( aAudio.mbBuiltIn ? aAudio.msName : aAudio.msLink );
+ mpTarget->msValue = sSndName;
+ break;
+ }
+ case NMSP_PPT|XML_spTgt:
+ {
+ mpTarget->mnType = XML_spTgt;
+ OUString aId = xAttribs->getOptionalValue( XML_spid );
+ mpTarget->msValue = aId;
+ xRet.set( new ShapeTargetElementContext( *this, mpTarget->maShapeTarget ) );
+ break;
+ }
+ default:
+ OSL_TRACE( "OOX: unhandled tag %ld in TL_TimeTargetElement.", (aElementToken & ~NMSP_MASK) );
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+
+} }
diff --git a/oox/source/ppt/timetargetelementcontext.hxx b/oox/source/ppt/timetargetelementcontext.hxx
new file mode 100644
index 000000000000..8c7c5b6422e0
--- /dev/null
+++ b/oox/source/ppt/timetargetelementcontext.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timetargetelementcontext.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:01 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_TIMETARGETELEMENTCONTEXT
+#define OOX_PPT_TIMETARGETELEMENTCONTEXT
+
+
+#include "oox/core/context.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/ppt/animationspersist.hxx"
+
+namespace oox { namespace ppt {
+
+ /** context CT_TLTimeTargetElement */
+ class TimeTargetElementContext
+ : public ::oox::core::Context
+ {
+ public:
+ TimeTargetElementContext( const ::oox::core::FragmentHandlerRef & xHandler, const AnimTargetElementPtr & aValue );
+ ~TimeTargetElementContext( ) throw( );
+ virtual void SAL_CALL endFastElement( sal_Int32 /*aElement*/ ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs ) throw ( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ private:
+ AnimTargetElementPtr mpTarget;
+ };
+
+} }
+
+
+#endif
diff --git a/oox/source/shape/FastTokenHandlerService.cxx b/oox/source/shape/FastTokenHandlerService.cxx
new file mode 100644
index 000000000000..cfa78248e43c
--- /dev/null
+++ b/oox/source/shape/FastTokenHandlerService.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: FastTokenHandlerService.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:06 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "FastTokenHandlerService.hxx"
+
+namespace oox {
+namespace shape {
+
+using namespace ::com::sun::star;
+
+FastTokenHandlerService::FastTokenHandlerService(uno::Reference< uno::XComponentContext > const & context) :
+ m_xContext(context)
+{}
+
+// com.sun.star.uno.XServiceInfo:
+::rtl::OUString SAL_CALL FastTokenHandlerService::getImplementationName() throw (uno::RuntimeException)
+{
+ return FastTokenHandlerService_getImplementationName();
+}
+
+::sal_Bool SAL_CALL FastTokenHandlerService::supportsService(::rtl::OUString const & serviceName) throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > serviceNames = FastTokenHandlerService_getSupportedServiceNames();
+ for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
+ if (serviceNames[i] == serviceName)
+ return sal_True;
+ }
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL FastTokenHandlerService::getSupportedServiceNames() throw (uno::RuntimeException)
+{
+ return FastTokenHandlerService_getSupportedServiceNames();
+}
+
+::sal_Int32 SAL_CALL FastTokenHandlerService::getToken(const ::rtl::OUString & Identifier) throw (::com::sun::star::uno::RuntimeException)
+{
+ return mFastTokenHandler.getToken(Identifier);
+}
+
+::rtl::OUString SAL_CALL FastTokenHandlerService::getIdentifier(::sal_Int32 Token) throw (::com::sun::star::uno::RuntimeException)
+{
+ return mFastTokenHandler.getIdentifier(Token);
+}
+
+::sal_Int32 SAL_CALL FastTokenHandlerService::getTokenFromUTF8(const ::com::sun::star::uno::Sequence< ::sal_Int8 > & Identifier) throw (::com::sun::star::uno::RuntimeException)
+{
+ return mFastTokenHandler.getTokenFromUTF8(Identifier);
+}
+
+::rtl::OUString SAL_CALL FastTokenHandlerService_getImplementationName() {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.oox.FastTokenHandlerService"));
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL FastTokenHandlerService_getSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > s(1);
+ s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.sax.FastTokenHandler"));
+ return s;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL FastTokenHandlerService_create(
+ const uno::Reference< uno::XComponentContext > & context)
+ SAL_THROW((uno::Exception))
+{
+ return static_cast< ::cppu::OWeakObject * >(new FastTokenHandlerService(context));
+}
+
+uno::Reference< uno::XInterface > SAL_CALL
+FastTokenHandlerService_createInstance
+( const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ uno::Reference<beans::XPropertySet>
+ xPropertySet(rSMgr, uno::UNO_QUERY_THROW);
+ uno::Any aDefaultContext = xPropertySet->getPropertyValue
+ (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
+
+ uno::Reference<uno::XComponentContext> xContext;
+ aDefaultContext >>= xContext;
+
+ return FastTokenHandlerService_create(xContext);
+}
+
+}}
diff --git a/oox/source/shape/FastTokenHandlerService.hxx b/oox/source/shape/FastTokenHandlerService.hxx
new file mode 100644
index 000000000000..c3c8a8e4034c
--- /dev/null
+++ b/oox/source/shape/FastTokenHandlerService.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: FastTokenHandlerService.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:06 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+#ifndef OOX_SHAPE_FAST_TOKEN_HANDLER_SERVICE_HXX
+#define OOX_SHAPE_FAST_TOKEN_HANDLER_SERVICE_HXX
+
+#include <oox/core/fasttokenhandler.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"
+
+namespace css = ::com::sun::star;
+
+namespace oox {
+namespace shape {
+
+class FastTokenHandlerService:
+ public ::cppu::WeakImplHelper2<
+ css::lang::XServiceInfo,
+ css::xml::sax::XFastTokenHandler>
+{
+public:
+ explicit FastTokenHandlerService(css::uno::Reference< css::uno::XComponentContext > const & context);
+
+ // ::com::sun::star::lang::XServiceInfo:
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService(const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ // ::com::sun::star::xml::sax::XFastTokenHandler:
+ virtual ::sal_Int32 SAL_CALL getToken(const ::rtl::OUString & Identifier) throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getIdentifier(::sal_Int32 Token) throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getTokenFromUTF8(const css::uno::Sequence< ::sal_Int8 > & Identifier) throw (css::uno::RuntimeException);
+
+private:
+ FastTokenHandlerService(FastTokenHandlerService &); // not defined
+ void operator =(FastTokenHandlerService &); // not defined
+
+ virtual ~FastTokenHandlerService() {}
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ FastTokenHandler mFastTokenHandler;
+};
+
+::rtl::OUString SAL_CALL FastTokenHandlerService_getImplementationName();
+
+css::uno::Sequence< ::rtl::OUString > SAL_CALL FastTokenHandlerService_getSupportedServiceNames();
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL _FastTokenHandlerService_create(
+ const css::uno::Reference< css::uno::XComponentContext > & context)
+ SAL_THROW((css::uno::Exception));
+
+}}
+#endif // OOX_SHAPE_FAST_TOKEN_HANDLER_SERVICE_HXX
diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
new file mode 100644
index 000000000000..acf0dd477de1
--- /dev/null
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ShapeContextHandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:06 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+#include "ShapeContextHandler.hxx"
+#include "oox/core/fragmenthandler.hxx"
+
+namespace oox { namespace shape {
+
+using namespace ::com::sun::star;
+using namespace core;
+using namespace drawingml;
+
+ShapeContextHandler::ShapeContextHandler
+(uno::Reference< uno::XComponentContext > const & context) :
+m_xContext(context)
+{
+ FragmentHandlerRef rFragmentHandler;
+ ShapePtr pMasterShape;
+ mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
+
+ mxGraphicShapeContext.set(new GraphicShapeContext(rFragmentHandler,
+ pMasterShape,
+ mpShape));
+
+ mpThemePtr.reset(new Theme());
+ uno::Reference<lang::XMultiServiceFactory>
+ xFactory(context->getServiceManager(), uno::UNO_QUERY_THROW);
+ mpFilterBase.reset(new ShapeFilterBase(xFactory));
+}
+
+ShapeContextHandler::~ShapeContextHandler()
+{
+}
+
+// ::com::sun::star::xml::sax::XFastContextHandler:
+void SAL_CALL ShapeContextHandler::startFastElement
+(::sal_Int32 Element,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ if (mxGraphicShapeContext.is())
+ mxGraphicShapeContext->startFastElement(Element, Attribs);
+}
+
+void SAL_CALL ShapeContextHandler::startUnknownElement
+(const ::rtl::OUString & Namespace, const ::rtl::OUString & Name,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ if (mxGraphicShapeContext.is())
+ mxGraphicShapeContext->startUnknownElement(Namespace, Name, Attribs);
+}
+
+void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ if (mxGraphicShapeContext.is())
+ mxGraphicShapeContext->endFastElement(Element);
+}
+
+void SAL_CALL ShapeContextHandler::endUnknownElement
+(const ::rtl::OUString & Namespace,
+ const ::rtl::OUString & Name)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ if (mxGraphicShapeContext.is())
+ mxGraphicShapeContext->endUnknownElement(Namespace, Name);
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+ShapeContextHandler::createFastChildContext
+(::sal_Int32 Element,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xResult;
+
+ if (mxGraphicShapeContext.is())
+ xResult.set(mxGraphicShapeContext->createFastChildContext
+ (Element, Attribs));
+
+ return xResult;
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+ShapeContextHandler::createUnknownChildContext
+(const ::rtl::OUString & Namespace,
+ const ::rtl::OUString & Name,
+ const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ if (mxGraphicShapeContext.is())
+ return mxGraphicShapeContext->createUnknownChildContext
+ (Namespace, Name, Attribs);
+
+ return uno::Reference< xml::sax::XFastContextHandler >();
+}
+
+void SAL_CALL ShapeContextHandler::characters(const ::rtl::OUString & aChars)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ if (mxGraphicShapeContext.is())
+ mxGraphicShapeContext->characters(aChars);
+}
+
+// ::com::sun::star::xml::sax::XFastShapeContextHandler:
+uno::Reference< drawing::XShape > SAL_CALL
+ShapeContextHandler::getShape() throw (uno::RuntimeException)
+{
+ uno::Reference< drawing::XShape > xResult;
+ std::map< ::rtl::OUString, ShapePtr > aShapeMap;
+
+ if (mpFilterBase.get() != NULL && mxModel.is() &&
+ mpThemePtr.get() != NULL && mxShapes.is())
+ {
+ mpShape->addShape
+ (*mpFilterBase, mxModel, mpThemePtr, aShapeMap,
+ mxShapes, NULL);
+
+ xResult.set(mpShape->getXShape());
+ }
+
+ return xResult;
+}
+
+css::uno::Reference< css::drawing::XShapes > SAL_CALL
+ShapeContextHandler::getShapes() throw (css::uno::RuntimeException)
+{
+ return mxShapes;
+}
+
+void SAL_CALL ShapeContextHandler::setShapes
+(const css::uno::Reference< css::drawing::XShapes > & the_value)
+ throw (css::uno::RuntimeException)
+{
+ mxShapes = the_value;
+}
+
+css::uno::Reference< css::frame::XModel > SAL_CALL
+ShapeContextHandler::getModel() throw (css::uno::RuntimeException)
+{
+ return mxModel;
+}
+
+void SAL_CALL ShapeContextHandler::setModel
+(const css::uno::Reference< css::frame::XModel > & the_value)
+ throw (css::uno::RuntimeException)
+{
+ mxModel = the_value;
+}
+
+::rtl::OUString ShapeContextHandler::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return ShapeContextHandler_getImplementationName();
+}
+
+uno::Sequence< ::rtl::OUString > ShapeContextHandler::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return ShapeContextHandler_getSupportedServiceNames();
+}
+
+::rtl::OUString SAL_CALL ShapeContextHandler_getImplementationName() {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.oox.ShapeContextHandler"));
+}
+
+::sal_Bool SAL_CALL ShapeContextHandler::supportsService
+(const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aSeq = getSupportedServiceNames();
+
+ if (aSeq[0].equals(ServiceName))
+ return sal_True;
+
+ return sal_False;
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ShapeContextHandler_getSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > s(1);
+ s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.sax.FastShapeContextHandler"));
+ return s;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL
+ShapeContextHandler_create(
+ const uno::Reference< uno::XComponentContext > & context)
+ SAL_THROW((uno::Exception))
+{
+ return static_cast< ::cppu::OWeakObject * >
+ (new ShapeContextHandler(context));
+}
+
+uno::Reference< uno::XInterface > SAL_CALL
+ShapeContextHandler_createInstance
+( const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ uno::Reference<beans::XPropertySet>
+ xPropertySet(rSMgr, uno::UNO_QUERY_THROW);
+ uno::Any aDefaultContext = xPropertySet->getPropertyValue
+ (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
+
+ uno::Reference<uno::XComponentContext> xContext;
+ aDefaultContext >>= xContext;
+
+ return ShapeContextHandler_create(xContext);
+}
+
+}}
diff --git a/oox/source/shape/ShapeContextHandler.hxx b/oox/source/shape/ShapeContextHandler.hxx
new file mode 100644
index 000000000000..6b79de0924b2
--- /dev/null
+++ b/oox/source/shape/ShapeContextHandler.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ShapeContextHandler.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:06 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+#ifndef OOX_SHAPE_SHAPE_CONTEXT_HANDLER_HXX
+#define OOX_SHAPE_SHAPE_CONTEXT_HANDLER_HXX
+
+#include <boost/shared_ptr.hpp>
+#include "sal/config.h"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/xml/sax/XFastShapeContextHandler.hpp"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/theme.hxx"
+#include "ShapeFilterBase.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace oox { namespace shape {
+
+// component and service helper functions:
+::rtl::OUString SAL_CALL ShapeContextHandler_getImplementationName();
+
+css::uno::Sequence< ::rtl::OUString > SAL_CALL
+ShapeContextHandler_getSupportedServiceNames();
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL
+ShapeContextHandler_create
+( css::uno::Reference< css::uno::XComponentContext > const & context );
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL
+ShapeContextHandler_createInstance
+( const css::uno::Reference< css::lang::XMultiServiceFactory > & rSMgr)
+throw( css::uno::Exception );
+
+class ShapeContextHandler:
+ public ::cppu::WeakImplHelper1<
+ css::xml::sax::XFastShapeContextHandler>
+{
+public:
+ explicit ShapeContextHandler
+ (css::uno::Reference< css::uno::XComponentContext > const & context);
+
+ virtual ~ShapeContextHandler();
+
+ // ::com::sun::star::lang::XServiceInfo:
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL supportsService
+ (const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ // ::com::sun::star::xml::sax::XFastContextHandler:
+ virtual void SAL_CALL startFastElement
+ (::sal_Int32 Element,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+ virtual void SAL_CALL startUnknownElement
+ (const ::rtl::OUString & Namespace,
+ const ::rtl::OUString & Name,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+ virtual void SAL_CALL endFastElement(::sal_Int32 Element)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+ virtual void SAL_CALL endUnknownElement
+ (const ::rtl::OUString & Namespace,
+ const ::rtl::OUString & Name)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext
+ (::sal_Int32 Element,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+ createUnknownChildContext
+ (const ::rtl::OUString & Namespace,
+ const ::rtl::OUString & Name,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & Attribs)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+ virtual void SAL_CALL characters(const ::rtl::OUString & aChars)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+ // ::com::sun::star::xml::sax::XFastShapeContextHandler:
+ virtual css::uno::Reference< css::drawing::XShape > SAL_CALL getShape()
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::drawing::XShapes > SAL_CALL getShapes()
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setShapes
+ (const css::uno::Reference< css::drawing::XShapes > & the_value)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel()
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setModel
+ (const css::uno::Reference< css::frame::XModel > & the_value)
+ throw (css::uno::RuntimeException);
+
+private:
+ ShapeContextHandler(ShapeContextHandler &); // not defined
+ void operator =(ShapeContextHandler &); // not defined
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ drawingml::ShapePtr mpShape;
+
+ typedef boost::shared_ptr<drawingml::GraphicShapeContext>
+ GraphicShapeContextPtr;
+ css::uno::Reference<XFastContextHandler> mxGraphicShapeContext;
+
+ ShapeFilterBase::Pointer_t mpFilterBase;
+ css::uno::Reference<css::frame::XModel> mxModel;
+ drawingml::ThemePtr mpThemePtr;
+ css::uno::Reference<css::drawing::XShapes> mxShapes;
+};
+
+}}
+
+#endif // OOX_SHAPE_SHAPE_CONTEXT_HANDLER_HXX
diff --git a/oox/source/shape/ShapeFilterBase.cxx b/oox/source/shape/ShapeFilterBase.cxx
new file mode 100644
index 000000000000..30c4cdf462e5
--- /dev/null
+++ b/oox/source/shape/ShapeFilterBase.cxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ShapeFilterBase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:06 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+#include "ShapeFilterBase.hxx"
+
+namespace oox {
+namespace shape {
+
+using namespace ::com::sun::star;
+
+ShapeFilterBase::ShapeFilterBase
+(const uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ rxFactory)
+: XmlFilterBase(rxFactory)
+{
+}
+
+ShapeFilterBase::~ShapeFilterBase()
+{
+}
+
+sal_Int32 ShapeFilterBase::getSchemeClr(sal_Int32 /*nColorSchemeToken*/ ) const
+{
+ return 0;
+}
+
+const vml::DrawingPtr ShapeFilterBase::getDrawings()
+{
+ return vml::DrawingPtr();
+}
+
+::rtl::OUString ShapeFilterBase::implGetImplementationName() const
+{
+ return ::rtl::OUString();
+}
+
+}
+}
diff --git a/oox/source/shape/ShapeFilterBase.hxx b/oox/source/shape/ShapeFilterBase.hxx
new file mode 100644
index 000000000000..ab9270141dba
--- /dev/null
+++ b/oox/source/shape/ShapeFilterBase.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ShapeFilterBase.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef OOX_SHAPE_SHAPEFILTERBASE_HXX
+#define OOX_SHAPE_SHAPEFILTERBASE_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <rtl/ref.hxx>
+#include "oox/vml/drawing.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+
+namespace oox {
+namespace shape {
+
+class FragmentHandler;
+
+// ============================================================================
+
+
+class ShapeFilterBase : public core::XmlFilterBase
+{
+public:
+ typedef boost::shared_ptr<ShapeFilterBase> Pointer_t;
+
+ explicit ShapeFilterBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
+
+ virtual ~ShapeFilterBase();
+
+ /** 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 drawings collection. */
+ virtual const ::oox::vml::DrawingPtr getDrawings();
+
+ virtual rtl::OUString implGetImplementationName() const;
+
+ virtual bool importDocument() { return false; }
+ virtual bool exportDocument() { return false; }
+};
+
+// ============================================================================
+
+} // namespace shape
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/shape/makefile.mk b/oox/source/shape/makefile.mk
new file mode 100644
index 000000000000..d0233a990e2a
--- /dev/null
+++ b/oox/source/shape/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=shape
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/ShapeContextHandler.obj \
+ $(SLO)$/ShapeFilterBase.obj \
+ $(SLO)$/FastTokenHandlerService.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/token/gentoken.pl b/oox/source/token/gentoken.pl
new file mode 100644
index 000000000000..8f0a4610d926
--- /dev/null
+++ b/oox/source/token/gentoken.pl
@@ -0,0 +1,55 @@
+$ARGV0 = shift @ARGV;
+$ARGV1 = shift @ARGV;
+$ARGV2 = shift @ARGV;
+
+open ( TOKENS, $ARGV0 ) || die "can't open token file: $!";
+my %tokens;
+
+while ( defined ($line = <TOKENS>) )
+{
+ chomp($line);
+ @token = split(/\s+/,$line);
+ if ( not defined ($token[1]) )
+ {
+ $token[1] = "XML_".$token[0];
+ $token[1] =~ tr/\-\.\:/___/;
+ $token[1] =~ s/\+/PLUS/g;
+ $token[1] =~ s/\-/MINUS/g;
+ }
+
+ $tokens{$token[0]} = $token[1];
+}
+close ( TOKENS );
+
+open ( HXX, ">$ARGV1" ) || die "can't open tokens.hxx file: $!";
+open ( GPERF, ">$ARGV2" ) || die "can't open tokens.gperf file: $!";
+
+print ( GPERF "%language=C++\n" );
+print ( GPERF "%global-table\n" );
+print ( GPERF "%null-strings\n" );
+print ( GPERF "%struct-type\n" );
+print ( GPERF "struct xmltoken\n" );
+print ( GPERF "{\n" );
+print ( GPERF " const sal_Char *name; sal_Int32 nToken; \n" );
+print ( GPERF "};\n" );
+print ( GPERF "%%\n" );
+
+print ( HXX "#ifndef _TOKEN_HXX_\n" );
+print ( HXX "#define _TOKEN_HXX_\n\n" );
+print ( HXX "#ifndef _SAL_TYPES_H_\n" );
+print ( HXX "#include <sal/types.h>\n" );
+print ( HXX "#endif\n\n" );
+
+$i = 0;
+foreach( sort(keys(%tokens)) )
+{
+ print( HXX "const sal_Int32 $tokens{$_} = $i;\n" );
+ print( GPERF "$_,$tokens{$_}\n" );
+ $i = $i + 1;
+}
+print ( GPERF "%%\n" );
+print ( HXX "const sal_Int32 XML_TOKEN_COUNT = $i;\n" );
+print ( HXX "const sal_Int32 XML_TOKEN_INVALID = -1;\n\n" );
+print ( HXX "#endif\n" );
+close ( HXX );
+close ( GPERF );
diff --git a/oox/source/token/makefile.mk b/oox/source/token/makefile.mk
new file mode 100644
index 000000000000..543138315aa0
--- /dev/null
+++ b/oox/source/token/makefile.mk
@@ -0,0 +1,66 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=token
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/tokenmap.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(INCCOM)$/tokens.hxx $(MISC)$/tokens.gperf : tokens.txt gentoken.pl
+ $(PERL) gentoken.pl tokens.txt $(INCCOM)$/tokens.hxx $(MISC)$/tokens.gperf
+
+$(INCCOM)$/tokens.cxx : $(MISC)$/tokens.gperf
+ gperf --compare-strncmp --output-file=$(MISC)$/_tokens.cxx $(MISC)$/tokens.gperf
+ $(TYPE) $(MISC)$/_tokens.cxx | $(SED) -e "s/(char\*)0/(char\*)0, 0/g" >$(INCCOM)$/tokens.cxx
+
+$(SLO)$/tokenmap.obj : $(INCCOM)$/tokens.cxx $(INCCOM)$/tokens.hxx
+
+$(INCCOM)$/tokens.gperf : $(INCCOM)$/tokens.hxx
diff --git a/oox/source/token/parsexsd.pl b/oox/source/token/parsexsd.pl
new file mode 100644
index 000000000000..3b6745121e4c
--- /dev/null
+++ b/oox/source/token/parsexsd.pl
@@ -0,0 +1,48 @@
+$ARGV = shift @ARGV;
+my %tokens;
+
+my @files = glob("$ARGV/*.rnc");
+
+open( TOKEN, ">tokens.txt" ) || die "can't write token file";
+
+foreach( @files )
+{
+ print( "parsing $_\n" );
+ open ( XSD, $_ ) || die "can't open token file: $!";
+ while( <XSD> )
+ {
+ chomp($_);
+ if( /element (\S*:)?(\S*)/ )
+ {
+ $tokens{$2} = 1;
+ print(".");
+ }
+ elsif( /attribute (\S*:)?(\S*)/ )
+ {
+ $tokens{$2} = 1;
+ print(".");
+ }
+ elsif( /list\s*\{/ )
+ {
+ while( <XSD> )
+ {
+ chomp($_);
+ last if( /^\s*\}/ );
+ if( /"(\S*?)\"/ )
+ {
+ $tokens{$1} = 1;
+ print(".");
+ }
+ }
+ }
+ }
+ close ( XSD );
+
+ print("\n" );
+}
+
+foreach( sort(keys(%tokens)) )
+{
+ print TOKEN "$_\n";
+}
+close( TOKEN );
diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx
new file mode 100644
index 000000000000..016e3055da53
--- /dev/null
+++ b/oox/source/token/tokenmap.cxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tokenmap.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+
+#include "oox/core/fasttokenhandler.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using ::osl::Mutex;
+using ::osl::MutexGuard;
+using namespace ::com::sun::star::xml::sax;
+
+#ifdef WNT
+#pragma warning(disable:4129)
+#endif
+
+namespace oox
+{
+
+#include "tokens.cxx"
+
+Mutex& getTokenMutex()
+{
+ static Mutex aMutex;
+ return aMutex;
+}
+
+::sal_Int32 FastTokenHandler::getToken( const ::rtl::OUString& Identifier ) throw (::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard guard( getTokenMutex() );
+
+ rtl::OString aUTF8( Identifier.getStr(), Identifier.getLength(), RTL_TEXTENCODING_UTF8 );
+
+ struct xmltoken * t = Perfect_Hash::in_word_set( aUTF8, aUTF8.getLength() );
+ if( t )
+ return t->nToken;
+ else
+ return FastToken::DONTKNOW;
+}
+
+::rtl::OUString FastTokenHandler::getIdentifier( ::sal_Int32 nToken ) throw (::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard guard( getTokenMutex() );
+
+ if( nToken >= XML_TOKEN_COUNT )
+ return OUString();
+
+ static OUString aTokens[XML_TOKEN_COUNT];
+
+ if( aTokens[nToken].getLength() == 0 )
+ aTokens[nToken] = OUString::createFromAscii(wordlist[nToken].name);
+
+ return aTokens[nToken];
+}
+
+::sal_Int32 FastTokenHandler::getTokenFromUTF8( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& Identifier ) throw (::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard guard( getTokenMutex() );
+
+ struct xmltoken * t = Perfect_Hash::in_word_set((const char*)Identifier.getConstArray(), Identifier.getLength());
+ if( t )
+ return t->nToken;
+ else
+ return FastToken::DONTKNOW;
+}
+
+}
+
+
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
new file mode 100644
index 000000000000..bb8f4ceac6ec
--- /dev/null
+++ b/oox/source/token/tokens.txt
@@ -0,0 +1,5569 @@
+1D
+1pic
+1picTitle
+2D
+2pic
+2picTitle
+35mm
+3Arrows
+3ArrowsGray
+3Flags
+3Signs
+3Symbols
+3Symbols2
+3TrafficLights1
+3TrafficLights2
+3dDkShadow
+3dLight
+4Arrows
+4ArrowsGray
+4Rating
+4RedToBlack
+4TrafficLights
+4pic
+4picTitle
+5Arrows
+5ArrowsGray
+5Quarters
+5Rating
+A1
+A3
+A4
+AbbreviatedCaseNumber
+Accel
+Accel2
+AlbumTitle
+Always
+Anchor
+AppVersion
+Append
+Application
+Art
+ArticleInAPeriodical
+Artist
+Author
+AutoFill
+AutoFit
+AutoLine
+AutoPict
+AutoScale
+B4ISO
+B4JIS
+B5ISO
+B5JIS
+Bitmap
+Book
+BookAuthor
+BookSection
+BookTitle
+BroadcastTitle
+Broadcaster
+Button
+CF
+Camera
+Cancel
+Case
+CaseNumber
+ChapterNumber
+Characters
+CharactersWithSpaces
+Checkbox
+Checked
+City
+ClientData
+ColHidden
+Colored
+Column
+Comments
+Company
+Compiler
+Composer
+Conductor
+ConferenceName
+ConferenceProceedings
+ConnectionID
+Content
+ContentType
+Corporate
+Counsel
+CountryRegion
+Court
+DDE
+DMY
+DVASPECT_CONTENT
+DVASPECT_ICON
+DYM
+DataBinding
+DataBindingLoadMode
+DataBindingName
+Day
+DayAccessed
+Default
+DefaultSize
+Department
+Dialog
+DigSig
+Director
+Disabled
+Dismiss
+Distributor
+DocSecurity
+DocumentFromInternetSite
+DrawAspect
+Drop
+DropLines
+DropStyle
+Dx
+EMD
+ENTITIES
+ENTITY
+Edit
+Edition
+Editor
+ElectronicSource
+Embed
+EnhancedMetaFile
+Extension
+False
+FieldCodes
+FileBinding
+FileBindingName
+Film
+First
+FirstButton
+FmlaGroup
+FmlaLink
+FmlaMacro
+FmlaPict
+FmlaRange
+FmlaTxbx
+Format
+Formula
+GBox
+Group
+Guid
+HLinks
+HTMLInset
+HTMLOutset
+HeadingPairs
+Help
+HiddenSlides
+Hiragana
+Horiz
+HyperlinkBase
+HyperlinksChanged
+ID
+IDREF
+IDREFS
+Icon
+Id
+Inc
+Institution
+InternetSite
+InternetSiteTitle
+Interview
+Interviewee
+Interviewer
+Inventor
+Issue
+JournalArticle
+JournalName
+JustLastX
+LCID
+LCT
+Label
+Last
+LineA
+Lines
+Link
+LinkType
+LinksUpToDate
+List
+ListItem
+LockText
+Locked
+LockedField
+M1
+M10
+M11
+M12
+M2
+M3
+M4
+M5
+M6
+M7
+M8
+M9
+MDY
+MMClips
+MYD
+Manager
+Map
+MapInfo
+MapOCX
+Max
+Medium
+Middle
+Min
+Misc
+Month
+MonthAccessed
+MoveWithCells
+Movie
+MultiLine
+MultiSel
+NA
+NCName
+NMTOKEN
+NMTOKENS
+NOTATION
+Name
+NameList
+Namespace
+NoThreeD
+NoThreeD2
+Note
+Notes
+NumberVolumes
+OLEObject
+OLEUPDATE_ALWAYS
+OLEUPDATE_ONCALL
+ObjectID
+ObjectType
+OnCall
+Override
+Page
+Pages
+Paragraphs
+PartName
+Patent
+PatentNumber
+Performance
+Performer
+PeriodicalTitle
+Person
+Pict
+PictOld
+PictPrint
+PictScreen
+Picture
+PresentationFormat
+PreserveFormat
+PreserveSortAFLayout
+PrintObject
+ProducerName
+ProductionCompany
+ProgID
+Properties
+PublicationTitle
+Publisher
+Q1
+Q2
+Q3
+Q4
+QName
+R1C1
+Radio
+RecalcAlways
+RecordingNumber
+Rect
+RectA
+RefOrder
+Relationship
+RelationshipReference
+Relationships
+RelationshipsGroupReference
+Report
+Reporter
+RootElement
+Row
+RowHidden
+ScaleCrop
+Schema
+SchemaID
+SchemaRef
+ScriptExtended
+ScriptLanguage
+ScriptLocation
+ScriptText
+Scroll
+SecretEdit
+Sel
+SelType
+SelectedStyle
+SelectionNamespaces
+Shape
+ShapeID
+SharedDoc
+ShortTitle
+ShowImportExportValidationErrors
+SignatureTime
+SizeWithCells
+Slides
+SoundRecording
+Source
+SourceId
+SourceType
+Sources
+Spin
+StandardNumber
+StateProvince
+Station
+StyleName
+Tag
+Target
+TargetMode
+Template
+TextHAlign
+TextVAlign
+Theater
+ThesisType
+Title
+TitlesOfParts
+TotalTime
+Translator
+True
+Type
+Types
+UIObj
+URI
+URL
+UpdateMode
+VScroll
+VTEdit
+Val
+ValidIds
+Value
+Version
+Visible
+Volume
+WidthMin
+Words
+Writer
+XY
+YDM
+YMD
+YZ
+Year
+YearAccessed
+ZX
+a
+aa
+above
+aboveAverage
+absSizeAnchor
+absolute
+absoluteAnchor
+abstractNum
+abstractNumId
+aca
+acc
+accPr
+accel
+accent1
+accent2
+accent3
+accent4
+accent5
+accent6
+accentBorderCallout1
+accentBorderCallout2
+accentBorderCallout3
+accentCallout1
+accentCallout2
+accentCallout3
+accentbar
+accumulate
+action
+actionButtonBackPrevious
+actionButtonBeginning
+actionButtonBlank
+actionButtonDocument
+actionButtonEnd
+actionButtonForwardNext
+actionButtonHelp
+actionButtonHome
+actionButtonInformation
+actionButtonMovie
+actionButtonReturn
+actionButtonSound
+active
+activeBorder
+activeCaption
+activeCell
+activeCellId
+activeCol
+activePane
+activeRecord
+activeRow
+activeSheetId
+activeTab
+activeWritingStyle
+actualPg
+ad
+add
+additionalCharacteristics
+additive
+addlxml
+addressBook
+addressFieldName
+adj
+adjLst
+adjust
+adjustColumnWidth
+adjustLineHeightInTable
+adjustRightInd
+adjusthandles
+administrators
+advAuto
+advClick
+advTm
+advise
+aft
+after
+afterAutospacing
+afterEffect
+afterGroup
+afterLines
+ahLst
+ahPolar
+ahXY
+aiueo
+aiueoFullWidth
+alg
+algIdExt
+algIdExtSource
+algn
+alias
+aliases
+aliceBlue
+align
+alignBordersAndEdges
+alignOff
+alignTablesRowByRow
+alignTx
+alignWithMargins
+alignment
+alignshape
+all
+allAtOnce
+allCaption
+allDrilled
+allLines
+allPages
+allPts
+allUniqueName
+allowBlank
+allowOverlap
+allowPNG
+allowPng
+allowRefreshQuery
+allowSpaceOfSameStyleInTable
+allowcomments
+allowincell
+allowoverlap
+aln
+alnAt
+alnScr
+alongPath
+alpha
+alphaBiLevel
+alphaCeiling
+alphaFloor
+alphaInv
+alphaLcParenBoth
+alphaLcParenR
+alphaLcPeriod
+alphaMod
+alphaModFix
+alphaOff
+alphaOutset
+alphaRepl
+alphaUcParenBoth
+alphaUcParenR
+alphaUcPeriod
+alt
+altChunk
+altChunkPr
+altLang
+altName
+althref
+always
+alwaysMergeEmptyNamespace
+alwaysShow
+alwaysShowPlaceholderText
+amt
+anchor
+anchorCtr
+anchorLock
+anchorlock
+anchorx
+anchory
+ancst
+ancstOrSelf
+and
+ang
+angle
+anim
+animBg
+animClr
+animEffect
+animLvl
+animMotion
+animOne
+animRot
+animScale
+annotation
+annotationRef
+antiqueWhite
+antsBlack
+antsRed
+any
+anyType
+anyURI
+appName
+appWorkspace
+apples
+applyAlignment
+applyAlignmentFormats
+applyBorder
+applyBorderFormats
+applyBreakingRules
+applyFill
+applyFont
+applyFontFormats
+applyNumberFormat
+applyNumberFormats
+applyPatternFormats
+applyProtection
+applyStyles
+applyToEnd
+applyToFront
+applyToSides
+applyWidthHeightFormats
+aqua
+aquamarine
+ar
+arabic1Minus
+arabic2Minus
+arabicAbjad
+arabicAlpha
+arabicDbPeriod
+arabicDbPlain
+arabicParenBoth
+arabicParenR
+arabicPeriod
+arabicPlain
+arc
+arcTo
+archedScallops
+arcsize
+area
+area3DChart
+areaChart
+areaError
+arg
+argPr
+argSz
+around
+arr
+array
+arrow
+arrowok
+artDeco
+asDisplayed
+ascending
+ascendingAlpha
+ascendingNatural
+ascii
+asciiTheme
+aspect
+aspectratio
+assign
+asst
+asteriskTotals
+atEnd
+atLeast
+atMost
+attachedSchema
+attachedTemplate
+attr
+attrName
+attrNameLst
+attribute
+audio
+audioCd
+audioFile
+author
+authorId
+authors
+auto
+autoAdjust
+autoCaption
+autoCaptions
+autoCompressPictures
+autoEnd
+autoExp
+autoFilter
+autoFilterDateGrouping
+autoFormatId
+autoFormatOverride
+autoHyphenation
+autoLoad
+autoNoTable
+autoPage
+autoPageBreaks
+autoRecover
+autoRedefine
+autoRepublish
+autoRev
+autoShow
+autoSortScope
+autoSpaceDE
+autoSpaceDN
+autoSpaceLikeWord95
+autoStart
+autoText
+autoTitleDeleted
+autoTxRot
+autoTxt
+autoUpdate
+autoUpdateAnimBg
+autoZero
+autofit
+autofitToFirstFixedWidthCell
+autoformat
+autolayout
+autorotationcenter
+avLst
+average
+avg
+avgSubtotal
+axId
+axPos
+axis
+axisCol
+axisPage
+axisRow
+axisValues
+azure
+b
+bCs
+bCtr
+bCtrCh
+bCtrDes
+bIns
+bL
+bMarg
+bOff
+bR
+babyPacifier
+babyRattle
+back
+backWall
+backdepth
+backdrop
+background
+background1
+background2
+backgroundQuery
+backgroundRefresh
+backupFile
+backward
+backwardCompatible
+backwards
+bal
+balanceSingleByteDoubleByteWidth
+balanced
+balloons3Colors
+balloonsHotAir
+band1H
+band1Horz
+band1V
+band1Vert
+band2H
+band2Horz
+band2V
+band2Vert
+bandCol
+bandFmt
+bandFmts
+bandRow
+banner
+bar
+bar3DChart
+barChart
+barDir
+barPr
+base
+base64Binary
+baseColWidth
+baseField
+baseItem
+baseJc
+baseTimeUnit
+baseType
+basedOn
+baseline
+basicBlackDashes
+basicBlackDots
+basicBlackSquares
+basicThinLines
+basicWhiteDashes
+basicWhiteDots
+basicWhiteSquares
+basicWideInline
+basicWideMidline
+basicWideOutline
+bats
+bbPlcHdr
+bc
+bdr
+bef
+before
+beforeAutospacing
+beforeLines
+beg
+begChr
+begMarg
+begPad
+begPts
+begSty
+begin
+beginsWith
+behavior
+behaviors
+behindDoc
+beige
+below
+belowAverage
+bend
+bendDist
+bendPt
+beneathText
+bentArrow
+bentConnector2
+bentConnector3
+bentConnector4
+bentConnector5
+bentUpArrow
+bestFit
+between
+bevel
+bevelB
+bevelT
+bg
+bg1
+bg2
+bgClr
+bgColor
+bgFillStyleLst
+bgPr
+bgRef
+bi
+biLevel
+bib
+bibliography
+bidi
+bidiVisual
+bilevel
+billions
+birds
+birdsFlight
+bisque
+bk
+bkPtFixedVal
+bkpt
+bl
+black
+blackAndWhite
+blackGray
+blackTextAndLines
+blackTextOnWhite
+blackWhite
+blacklevel
+blanchedAlmond
+blank
+blankRow
+bld
+bldAsOne
+bldChart
+bldDgm
+bldGraphic
+bldLst
+bldLvl
+bldOleChart
+bldP
+bldStep
+bldSub
+blend
+blinds
+blinkBackground
+blip
+blipFill
+blipPhldr
+blob
+block
+blockArc
+blockQuote
+blue
+blueMod
+blueOff
+blueViolet
+blur
+blurRad
+bmk
+body
+bodyDiv
+bodyPr
+bodyStyle
+bold
+boldItalic
+bookFoldPrinting
+bookFoldPrintingSheets
+bookFoldRevPrinting
+bookViews
+bookmarkEnd
+bookmarkIdSeed
+bookmarkStart
+bool
+boolVal
+boolean
+border
+borderBox
+borderBoxPr
+borderCallout1
+borderCallout2
+borderCallout3
+borderId
+borderbottom
+borderbottomcolor
+borderleft
+borderleftcolor
+borderright
+borderrightcolor
+borders
+bordersDoNotSurroundFooter
+bordersDoNotSurroundHeader
+bordertop
+bordertopcolor
+bot
+both
+bothSides
+bottom
+bottomFromText
+bottomLeft
+bottomMargin
+bottomRight
+boundingCube
+box
+boxPr
+br
+bracePair
+bracketPair
+branch
+breadthByLvl
+breadthByNode
+bright
+brightRoom
+brightness
+brk
+brkBin
+brkBinSub
+brown
+browse
+browser
+bstr
+btLr
+btnFace
+btnHighlight
+btnShadow
+btnText
+buAutoNum
+buBlip
+buChar
+buClr
+buClrTx
+buFont
+buFontTx
+buNone
+buSzPct
+buSzPts
+buSzTx
+bubble3D
+bubbleChart
+bubbleScale
+bubbleSize
+build
+builtIn
+builtInGroupCount
+builtInUnit
+builtinId
+bulEnabled
+bullet
+bulletEnabled
+bullseye
+burlyWood
+button
+bw
+bwMode
+bwmode
+bwnormal
+bwpure
+bx
+by
+byPosition
+byte
+c
+cBhvr
+cGp
+cGpRule
+cMediaNode
+cNvCxnSpPr
+cNvGraphicFramePr
+cNvGrpSpPr
+cNvPicPr
+cNvPr
+cNvSpPr
+cSld
+cSldViewPr
+cSp
+cTn
+cViewPr
+ca
+cabins
+cacheField
+cacheFields
+cacheHierarchies
+cacheHierarchy
+cacheId
+cacheIndex
+cacheSource
+cachedColBalance
+cadetBlue
+cakeSlice
+calcChain
+calcCompleted
+calcId
+calcMode
+calcOnExit
+calcOnSave
+calcPr
+calcmode
+calculated
+calculatedColumn
+calculatedColumnFormula
+calculatedItem
+calculatedItems
+calculatedMember
+calculatedMembers
+calendar
+calendarType
+call
+callout
+callout1
+callout2
+callout3
+camera
+can
+canSlip
+candyCorn
+cantSplit
+canvas
+cap
+caps
+caption
+captionBeginsWith
+captionBetween
+captionContains
+captionEndsWith
+captionEqual
+captionGreaterThan
+captionGreaterThanOrEqual
+captionLessThan
+captionLessThanOrEqual
+captionNotBeginsWith
+captionNotBetween
+captionNotContains
+captionNotEndsWith
+captionNotEqual
+captionText
+captions
+cardinalText
+caseSensitive
+cat
+catAx
+catLst
+catalog
+category
+categoryEl
+categoryIdx
+ccw
+ccwIn
+ccwOut
+cell
+cell3D
+cellColor
+cellComments
+cellDel
+cellIns
+cellIs
+cellMerge
+cellMeta
+cellMetadata
+cellSmartTag
+cellSmartTagPr
+cellSmartTags
+cellStyle
+cellStyleXfs
+cellStyles
+cellWatch
+cellWatches
+cellXfs
+celticKnotwork
+center
+centerContinuous
+centerGroup
+centered
+certificateBanner
+cf
+cfRule
+cfvo
+ch
+chAlign
+chDir
+chExt
+chMax
+chOff
+chOrder
+chPref
+chainLink
+champagneBottle
+changesSavedWin
+chapNum
+chapSep
+chapStyle
+char
+charRg
+charSpace
+character
+characterSpacingControl
+characteristic
+charset
+chart
+chartAndTx
+chartFormat
+chartFormats
+chartObject
+chartPlus
+chartSpace
+chartStar
+chartX
+chartreuse
+chartsheet
+checkBox
+checkCompatibility
+checkErrors
+checkStyle
+checked
+checkedBarBlack
+checkedBarColor
+checker
+checkered
+chevron
+chicago
+childStyle
+childTnLst
+chilly
+chineseCounting
+chineseCountingThousand
+chineseLegalSimplified
+chocolate
+choose
+chord
+chosung
+chr
+christmasTree
+chromakey
+circle
+circleNumDbPlain
+circleNumWdBlackPlain
+circleNumWdWhitePlain
+circlesLines
+circlesRectangles
+circularArrow
+citation
+class
+classic
+classicalWave
+clean
+clear
+clearAll
+clearComments
+clearContents
+clearFormats
+click
+clickAndTypeStyle
+clickEffect
+clickPar
+clientData
+clientInsertedTime
+clip
+clipArt
+clipArtAndTx
+clipArtAndVertTx
+clippath
+clipped
+cliptowrap
+clocks
+close
+cloud
+cloudCallout
+clr
+clrChange
+clrData
+clrFrom
+clrIdx
+clrMap
+clrMapOvr
+clrMode
+clrMru
+clrRepl
+clrScheme
+clrSchemeMapping
+clrSpc
+clrTo
+clrVal
+clsid
+clustered
+cm
+cmAuthor
+cmAuthorLst
+cmLst
+cmd
+cmpd
+cnfStyle
+cnt
+code
+codeName
+codePage
+coerce
+coherent3DOff
+col
+colBreaks
+colDelim
+colFields
+colFirst
+colGrandTotals
+colHeaderCaption
+colHierarchiesUsage
+colHierarchyUsage
+colId
+colItems
+colLast
+colOff
+colPageCount
+collapse
+collapsed
+collapsedLevelsAreSubtotals
+colon
+color
+color2
+colorFilter
+colorId
+colorScale
+colormenu
+colormode
+colormru
+colors
+colorsDef
+colorsDefHdr
+colorsDefHdrLst
+cols
+column
+columnSort
+comb
+combine
+combineBrackets
+comboBox
+commIndAndComment
+commIndicator
+commNone
+comma
+command
+commandType
+comment
+commentList
+commentRangeEnd
+commentRangeStart
+commentReference
+comments
+comp
+compact
+compactData
+compass
+compat
+compatLnSpc
+compatMode
+complex
+composite
+compressPunctuation
+compressPunctuationAndJapaneseKana
+computedArea
+concurrent
+concurrentCalc
+concurrentManualCount
+cond
+condense
+conditionalFormat
+conditionalFormats
+conditionalFormatting
+cone
+coneToMax
+confetti
+confettiGrays
+confettiOutline
+confettiStreamers
+confettiWhite
+conn
+connDist
+connRout
+connectString
+connectangles
+connection
+connectionId
+connections
+connectloc
+connectlocs
+connector
+connectortype
+connecttype
+consecutive
+consecutiveHyphenLimit
+consolidation
+constr
+constrLst
+constrainbounds
+cont
+contDir
+containsBlank
+containsBlanks
+containsDate
+containsErrors
+containsInteger
+containsMixedTypes
+containsNonDate
+containsNumber
+containsSemiMixedTypes
+containsString
+containsText
+content
+contentLocked
+contentStatus
+contentType
+contextualSpacing
+continuationNotice
+continuationSeparator
+continue
+continuous
+contourClr
+contourW
+contrast
+contrasting
+contributors
+control
+control1
+control2
+controls
+convMailMergeEsc
+convex
+coolSlant
+coordorigin
+coordsize
+copies
+copy
+coral
+coreProperties
+corner
+cornerTabs
+cornerTriangles
+cornflowerBlue
+cornsilk
+count
+countA
+countASubtotal
+countBy
+countNums
+countSubtotal
+couponCutoutDashes
+couponCutoutDots
+cover
+coverPg
+cp
+cr
+crashSave
+crazyMaze
+created
+createdVersion
+creator
+creaturesButterfly
+creaturesFish
+creaturesInsects
+creaturesLadyBug
+credentials
+crimson
+cropbottom
+cropleft
+cropping
+cropright
+croptop
+cross
+crossAx
+crossBetween
+crossStitch
+crosses
+crossesAt
+cryptAlgorithmClass
+cryptAlgorithmSid
+cryptAlgorithmType
+cryptProvider
+cryptProviderType
+cryptProviderTypeExt
+cryptProviderTypeExtSource
+cryptSpinCount
+cs
+csCatId
+csTypeId
+csb0
+csb1
+css
+cstate
+cstheme
+ct
+ctr
+ctrShpMap
+ctrTitle
+ctrX
+ctrXOff
+ctrY
+ctrYOff
+ctrlPr
+cube
+cubicBezTo
+culture
+cup
+curly
+current
+currentDate
+currentTime
+curve
+curved
+curvedConnector2
+curvedConnector3
+curvedConnector4
+curvedConnector5
+curvedDownArrow
+curvedLeftArrow
+curvedRightArrow
+curvedUpArrow
+cust
+custAng
+custAutoTxt
+custBib
+custClr
+custClrLst
+custCoverPg
+custDash
+custData
+custDataLst
+custEq
+custFlipHor
+custFlipVert
+custFtrs
+custGeom
+custHdrs
+custLinFactNeighborX
+custLinFactNeighborY
+custLinFactX
+custLinFactY
+custPgNum
+custPgNumB
+custPgNumMargins
+custPgNumT
+custQuickParts
+custRadScaleInc
+custRadScaleRad
+custScaleX
+custScaleY
+custShow
+custShowLst
+custSplit
+custSzX
+custSzY
+custT
+custTblOfContents
+custTbls
+custTxtBox
+custUnit
+custWatermarks
+custom
+custom1
+custom2
+custom3
+custom4
+custom5
+customBuiltin
+customFilter
+customFilters
+customFormat
+customHeight
+customList
+customListSort
+customMarkFollows
+customMenu
+customPr
+customProperties
+customRollUp
+customSheetView
+customSheetViews
+customStyle
+customView
+customWidth
+customWorkbookView
+customWorkbookViews
+customXml
+customXmlDelRangeEnd
+customXmlDelRangeStart
+customXmlInsRangeEnd
+customXmlInsRangeStart
+customXmlMoveFromRangeEnd
+customXmlMoveFromRangeStart
+customXmlMoveToRangeEnd
+customXmlMoveToRangeStart
+customXmlPr
+cut
+cw
+cwIn
+cwOut
+cx
+cxn
+cxnId
+cxnLst
+cxnSp
+cxnSpLocks
+cy
+cyan
+cycle
+cylinder
+d
+dLbl
+dLblPos
+dLbls
+dPr
+dPt
+dTable
+dark1
+dark2
+darkBlue
+darkCyan
+darkDown
+darkGray
+darkGreen
+darkGrid
+darkHorizontal
+darkMagenta
+darkRed
+darkTrellis
+darkUp
+darkVertical
+darkYellow
+darken
+darkenLess
+dash
+dashDnDiag
+dashDot
+dashDotDot
+dashDotDotHeavy
+dashDotHeavy
+dashDotStroked
+dashHeavy
+dashHorz
+dashLong
+dashLongHeavy
+dashSmallGap
+dashUpDiag
+dashVert
+dashed
+dashedHeavy
+dashedSmall
+dashstyle
+data
+dataBar
+dataBinding
+dataBound
+dataCaption
+dataCellStyle
+dataConsolidate
+dataDxfId
+dataExtractLoad
+dataField
+dataFields
+dataModel
+dataOnRows
+dataOnly
+dataPosition
+dataRef
+dataRefs
+dataSource
+dataSourceSort
+dataTable
+dataType
+dataValidation
+dataValidations
+database
+databaseField
+datastoreItem
+date
+date1904
+dateAx
+dateBetween
+dateEqual
+dateFormat
+dateGroupItem
+dateNewerThan
+dateNewerThanOrEqual
+dateNotBetween
+dateNotEqual
+dateOlderThan
+dateOlderThanOrEqual
+dateTime
+dateTimeGrouping
+day
+dayLong
+dayShort
+days
+dbColumn
+dbPr
+dbl
+dblStrike
+ddList
+ddeItem
+ddeItems
+ddeLink
+ddeService
+ddeTopic
+dec
+decagon
+decel
+decimal
+decimalEnclosedCircle
+decimalEnclosedCircleChinese
+decimalEnclosedFullstop
+decimalEnclosedParen
+decimalFullWidth
+decimalFullWidth2
+decimalHalfWidth
+decimalSymbol
+decimalZero
+decoArch
+decoArchColor
+decoBlocks
+decorated
+decorative
+deepPink
+deepSkyBlue
+def
+defJc
+defLockedState
+defPPr
+defQFormat
+defRPr
+defSemiHidden
+defStyle
+defTabSz
+defUIPriority
+defUnhideWhenUsed
+default
+defaultAttributeDrillState
+defaultColWidth
+defaultGridColor
+defaultMemberUniqueName
+defaultPivotStyle
+defaultRowHeight
+defaultSubtotal
+defaultTabStop
+defaultTableStyle
+defaultTextStyle
+defaultThemeVersion
+definedName
+definedNames
+deg
+degHide
+degree
+del
+del1
+del2
+delInstrText
+delText
+delay
+delete
+deleteCol
+deleteColumns
+deleteRow
+deleteRows
+deleted
+deletedField
+delimited
+delimiter
+den
+denormalized
+depth
+depthByBranch
+depthByNode
+depthPercent
+des
+desOrSelf
+desc
+descending
+descendingAlpha
+descendingNatural
+descr
+description
+destId
+destOrd
+destination
+destinationFile
+detectmouseclick
+dgm
+dgmbasetextscale
+dgmfontsize
+dgmlayout
+dgmlayoutmru
+dgmnodekind
+dgmscalex
+dgmscaley
+dgmstyle
+diagBrick
+diagCross
+diagStripe
+diagonal
+diagonalDown
+diagonalUp
+diagram
+dialogsheet
+diam
+diamond
+diamondsGray
+diff
+difference
+differentFirst
+differentOddEven
+diffusity
+dim
+dimGray
+dimension
+dimensionUniqueName
+dimensions
+dir
+dirty
+disableEdit
+disableFieldList
+disablePrompts
+disableRefresh
+disabled
+discrete
+discretePr
+diskRevisions
+dispBlanksAs
+dispDef
+dispEq
+dispRSqr
+dispUnits
+dispUnitsLbl
+displacedByCustomXml
+display
+displayBackgroundShape
+displayFolder
+displayHangulFixedWidth
+displayHorizontalDrawingGridEvery
+displayName
+displayText
+displayVerticalDrawingGridEvery
+displayed
+dissolve
+dist
+distB
+distL
+distR
+distT
+distance
+distribute
+distributeLetter
+distributeSpace
+distributed
+div
+divBdr
+divId
+divot
+divs
+divsChild
+dk1
+dk2
+dkBlue
+dkCyan
+dkDnDiag
+dkEdge
+dkGoldenrod
+dkGray
+dkGreen
+dkHorz
+dkKhaki
+dkMagenta
+dkOliveGreen
+dkOrange
+dkOrchid
+dkRed
+dkSalmon
+dkSeaGreen
+dkSlateBlue
+dkSlateGray
+dkTurquoise
+dkUpDiag
+dkVert
+dkViolet
+dllVersion
+dm
+dn
+dnDiag
+doNotAutoCompressPictures
+doNotAutofitConstrainedTables
+doNotBreakConstrainedForcedTable
+doNotBreakWrappedTables
+doNotCompress
+doNotDemarcateInvalidXml
+doNotDisplayPageBoundaries
+doNotEmbedSmartTags
+doNotExpandShiftReturn
+doNotHyphenateCaps
+doNotIncludeSubdocsInStats
+doNotLeaveBackslashAlone
+doNotOrganizeInFolder
+doNotRelyOnCSS
+doNotSaveAsSingleFile
+doNotShadeFormData
+doNotSnapToGridInCell
+doNotSuppressBlankLines
+doNotSuppressIndentation
+doNotSuppressParagraphBorders
+doNotTrackFormatting
+doNotTrackMoves
+doNotUseEastAsianBreakRules
+doNotUseHTMLParagraphAutoSpacing
+doNotUseIndentAsNumberingTabStop
+doNotUseLongFileNames
+doNotUseMarginsForDrawingGridOrigin
+doNotValidateAgainstSchema
+doNotVertAlignCellWithSp
+doNotVertAlignInTxbx
+doNotWrapTextWithPunct
+doc
+docDefaults
+docEnd
+docGrid
+docLocation
+docPart
+docPartBody
+docPartCategory
+docPartGallery
+docPartList
+docPartObj
+docPartPr
+docPartUnique
+docParts
+docPr
+docVar
+docVars
+document
+document1
+document2
+documentProtection
+documentType
+dodecagon
+dodgerBlue
+donut
+dos
+dot
+dotDash
+dotDashHeavy
+dotDmnd
+dotDotDash
+dotDotDashHeavy
+dotGrid
+dotted
+dottedHeavy
+double
+double-struck
+doubleAccounting
+doubleD
+doubleDiamonds
+doubleQuote
+doubleWave
+doubleclicknotify
+doughnutChart
+down
+downArrow
+downArrowCallout
+downBars
+downThenOver
+dpi
+dr
+draft
+dragOff
+dragToCol
+dragToData
+dragToPage
+dragToRow
+drawing
+drawingGridHorizontalOrigin
+drawingGridHorizontalSpacing
+drawingGridVerticalOrigin
+drawingGridVerticalSpacing
+drill
+drop
+dropCap
+dropDownList
+dropLines
+dropauto
+ds
+dstNode
+dstrike
+dt
+dt2D
+dtr
+duotone
+duplicateValues
+dur
+duration
+dvAspect
+dx
+dxa
+dxaOrig
+dxf
+dxfId
+dxfs
+dy
+dyaOrig
+dynamicAddress
+dynamicFilter
+dz
+e
+eMail
+ea
+ea1ChsPeriod
+ea1ChsPlain
+ea1ChtPeriod
+ea1ChtPlain
+ea1JpnChsDbPeriod
+ea1JpnKorPeriod
+ea1JpnKorPlain
+eaLnBrk
+eaVert
+eachPage
+eachSect
+earth1
+earth2
+eastAsia
+eastAsiaTheme
+eastAsianLayout
+eb
+eclipsingSquares1
+eclipsingSquares2
+ed
+edGrp
+edge
+edit
+editAs
+editData
+editPage
+editas
+edited
+editors
+effect
+effectClrLst
+effectDag
+effectExtent
+effectLst
+effectRef
+effectStyle
+effectStyleLst
+eggsBlack
+el
+elbow
+ellipse
+ellipseRibbon
+ellipseRibbon2
+ellipsis
+else
+em
+emDash
+email
+embed
+embedBold
+embedBoldItalic
+embedItalic
+embedRegular
+embedSystemFonts
+embedTrueTypeFonts
+embeddedFont
+embeddedFontLst
+emboss
+embosscolor
+emph
+empty
+emptyCellReference
+enDash
+enableDrill
+enableFieldProperties
+enableFormatConditionsCalculation
+enableRefresh
+enableWizard
+enabled
+encoding
+end
+endA
+endAngle
+endChr
+endCnv
+endCondLst
+endCxn
+endDate
+endMarg
+endNum
+endOfListFormulaUpdate
+endPad
+endParaRPr
+endPos
+endPts
+endSnd
+endSty
+endSync
+endarrow
+endarrowlength
+endarrowwidth
+endcap
+endnote
+endnotePr
+endnoteRef
+endnoteReference
+endnotes
+endsWith
+enforcement
+entr
+entries
+entry
+entryMacro
+envelopes
+eol
+eq
+eqArr
+eqArrPr
+eqn
+equ
+equal
+equalAverage
+equalWidth
+equation
+equationxml
+err
+errBarType
+errBars
+errDir
+errValType
+error
+errorCaption
+errorStyle
+errorTitle
+errors
+evalError
+evalOrder
+even
+evenAndOddHeaders
+evenFooter
+evenHeader
+evenPage
+everyone
+evt
+evtFilter
+exact
+excl
+exclusive
+exit
+exitMacro
+exp
+explosion
+expression
+ext
+extLst
+extend
+extendable
+extent
+external
+externalBook
+externalData
+externalLink
+externalReference
+externalReferences
+extraClrScheme
+extraClrSchemeLst
+extrusion
+extrusionClr
+extrusionH
+extrusionOk
+extrusioncolor
+extrusionok
+f
+fHdr
+fLocksText
+fLocksWithSheet
+fName
+fNode
+fPr
+fPrintsWithSheet
+fPublished
+facet
+fact
+factor
+fade
+fadeDir
+fallback
+false
+family
+fans
+fast
+fax
+fc
+ffData
+fgClr
+fgColor
+fi
+field
+fieldGroup
+fieldId
+fieldIdWrapped
+fieldListSortAscending
+fieldMapData
+fieldPosition
+fieldPrintTitles
+fieldUsage
+fieldsUsage
+fileRecoveryPr
+fileSharing
+fileType
+fileVersion
+filetime
+fill
+fillClrLst
+fillFormulas
+fillId
+fillOverlay
+fillRect
+fillRef
+fillStyleLst
+fillToRect
+fillcolor
+filled
+fillok
+fills
+filltype
+film
+filter
+filterColumn
+filterMode
+filterPrivacy
+filterUnique
+filterVal
+filters
+firebrick
+firecrackers
+first
+firstAndLastLine
+firstBackgroundRefresh
+firstCol
+firstColumn
+firstColumnStripe
+firstColumnSubheading
+firstDataCol
+firstDataRow
+firstFooter
+firstHeader
+firstHeaderCell
+firstHeaderRow
+firstLine
+firstLineChars
+firstLineOnly
+firstPage
+firstPageNumber
+firstRow
+firstRowStripe
+firstRowSubheading
+firstSheet
+firstSliceAng
+firstSlideNum
+firstSubtotalColumn
+firstSubtotalRow
+firstTotalCell
+fitText
+fitToHeight
+fitToPage
+fitToSlide
+fitToWidth
+fitpath
+fitshape
+fixed
+fixedVal
+flat
+flatBorders
+flatTx
+fld
+fldChar
+fldCharType
+fldData
+fldLock
+fldSimple
+flip
+flipH
+flipV
+float
+flood
+floor
+floralWhite
+flowChartAlternateProcess
+flowChartCollate
+flowChartConnector
+flowChartDecision
+flowChartDelay
+flowChartDisplay
+flowChartDocument
+flowChartExtract
+flowChartInputOutput
+flowChartInternalStorage
+flowChartMagneticDisk
+flowChartMagneticDrum
+flowChartMagneticTape
+flowChartManualInput
+flowChartManualOperation
+flowChartMerge
+flowChartMultidocument
+flowChartOfflineStorage
+flowChartOffpageConnector
+flowChartOnlineStorage
+flowChartOr
+flowChartPredefinedProcess
+flowChartPreparation
+flowChartProcess
+flowChartPunchedCard
+flowChartPunchedTape
+flowChartSort
+flowChartSummingJunction
+flowChartTerminator
+flowDir
+flowersBlockPrint
+flowersDaisies
+flowersModern1
+flowersModern2
+flowersPansy
+flowersRedRose
+flowersRoses
+flowersTeacup
+flowersTiny
+fltVal
+fmla
+fmt
+fmtId
+fmtScheme
+fmtid
+focus
+focusposition
+focussize
+folHlink
+foldedCorner
+follow
+followColorScheme
+followSib
+followedHyperlink
+font
+fontAlgn
+fontColor
+fontId
+fontKey
+fontRef
+fontScale
+fontScheme
+fontSz
+fonts
+footer
+footerReference
+footnote
+footnoteLayoutLikeWW8
+footnotePr
+footnoteRef
+footnoteReference
+footnotes
+for
+forEach
+forName
+forceAA
+forceFullCalc
+forceUpgrade
+forcedash
+foredepth
+forestGreen
+forgetLastTabAlignment
+formFld
+formLetters
+formProt
+format
+formatCells
+formatCode
+formatColumns
+formatRows
+formats
+formatting
+forms
+formsDesign
+formula
+formula1
+formula2
+formulaRange
+formulas
+forward
+fourObj
+fov
+fraktur
+frame
+frameLayout
+framePr
+frameSlides
+frameStyle1
+frameStyle2
+frameStyle3
+frameStyle4
+frameStyle5
+frameStyle6
+frameStyle7
+frameset
+framesetSplitbar
+freeze
+freezing
+from
+fromB
+fromL
+fromR
+fromT
+fromWordArt
+front
+frozen
+frozenSplit
+ftr
+ftrs
+fuchsia
+full
+fullAlpha
+fullCalcOnLoad
+fullDate
+fullHangul
+fullKatakana
+fullPage
+fullPrecision
+fullScrn
+fullwidthKatakana
+func
+funcPr
+function
+functionGroup
+functionGroupId
+functionGroups
+funnel
+futureMetadata
+g
+gDay
+gMonth
+gMonthDay
+gYear
+gYearMonth
+gain
+gainsboro
+gallery
+gamma
+ganada
+gap
+gapDepth
+gapWidth
+gd
+gdLst
+gdRefAng
+gdRefR
+gdRefX
+gdRefY
+ge
+gear6
+gear9
+gems
+general
+gfxdata
+ghostCol
+ghostRow
+ghostWhite
+gingerbreadMan
+glossaryDocument
+glow
+goal
+gold
+goldenrod
+grDir
+gradFill
+gradient
+gradientActiveCaption
+gradientCenter
+gradientFill
+gradientInactiveCaption
+gradientRadial
+gradientUnscaled
+gradientshapeok
+gramEnd
+gramStart
+grammar
+grand
+grandCol
+grandRow
+grandTotalCaption
+graphic
+graphicData
+graphicEl
+graphicFrame
+graphicFrameLocks
+grav
+gray
+gray0625
+gray125
+grayOutline
+grayScale
+grayText
+grayWhite
+grayscale
+grayscl
+greaterThan
+greaterThanOrEqual
+green
+greenMod
+greenOff
+greenYellow
+gregorian
+gregorianArabic
+gregorianMeFrench
+gregorianUs
+gregorianXlitEnglish
+gregorianXlitFrench
+gridAfter
+gridBefore
+gridCol
+gridDropZones
+gridLegend
+gridLines
+gridLinesSet
+gridSpacing
+gridSpan
+group
+groupBy
+groupChr
+groupChrPr
+groupInterval
+groupItems
+groupLevel
+groupLevels
+groupMember
+groupMembers
+grouping
+groups
+grow
+growAutofit
+growShrinkType
+grpFill
+grpId
+grpSp
+grpSpLocks
+grpSpPr
+gs
+gsLst
+gt
+gte
+guid
+guide
+guideLst
+gutter
+gutterAtTop
+h
+hAnchor
+hAnsi
+hAnsiTheme
+hArH
+hMerge
+hMode
+hOff
+hPercent
+hR
+hRule
+hSpace
+hagakiCard
+hair
+hairline
+half
+halfAlpha
+halfFrame
+halfHangul
+halfKatakana
+halfwidthKatakana
+handles
+handmade1
+handmade2
+handoutMaster
+handoutMasterId
+handoutMasterIdLst
+handoutView
+handouts1
+handouts2
+handouts3
+handouts4
+handouts6
+handouts9
+hang
+hanging
+hangingChars
+hangingPunct
+hardEdge
+harsh
+hasCustomPrompt
+hash
+hashData
+hdr
+hdrShapeDefaults
+hdrs
+headEnd
+header
+headerFooter
+headerReference
+headerRow
+headerRowBorderDxfId
+headerRowCellStyle
+headerRowCount
+headerRowDxfId
+headerSource
+headers
+headersInLastRefresh
+heading
+headings
+heart
+heartBalloon
+heartGray
+hearts
+heavy
+hebrew
+hebrew1
+hebrew2
+hebrew2Minus
+heebieJeebies
+help
+helpText
+heptagon
+hex
+hexBinary
+hexagon
+hf
+hiLowLines
+hidden
+hiddenButton
+hiddenColumn
+hiddenColumns
+hiddenLevel
+hiddenRow
+hiddenRows
+hiddenSlides
+hide
+hideBot
+hideGeom
+hideGrammaticalErrors
+hideLastTrans
+hideLeft
+hideMark
+hideNewItems
+hidePivotFieldList
+hideRight
+hideSpellingErrors
+hideTop
+hier
+hierAlign
+hierBranch
+hierChild
+hierRoot
+hierarchy
+hierarchyUsage
+high
+highContrast
+highKashida
+highlight
+highlightClick
+highlightText
+hijri
+hindiAlpha1Period
+hindiAlphaPeriod
+hindiConsonants
+hindiCounting
+hindiNumParenR
+hindiNumPeriod
+hindiNumbers
+hindiVowels
+hint
+hiragana
+history
+hlink
+hlinkClick
+hlinkHover
+hlinkMouseOver
+hold
+holeSize
+holly
+homePlate
+honeydew
+horizontal
+horizontalCentered
+horizontalDpi
+horizontalScroll
+horz
+horzAlign
+horzAnchor
+horzBarState
+horzBrick
+horzCross
+horzOverflow
+horzStripe
+hotLight
+hotPink
+hour
+hours
+houseFunky
+how
+hps
+hpsBaseText
+hpsRaise
+hqprint
+hr
+hralign
+href
+hrnoshade
+hrpct
+hrstd
+hsl
+hslClr
+ht
+htmlFormat
+htmlPubPr
+htmlTables
+hue
+hueDir
+hueMod
+hueOff
+hundredMillions
+hundredThousands
+hundreds
+hybridMultilevel
+hyperlink
+hyperlinks
+hyphen
+hyphenationZone
+hypnotic
+i
+i1
+i2
+i3
+i4
+i8
+iCs
+iLevel
+iMeasureFld
+iMeasureHier
+iceCreamCones
+icon
+iconFilter
+iconId
+iconSet
+id
+idcntr
+iddest
+identifier
+ideographDigital
+ideographEnclosedCircle
+ideographLegalTraditional
+ideographTraditional
+ideographZodiac
+ideographZodiacTraditional
+idmap
+idref
+idsrc
+idx
+if
+ignore
+ignoreMixedContent
+ignoredError
+ignoredErrors
+ilvl
+image
+imagealignshape
+imageaspect
+imagedata
+imagesize
+imeMode
+img
+imgH
+imgSz
+imgW
+immersive
+imprint
+in
+inBase
+inByRing
+inEnd
+inactiveBorder
+inactiveCaption
+inactiveCaptionText
+includeHiddenRowCol
+includeNewItemsInFilter
+includePrintSettings
+ind
+indefinite
+indent
+index
+indexed
+indexedColors
+indianRed
+indigo
+infoBk
+infoText
+information
+init
+initials
+ink
+inkAnnotations
+inkTgt
+inline
+inlineStr
+inner
+innerShdw
+inputCells
+ins
+insDel
+insertBlankRow
+insertClear
+insertCol
+insertColumns
+insertDelete
+insertHyperlinks
+insertPageBreak
+insertRow
+insertRowShift
+insertRows
+inset
+insetmode
+insetpen
+insetpenok
+inside
+insideH
+insideMargin
+insideV
+instr
+instrText
+int
+intLim
+intVal
+integer
+integrated
+interSp
+interactiveSeq
+intercept
+intermediate
+interval
+intraSp
+inv
+invGamma
+invGray
+invalEndChars
+invalStChars
+invalid
+invalidUrl
+inverseGray
+invertIfNegative
+invx
+invy
+iroha
+irohaFullWidth
+irregularSeal1
+irregularSeal2
+is
+isLgl
+isNarration
+isPhoto
+iscomment
+isometricBottomDown
+isometricBottomUp
+isometricLeftDown
+isometricLeftUp
+isometricOffAxis1Left
+isometricOffAxis1Right
+isometricOffAxis1Top
+isometricOffAxis2Left
+isometricOffAxis2Right
+isometricOffAxis2Top
+isometricOffAxis3Bottom
+isometricOffAxis3Left
+isometricOffAxis3Right
+isometricOffAxis4Bottom
+isometricOffAxis4Left
+isometricOffAxis4Right
+isometricRightDown
+isometricRightUp
+isometricTopDown
+isometricTopUp
+issignatureline
+italic
+item
+itemID
+itemPageCount
+itemPrintTitles
+items
+iterate
+iterateCount
+iterateDelta
+ivory
+japan
+japaneseCounting
+japaneseDigitalTenThousand
+japaneseLegal
+jc
+joinstyle
+just
+justLow
+justify
+justifyLastLine
+k
+keepAlive
+keepChangeHistory
+keepLines
+keepNext
+kern
+key
+keyAttribute
+keywords
+khaki
+kinsoku
+kiosk
+korea
+koreanCounting
+koreanDigital
+koreanDigital2
+koreanLegal
+kpi
+kpis
+kumimoji
+kx
+ky
+l
+lB
+lBounds
+lCtrCh
+lCtrDes
+lIns
+lMarg
+lMargin
+lOff
+lT
+label
+labelOnly
+landscape
+lang
+language
+largest
+last
+last7Days
+lastClick
+lastClr
+lastCol
+lastColumn
+lastEdited
+lastGuid
+lastHeaderCell
+lastIdx
+lastLineOnly
+lastModifiedBy
+lastMonth
+lastPrinted
+lastQuarter
+lastRenderedPageBreak
+lastRow
+lastTotalCell
+lastValue
+lastView
+lastWeek
+lastYear
+lat
+latentStyles
+latin
+latinLnBrk
+lavender
+lavenderBlush
+lawnGreen
+layout
+layoutDef
+layoutDefHdr
+layoutDefHdrLst
+layoutInCell
+layoutNode
+layoutRawTableWidth
+layoutTableRowsApart
+layoutTarget
+lblAlgn
+lblOffset
+ld
+le
+leader
+leaderLines
+ledger
+left
+leftArrow
+leftArrowCallout
+leftBrace
+leftBracket
+leftChars
+leftCircularArrow
+leftFromText
+leftLabels
+leftMargin
+leftRightArrow
+leftRightArrowCallout
+leftRightCircularArrow
+leftRightRibbon
+leftRightUpArrow
+leftUpArrow
+legacy
+legacyDrawing
+legacyDrawingHF
+legacyFlat1
+legacyFlat2
+legacyFlat3
+legacyFlat4
+legacyHarsh1
+legacyHarsh2
+legacyHarsh3
+legacyHarsh4
+legacyIndent
+legacyMatte
+legacyMetal
+legacyNormal1
+legacyNormal2
+legacyNormal3
+legacyNormal4
+legacyObliqueBottom
+legacyObliqueBottomLeft
+legacyObliqueBottomRight
+legacyObliqueFront
+legacyObliqueLeft
+legacyObliqueRight
+legacyObliqueTop
+legacyObliqueTopLeft
+legacyObliqueTopRight
+legacyPerspectiveBottom
+legacyPerspectiveBottomLeft
+legacyPerspectiveBottomRight
+legacyPerspectiveFront
+legacyPerspectiveLeft
+legacyPerspectiveRight
+legacyPerspectiveTop
+legacyPerspectiveTopLeft
+legacyPerspectiveTopRight
+legacyPlastic
+legacySpace
+legacyWireframe
+legend
+legendEntry
+legendPos
+lemonChiffon
+len
+length
+lengthspecified
+lessThan
+lessThanOrEqual
+letter
+level
+lg
+lgCheck
+lgConfetti
+lgDash
+lgDashDot
+lgDashDotDot
+lgGrid
+lid
+light1
+light2
+lightBulb
+lightDown
+lightGray
+lightGrayscale
+lightGrid
+lightHorizontal
+lightRig
+lightTrellis
+lightUp
+lightVertical
+lighten
+lightenLess
+lightface
+lightharsh
+lightharsh2
+lightlevel
+lightlevel2
+lightning1
+lightning2
+lightningBolt
+lightposition
+lightposition2
+lights
+lim
+limLoc
+limLow
+limLowPr
+limUpp
+limUppPr
+lime
+limeGreen
+limo
+lin
+linClrLst
+linDir
+line
+line3DChart
+lineChart
+lineInv
+lineMarker
+linePitch
+lineRule
+lineTo
+lineWrapLikeWord6
+linear
+linen
+lines
+linesAndChars
+linestyle
+lineStyleLst
+link
+linkStyles
+linkTarget
+linkToQuery
+linkedToFile
+list
+listDataValidation
+listEntry
+listItem
+listSeparator
+lit
+lkTxEntry
+ln
+lnB
+lnBlToTr
+lnDef
+lnL
+lnNumType
+lnR
+lnRef
+lnSpAfChP
+lnSpAfParP
+lnSpCh
+lnSpPar
+lnSpc
+lnSpcReduction
+lnStyleLst
+lnT
+lnTlToBr
+lnTo
+lo
+loCatId
+loTypeId
+local
+localConnection
+localRefresh
+localSheetId
+location
+lock
+lockRevision
+lockStructure
+lockWindows
+locked
+lockedCanvas
+lockrotationcenter
+log
+logBase
+lon
+long
+longCurve
+longFileNames
+longText
+loop
+low
+lowKashida
+lowerLetter
+lowerRoman
+lowestEdited
+lpstr
+lpwstr
+lrTb
+lrTbV
+lsdException
+lstStyle
+lt
+lt1
+lt2
+ltBlue
+ltCoral
+ltCyan
+ltDnDiag
+ltGoldenrodYellow
+ltGray
+ltGreen
+ltHorz
+ltPink
+ltSalmon
+ltSeaGreen
+ltSkyBlue
+ltSlateGray
+ltSteelBlue
+ltUpDiag
+ltVert
+ltYellow
+lte
+lu
+lum
+lumMod
+lumOff
+lvl
+lvl1pPr
+lvl2pPr
+lvl3pPr
+lvl4pPr
+lvl5pPr
+lvl6pPr
+lvl7pPr
+lvl8pPr
+lvl9pPr
+lvlAtOnce
+lvlJc
+lvlOne
+lvlOverride
+lvlPicBulletId
+lvlRestart
+lvlText
+m
+mPr
+mac
+macro
+magenta
+mailAsAttachment
+mailMerge
+mailSubject
+mailingLabels
+main
+mainDocumentType
+mainSeq
+major
+majorAscii
+majorBidi
+majorEastAsia
+majorFont
+majorGridlines
+majorHAnsi
+majorTickMark
+majorTimeUnit
+majorUnit
+man
+manifestLocation
+manual
+manualBreakCount
+manualLayout
+map
+mapId
+mapPins
+mapleLeaf
+mapleMuffins
+mappedName
+mappingCount
+maps
+marB
+marBottom
+marH
+marL
+marLeft
+marR
+marRight
+marT
+marTop
+marW
+margin
+marker
+markup
+maroon
+marquee
+marqueeToothed
+master
+masterClrMapping
+masterPages
+masterRel
+match
+matchSrc
+matchingName
+mathDivide
+mathEqual
+mathFont
+mathMinus
+mathMultiply
+mathNotEqual
+mathPlus
+mathPr
+matrix
+matte
+max
+maxAng
+maxDate
+maxDepth
+maxDist
+maxLength
+maxMin
+maxR
+maxRId
+maxRank
+maxSheetId
+maxSubtotal
+maxVal
+maxValue
+maxX
+maxY
+maximized
+mc
+mcJc
+mcPr
+mcs
+mdx
+mdxMetadata
+mdxSubqueries
+measure
+measureFilter
+measureGroup
+measureGroups
+measures
+med
+medAquamarine
+medBlue
+medOrchid
+medPurple
+medSeaGreen
+medSlateBlue
+medSpringGreen
+medTurquoise
+medVioletRed
+media
+mediaAndTx
+mediacall
+medium
+mediumDashDot
+mediumDashDotDot
+mediumDashed
+mediumGray
+mediumKashida
+member
+memberName
+memberPropertyField
+memberValueDatatype
+members
+menu
+menuBar
+menuHighlight
+menuText
+merge
+mergeCell
+mergeCells
+mergeInterval
+mergeItem
+metadata
+metadataStrings
+metadataType
+metadataTypes
+metal
+meth
+method
+mid
+midCat
+midL
+midR
+middle
+middleDot
+midnightBlue
+millions
+min
+minAng
+minDate
+minLength
+minMax
+minR
+minRId
+minRefreshableVersion
+minSubtotal
+minSupportedVersion
+minValue
+minVer
+minX
+minY
+minimized
+minimumVersion
+minor
+minorAscii
+minorBidi
+minorEastAsia
+minorFont
+minorGridlines
+minorHAnsi
+minorTickMark
+minorTimeUnit
+minorUnit
+mintCream
+minus
+minusx
+minusy
+minute
+minutes
+mirrorIndents
+mirrorMargins
+missingCaption
+missingItemsLimit
+mistyRose
+miter
+miterlimit
+moccasin
+mod
+modelId
+modern
+modified
+modifyVerifier
+mongolianVert
+monospace
+month
+monthLong
+monthShort
+months
+moon
+moons
+morning
+mosaic
+moveFrom
+moveFromRangeEnd
+moveFromRangeStart
+moveTo
+moveToRangeEnd
+moveToRangeStart
+moveWith
+movie
+movingAvg
+mp
+mpFld
+mpMap
+mps
+mr
+mruColors
+ms
+mult
+multiLevelType
+multiLine
+multiLvlStrCache
+multiLvlStrRef
+multilevel
+multipleFieldFilters
+multipleItemSelectionAllowed
+musicNotes
+mute
+mwSmallCaps
+n
+na
+name
+nameLen
+namespaceUri
+namespaceuri
+narHorz
+narVert
+narrow
+nary
+naryLim
+naryPr
+native
+navajoWhite
+navy
+nc
+nd
+ndxf
+neCell
+negativeInteger
+neq
+never
+new
+newDocument
+newLength
+newName
+newPage
+newSection
+newsflash
+next
+nextAc
+nextClick
+nextColumn
+nextCondLst
+nextId
+nextMonth
+nextPage
+nextQuarter
+nextTo
+nextWeek
+nextYear
+nf
+nil
+nlCheck
+noAdjustHandles
+noArr
+noAutofit
+noBar
+noBorder
+noBreak
+noBreakHyphen
+noChangeArrowheads
+noChangeAspect
+noChangeShapeType
+noColumnBalance
+noControl
+noConversion
+noCrop
+noDrilldown
+noEditPoints
+noEndCap
+noEndnote
+noExtraLineSpacing
+noFill
+noGrp
+noIndicator
+noLabel
+noLeading
+noLineBreaksAfter
+noLineBreaksBefore
+noMove
+noMultiLvlLbl
+noProof
+noPunctuationKerning
+noResize
+noResizeAllowed
+noRot
+noSelect
+noSmoking
+noSpaceRaiseLower
+noStrike
+noTabHangInd
+noTextEdit
+noUngrp
+noWrap
+node
+nodeHorzAlign
+nodePh
+nodeType
+nodeVertAlign
+nonAsst
+nonAutoSortDefault
+nonIsoscelesTrapezoid
+nonNegativeInteger
+nonNorm
+nonPositiveInteger
+none
+nor
+norm
+normAutofit
+normal
+normalViewPr
+normalizeH
+normalizedString
+northwest
+notBeside
+notBetween
+notContains
+notContainsBlanks
+notContainsErrors
+notContainsText
+notEqual
+notFirstPage
+notSpecified
+notTrueType
+notchedRightArrow
+notes
+notesMaster
+notesMasterId
+notesMasterIdLst
+notesMasterView
+notesStyle
+notesSz
+notesTextViewPr
+notesView
+notesViewPr
+nothing
+np
+ns
+nsid
+null
+num
+numCache
+numCol
+numFmt
+numFmtId
+numFmts
+numId
+numIdMacAtCleanup
+numLit
+numPicBullet
+numPicBulletId
+numPr
+numRef
+numRestart
+numSld
+numStart
+numStyleLink
+numTab
+number
+numberInDash
+numberStoredAsText
+numbering
+numberingChange
+nvCxnSpPr
+nvGraphicFramePr
+nvGrpSpPr
+nvPicPr
+nvPr
+nvSpPr
+nwCell
+o
+oMath
+oMathPara
+oMathParaPr
+obj
+objAndTwoObj
+objAndTx
+objDist
+objOnly
+objOverTx
+objTx
+object
+objectDefaults
+objects
+obliqueBottom
+obliqueBottomLeft
+obliqueBottomRight
+obliqueLeft
+obliqueRight
+obliqueTop
+obliqueTopLeft
+obliqueTopRight
+oblob
+obscured
+oc
+octagon
+odbc
+odcFile
+oddFooter
+oddHeader
+oddPage
+odso
+odxf
+ofPieChart
+ofPieType
+off
+offset
+offset2
+offsetFrom
+olapFunctions
+olapPr
+old
+oldComment
+oldCustomMenu
+oldDescription
+oldFormula
+oldFunction
+oldFunctionGroupId
+oldHelp
+oldHidden
+oldLace
+oldLength
+oldName
+oldPh
+oldQuotePrefix
+oldShortcutKey
+oldStatusBar
+ole
+oleChartEl
+oleItem
+oleItems
+oleLink
+oleObj
+oleObject
+oleObjects
+oleSize
+oleUpdate
+oleicon
+oleid
+olive
+oliveDrab
+on
+onBegin
+onClick
+onDblClick
+onEnd
+onMouseOut
+onMouseOver
+onNext
+onPrev
+onStopAudio
+one
+oneCell
+oneCellAnchor
+oneField
+oned
+onlySync
+onlyUseConnectionFile
+op
+opEmu
+opacity
+opacity2
+open
+openDmnd
+operator
+optimizeForBrowser
+optimizeMemory
+orange
+orangeRed
+orchid
+order
+ordinal
+ordinalText
+orgChart
+organizeInFolders
+orgchart
+orient
+orientation
+orientationangle
+origin
+original
+orthographicFront
+ostorage
+ostream
+other
+otherStyle
+out
+outByRing
+outEnd
+outer
+outerShdw
+outline
+outline1pPr
+outline2pPr
+outlineData
+outlineLevel
+outlineLevelCol
+outlineLevelRow
+outlineLvl
+outlinePr
+outlineSymbols
+outlineView
+outlineViewPr
+outset
+outside
+outsideMargin
+oval
+ovals
+over
+overThenDown
+overflow
+overflowPunct
+overhead
+overlap
+overlay
+override
+overrideClrMapping
+overwriteClear
+owners
+p
+pBdr
+pLen
+pPos
+pPr
+pPrChange
+pPrDefault
+pRg
+pStyle
+packages
+page
+pageBottom
+pageBreakBefore
+pageBreakPreview
+pageField
+pageFieldLabels
+pageFieldValues
+pageFields
+pageItem
+pageLayout
+pageMargins
+pageOrder
+pageOverThenDown
+pageSetUpPr
+pageSetup
+pageStyle
+pageWrap
+pages
+paleGoldenrod
+paleGreen
+paleTurquoise
+paleVioletRed
+palmsBlack
+palmsColor
+pane
+panose
+panose1
+papayaWhip
+paperClips
+paperSize
+paperSrc
+papyrus
+par
+parOf
+parTrans
+parTransId
+parTxLTRAlign
+parTxRTLAlign
+paragraph
+parallel
+parallelogram
+param
+parameter
+parameterType
+parameters
+parent
+parentSet
+parsePre
+partyFavor
+partyGlass
+password
+pasteAll
+pasteBorders
+pasteColWidths
+pasteComments
+pasteDataValidation
+pasteFormats
+pasteFormulas
+pasteNumberFormats
+pasteValues
+path
+pathEditMode
+pathLst
+pattFill
+pattern
+patternFill
+patternType
+pct
+pct10
+pct12
+pct15
+pct20
+pct25
+pct30
+pct35
+pct37
+pct40
+pct45
+pct5
+pct50
+pct55
+pct60
+pct62
+pct65
+pct70
+pct75
+pct80
+pct85
+pct87
+pct90
+pct95
+peachPuff
+penClr
+pencils
+pentagon
+people
+peopleHats
+peopleWaving
+percent
+percentDiff
+percentOfCol
+percentOfRow
+percentOfTotal
+percentStacked
+percentage
+percentile
+period
+permEnd
+permStart
+personal
+personalCompose
+personalReply
+personalView
+perspective
+perspectiveAbove
+perspectiveAboveLeftFacing
+perspectiveAboveRightFacing
+perspectiveBelow
+perspectiveContrastingLeftFacing
+perspectiveContrastingRightFacing
+perspectiveFront
+perspectiveHeroicExtremeLeftFacing
+perspectiveHeroicExtremeRightFacing
+perspectiveHeroicLeftFacing
+perspectiveHeroicRightFacing
+perspectiveLeft
+perspectiveRelaxed
+perspectiveRelaxedModerately
+perspectiveRight
+peru
+pg
+pgBorders
+pgMar
+pgNum
+pgNumB
+pgNumMargins
+pgNumT
+pgNumType
+pgSz
+ph
+phClr
+phant
+phantPr
+phldr
+phldrT
+phonetic
+phoneticPr
+photoAlbum
+pic
+picLocks
+picTx
+pict
+picture
+pictureFormat
+pictureOptions
+pictureStackUnit
+pid
+pie
+pie3DChart
+pieChart
+pieWedge
+pinYin
+pink
+pitch
+pitchFamily
+pivot
+pivotArea
+pivotAreas
+pivotButton
+pivotCache
+pivotCacheDefinition
+pivotCacheRecords
+pivotCaches
+pivotField
+pivotFields
+pivotFmt
+pivotFmts
+pivotHierarchies
+pivotHierarchy
+pivotSelection
+pivotSource
+pivotTable
+pivotTableDefinition
+pivotTableStyle
+pivotTableStyleInfo
+pivotTables
+pixelsPerInch
+placeholder
+placeholders
+plaid
+plane
+plaque
+plaqueTabs
+plastic
+plcHide
+plotArea
+plotVisOnly
+plum
+plus
+poinsettias
+points
+polar
+poly
+polyline
+portrait
+pos
+posEven
+posOdd
+posOffset
+position
+positionH
+positionV
+positiveInteger
+post
+postSp
+postageStamp
+powder
+powderBlue
+power
+prLst
+prSet
+preSp
+preced
+precedSib
+preferPic
+preferRelativeResize
+preferSingleView
+preferrelative
+prefixMappings
+pres
+presAssocID
+presId
+presLayoutVars
+presName
+presOf
+presParOf
+presStyleCnt
+presStyleIdx
+presStyleLbl
+present
+presentation
+presentationAccent
+presentationPr
+presentationText
+preserve
+preserveFormatting
+preserveHistory
+preserveSortFilterLayout
+presetClass
+presetID
+presetSubtype
+prev
+prevAc
+prevCondLst
+previousCol
+previousRow
+pri
+primFontSz
+print
+printArea
+printBodyTextBeforeHeader
+printColBlack
+printDrill
+printFormsData
+printFractionalCharacterWidth
+printOptions
+printPostScriptOverText
+printSettings
+printTwoOnOne
+printer
+printerSettings
+priority
+prnPr
+prnWhat
+product
+productSubtotal
+progId
+progress
+prompt
+promptTitle
+promptedSolutions
+proofErr
+proofState
+property
+propertyName
+prot
+protected
+protectedRange
+protectedRanges
+protection
+provid
+proxy
+prst
+prstClr
+prstDash
+prstGeom
+prstMaterial
+prstShdw
+prstTxWarp
+pt
+ptCount
+ptInCategory
+ptInSeries
+ptLst
+ptType
+ptab
+ptsTypes
+pubBrowser
+publishItems
+publishToServer
+published
+pull
+pumpkin1
+purple
+push
+pushPinNote1
+pushPinNote2
+pyra
+pyraAcctBkgdNode
+pyraAcctPos
+pyraAcctRatio
+pyraAcctTxMar
+pyraAcctTxNode
+pyraLvlNode
+pyramid
+pyramidToMax
+pyramids
+pyramidsAbove
+qFormat
+qs
+qsCatId
+qsTypeId
+quadArrow
+quadArrowCallout
+quadBezTo
+quadrants
+qualifier
+quarter
+quarters
+query
+queryCache
+queryFailed
+queryTable
+queryTableDeletedFields
+queryTableField
+queryTableFieldId
+queryTableFields
+queryTableRefresh
+quickTimeFile
+quotePrefix
+r
+r1
+r2
+r4
+r8
+rAng
+rAngAx
+rB
+rCtr
+rCtrCh
+rCtrDes
+rFont
+rFonts
+rId
+rIns
+rMarg
+rMargin
+rOff
+rPh
+rPr
+rPrChange
+rPrDefault
+rSp
+rSpRule
+rStyle
+rT
+ra
+rad
+radPr
+radarChart
+radarStyle
+radial
+radiusrange
+raf
+random
+randomBar
+range
+rangePr
+rangeSet
+rangeSets
+rank
+rankBy
+rc
+rcc
+rcft
+rcmt
+rctx
+rcv
+rd
+rdn
+readModeInkLockDown
+readOnly
+readOnlyRecommended
+readingOrder
+realTimeData
+recipientData
+recipients
+recolor
+recolortarget
+recommended
+reconnectionMethod
+recordCount
+rect
+red
+redMod
+redOff
+ref
+ref3D
+refError
+refFor
+refForName
+refMode
+refPtType
+refType
+reference
+references
+refersTo
+reflection
+refreshAllConnections
+refreshError
+refreshOnChange
+refreshOnLoad
+refreshedBy
+refreshedDate
+refreshedVersion
+regroupid
+regrouptable
+regular
+rel
+relIds
+relOff
+relSizeAnchor
+relation
+relationtable
+relative
+relativeFrom
+relativeHeight
+relativeIndent
+relativeTo
+relaxedInset
+relid
+relyOnVML
+relyOnVml
+remove
+removeDataOnSave
+removeDateAndTime
+removePersonalInfoOnSave
+removePersonalInformation
+render
+repairLoad
+repeat
+repeatCount
+repeatDur
+repl
+resId
+reservationPassword
+resizeGraphics
+resizeHandles
+rest
+restart
+restored
+restoredLeft
+restoredTop
+result
+rev
+revDir
+revPos
+reverse
+reverseDiagStripe
+reviewed
+reviewedList
+revision
+revisionId
+revisionView
+revisions
+revisionsPassword
+rfmt
+rgb
+rgbColor
+ribbon
+ribbon2
+riblet
+rich
+richText
+rig
+right
+rightArrow
+rightArrowCallout
+rightBrace
+rightBracket
+rightChars
+rightFromText
+rightMargin
+rightToLeft
+rightVertical
+rings
+ris
+rm
+rnd
+roman
+romanLcParenBoth
+romanLcParenR
+romanLcPeriod
+romanUcParenBoth
+romanUcParenR
+romanUcPeriod
+root
+rosyBrown
+rot
+rotPath
+rotWithShape
+rotX
+rotY
+rotate
+rotation
+rotationangle
+rotationcenter
+round
+round1Rect
+round2DiagRect
+round2SameRect
+roundRect
+roundedCorners
+roundrect
+row
+rowBreaks
+rowColShift
+rowDrillCount
+rowFields
+rowGrandTotals
+rowHeaderCaption
+rowHierarchiesUsage
+rowHierarchyUsage
+rowItems
+rowNumbers
+rowOff
+rowPageCount
+rowSpan
+rows
+royalBlue
+rqt
+rrc
+rsaAES
+rsaFull
+rsid
+rsidDel
+rsidP
+rsidR
+rsidRDefault
+rsidRPr
+rsidRoot
+rsidSect
+rsidTr
+rsids
+rsnm
+rt
+rtShortDist
+rtTriangle
+rtf
+rtl
+rtlCol
+rtlGutter
+rtn
+ru
+ruby
+rubyAlign
+rubyBase
+rubyPr
+rule
+ruleLst
+rules
+runTotal
+rupBuild
+russianLower
+russianUpper
+s
+sId
+sPre
+sPrePr
+sSub
+sSubPr
+sSubSup
+sSubSupPr
+sSup
+sSupPr
+saddleBrown
+safari
+saka
+salmon
+salt
+saltData
+sameClick
+sameDir
+sampData
+sandyBrown
+sans-serif
+sat
+satMod
+satOff
+saveData
+saveExternalLinkValues
+saveFormsData
+saveInvalidXml
+savePassword
+savePreviewPicture
+saveSmartTagsAsXml
+saveSubsetFonts
+saveThroughXslt
+saveXmlDataOnly
+sawtooth
+sawtoothGray
+sb
+scale
+scaleToFitPaper
+scaleWithDoc
+scaled
+scaling
+scaredCat
+scatterChart
+scatterStyle
+scenario
+scenarios
+scene3d
+schema
+schemaLibrary
+schemaLocation
+schemaRef
+schemaRefs
+scheme
+schemeClr
+scope
+scr
+screen
+screen16x10
+screen16x9
+screen4x3
+scrgbClr
+script
+scrollBar
+scrollbar
+sd
+sdt
+sdtContent
+sdtContentLocked
+sdtEndPr
+sdtLocked
+sdtPr
+seCell
+seaGreen
+seaShell
+seattle
+secChAlign
+secFontSz
+secHead
+secLinDir
+secSibSp
+second
+secondColumnStripe
+secondColumnSubheading
+secondPiePt
+secondPieSize
+secondRowStripe
+secondRowSubheading
+secondSubtotalColumn
+secondSubtotalRow
+seconds
+sectEnd
+sectPr
+sectPrChange
+securityDescriptor
+seek
+segments
+selectFldWithFirstOrLastChar
+selectLockedCells
+selectUnlockedCells
+selected
+selection
+self
+semiHidden
+semicolon
+sendLocale
+sep
+sepChr
+separate
+separator
+seq
+ser
+serAx
+serLines
+series
+seriesEl
+seriesIdx
+serverCommand
+serverField
+serverFill
+serverFont
+serverFontColor
+serverFormat
+serverFormats
+serverNumberFormat
+serverSldId
+serverSldModifiedTime
+serverZoom
+set
+setDefinition
+sets
+settings
+shade
+shadeToTitle
+shadow
+shadowcolor
+shadowedSquares
+shadowok
+shape
+shapeDefaults
+shapeId
+shapeLayoutLikeWW8
+shapedefaults
+shapeid
+shapelayout
+shapetype
+shared
+sharedItems
+sharksTeeth
+shd
+shdw1
+shdw10
+shdw11
+shdw12
+shdw13
+shdw14
+shdw15
+shdw16
+shdw17
+shdw18
+shdw19
+shdw2
+shdw20
+shdw3
+shdw4
+shdw5
+shdw6
+shdw7
+shdw8
+shdw9
+sheet
+sheetCalcPr
+sheetData
+sheetDataSet
+sheetFormatPr
+sheetId
+sheetIdMap
+sheetName
+sheetNames
+sheetPosition
+sheetPr
+sheetProtection
+sheetView
+sheetViews
+sheets
+shimmer
+shingle
+shininess
+shorebirdTracks
+short
+shortcutKey
+show
+showAll
+showAnimation
+showAsCaption
+showAsIcon
+showAutoFilter
+showBorderUnselectedTables
+showBreaksInFrames
+showBubbleSize
+showButton
+showCalcMbrs
+showCaptions
+showCatName
+showCell
+showColHeaders
+showColStripes
+showColumnStripes
+showComments
+showDLblsOverMax
+showDataAs
+showDataDropDown
+showDataTips
+showDrill
+showDropDown
+showDropDowns
+showDropZones
+showEmptyCol
+showEmptyRow
+showEnvelope
+showError
+showErrorMessage
+showFirstColumn
+showFormatting
+showFormulaBar
+showFormulas
+showGridLines
+showGuides
+showHeader
+showHeaders
+showHorizontalScroll
+showHorzBorder
+showInFieldList
+showInkAnnotation
+showInputMessage
+showItems
+showKeys
+showLastColumn
+showLeaderLines
+showLegendKey
+showMasterPhAnim
+showMasterSp
+showMemberPropertyTips
+showMissing
+showMultipleLabel
+showNarration
+showNegBubbles
+showObjects
+showOutline
+showOutlineIcons
+showOutlineSymbols
+showPageBreaks
+showPercent
+showPivotChartFilter
+showPr
+showPropAsCaption
+showPropCell
+showPropTip
+showRowCol
+showRowColHeaders
+showRowHeaders
+showRowStripes
+showRuler
+showScrollbar
+showSerName
+showSheetTabs
+showSpeakerNotes
+showSpecialPlsOnTitleSld
+showStatusbar
+showTip
+showVal
+showValue
+showVertBorder
+showVerticalScroll
+showWhenStopped
+showWhiteSpace
+showXMLTags
+showZeros
+showingPlcHdr
+showsigndate
+shp
+shpTxLTRAlignCh
+shpTxRTLAlignCh
+shrinkToFit
+si
+sib
+sibSp
+sibTrans
+sibTransId
+side
+sideWall
+sienna
+sig
+sigma
+signatureline
+signinginstructions
+signinginstructionsset
+sigprovurl
+silver
+simplePos
+single
+singleAccounting
+singleLevel
+singleQuote
+singleSignOnId
+singleXmlCell
+singleXmlCells
+singleclick
+size
+sizeAuto
+sizeRepresents
+skew
+skewamt
+skewangle
+skip
+skipTimed
+skw
+skyBlue
+skyrocket
+slantDashDot
+slateBlue
+slateGray
+sld
+sldAll
+sldId
+sldIdLst
+sldImg
+sldLayout
+sldLayoutId
+sldLayoutIdLst
+sldLst
+sldMaster
+sldMasterId
+sldMasterIdLst
+sldMasterView
+sldNum
+sldRg
+sldSorterView
+sldSyncPr
+sldSz
+sldTgt
+sldThumbnailView
+sldView
+slideViewPr
+slides
+slope
+slow
+sm
+smCheck
+smConfetti
+smGrid
+small
+smallCaps
+smallFrac
+smartTag
+smartTagPr
+smartTagType
+smartTagTypes
+smartTags
+smileyFace
+smooth
+smoothMarker
+smtClean
+smtId
+snake
+snapToChars
+snapToGrid
+snapToObjects
+snapVertSplitter
+snd
+sndAc
+sndTgt
+sng
+sngStrike
+snip1Rect
+snip2DiagRect
+snip2SameRect
+snipRoundRect
+snow
+snowflakeFancy
+snowflakes
+soft
+softEdge
+softHyphen
+softRound
+softmetal
+solid
+solidDmnd
+solidFill
+solutionID
+solveOrder
+sombrero
+sort
+sortBy
+sortByTuple
+sortCondition
+sortMethod
+sortState
+sortType
+sorterViewPr
+source
+sourceData
+sourceFile
+sourceFileName
+sourceLinked
+sourceObject
+sourceRef
+sourceSheetId
+sourceType
+southwest
+sp
+sp3d
+spAutoFit
+spDef
+spLocks
+spPr
+spTgt
+spTree
+space
+spaceForUL
+spacing
+spacingInWholePoints
+span
+spanAng
+spans
+sparkle
+spc
+spcAft
+spcBef
+spcCol
+spcFirstLastPara
+spcPct
+spcPts
+spd
+specVanish
+specularity
+spellEnd
+spellStart
+speller
+spelling
+sphere
+spid
+spidmax
+spinCount
+split
+splitAll
+splitFirst
+splitPgBreakAndParaMark
+splitPos
+splitType
+spokes
+spreadsheet
+springGreen
+spt
+sq
+sqlType
+sqref
+square
+squareTabs
+src
+srcId
+srcNode
+srcOrd
+srcRect
+srgbClr
+sst
+st
+stA
+stAng
+stBulletLvl
+stCondLst
+stCxn
+stElem
+stPos
+stSnd
+stack
+stackScale
+stacked
+standard
+star
+star10
+star12
+star16
+star24
+star32
+star4
+star5
+star6
+star7
+star8
+stars
+stars3d
+starsBlack
+starsShadowed
+starsTop
+start
+startAngle
+startAt
+startDate
+startNum
+startOverride
+startarrow
+startarrowlength
+startarrowwidth
+state
+status
+statusBar
+statusText
+std
+stdDev
+stdDevP
+stdDevPSubtotal
+stdDevSubtotal
+stdDevp
+stdErr
+stealth
+steelBlue
+stemThick
+step
+stockChart
+stop
+stopIfTrue
+storage
+storeItemID
+storeMappedDataAs
+stored
+stp
+str
+strCache
+strLit
+strRef
+strVal
+stra
+straight
+straightConnector1
+stream
+stretch
+strictFirstAndLastChars
+strike
+strikeBLTR
+strikeH
+strikeTLBR
+strikeV
+string
+stringValue1
+stringValue2
+stripedRightArrow
+strips
+stroke
+strokecolor
+stroked
+strokeok
+strokeweight
+sty
+style
+styleData
+styleDef
+styleDefHdr
+styleDefHdrLst
+styleId
+styleLbl
+styleLink
+styleLockQFSet
+styleLockTheme
+styleName
+stylePaneFormatFilter
+stylePaneSortMethod
+styleSheet
+styles
+sub
+subDoc
+subFontBySize
+subHide
+subSp
+subSup
+subTitle
+subTnLst
+subject
+subscript
+subsetted
+subtotal
+subtotalCaption
+subtotalHiddenItems
+subtotalTop
+suff
+suggestedsigner
+suggestedsigner2
+suggestedsigneremail
+sum
+sumSubtotal
+summaryBelow
+summaryLength
+summaryRight
+sun
+sunrise
+sunset
+sup
+supHide
+superscript
+supportAdvancedDrill
+supportSubquery
+suppressAutoHyphens
+suppressBottomSpacing
+suppressLineNumbers
+suppressOverlap
+suppressSpBfAfterPgBrk
+suppressSpacingAtTopOfPage
+suppressTopSpacing
+suppressTopSpacingWP
+surface3DChart
+surfaceChart
+swAng
+swCell
+swapBordersFacingPages
+swirligig
+swiss
+switch
+swooshArrow
+sx
+sy
+sym
+symbol
+syncBehavior
+syncHorizontal
+syncRef
+syncVertical
+sysClr
+sysDash
+sysDashDot
+sysDashDotDot
+sysDot
+sz
+szCs
+t
+t1
+t2
+tCtr
+tCtrCh
+tCtrDes
+tIns
+tL
+tMarg
+tOff
+tR
+tab
+tabColor
+tabLst
+tabRatio
+tabSelected
+table
+tableBorderDxfId
+tableColumn
+tableColumnId
+tableColumns
+tablePart
+tableParts
+tableStyle
+tableStyleElement
+tableStyleId
+tableStyleInfo
+tableStyles
+tableType
+tablelimits
+tableproperties
+tables
+tabs
+tag
+tagLst
+tags
+tailEnd
+taiwan
+taiwaneseCounting
+taiwaneseCountingThousand
+taiwaneseDigital
+tan
+target
+targetScreenSize
+targetScreenSz
+targetscreensize
+tav
+tavLst
+tbLrV
+tbRl
+tbRlV
+tbl
+tblBg
+tblBorders
+tblCellMar
+tblCellSpacing
+tblGrid
+tblGridChange
+tblHeader
+tblInd
+tblLayout
+tblLook
+tblOfContents
+tblOverlap
+tblPr
+tblPrChange
+tblPrEx
+tblPrExChange
+tblStyle
+tblStyleColBandSize
+tblStyleLst
+tblStylePr
+tblStyleRowBandSize
+tblW
+tblpPr
+tblpX
+tblpXSpec
+tblpY
+tblpYSpec
+tbls
+tc
+tcBdr
+tcBorders
+tcFitText
+tcMar
+tcPr
+tcPrChange
+tcStyle
+tcTxStyle
+tcW
+teal
+teardrop
+temporary
+tenMillions
+tenThousands
+tentative
+text
+text1
+text2
+textAlignment
+textAndBackground
+textArchDown
+textArchDownPour
+textArchUp
+textArchUpPour
+textButton
+textButtonPour
+textCanDown
+textCanUp
+textCascadeDown
+textCascadeUp
+textChevron
+textChevronInverted
+textCircle
+textCirclePour
+textCurveDown
+textCurveUp
+textDates
+textDeflate
+textDeflateBottom
+textDeflateInflate
+textDeflateInflateDeflate
+textDeflateTop
+textDirection
+textDoubleWave1
+textFadeDown
+textFadeLeft
+textFadeRight
+textFadeUp
+textField
+textFields
+textFile
+textFit
+textInflate
+textInflateBottom
+textInflateTop
+textInput
+textLength
+textNoShape
+textPlain
+textPr
+textRingInside
+textRingOutside
+textRotation
+textSlantDown
+textSlantUp
+textStop
+textTriangle
+textTriangleInverted
+textWave1
+textWave2
+textWave4
+textWrapping
+textborder
+textbox
+textboxTightWrap
+textboxrect
+textdata
+textlink
+textpath
+textpathok
+tgtEl
+tgtFrame
+thai
+thaiAlphaParenBoth
+thaiAlphaParenR
+thaiAlphaPeriod
+thaiCounting
+thaiDist
+thaiDistribute
+thaiLetters
+thaiNumParenBoth
+thaiNumParenR
+thaiNumPeriod
+thaiNumbers
+theme
+themeColor
+themeElements
+themeFill
+themeFillShade
+themeFillTint
+themeFontLang
+themeManager
+themeOverride
+themeShade
+themeTint
+thick
+thickBetweenThin
+thickBetweenThinLarge
+thickBetweenThinSmall
+thickBot
+thickBottom
+thickThin
+thickThinLarge
+thickThinLargeGap
+thickThinMediumGap
+thickThinSmall
+thickThinSmallGap
+thickTop
+thicket
+thickness
+thin
+thinDiagCross
+thinDiagStripe
+thinHorzCross
+thinHorzStripe
+thinReverseDiagStripe
+thinThick
+thinThickLarge
+thinThickLargeGap
+thinThickMediumGap
+thinThickSmall
+thinThickSmallGap
+thinThickThinLargeGap
+thinThickThinMediumGap
+thinThickThinSmallGap
+thinThin
+thinVertStripe
+thirdColumnSubheading
+thirdRowSubheading
+thirdSubtotalColumn
+thirdSubtotalRow
+thisMonth
+thisQuarter
+thisWeek
+thisYear
+thistle
+thousands
+threeDEmboss
+threeDEngrave
+threePt
+thresh
+through
+thruBlk
+tickLblPos
+tickLblSkip
+tickMarkSkip
+tight
+tile
+tileRect
+time
+timePeriod
+timing
+tint
+title
+titleOnly
+titlePg
+titleStyle
+tl
+tl2br
+tm
+tmAbs
+tmFilter
+tmPct
+tmRoot
+tmpl
+tmplLst
+tn
+tnLst
+to
+today
+token
+tomato
+tomorrow
+toolbar
+tooltip
+top
+top10
+topAndBottom
+topAutoShow
+topFromText
+topLabels
+topLeft
+topLeftCell
+topLinePunct
+topMargin
+topRight
+tornPaper
+tornPaperBlack
+totalRow
+totalsRowBorderDxfId
+totalsRowCellStyle
+totalsRowCount
+totalsRowDxfId
+totalsRowFormula
+totalsRowFunction
+totalsRowLabel
+totalsRowShown
+tp
+tpl
+tplc
+tpls
+tr
+tr2bl
+trHeight
+trPr
+trPrChange
+track
+trackRevisions
+trackedChanges
+trans
+transition
+transitionEntry
+transitionEvaluation
+translucentPowder
+transp
+trapezoid
+tree
+trees
+trellis
+trend
+trendline
+trendlineLbl
+trendlineType
+tri
+triangle
+triangleParty
+triangles
+tribal1
+tribal2
+tribal3
+tribal4
+tribal5
+tribal6
+trillions
+trim
+triple
+true
+truncateFontHeightsLikeWP6
+tupleCache
+turquoise
+twistedLines1
+twistedLines2
+twoCell
+twoCellAnchor
+twoColTx
+twoDigitTextYear
+twoObj
+twoObjAndObj
+twoObjAndTx
+twoObjOverTx
+twoPt
+twoTxTwoObj
+tx
+tx1
+tx2
+txAnchorHorz
+txAnchorHorzCh
+txAnchorVert
+txAnchorVertCh
+txAndChart
+txAndClipArt
+txAndMedia
+txAndObj
+txAndTwoObj
+txBlDir
+txBody
+txBox
+txDef
+txDir
+txEffectClrLst
+txEl
+txFillClrLst
+txLinClrLst
+txOverObj
+txPr
+txSp
+txStyles
+txbxContent
+txtBox
+ty
+type
+typeAny
+typeface
+types
+u
+uBounds
+uFill
+uFillTx
+uLn
+uLnTx
+ua
+udl
+ui1
+ui2
+ui4
+ui8
+uiCompat97To2003
+uiExpand
+uiPriority
+uint
+ulTrailSpace
+un
+unbalanced
+unbalancedGroup
+unboundColumnsLeft
+unboundColumnsRight
+undOvr
+underDot
+underlineTabInNumList
+underscore
+undo
+undone
+undrawn
+ungrouping
+unhideWhenUsed
+uniqueCount
+uniqueId
+uniqueList
+uniqueMemberProperty
+uniqueName
+uniqueParent
+uniqueTag
+uniqueValues
+unknown
+unknownRelationship
+unlocked
+unlockedFormula
+unsignedByte
+unsignedInt
+unsignedLong
+unsignedShort
+up
+upArrow
+upArrowCallout
+upBars
+upDiag
+upDownArrow
+upDownArrowCallout
+upDownBars
+updateAutomatic
+updateFields
+updateLinks
+updatedVersion
+upgradeOnRefresh
+upperLetter
+upperRoman
+upr
+upright
+uri
+url
+usb0
+usb1
+usb2
+usb3
+useA
+useAltKinsokuLineBreakRules
+useAnsiKerningPairs
+useAutoFormatting
+useBgFill
+useDef
+useFELayout
+useFirstPageNumber
+useLongFilenames
+useNormalStyleForList
+usePrinterDefaults
+usePrinterMetrics
+useSingleBorderforContiguousCells
+useSpRect
+useTimings
+useWord2002TableStyleRules
+useWord97LineBreakRules
+useXSLTWhenSaving
+user
+userA
+userB
+userC
+userD
+userDrawn
+userE
+userF
+userG
+userH
+userI
+userInfo
+userInterface
+userJ
+userK
+userL
+userM
+userN
+userName
+userO
+userP
+userQ
+userR
+userS
+userSet
+userShapes
+userT
+userU
+userV
+userW
+userX
+userY
+userZ
+userdrawn
+userhidden
+users
+uturnArrow
+v
+v3
+v3v4
+v4
+vAlign
+vAnchor
+vMerge
+vMergeOrig
+vSpace
+vacatedStyle
+val
+valAx
+value
+valueBetween
+valueEqual
+valueGreaterThan
+valueGreaterThanOrEqual
+valueLessThan
+valueLessThanOrEqual
+valueMetadata
+valueNotBetween
+valueNotEqual
+valueType
+values
+vanish
+var
+varLst
+varP
+varPSubtotal
+varScale
+varSubtotal
+variable
+variant
+varp
+varyColors
+vbProcedure
+vector
+vendorID
+venn
+verb
+version
+vert
+vert270
+vertAlign
+vertAnchor
+vertBarState
+vertCompress
+vertJc
+vertOverflow
+vertStripe
+vertTitleAndTx
+vertTitleAndTxOverChart
+vertTx
+vertical
+verticalCentered
+verticalDpi
+verticalScroll
+verticies
+veryHidden
+video
+videoFile
+vietnameseCounting
+view
+view3D
+viewMergedData
+viewPr
+viewpoint
+viewpointorigin
+vine
+violet
+visibility
+visible
+visualTotals
+vm
+vml
+vocabulary
+vol
+volType
+volTypes
+vstream
+w
+wAfter
+wArH
+wBefore
+wMode
+wOff
+wR
+warmMatte
+warning
+watermarks
+wavAudioFile
+wave
+waveline
+wavy
+wavyDbl
+wavyDouble
+wavyHeavy
+wd
+wdDnDiag
+wdUpDiag
+weave
+weavingAngles
+weavingBraid
+weavingRibbon
+weavingStrips
+web
+webHidden
+webPr
+webPublishItem
+webPublishItems
+webPublishObject
+webPublishObjects
+webPublishing
+webSettings
+wedge
+wedgeEllipseCallout
+wedgeRectCallout
+wedgeRoundRectCallout
+weight
+wheat
+wheel
+whenNotActive
+white
+whiteFlowers
+whiteSmoke
+whiteTextOnBlack
+whole
+wholeTable
+wholeTbl
+wide
+widowControl
+width
+win
+window
+windowFrame
+windowHeight
+windowProtection
+windowText
+windowWidth
+wipe
+wireFrame
+wireframe
+withEffect
+withGroup
+woodwork
+wordArtVert
+wordArtVertRtl
+wordWrap
+words
+workbook
+workbookParameter
+workbookPassword
+workbookPr
+workbookProtection
+workbookView
+workbookViewId
+worksheet
+worksheetSource
+wpJustification
+wpSpaceWidth
+wrap
+wrapIndent
+wrapNone
+wrapPolygon
+wrapRight
+wrapSquare
+wrapText
+wrapThrough
+wrapTight
+wrapTopAndBottom
+wrapTrailSpaces
+wrapcoords
+writeProtection
+wsDr
+x
+xAlign
+xIllusions
+xMode
+xSplit
+xVal
+xWindow
+xf
+xfDxf
+xfId
+xfrm
+xfrmType
+xl2000
+xl97
+xlm
+xml
+xmlBased
+xmlCellPr
+xmlColumnPr
+xmlDataType
+xmlPr
+xpath
+xrange
+xscale
+xy
+y
+yAlign
+yMode
+ySplit
+yVal
+yWindow
+year
+yearLong
+yearShort
+yearToDate
+years
+yellow
+yellowGreen
+yesterday
+yrange
+z
+zOrder
+zOrderOff
+zanyTriangles
+zero
+zeroAsc
+zeroDesc
+zeroHeight
+zeroValues
+zeroWid
+zigZag
+zigZagStitch
+zoom
+zoomContents
+zoomScale
+zoomScaleNormal
+zoomScalePageLayoutView
+zoomScaleSheetLayoutView
+zoomToFit \ No newline at end of file
diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk
new file mode 100644
index 000000000000..c49456af8bbd
--- /dev/null
+++ b/oox/source/vml/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=vml
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/vmlshape.obj\
+ $(SLO)$/vmldrawing.obj\
+ $(SLO)$/vmldrawingfragmenthandler.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx
new file mode 100644
index 000000000000..482c8756b417
--- /dev/null
+++ b/oox/source/vml/vmldrawing.cxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vmldrawing.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/vml/drawing.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using namespace ::oox::core;
+
+namespace oox { namespace vml {
+
+Drawing::Drawing()
+{
+}
+Drawing::~Drawing()
+{
+}
+
+ShapePtr Drawing::createShapeById( const rtl::OUString sId ) const
+{
+ ShapePtr pRet, pRef;
+ std::vector< ShapePtr >::const_iterator aIter( maShapes.begin() );
+ while( aIter != maShapes.end() )
+ {
+ if ( (*aIter)->msId == sId )
+ {
+ pRef = (*aIter);
+ break;
+ }
+ aIter++;
+ }
+ if ( pRef )
+ {
+ pRet = ShapePtr( new Shape() );
+ if ( pRef->msType.getLength() )
+ {
+ std::vector< ShapePtr >::const_iterator aShapeTypeIter( maShapeTypes.begin() );
+ while( aShapeTypeIter != maShapeTypes.end() )
+ {
+ if ( (*aShapeTypeIter)->msType == pRef->msType )
+ {
+ pRet->applyAttributes( *(*aShapeTypeIter).get() );
+ break;
+ }
+ aShapeTypeIter++;
+ }
+ }
+ pRet->applyAttributes( *pRef.get() );
+ }
+ return pRet;
+}
+
+rtl::OUString Drawing::getGraphicUrlById( const rtl::OUString sId ) const
+{
+ rtl::OUString sGraphicURL;
+ std::vector< ShapePtr >::const_iterator aIter( maShapes.begin() );
+ while( aIter != maShapes.end() )
+ {
+ if ( (*aIter)->msId == sId )
+ {
+ sGraphicURL = (*aIter)->msGraphicURL;
+ break;
+ }
+ aIter++;
+ }
+ return sGraphicURL;
+}
+
+} }
diff --git a/oox/source/vml/vmldrawingfragmenthandler.cxx b/oox/source/vml/vmldrawingfragmenthandler.cxx
new file mode 100644
index 000000000000..1fd9a4ecbb50
--- /dev/null
+++ b/oox/source/vml/vmldrawingfragmenthandler.cxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vmldrawingfragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "oox/core/context.hxx"
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/vml/drawingfragmenthandler.hxx"
+#include "oox/core/namespaces.hxx"
+#include "tokens.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+
+namespace oox { namespace vml {
+
+//--------------------------------------------------------------------------------------------------------------
+
+class BasicShapeContext : public oox::core::Context
+{
+public:
+ BasicShapeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, const ShapePtr pShapePtr );
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
+ const Reference< XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, RuntimeException);
+private:
+ ShapePtr mpShapePtr;
+};
+BasicShapeContext::BasicShapeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 /* aElement */, const Reference< XFastAttributeList >& xAttribs, const ShapePtr pShapePtr )
+: Context( xHandler )
+, mpShapePtr( pShapePtr )
+{
+ mpShapePtr->msId = xAttribs->getOptionalValue( XML_id );
+ mpShapePtr->msType = xAttribs->getOptionalValue( XML_type );
+ rtl::OUString aShapeType( xAttribs->getOptionalValue( NMSP_OFFICE|XML_spt ) );
+ if ( aShapeType.getLength() )
+ mpShapePtr->mnShapeType = aShapeType.toInt32();
+ rtl::OUString aCoordSize( xAttribs->getOptionalValue( XML_coordsize ) );
+ if ( aCoordSize.getLength() )
+ {
+ sal_Int32 nIndex = 0;
+ rtl::OUString aCoordWidth ( aCoordSize.getToken( 0, ',', nIndex ) );
+ rtl::OUString aCoordHeight( aCoordSize.getToken( 0, ',', nIndex ) );
+ if ( aCoordWidth.getLength() )
+ mpShapePtr->mnCoordWidth = aCoordWidth.toInt32();
+ if ( aCoordHeight.getLength() )
+ mpShapePtr->mnCoordHeight = aCoordHeight.toInt32();
+ }
+ mpShapePtr->msPath = xAttribs->getOptionalValue( XML_path );
+ mpShapePtr->mnStroked = xAttribs->getOptionalValueToken( XML_stroked, 0 );
+ mpShapePtr->mnFilled = xAttribs->getOptionalValueToken( XML_filled, 0 );
+}
+Reference< XFastContextHandler > BasicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case NMSP_VML|XML_imagedata:
+ {
+ OUString aRelId( xAttribs->getOptionalValue( NMSP_OFFICE|XML_relid ) );
+ mpShapePtr->msGraphicURL = getHandler()->getFragmentPathFromRelId( aRelId );
+ mpShapePtr->msImageTitle = xAttribs->getOptionalValue( NMSP_OFFICE|XML_title );
+ }
+ break;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+//--------------------------------------------------------------------------------------------------------------
+// CT_Shapetype
+class ShapeTypeContext : public BasicShapeContext
+{
+public:
+ ShapeTypeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, const ShapePtr pShapePtr );
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
+ const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+
+};
+ShapeTypeContext::ShapeTypeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, const ShapePtr pShapePtr )
+: BasicShapeContext( xHandler, aElement, xAttribs, pShapePtr )
+{
+}
+Reference< XFastContextHandler > ShapeTypeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+// switch( aElementToken )
+// {
+// default:
+ xRet = BasicShapeContext::createFastChildContext( aElementToken, xAttribs );
+// break;
+// }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+//--------------------------------------------------------------------------------------------------------------
+// CT_Shape
+class ShapeContext : public BasicShapeContext
+{
+public:
+ ShapeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, const ShapePtr pShapePtr );
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
+ const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+};
+ShapeContext::ShapeContext( const FragmentHandlerRef& xHandler,
+ sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, const ShapePtr pShapePtr )
+: BasicShapeContext( xHandler, aElement, xAttribs, pShapePtr )
+{
+}
+Reference< XFastContextHandler > ShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+// switch( aElementToken )
+// {
+// default:
+ xRet = BasicShapeContext::createFastChildContext( aElementToken, xAttribs );
+// break;
+// }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+//--------------------------------------------------------------------------------------------------------------
+
+DrawingFragmentHandler::DrawingFragmentHandler( const XmlFilterRef& xFilter, const OUString& rFragmentPath, const DrawingPtr pDrawingPtr )
+ throw()
+: FragmentHandler( xFilter, rFragmentPath )
+, mpDrawingPtr( pDrawingPtr )
+{
+}
+DrawingFragmentHandler::~DrawingFragmentHandler()
+ throw()
+{
+}
+Reference< XFastContextHandler > DrawingFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case XML_xml:
+ break;
+ case NMSP_OFFICE|XML_shapelayout:
+ break;
+ case NMSP_VML|XML_shapetype:
+ {
+ ShapePtr pShapePtr( new Shape );
+ xRet = new ShapeTypeContext( this, aElementToken, xAttribs, pShapePtr );
+ mpDrawingPtr->getShapeTypes().push_back( pShapePtr );
+ }
+ break;
+ case NMSP_VML|XML_shape:
+ {
+ ShapePtr pShapePtr( new Shape );
+ xRet = new ShapeContext( this, aElementToken, xAttribs, pShapePtr );
+ mpDrawingPtr->getShapes().push_back( pShapePtr );
+ }
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+void SAL_CALL DrawingFragmentHandler::endDocument()
+ throw (SAXException, RuntimeException)
+{
+}
+
+//--------------------------------------------------------------------------------------------------------------
+
+
+
+} }
+
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
new file mode 100644
index 000000000000..25e1f2d73c52
--- /dev/null
+++ b/oox/source/vml/vmlshape.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vmlshape.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/vml/shape.hxx"
+
+namespace oox { namespace vml {
+
+Shape::Shape()
+: mnShapeType( 0 )
+, mnCoordWidth( 0 )
+, mnCoordHeight( 0 )
+, mnStroked( 0 )
+, mnFilled( 0 )
+{
+}
+Shape::~Shape()
+{
+}
+
+void Shape::applyAttributes( const vml::Shape& rSource )
+{
+ if ( rSource.msId.getLength() )
+ msId = rSource.msId;
+ if ( rSource.msType.getLength() )
+ msType = rSource.msType;
+ if ( rSource.mnShapeType )
+ mnShapeType = rSource.mnShapeType;
+ if ( rSource.mnCoordWidth )
+ mnCoordWidth = rSource.mnCoordWidth;
+ if ( rSource.mnCoordHeight )
+ mnCoordHeight = rSource.mnCoordHeight;
+ if ( rSource.mnStroked )
+ mnStroked = rSource.mnStroked;
+ if ( rSource.mnFilled )
+ mnFilled = rSource.mnFilled;
+ if ( rSource.msPath.getLength() )
+ msPath = rSource.msPath;
+}
+
+} }
diff --git a/oox/source/xls/addressconverter.cxx b/oox/source/xls/addressconverter.cxx
new file mode 100644
index 000000000000..9d2a781cfdc2
--- /dev/null
+++ b/oox/source/xls/addressconverter.cxx
@@ -0,0 +1,772 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: addressconverter.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/addressconverter.hxx"
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/biffoutputstream.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OStringBuffer;
+using ::rtl::OUStringToOString;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::XCellRangeAddressable;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+//! TODO: this limit may be changed
+const sal_Int16 API_MAXTAB = 255;
+
+const sal_Int32 OOX_MAXCOL = static_cast< sal_Int32 >( (1 << 14) - 1 );
+const sal_Int32 OOX_MAXROW = static_cast< sal_Int32 >( (1 << 20) - 1 );
+const sal_Int16 OOX_MAXTAB = static_cast< sal_Int16 >( (1 << 15) - 1 );
+
+const sal_Int32 BIFF2_MAXCOL = 255;
+const sal_Int32 BIFF2_MAXROW = 16383;
+const sal_Int16 BIFF2_MAXTAB = 0;
+
+const sal_Int32 BIFF3_MAXCOL = BIFF2_MAXCOL;
+const sal_Int32 BIFF3_MAXROW = BIFF2_MAXROW;
+const sal_Int16 BIFF3_MAXTAB = BIFF2_MAXTAB;
+
+const sal_Int32 BIFF4_MAXCOL = BIFF3_MAXCOL;
+const sal_Int32 BIFF4_MAXROW = BIFF3_MAXROW;
+const sal_Int16 BIFF4_MAXTAB = 32767;
+
+const sal_Int32 BIFF5_MAXCOL = BIFF4_MAXCOL;
+const sal_Int32 BIFF5_MAXROW = BIFF4_MAXROW;
+const sal_Int16 BIFF5_MAXTAB = BIFF4_MAXTAB;
+
+const sal_Int32 BIFF8_MAXCOL = BIFF5_MAXCOL;
+const sal_Int32 BIFF8_MAXROW = 65535;
+const sal_Int16 BIFF8_MAXTAB = BIFF5_MAXTAB;
+
+const sal_Unicode BIFF_URL_DRIVE = '\x01'; /// DOS drive letter or UNC path.
+const sal_Unicode BIFF_URL_ROOT = '\x02'; /// Root directory of current drive.
+const sal_Unicode BIFF_URL_SUBDIR = '\x03'; /// Subdirectory delimiter.
+const sal_Unicode BIFF_URL_PARENT = '\x04'; /// Parent directory.
+const sal_Unicode BIFF_URL_RAW = '\x05'; /// Unencoded URL.
+const sal_Unicode BIFF_URL_INSTALL = '\x06'; /// Application installation directory.
+const sal_Unicode BIFF_URL_INSTALL2 = '\x07'; /// Alternative application installation directory.
+const sal_Unicode BIFF_URL_ADDIN = '\x08'; /// Add-in installation directory.
+const sal_Unicode BIFF4_URL_SHEET = '\x09'; /// BIFF4 internal sheet.
+const sal_Unicode BIFF_URL_UNC = '@'; /// UNC path root.
+
+
+inline sal_uInt16 lclGetBiffAddressSize( bool bCol16Bit, bool bRow32Bit )
+{
+ return (bCol16Bit ? 2 : 1) + (bRow32Bit ? 4 : 2);
+}
+
+inline sal_uInt16 lclGetBiffRangeSize( bool bCol16Bit, bool bRow32Bit )
+{
+ return 2 * lclGetBiffAddressSize( bCol16Bit, bRow32Bit );
+}
+
+} // namespace
+
+// ============================================================================
+// ============================================================================
+
+CellAddress ApiCellRangeList::getBaseAddress() const
+{
+ if( empty() )
+ return CellAddress();
+ return CellAddress( front().Sheet, front().StartColumn, front().StartRow );
+}
+
+// ============================================================================
+
+void BinAddress::read( RecordInputStream& rStrm )
+{
+ rStrm >> mnRow >> mnCol;
+}
+
+void BinAddress::read( BiffInputStream& rStrm, bool bCol16Bit, bool bRow32Bit )
+{
+ mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
+ mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
+}
+
+void BinAddress::write( BiffOutputStream& rStrm, bool bCol16Bit, bool bRow32Bit ) const
+{
+ if( bRow32Bit )
+ rStrm << mnRow;
+ else
+ rStrm << static_cast< sal_uInt16 >( mnRow );
+ if( bCol16Bit )
+ rStrm << static_cast< sal_uInt16 >( mnCol );
+ else
+ rStrm << static_cast< sal_uInt8 >( mnCol );
+}
+
+// ============================================================================
+
+bool BinRange::contains( const BinAddress& rAddr ) const
+{
+ return (maFirst.mnCol <= rAddr.mnCol) && (rAddr.mnCol <= maLast.mnCol) &&
+ (maFirst.mnRow <= rAddr.mnRow) && (rAddr.mnRow <= maLast.mnRow);
+}
+
+void BinRange::read( RecordInputStream& rStrm )
+{
+ rStrm >> maFirst.mnRow >> maLast.mnRow >> maFirst.mnCol >> maLast.mnCol;
+}
+
+void BinRange::read( BiffInputStream& rStrm, bool bCol16Bit, bool bRow32Bit )
+{
+ maFirst.mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
+ maLast.mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
+ maFirst.mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
+ maLast.mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
+}
+
+void BinRange::write( BiffOutputStream& rStrm, bool bCol16Bit, bool bRow32Bit ) const
+{
+ if( bRow32Bit )
+ rStrm << maFirst.mnRow << maLast.mnRow;
+ else
+ rStrm << static_cast< sal_uInt16 >( maFirst.mnRow ) << static_cast< sal_uInt16 >( maLast.mnRow );
+ if( bCol16Bit )
+ rStrm << static_cast< sal_uInt16 >( maFirst.mnCol ) << static_cast< sal_uInt16 >( maLast.mnCol );
+ else
+ rStrm << static_cast< sal_uInt8 >( maFirst.mnCol ) << static_cast< sal_uInt8 >( maLast.mnCol );
+}
+
+// ============================================================================
+
+BinRange BinRangeList::getEnclosingRange() const
+{
+ BinRange aRange;
+ if( !empty() )
+ {
+ const_iterator aIt = begin(), aEnd = end();
+ aRange = *aIt;
+ for( ++aIt; aIt != aEnd; ++aIt )
+ {
+ aRange.maFirst.mnCol = ::std::min( aRange.maFirst.mnCol, aIt->maFirst.mnCol );
+ aRange.maFirst.mnRow = ::std::min( aRange.maFirst.mnRow, aIt->maFirst.mnRow );
+ aRange.maLast.mnCol = ::std::max( aRange.maLast.mnCol, aIt->maLast.mnCol );
+ aRange.maLast.mnRow = ::std::max( aRange.maLast.mnRow, aIt->maLast.mnRow );
+ }
+ }
+ return aRange;
+}
+
+void BinRangeList::read( RecordInputStream& rStrm )
+{
+ sal_Int32 nCount = rStrm.readInt32();
+ resize( getLimitedValue< size_t, sal_Int32 >( nCount, 0, rStrm.getRecLeft() / 16 ) );
+ for( iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ aIt->read( rStrm );
+}
+
+void BinRangeList::read( BiffInputStream& rStrm, bool bCol16Bit, bool bRow32Bit )
+{
+ sal_uInt16 nCount = rStrm.readuInt16();
+ resize( getLimitedValue< size_t, sal_uInt32 >( nCount, 0, rStrm.getRecLeft() / lclGetBiffRangeSize( bCol16Bit, bRow32Bit ) ) );
+ for( iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ aIt->read( rStrm, bCol16Bit, bRow32Bit );
+}
+
+void BinRangeList::write( BiffOutputStream& rStrm, bool bCol16Bit, bool bRow32Bit ) const
+{
+ writeSubList( rStrm, 0, size(), bCol16Bit, bRow32Bit );
+}
+
+void BinRangeList::writeSubList( BiffOutputStream& rStrm, size_t nBegin, size_t nCount, bool bCol16Bit, bool bRow32Bit ) const
+{
+ OSL_ENSURE( nBegin <= size(), "BiffRangeList::writeSubList - invalid start position" );
+ size_t nEnd = ::std::min< size_t >( nBegin + nCount, size() );
+ sal_uInt16 nBiffCount = getLimitedValue< sal_uInt16, size_t >( nEnd - nBegin, 0, SAL_MAX_UINT16 );
+ rStrm << nBiffCount;
+ rStrm.setPortionSize( lclGetBiffRangeSize( bCol16Bit, bRow32Bit ) );
+ for( const_iterator aIt = begin() + nBegin, aEnd = begin() + nEnd; aIt != aEnd; ++aIt )
+ aIt->write( rStrm, bCol16Bit, bRow32Bit );
+}
+
+// ============================================================================
+// ============================================================================
+
+AddressConverter::AddressConverter( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mcUrlThisWorkbook( 0 ),
+ mcUrlExternal( 0 ),
+ mcUrlThisSheet( 0 ),
+ mcUrlInternal( 0 ),
+ mbColOverflow( false ),
+ mbRowOverflow( false ),
+ mbTabOverflow( false )
+{
+ switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ initializeMaxPos( OOX_MAXTAB, OOX_MAXCOL, OOX_MAXROW );
+ break;
+ case FILTER_BIFF: switch( getBiff() )
+ {
+ case BIFF2:
+ initializeMaxPos( BIFF2_MAXTAB, BIFF2_MAXCOL, BIFF2_MAXROW );
+ initializeEncodedUrl( '\x00', '\x01', '\x02', '\x00' );
+ break;
+ case BIFF3:
+ initializeMaxPos( BIFF3_MAXTAB, BIFF3_MAXCOL, BIFF3_MAXROW );
+ initializeEncodedUrl( '\x00', '\x01', '\x02', '\x00' );
+ break;
+ case BIFF4:
+ initializeMaxPos( BIFF4_MAXTAB, BIFF4_MAXCOL, BIFF4_MAXROW );
+ initializeEncodedUrl( '\x00', '\x01', '\x02', '\x00' );
+ break;
+ case BIFF5:
+ initializeMaxPos( BIFF5_MAXTAB, BIFF5_MAXCOL, BIFF5_MAXROW );
+ initializeEncodedUrl( '\x04', '\x01', '\x02', '\x03' );
+ break;
+ case BIFF8:
+ initializeMaxPos( BIFF8_MAXTAB, BIFF8_MAXCOL, BIFF8_MAXROW );
+ initializeEncodedUrl( '\x04', '\x01', '\x00', '\x02' );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+bool AddressConverter::parseOoxAddress2d(
+ sal_Int32& ornColumn, sal_Int32& ornRow,
+ const OUString& rString, sal_Int32 nStart, sal_Int32 nLength )
+{
+ ornColumn = ornRow = 0;
+ if( (nStart < 0) || (nStart >= rString.getLength()) || (nLength < 2) )
+ return false;
+
+ const sal_Unicode* pcChar = rString.getStr() + nStart;
+ const sal_Unicode* pcEndChar = pcChar + ::std::min( nLength, rString.getLength() - nStart );
+
+ enum { STATE_COL, STATE_ROW } eState = STATE_COL;
+ while( pcChar < pcEndChar )
+ {
+ sal_Unicode cChar = *pcChar;
+ switch( eState )
+ {
+ case STATE_COL:
+ {
+ if( ('a' <= cChar) && (cChar <= 'z') )
+ (cChar -= 'a') += 'A';
+ if( ('A' <= cChar) && (cChar <= 'Z') )
+ {
+ /* Return, if 1-based column index is already 6 characters
+ long (12356631 is column index for column AAAAAA). */
+ if( ornColumn >= 12356631 )
+ return false;
+ (ornColumn *= 26) += (cChar - 'A' + 1);
+ }
+ else if( ornColumn > 0 )
+ {
+ --pcChar;
+ eState = STATE_ROW;
+ }
+ else
+ return false;
+ }
+ break;
+
+ case STATE_ROW:
+ {
+ if( ('0' <= cChar) && (cChar <= '9') )
+ {
+ // return, if 1-based row is already 9 digits long
+ if( ornRow >= 100000000 )
+ return false;
+ (ornRow *= 10) += (cChar - '0');
+ }
+ else
+ return false;
+ }
+ break;
+ }
+ ++pcChar;
+ }
+
+ --ornColumn;
+ --ornRow;
+ return (ornColumn >= 0) && (ornRow >= 0);
+}
+
+bool AddressConverter::parseOoxRange2d(
+ sal_Int32& ornStartColumn, sal_Int32& ornStartRow,
+ sal_Int32& ornEndColumn, sal_Int32& ornEndRow,
+ const OUString& rString, sal_Int32 nStart, sal_Int32 nLength )
+{
+ ornStartColumn = ornStartRow = ornEndColumn = ornEndRow = 0;
+ if( (nStart < 0) || (nStart >= rString.getLength()) || (nLength < 2) )
+ return false;
+
+ sal_Int32 nEnd = nStart + ::std::min( nLength, rString.getLength() - nStart );
+ sal_Int32 nColonPos = rString.indexOf( ':', nStart );
+ if( (nStart < nColonPos) && (nColonPos + 1 < nEnd) )
+ {
+ return
+ parseOoxAddress2d( ornStartColumn, ornStartRow, rString, nStart, nColonPos - nStart ) &&
+ parseOoxAddress2d( ornEndColumn, ornEndRow, rString, nColonPos + 1, nLength - nColonPos - 1 );
+ }
+
+ if( parseOoxAddress2d( ornStartColumn, ornStartRow, rString, nStart, nLength ) )
+ {
+ ornEndColumn = ornStartColumn;
+ ornEndRow = ornStartRow;
+ return true;
+ }
+
+ return false;
+}
+
+namespace {
+
+bool lclAppendUrlChar( OUStringBuffer& orUrl, sal_Unicode cChar, bool bEncodeSpecial )
+{
+ // #126855# encode special characters
+ if( bEncodeSpecial ) switch( cChar )
+ {
+ case '#': orUrl.appendAscii( "%23" ); return true;
+ case '%': orUrl.appendAscii( "%25" ); return true;
+ }
+ orUrl.append( cChar );
+ return cChar >= ' ';
+}
+
+} // namespace
+
+bool AddressConverter::parseBiffTargetUrl(
+ OUString& orClassName, OUString& orTargetUrl, OUString& orSheetName,
+ const OUString& rBiffTargetUrl )
+{
+ OUStringBuffer aTargetUrl;
+ OUStringBuffer aSheetName;
+
+ enum
+ {
+ STATE_START,
+ STATE_ENCODED_PATH_START, /// Start of encoded file path.
+ STATE_ENCODED_PATH, /// Inside encoded file path.
+ STATE_ENCODED_DRIVE, /// DOS drive letter or start of UNC path.
+ STATE_ENCODED_URL, /// Encoded URL, e.g. http links.
+ STATE_UNENCODED, /// Unencoded URL, could be DDE or OLE.
+ STATE_DDE_OLE, /// Second part of DDE or OLE link.
+ STATE_FILENAME, /// File name enclosed in brackets.
+ STATE_SHEETNAME, /// Sheet name following enclosed file name.
+ STATE_UNSUPPORTED, /// Unsupported special paths.
+ STATE_ERROR
+ }
+ eState = STATE_START;
+
+ const sal_Unicode* pcChar = rBiffTargetUrl.getStr();
+ const sal_Unicode* pcEnd = pcChar + rBiffTargetUrl.getLength();
+ for( ; (eState != STATE_ERROR) && (pcChar < pcEnd) && (*pcChar != 0); ++pcChar )
+ {
+ sal_Unicode cChar = *pcChar;
+ switch( eState )
+ {
+ case STATE_START:
+ if( (cChar == mcUrlThisWorkbook) || (cChar == mcUrlThisSheet) )
+ {
+ if( pcChar + 1 < pcEnd ) eState = STATE_ERROR;
+ }
+ else if( cChar == mcUrlExternal )
+ eState = (pcChar + 1 < pcEnd) ? STATE_ENCODED_PATH_START : STATE_ERROR;
+ else if( cChar == mcUrlInternal )
+ eState = (pcChar + 1 < pcEnd) ? STATE_SHEETNAME : STATE_ERROR;
+ else
+ eState = lclAppendUrlChar( aTargetUrl, cChar, true ) ? STATE_UNENCODED : STATE_ERROR;
+ break;
+
+ case STATE_ENCODED_PATH_START:
+ if( cChar == BIFF_URL_DRIVE )
+ eState = STATE_ENCODED_DRIVE;
+ else if( cChar == BIFF_URL_ROOT )
+ {
+ aTargetUrl.append( sal_Unicode( '/' ) );
+ eState = STATE_ENCODED_PATH;
+ }
+ else if( cChar == BIFF_URL_PARENT )
+ aTargetUrl.appendAscii( "../" );
+ else if( cChar == BIFF_URL_RAW )
+ eState = STATE_ENCODED_URL;
+ else if( cChar == BIFF_URL_INSTALL )
+ eState = STATE_UNSUPPORTED;
+ else if( cChar == BIFF_URL_INSTALL2 )
+ eState = STATE_UNSUPPORTED;
+ else if( cChar == BIFF_URL_ADDIN )
+ eState = STATE_UNSUPPORTED;
+ else if( (getBiff() == BIFF4) && (cChar == BIFF4_URL_SHEET) )
+ eState = STATE_SHEETNAME;
+ else if( cChar == '[' )
+ eState = STATE_FILENAME;
+ else if( lclAppendUrlChar( aTargetUrl, cChar, true ) )
+ eState = STATE_ENCODED_PATH;
+ else
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_ENCODED_PATH:
+ if( cChar == BIFF_URL_SUBDIR )
+ aTargetUrl.append( sal_Unicode( '/' ) );
+ else if( cChar == '[' )
+ eState = STATE_FILENAME;
+ else if( !lclAppendUrlChar( aTargetUrl, cChar, true ) )
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_ENCODED_DRIVE:
+ if( cChar == BIFF_URL_UNC )
+ {
+ aTargetUrl.appendAscii( "file://" );
+ eState = STATE_ENCODED_PATH;
+ }
+ else
+ {
+ aTargetUrl.appendAscii( "file:///" );
+ eState = lclAppendUrlChar( aTargetUrl, cChar, false ) ? STATE_ENCODED_PATH : STATE_ERROR;
+ aTargetUrl.appendAscii( ":/" );
+ }
+ break;
+
+ case STATE_ENCODED_URL:
+ {
+ sal_Int32 nLength = cChar;
+ if( nLength + 1 == pcEnd - pcChar )
+ aTargetUrl.append( pcChar + 1, nLength );
+ else
+ eState = STATE_ERROR;
+ }
+ break;
+
+ case STATE_UNENCODED:
+ if( cChar == BIFF_URL_SUBDIR )
+ {
+ orClassName = aTargetUrl.makeStringAndClear();
+ eState = STATE_DDE_OLE;
+ }
+ else if( cChar == '[' )
+ eState = STATE_FILENAME;
+ else if( !lclAppendUrlChar( aTargetUrl, cChar, true ) )
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_DDE_OLE:
+ if( !lclAppendUrlChar( aTargetUrl, cChar, true ) )
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_FILENAME:
+ if( cChar == ']' )
+ eState = STATE_SHEETNAME;
+ else if( !lclAppendUrlChar( aTargetUrl, cChar, true ) )
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_SHEETNAME:
+ if( !lclAppendUrlChar( aSheetName, cChar, false ) )
+ eState = STATE_ERROR;
+ break;
+
+ case STATE_UNSUPPORTED:
+ pcChar = pcEnd - 1;
+ break;
+
+ case STATE_ERROR:
+ break;
+ }
+ }
+
+ orTargetUrl = aTargetUrl.makeStringAndClear();
+ orSheetName = aSheetName.makeStringAndClear();
+
+ OSL_ENSURE( (eState != STATE_ERROR) && (pcChar == pcEnd),
+ OStringBuffer( "AddressConverter::parseBiffTargetUrl - parser error in target \"" ).
+ append( OUStringToOString( rBiffTargetUrl, RTL_TEXTENCODING_UTF8 ) ).append( '"' ).getStr() );
+ return (eState != STATE_ERROR) && (eState != STATE_UNSUPPORTED) && (pcChar == pcEnd);
+}
+
+// ----------------------------------------------------------------------------
+
+bool AddressConverter::checkCol( sal_Int32 nCol, bool bTrackOverflow )
+{
+ bool bValid = (0 <= nCol) && (nCol <= maMaxPos.Column);
+ if( !bValid && bTrackOverflow )
+ mbColOverflow = true;
+ return bValid;
+}
+
+bool AddressConverter::checkRow( sal_Int32 nRow, bool bTrackOverflow )
+{
+ bool bValid = (0 <= nRow) && (nRow <= maMaxPos.Row);
+ if( !bValid && bTrackOverflow )
+ mbRowOverflow = true;
+ return bValid;
+}
+
+bool AddressConverter::checkTab( sal_Int16 nSheet, bool bTrackOverflow )
+{
+ bool bValid = (0 <= nSheet) && (nSheet <= maMaxPos.Sheet);
+ if( !bValid && bTrackOverflow )
+ mbTabOverflow |= (nSheet > maMaxPos.Sheet); // do not warn for deleted refs (-1)
+ return bValid;
+}
+
+// ----------------------------------------------------------------------------
+
+bool AddressConverter::checkCellAddress( const CellAddress& rAddress, bool bTrackOverflow )
+{
+ return
+ checkTab( rAddress.Sheet, bTrackOverflow ) &&
+ checkCol( rAddress.Column, bTrackOverflow ) &&
+ checkRow( rAddress.Row, bTrackOverflow );
+}
+
+bool AddressConverter::convertToCellAddressUnckecked( CellAddress& orAddress,
+ const OUString& rString, sal_Int16 nSheet )
+{
+ orAddress.Sheet = nSheet;
+ return parseOoxAddress2d( orAddress.Column, orAddress.Row, rString );
+}
+
+bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
+ const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ return
+ convertToCellAddressUnckecked( orAddress, rString, nSheet ) &&
+ checkCellAddress( orAddress, bTrackOverflow );
+}
+
+CellAddress AddressConverter::createValidCellAddress(
+ const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ CellAddress aAddress;
+ if( !convertToCellAddress( aAddress, rString, nSheet, bTrackOverflow ) )
+ {
+ aAddress.Sheet = getLimitedValue< sal_Int16, sal_Int16 >( nSheet, 0, maMaxPos.Sheet );
+ aAddress.Column = ::std::min( aAddress.Column, maMaxPos.Column );
+ aAddress.Row = ::std::min( aAddress.Row, maMaxPos.Row );
+ }
+ return aAddress;
+}
+
+void AddressConverter::convertToCellAddressUnckecked( CellAddress& orAddress,
+ const BinAddress& rBinAddress, sal_Int16 nSheet )
+{
+ orAddress.Sheet = nSheet;
+ orAddress.Column = rBinAddress.mnCol;
+ orAddress.Row = rBinAddress.mnRow;
+}
+
+bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
+ const BinAddress& rBinAddress, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ convertToCellAddressUnckecked( orAddress, rBinAddress, nSheet );
+ return checkCellAddress( orAddress, bTrackOverflow );
+}
+
+CellAddress AddressConverter::createValidCellAddress(
+ const BinAddress& rBinAddress, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ CellAddress aAddress;
+ if( !convertToCellAddress( aAddress, rBinAddress, nSheet, bTrackOverflow ) )
+ {
+ aAddress.Sheet = getLimitedValue< sal_Int16, sal_Int16 >( nSheet, 0, maMaxPos.Sheet );
+ aAddress.Column = getLimitedValue< sal_Int32, sal_Int32 >( rBinAddress.mnCol, 0, maMaxPos.Column );
+ aAddress.Row = getLimitedValue< sal_Int32, sal_Int32 >( rBinAddress.mnRow, 0, maMaxPos.Row );
+ }
+ return aAddress;
+}
+
+// ----------------------------------------------------------------------------
+
+bool AddressConverter::checkCellRange( const CellRangeAddress& rRange, bool bTrackOverflow )
+{
+ checkCol( rRange.EndColumn, bTrackOverflow );
+ checkRow( rRange.EndRow, bTrackOverflow );
+ return
+ checkTab( rRange.Sheet, bTrackOverflow ) &&
+ checkCol( rRange.StartColumn, bTrackOverflow ) &&
+ checkRow( rRange.StartRow, bTrackOverflow );
+}
+
+bool AddressConverter::validateCellRange( CellRangeAddress& orRange, bool bTrackOverflow )
+{
+ if( orRange.StartColumn > orRange.EndColumn )
+ ::std::swap( orRange.StartColumn, orRange.EndColumn );
+ if( orRange.StartRow > orRange.EndRow )
+ ::std::swap( orRange.StartRow, orRange.EndRow );
+ if( !checkCellRange( orRange, bTrackOverflow ) )
+ return false;
+ if( orRange.EndColumn > maMaxPos.Column )
+ orRange.EndColumn = maMaxPos.Column;
+ if( orRange.EndRow > maMaxPos.Row )
+ orRange.EndRow = maMaxPos.Row;
+ return true;
+}
+
+bool AddressConverter::convertToCellRangeUnchecked( CellRangeAddress& orRange,
+ const OUString& rString, sal_Int16 nSheet )
+{
+ orRange.Sheet = nSheet;
+ return parseOoxRange2d( orRange.StartColumn, orRange.StartRow, orRange.EndColumn, orRange.EndRow, rString );
+}
+
+bool AddressConverter::convertToCellRange( CellRangeAddress& orRange,
+ const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ return
+ convertToCellRangeUnchecked( orRange, rString, nSheet ) &&
+ validateCellRange( orRange, bTrackOverflow );
+}
+
+void AddressConverter::convertToCellRangeUnchecked( CellRangeAddress& orRange,
+ const BinRange& rBinRange, sal_Int16 nSheet )
+{
+ orRange.Sheet = nSheet;
+ orRange.StartColumn = rBinRange.maFirst.mnCol;
+ orRange.StartRow = rBinRange.maFirst.mnRow;
+ orRange.EndColumn = rBinRange.maLast.mnCol;
+ orRange.EndRow = rBinRange.maLast.mnRow;
+}
+
+bool AddressConverter::convertToCellRange( CellRangeAddress& orRange,
+ const BinRange& rBinRange, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ convertToCellRangeUnchecked( orRange, rBinRange, nSheet );
+ return validateCellRange( orRange, bTrackOverflow );
+}
+
+// ----------------------------------------------------------------------------
+
+bool AddressConverter::checkCellRangeList( const ApiCellRangeList& rRanges, bool bTrackOverflow )
+{
+ for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt )
+ if( !checkCellRange( *aIt, bTrackOverflow ) )
+ return false;
+ return true;
+}
+
+void AddressConverter::validateCellRangeList( ApiCellRangeList& orRanges, bool bTrackOverflow )
+{
+ for( size_t nIndex = orRanges.size(); nIndex > 0; --nIndex )
+ if( !validateCellRange( orRanges[ nIndex - 1 ], bTrackOverflow ) )
+ orRanges.erase( orRanges.begin() + nIndex - 1 );
+}
+
+void AddressConverter::convertToCellRangeList( ApiCellRangeList& orRanges,
+ const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = rString.getLength();
+ CellRangeAddress aRange;
+ while( (0 <= nPos) && (nPos < nLen) )
+ {
+ OUString aToken = rString.getToken( 0, ' ', nPos );
+ if( (aToken.getLength() > 0) && convertToCellRange( aRange, aToken, nSheet, bTrackOverflow ) )
+ orRanges.push_back( aRange );
+ }
+}
+
+void AddressConverter::convertToCellRangeList( ApiCellRangeList& orRanges,
+ const BinRangeList& rBinRanges, sal_Int16 nSheet, bool bTrackOverflow )
+{
+ CellRangeAddress aRange;
+ for( BinRangeList::const_iterator aIt = rBinRanges.begin(), aEnd = rBinRanges.end(); aIt != aEnd; ++aIt )
+ if( convertToCellRange( aRange, *aIt, nSheet, bTrackOverflow ) )
+ orRanges.push_back( aRange );
+}
+
+// private --------------------------------------------------------------------
+
+void AddressConverter::initializeMaxPos(
+ sal_Int16 nMaxXlsTab, sal_Int32 nMaxXlsCol, sal_Int32 nMaxXlsRow )
+{
+ maMaxXlsPos.Sheet = nMaxXlsTab;
+ maMaxXlsPos.Column = nMaxXlsCol;
+ maMaxXlsPos.Row = nMaxXlsRow;
+
+ // maximum cell position in Calc
+ try
+ {
+ Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
+ Reference< XCellRangeAddressable > xAddressable( xSheetsIA->getByIndex( 0 ), UNO_QUERY_THROW );
+ CellRangeAddress aRange = xAddressable->getRangeAddress();
+ maMaxApiPos = CellAddress( API_MAXTAB, aRange.EndColumn, aRange.EndRow );
+ maMaxPos = getBaseFilter().isImportFilter() ? maMaxApiPos : maMaxXlsPos;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "AddressConverter::AddressConverter - cannot get sheet limits" );
+ }
+}
+
+void AddressConverter::initializeEncodedUrl(
+ sal_Unicode cUrlThisWorkbook, sal_Unicode cUrlExternal,
+ sal_Unicode cUrlThisSheet, sal_Unicode cUrlInternal )
+{
+ mcUrlThisWorkbook = cUrlThisWorkbook;
+ mcUrlExternal = cUrlExternal;
+ mcUrlThisSheet = cUrlThisSheet;
+ mcUrlInternal = cUrlInternal;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/autofiltercontext.cxx b/oox/source/xls/autofiltercontext.cxx
new file mode 100644
index 000000000000..99f56575dc01
--- /dev/null
+++ b/oox/source/xls/autofiltercontext.cxx
@@ -0,0 +1,770 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: autofiltercontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/autofiltercontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor.hpp>
+#include <com/sun/star/sheet/FilterOperator.hpp>
+#include <com/sun/star/sheet/FilterConnection.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/XLocaleData.hpp>
+
+#define DEBUG_OOX_AUTOFILTER 0
+
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+#include <com/sun/star/sheet/XExtendedSheetFilterDescriptor.hpp>
+#include <com/sun/star/sheet/TableFilterFieldNormal.hpp>
+#include <com/sun/star/sheet/TableFilterFieldMultiString.hpp>
+using ::com::sun::star::sheet::TableFilterFieldNormal;
+using ::com::sun::star::sheet::TableFilterFieldMultiString;
+using ::com::sun::star::sheet::XExtendedSheetFilterDescriptor;
+#else
+#include <com/sun/star/sheet/TableFilterField.hpp>
+using ::com::sun::star::sheet::TableFilterField;
+#endif
+
+#if DEBUG_OOX_AUTOFILTER
+#include <stdio.h>
+#endif
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::std::list;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::container::XNamed;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::table::XCellRange;
+using ::com::sun::star::sheet::XDatabaseRange;
+using ::com::sun::star::sheet::XDatabaseRanges;
+using ::com::sun::star::sheet::XSheetFilterDescriptor;
+using ::com::sun::star::i18n::LocaleDataItem;
+using ::com::sun::star::i18n::XLocaleData;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::lang::Locale;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+FilterFieldItem::FilterFieldItem() :
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ mpField(new TableFilterFieldNormal),
+#else
+ mpField(new TableFilterField),
+#endif
+ meType(NORMAL)
+{
+}
+
+FilterFieldItem::FilterFieldItem(Type eType) :
+ meType(eType)
+{
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ switch ( eType )
+ {
+ case MULTI_STRING:
+ mpField.reset(new TableFilterFieldMultiString);
+ break;
+ case NORMAL:
+ mpField.reset(new TableFilterFieldNormal);
+ break;
+ default:
+ mpField.reset(new TableFilterFieldNormal);
+ }
+#else
+ mpField.reset(new TableFilterField);
+ meType = NORMAL;
+#endif
+}
+
+// ============================================================================
+
+OoxAutoFilterContext::OoxAutoFilterContext( const OoxWorksheetFragmentBase& rFragment ) :
+ OoxWorksheetContextBase( rFragment ),
+ mbValidAddress( false ),
+ mbUseRegex( false ),
+ mbShowBlank( false ),
+ mbConnectionAnd( false )
+{
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxAutoFilterContext::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( autoFilter ):
+ return (nElement == XLS_TOKEN( filterColumn ));
+ case XLS_TOKEN( filterColumn ):
+ return (nElement == XLS_TOKEN( filters )) ||
+ (nElement == XLS_TOKEN( customFilters )) ||
+ (nElement == XLS_TOKEN( top10 )) ||
+ (nElement == XLS_TOKEN( dynamicFilter ));
+ case XLS_TOKEN( filters ):
+ return (nElement == XLS_TOKEN( filter ));
+ case XLS_TOKEN( customFilters ):
+ return (nElement == XLS_TOKEN( customFilter ));
+ }
+ return false;
+}
+
+void OoxAutoFilterContext::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( autoFilter ):
+ importAutoFilter( rAttribs );
+ break;
+ case XLS_TOKEN( filterColumn ):
+ if ( mbValidAddress )
+ importFilterColumn( rAttribs );
+ break;
+ case XLS_TOKEN( filters ):
+ if ( mbValidAddress )
+ importFilters( rAttribs );
+ break;
+ case XLS_TOKEN( filter ):
+ if ( mbValidAddress )
+ importFilter( rAttribs );
+ break;
+ case XLS_TOKEN( customFilters ):
+ if ( mbValidAddress )
+ importCustomFilters( rAttribs );
+ break;
+ case XLS_TOKEN( customFilter ):
+ if ( mbValidAddress )
+ importCustomFilter( rAttribs );
+ break;
+ case XLS_TOKEN( top10 ):
+ if ( mbValidAddress )
+ importTop10( rAttribs );
+ break;
+ case XLS_TOKEN( dynamicFilter ):
+ if ( mbValidAddress )
+ importDynamicFilter( rAttribs );
+ break;
+ }
+}
+
+void OoxAutoFilterContext::onEndElement( const OUString& /*rChars*/ )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( autoFilter ):
+ maybeShowBlank();
+ setAutoFilter();
+ break;
+ case XLS_TOKEN( filters ):
+ setFilterNames();
+ break;
+ }
+}
+
+#if DEBUG_OOX_AUTOFILTER
+static void lclPrintNormalField(
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ TableFilterFieldNormal* pField
+#else
+ TableFilterField* pField
+#endif
+)
+{
+ using namespace ::com::sun::star::sheet;
+
+ printf(" Operator: ");
+ switch ( pField->Operator )
+ {
+ case FilterOperator_EQUAL:
+ printf("EQUAL");
+ break;
+ case FilterOperator_NOT_EQUAL:
+ printf("NOT_EQUAL");
+ break;
+ case com::sun::star::sheet::FilterOperator_GREATER:
+ printf("GREATER");
+ break;
+ case com::sun::star::sheet::FilterOperator_GREATER_EQUAL:
+ printf("GREATER_EQUAL");
+ break;
+ case FilterOperator_LESS:
+ printf("LESS");
+ break;
+ case FilterOperator_LESS_EQUAL:
+ printf("LESS_EQUAL");
+ break;
+ case FilterOperator_NOT_EMPTY:
+ printf("NOT_EMPTY");
+ break;
+ case FilterOperator_EMPTY:
+ printf("EMPTY");
+ break;
+ case FilterOperator_BOTTOM_PERCENT:
+ printf("BOTTOM_PERCENT");
+ break;
+ case FilterOperator_BOTTOM_VALUES:
+ printf("BOTTOM_VALUES");
+ break;
+ case FilterOperator_TOP_PERCENT:
+ printf("TOP_PERCENT");
+ break;
+ case FilterOperator_TOP_VALUES:
+ printf("TOP_VALUES");
+ break;
+ default:
+ printf("other");
+ }
+ printf("\n");
+
+ printf(" StringValue: %s\n",
+ OUStringToOString(pField->StringValue, RTL_TEXTENCODING_UTF8).getStr());
+
+ printf(" NumericValue: %g\n", pField->NumericValue);
+
+ printf(" IsNumeric: ");
+ if (pField->IsNumeric)
+ printf("yes\n");
+ else
+ printf("no\n");
+}
+
+static void lclPrintFieldConnection( ::com::sun::star::sheet::FilterConnection eConn )
+{
+ using namespace ::com::sun::star::sheet;
+
+ printf(" Connection: ");
+ switch ( eConn )
+ {
+ case FilterConnection_AND:
+ printf("AND");
+ break;
+ case FilterConnection_OR:
+ printf("OR");
+ break;
+ case FilterConnection_MAKE_FIXED_SIZE:
+ printf("MAKE_FIXED_SIZE");
+ break;
+ default:
+ printf("other");
+ }
+ printf("\n");
+}
+
+static void lclPrintFilterField( const FilterFieldItem& aItem )
+{
+ using namespace ::com::sun::star::sheet;
+
+ printf("----------------------------------------\n");
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ {
+ // Print common fields first.
+
+ TableFilterFieldBase* pField = aItem.mpField.get();
+ printf(" Field: %ld\n", pField->Field);
+ lclPrintFieldConnection(pField->Connection);
+ }
+ switch ( aItem.meType )
+ {
+ case FilterFieldItem::NORMAL:
+ {
+ TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get());
+ lclPrintNormalField(pField);
+ }
+ break;
+ case FilterFieldItem::MULTI_STRING:
+ {
+ TableFilterFieldMultiString* pMultiStrField = static_cast<TableFilterFieldMultiString*>(aItem.mpField.get());
+ sal_Int32 nSize = pMultiStrField->StringSet.getLength();
+ printf(" StringSet:\n");
+ for ( sal_Int32 i = 0; i < nSize; ++i )
+ {
+ printf(" * %s\n",
+ OUStringToOString(pMultiStrField->StringSet[i], RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ break;
+ }
+#else
+ TableFilterField* pField = aItem.mpField.get();
+ printf(" Field: %ld\n", pField->Field);
+ lclPrintFieldConnection(pField->Connection);
+ lclPrintNormalField(pField);
+
+#endif
+ fflush(stdout);
+}
+#endif
+
+void OoxAutoFilterContext::initialize()
+{
+ maFields.clear();
+ maFilterNames.clear();
+ mbValidAddress = mbShowBlank = mbUseRegex = mbConnectionAnd = false;
+}
+
+void OoxAutoFilterContext::setAutoFilter()
+{
+ using namespace ::com::sun::star::sheet;
+
+ // Name this built-in database.
+ OUStringBuffer sDataAreaNameBuf( CREATE_OUSTRING("Excel_BuiltIn__FilterDatabase_ ") );
+ sDataAreaNameBuf.append( static_cast<sal_Int32>(getSheetIndex()+1) );
+
+ OUString sDataAreaName = sDataAreaNameBuf.makeStringAndClear();
+ Reference< XCellRange > xCellRange = getCellRange( maAutoFilterRange );
+
+ // Create a new database range, add filters to it and refresh the database
+ // for that to take effect.
+
+ Reference< XDatabaseRanges > xDBRanges;
+ {
+ PropertySet aDocProp( getDocument() );
+ aDocProp.getProperty( xDBRanges, CREATE_OUSTRING("DatabaseRanges") );
+ if ( !xDBRanges.is() )
+ {
+ OSL_ENSURE(false, "OoxAutoFilterContext::setAutoFilter: DBRange empty");
+ return;
+ }
+ }
+
+ Reference< XNameAccess > xNA( xDBRanges, UNO_QUERY_THROW );
+ if ( !xNA->hasByName( sDataAreaName ) )
+ xDBRanges->addNewByName( sDataAreaName, maAutoFilterRange );
+
+ Reference< XDatabaseRange > xDB( xNA->getByName( sDataAreaName ), UNO_QUERY );
+ if ( xDB.is() )
+ {
+ PropertySet aProp( xDB );
+ aProp.setProperty( CREATE_OUSTRING("AutoFilter"), true );
+ }
+
+ sal_Int32 nSize = maFields.size();
+ sal_Int32 nMaxFieldCount = nSize;
+ Reference< XSheetFilterDescriptor > xDescriptor = xDB->getFilterDescriptor();
+ if ( xDescriptor.is() )
+ {
+ PropertySet aProp( xDescriptor );
+ aProp.setProperty( CREATE_OUSTRING("ContainsHeader"), true );
+ aProp.setProperty( CREATE_OUSTRING("UseRegularExpressions"), mbUseRegex );
+ aProp.getProperty( nMaxFieldCount, CREATE_OUSTRING("MaxFieldCount") );
+ }
+ else
+ {
+ OSL_ENSURE(false, "OoxAutoFilterContext::setAutoFilter: descriptor is empty");
+ return;
+ }
+
+ // Unpack all column field items into a sequence.
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ Reference< XExtendedSheetFilterDescriptor > xExtDescriptor( xDescriptor, UNO_QUERY );
+ if ( !xExtDescriptor.is() )
+ {
+ OSL_ENSURE(false, "OoxAutoFilterContext::setAutoFilter: extended descriptor is empty");
+ return;
+ }
+
+ xExtDescriptor->begin();
+
+ list< FilterFieldItem >::const_iterator itr = maFields.begin(), itrEnd = maFields.end();
+ for (sal_Int32 i = 0; itr != itrEnd && i < nMaxFieldCount; ++itr, ++i)
+ {
+#if DEBUG_OOX_AUTOFILTER
+ lclPrintFilterField(*itr);
+#endif
+ switch ( itr->meType )
+ {
+ case oox::xls::FilterFieldItem::MULTI_STRING:
+ {
+ // multi-string filter type
+ TableFilterFieldMultiString* pField = static_cast<TableFilterFieldMultiString*>( itr->mpField.get() );
+ xExtDescriptor->addFilterFieldMultiString( *pField );
+ }
+ break;
+ case oox::xls::FilterFieldItem::NORMAL:
+ default:
+ // normal filter type
+ TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>( itr->mpField.get() );
+ xExtDescriptor->addFilterFieldNormal( *pField );
+ }
+ }
+ xExtDescriptor->commit();
+
+#else
+ Sequence< TableFilterField > aFields(nSize);
+ list< FilterFieldItem >::const_iterator itr = maFields.begin(), itrEnd = maFields.end();
+ for (sal_Int32 i = 0; itr != itrEnd && i < nMaxFieldCount; ++itr, ++i)
+ {
+#if DEBUG_OOX_AUTOFILTER
+ lclPrintFilterField( *itr );
+#endif
+ aFields[i] = *itr->mpField;
+ }
+ xDescriptor->setFilterFields( aFields );
+#endif
+ xDB->refresh();
+}
+
+void OoxAutoFilterContext::maybeShowBlank()
+{
+ using namespace ::com::sun::star::sheet;
+
+ if ( !mbShowBlank )
+ return;
+
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ FilterFieldItem aItem(FilterFieldItem::NORMAL);
+ TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get());
+ pField->Field = mnCurColID;
+ pField->Operator = FilterOperator_EMPTY;
+ pField->Connection = FilterConnection_AND;
+ pField->IsNumeric = false;
+#else
+ FilterFieldItem aItem;
+ aItem.mpField->Field = mnCurColID;
+ aItem.mpField->Operator = FilterOperator_EMPTY;
+ aItem.mpField->Connection = FilterConnection_AND;
+ aItem.mpField->IsNumeric = false;
+#endif
+ maFields.push_back(aItem);
+}
+
+void OoxAutoFilterContext::setFilterNames()
+{
+ using namespace ::com::sun::star::sheet;
+
+
+ sal_Int32 size = maFilterNames.size();
+ if ( !size )
+ return;
+
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ Sequence< OUString > aStrList(size);
+ list< OUString >::const_iterator itr = maFilterNames.begin(), itrEnd = maFilterNames.end();
+ for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i)
+ aStrList[i] = *itr;
+
+ FilterFieldItem aItem(FilterFieldItem::MULTI_STRING);
+ TableFilterFieldMultiString* pField = static_cast<TableFilterFieldMultiString*>( aItem.mpField.get() );
+ pField->Field = mnCurColID;
+ pField->Connection = FilterConnection_AND;
+ pField->StringSet = aStrList;
+
+ maFields.push_back(aItem);
+#else
+ static const OUString sSep = CREATE_OUSTRING("|");
+
+ OUStringBuffer buf;
+ if ( size > 1 )
+ {
+ buf.append( CREATE_OUSTRING("^(") );
+ mbUseRegex = true;
+ }
+
+ list< OUString >::const_iterator itr = maFilterNames.begin(), itrEnd = maFilterNames.end();
+ bool bFirst = true;
+ for (; itr != itrEnd; ++itr)
+ {
+ if (bFirst)
+ bFirst = false;
+ else
+ buf.append( sSep );
+ buf.append( *itr );
+ }
+ if ( size > 1 )
+ buf.append( CREATE_OUSTRING(")$") );
+
+ FilterFieldItem aItem;
+ aItem.mpField->Field = mnCurColID;
+ aItem.mpField->StringValue = buf.makeStringAndClear();
+ aItem.mpField->Operator = FilterOperator_EQUAL;
+ aItem.mpField->Connection = FilterConnection_AND;
+ aItem.mpField->IsNumeric = false;
+ maFields.push_back(aItem);
+#endif
+}
+
+void OoxAutoFilterContext::importAutoFilter( const AttributeList& rAttribs )
+{
+ initialize();
+
+ mbValidAddress = getAddressConverter().convertToCellRange(
+ maAutoFilterRange, rAttribs.getString( XML_ref ), getSheetIndex(), true );
+}
+
+void OoxAutoFilterContext::importFilterColumn( const AttributeList& rAttribs )
+{
+ // hiddenButton and showButton attributes are not used for now.
+ mnCurColID = rAttribs.getInteger( XML_colId, -1 );
+}
+
+void OoxAutoFilterContext::importTop10( const AttributeList& rAttribs )
+{
+ using namespace ::com::sun::star::sheet;
+
+ // filterVal attribute is not necessarily, since Calc also supports top 10
+ // and top 10% filter type.
+ FilterFieldItem aItem;
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get());
+#else
+ TableFilterField* pField = aItem.mpField.get();
+#endif
+ pField->Field = mnCurColID;
+
+ bool bPercent = rAttribs.getBool( XML_percent, false );
+ bool bTop = rAttribs.getBool( XML_top, true );
+ pField->NumericValue = rAttribs.getDouble( XML_val, 0.0 );
+ pField->IsNumeric = true;
+
+ // When top10 filter item is present, that's the only filter item for that column.
+ if ( bTop )
+ if ( bPercent )
+ pField->Operator = FilterOperator_TOP_PERCENT;
+ else
+ pField->Operator = FilterOperator_TOP_VALUES;
+ else
+ if ( bPercent )
+ pField->Operator = FilterOperator_BOTTOM_PERCENT;
+ else
+ pField->Operator = FilterOperator_BOTTOM_VALUES;
+
+ maFields.push_back(aItem);
+}
+
+void OoxAutoFilterContext::importCustomFilters( const AttributeList& rAttribs )
+{
+ // OR is default when the 'and' attribute is absent.
+ mbConnectionAnd = rAttribs.getBool( XML_and, false );
+}
+
+/** Do a best-effort guess of whether or not the given string is numerical. */
+static bool lclIsNumeric( const OUString& _str, const LocaleDataItem& aLocaleItem )
+{
+ OUString str = _str.trim();
+ sal_Int32 size = str.getLength();
+
+ if ( !size )
+ // Empty string. This can't be a number.
+ return false;
+
+ // Get the decimal separator for the current locale.
+ const OUString& sep = aLocaleItem.decimalSeparator;
+
+ bool bDecimalSep = false;
+ for (sal_Int32 i = 0; i < size; ++i)
+ {
+ OUString c = str.copy(i, 1);
+ if ( !c.compareTo(sep) )
+ {
+ if ( bDecimalSep )
+ return false;
+ else
+ {
+ bDecimalSep = true;
+ continue;
+ }
+ }
+ if ( (0 > c.compareToAscii("0") || 0 < c.compareToAscii("9")) )
+ return false;
+ }
+
+ return true;
+}
+
+/** Convert wildcard characters to regex equivalent. Returns true if any
+ wildcard character is found. */
+static bool lclWildcard2Regex( OUString& str )
+{
+ bool bWCFound = false;
+ OUStringBuffer buf;
+ sal_Int32 size = str.getLength();
+ buf.ensureCapacity(size + 6); // pure heuristics.
+
+ sal_Unicode dot = '.', star = '*', hat = '^', dollar = '$';
+ buf.append(hat);
+ for (sal_Int32 i = 0; i < size; ++i)
+ {
+ OUString c = str.copy(i, 1);
+ if ( !c.compareToAscii("?") )
+ {
+ buf.append(dot);
+ bWCFound = true;
+ }
+ else if ( !c.compareToAscii("*") )
+ {
+ buf.append(dot);
+ buf.append(star);
+ bWCFound = true;
+ }
+ else
+ buf.append(c);
+ }
+ buf.append(dollar);
+
+ if (bWCFound)
+ str = buf.makeStringAndClear();
+
+ return bWCFound;
+}
+
+/** Translate Excel's filter operator to Calc's. */
+static ::com::sun::star::sheet::FilterOperator lclTranslateFilterOp( sal_Int32 nToken )
+{
+ using namespace ::com::sun::star::sheet;
+
+ switch ( nToken )
+ {
+ case XML_equal:
+ return FilterOperator_EQUAL;
+ case XML_notEqual:
+ return FilterOperator_NOT_EQUAL;
+ case XML_greaterThan:
+ return FilterOperator_GREATER;
+ case XML_greaterThanOrEqual:
+ return FilterOperator_GREATER_EQUAL;
+ case XML_lessThan:
+ return FilterOperator_LESS;
+ case XML_lessThanOrEqual:
+ return FilterOperator_LESS_EQUAL;
+ }
+ return FilterOperator_EQUAL;
+}
+
+void OoxAutoFilterContext::importCustomFilter( const AttributeList& rAttribs )
+{
+ using namespace ::com::sun::star::sheet;
+
+ sal_Int32 nToken = rAttribs.getToken( XML_operator, XML_equal );
+#if USE_SC_MULTI_STRING_FILTER_PATCH
+ FilterFieldItem aItem(FilterFieldItem::NORMAL);
+ TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get());
+#else
+ FilterFieldItem aItem;
+ TableFilterField* pField = aItem.mpField.get();
+#endif
+ pField->Field = mnCurColID;
+ pField->StringValue = rAttribs.getString( XML_val );
+ pField->NumericValue = pField->StringValue.toDouble();
+ pField->Operator = lclTranslateFilterOp( nToken );
+
+ if ( nToken == XML_notEqual && !pField->StringValue.compareToAscii(" ") )
+ {
+ // Special case for hiding blanks. Excel translates "hide blanks" to
+ // (filter if notEqual " "). So, we need to translate it back.
+ pField->Operator = FilterOperator_NOT_EMPTY;
+ pField->IsNumeric = false;
+ maFields.push_back(aItem);
+ return;
+ }
+
+ switch ( nToken )
+ {
+ case XML_equal:
+ case XML_notEqual:
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XLocaleData > xLocale( xFactory->createInstance(
+ CREATE_OUSTRING("com.sun.star.i18n.LocaleData") ), UNO_QUERY );
+
+ if ( !xLocale.is() )
+ return;
+
+ LocaleDataItem aLocaleItem = xLocale->getLocaleItem( ::com::sun::star::lang::Locale() );
+ pField->IsNumeric = lclIsNumeric(pField->StringValue, aLocaleItem);
+
+ if ( !pField->IsNumeric && lclWildcard2Regex(pField->StringValue) )
+ mbUseRegex = true;
+
+ maFields.push_back(aItem);
+ }
+ break;
+
+ case XML_greaterThan:
+ case XML_greaterThanOrEqual:
+ case XML_lessThan:
+ case XML_lessThanOrEqual:
+ {
+ pField->IsNumeric = true;
+ maFields.push_back(aItem);
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "OoxAutoFilterContext::importCustomFilter: unhandled case" );
+ }
+}
+
+void OoxAutoFilterContext::importFilters( const AttributeList& rAttribs )
+{
+ // blank (boolean) and calendarType attributes can be present, but not used for now.
+
+ mbShowBlank = rAttribs.getBool( XML_blank, false );
+ maFilterNames.clear();
+}
+
+void OoxAutoFilterContext::importFilter( const AttributeList& rAttribs )
+{
+ if (mnCurColID == -1)
+ return;
+
+ OUString value = rAttribs.getString( XML_val );
+ if ( value.getLength() )
+ maFilterNames.push_back(value);
+}
+
+void OoxAutoFilterContext::importDynamicFilter( const AttributeList& /*rAttribs*/ )
+{
+ // not implemented yet - Calc doesn't support this.
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/biffcodec.cxx b/oox/source/xls/biffcodec.cxx
new file mode 100644
index 000000000000..0eb0db29aa91
--- /dev/null
+++ b/oox/source/xls/biffcodec.cxx
@@ -0,0 +1,211 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: biffcodec.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:07 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffcodec.hxx"
+#include <osl/thread.h>
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OStringToOUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+const OString& BiffCodecHelper::getBiff5WbProtPassword()
+{
+ static const OString saPass( "VelvetSweatshop" );
+ return saPass;
+}
+
+const OUString& BiffCodecHelper::getBiff8WbProtPassword()
+{
+ static const OUString saPass = OStringToOUString( getBiff5WbProtPassword(), RTL_TEXTENCODING_ASCII_US );
+ return saPass;
+}
+
+// ============================================================================
+
+BiffDecoderBase::BiffDecoderBase( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnError( CODEC_ERROR_UNSUPP_CRYPT )
+{
+}
+
+BiffDecoderBase::~BiffDecoderBase()
+{
+}
+
+void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
+{
+ if( pnDestData && pnSrcData && (nBytes > 0) )
+ {
+ if( isValid() )
+ implDecode( pnDestData, pnSrcData, nStreamPos, nBytes );
+ else
+ memcpy( pnDestData, pnSrcData, nBytes );
+ }
+}
+
+void BiffDecoderBase::setHasValidPassword( bool bValid )
+{
+ mnError = bValid ? CODEC_OK : CODEC_ERROR_WRONG_PASS;
+}
+
+// ============================================================================
+
+BiffDecoder_XOR::BiffDecoder_XOR( const WorkbookHelper& rHelper, sal_uInt16 nKey, sal_uInt16 nHash ) :
+ BiffDecoderBase( rHelper ),
+ maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL )
+{
+ init( BiffCodecHelper::getBiff5WbProtPassword(), nKey, nHash );
+ if( !isValid() )
+ {
+ OString aPass = OUStringToOString( queryPassword(), osl_getThreadTextEncoding() );
+ init( aPass, nKey, nHash );
+ }
+}
+
+void BiffDecoder_XOR::init( const OString& rPass, sal_uInt16 nKey, sal_uInt16 nHash )
+{
+ sal_Int32 nLen = rPass.getLength();
+ bool bValid = (0 < nLen) && (nLen < 16);
+
+ if( bValid )
+ {
+ // copy byte string to sal_uInt8 array
+ sal_uInt8 pnPassw[ 16 ];
+ memset( pnPassw, 0, sizeof( pnPassw ) );
+ memcpy( pnPassw, rPass.getStr(), static_cast< size_t >( nLen ) );
+
+ // init codec
+ maCodec.initKey( pnPassw );
+ bValid = maCodec.verifyKey( nKey, nHash );
+ }
+
+ setHasValidPassword( bValid );
+}
+
+void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
+{
+ maCodec.startBlock();
+ maCodec.skip( static_cast< sal_Int32 >( (nStreamPos + nBytes) & 0x0F ) );
+ maCodec.decode( pnDestData, pnSrcData, nBytes );
+}
+
+// ============================================================================
+
+namespace {
+
+/** Returns the block index of the passed stream position for RCF decryption. */
+sal_Int32 lclGetRcfBlock( sal_Int64 nStreamPos )
+{
+ return static_cast< sal_Int32 >( nStreamPos / BIFF_RCF_BLOCKSIZE );
+}
+
+/** Returns the offset of the passed stream position in a block for RCF decryption. */
+sal_Int32 lclGetRcfOffset( sal_Int64 nStreamPos )
+{
+ return static_cast< sal_Int32 >( nStreamPos % BIFF_RCF_BLOCKSIZE );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+BiffDecoder_RCF::BiffDecoder_RCF( const WorkbookHelper& rHelper,
+ sal_uInt8 pnDocId[ 16 ], sal_uInt8 pnSaltData[ 16 ], sal_uInt8 pnSaltHash[ 16 ] ) :
+ BiffDecoderBase( rHelper )
+{
+ init( BiffCodecHelper::getBiff8WbProtPassword(), pnDocId, pnSaltData, pnSaltHash );
+ if( !isValid() )
+ init( queryPassword(), pnDocId, pnSaltData, pnSaltHash );
+}
+
+void BiffDecoder_RCF::init( const OUString& rPass, sal_uInt8 pnDocId[ 16 ], sal_uInt8 pnSaltData[ 16 ], sal_uInt8 pnSaltHash[ 16 ] )
+{
+ sal_Int32 nLen = rPass.getLength();
+ bool bValid = (0 < nLen) && (nLen < 16);
+
+ if( bValid )
+ {
+ // copy string to sal_uInt16 array
+ sal_uInt16 pnPassw[ 16 ];
+ memset( pnPassw, 0, sizeof( pnPassw ) );
+ const sal_Unicode* pcChar = rPass.getStr();
+ const sal_Unicode* pcCharEnd = pcChar + nLen;
+ sal_uInt16* pnCurrPass = pnPassw;
+ for( ; pcChar < pcCharEnd; ++pcChar, ++pnCurrPass )
+ *pnCurrPass = static_cast< sal_uInt16 >( *pcChar );
+
+ // init codec
+ maCodec.initKey( pnPassw, pnDocId );
+ bValid = maCodec.verifyKey( pnSaltData, pnSaltHash );
+ }
+
+ setHasValidPassword( bValid );
+}
+
+void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
+{
+ sal_uInt8* pnCurrDest = pnDestData;
+ const sal_uInt8* pnCurrSrc = pnSrcData;
+ sal_Int64 nCurrPos = nStreamPos;
+ sal_uInt16 nBytesLeft = nBytes;
+ while( nBytesLeft > 0 )
+ {
+ // initialize codec for current stream position
+ maCodec.startBlock( lclGetRcfBlock( nCurrPos ) );
+ maCodec.skip( lclGetRcfOffset( nCurrPos ) );
+
+ // decode the block
+ sal_uInt16 nBlockLeft = static_cast< sal_uInt16 >( BIFF_RCF_BLOCKSIZE - lclGetRcfOffset( nCurrPos ) );
+ sal_uInt16 nDecBytes = ::std::min( nBytesLeft, nBlockLeft );
+ maCodec.decode( pnCurrDest, pnCurrSrc, static_cast< sal_Int32 >( nDecBytes ) );
+
+ // prepare for next block
+ pnCurrDest += nDecBytes;
+ pnCurrSrc += nDecBytes;
+ nCurrPos += nDecBytes;
+ nBytesLeft = nBytesLeft - nDecBytes;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/biffdetector.cxx b/oox/source/xls/biffdetector.cxx
new file mode 100644
index 000000000000..b30e820fcbf0
--- /dev/null
+++ b/oox/source/xls/biffdetector.cxx
@@ -0,0 +1,241 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: biffdetector.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffdetector.hxx"
+#include <algorithm>
+#include <rtl/strbuf.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/olestorage.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::io::XInputStream;
+using ::comphelper::MediaDescriptor;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+Sequence< OUString > BiffDetector_getSupportedServiceNames()
+{
+ Sequence< OUString > aServiceNames( 1 );
+ aServiceNames[ 0 ] = CREATE_OUSTRING( "com.sun.star.frame.ExtendedTypeDetection" );
+ return aServiceNames;
+}
+
+OUString BiffDetector_getImplementationName()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.BiffDetector" );
+}
+
+Reference< XInterface > SAL_CALL BiffDetector_createInstance( const Reference< XMultiServiceFactory >& rxFactory ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new BiffDetector( rxFactory ) );
+}
+
+// ============================================================================
+
+BiffDetector::BiffDetector( const Reference< XMultiServiceFactory >& rxFactory ) :
+ mxFactory( rxFactory )
+{
+}
+
+BiffDetector::~BiffDetector()
+{
+}
+
+BiffType BiffDetector::detectStreamBiffVersion( BinaryInputStream& rInStream )
+{
+ BiffType eBiff = BIFF_UNKNOWN;
+ if( rInStream.is() && rInStream.isSeekable() && (rInStream.getLength() > 4) )
+ {
+ sal_Int64 nOldPos = rInStream.tell();
+ rInStream.seek( 0 );
+ sal_uInt16 nBofId, nBofSize;
+ rInStream >> nBofId >> nBofSize;
+
+ if( (4 <= nBofSize) && (nBofSize <= 16) && (rInStream.tell() + nBofSize <= rInStream.getLength()) )
+ {
+ switch( nBofId )
+ {
+ case BIFF2_ID_BOF:
+ eBiff = BIFF2;
+ break;
+ case BIFF3_ID_BOF:
+ eBiff = BIFF3;
+ break;
+ case BIFF4_ID_BOF:
+ eBiff = BIFF4;
+ break;
+ case BIFF5_ID_BOF:
+ {
+ if( 6 <= nBofSize )
+ {
+ sal_uInt16 nVersion;
+ rInStream >> nVersion;
+ // #i23425# #i44031# #i62752# there are some *really* broken documents out there...
+ switch( nVersion & 0xFF00 )
+ {
+ case 0: eBiff = BIFF5; break; // #i44031# #i62752#
+ case BIFF_BOF_BIFF2: eBiff = BIFF2; break;
+ case BIFF_BOF_BIFF3: eBiff = BIFF3; break;
+ case BIFF_BOF_BIFF4: eBiff = BIFF4; break;
+ case BIFF_BOF_BIFF5: eBiff = BIFF5; break;
+ case BIFF_BOF_BIFF8: eBiff = BIFF8; break;
+ default: OSL_ENSURE( false,
+ OStringBuffer( "lclDetectStreamBiffVersion - unknown BIFF version: 0x" ).
+ append( static_cast< sal_Int32 >( nVersion ), 16 ).getStr() );
+ }
+ }
+ }
+ break;
+ // else do nothing, no BIFF stream
+ }
+ }
+ rInStream.seek( nOldPos );
+ }
+ return eBiff;
+}
+
+BiffType BiffDetector::detectStorageBiffVersion( OUString& orWorkbookStreamName, StorageRef xStorage )
+{
+ static const OUString saBookName = CREATE_OUSTRING( "Book" );
+ static const OUString saWorkbookName = CREATE_OUSTRING( "Workbook" );
+
+ BiffType eBiff = BIFF_UNKNOWN;
+ if( xStorage.get() )
+ {
+ if( xStorage->isStorage() )
+ {
+ // try to open the "Book" stream
+ BinaryInputStream aBookStrm5( xStorage->openInputStream( saBookName ), true );
+ BiffType eBookStrm5Biff = detectStreamBiffVersion( aBookStrm5 );
+
+ // try to open the "Workbook" stream
+ BinaryInputStream aBookStrm8( xStorage->openInputStream( saWorkbookName ), true );
+ BiffType eBookStrm8Biff = detectStreamBiffVersion( aBookStrm8 );
+
+ // decide which stream to use
+ if( (eBookStrm8Biff != BIFF_UNKNOWN) && ((eBookStrm5Biff == BIFF_UNKNOWN) || (eBookStrm8Biff > eBookStrm5Biff)) )
+ {
+ /* Only "Workbook" stream exists; or both streams exist,
+ and "Workbook" has higher BIFF version than "Book" stream. */
+ eBiff = eBookStrm8Biff;
+ orWorkbookStreamName = saWorkbookName;
+ }
+ else if( eBookStrm5Biff != BIFF_UNKNOWN )
+ {
+ /* Only "Book" stream exists; or both streams exist,
+ and "Book" has higher BIFF version than "Workbook" stream. */
+ eBiff = eBookStrm5Biff;
+ orWorkbookStreamName = saBookName;
+ }
+ }
+ else
+ {
+ // no storage, try plain input stream from medium (even for BIFF5+)
+ BinaryInputStream aStrm( xStorage->openInputStream( OUString() ), false );
+ eBiff = detectStreamBiffVersion( aStrm );
+ orWorkbookStreamName = OUString();
+ }
+ }
+
+ return eBiff;
+}
+
+// com.sun.star.lang.XServiceInfo interface -----------------------------------
+
+OUString SAL_CALL BiffDetector::getImplementationName() throw( RuntimeException )
+{
+ return BiffDetector_getImplementationName();
+}
+
+sal_Bool SAL_CALL BiffDetector::supportsService( const OUString& rService ) throw( RuntimeException )
+{
+ const Sequence< OUString > aServices( BiffDetector_getSupportedServiceNames() );
+ const OUString* pArray = aServices.getConstArray();
+ const OUString* pArrayEnd = pArray + aServices.getLength();
+ return ::std::find( pArray, pArrayEnd, rService ) != pArrayEnd;
+}
+
+Sequence< OUString > SAL_CALL BiffDetector::getSupportedServiceNames() throw( RuntimeException )
+{
+ return BiffDetector_getSupportedServiceNames();
+}
+
+// com.sun.star.document.XExtendedFilterDetect interface ----------------------
+
+OUString SAL_CALL BiffDetector::detect( Sequence< PropertyValue >& rDescriptor ) throw( RuntimeException )
+{
+ OUString aTypeName;
+
+ MediaDescriptor aDescriptor( rDescriptor );
+ aDescriptor.addInputStream();
+
+ Reference< XInputStream > xInStrm( aDescriptor[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY );
+ if( xInStrm.is() )
+ {
+ OUString aWorkbookName;
+ StorageRef xStorage( new OleStorage( mxFactory, xInStrm, true ) );
+ switch( detectStorageBiffVersion( aWorkbookName, xStorage ) )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4: aTypeName = CREATE_OUSTRING( "calc_MS_Excel_40" ); break;
+ case BIFF5: aTypeName = CREATE_OUSTRING( "calc_MS_Excel_95" ); break;
+ case BIFF8: aTypeName = CREATE_OUSTRING( "calc_MS_Excel_97" ); break;
+ default:;
+ }
+ }
+
+ return aTypeName;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/bifffragmenthandler.cxx b/oox/source/xls/bifffragmenthandler.cxx
new file mode 100644
index 000000000000..061e213b1092
--- /dev/null
+++ b/oox/source/xls/bifffragmenthandler.cxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bifffragmenthandler.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/bifffragmenthandler.hxx"
+#include "oox/xls/biffhelper.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 BIFF_BOF_GLOBALS = 0x0005; /// BIFF5-BIFF8 workbook globals.
+const sal_uInt16 BIFF_BOF_MODULE = 0x0006; /// BIFF5-BIFF8 Visual Basic module.
+const sal_uInt16 BIFF_BOF_SHEET = 0x0010; /// BIFF2-BIFF8 worksheet/dialog sheet.
+const sal_uInt16 BIFF_BOF_CHART = 0x0020; /// BIFF2-BIFF8 chart sheet.
+const sal_uInt16 BIFF_BOF_MACRO = 0x0040; /// BIFF4-BIFF8 macro sheet.
+const sal_uInt16 BIFF_BOF_WORKSPACE = 0x0100; /// BIFF3-BIFF8 workspace.
+
+} // namespace
+
+// ============================================================================
+
+BiffFragmentHandler::~BiffFragmentHandler()
+{
+}
+
+bool BiffFragmentHandler::importFragment( BiffInputStream& rStrm )
+{
+ // default implementation: skip the entire fragment
+ return skipFragment( rStrm );
+}
+
+bool BiffFragmentHandler::isBofRecord( sal_uInt16 nRecId )
+{
+ return (nRecId == BIFF2_ID_BOF) || (nRecId == BIFF3_ID_BOF) || (nRecId == BIFF4_ID_BOF) || (nRecId == BIFF5_ID_BOF);
+}
+
+BiffFragmentType BiffFragmentHandler::startFragment( BiffInputStream& rStrm, BiffType eBiff )
+{
+ BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN;
+ if( rStrm.startNextRecord() )
+ {
+ /* #i23425# Don't rely on BOF record ID to read BOF contents, but on
+ the detected BIFF version. */
+ if( isBofRecord( rStrm.getRecId() ) )
+ {
+ // BOF is always written unencrypted
+ rStrm.enableDecoder( false );
+ sal_uInt16 nType = rStrm.skip( 2 ).readuInt16();
+
+ // decide which fragment types are valid for current BIFF version
+ switch( eBiff )
+ {
+ case BIFF2: switch( nType )
+ {
+ case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break;
+ case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACRO; break;
+ // #i51490# Excel interprets invalid types as worksheet
+ default: eFragment = BIFF_FRAGMENT_WORKSHEET;
+ }
+ break;
+
+ case BIFF3: switch( nType )
+ {
+ case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break;
+ case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACRO; break;
+ case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break;
+ // #i51490# Excel interprets invalid types as worksheet
+ default: eFragment = BIFF_FRAGMENT_WORKSHEET;
+ };
+ break;
+
+ case BIFF4: switch( nType )
+ {
+ case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break;
+ case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACRO; break;
+ case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_WORKSPACE; break;
+ // #i51490# Excel interprets invalid types as worksheet
+ default: eFragment = BIFF_FRAGMENT_WORKSHEET;
+ };
+ break;
+
+ case BIFF5:
+ case BIFF8: switch( nType )
+ {
+ case BIFF_BOF_GLOBALS: eFragment = BIFF_FRAGMENT_GLOBALS; break;
+ case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_CHART; break;
+ case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACRO; break;
+ case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break;
+ // #i51490# Excel interprets invalid types as worksheet
+ default: eFragment = BIFF_FRAGMENT_WORKSHEET;
+ };
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+ }
+ }
+ return eFragment;
+}
+
+bool BiffFragmentHandler::skipFragment( BiffInputStream& rStrm )
+{
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ if( isBofRecord( rStrm.getRecId() ) )
+ skipFragment( rStrm );
+ return rStrm.isValid() && (rStrm.getRecId() == BIFF_ID_EOF);
+}
+
+// ============================================================================
+
+BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+// ============================================================================
+
+BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const WorkbookHelper& rHelper,
+ ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) :
+ WorksheetHelperRoot( rHelper, xProgressBar, eSheetType, nSheet )
+{
+}
+
+BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const WorksheetHelper& rHelper ) :
+ WorksheetHelperRoot( rHelper )
+{
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/biffhelper.cxx b/oox/source/xls/biffhelper.cxx
new file mode 100644
index 000000000000..fb04a87e2502
--- /dev/null
+++ b/oox/source/xls/biffhelper.cxx
@@ -0,0 +1,296 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: biffhelper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffhelper.hxx"
+#include <algorithm>
+#include <rtl/math.hxx>
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/biffoutputstream.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace oox {
+namespace xls {
+
+// GUID =======================================================================
+
+BiffGuid::BiffGuid()
+{
+ ::std::fill_n( mpnData, sizeof( mpnData ), 0 );
+}
+
+BiffGuid::BiffGuid(
+ sal_uInt32 nData1, sal_uInt16 nData2, sal_uInt16 nData3,
+ sal_uInt8 nData41, sal_uInt8 nData42, sal_uInt8 nData43, sal_uInt8 nData44,
+ sal_uInt8 nData45, sal_uInt8 nData46, sal_uInt8 nData47, sal_uInt8 nData48 )
+{
+ // convert to little endian -> makes streaming easy
+ ByteOrderConverter::writeLittleEndian( mpnData, nData1 );
+ ByteOrderConverter::writeLittleEndian( mpnData + 4, nData2 );
+ ByteOrderConverter::writeLittleEndian( mpnData + 6, nData3 );
+ mpnData[ 8 ] = nData41;
+ mpnData[ 9 ] = nData42;
+ mpnData[ 10 ] = nData43;
+ mpnData[ 11 ] = nData44;
+ mpnData[ 12 ] = nData45;
+ mpnData[ 13 ] = nData46;
+ mpnData[ 14 ] = nData47;
+ mpnData[ 15 ] = nData48;
+}
+
+bool operator==( const BiffGuid& rGuid1, const BiffGuid& rGuid2 )
+{
+ return ::std::equal( rGuid1.mpnData, STATIC_ARRAY_END( rGuid1.mpnData ), rGuid2.mpnData );
+}
+
+bool operator<( const BiffGuid& rGuid1, const BiffGuid& rGuid2 )
+{
+ return ::std::lexicographical_compare(
+ rGuid1.mpnData, STATIC_ARRAY_END( rGuid1.mpnData ),
+ rGuid2.mpnData, STATIC_ARRAY_END( rGuid2.mpnData ) );
+}
+
+BiffInputStream& operator>>( BiffInputStream& rStrm, BiffGuid& rGuid )
+{
+ rStrm.read( rGuid.mpnData, 16 ); // mpnData always in little endian
+ return rStrm;
+}
+
+BiffOutputStream& operator<<( BiffOutputStream& rStrm, const BiffGuid& rGuid )
+{
+ rStrm.setPortionSize( 16 );
+ rStrm.write( rGuid.mpnData, 16 ); // mpnData already in little endian
+ rStrm.setPortionSize( 0 );
+ return rStrm;
+}
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 BIFF_RK_100FLAG = 0x00000001;
+const sal_Int32 BIFF_RK_INTFLAG = 0x00000002;
+const sal_Int32 BIFF_RK_VALUEMASK = 0xFFFFFFFC;
+
+// ----------------------------------------------------------------------------
+
+static const struct CodePageEntry
+{
+ sal_uInt16 mnCodePage;
+ rtl_TextEncoding meTextEnc;
+}
+spCodePages[] =
+{
+ { 437, RTL_TEXTENCODING_IBM_437 }, // OEM US
+// { 720, RTL_TEXTENCODING_IBM_720 }, // OEM Arabic
+ { 737, RTL_TEXTENCODING_IBM_737 }, // OEM Greek
+ { 775, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic
+ { 850, RTL_TEXTENCODING_IBM_850 }, // OEM Latin I
+ { 852, RTL_TEXTENCODING_IBM_852 }, // OEM Latin II (Central European)
+ { 855, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic
+ { 857, RTL_TEXTENCODING_IBM_857 }, // OEM Turkish
+// { 858, RTL_TEXTENCODING_IBM_858 }, // OEM Multilingual Latin I with Euro
+ { 860, RTL_TEXTENCODING_IBM_860 }, // OEM Portugese
+ { 861, RTL_TEXTENCODING_IBM_861 }, // OEM Icelandic
+ { 862, RTL_TEXTENCODING_IBM_862 }, // OEM Hebrew
+ { 863, RTL_TEXTENCODING_IBM_863 }, // OEM Canadian (French)
+ { 864, RTL_TEXTENCODING_IBM_864 }, // OEM Arabic
+ { 865, RTL_TEXTENCODING_IBM_865 }, // OEM Nordic
+ { 866, RTL_TEXTENCODING_IBM_866 }, // OEM Cyrillic (Russian)
+ { 869, RTL_TEXTENCODING_IBM_869 }, // OEM Greek (Modern)
+ { 874, RTL_TEXTENCODING_MS_874 }, // MS Windows Thai
+ { 932, RTL_TEXTENCODING_MS_932 }, // MS Windows Japanese Shift-JIS
+ { 936, RTL_TEXTENCODING_MS_936 }, // MS Windows Chinese Simplified GBK
+ { 949, RTL_TEXTENCODING_MS_949 }, // MS Windows Korean (Wansung)
+ { 950, RTL_TEXTENCODING_MS_950 }, // MS Windows Chinese Traditional BIG5
+ { 1200, RTL_TEXTENCODING_DONTKNOW }, // Unicode (BIFF8) - return *_DONTKNOW to preserve old code page
+ { 1250, RTL_TEXTENCODING_MS_1250 }, // MS Windows Latin II (Central European)
+ { 1251, RTL_TEXTENCODING_MS_1251 }, // MS Windows Cyrillic
+ { 1252, RTL_TEXTENCODING_MS_1252 }, // MS Windows Latin I (BIFF4-BIFF8)
+ { 1253, RTL_TEXTENCODING_MS_1253 }, // MS Windows Greek
+ { 1254, RTL_TEXTENCODING_MS_1254 }, // MS Windows Turkish
+ { 1255, RTL_TEXTENCODING_MS_1255 }, // MS Windows Hebrew
+ { 1256, RTL_TEXTENCODING_MS_1256 }, // MS Windows Arabic
+ { 1257, RTL_TEXTENCODING_MS_1257 }, // MS Windows Baltic
+ { 1258, RTL_TEXTENCODING_MS_1258 }, // MS Windows Vietnamese
+ { 1361, RTL_TEXTENCODING_MS_1361 }, // MS Windows Korean (Johab)
+ { 10000, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
+ { 32768, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman
+ { 32769, RTL_TEXTENCODING_MS_1252 } // MS Windows Latin I (BIFF2-BIFF3)
+};
+
+/** Predicate to search by given code page. */
+struct CodePageEntry_CPPred
+{
+ inline explicit CodePageEntry_CPPred( sal_uInt16 nCodePage ) : mnCodePage( nCodePage ) {}
+ inline bool operator()( const CodePageEntry& rEntry ) const { return rEntry.mnCodePage == mnCodePage; }
+ sal_uInt16 mnCodePage;
+};
+
+/** Predicate to search by given text encoding. */
+struct CodePageEntry_TEPred
+{
+ inline explicit CodePageEntry_TEPred( rtl_TextEncoding eTextEnc ) : meTextEnc( eTextEnc ) {}
+ inline bool operator()( const CodePageEntry& rEntry ) const { return rEntry.meTextEnc == meTextEnc; }
+ rtl_TextEncoding meTextEnc;
+};
+
+} // namespace
+
+// ============================================================================
+
+const BiffGuid BiffHelper::maGuidStdHlink(
+ 0x79EAC9D0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
+
+const BiffGuid BiffHelper::maGuidUrlMoniker(
+ 0x79EAC9E0, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B );
+
+const BiffGuid BiffHelper::maGuidFileMoniker(
+ 0x00000303, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
+
+// conversion -----------------------------------------------------------------
+
+double BiffHelper::calcDoubleFromRk( sal_Int32 nRkValue )
+{
+ double fValue = 0.0;
+ if( getFlag( nRkValue, BIFF_RK_INTFLAG ) )
+ {
+ sal_Int32 nTemp = nRkValue >> 2;
+ setFlag< sal_Int32 >( nTemp, 0xE0000000, nRkValue < 0 );
+ fValue = nTemp;
+ }
+ else
+ {
+ sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &fValue );
+ pDouble->w32_parts.msw = static_cast< sal_uInt32 >( nRkValue & BIFF_RK_VALUEMASK );
+ }
+
+ if( getFlag( nRkValue, BIFF_RK_100FLAG ) )
+ fValue /= 100.0;
+
+ return fValue;
+}
+
+namespace {
+
+bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue )
+{
+ // double
+ const sal_math_Double* pValue = reinterpret_cast< const sal_math_Double* >( &fValue );
+ if( (pValue->w32_parts.lsw == 0) && ((pValue->w32_parts.msw & 0x3) == 0) )
+ {
+ ornRkValue = static_cast< sal_Int32 >( pValue->w32_parts.msw );
+ return true;
+ }
+
+ // integer
+ double fInt = 0.0;
+ double fFrac = modf( fValue, &fInt );
+ if( (fFrac == 0.0) && (-536870912.0 <= fInt) && (fInt <= 536870911.0) ) // 2^29
+ {
+ ornRkValue = static_cast< sal_Int32 >( fInt );
+ ornRkValue <<= 2;
+ ornRkValue |= BIFF_RK_INTFLAG;
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+bool BiffHelper::calcRkFromDouble( sal_Int32& ornRkValue, double fValue )
+{
+ if( lclCalcRkFromDouble( ornRkValue, fValue ) )
+ return true;
+
+ if( lclCalcRkFromDouble( ornRkValue, fValue * 100 ) )
+ {
+ ornRkValue |= BIFF_RK_100FLAG;
+ return true;
+ }
+
+ return false;
+}
+
+double BiffHelper::calcDoubleFromError( sal_uInt8 nErrorCode )
+{
+ sal_uInt16 nApiError = 0x7FFF;
+ switch( nErrorCode )
+ {
+ case BIFF_ERR_NULL: nApiError = 521; break;
+ case BIFF_ERR_DIV0: nApiError = 532; break;
+ case BIFF_ERR_VALUE: nApiError = 519; break;
+ case BIFF_ERR_REF: nApiError = 524; break;
+ case BIFF_ERR_NAME: nApiError = 525; break;
+ case BIFF_ERR_NUM: nApiError = 503; break;
+ case BIFF_ERR_NA: nApiError = 0x7FFF; break;
+ default: OSL_ENSURE( false, "BiffHelper::calcDoubleFromError - unknown error code" );
+ }
+ double fValue;
+ ::rtl::math::setNan( &fValue );
+ reinterpret_cast< sal_math_Double* >( &fValue )->nan_parts.fraction_lo = nApiError;
+ return fValue;
+}
+
+rtl_TextEncoding BiffHelper::calcTextEncodingFromCodePage( sal_uInt16 nCodePage )
+{
+ const CodePageEntry* pEntry = ::std::find_if( spCodePages, STATIC_ARRAY_END( spCodePages ), CodePageEntry_CPPred( nCodePage ) );
+ if( pEntry == STATIC_ARRAY_END( spCodePages ) )
+ {
+ OSL_ENSURE( false, "UnitConverter::calcTextEncodingFromCodePage - unknown code page" );
+ return RTL_TEXTENCODING_DONTKNOW;
+ }
+ return pEntry->meTextEnc;
+}
+
+sal_uInt16 BiffHelper::calcCodePageFromTextEncoding( rtl_TextEncoding eTextEnc )
+{
+ const CodePageEntry* pEntry = ::std::find_if( spCodePages, STATIC_ARRAY_END( spCodePages ), CodePageEntry_TEPred( eTextEnc ) );
+ if( pEntry == STATIC_ARRAY_END( spCodePages ) )
+ {
+ OSL_ENSURE( false, "UnitConverter::calcCodePageFromTextEncoding - unsupported text encoding" );
+ return 1252;
+ }
+ return pEntry->mnCodePage;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/biffinputstream.cxx b/oox/source/xls/biffinputstream.cxx
new file mode 100644
index 000000000000..70428f9de3ad
--- /dev/null
+++ b/oox/source/xls/biffinputstream.cxx
@@ -0,0 +1,646 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: biffinputstream.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using ::rtl::OStringToOUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace prv {
+
+BiffInputRecordBuffer::BiffInputRecordBuffer( BinaryInputStream& rInStrm ) :
+ mrInStrm( rInStrm ),
+ mpCurrentData( 0 ),
+ mnHeaderPos( -1 ),
+ mnBodyPos( 0 ),
+ mnBufferBodyPos( 0 ),
+ mnNextHeaderPos( 0 ),
+ mnRecId( BIFF_ID_UNKNOWN ),
+ mnRecSize( 0 ),
+ mnRecPos( 0 ),
+ mbValidHeader( false )
+{
+ OSL_ENSURE( mrInStrm.isSeekable(), "BiffInputRecordBuffer::BiffInputRecordBuffer - stream must be seekable" );
+ mrInStrm.seekToStart();
+ maOriginalData.reserve( SAL_MAX_UINT16 );
+ maDecodedData.reserve( SAL_MAX_UINT16 );
+ enableDecoder( false ); // updates mpCurrentData
+}
+
+void BiffInputRecordBuffer::restartAt( sal_Int64 nPos )
+{
+ mnHeaderPos = -1;
+ mnBodyPos = mnBufferBodyPos = 0;
+ mnNextHeaderPos = nPos;
+ mnRecId = BIFF_ID_UNKNOWN;
+ mnRecSize = mnRecPos = 0;
+ mbValidHeader = false;
+}
+
+void BiffInputRecordBuffer::setDecoder( BiffDecoderRef xDecoder )
+{
+ mxDecoder = xDecoder;
+ enableDecoder( true );
+ updateDecoded();
+}
+
+void BiffInputRecordBuffer::enableDecoder( bool bEnable )
+{
+ mpCurrentData = (bEnable && mxDecoder.get() && mxDecoder->isValid()) ? &maDecodedData : &maOriginalData;
+}
+
+bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos )
+{
+ mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.getLength());
+ if( mbValidHeader )
+ {
+ mnHeaderPos = nHeaderPos;
+ mrInStrm.seek( nHeaderPos );
+ mrInStrm >> mnRecId >> mnRecSize;
+ mnBodyPos = mrInStrm.tell();
+ mnNextHeaderPos = mnBodyPos + mnRecSize;
+ mbValidHeader = mnNextHeaderPos <= mrInStrm.getLength();
+ }
+ if( !mbValidHeader )
+ {
+ mnHeaderPos = mnBodyPos = -1;
+ mnNextHeaderPos = 0;
+ mnRecId = BIFF_ID_UNKNOWN;
+ mnRecSize = 0;
+ }
+ mnRecPos = 0;
+ return mbValidHeader;
+}
+
+bool BiffInputRecordBuffer::startNextRecord()
+{
+ return startRecord( mnNextHeaderPos );
+}
+
+sal_uInt16 BiffInputRecordBuffer::getNextRecId()
+{
+ sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
+ if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.getLength()) )
+ {
+ mrInStrm.seek( mnNextHeaderPos );
+ mrInStrm >> nRecId;
+ }
+ return nRecId;
+}
+
+void BiffInputRecordBuffer::read( void* opData, sal_uInt16 nBytes )
+{
+ updateBuffer();
+ OSL_ENSURE( nBytes > 0, "BiffInputRecordBuffer::read - nothing to read" );
+ OSL_ENSURE( nBytes <= getRecLeft(), "BiffInputRecordBuffer::read - buffer overflow" );
+ memcpy( opData, &(*mpCurrentData)[ mnRecPos ], nBytes );
+ mnRecPos = mnRecPos + nBytes;
+}
+
+inline void BiffInputRecordBuffer::skip( sal_uInt16 nBytes )
+{
+ OSL_ENSURE( nBytes > 0, "BiffInputRecordBuffer::skip - nothing to skip" );
+ OSL_ENSURE( nBytes <= getRecLeft(), "BiffInputRecordBuffer::skip - buffer overflow" );
+ mnRecPos = mnRecPos + nBytes;
+}
+
+void BiffInputRecordBuffer::updateBuffer()
+{
+ OSL_ENSURE( mbValidHeader, "BiffInputRecordBuffer::updateBuffer - invalid access" );
+ if( mnBodyPos != mnBufferBodyPos )
+ {
+ mrInStrm.seek( mnBodyPos );
+ maOriginalData.resize( mnRecSize );
+ if( mnRecSize > 0 )
+ mrInStrm.read( &maOriginalData.front(), static_cast< sal_Int32 >( mnRecSize ) );
+ mnBufferBodyPos = mnBodyPos;
+ updateDecoded();
+ }
+}
+
+void BiffInputRecordBuffer::updateDecoded()
+{
+ if( mxDecoder.get() && mxDecoder->isValid() )
+ {
+ maDecodedData.resize( mnRecSize );
+ if( mnRecSize > 0 )
+ mxDecoder->decode( &maDecodedData.front(), &maOriginalData.front(), mnBodyPos, mnRecSize );
+ }
+}
+
+} // namespace prv
+
+// ============================================================================
+
+BiffInputStream::BiffInputStream( BinaryInputStream& rInStream, bool bContLookup ) :
+ maRecBuffer( rInStream ),
+ mnRecHandle( -1 ),
+ mnRecId( BIFF_ID_UNKNOWN ),
+ mnAltContId( BIFF_ID_UNKNOWN ),
+ mnCurrRecSize( 0 ),
+ mnComplRecSize( 0 ),
+ mbHasComplRec( false ),
+ mcNulSubst( BIFF_DEF_NUL_SUBST_CHAR ),
+ mbCont( bContLookup ),
+ mbValid( false )
+{
+}
+
+BiffInputStream::~BiffInputStream()
+{
+}
+
+// record control -------------------------------------------------------------
+
+bool BiffInputStream::startNextRecord()
+{
+ bool bValidRec = false;
+ /* #i4266# ignore zero records (id==len==0) (e.g. the application
+ "Crystal Report" writes zero records between other records) */
+ bool bIsZeroRec = false;
+ do
+ {
+ // record header is never encrypted
+ maRecBuffer.enableDecoder( false );
+ // read header of next raw record, returns false at end of stream
+ bValidRec = maRecBuffer.startNextRecord();
+ // ignore record, if identifier and size are zero
+ bIsZeroRec = (maRecBuffer.getRecId() == 0) && (maRecBuffer.getRecSize() == 0);
+ }
+ while( bValidRec && ((mbCont && isContinueId( maRecBuffer.getRecId() )) || bIsZeroRec) );
+
+ // setup other class members
+ setupRecord();
+ return isInRecord();
+}
+
+bool BiffInputStream::startRecordByHandle( sal_Int64 nRecHandle )
+{
+ rewindToRecord( nRecHandle );
+ return startNextRecord();
+}
+
+void BiffInputStream::resetRecord( bool bContLookup, sal_uInt16 nAltContId )
+{
+ if( isInRecord() )
+ {
+ mbCont = bContLookup;
+ mnAltContId = nAltContId;
+ restartRecord( true );
+ maRecBuffer.enableDecoder( true );
+ }
+}
+
+void BiffInputStream::rewindRecord()
+{
+ rewindToRecord( mnRecHandle );
+}
+
+// decoder --------------------------------------------------------------------
+
+void BiffInputStream::setDecoder( BiffDecoderRef xDecoder )
+{
+ maRecBuffer.setDecoder( xDecoder );
+}
+
+BiffDecoderRef BiffInputStream::getDecoder() const
+{
+ return maRecBuffer.getDecoder();
+}
+
+void BiffInputStream::enableDecoder( bool bEnable )
+{
+ maRecBuffer.enableDecoder( bEnable );
+}
+
+// stream/record state and info -----------------------------------------------
+
+sal_uInt32 BiffInputStream::getRecPos() const
+{
+ return mbValid ? (mnCurrRecSize - maRecBuffer.getRecLeft()) : BIFF_REC_SEEK_TO_END;
+}
+
+sal_uInt32 BiffInputStream::getRecSize()
+{
+ if( !mbHasComplRec )
+ {
+ sal_uInt32 nCurrPos = getRecPos(); // save current position in record
+ while( jumpToNextContinue() ); // jumpToNextContinue() adds up mnCurrRecSize
+ mnComplRecSize = mnCurrRecSize;
+ mbHasComplRec = true;
+ seek( nCurrPos ); // restore position, seek() resets old mbValid state
+ }
+ return mnComplRecSize;
+}
+
+sal_uInt32 BiffInputStream::getRecLeft()
+{
+ return mbValid ? (getRecSize() - getRecPos()) : 0;
+}
+
+sal_uInt16 BiffInputStream::getNextRecId()
+{
+ sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
+ if( isInRecord() )
+ {
+ sal_uInt32 nCurrPos = getRecPos(); // save current position in record
+ while( jumpToNextContinue() ); // skip following CONTINUE records
+ if( maRecBuffer.startNextRecord() ) // read header of next record
+ nRecId = maRecBuffer.getRecId();
+ seek( nCurrPos ); // restore position, seek() resets old mbValid state
+ }
+ return nRecId;
+}
+
+sal_Int64 BiffInputStream::getCoreStreamPos() const
+{
+ return maRecBuffer.getCoreStream().tell();
+}
+
+sal_Int64 BiffInputStream::getCoreStreamSize() const
+{
+ return maRecBuffer.getCoreStream().getLength();
+}
+
+// stream read access ---------------------------------------------------------
+
+sal_uInt32 BiffInputStream::read( void* opData, sal_uInt32 nBytes )
+{
+ sal_uInt32 nRet = 0;
+ if( mbValid && opData && (nBytes > 0) )
+ {
+ sal_uInt8* pnBuffer = reinterpret_cast< sal_uInt8* >( opData );
+ sal_uInt32 nBytesLeft = nBytes;
+
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft );
+ // check nReadSize, stream may already be located at end of a raw record
+ if( nReadSize > 0 )
+ {
+ maRecBuffer.read( pnBuffer, nReadSize );
+ nRet += nReadSize;
+ pnBuffer += nReadSize;
+ nBytesLeft -= nReadSize;
+ }
+ if( nBytesLeft > 0 )
+ jumpToNextContinue();
+ OSL_ENSURE( mbValid, "BiffInputStream::read - record overread" );
+ }
+ }
+ return nRet;
+}
+
+// seeking --------------------------------------------------------------------
+
+BiffInputStream& BiffInputStream::seek( sal_uInt32 nRecPos )
+{
+ if( isInRecord() )
+ {
+ if( !mbValid || (nRecPos < getRecPos()) )
+ restartRecord( false );
+ if( mbValid && (nRecPos > getRecPos()) )
+ skip( nRecPos - getRecPos() );
+ }
+ return *this;
+}
+
+BiffInputStream& BiffInputStream::skip( sal_uInt32 nBytes )
+{
+ sal_uInt32 nBytesLeft = nBytes;
+ while( mbValid && (nBytesLeft > 0) )
+ {
+ sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft );
+ // check nSkipSize, stream may already be located at end of a raw record
+ if( nSkipSize > 0 )
+ {
+ maRecBuffer.skip( nSkipSize );
+ nBytesLeft -= nSkipSize;
+ }
+ if( nBytesLeft > 0 )
+ jumpToNextContinue();
+ OSL_ENSURE( mbValid, "BiffInputStream::skip - record overread" );
+ }
+ return *this;
+}
+
+// character arrays -----------------------------------------------------------
+
+OString BiffInputStream::readCharArray( sal_uInt16 nChars )
+{
+ ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nChars ) + 1 );
+ size_t nCharsRead = static_cast< size_t >( read( &aBuffer.front(), nChars ) );
+ aBuffer[ nCharsRead ] = 0;
+ return OString( &aBuffer.front() );
+}
+
+OUString BiffInputStream::readCharArray( sal_uInt16 nChars, rtl_TextEncoding eTextEnc )
+{
+ return OStringToOUString( readCharArray( nChars ), eTextEnc );
+}
+
+OUString BiffInputStream::readUnicodeArray( sal_uInt16 nChars )
+{
+ ::std::vector< sal_Unicode > aBuffer;
+ aBuffer.reserve( static_cast< size_t >( nChars ) + 1 );
+ sal_uInt16 nChar;
+ for( sal_uInt16 nCharIdx = 0; mbValid && (nCharIdx < nChars); ++nCharIdx )
+ {
+ readValue( nChar );
+ aBuffer.push_back( static_cast< sal_Unicode >( nChar ) );
+ }
+ aBuffer.push_back( 0 );
+ return OUString( &aBuffer.front() );
+}
+
+// byte strings ---------------------------------------------------------------
+
+OString BiffInputStream::readByteString( bool b16BitLen )
+{
+ sal_uInt16 nStrLen = b16BitLen ? readuInt16() : readuInt8();
+ return readCharArray( nStrLen );
+}
+
+OUString BiffInputStream::readByteString( bool b16BitLen, rtl_TextEncoding eTextEnc )
+{
+ return OStringToOUString( readByteString( b16BitLen ), eTextEnc );
+}
+
+void BiffInputStream::skipByteString( bool b16BitLen )
+{
+ skip( b16BitLen ? readuInt16() : readuInt8() );
+}
+
+// Unicode strings ------------------------------------------------------------
+
+sal_uInt32 BiffInputStream::readExtendedUniStringHeader(
+ bool& rb16Bit, bool& rbFonts, bool& rbPhonetic,
+ sal_uInt16& rnFontCount, sal_uInt32& rnPhoneticSize, sal_uInt8 nFlags )
+{
+ OSL_ENSURE( !getFlag( nFlags, BIFF_STRF_UNKNOWN ), "BiffInputStream::readExtendedUniStringHeader - unknown flags" );
+ rb16Bit = getFlag( nFlags, BIFF_STRF_16BIT );
+ rbFonts = getFlag( nFlags, BIFF_STRF_RICH );
+ rbPhonetic = getFlag( nFlags, BIFF_STRF_PHONETIC );
+ rnFontCount = 0;
+ if( rbFonts ) readValue( rnFontCount );
+ rnPhoneticSize = 0;
+ if( rbPhonetic ) readValue( rnPhoneticSize );
+ return rnPhoneticSize + 4 * rnFontCount;
+}
+
+sal_uInt32 BiffInputStream::readExtendedUniStringHeader( bool& rb16Bit, sal_uInt8 nFlags )
+{
+ bool bFonts, bPhonetic;
+ sal_uInt16 nFontCount;
+ sal_uInt32 nPhoneticSize;
+ return readExtendedUniStringHeader( rb16Bit, bFonts, bPhonetic, nFontCount, nPhoneticSize, nFlags );
+}
+
+OUString BiffInputStream::readRawUniString( sal_uInt16 nChars, bool b16Bit )
+{
+ ::std::vector< sal_Unicode > aCharVec;
+ aCharVec.reserve( nChars + 1 );
+
+ /* This function has to react on CONTINUE records to reads the repeated
+ flags field, so readUnicodeArray() cannot be used here. */
+ sal_uInt16 nCharsLeft = nChars;
+ while( isValid() && (nCharsLeft > 0) )
+ {
+ sal_uInt16 nPortionCount = 0;
+ if( b16Bit )
+ {
+ nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 );
+ OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0),
+ "BiffInputStream::readRawUniString - missing a byte" );
+ // read the character array
+ sal_uInt16 nReadChar;
+ for( sal_uInt16 nCharIdx = 0; isValid() && (nCharIdx < nPortionCount); ++nCharIdx )
+ {
+ readValue( nReadChar );
+ aCharVec.push_back( (nReadChar == 0) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar ) );
+ }
+ }
+ else
+ {
+ nPortionCount = getMaxRawReadSize( nCharsLeft );
+ // read the character array
+ sal_uInt8 nReadChar;
+ for( sal_uInt16 nCharIdx = 0; isValid() && (nCharIdx < nPortionCount); ++nCharIdx )
+ {
+ readValue( nReadChar );
+ aCharVec.push_back( (nReadChar == 0) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar ) );
+ }
+ }
+
+ // prepare for next CONTINUE record
+ nCharsLeft = nCharsLeft - nPortionCount;
+ if( nCharsLeft > 0 )
+ jumpToNextStringContinue( b16Bit );
+ }
+
+ // string may contain embedded NUL characters, do not create the OUString by length of vector
+ aCharVec.push_back( 0 );
+ return OUString( &aCharVec.front() );
+}
+
+OUString BiffInputStream::readUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
+{
+ bool b16Bit;
+ sal_uInt32 nExtSize = readExtendedUniStringHeader( b16Bit, nFlags );
+ OUString aStr = readRawUniString( nChars, b16Bit );
+ skip( nExtSize );
+ return aStr;
+}
+
+OUString BiffInputStream::readUniString( sal_uInt16 nChars )
+{
+ return readUniString( nChars, readuInt8() );
+}
+
+OUString BiffInputStream::readUniString()
+{
+ return readUniString( readuInt16() );
+}
+
+void BiffInputStream::skipRawUniString( sal_uInt16 nChars, bool b16Bit )
+{
+ sal_uInt16 nCharsLeft = nChars;
+ while( isValid() && (nCharsLeft > 0) )
+ {
+ sal_uInt16 nPortionCount;
+ if( b16Bit )
+ {
+ nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 );
+ OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0),
+ "BiffInputStream::skipRawUniString - missing a byte" );
+ skip( 2 * nPortionCount );
+ }
+ else
+ {
+ nPortionCount = getMaxRawReadSize( nCharsLeft );
+ skip( nPortionCount );
+ }
+
+ // prepare for next CONTINUE record
+ nCharsLeft = nCharsLeft - nPortionCount;
+ if( nCharsLeft > 0 )
+ jumpToNextStringContinue( b16Bit );
+ }
+}
+
+void BiffInputStream::skipUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
+{
+ bool b16Bit;
+ sal_uInt32 nExtSize = readExtendedUniStringHeader( b16Bit, nFlags );
+ skipRawUniString( nChars, b16Bit );
+ skip( nExtSize );
+}
+
+void BiffInputStream::skipUniString( sal_uInt16 nChars )
+{
+ skipUniString( nChars, readuInt8() );
+}
+
+void BiffInputStream::skipUniString()
+{
+ skipUniString( readuInt16() );
+}
+
+// private --------------------------------------------------------------------
+
+void BiffInputStream::setupRecord()
+{
+ // initialize class members
+ mnRecHandle = maRecBuffer.getRecHeaderPos();
+ mnRecId = maRecBuffer.getRecId();
+ mnAltContId = BIFF_ID_UNKNOWN;
+ mnCurrRecSize = mnComplRecSize = maRecBuffer.getRecSize();
+ mbHasComplRec = !mbCont;
+ mbValid = isInRecord();
+ setNulSubstChar( BIFF_DEF_NUL_SUBST_CHAR );
+ // enable decoder in new record
+ enableDecoder( true );
+}
+
+void BiffInputStream::restartRecord( bool bInvalidateRecSize )
+{
+ if( isInRecord() )
+ {
+ maRecBuffer.startRecord( getRecHandle() );
+ mnCurrRecSize = maRecBuffer.getRecSize();
+ if( bInvalidateRecSize )
+ {
+ mnComplRecSize = mnCurrRecSize;
+ mbHasComplRec = !mbCont;
+ }
+ mbValid = true;
+ }
+}
+
+void BiffInputStream::rewindToRecord( sal_Int64 nRecHandle )
+{
+ if( nRecHandle >= 0 )
+ {
+ maRecBuffer.restartAt( nRecHandle );
+ mnRecHandle = -1;
+ mbValid = false;
+ }
+}
+
+bool BiffInputStream::isContinueId( sal_uInt16 nRecId ) const
+{
+ return (nRecId == BIFF_ID_CONT) || (nRecId == mnAltContId);
+}
+
+bool BiffInputStream::jumpToNextContinue()
+{
+ mbValid = mbValid && mbCont && isContinueId( maRecBuffer.getNextRecId() ) && maRecBuffer.startNextRecord();
+ if( mbValid )
+ mnCurrRecSize += maRecBuffer.getRecSize();
+ return mbValid;
+}
+
+bool BiffInputStream::jumpToNextStringContinue( bool& rb16Bit )
+{
+ OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - unexpected garbage" );
+
+ if( mbCont && (getRecLeft() > 0) )
+ {
+ jumpToNextContinue();
+ }
+ else if( mnRecId == BIFF_ID_CONT )
+ {
+ /* CONTINUE handling is off, but we have started reading in a CONTINUE
+ record -> start next CONTINUE for TXO import. We really start a new
+ record here - no chance to return to string origin. */
+ mbValid = mbValid && (maRecBuffer.getNextRecId() == BIFF_ID_CONT) && maRecBuffer.startNextRecord();
+ if( mbValid )
+ setupRecord();
+ }
+
+ // trying to read the flags invalidates stream, if no CONTINUE record has been found
+ sal_uInt8 nFlags;
+ readValue( nFlags );
+ rb16Bit = getFlag( nFlags, BIFF_STRF_16BIT );
+ return mbValid;
+}
+
+bool BiffInputStream::ensureRawReadSize( sal_uInt16 nBytes )
+{
+ if( mbValid && (nBytes > 0) )
+ {
+ while( mbValid && (maRecBuffer.getRecLeft() == 0) ) jumpToNextContinue();
+ mbValid = mbValid && (nBytes <= maRecBuffer.getRecLeft());
+ OSL_ENSURE( mbValid, "BiffInputStream::ensureRawReadSize - record overread" );
+ }
+ return mbValid;
+}
+
+sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_uInt32 nBytes ) const
+{
+ return static_cast< sal_uInt16 >( ::std::min< sal_uInt32 >( nBytes, maRecBuffer.getRecLeft() ) );
+}
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/biffoutputstream.cxx b/oox/source/xls/biffoutputstream.cxx
new file mode 100644
index 000000000000..570b145931ce
--- /dev/null
+++ b/oox/source/xls/biffoutputstream.cxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: biffoutputstream.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffoutputstream.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace prv {
+
+BiffOutputRecordBuffer::BiffOutputRecordBuffer( BinaryOutputStream& rOutStrm, sal_uInt16 nMaxRecSize ) :
+ mrOutStrm( rOutStrm ),
+ mnMaxRecSize( nMaxRecSize ),
+ mnRecId( BIFF_ID_UNKNOWN ),
+ mbInRec( false )
+{
+ OSL_ENSURE( mrOutStrm.isSeekable(), "BiffOutputRecordBuffer::BiffOutputRecordBuffer - stream must be seekable" );
+ maData.reserve( SAL_MAX_UINT16 );
+}
+
+void BiffOutputRecordBuffer::startRecord( sal_uInt16 nRecId )
+{
+ OSL_ENSURE( !mbInRec, "BiffOutputRecordBuffer::startRecord - another record still open" );
+ mnRecId = nRecId;
+ maData.clear();
+ mbInRec = true;
+}
+
+void BiffOutputRecordBuffer::endRecord()
+{
+ OSL_ENSURE( mbInRec, "BiffOutputRecordBuffer::endRecord - no record open" );
+ sal_uInt16 nRecSize = getLimitedValue< sal_uInt16, size_t >( maData.size(), 0, SAL_MAX_UINT16 );
+ mrOutStrm.seekToEnd();
+ mrOutStrm << mnRecId << nRecSize;
+ if( nRecSize > 0 )
+ mrOutStrm.write( &maData.front(), nRecSize );
+ mbInRec = false;
+}
+
+void BiffOutputRecordBuffer::write( const void* pData, sal_uInt16 nBytes )
+{
+ OSL_ENSURE( mbInRec, "BiffOutputRecordBuffer::write - no record open" );
+ OSL_ENSURE( nBytes > 0, "BiffOutputRecordBuffer::write - nothing to write" );
+ OSL_ENSURE( nBytes <= getRecLeft(), "BiffOutputRecordBuffer::write - buffer overflow" );
+ maData.resize( maData.size() + nBytes );
+ memcpy( &*(maData.end() - nBytes), pData, nBytes );
+}
+
+void BiffOutputRecordBuffer::fill( sal_uInt8 nValue, sal_uInt16 nBytes )
+{
+ OSL_ENSURE( mbInRec, "BiffOutputRecordBuffer::write - no record open" );
+ OSL_ENSURE( nBytes > 0, "BiffOutputRecordBuffer::write - nothing to write" );
+ OSL_ENSURE( nBytes <= getRecLeft(), "BiffOutputRecordBuffer::write - buffer overflow" );
+ maData.resize( maData.size() + nBytes, nValue );
+}
+
+} // namespace prv
+
+// ============================================================================
+
+BiffOutputStream::BiffOutputStream( BinaryOutputStream& rOutStream, sal_uInt16 nMaxRecSize ) :
+ maRecBuffer( rOutStream, nMaxRecSize ),
+ mnPortionSize( 0 ),
+ mnPortionPos( 0 )
+{
+}
+
+BiffOutputStream::~BiffOutputStream()
+{
+}
+
+// record control -------------------------------------------------------------
+
+void BiffOutputStream::startRecord( sal_uInt16 nRecId )
+{
+ maRecBuffer.startRecord( nRecId );
+ setPortionSize( 0 );
+}
+
+void BiffOutputStream::endRecord()
+{
+ maRecBuffer.endRecord();
+}
+
+void BiffOutputStream::setPortionSize( sal_uInt16 nSize )
+{
+ mnPortionSize = nSize;
+ mnPortionPos = 0;
+}
+
+// stream/record state and info -----------------------------------------------
+
+// stream write access --------------------------------------------------------
+
+void BiffOutputStream::write( const void* pData, sal_uInt32 nBytes )
+{
+ if( pData && (nBytes > 0) )
+ {
+ const sal_uInt8* pnBuffer = reinterpret_cast< const sal_uInt8* >( pData );
+ sal_uInt32 nBytesLeft = nBytes;
+ while( nBytesLeft > 0 )
+ {
+ sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft );
+ maRecBuffer.write( pnBuffer, nBlockSize );
+ pnBuffer += nBlockSize;
+ nBytesLeft -= nBlockSize;
+ }
+ }
+}
+
+void BiffOutputStream::fill( sal_uInt8 nValue, sal_uInt32 nBytes )
+{
+ sal_uInt32 nBytesLeft = nBytes;
+ while( nBytesLeft > 0 )
+ {
+ sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft );
+ maRecBuffer.fill( nValue, nBlockSize );
+ nBytesLeft -= nBlockSize;
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void BiffOutputStream::ensureRawBlock( sal_uInt16 nSize )
+{
+ if( (maRecBuffer.getRecLeft() < nSize) ||
+ ((mnPortionSize > 0) && (mnPortionPos == 0) && (maRecBuffer.getRecLeft() < mnPortionSize)) )
+ {
+ maRecBuffer.endRecord();
+ maRecBuffer.startRecord( BIFF_ID_CONT );
+ }
+ if( mnPortionSize > 0 )
+ {
+ OSL_ENSURE( mnPortionPos + nSize <= mnPortionSize, "BiffOutputStreamI::ensureRawBlock - portion overflow" );
+ mnPortionPos = (mnPortionPos + nSize) % mnPortionSize; // prevent compiler warning, do not use operator+=, operator%=
+ }
+}
+
+sal_uInt16 BiffOutputStream::prepareRawBlock( sal_uInt32 nTotalSize )
+{
+ sal_uInt16 nRecLeft = maRecBuffer.getRecLeft();
+ if( mnPortionSize > 0 )
+ {
+ OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::prepareRawBlock - block operation inside portion" );
+ OSL_ENSURE( nTotalSize % mnPortionSize == 0, "BiffOutputStream::prepareRawBlock - portion size does not match block size" );
+ nRecLeft = (nRecLeft / mnPortionSize) * mnPortionSize;
+ }
+ sal_uInt16 nSize = getLimitedValue< sal_uInt16, sal_uInt32 >( nTotalSize, 0, nRecLeft );
+ ensureRawBlock( nSize );
+ return nSize;
+}
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/condformatbuffer.cxx b/oox/source/xls/condformatbuffer.cxx
new file mode 100644
index 000000000000..f22910846d6c
--- /dev/null
+++ b/oox/source/xls/condformatbuffer.cxx
@@ -0,0 +1,782 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: condformatbuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/condformatbuffer.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/validationpropertyhelper.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::style::XStyleFamiliesSupplier;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::container::XNameContainer;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::ConditionOperator;
+using ::com::sun::star::table::XCellRange;
+using ::com::sun::star::sheet::XSheetCellRanges;
+using ::com::sun::star::sheet::XSheetConditionalEntries;
+using ::com::sun::star::sheet::XSpreadsheetDocument;
+using ::com::sun::star::sheet::XSpreadsheets;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::style::XStyle;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 OOBIN_CFRULE_TYPE_CELLIS = 1;
+const sal_Int32 OOBIN_CFRULE_TYPE_EXPRESSION = 2;
+const sal_Int32 OOBIN_CFRULE_TYPE_COLORSCALE = 3;
+const sal_Int32 OOBIN_CFRULE_TYPE_DATABAR = 4;
+const sal_Int32 OOBIN_CFRULE_TYPE_TOPTEN = 5;
+const sal_Int32 OOBIN_CFRULE_TYPE_ICONSET = 6;
+
+const sal_Int32 OOBIN_CFRULE_SUB_CELLIS = 0;
+const sal_Int32 OOBIN_CFRULE_SUB_EXPRESSION = 1;
+const sal_Int32 OOBIN_CFRULE_SUB_COLORSCALE = 2;
+const sal_Int32 OOBIN_CFRULE_SUB_DATABAR = 3;
+const sal_Int32 OOBIN_CFRULE_SUB_ICONSET = 4;
+const sal_Int32 OOBIN_CFRULE_SUB_TOPTEN = 5;
+const sal_Int32 OOBIN_CFRULE_SUB_UNIQUE = 7;
+const sal_Int32 OOBIN_CFRULE_SUB_TEXT = 8;
+const sal_Int32 OOBIN_CFRULE_SUB_BLANK = 9;
+const sal_Int32 OOBIN_CFRULE_SUB_NOTBLANK = 10;
+const sal_Int32 OOBIN_CFRULE_SUB_ERROR = 11;
+const sal_Int32 OOBIN_CFRULE_SUB_NOTERROR = 12;
+const sal_Int32 OOBIN_CFRULE_SUB_TODAY = 15;
+const sal_Int32 OOBIN_CFRULE_SUB_TOMORROW = 16;
+const sal_Int32 OOBIN_CFRULE_SUB_YESTERDAY = 17;
+const sal_Int32 OOBIN_CFRULE_SUB_LAST7DAYS = 18;
+const sal_Int32 OOBIN_CFRULE_SUB_LASTMONTH = 19;
+const sal_Int32 OOBIN_CFRULE_SUB_NEXTMONTH = 20;
+const sal_Int32 OOBIN_CFRULE_SUB_THISWEEK = 21;
+const sal_Int32 OOBIN_CFRULE_SUB_NEXTWEEK = 22;
+const sal_Int32 OOBIN_CFRULE_SUB_LASTWEEK = 23;
+const sal_Int32 OOBIN_CFRULE_SUB_THISMONTH = 24;
+const sal_Int32 OOBIN_CFRULE_SUB_ABOVEAVERAGE = 25;
+const sal_Int32 OOBIN_CFRULE_SUB_BELOWAVERAGE = 26;
+const sal_Int32 OOBIN_CFRULE_SUB_DUPLICATE = 27;
+const sal_Int32 OOBIN_CFRULE_SUB_EQABOVEAVERAGE = 29;
+const sal_Int32 OOBIN_CFRULE_SUB_EQBELOWAVERAGE = 30;
+
+const sal_Int32 OOBIN_CFRULE_TIMEOP_TODAY = 0;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_YESTERDAY = 1;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_LAST7DAYS = 2;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_THISWEEK = 3;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_LASTWEEK = 4;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_LASTMONTH = 5;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_TOMORROW = 6;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_NEXTWEEK = 7;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_NEXTMONTH = 8;
+const sal_Int32 OOBIN_CFRULE_TIMEOP_THISMONTH = 9;
+
+const sal_uInt16 OOBIN_CFRULE_STOPIFTRUE = 0x0002;
+const sal_uInt16 OOBIN_CFRULE_ABOVEAVERAGE = 0x0004;
+const sal_uInt16 OOBIN_CFRULE_BOTTOM = 0x0008;
+const sal_uInt16 OOBIN_CFRULE_PERCENT = 0x0010;
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void lclAppendProperty( ::std::vector< PropertyValue >& orProps, const OUString& rPropName, const Type& rValue )
+{
+ orProps.push_back( PropertyValue() );
+ orProps.back().Name = rPropName;
+ orProps.back().Value <<= rValue;
+}
+
+} // namespace
+
+// ============================================================================
+
+OoxCondFormatRuleData::OoxCondFormatRuleData() :
+ mnPriority( -1 ),
+ mnType( XML_TOKEN_INVALID ),
+ mnOperator( XML_TOKEN_INVALID ),
+ mnTimePeriod( XML_TOKEN_INVALID ),
+ mnRank( 0 ),
+ mnStdDev( 0 ),
+ mnDxfId( -1 ),
+ mbStopIfTrue( false ),
+ mbBottom( false ),
+ mbPercent( false ),
+ mbAboveAverage( true ),
+ mbEqualAverage( false )
+{
+}
+
+void OoxCondFormatRuleData::setBinOperator( sal_Int32 nOperator )
+{
+ static const sal_Int32 spnOperators[] = {
+ XML_TOKEN_INVALID, XML_between, XML_notBetween, XML_equal, XML_notEqual,
+ XML_greaterThan, XML_lessThan, XML_greaterThanOrEqual, XML_lessThanOrEqual };
+ mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
+}
+
+void OoxCondFormatRuleData::setOobTextType( sal_Int32 nOperator )
+{
+ // note: type XML_notContainsText vs. operator XML_notContains
+ static const sal_Int32 spnTypes[] = { XML_containsText, XML_notContainsText, XML_beginsWith, XML_endsWith };
+ mnType = STATIC_ARRAY_SELECT( spnTypes, nOperator, XML_TOKEN_INVALID );
+ static const sal_Int32 spnOperators[] = { XML_containsText, XML_notContains, XML_beginsWith, XML_endsWith };
+ mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
+}
+
+// ============================================================================
+
+CondFormatRule::CondFormatRule( const CondFormat& rCondFormat ) :
+ WorksheetHelper( rCondFormat ),
+ mrCondFormat( rCondFormat )
+{
+}
+
+void CondFormatRule::importCfRule( const AttributeList& rAttribs )
+{
+ maOoxData.maText = rAttribs.getString( XML_text );
+ maOoxData.mnPriority = rAttribs.getInteger( XML_priority, -1 );
+ maOoxData.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
+ maOoxData.mnOperator = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID );
+ maOoxData.mnTimePeriod = rAttribs.getToken( XML_timePeriod, XML_TOKEN_INVALID );
+ maOoxData.mnRank = rAttribs.getInteger( XML_rank, 0 );
+ maOoxData.mnStdDev = rAttribs.getInteger( XML_stdDev, 0 );
+ maOoxData.mnDxfId = rAttribs.getInteger( XML_dxfId, -1 );
+ maOoxData.mbStopIfTrue = rAttribs.getBool( XML_stopIfTrue, false );
+ maOoxData.mbBottom = rAttribs.getBool( XML_bottom, false );
+ maOoxData.mbPercent = rAttribs.getBool( XML_percent, false );
+ maOoxData.mbAboveAverage = rAttribs.getBool( XML_aboveAverage, true );
+ maOoxData.mbEqualAverage = rAttribs.getBool( XML_equalAverage, false );
+}
+
+void CondFormatRule::appendFormula( const OUString& rFormula )
+{
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( mrCondFormat.getRanges().getBaseAddress() );
+ getFormulaParser().importFormula( aContext, rFormula );
+ maOoxData.maFormulas.push_back( aContext );
+}
+
+void CondFormatRule::importCfRule( RecordInputStream& rStrm )
+{
+ sal_Int32 nType, nSubType, nOperator, nFmla1Size, nFmla2Size, nFmla3Size;
+ sal_uInt16 nFlags;
+ rStrm >> nType >> nSubType >> maOoxData.mnDxfId >> maOoxData.mnPriority >> nOperator;
+ rStrm.skip( 8 );
+ rStrm >> nFlags >> nFmla1Size >> nFmla2Size >> nFmla3Size >> maOoxData.maText;
+
+ /* Import the formulas. For no obvious reason, the sizes of the formulas
+ are already stored before. Nevertheless the following formulas contain
+ their own sizes. */
+
+ // first formula
+ OSL_ENSURE( (nFmla1Size >= 0) || ((nFmla2Size == 0) && (nFmla3Size == 0)), "CondFormatRule::importCfRule - missing first formula" );
+ OSL_ENSURE( (nFmla1Size > 0) == (rStrm.getRecLeft() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
+ if( rStrm.getRecLeft() >= 8 )
+ {
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( mrCondFormat.getRanges().getBaseAddress() );
+ getFormulaParser().importFormula( aContext, rStrm );
+ maOoxData.maFormulas.push_back( aContext );
+
+ // second formula
+ OSL_ENSURE( (nFmla2Size >= 0) || (nFmla3Size == 0), "CondFormatRule::importCfRule - missing second formula" );
+ OSL_ENSURE( (nFmla2Size > 0) == (rStrm.getRecLeft() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
+ if( rStrm.getRecLeft() >= 8 )
+ {
+ getFormulaParser().importFormula( aContext, rStrm );
+ maOoxData.maFormulas.push_back( aContext );
+
+ // third formula
+ OSL_ENSURE( (nFmla3Size > 0) == (rStrm.getRecLeft() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
+ if( rStrm.getRecLeft() >= 8 )
+ {
+ getFormulaParser().importFormula( aContext, rStrm );
+ maOoxData.maFormulas.push_back( aContext );
+ }
+ }
+ }
+
+ // flags
+ maOoxData.mbStopIfTrue = getFlag( nFlags, OOBIN_CFRULE_STOPIFTRUE );
+ maOoxData.mbBottom = getFlag( nFlags, OOBIN_CFRULE_BOTTOM );
+ maOoxData.mbPercent = getFlag( nFlags, OOBIN_CFRULE_PERCENT );
+ maOoxData.mbAboveAverage = getFlag( nFlags, OOBIN_CFRULE_ABOVEAVERAGE );
+ // no flag for equalAverage, must be determined from subtype below...
+
+ // Convert the type/operator settings. This is a real mess...
+ switch( nType )
+ {
+ case OOBIN_CFRULE_TYPE_CELLIS:
+ OSL_ENSURE( nSubType == OOBIN_CFRULE_SUB_CELLIS, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ maOoxData.mnType = XML_cellIs;
+ maOoxData.setBinOperator( nOperator );
+ OSL_ENSURE( maOoxData.mnOperator != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unknown operator" );
+ break;
+ case OOBIN_CFRULE_TYPE_EXPRESSION:
+ // here we have to look at the subtype to find the real type...
+ switch( nSubType )
+ {
+ case OOBIN_CFRULE_SUB_EXPRESSION:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_expression;
+ break;
+ case OOBIN_CFRULE_SUB_UNIQUE:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_uniqueValues;
+ break;
+ case OOBIN_CFRULE_SUB_TEXT:
+ maOoxData.setOobTextType( nOperator );
+ OSL_ENSURE( maOoxData.mnType != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unexpected operator value" );
+ break;
+ case OOBIN_CFRULE_SUB_BLANK:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_containsBlanks;
+ break;
+ case OOBIN_CFRULE_SUB_NOTBLANK:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_notContainsBlanks;
+ break;
+ case OOBIN_CFRULE_SUB_ERROR:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_containsErrors;
+ break;
+ case OOBIN_CFRULE_SUB_NOTERROR:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_notContainsErrors;
+ break;
+ case OOBIN_CFRULE_SUB_TODAY:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_TODAY, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_today;
+ break;
+ case OOBIN_CFRULE_SUB_TOMORROW:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_TOMORROW, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_tomorrow;
+ break;
+ case OOBIN_CFRULE_SUB_YESTERDAY:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_YESTERDAY, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_yesterday;
+ break;
+ case OOBIN_CFRULE_SUB_LAST7DAYS:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_LAST7DAYS, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_last7Days;
+ break;
+ case OOBIN_CFRULE_SUB_LASTMONTH:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_LASTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_lastMonth;
+ break;
+ case OOBIN_CFRULE_SUB_NEXTMONTH:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_NEXTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_nextMonth;
+ break;
+ case OOBIN_CFRULE_SUB_THISWEEK:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_THISWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_thisWeek;
+ break;
+ case OOBIN_CFRULE_SUB_NEXTWEEK:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_NEXTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_nextWeek;
+ break;
+ case OOBIN_CFRULE_SUB_LASTWEEK:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_LASTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_lastWeek;
+ break;
+ case OOBIN_CFRULE_SUB_THISMONTH:
+ OSL_ENSURE( nOperator == OOBIN_CFRULE_TIMEOP_THISMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maOoxData.mnType = XML_timePeriod;
+ maOoxData.mnTimePeriod = XML_thisMonth;
+ break;
+ case OOBIN_CFRULE_SUB_ABOVEAVERAGE:
+ OSL_ENSURE( maOoxData.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maOoxData.mnType = XML_aboveAverage;
+ maOoxData.mnStdDev = nOperator; // operator field used for standard deviation
+ maOoxData.mbAboveAverage = true;
+ maOoxData.mbEqualAverage = false; // does not exist as real flag...
+ break;
+ case OOBIN_CFRULE_SUB_BELOWAVERAGE:
+ OSL_ENSURE( !maOoxData.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maOoxData.mnType = XML_aboveAverage;
+ maOoxData.mnStdDev = nOperator; // operator field used for standard deviation
+ maOoxData.mbAboveAverage = false;
+ maOoxData.mbEqualAverage = false; // does not exist as real flag...
+ break;
+ case OOBIN_CFRULE_SUB_DUPLICATE:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_duplicateValues;
+ break;
+ case OOBIN_CFRULE_SUB_EQABOVEAVERAGE:
+ OSL_ENSURE( maOoxData.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maOoxData.mnType = XML_aboveAverage;
+ maOoxData.mnStdDev = nOperator; // operator field used for standard deviation
+ maOoxData.mbAboveAverage = true;
+ maOoxData.mbEqualAverage = true; // does not exist as real flag...
+ break;
+ case OOBIN_CFRULE_SUB_EQBELOWAVERAGE:
+ OSL_ENSURE( !maOoxData.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maOoxData.mnType = XML_aboveAverage;
+ maOoxData.mnStdDev = nOperator; // operator field used for standard deviation
+ maOoxData.mbAboveAverage = false;
+ maOoxData.mbEqualAverage = true; // does not exist as real flag...
+ break;
+ }
+ break;
+ case OOBIN_CFRULE_TYPE_COLORSCALE:
+ OSL_ENSURE( nSubType == OOBIN_CFRULE_SUB_COLORSCALE, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_colorScale;
+ break;
+ case OOBIN_CFRULE_TYPE_DATABAR:
+ OSL_ENSURE( nSubType == OOBIN_CFRULE_SUB_DATABAR, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_dataBar;
+ break;
+ case OOBIN_CFRULE_TYPE_TOPTEN:
+ OSL_ENSURE( nSubType == OOBIN_CFRULE_SUB_TOPTEN, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ maOoxData.mnType = XML_top10;
+ maOoxData.mnRank = nOperator; // operator field used for rank value
+ break;
+ case OOBIN_CFRULE_TYPE_ICONSET:
+ OSL_ENSURE( nSubType == OOBIN_CFRULE_SUB_ICONSET, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maOoxData.mnType = XML_iconSet;
+ break;
+ default:
+ OSL_ENSURE( false, "CondFormatRule::importCfRule - unknown rule type" );
+ }
+}
+
+void CondFormatRule::importCfRule( BiffInputStream& rStrm, sal_Int32 nPriority )
+{
+ sal_uInt8 nType, nOperator;
+ sal_uInt16 nFmla1Size, nFmla2Size;
+ sal_uInt32 nFlags;
+ rStrm >> nType >> nOperator >> nFmla1Size >> nFmla2Size >> nFlags;
+ rStrm.skip( 2 );
+
+ static const sal_Int32 spnTypeIds[] = { XML_TOKEN_INVALID, XML_cellIs, XML_expression };
+ maOoxData.mnType = STATIC_ARRAY_SELECT( spnTypeIds, nType, XML_TOKEN_INVALID );
+
+ maOoxData.setBinOperator( nOperator );
+ maOoxData.mnPriority = nPriority;
+ maOoxData.mbStopIfTrue = true;
+
+ DxfRef xDxf = getStyles().createDxf( &maOoxData.mnDxfId );
+ xDxf->importCfRule( rStrm, nFlags );
+ xDxf->finalizeImport();
+
+ // import the formulas
+ OSL_ENSURE( (nFmla1Size > 0) || (nFmla2Size == 0), "CondFormatRule::importCfRule - missing first formula" );
+ if( nFmla1Size > 0 )
+ {
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( mrCondFormat.getRanges().getBaseAddress() );
+ getFormulaParser().importFormula( aContext, rStrm, &nFmla1Size );
+ maOoxData.maFormulas.push_back( aContext );
+ if( nFmla2Size > 0 )
+ {
+ getFormulaParser().importFormula( aContext, rStrm, &nFmla2Size );
+ maOoxData.maFormulas.push_back( aContext );
+ }
+ }
+}
+
+void CondFormatRule::finalizeImport( const Reference< XSheetConditionalEntries >& rxEntries )
+{
+ ConditionOperator eOperator = ::com::sun::star::sheet::ConditionOperator_NONE;
+
+ /* Replacement formula for unsupported rule types (text comparison rules,
+ time period rules, cell type rules). The replacement formulas below may
+ contain several placeholders:
+ - '#B' will be replaced by the current base address (may occur
+ several times).
+ - '#R' will be replaced by the entire range list of the conditional
+ formatting (absolute addresses).
+ - '#T' will be replaced by the quoted comparison text.
+ - '#L' will be replaced by the length of the comparison text (from
+ the 'text' attribute) used in text comparison rules.
+ - '#K' will be replaced by the rank (from the 'rank' attribute) used in
+ top-10 rules.
+ - '#M' will be replaced by the top/bottom flag (from the 'bottom'
+ attribute) used in the RANK function in top-10 rules.
+ */
+ OUString aReplaceFormula;
+
+ switch( maOoxData.mnType )
+ {
+ case XML_cellIs:
+ eOperator = ValidationPropertyHelper::convertToApiOperator( maOoxData.mnOperator );
+ break;
+ case XML_expression:
+ eOperator = ::com::sun::star::sheet::ConditionOperator_FORMULA;
+ break;
+ case XML_containsText:
+ OSL_ENSURE( maOoxData.mnOperator == XML_containsText, "CondFormatRule::finalizeImport - unexpected operator" );
+ aReplaceFormula = CREATE_OUSTRING( "NOT(ISERROR(SEARCH(#T,#B)))" );
+ break;
+ case XML_notContainsText:
+ // note: type XML_notContainsText vs. operator XML_notContains
+ OSL_ENSURE( maOoxData.mnOperator == XML_notContains, "CondFormatRule::finalizeImport - unexpected operator" );
+ aReplaceFormula = CREATE_OUSTRING( "ISERROR(SEARCH(#T,#B))" );
+ break;
+ case XML_beginsWith:
+ OSL_ENSURE( maOoxData.mnOperator == XML_beginsWith, "CondFormatRule::finalizeImport - unexpected operator" );
+ aReplaceFormula = CREATE_OUSTRING( "LEFT(#B,#L)=#T" );
+ break;
+ case XML_endsWith:
+ OSL_ENSURE( maOoxData.mnOperator == XML_endsWith, "CondFormatRule::finalizeImport - unexpected operator" );
+ aReplaceFormula = CREATE_OUSTRING( "RIGHT(#B,#L)=#T" );
+ break;
+ case XML_timePeriod:
+ switch( maOoxData.mnTimePeriod )
+ {
+ case XML_yesterday:
+ aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()-1" );
+ break;
+ case XML_today:
+ aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()" );
+ break;
+ case XML_tomorrow:
+ aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()+1" );
+ break;
+ case XML_last7Days:
+ aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY())" );
+ break;
+ case XML_lastWeek:
+ aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())-7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY()))" );
+ break;
+ case XML_thisWeek:
+ aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY())+7)" );
+ break;
+ case XML_nextWeek:
+ aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())+7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY())+14)" );
+ break;
+ case XML_lastMonth:
+ aReplaceFormula = CREATE_OUSTRING( "OR(AND(MONTH(#B)=MONTH(TODAY())-1,YEAR(#B)=YEAR(TODAY())),AND(MONTH(#B)=12,MONTH(TODAY())=1,YEAR(#B)=YEAR(TODAY())-1))" );
+ break;
+ case XML_thisMonth:
+ aReplaceFormula = CREATE_OUSTRING( "AND(MONTH(#B)=MONTH(TODAY()),YEAR(#B)=YEAR(TODAY()))" );
+ break;
+ case XML_nextMonth:
+ aReplaceFormula = CREATE_OUSTRING( "OR(AND(MONTH(#B)=MONTH(TODAY())+1,YEAR(#B)=YEAR(TODAY())),AND(MONTH(#B)=1,MONTH(TODAY())=12,YEAR(#B)=YEAR(TODAY())+1))" );
+ break;
+ default:
+ OSL_ENSURE( false, "CondFormatRule::finalizeImport - unknown time period type" );
+ }
+ break;
+ case XML_containsBlanks:
+ aReplaceFormula = CREATE_OUSTRING( "LEN(TRIM(#B))=0" );
+ break;
+ case XML_notContainsBlanks:
+ aReplaceFormula = CREATE_OUSTRING( "LEN(TRIM(#B))>0" );
+ break;
+ case XML_containsErrors:
+ aReplaceFormula = CREATE_OUSTRING( "ISERROR(#B)" );
+ break;
+ case XML_notContainsErrors:
+ aReplaceFormula = CREATE_OUSTRING( "NOT(ISERROR(#B))" );
+ break;
+ case XML_top10:
+ if( maOoxData.mbPercent )
+ aReplaceFormula = CREATE_OUSTRING( "RANK(#B,#R,#M)/COUNT(#R)<=#K%" );
+ else
+ aReplaceFormula = CREATE_OUSTRING( "RANK(#B,#R,#M)<=#K" );
+ break;
+ case XML_aboveAverage:
+ if( maOoxData.mnStdDev == 0 )
+ {
+ if( maOoxData.mbAboveAverage )
+ aReplaceFormula = maOoxData.mbEqualAverage ? CREATE_OUSTRING( "#B>=AVERAGE(#R)" ) : CREATE_OUSTRING( "#B>AVERAGE(#R)" );
+ else
+ aReplaceFormula = maOoxData.mbEqualAverage ? CREATE_OUSTRING( "#B<=AVERAGE(#R)" ) : CREATE_OUSTRING( "#B<AVERAGE(#R)" );
+ }
+ break;
+ }
+
+ if( aReplaceFormula.getLength() > 0 )
+ {
+ OUString aAddress, aRanges, aText;
+ sal_Int32 nStrPos = aReplaceFormula.getLength();
+ while( (nStrPos = aReplaceFormula.lastIndexOf( '#', nStrPos )) >= 0 )
+ {
+ switch( aReplaceFormula[ nStrPos + 1 ] )
+ {
+ case 'B': // current base address
+ if( aAddress.getLength() == 0 )
+ aAddress = FormulaProcessorBase::generateAddress2dString( mrCondFormat.getRanges().getBaseAddress(), false );
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aAddress );
+ break;
+ case 'R': // range list of conditional formatting
+ if( aRanges.getLength() == 0 )
+ aRanges = FormulaProcessorBase::generateRangeList2dString( mrCondFormat.getRanges(), true, ',', true );
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aRanges );
+ break;
+ case 'T': // comparison text
+ if( aText.getLength() == 0 )
+ {
+ // handle quote characters in comparison text
+ aText = maOoxData.maText;
+ sal_Int32 nQuotePos = aText.getLength();
+ while( (nQuotePos = aText.lastIndexOf( '"', nQuotePos )) >= 0 )
+ aText = aText.replaceAt( nQuotePos, 1, CREATE_OUSTRING( "\"\"" ) );
+ aText = OUStringBuffer().append( sal_Unicode( '"' ) ).append( aText ).append( sal_Unicode( '"' ) ).makeStringAndClear();
+ }
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aText );
+ break;
+ case 'L': // length of comparison text
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
+ OUString::valueOf( maOoxData.maText.getLength() ) );
+ break;
+ case 'K': // top-10 rank
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
+ OUString::valueOf( maOoxData.mnRank ) );
+ break;
+ case 'M': // top-10 top/bottom flag
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
+ OUString::valueOf( static_cast< sal_Int32 >( maOoxData.mbBottom ? 1 : 0 ) ) );
+ break;
+ default:
+ OSL_ENSURE( false, "CondFormatRule::finalizeImport - unknown placeholder" );
+ }
+ }
+
+ // set the replacement formula
+ maOoxData.maFormulas.clear();
+ appendFormula( aReplaceFormula );
+ eOperator = ::com::sun::star::sheet::ConditionOperator_FORMULA;
+ }
+
+ if( rxEntries.is() && (eOperator != ::com::sun::star::sheet::ConditionOperator_NONE) && !maOoxData.maFormulas.empty() )
+ {
+ ::std::vector< PropertyValue > aProps;
+ // create condition properties
+ lclAppendProperty( aProps, CREATE_OUSTRING( "Operator" ), eOperator );
+ lclAppendProperty( aProps, CREATE_OUSTRING( "Formula1" ), maOoxData.maFormulas[ 0 ].getTokens() );
+ if( maOoxData.maFormulas.size() >= 2 )
+ lclAppendProperty( aProps, CREATE_OUSTRING( "Formula2" ), maOoxData.maFormulas[ 1 ].getTokens() );
+
+ // style name for the formatting attributes
+ OUString aStyleName = getStyles().createDxfStyle( maOoxData.mnDxfId );
+ if( aStyleName.getLength() > 0 )
+ lclAppendProperty( aProps, CREATE_OUSTRING( "StyleName" ), aStyleName );
+
+ // append the new rule
+ try
+ {
+ rxEntries->addNew( ContainerHelper::vectorToSequence( aProps ) );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+// ============================================================================
+
+OoxCondFormatData::OoxCondFormatData() :
+ mbPivot( false )
+{
+}
+
+// ============================================================================
+
+CondFormat::CondFormat( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void CondFormat::importConditionalFormatting( const AttributeList& rAttribs )
+{
+ getAddressConverter().convertToCellRangeList( maOoxData.maRanges, rAttribs.getString( XML_sqref ), getSheetIndex(), true );
+ maOoxData.mbPivot = rAttribs.getBool( XML_pivot, false );
+}
+
+CondFormatRuleRef CondFormat::importCfRule( const AttributeList& rAttribs )
+{
+ CondFormatRuleRef xRule = createRule();
+ xRule->importCfRule( rAttribs );
+ insertRule( xRule );
+ return xRule;
+}
+
+void CondFormat::importCondFormatting( RecordInputStream& rStrm )
+{
+ BinRangeList aRanges;
+ rStrm.skip( 8 );
+ rStrm >> aRanges;
+ getAddressConverter().convertToCellRangeList( maOoxData.maRanges, aRanges, getSheetIndex(), true );
+}
+
+void CondFormat::importCfRule( RecordInputStream& rStrm )
+{
+ CondFormatRuleRef xRule = createRule();
+ xRule->importCfRule( rStrm );
+ insertRule( xRule );
+}
+
+void CondFormat::importCfHeader( BiffInputStream& rStrm )
+{
+ // import the CFHEADER record
+ sal_uInt16 nRuleCount;
+ BinRangeList aRanges;
+ rStrm >> nRuleCount;
+ rStrm.skip( 10 );
+ rStrm >> aRanges;
+ getAddressConverter().convertToCellRangeList( maOoxData.maRanges, aRanges, getSheetIndex(), true );
+
+ // import following list of CFRULE records
+ for( sal_uInt16 nRule = 0; (nRule < nRuleCount) && (rStrm.getNextRecId() == BIFF_ID_CFRULE) && rStrm.startNextRecord(); ++nRule )
+ {
+ CondFormatRuleRef xRule = createRule();
+ xRule->importCfRule( rStrm, nRule + 1 );
+ insertRule( xRule );
+ }
+}
+
+void CondFormat::finalizeImport()
+{
+ Reference< XSheetCellRanges > xRanges = getCellRangeList( maOoxData.maRanges );
+ if( xRanges.is() )
+ {
+ PropertySet aPropSet( xRanges );
+ Reference< XSheetConditionalEntries > xEntries;
+ aPropSet.getProperty( xEntries, CREATE_OUSTRING( "ConditionalFormat" ) );
+ if( xEntries.is() )
+ {
+ // maRules is sorted by rule priority
+ maRules.forEachMem( &CondFormatRule::finalizeImport, xEntries );
+ aPropSet.setProperty( CREATE_OUSTRING( "ConditionalFormat" ), xEntries );
+ }
+ }
+}
+
+CondFormatRuleRef CondFormat::createRule()
+{
+ return CondFormatRuleRef( new CondFormatRule( *this ) );
+}
+
+void CondFormat::insertRule( CondFormatRuleRef xRule )
+{
+ if( xRule.get() && (xRule->getPriority() > 0) )
+ {
+ OSL_ENSURE( maRules.find( xRule->getPriority() ) == maRules.end(), "CondFormat::insertRule - multiple rules with equal priority" );
+ maRules[ xRule->getPriority() ] = xRule;
+ }
+}
+
+// ============================================================================
+
+CondFormatBuffer::CondFormatBuffer( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+CondFormatRef CondFormatBuffer::importConditionalFormatting( const AttributeList& rAttribs )
+{
+ CondFormatRef xCondFmt = createCondFormat();
+ xCondFmt->importConditionalFormatting( rAttribs );
+ return xCondFmt;
+}
+
+CondFormatRef CondFormatBuffer::importCondFormatting( RecordInputStream& rStrm )
+{
+ CondFormatRef xCondFmt = createCondFormat();
+ xCondFmt->importCondFormatting( rStrm );
+ return xCondFmt;
+}
+
+void CondFormatBuffer::importCfHeader( BiffInputStream& rStrm )
+{
+ createCondFormat()->importCfHeader( rStrm );
+}
+
+void CondFormatBuffer::finalizeImport()
+{
+ maCondFormats.forEachMem( &CondFormat::finalizeImport );
+}
+
+// private --------------------------------------------------------------------
+
+CondFormatRef CondFormatBuffer::createCondFormat()
+{
+ CondFormatRef xCondFmt( new CondFormat( *this ) );
+ maCondFormats.push_back( xCondFmt );
+ return xCondFmt;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/condformatcontext.cxx b/oox/source/xls/condformatcontext.cxx
new file mode 100644
index 000000000000..d387bc959cca
--- /dev/null
+++ b/oox/source/xls/condformatcontext.cxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: condformatcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/condformatcontext.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+OoxCondFormatContext::OoxCondFormatContext( const OoxWorksheetFragmentBase& rFragment ) :
+ OoxWorksheetContextBase( rFragment )
+{
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxCondFormatContext::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( conditionalFormatting ):
+ return (nElement == XLS_TOKEN( cfRule ));
+ case XLS_TOKEN( cfRule ):
+ return (nElement == XLS_TOKEN( formula ));
+ }
+ return false;
+}
+
+void OoxCondFormatContext::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( conditionalFormatting ):
+ mxCondFmt = getCondFormats().importConditionalFormatting( rAttribs );
+ break;
+ case XLS_TOKEN( cfRule ):
+ if( mxCondFmt.get() ) mxRule = mxCondFmt->importCfRule( rAttribs );
+ break;
+ }
+}
+
+void OoxCondFormatContext::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( formula ):
+ if( mxCondFmt.get() && mxRule.get() ) mxRule->appendFormula( rChars );
+ break;
+ }
+}
+
+bool OoxCondFormatContext::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_CONDFORMATTING:
+ return (nRecId == OOBIN_ID_CFRULE);
+ }
+ return false;
+}
+
+void OoxCondFormatContext::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_CONDFORMATTING:
+ mxCondFmt = getCondFormats().importCondFormatting( rStrm );
+ break;
+ case OOBIN_ID_CFRULE:
+ if( mxCondFmt.get() ) mxCondFmt->importCfRule( rStrm );
+ break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/connectionsfragment.cxx b/oox/source/xls/connectionsfragment.cxx
new file mode 100644
index 000000000000..125e79cccc45
--- /dev/null
+++ b/oox/source/xls/connectionsfragment.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: connectionsfragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/connectionsfragment.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/webquerybuffer.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::xml::sax::SAXException;
+
+namespace oox {
+namespace xls {
+
+OoxConnectionsFragment::OoxConnectionsFragment( const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+bool OoxConnectionsFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT: return (nElement == XLS_TOKEN( connections ));
+ case XLS_TOKEN( connections ): return (nElement == XLS_TOKEN( connection ));
+ case XLS_TOKEN( connection ): return (nElement == XLS_TOKEN( webPr )) ||
+ (nElement == XLS_TOKEN( textPr )) ||
+ (nElement == XLS_TOKEN( dbPr )) ||
+ (nElement == XLS_TOKEN( olapPr )) ||
+ (nElement == XLS_TOKEN( parameters ));
+ case XLS_TOKEN( webPr ): return (nElement == XLS_TOKEN( tables ));
+ case XLS_TOKEN( tables ): return (nElement == XLS_TOKEN( m )) ||
+ (nElement == XLS_TOKEN( s )) ||
+ (nElement == XLS_TOKEN( x ));
+ }
+ return false;
+}
+
+void OoxConnectionsFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch ( getCurrentContext() )
+ {
+ case XLS_TOKEN( connection ):
+ importConnection( rAttribs );
+ break;
+ case XLS_TOKEN( webPr ):
+ importWebPr( rAttribs );
+ break;
+ case XLS_TOKEN( tables ):
+ importTables( rAttribs );
+ break;
+ case XLS_TOKEN( s ):
+ importS( rAttribs );
+ break;
+ case XLS_TOKEN( x ):
+ importX( rAttribs );
+ break;
+ }
+}
+
+void OoxConnectionsFragment::importConnection( const AttributeList& rAttribs )
+{
+ if ( rAttribs.getInteger( XML_type, 0 ) == Connection::CONNECTION_WEBQUERY )
+ {
+ getWebQueries().importConnection( rAttribs );
+ }
+}
+
+void OoxConnectionsFragment::importWebPr( const AttributeList& rAttribs )
+{
+ getWebQueries().importWebPr( rAttribs );
+}
+
+void OoxConnectionsFragment::importTables( const AttributeList& /*rAttribs*/ )
+{
+// sal_Int32 nCount = rAttribs.getInteger( XML_count, 0 );
+}
+
+void OoxConnectionsFragment::importS( const AttributeList& /*rAttribs*/ )
+{
+// OUString aName = rAttribs.getString( XML_v );
+}
+
+void OoxConnectionsFragment::importX( const AttributeList& /*rAttribs*/ )
+{
+// sal_Int32 nSharedId = rAttribs.getInteger( XML_v, 0 );
+}
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/defnamesbuffer.cxx b/oox/source/xls/defnamesbuffer.cxx
new file mode 100644
index 000000000000..6fc1623dea0e
--- /dev/null
+++ b/oox/source/xls/defnamesbuffer.cxx
@@ -0,0 +1,674 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: defnamesbuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/defnamesbuffer.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/SingleReference.hpp>
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/ooxtokens.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::SingleReference;
+using ::com::sun::star::sheet::ComplexReference;
+using ::com::sun::star::sheet::XNamedRanges;
+using ::com::sun::star::sheet::XNamedRange;
+using ::com::sun::star::sheet::XFormulaTokens;
+using ::com::sun::star::sheet::XPrintAreas;
+using namespace ::com::sun::star::sheet::ReferenceFlags;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 BIFF_DEFNAME_HIDDEN = 0x0001;
+const sal_uInt16 BIFF_DEFNAME_FUNC = 0x0002;
+const sal_uInt16 BIFF_DEFNAME_VBNAME = 0x0004;
+const sal_uInt16 BIFF_DEFNAME_MACRO = 0x0008;
+const sal_uInt16 BIFF_DEFNAME_CALCEXP = 0x0010;
+const sal_uInt16 BIFF_DEFNAME_BUILTIN = 0x0020;
+const sal_uInt16 BIFF_DEFNAME_FGROUPMASK = 0x0FC0;
+const sal_uInt16 BIFF_DEFNAME_BIG = 0x1000;
+
+const sal_uInt8 BIFF2_DEFNAME_FUNC = 0x02; /// BIFF2 function/command flag.
+
+const sal_uInt16 BIFF_DEFNAME_GLOBAL = 0; /// 0 = Globally defined name.
+
+} // namespace
+
+// ============================================================================
+
+OoxDefinedNameData::OoxDefinedNameData() :
+ mnSheet( -1 ),
+ mbMacro( false ),
+ mbFunction( false ),
+ mbVBName( false ),
+ mbHidden( false )
+{
+}
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 BIFF_REFFLAG_COL1REL = 0x0001;
+const sal_uInt16 BIFF_REFFLAG_ROW1REL = 0x0002;
+const sal_uInt16 BIFF_REFFLAG_COL2REL = 0x0004;
+const sal_uInt16 BIFF_REFFLAG_ROW2REL = 0x0008;
+
+void lclConvertRefFlags( sal_Int32& ornFlags, sal_Int32& ornAbsPos, sal_Int32& ornRelPos, sal_Int32 nBasePos, sal_Int32 nApiRelFlag, bool bRel )
+{
+ if( getFlag( ornFlags, nApiRelFlag ) && !bRel )
+ {
+ // convert relative to absolute
+ setFlag( ornFlags, nApiRelFlag, false );
+ ornAbsPos = nBasePos + ornRelPos;
+ }
+ else if( !getFlag( ornFlags, nApiRelFlag ) && bRel )
+ {
+ // convert absolute to relative
+ setFlag( ornFlags, nApiRelFlag, true );
+ ornRelPos = ornAbsPos - nBasePos;
+ }
+}
+
+void lclConvertSingleRefFlags( SingleReference& orApiRef, const CellAddress& rBaseAddress, bool bColRel, bool bRowRel )
+{
+ lclConvertRefFlags(
+ orApiRef.Flags, orApiRef.Column, orApiRef.RelativeColumn,
+ rBaseAddress.Column, COLUMN_RELATIVE, bColRel );
+ lclConvertRefFlags(
+ orApiRef.Flags, orApiRef.Row, orApiRef.RelativeRow,
+ rBaseAddress.Row, ROW_RELATIVE, bRowRel );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+DefinedNameBase::DefinedNameBase( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ) :
+ WorkbookHelper( rHelper )
+{
+ maOoxData.mnSheet = nLocalSheet;
+}
+
+Any DefinedNameBase::getReference( const CellAddress& rBaseAddress ) const
+{
+ if( maRefAny.hasValue() && (maOoxData.maName.getLength() >= 2) && (maOoxData.maName[ 0 ] == '\x01') )
+ {
+ sal_Unicode cFlagsChar = maOoxData.maName.toAsciiUpperCase()[ 1 ];
+ if( ('A' <= cFlagsChar) && (cFlagsChar <= 'P') )
+ {
+ sal_uInt16 nFlags = static_cast< sal_uInt16 >( cFlagsChar - 'A' );
+ if( maRefAny.has< SingleReference >() && (cFlagsChar <= 'D') )
+ {
+ SingleReference aApiRef;
+ maRefAny >>= aApiRef;
+ lclConvertSingleRefFlags( aApiRef, rBaseAddress, getFlag( nFlags, BIFF_REFFLAG_COL1REL ), getFlag( nFlags, BIFF_REFFLAG_ROW1REL ) );
+ return Any( aApiRef );
+ }
+ if( maRefAny.has< ComplexReference >() )
+ {
+ 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 Any();
+}
+
+void DefinedNameBase::importOoxFormula( FormulaContext& rContext )
+{
+ if( maOoxData.maFormula.getLength() > 0 )
+ {
+ rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maOoxData.mnSheet ), 0, 0 ) );
+ getFormulaParser().importFormula( rContext, maOoxData.maFormula );
+ }
+ else
+ getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME );
+}
+
+void DefinedNameBase::importOobFormula( FormulaContext& rContext, RecordInputStream& rStrm )
+{
+ rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maOoxData.mnSheet ), 0, 0 ) );
+ getFormulaParser().importFormula( rContext, rStrm );
+}
+
+void DefinedNameBase::importBiffFormula( FormulaContext& rContext, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize )
+{
+ rContext.setBaseAddress( CellAddress( static_cast< sal_Int16 >( maOoxData.mnSheet ), 0, 0 ) );
+ if( !pnFmlaSize || (*pnFmlaSize > 0) )
+ getFormulaParser().importFormula( rContext, rStrm, pnFmlaSize );
+ else
+ getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME );
+}
+
+void DefinedNameBase::setReference( const ApiTokenSequence& rTokens )
+{
+ maRefAny = getFormulaParser().extractReference( rTokens );
+}
+
+// ============================================================================
+
+namespace {
+
+const sal_Char* const spcLegacyPrefix = "Excel_BuiltIn_";
+const sal_Char* const spcOoxPrefix = "_xlnm.";
+
+const sal_Char* const sppcBaseNames[] =
+{
+ "Consolidate_Area", /* OOX */
+ "Auto_Open",
+ "Auto_Close",
+ "Extract", /* OOX */
+ "Database", /* OOX */
+ "Criteria", /* OOX */
+ "Print_Area", /* OOX */
+ "Print_Titles", /* OOX */
+ "Recorder",
+ "Data_Form",
+ "Auto_Activate",
+ "Auto_Deactivate",
+ "Sheet_Title", /* OOX */
+ "_FilterDatabase" /* OOX */
+};
+
+/** Localized names for _xlnm._FilterDatabase as used in BIFF5. */
+const sal_Char* const sppcFilterDbNames[] =
+{
+ "_FilterDatabase", // English
+ "_FilterDatenbank" // German
+};
+
+OUString lclGetBaseName( sal_Unicode cBuiltinId )
+{
+ OSL_ENSURE( cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ), "lclGetBaseName - unknown builtin name" );
+ OUStringBuffer aBuffer;
+ if( cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ) )
+ aBuffer.appendAscii( sppcBaseNames[ cBuiltinId ] );
+ else
+ aBuffer.append( static_cast< sal_Int32 >( cBuiltinId ) );
+ return aBuffer.makeStringAndClear();
+}
+
+OUString lclGetFinalName( sal_Unicode cBuiltinId )
+{
+ return OUStringBuffer().appendAscii( spcOoxPrefix ).append( lclGetBaseName( cBuiltinId ) ).makeStringAndClear();
+}
+
+sal_Unicode lclGetBuiltinIdFromOox( const OUString& rOoxName )
+{
+ OUString aPrefix = OUString::createFromAscii( spcOoxPrefix );
+ sal_Int32 nPrefixLen = aPrefix.getLength();
+ if( rOoxName.matchIgnoreAsciiCase( aPrefix ) )
+ {
+ for( sal_Unicode cBuiltinId = 0; cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ); ++cBuiltinId )
+ {
+ OUString aBaseName = lclGetBaseName( cBuiltinId );
+ sal_Int32 nBaseNameLen = aBaseName.getLength();
+ if( (rOoxName.getLength() == nPrefixLen + nBaseNameLen) && rOoxName.matchIgnoreAsciiCase( aBaseName, nPrefixLen ) )
+ return cBuiltinId;
+ }
+ }
+ return OOX_DEFNAME_UNKNOWN;
+}
+
+sal_Unicode lclGetBuiltinIdFromOob( const OUString& rOobName )
+{
+ for( sal_Unicode cBuiltinId = 0; cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ); ++cBuiltinId )
+ if( rOobName.equalsIgnoreAsciiCaseAscii( sppcBaseNames[ cBuiltinId ] ) )
+ return cBuiltinId;
+ return OOX_DEFNAME_UNKNOWN;
+}
+
+bool lclIsFilterDatabaseName( const OUString& rName )
+{
+ for( const sal_Char* const* ppcName = sppcFilterDbNames; ppcName < STATIC_ARRAY_END( sppcFilterDbNames ); ++ppcName )
+ if( rName.equalsIgnoreAsciiCaseAscii( *ppcName ) )
+ return true;
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+DefinedName::DefinedName( const WorkbookHelper& rHelper, sal_Int32 nLocalSheet ) :
+ DefinedNameBase( rHelper, nLocalSheet ),
+ mnTokenIndex( -1 ),
+ mcBuiltinId( OOX_DEFNAME_UNKNOWN ),
+ mpStrm( 0 ),
+ mnRecHandle( -1 ),
+ mnRecPos( 0 ),
+ mnFmlaSize( 0 )
+{
+}
+
+void DefinedName::importDefinedName( const AttributeList& rAttribs )
+{
+ maOoxData.maName = rAttribs.getString( XML_name );
+ maOoxData.mnSheet = rAttribs.getInteger( XML_localSheetId, -1 );
+ maOoxData.mbMacro = rAttribs.getBool( XML_xlm, false );
+ maOoxData.mbFunction = rAttribs.getBool( XML_function, false );
+ maOoxData.mbVBName = rAttribs.getBool( XML_vbProcedure, false );
+ maOoxData.mbHidden = rAttribs.getBool( XML_hidden, false );
+ mcBuiltinId = lclGetBuiltinIdFromOox( maOoxData.maName );
+}
+
+void DefinedName::setFormula( const OUString& rFormula )
+{
+ maOoxData.maFormula = rFormula;
+}
+
+void DefinedName::importDefinedName( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ rStrm.skip( 3 ); // 2 bytes unknown, 1 byte keyboard shortcut
+ rStrm >> maOoxData.mnSheet >> maOoxData.maName;
+
+ // macro function/command, hidden flag, equal flags in BIFF and OOBIN
+ maOoxData.mbMacro = getFlag( nFlags, BIFF_DEFNAME_MACRO );
+ maOoxData.mbFunction = getFlag( nFlags, BIFF_DEFNAME_FUNC );
+ maOoxData.mbVBName = getFlag( nFlags, BIFF_DEFNAME_VBNAME );
+ maOoxData.mbHidden = getFlag( nFlags, BIFF_DEFNAME_HIDDEN );
+
+ // get builtin name index from name
+ if( getFlag( nFlags, BIFF_DEFNAME_BUILTIN ) )
+ mcBuiltinId = lclGetBuiltinIdFromOob( maOoxData.maName );
+ // unhide built-in names (_xlnm._FilterDatabase is always hidden)
+ if( isBuiltinName() )
+ maOoxData.mbHidden = false;
+
+ // store token array data
+ sal_Int32 nRecPos = rStrm.getRecPos();
+ sal_Int32 nFmlaSize = rStrm.readInt32();
+ rStrm.skip( nFmlaSize );
+ sal_Int32 nAddDataSize = rStrm.readInt32();
+ if( rStrm.isValid() && (nFmlaSize > 0) && (nAddDataSize >= 0) && (rStrm.getRecLeft() >= nAddDataSize) )
+ {
+ sal_Int32 nTotalSize = 8 + nFmlaSize + nAddDataSize;
+ mxFormula.reset( new RecordDataSequence( nTotalSize ) );
+ rStrm.seek( nRecPos );
+ rStrm.read( mxFormula->getArray(), nTotalSize );
+ }
+}
+
+void DefinedName::importDefinedName( BiffInputStream& rStrm )
+{
+ BiffType eBiff = getBiff();
+ sal_uInt16 nFlags = 0;
+ sal_Int16 nRefId = BIFF_DEFNAME_GLOBAL;
+ sal_Int16 nTabId = BIFF_DEFNAME_GLOBAL;
+ sal_uInt8 nNameLen = 0, nShortCut = 0;
+
+ switch( eBiff )
+ {
+ case BIFF2:
+ {
+ sal_uInt8 nFlagsBiff2;
+ rStrm >> nFlagsBiff2;
+ rStrm.skip( 1 );
+ rStrm >> nShortCut >> nNameLen;
+ mnFmlaSize = rStrm.readuInt8();
+ setFlag( nFlags, BIFF_DEFNAME_FUNC, getFlag( nFlagsBiff2, BIFF2_DEFNAME_FUNC ) );
+ maOoxData.maName = rStrm.readCharArray( nNameLen, getTextEncoding() );
+ }
+ break;
+ case BIFF3:
+ case BIFF4:
+ rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize;
+ maOoxData.maName = rStrm.readCharArray( nNameLen, getTextEncoding() );
+ break;
+ case BIFF5:
+ rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize >> nRefId >> nTabId;
+ maOoxData.maName = rStrm.skip( 4 ).readCharArray( nNameLen, getTextEncoding() );
+ break;
+ case BIFF8:
+ rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize >> nRefId >> nTabId;
+ maOoxData.maName = rStrm.skip( 4 ).readUniString( nNameLen );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+
+ // macro function/command, hidden flag
+ maOoxData.mbMacro = getFlag( nFlags, BIFF_DEFNAME_MACRO );
+ maOoxData.mbFunction = getFlag( nFlags, BIFF_DEFNAME_FUNC );
+ maOoxData.mbVBName = getFlag( nFlags, BIFF_DEFNAME_VBNAME );
+ maOoxData.mbHidden = getFlag( nFlags, BIFF_DEFNAME_HIDDEN );
+
+ // get builtin name index from name
+ if( getFlag( nFlags, BIFF_DEFNAME_BUILTIN ) )
+ {
+ OSL_ENSURE( maOoxData.maName.getLength() == 1, "DefinedName::importDefinedName - wrong builtin name" );
+ if( maOoxData.maName.getLength() > 0 )
+ {
+ mcBuiltinId = maOoxData.maName[ 0 ];
+ if( mcBuiltinId == '?' ) // the NUL character is imported as '?'
+ mcBuiltinId = OOX_DEFNAME_CONSOLIDATEAREA;
+ }
+ }
+ /* In BIFF5, _xlnm._FilterDatabase appears as hidden user name without
+ built-in flag, and even worse, localized. */
+ else if( (eBiff == BIFF5) && lclIsFilterDatabaseName( maOoxData.maName ) )
+ {
+ mcBuiltinId = OOX_DEFNAME_FILTERDATABASE;
+ }
+
+ // unhide built-in names (_xlnm._FilterDatabase is always hidden)
+ if( isBuiltinName() )
+ maOoxData.mbHidden = false;
+
+ // get sheet index for sheet-local names in BIFF5-BIFF8
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ 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 )
+ maOoxData.mnSheet = pExtLink->getSheetIndex();
+ break;
+ case BIFF8:
+ // one-based sheet index
+ if( nTabId != BIFF_DEFNAME_GLOBAL )
+ maOoxData.mnSheet = nTabId - 1;
+ break;
+ case BIFF_UNKNOWN:
+ break;
+ }
+
+ // store record position to be able to import token array later
+ mpStrm = &rStrm;
+ mnRecHandle = rStrm.getRecHandle();
+ mnRecPos = rStrm.getRecPos();
+}
+
+void DefinedName::createNameObject()
+{
+ // do not create hidden names and names for (macro) functions
+ if( maOoxData.mbHidden || maOoxData.mbFunction )
+ return;
+
+ // convert original name to final Calc name
+ if( maOoxData.mbVBName )
+ maFinalName = maOoxData.maName;
+ else if( isBuiltinName() )
+ maFinalName = lclGetFinalName( mcBuiltinId );
+ else
+ maFinalName = maOoxData.maName; //! TODO convert to valid name
+
+ // append sheet index for local names in multi-sheet documents
+ if( isWorkbookFile() && !isGlobalName() )
+ maFinalName = OUStringBuffer( maFinalName ).append( sal_Unicode( '_' ) ).append( maOoxData.mnSheet + 1 ).makeStringAndClear();
+
+ // special flags for this name
+ sal_Int32 nNameFlags = 0;
+ using namespace ::com::sun::star::sheet::NamedRangeFlag;
+ if( !isGlobalName() ) switch( mcBuiltinId )
+ {
+ case OOX_DEFNAME_CRITERIA: nNameFlags = FILTER_CRITERIA; break;
+ case OOX_DEFNAME_PRINTAREA: nNameFlags = PRINT_AREA; break;
+ case OOX_DEFNAME_PRINTTITLES: nNameFlags = COLUMN_HEADER | ROW_HEADER; break;
+ }
+
+ // create the name and insert it into the document, maFinalName will be changed to the resulting name
+ mxNamedRange = getDefinedNames().createDefinedName( maFinalName, nNameFlags );
+ // index of this defined name used in formula token arrays
+ mnTokenIndex = getDefinedNames().getTokenIndex( mxNamedRange );
+}
+
+void DefinedName::convertFormula()
+{
+ Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY );
+ if( xTokens.is() )
+ {
+ // convert and set formula of the defined name
+ SimpleFormulaContext aContext( xTokens, true, true );
+ switch( getFilterType() )
+ {
+ case FILTER_OOX: implImportOoxFormula( aContext ); break;
+ case FILTER_BIFF: implImportBiffFormula( aContext ); break;
+ case FILTER_UNKNOWN: break;
+ }
+
+ // set builtin names (print ranges, repeated titles, filter ranges)
+ if( !isGlobalName() ) switch( mcBuiltinId )
+ {
+ case OOX_DEFNAME_PRINTAREA:
+ {
+ Reference< XPrintAreas > xPrintAreas( getSheet( maOoxData.mnSheet ), UNO_QUERY );
+ ApiCellRangeList aPrintRanges;
+ getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), maOoxData.mnSheet );
+ if( xPrintAreas.is() && !aPrintRanges.empty() )
+ xPrintAreas->setPrintAreas( ContainerHelper::vectorToSequence( aPrintRanges ) );
+ }
+ break;
+ case OOX_DEFNAME_PRINTTITLES:
+ {
+ Reference< XPrintAreas > xPrintAreas( getSheet( maOoxData.mnSheet ), UNO_QUERY );
+ ApiCellRangeList aTitleRanges;
+ getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), maOoxData.mnSheet );
+ if( xPrintAreas.is() && !aTitleRanges.empty() )
+ {
+ bool bHasRowTitles = false;
+ bool bHasColTitles = false;
+ const CellAddress& rMaxPos = getAddressConverter().getMaxAddress();
+ for( ApiCellRangeList::const_iterator aIt = aTitleRanges.begin(), aEnd = aTitleRanges.end(); (aIt != aEnd) && (!bHasRowTitles || !bHasColTitles); ++aIt )
+ {
+ bool bFullRow = (aIt->StartColumn == 0) && (aIt->EndColumn >= rMaxPos.Column);
+ bool bFullCol = (aIt->StartRow == 0) && (aIt->EndRow >= rMaxPos.Row);
+ if( !bHasRowTitles && bFullRow && !bFullCol )
+ {
+ xPrintAreas->setTitleRows( *aIt );
+ xPrintAreas->setPrintTitleRows( sal_True );
+ bHasRowTitles = true;
+ }
+ else if( !bHasColTitles && bFullCol && !bFullRow )
+ {
+ xPrintAreas->setTitleColumns( *aIt );
+ xPrintAreas->setPrintTitleColumns( sal_True );
+ bHasColTitles = true;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ else if( maOoxData.mbHidden && (maOoxData.maName.getLength() > 0) && (maOoxData.maName[ 0 ] == '\x01') )
+ {
+ // import BIFF2-BIFF4 external references
+ TokensFormulaContext aContext( true, true );
+ implImportBiffFormula( aContext );
+ setReference( aContext.getTokens() );
+ }
+}
+
+void DefinedName::implImportOoxFormula( FormulaContext& rContext )
+{
+ if( mxFormula.get() )
+ {
+ RecordInputStream aStrm( *mxFormula );
+ importOobFormula( rContext, aStrm );
+ }
+ else
+ importOoxFormula( rContext );
+}
+
+void DefinedName::implImportBiffFormula( FormulaContext& rContext )
+{
+ OSL_ENSURE( mpStrm, "DefinedName::importBiffFormula - missing BIFF stream" );
+ sal_Int64 nCurrRecHandle = mpStrm->getRecHandle();
+ if( mpStrm->startRecordByHandle( mnRecHandle ) )
+ mpStrm->seek( mnRecPos );
+ importBiffFormula( rContext, *mpStrm, &mnFmlaSize );
+ mpStrm->startRecordByHandle( nCurrRecHandle );
+}
+
+// ============================================================================
+
+DefinedNamesBuffer::DefinedNamesBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maTokenIndexProp( CREATE_OUSTRING( "TokenIndex" ) ),
+ mnLocalSheet( -1 )
+{
+}
+
+Reference< XNamedRange > DefinedNamesBuffer::createDefinedName( OUString& orName, sal_Int32 nNameFlags ) const
+{
+ // find an unused name
+ Reference< XNamedRanges > xNamedRanges = getNamedRanges();
+ Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY );
+ if( xNameAccess.is() )
+ orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
+
+ // create the name and insert it into the Calc document
+ Reference< XNamedRange > xNamedRange;
+ if( xNamedRanges.is() && (orName.getLength() > 0) ) try
+ {
+ xNamedRanges->addNewByName( orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags );
+ xNamedRange.set( xNamedRanges->getByName( orName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "DefinedNamesBuffer::createDefinedName - cannot create defined name" );
+ }
+ return xNamedRange;
+}
+
+sal_Int32 DefinedNamesBuffer::getTokenIndex( const Reference< XNamedRange >& rxNamedRange ) const
+{
+ PropertySet aPropSet( rxNamedRange );
+ sal_Int32 nIndex = -1;
+ return aPropSet.getProperty( nIndex, maTokenIndexProp ) ? nIndex : -1;
+}
+
+void DefinedNamesBuffer::setLocalSheetIndex( sal_Int32 nLocalSheet )
+{
+ mnLocalSheet = nLocalSheet;
+}
+
+DefinedNameRef DefinedNamesBuffer::importDefinedName( const AttributeList& rAttribs )
+{
+ DefinedNameRef xDefName = createDefinedName();
+ xDefName->importDefinedName( rAttribs );
+ return xDefName;
+}
+
+void DefinedNamesBuffer::importDefinedName( RecordInputStream& rStrm )
+{
+ createDefinedName()->importDefinedName( rStrm );
+}
+
+void DefinedNamesBuffer::importDefinedName( BiffInputStream& rStrm )
+{
+ createDefinedName()->importDefinedName( rStrm );
+}
+
+void DefinedNamesBuffer::finalizeImport()
+{
+ /* First insert all names without formula definition into the document. */
+ maDefNames.forEachMem( &DefinedName::createNameObject );
+ /* Now convert all name formulas, so that the formula parser can find all
+ names in case of circular dependencies. */
+ maDefNames.forEachMem( &DefinedName::convertFormula );
+}
+
+DefinedNameRef DefinedNamesBuffer::getByIndex( sal_Int32 nIndex ) const
+{
+ return maDefNames.get( nIndex );
+}
+
+DefinedNameRef DefinedNamesBuffer::getByOoxName( const OUString& rOoxName, sal_Int32 nSheet ) const
+{
+ DefinedNameRef xGlobalName; // a found global name
+ DefinedNameRef xLocalName; // a found local name
+ for( DefNameVec::const_iterator aIt = maDefNames.begin(), aEnd = maDefNames.end(); (aIt != aEnd) && !xLocalName; ++aIt )
+ {
+ DefinedNameRef xCurrName = *aIt;
+ if( xCurrName->getOoxName() == rOoxName )
+ {
+ if( xCurrName->getSheetIndex() == nSheet )
+ xLocalName = xCurrName;
+ else if( xCurrName->isGlobalName() )
+ xGlobalName = xCurrName;
+ }
+ }
+ return xLocalName.get() ? xLocalName : xGlobalName;
+}
+
+DefinedNameRef DefinedNamesBuffer::createDefinedName()
+{
+ DefinedNameRef xDefName( new DefinedName( *this, mnLocalSheet ) );
+ maDefNames.push_back( xDefName );
+ return xDefName;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/excelfilter.cxx b/oox/source/xls/excelfilter.cxx
new file mode 100644
index 000000000000..feaf77188ee6
--- /dev/null
+++ b/oox/source/xls/excelfilter.cxx
@@ -0,0 +1,284 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: excelfilter.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/excelfilter.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/xls/biffdetector.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/workbookfragment.hxx"
+#include "oox/dump/biffdumper.hxx"
+#include "oox/dump/xlsbdumper.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::xml::sax::XFastDocumentHandler;
+using ::oox::core::BinaryFilterBase;
+using ::oox::core::FragmentHandlerRef;
+using ::oox::core::RecordInfo;
+using ::oox::core::RecordInfoProvider;
+using ::oox::core::RecordInfoProviderRef;
+using ::oox::core::Relation;
+using ::oox::core::Relations;
+using ::oox::core::XmlFilterBase;
+using ::oox::vml::DrawingPtr;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+/** List of OOBIN record identifiers that start a new context level. */
+static const struct RecordInfo spRecInfos[] =
+{
+ { OOBIN_ID_BOOKVIEWS, OOBIN_ID_BOOKVIEWS + 1 },
+ { OOBIN_ID_BORDERS, OOBIN_ID_BORDERS + 1 },
+ { OOBIN_ID_CELLSTYLES, OOBIN_ID_CELLSTYLES + 1 },
+ { OOBIN_ID_CELLSTYLEXFS, OOBIN_ID_CELLSTYLEXFS + 1 },
+ { OOBIN_ID_CELLXFS, OOBIN_ID_CELLXFS + 1 },
+ { OOBIN_ID_CFRULE, OOBIN_ID_CFRULE + 1 },
+ { OOBIN_ID_COLBREAKS, OOBIN_ID_COLBREAKS + 1 },
+ { OOBIN_ID_COLORS, OOBIN_ID_COLORS + 1 },
+ { OOBIN_ID_COLORSCALE, OOBIN_ID_COLORSCALE + 1 },
+ { OOBIN_ID_COLS, OOBIN_ID_COLS + 1 },
+ { OOBIN_ID_CONDFORMATTING, OOBIN_ID_CONDFORMATTING + 1 },
+ { OOBIN_ID_DATABAR, OOBIN_ID_DATABAR + 1 },
+ { OOBIN_ID_DATAVALIDATIONS, OOBIN_ID_DATAVALIDATIONS + 1 },
+ { OOBIN_ID_DDEITEMVALUES, OOBIN_ID_DDEITEMVALUES + 1 },
+ { OOBIN_ID_DXFS, OOBIN_ID_DXFS + 1 },
+ { OOBIN_ID_EXTERNALBOOK, -1 },
+ { OOBIN_ID_EXTERNALREFS, OOBIN_ID_EXTERNALREFS + 1 },
+ { OOBIN_ID_EXTROW, -1 },
+ { OOBIN_ID_EXTSHEETDATA, OOBIN_ID_EXTSHEETDATA + 1 },
+ { OOBIN_ID_FILLS, OOBIN_ID_FILLS + 1 },
+ { OOBIN_ID_FONTS, OOBIN_ID_FONTS + 1 },
+ { OOBIN_ID_HEADERFOOTER, OOBIN_ID_HEADERFOOTER + 1 },
+ { OOBIN_ID_ICONSET, OOBIN_ID_ICONSET + 1 },
+ { OOBIN_ID_INDEXEDCOLORS, OOBIN_ID_INDEXEDCOLORS + 1 },
+ { OOBIN_ID_MERGECELLS, OOBIN_ID_MERGECELLS + 1 },
+ { OOBIN_ID_MRUCOLORS, OOBIN_ID_MRUCOLORS + 1 },
+ { OOBIN_ID_NUMFMTS, OOBIN_ID_NUMFMTS + 1 },
+ { OOBIN_ID_ROW, -1 },
+ { OOBIN_ID_ROWBREAKS, OOBIN_ID_ROWBREAKS + 1 },
+ { OOBIN_ID_SHEETDATA, OOBIN_ID_SHEETDATA + 1 },
+ { OOBIN_ID_SHEETDATASET, OOBIN_ID_SHEETDATASET + 1 },
+ { OOBIN_ID_SHEETS, OOBIN_ID_SHEETS + 1 },
+ { OOBIN_ID_SHEETVIEW, OOBIN_ID_SHEETVIEW + 1 },
+ { OOBIN_ID_SHEETVIEWS, OOBIN_ID_SHEETVIEWS + 1 },
+ { OOBIN_ID_SST, OOBIN_ID_SST + 1 },
+ { OOBIN_ID_STYLESHEET, OOBIN_ID_STYLESHEET + 1 },
+ { OOBIN_ID_TABLE, OOBIN_ID_TABLE + 1 },
+ { OOBIN_ID_TABLEPARTS, OOBIN_ID_TABLEPARTS + 2 }, // end element increased by 2!
+ { OOBIN_ID_TABLESTYLES, OOBIN_ID_TABLESTYLES + 1 },
+ { OOBIN_ID_VOLTYPE, OOBIN_ID_VOLTYPE + 1 },
+ { OOBIN_ID_VOLTYPEMAIN, OOBIN_ID_VOLTYPEMAIN + 1 },
+ { OOBIN_ID_VOLTYPES, OOBIN_ID_VOLTYPES + 1 },
+ { OOBIN_ID_WORKBOOK, OOBIN_ID_WORKBOOK + 1 },
+ { OOBIN_ID_WORKSHEET, OOBIN_ID_WORKSHEET + 1 },
+ { -1, -1 }
+};
+
+} // namespace
+
+// ============================================================================
+
+OUString SAL_CALL ExcelFilter_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilter" );
+}
+
+Sequence< OUString > SAL_CALL ExcelFilter_getSupportedServiceNames() throw()
+{
+ OUString aServiceName = CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilter" );
+ Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL ExcelFilter_createInstance(
+ const Reference< XMultiServiceFactory >& rxFactory ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new ExcelFilter( rxFactory ) );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcelFilter::ExcelFilter( const Reference< XMultiServiceFactory >& rxFactory ) :
+ XmlFilterBase( rxFactory ),
+ mpHelper( 0 )
+{
+}
+
+ExcelFilter::~ExcelFilter()
+{
+}
+
+bool ExcelFilter::importDocument() throw()
+{
+#if OOX_INCLUDE_DUMPER
+ {
+ ::oox::dump::xlsb::Dumper aDumper( *this );
+ aDumper.dump();
+ if( !aDumper.isImportEnabled() )
+ return aDumper.isValid();
+ }
+#endif
+
+ bool bRet = false;
+ OUString aWorkbookPath = getFragmentPathFromType( CREATE_RELATIONS_TYPE( "officeDocument" ) );
+ if( aWorkbookPath.getLength() > 0 )
+ {
+ WorkbookHelperRoot aHelper( *this );
+ if( aHelper.isValid() )
+ {
+ mpHelper = &aHelper; // needed for callbacks
+ bRet = importFragment( new OoxWorkbookFragment( aHelper, aWorkbookPath ) );
+ mpHelper = 0;
+ }
+ }
+ return bRet;
+}
+
+bool ExcelFilter::exportDocument() throw()
+{
+ return false;
+}
+
+sal_Int32 ExcelFilter::getSchemeClr( sal_Int32 nColorSchemeToken ) const
+{
+ OSL_ENSURE( mpHelper, "ExcelFilter::getSchemeClr - no workbook helper" );
+ return mpHelper ? mpHelper->getTheme().getColorByToken( nColorSchemeToken ) : -1;
+}
+
+const DrawingPtr ExcelFilter::getDrawings()
+{
+ return DrawingPtr();
+}
+
+RecordInfoProviderRef ExcelFilter::getRecordInfoProvider()
+{
+ if( !mxRecInfoProv )
+ mxRecInfoProv.reset( new RecordInfoProvider( spRecInfos ) );
+ return mxRecInfoProv;
+}
+
+OUString ExcelFilter::implGetImplementationName() const
+{
+ return ExcelFilter_getImplementationName();
+}
+
+// ============================================================================
+
+OUString SAL_CALL ExcelBiffFilter_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelBiffFilter" );
+}
+
+Sequence< OUString > SAL_CALL ExcelBiffFilter_getSupportedServiceNames() throw()
+{
+ OUString aServiceName = CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelBiffFilter" );
+ Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL ExcelBiffFilter_createInstance(
+ const Reference< XMultiServiceFactory >& rxFactory ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new ExcelBiffFilter( rxFactory ) );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcelBiffFilter::ExcelBiffFilter( const Reference< XMultiServiceFactory >& rxFactory ) :
+ BinaryFilterBase( rxFactory )
+{
+}
+
+ExcelBiffFilter::~ExcelBiffFilter()
+{
+}
+
+bool ExcelBiffFilter::importDocument() throw()
+{
+#if OOX_INCLUDE_DUMPER
+ {
+ ::oox::dump::biff::Dumper aDumper( *this );
+ aDumper.dump();
+ if( !aDumper.isImportEnabled() )
+ return aDumper.isValid();
+ }
+#endif
+
+ bool bRet = false;
+
+ // detect BIFF version and workbook stream name
+ OUString aWorkbookName;
+ BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
+ BinaryInputStream aInStrm( getStorage()->openInputStream( aWorkbookName ), aWorkbookName.getLength() > 0 );
+ OSL_ENSURE( (eBiff != BIFF_UNKNOWN) && aInStrm.is(), "ExcelBiffFilter::ExcelBiffFilter - invalid file format" );
+
+ if( (eBiff != BIFF_UNKNOWN) && aInStrm.is() )
+ {
+ WorkbookHelperRoot aHelper( *this, eBiff );
+ if( aHelper.isValid() )
+ {
+ BiffWorkbookFragment aFragment( aHelper );
+ BiffInputStream aBiffStream( aInStrm );
+ bRet = aFragment.importFragment( aBiffStream );
+ }
+ }
+ return bRet;
+}
+
+bool ExcelBiffFilter::exportDocument() throw()
+{
+ return false;
+}
+
+OUString ExcelBiffFilter::implGetImplementationName() const
+{
+ return ExcelBiffFilter_getImplementationName();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx
new file mode 100644
index 000000000000..72dab2171955
--- /dev/null
+++ b/oox/source/xls/externallinkbuffer.cxx
@@ -0,0 +1,857 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: externallinkbuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/externallinkbuffer.hxx"
+#include <rtl/strbuf.hxx>
+#include <com/sun/star/sheet/XDDELinks.hpp>
+#include <com/sun/star/sheet/XDDELink.hpp>
+#include <com/sun/star/sheet/XDDELinkResults.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/ooxfragmenthandler.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+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::XDDELinks;
+using ::com::sun::star::sheet::XDDELinkResults;
+using ::oox::core::Relations;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 OOBIN_EXTERNALBOOK_BOOK = 0;
+const sal_uInt16 OOBIN_EXTERNALBOOK_DDE = 1;
+const sal_uInt16 OOBIN_EXTERNALBOOK_OLE = 2;
+
+const sal_uInt16 OOBIN_EXTNAME_AUTOMATIC = 0x0002;
+const sal_uInt16 OOBIN_EXTNAME_PREFERPIC = 0x0004;
+const sal_uInt16 OOBIN_EXTNAME_STDDOCNAME = 0x0008;
+const sal_uInt16 OOBIN_EXTNAME_OLEOBJECT = 0x0010;
+const sal_uInt16 OOBIN_EXTNAME_ICONIFIED = 0x0020;
+
+const sal_uInt16 BIFF_EXTNAME_BUILTIN = 0x0001;
+const sal_uInt16 BIFF_EXTNAME_AUTOMATIC = 0x0002;
+const sal_uInt16 BIFF_EXTNAME_PREFERPIC = 0x0004;
+const sal_uInt16 BIFF_EXTNAME_STDDOCNAME = 0x0008;
+const sal_uInt16 BIFF_EXTNAME_OLEOBJECT = 0x0010;
+const sal_uInt16 BIFF_EXTNAME_ICONIFIED = 0x8000;
+
+} // namespace
+
+// ============================================================================
+
+OoxExternalNameData::OoxExternalNameData() :
+ mbBuiltIn( false ),
+ mbNotify( false ),
+ mbPreferPic( false ),
+ mbStdDocName( false ),
+ mbOleObj( false ),
+ mbIconified( false )
+{
+}
+
+// ============================================================================
+
+ExternalName::ExternalName( const ExternalLink& rParentLink, sal_Int32 nLocalSheet ) :
+ DefinedNameBase( rParentLink, nLocalSheet ),
+ mrParentLink( rParentLink ),
+ mnStorageId( 0 ),
+ mbDdeLinkCreated( false )
+{
+}
+
+void ExternalName::importDefinedName( const AttributeList& rAttribs )
+{
+ maOoxData.maName = rAttribs.getString( XML_name );
+ OSL_ENSURE( maOoxData.maName.getLength() > 0, "ExternalName::importDefinedName - empty name" );
+ // zero-based index into sheet list of externalBook
+ maOoxData.mnSheet = mrParentLink.getSheetIndex( rAttribs.getInteger( XML_sheetId, -1 ) );
+}
+
+void ExternalName::importDdeItem( const AttributeList& rAttribs )
+{
+ maOoxData.maName = rAttribs.getString( XML_name );
+ OSL_ENSURE( maOoxData.maName.getLength() > 0, "ExternalName::importDdeItem - empty name" );
+ maOoxExtNameData.mbOleObj = false;
+ maOoxExtNameData.mbStdDocName = rAttribs.getBool( XML_ole, false );
+ maOoxExtNameData.mbNotify = rAttribs.getBool( XML_advise, false );
+ maOoxExtNameData.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
+}
+
+void ExternalName::importValues( const AttributeList& rAttribs )
+{
+ setResultSize( rAttribs.getInteger( XML_cols, 1 ), rAttribs.getInteger( XML_rows, 1 ) );
+}
+
+void ExternalName::importOleItem( const AttributeList& rAttribs )
+{
+ maOoxData.maName = rAttribs.getString( XML_name );
+ OSL_ENSURE( maOoxData.maName.getLength() > 0, "ExternalName::importOleItem - empty name" );
+ maOoxExtNameData.mbOleObj = true;
+ maOoxExtNameData.mbNotify = rAttribs.getBool( XML_advise, false );
+ maOoxExtNameData.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
+ maOoxExtNameData.mbIconified = rAttribs.getBool( XML_icon, false );
+}
+
+void ExternalName::importExternalName( RecordInputStream& rStrm )
+{
+ rStrm >> maOoxData.maName;
+ OSL_ENSURE( maOoxData.maName.getLength() > 0, "ExternalName::importExternalName - empty name" );
+}
+
+void ExternalName::importExternalNameFlags( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ sal_Int32 nSheetId;
+ rStrm >> nFlags >> nSheetId;
+ // one-based index into sheet list of EXTSHEETNAMES
+ maOoxData.mnSheet = mrParentLink.getSheetIndex( nSheetId - 1 );
+ // no flag for built-in names, as in OOX...
+ maOoxExtNameData.mbNotify = getFlag( nFlags, OOBIN_EXTNAME_AUTOMATIC );
+ maOoxExtNameData.mbPreferPic = getFlag( nFlags, OOBIN_EXTNAME_PREFERPIC );
+ maOoxExtNameData.mbStdDocName = getFlag( nFlags, OOBIN_EXTNAME_STDDOCNAME );
+ maOoxExtNameData.mbOleObj = getFlag( nFlags, OOBIN_EXTNAME_OLEOBJECT );
+ maOoxExtNameData.mbIconified = getFlag( nFlags, OOBIN_EXTNAME_ICONIFIED );
+ OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_OLE) == maOoxExtNameData.mbOleObj,
+ "ExternalName::importExternalNameFlags - wrong flags in external name" );
+}
+
+void ExternalName::importDdeItemValues( RecordInputStream& rStrm )
+{
+ sal_Int32 nRows, nCols;
+ rStrm >> nRows >> nCols;
+ setResultSize( nCols, nRows );
+}
+
+void ExternalName::importDdeItemBool( RecordInputStream& rStrm )
+{
+ appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
+}
+
+void ExternalName::importDdeItemDouble( RecordInputStream& rStrm )
+{
+ appendResultValue( rStrm.readDouble() );
+}
+
+void ExternalName::importDdeItemError( RecordInputStream& rStrm )
+{
+ appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
+}
+
+void ExternalName::importDdeItemString( RecordInputStream& rStrm )
+{
+ appendResultValue( rStrm.readString() );
+}
+
+void ExternalName::importExternalName( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags = 0;
+ if( getBiff() >= BIFF3 )
+ {
+ rStrm >> nFlags;
+ maOoxExtNameData.mbBuiltIn = getFlag( nFlags, BIFF_EXTNAME_BUILTIN );
+ maOoxExtNameData.mbNotify = getFlag( nFlags, BIFF_EXTNAME_AUTOMATIC );
+ maOoxExtNameData.mbPreferPic = getFlag( nFlags, BIFF_EXTNAME_PREFERPIC );
+
+ // BIFF5-BIFF8: sheet index for sheet-local names, OLE settings
+ if( getBiff() >= BIFF5 )
+ {
+ maOoxExtNameData.mbStdDocName = getFlag( nFlags, BIFF_EXTNAME_STDDOCNAME );
+ maOoxExtNameData.mbOleObj = getFlag( nFlags, BIFF_EXTNAME_OLEOBJECT );
+ maOoxExtNameData.mbIconified = getFlag( nFlags, BIFF_EXTNAME_ICONIFIED );
+
+ if( maOoxExtNameData.mbOleObj )
+ {
+ rStrm >> mnStorageId;
+ }
+ else
+ {
+ // get sheet index for sheet-local names
+ sal_Int16 nRefId = rStrm.skip( 2 ).readuInt16();
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ break;
+ case BIFF5:
+ // resolve nRefId to sheet index, zero is global name
+ if( nRefId > 0 )
+ if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
+ if( pExtLink->getLinkType() == LINKTYPE_EXTERNAL )
+ maOoxData.mnSheet = pExtLink->getSheetIndex();
+ break;
+ case BIFF8:
+ // one-based index into sheet list of EXTERNALBOOK record, zero is global name
+ if( nRefId > 0 )
+ maOoxData.mnSheet = mrParentLink.getSheetIndex( nRefId - 1 );
+ break;
+ case BIFF_UNKNOWN:
+ break;
+ }
+ }
+ }
+ }
+
+ maOoxData.maName = (getBiff() == BIFF8) ?
+ rStrm.readUniString( rStrm.readuInt8() ) :
+ rStrm.readByteString( false, getTextEncoding() );
+ OSL_ENSURE( maOoxData.maName.getLength() > 0, "ExternalName::importExternalName - empty name" );
+
+ switch( mrParentLink.getLinkType() )
+ {
+ case LINKTYPE_EXTERNAL:
+ // external cell references that are stored in hidden external names (seen in BIFF3-BIFF4)
+ if( (maOoxData.maName.getLength() > 0) && (maOoxData.maName[ 0 ] == '\x01') && (rStrm.getRecLeft() > 2) )
+ {
+ TokensFormulaContext aContext( true, true );
+ importBiffFormula( aContext, rStrm );
+ setReference( aContext.getTokens() );
+ }
+ break;
+
+ case LINKTYPE_DDE:
+ case LINKTYPE_OLE:
+ case LINKTYPE_MAYBE_DDE_OLE:
+ // DDE/OLE link results
+ if( rStrm.getRecLeft() > 3 )
+ {
+ bool bBiff8 = getBiff() == BIFF8;
+ sal_Int32 nCols = rStrm.readuInt8();
+ sal_Int32 nRows = rStrm.readuInt16();
+ if( bBiff8 ) { ++nCols; ++nRows; } else if( nCols == 0 ) nCols = 256;
+ setResultSize( nCols, nRows );
+
+ bool bLoop = true;
+ while( bLoop && rStrm.isValid() && (maCurrIt != maResults.end()) )
+ {
+ switch( rStrm.readuInt8() )
+ {
+ case BIFF_DATATYPE_EMPTY:
+ appendResultValue( OUString() );
+ rStrm.skip( 8 );
+ break;
+ case BIFF_DATATYPE_DOUBLE:
+ appendResultValue( rStrm.readDouble() );
+ break;
+ case BIFF_DATATYPE_STRING:
+ appendResultValue( bBiff8 ? rStrm.readUniString() : rStrm.readByteString( false, getTextEncoding() ) );
+ break;
+ case BIFF_DATATYPE_BOOL:
+ appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
+ rStrm.skip( 7 );
+ break;
+ case BIFF_DATATYPE_ERROR:
+ appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
+ rStrm.skip( 7 );
+ break;
+ default:
+ bLoop = false;
+ }
+ }
+ OSL_ENSURE( bLoop && rStrm.isValid() && (maCurrIt == maResults.end()),
+ "ExternalName::importExternalName - stream error in result set" );
+ }
+ break;
+
+ default:;
+ }
+}
+
+bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
+{
+ if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && (maOoxData.maName.getLength() > 0) )
+ {
+ // try to create a DDE link and to set the imported link results
+ if( !mbDdeLinkCreated ) try
+ {
+ Reference< XDDELinks > xDdeLinks( getDdeLinks(), UNO_QUERY_THROW );
+ mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maOoxData.maName, ::com::sun::star::sheet::DDELinkMode_DEFAULT );
+ if( !maResults.empty() )
+ {
+ Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
+ xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
+ }
+ mbDdeLinkCreated = true;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "ExternalName::getDdeLinkData - cannot create DDE link" );
+ }
+ // get link data from created DDE link
+ if( mxDdeLink.is() )
+ {
+ orDdeServer = mxDdeLink->getApplication();
+ orDdeTopic = mxDdeLink->getTopic();
+ orDdeItem = mxDdeLink->getItem();
+ return true;
+ }
+ }
+ return false;
+}
+
+void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
+{
+ OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_DDE) || (mrParentLink.getLinkType() == LINKTYPE_OLE) ||
+ (mrParentLink.getLinkType() == LINKTYPE_MAYBE_DDE_OLE), "ExternalName::setResultSize - wrong link type" );
+ OSL_ENSURE( (nRows > 0) && (nColumns > 0), "ExternalName::setResultSize - invalid matrix size" );
+ const CellAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
+ if( (0 < nRows) && (nRows <= rMaxPos.Row + 1) && (0 < nColumns) && (nColumns <= rMaxPos.Column + 1) )
+ maResults.resize( static_cast< size_t >( nColumns ), static_cast< size_t >( nRows ), Any( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ) );
+ else
+ maResults.clear();
+ maCurrIt = maResults.begin();
+}
+
+// ============================================================================
+
+ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ meLinkType( LINKTYPE_UNKNOWN )
+{
+}
+
+void ExternalLink::importExternalReference( const AttributeList& rAttribs )
+{
+ maRelId = rAttribs.getString( R_TOKEN( id ) );
+}
+
+void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
+{
+ OUString aTargetUrl = rRelations.getTargetFromRelId( rAttribs.getString( R_TOKEN( id ) ) );
+ setExternalTargetUrl( aTargetUrl );
+}
+
+void ExternalLink::importSheetName( const AttributeList& rAttribs )
+{
+ OUString aSheetName = rAttribs.getString( XML_val );
+ OSL_ENSURE( aSheetName.getLength() > 0, "ExternalLink::importSheetName - empty sheet name" );
+ if( meLinkType == LINKTYPE_EXTERNAL )
+ maSheetIndexes.push_back( getWorksheets().insertExternalSheet( maTargetUrl, aSheetName ) );
+}
+
+void ExternalLink::importDefinedName( const AttributeList& rAttribs )
+{
+ createExternalName()->importDefinedName( rAttribs );
+}
+
+void ExternalLink::importDdeLink( const AttributeList& rAttribs )
+{
+ OUString aDdeService = rAttribs.getString( XML_ddeService );
+ OUString aDdeTopic = rAttribs.getString( XML_ddeTopic );
+ setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
+}
+
+ExternalNameRef ExternalLink::importDdeItem( const AttributeList& rAttribs )
+{
+ ExternalNameRef xExtName = createExternalName();
+ xExtName->importDdeItem( rAttribs );
+ return xExtName;
+}
+
+void ExternalLink::importOleLink( const Relations& rRelations, const AttributeList& rAttribs )
+{
+ OUString aProgId = rAttribs.getString( XML_progId );
+ OUString aTargetUrl = rRelations.getTargetFromRelId( rAttribs.getString( R_TOKEN( id ) ) );
+ setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
+}
+
+ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs )
+{
+ ExternalNameRef xExtName = createExternalName();
+ xExtName->importOleItem( rAttribs );
+ return xExtName;
+}
+
+void ExternalLink::importExternalRef( RecordInputStream& rStrm )
+{
+ rStrm >> maRelId;
+}
+
+void ExternalLink::importExternalSelf( RecordInputStream& )
+{
+ meLinkType = LINKTYPE_SELF;
+}
+
+void ExternalLink::importExternalBook( const Relations& rRelations, RecordInputStream& rStrm )
+{
+ switch( rStrm.readuInt16() )
+ {
+ case OOBIN_EXTERNALBOOK_BOOK:
+ {
+ OUString aTargetUrl = rRelations.getTargetFromRelId( rStrm.readString() );
+ setExternalTargetUrl( aTargetUrl );
+ }
+ break;
+ case OOBIN_EXTERNALBOOK_DDE:
+ {
+ OUString aDdeService, aDdeTopic;
+ rStrm >> aDdeService >> aDdeTopic;
+ setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
+ }
+ break;
+ case OOBIN_EXTERNALBOOK_OLE:
+ {
+ OUString aTargetUrl = rRelations.getTargetFromRelId( rStrm.readString() );
+ OUString aProgId = rStrm.readString();
+ setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "ExternalLink::importExternalBook - unknown link type" );
+ }
+}
+
+void ExternalLink::importExtSheetNames( RecordInputStream& rStrm )
+{
+ // load external sheet names and create the linked sheets in the Calc document
+ OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::importExtSheetNames - invalid link type" );
+ if( meLinkType == LINKTYPE_EXTERNAL )
+ {
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); rStrm.isValid() && (nSheet < nCount); ++nSheet )
+ {
+ OUString aSheetName = rStrm.readString();
+ OSL_ENSURE( aSheetName.getLength() > 0, "ExternalLink::importExtSheetNames - empty sheet name" );
+ maSheetIndexes.push_back( rWorksheets.insertExternalSheet( maTargetUrl, aSheetName ) );
+ }
+ }
+}
+
+ExternalNameRef ExternalLink::importExternalName( RecordInputStream& rStrm )
+{
+ ExternalNameRef xExtName = createExternalName();
+ xExtName->importExternalName( rStrm );
+ return xExtName;
+}
+
+void ExternalLink::importExternSheet( BiffInputStream& rStrm )
+{
+ OStringBuffer aTargetBuffer( rStrm.readByteString( false ) );
+ // references to own sheets have wrong string length field (off by 1)
+ if( (aTargetBuffer.getLength() > 0) && (aTargetBuffer[ 0 ] == 3) )
+ aTargetBuffer.append( static_cast< sal_Char >( rStrm.readuInt8() ) );
+ // parse the encoded URL
+ OUString aBiffTarget = OStringToOUString( aTargetBuffer.makeStringAndClear(), getTextEncoding() );
+ OUString aSheetName = parseBiffTargetUrl( aBiffTarget );
+ switch( meLinkType )
+ {
+ case LINKTYPE_INTERNAL:
+ maSheetIndexes.push_back( getWorksheets().getFinalSheetIndex( aSheetName ) );
+ break;
+ case LINKTYPE_EXTERNAL:
+ maSheetIndexes.push_back( getWorksheets().insertExternalSheet( maTargetUrl, aSheetName ) );
+ break;
+ default:;
+ }
+}
+
+void ExternalLink::importExternalBook( BiffInputStream& rStrm )
+{
+ OUString aTarget;
+ sal_uInt16 nSheetCount;
+ rStrm >> nSheetCount;
+ if( rStrm.getRecLeft() == 2 )
+ {
+ if( rStrm.readuInt8() == 1 )
+ {
+ sal_Char cChar = static_cast< sal_Char >( rStrm.readuInt8() );
+ if( cChar != 0 )
+ aTarget = OStringToOUString( OString( cChar ), getTextEncoding() );
+ }
+ }
+ else if( rStrm.getRecLeft() >= 3 )
+ {
+ aTarget = rStrm.readUniString();
+ }
+
+ // parse the encoded URL
+ OUString aDummySheetName = parseBiffTargetUrl( aTarget );
+ OSL_ENSURE( aDummySheetName.getLength() == 0, "ExternalLink::importExternalBook - sheet name in encoded URL" );
+ (void)aDummySheetName; // prevent compiler warning
+
+ // load external sheet names and create the linked sheets in the Calc document
+ if( meLinkType == LINKTYPE_EXTERNAL )
+ {
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ for( sal_uInt16 nSheet = 0; rStrm.isValid() && (nSheet < nSheetCount); ++nSheet )
+ {
+ OUString aSheetName = rStrm.readUniString();
+ OSL_ENSURE( aSheetName.getLength() > 0, "ExternalLink::importExternalBook - empty sheet name" );
+ maSheetIndexes.push_back( rWorksheets.insertExternalSheet( maTargetUrl, aSheetName ) );
+ }
+ }
+}
+
+void ExternalLink::importExternalName( BiffInputStream& rStrm )
+{
+ ExternalNameRef xExtName = createExternalName();
+ xExtName->importExternalName( rStrm );
+ switch( meLinkType )
+ {
+ case LINKTYPE_DDE:
+ OSL_ENSURE( !xExtName->isOleObject(), "ExternalLink::importExternalName - OLE object in DDE link" );
+ break;
+ case LINKTYPE_OLE:
+ OSL_ENSURE( xExtName->isOleObject(), "ExternalLink::importExternalName - anything but OLE object in OLE link" );
+ break;
+ case LINKTYPE_MAYBE_DDE_OLE:
+ meLinkType = xExtName->isOleObject() ? LINKTYPE_OLE : LINKTYPE_DDE;
+ break;
+ default:
+ OSL_ENSURE( !xExtName->isOleObject(), "ExternalLink::importExternalName - OLE object in external name" );
+ }
+}
+
+sal_Int32 ExternalLink::getSheetIndex( sal_Int32 nTabId ) const
+{
+ OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOX) || (getBiff() == BIFF8),
+ "ExternalLink::getSheetIndex - invalid sheet index" );
+ return ((0 <= nTabId) && (static_cast< size_t >( nTabId ) < maSheetIndexes.size())) ?
+ maSheetIndexes[ static_cast< size_t >( nTabId ) ] : -1;
+}
+
+void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
+{
+ orSheetRange.setDeleted();
+ switch( meLinkType )
+ {
+ case LINKTYPE_SELF:
+ case LINKTYPE_INTERNAL:
+ orSheetRange.set( nTabId1, nTabId2 );
+ break;
+ case LINKTYPE_EXTERNAL: switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ // OOBIN: passed indexes point into sheet list of EXTSHEETLIST
+ orSheetRange.set( getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) );
+ break;
+ case FILTER_BIFF:
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ orSheetRange.set( getSheetIndex( nTabId1 ), getSheetIndex( 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.set( getSheetIndex(), pExtLink2->getSheetIndex() );
+ break;
+ case BIFF8:
+ // BIFF8: passed indexes point into sheet list of EXTERNALBOOK
+ orSheetRange.set( getSheetIndex( nTabId1 ), getSheetIndex( nTabId2 ) );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+ break;
+ case FILTER_UNKNOWN:
+ break;
+ }
+ break;
+
+ default:;
+ }
+}
+
+ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const
+{
+ return maExtNames.get( nIndex );
+}
+
+// private --------------------------------------------------------------------
+
+void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl )
+{
+ maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
+ meLinkType = (maTargetUrl.getLength() > 0) ? LINKTYPE_EXTERNAL : LINKTYPE_UNKNOWN;
+ OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::setExternalTargetUrl - empty target URL" );
+}
+
+void ExternalLink::setDdeOleTargetUrl( const OUString& rClassName, const OUString& rTargetUrl, ExternalLinkType eLinkType )
+{
+ maClassName = rClassName;
+ maTargetUrl = rTargetUrl;
+ meLinkType = ((maClassName.getLength() > 0) && (maTargetUrl.getLength() > 0)) ? eLinkType : LINKTYPE_UNKNOWN;
+ OSL_ENSURE( meLinkType == eLinkType, "ExternalLink::setDdeOleTargetUrl - missing classname or target" );
+}
+
+OUString ExternalLink::parseBiffTargetUrl( const OUString& rBiffTargetUrl )
+{
+ OUString aClassName, aTargetUrl, aSheetName;
+ meLinkType = LINKTYPE_UNKNOWN;
+ if( getAddressConverter().parseBiffTargetUrl( aClassName, aTargetUrl, aSheetName, rBiffTargetUrl ) )
+ {
+ if( aClassName.getLength() > 0 )
+ {
+ setDdeOleTargetUrl( aClassName, aTargetUrl, LINKTYPE_MAYBE_DDE_OLE );
+ }
+ else 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 ] == ' ') )
+ {
+ meLinkType = LINKTYPE_UNKNOWN;
+ }
+ else
+ {
+ setExternalTargetUrl( aTargetUrl );
+ }
+ }
+ return aSheetName;
+}
+
+ExternalNameRef ExternalLink::createExternalName()
+{
+ ExternalNameRef xExtName( new ExternalName( *this, getSheetIndex() ) );
+ maExtNames.push_back( xExtName );
+ return xExtName;
+}
+
+// ============================================================================
+
+OoxRefSheets::OoxRefSheets() :
+ mnExtRefId( -1 ),
+ mnTabId1( -1 ),
+ mnTabId2( -1 )
+{
+}
+
+void OoxRefSheets::readOobData( RecordInputStream& rStrm )
+{
+ rStrm >> mnExtRefId >> mnTabId1 >> mnTabId2;
+}
+
+void OoxRefSheets::readBiff8Data( BiffInputStream& rStrm )
+{
+ mnExtRefId = rStrm.readuInt16();
+ mnTabId1 = rStrm.readInt16();
+ mnTabId2 = rStrm.readInt16();
+}
+
+// ----------------------------------------------------------------------------
+
+ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mbUseRefSheets( false )
+{
+}
+
+ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs )
+{
+ ExternalLinkRef xExtLink = createExternalLink();
+ xExtLink->importExternalReference( rAttribs );
+ return xExtLink;
+}
+
+ExternalLinkRef ExternalLinkBuffer::importExternalRef( RecordInputStream& rStrm )
+{
+ mbUseRefSheets = true;
+ ExternalLinkRef xExtLink = createExternalLink();
+ xExtLink->importExternalRef( rStrm );
+ return xExtLink;
+}
+
+void ExternalLinkBuffer::importExternalSelf( RecordInputStream& rStrm )
+{
+ mbUseRefSheets = true;
+ createExternalLink()->importExternalSelf( rStrm );
+}
+
+void ExternalLinkBuffer::importExternalSheets( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbUseRefSheets, "ExternalLinkBuffer::importExternalSheets - missing EXTERNALREFS records" );
+ mbUseRefSheets = true;
+ OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternalSheets - multiple EXTERNALSHEETS records" );
+ maRefSheets.clear();
+ sal_Int32 nRefCount;
+ rStrm >> nRefCount;
+ size_t nMaxCount = getLimitedValue< size_t, sal_Int32 >( nRefCount, 0, rStrm.getRecLeft() / 12 );
+ maRefSheets.reserve( nMaxCount );
+ for( size_t nRefId = 0; rStrm.isValid() && (nRefId < nMaxCount); ++nRefId )
+ {
+ OoxRefSheets aRefSheets;
+ aRefSheets.readOobData( rStrm );
+ maRefSheets.push_back( aRefSheets );
+ }
+}
+
+ExternalLinkRef ExternalLinkBuffer::importExternSheet( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( getBiff() <= BIFF5, "ExternalLinkBuffer::importExternSheet - wrong BIFF version" );
+ ExternalLinkRef xExtLink = createExternalLink();
+ xExtLink->importExternSheet( rStrm );
+ return xExtLink;
+}
+
+ExternalLinkRef ExternalLinkBuffer::importExternalBook( BiffInputStream& rStrm )
+{
+ ExternalLinkRef xExtLink = createExternalLink();
+ xExtLink->importExternalBook( rStrm );
+ return xExtLink;
+}
+
+void ExternalLinkBuffer::importExternalName( BiffInputStream& rStrm )
+{
+ if( !maExtLinks.empty() )
+ maExtLinks.back()->importExternalName( rStrm );
+}
+
+void ExternalLinkBuffer::importExternSheet8( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( getBiff() == BIFF8, "ExternalLinkBuffer::importExternSheet - wrong BIFF version" );
+ OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternSheet - multiple EXTERNSHEET records" );
+ maRefSheets.clear();
+ sal_uInt16 nRefCount;
+ rStrm >> nRefCount;
+ maRefSheets.reserve( nRefCount );
+ for( sal_uInt16 nRefId = 0; rStrm.isValid() && (nRefId < nRefCount); ++nRefId )
+ {
+ OoxRefSheets aRefSheets;
+ aRefSheets.readBiff8Data( rStrm );
+ maRefSheets.push_back( aRefSheets );
+ }
+}
+
+ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId ) const
+{
+ ExternalLinkRef xExtLink;
+ switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ // OOXML: one-based index
+ if( !mbUseRefSheets )
+ xExtLink = maExtLinks.get( nRefId - 1 );
+ // OOBIN: zero-based index into ref-sheets list
+ else if( const OoxRefSheets* pRefSheets = getRefSheets( nRefId ) )
+ xExtLink = maExtLinks.get( pRefSheets->mnExtRefId );
+ break;
+ case FILTER_BIFF:
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ // one-based index to EXTERNSHEET records
+ xExtLink = maExtLinks.get( nRefId - 1 );
+ break;
+ case BIFF5:
+ if( nRefId < 0 )
+ {
+ // internal links in formula tokens have negative index
+ xExtLink = maExtLinks.get( -nRefId - 1 );
+ if( xExtLink.get() && !xExtLink->isInternalLink() )
+ xExtLink.reset();
+ }
+ else
+ {
+ // one-based index to EXTERNSHEET records
+ xExtLink = maExtLinks.get( nRefId - 1 );
+ }
+ break;
+ case BIFF8:
+ // zero-based index into REF list in EXTERNSHEET record
+ if( const OoxRefSheets* pRefSheets = getRefSheets( nRefId ) )
+ xExtLink = maExtLinks.get( pRefSheets->mnExtRefId );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+ return xExtLink;
+}
+
+LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId, sal_Int16 nTabId1, sal_Int16 nTabId2 ) const
+{
+ OSL_ENSURE( getBiff() <= BIFF5, "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
+ LinkSheetRange aSheetRange;
+ if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
+ pExtLink->getSheetRange( aSheetRange, nTabId1, nTabId2 );
+ return aSheetRange;
+}
+
+LinkSheetRange ExternalLinkBuffer::getSheetRange( sal_Int32 nRefId ) const
+{
+ OSL_ENSURE( ((getFilterType() == FILTER_OOX) && mbUseRefSheets) || (getBiff() == BIFF8), "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
+ LinkSheetRange aSheetRange;
+ if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
+ if( const OoxRefSheets* pRefSheets = getRefSheets( nRefId ) )
+ pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
+ return aSheetRange;
+}
+
+// private --------------------------------------------------------------------
+
+ExternalLinkRef ExternalLinkBuffer::createExternalLink()
+{
+ ExternalLinkRef xExtLink( new ExternalLink( *this ) );
+ maExtLinks.push_back( xExtLink );
+ return xExtLink;
+}
+
+const OoxRefSheets* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const
+{
+ return ((0 <= nRefId) && (static_cast< size_t >( nRefId ) < maRefSheets.size())) ?
+ &maRefSheets[ static_cast< size_t >( nRefId ) ] : 0;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/externallinkfragment.cxx b/oox/source/xls/externallinkfragment.cxx
new file mode 100644
index 000000000000..b291a6ad7147
--- /dev/null
+++ b/oox/source/xls/externallinkfragment.cxx
@@ -0,0 +1,392 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: externallinkfragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/externallinkfragment.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/core/recordparser.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/sheetdatacontext.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XFastContextHandler;
+using ::oox::core::RecordContextRef;
+using ::oox::core::Relation;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+OoxExternalLinkFragment::OoxExternalLinkFragment( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath, ExternalLink& rExtLink ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath ),
+ mrExtLink( rExtLink ),
+ mnResultType( XML_TOKEN_INVALID )
+{
+}
+
+bool OoxExternalLinkFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nElement == XLS_TOKEN( externalLink ));
+ case XLS_TOKEN( externalLink ):
+ return (nElement == XLS_TOKEN( externalBook )) ||
+ (nElement == XLS_TOKEN( ddeLink )) ||
+ (nElement == XLS_TOKEN( oleLink ));
+ case XLS_TOKEN( externalBook ):
+ return (nElement == XLS_TOKEN( sheetNames )) ||
+ (nElement == XLS_TOKEN( definedNames )) ||
+ (nElement == XLS_TOKEN( sheetDataSet ));
+ case XLS_TOKEN( sheetNames ):
+ return (nElement == XLS_TOKEN( sheetName ));
+ case XLS_TOKEN( definedNames ):
+ return (nElement == XLS_TOKEN( definedName ));
+ case XLS_TOKEN( sheetDataSet ):
+ return (nElement == XLS_TOKEN( sheetData ));
+ case XLS_TOKEN( ddeLink ):
+ return (nElement == XLS_TOKEN( ddeItems ));
+ case XLS_TOKEN( ddeItems ):
+ return (nElement == XLS_TOKEN( ddeItem ));
+ case XLS_TOKEN( ddeItem ):
+ return (nElement == XLS_TOKEN( values ));
+ case XLS_TOKEN( values ):
+ return (nElement == XLS_TOKEN( value ));
+ case XLS_TOKEN( value ):
+ return (nElement == XLS_TOKEN( val ));
+ case XLS_TOKEN( oleLink ):
+ return (nElement == XLS_TOKEN( oleItems ));
+ case XLS_TOKEN( oleItems ):
+ return (nElement == XLS_TOKEN( oleItem ));
+ }
+ return false;
+}
+
+Reference< XFastContextHandler > OoxExternalLinkFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheetData ):
+ if( mrExtLink.getLinkType() == LINKTYPE_EXTERNAL )
+ {
+ sal_Int32 nSheet = mrExtLink.getSheetIndex( rAttribs.getInteger( XML_sheetId, -1 ) );
+ Reference< XFastContextHandler > xHandler;
+ ::rtl::Reference< OoxExternalSheetDataContext > xContext( new OoxExternalSheetDataContext( *this, SHEETTYPE_WORKSHEET, nSheet ) );
+ if( xContext->isValidSheet() )
+ xHandler.set( xContext.get() );
+ return xHandler;
+ }
+ break;
+ }
+ return this;
+}
+
+void OoxExternalLinkFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( externalBook ): mrExtLink.importExternalBook( getRelations(), rAttribs ); break;
+ case XLS_TOKEN( sheetName ): mrExtLink.importSheetName( rAttribs ); break;
+ case XLS_TOKEN( definedName ): mrExtLink.importDefinedName( rAttribs ); break;
+ case XLS_TOKEN( ddeLink ): mrExtLink.importDdeLink( rAttribs ); break;
+ case XLS_TOKEN( ddeItem ): mxExtName = mrExtLink.importDdeItem( rAttribs ); break;
+ case XLS_TOKEN( values ): if( mxExtName.get() ) mxExtName->importValues( rAttribs ); break;
+ case XLS_TOKEN( value ): mnResultType = rAttribs.getToken( XML_t, XML_n ); break;
+ case XLS_TOKEN( oleLink ): mrExtLink.importOleLink( getRelations(), rAttribs ); break;
+ case XLS_TOKEN( oleItem ): mxExtName = mrExtLink.importOleItem( rAttribs ); break;
+ }
+}
+
+void OoxExternalLinkFragment::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( val ):
+ maResultValue = rChars;
+ break;
+ case XLS_TOKEN( value ):
+ if( mxExtName.get() ) switch( mnResultType )
+ {
+ case XML_b:
+ mxExtName->appendResultValue( maResultValue.toDouble() );
+ break;
+ case XML_e:
+ mxExtName->appendResultValue( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( maResultValue ) ) );
+ break;
+ case XML_n:
+ mxExtName->appendResultValue( maResultValue.toDouble() );
+ break;
+ case XML_str:
+ mxExtName->appendResultValue( maResultValue );
+ break;
+ default:
+ mxExtName->appendResultValue( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) );
+ }
+ break;
+ }
+}
+
+bool OoxExternalLinkFragment::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ /* Weird things are going on in this fragment...
+
+ Without external names, several EXTSHEETDATA/EXTSHEETDATA_END contexts
+ contain the external cells. They are not preceded by a SHEETDATASET
+ context record, but a SHEETDATASET_END record occurs at the end of the
+ stream. In this case we have to start a SHEETDATASET context on-the-fly
+ to keep the context stack valid.
+ */
+ if( (getCurrentContext() == OOBIN_ID_EXTERNALBOOK) && (nRecId == OOBIN_ID_EXTSHEETDATA) )
+ getRecordParser().pushContext( OOBIN_ID_SHEETDATASET, this );
+
+ /* With external names, SHEETDATASET contexts are opened after each
+ external name, but not closed before a new external name starts. Here
+ we have to close the SHEETDATASET context before.
+ */
+ else if( (getCurrentContext() == OOBIN_ID_SHEETDATASET) && (nRecId != OOBIN_ID_EXTSHEETDATA) )
+ getRecordParser().popContext();
+
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nRecId == OOBIN_ID_EXTERNALBOOK);
+ case OOBIN_ID_EXTERNALBOOK:
+ return (nRecId == OOBIN_ID_EXTSHEETNAMES) ||
+ (nRecId == OOBIN_ID_EXTERNALNAME) ||
+ (nRecId == OOBIN_ID_EXTERNALNAMEFLAGS) ||
+ (nRecId == OOBIN_ID_SHEETDATASET) ||
+ (nRecId == OOBIN_ID_DDEITEMVALUES);
+ case OOBIN_ID_SHEETDATASET:
+ return (nRecId == OOBIN_ID_EXTSHEETDATA);
+ case OOBIN_ID_DDEITEMVALUES:
+ return (nRecId == OOBIN_ID_DDEITEM_BOOL) ||
+ (nRecId == OOBIN_ID_DDEITEM_DOUBLE) ||
+ (nRecId == OOBIN_ID_DDEITEM_ERROR) ||
+ (nRecId == OOBIN_ID_DDEITEM_STRING);
+ }
+ return false;
+}
+
+RecordContextRef OoxExternalLinkFragment::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm )
+{
+ switch( nRecId )
+ {
+ case OOBIN_ID_EXTSHEETDATA:
+ if( mrExtLink.getLinkType() == LINKTYPE_EXTERNAL )
+ {
+ sal_Int32 nSheet = mrExtLink.getSheetIndex( rStrm.readInt32() );
+ RecordContextRef xRecContext;
+ ::rtl::Reference< OoxExternalSheetDataContext > xContext( new OoxExternalSheetDataContext( *this, SHEETTYPE_WORKSHEET, nSheet ) );
+ if( xContext->isValidSheet() )
+ xRecContext.set( xContext.get() );
+ return xRecContext;
+ }
+ break;
+ }
+ return this;
+}
+
+void OoxExternalLinkFragment::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_EXTERNALBOOK: mrExtLink.importExternalBook( getRelations(), rStrm ); break;
+ case OOBIN_ID_EXTSHEETNAMES: mrExtLink.importExtSheetNames( rStrm ); break;
+ case OOBIN_ID_EXTERNALNAME: mxExtName = mrExtLink.importExternalName( rStrm ); break;
+ case OOBIN_ID_EXTERNALNAMEFLAGS: if( mxExtName.get() ) mxExtName->importExternalNameFlags( rStrm ); break;
+ case OOBIN_ID_DDEITEMVALUES: if( mxExtName.get() ) mxExtName->importDdeItemValues( rStrm ); break;
+ case OOBIN_ID_DDEITEM_BOOL: if( mxExtName.get() ) mxExtName->importDdeItemBool( rStrm ); break;
+ case OOBIN_ID_DDEITEM_DOUBLE: if( mxExtName.get() ) mxExtName->importDdeItemDouble( rStrm ); break;
+ case OOBIN_ID_DDEITEM_ERROR: if( mxExtName.get() ) mxExtName->importDdeItemError( rStrm ); break;
+ case OOBIN_ID_DDEITEM_STRING: if( mxExtName.get() ) mxExtName->importDdeItemString( rStrm ); break;
+ }
+}
+
+// ============================================================================
+
+BiffExternalLinkFragment::BiffExternalLinkFragment( const WorkbookHelper& rHelper, bool bImportDefNames ) :
+ BiffWorkbookFragmentBase( rHelper ),
+ mbImportDefNames( bImportDefNames )
+{
+}
+
+BiffExternalLinkFragment::~BiffExternalLinkFragment()
+{
+}
+
+bool BiffExternalLinkFragment::importFragment( BiffInputStream& rStrm )
+{
+ // process all record in this sheet fragment
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ {
+ if( isBofRecord( rStrm.getRecId() ) )
+ skipFragment( rStrm ); // skip unknown embedded fragments
+ else
+ importRecord( rStrm );
+ }
+ return rStrm.isValid() && (rStrm.getRecId() == BIFF_ID_EOF);
+}
+
+void BiffExternalLinkFragment::importRecord( BiffInputStream& rStrm )
+{
+ sal_uInt16 nRecId = rStrm.getRecId();
+ switch( getBiff() )
+ {
+ case BIFF2: switch( nRecId )
+ {
+ case BIFF2_ID_EXTERNALNAME: importExternalName( rStrm ); break;
+ case BIFF_ID_EXTERNSHEET: importExternSheet( rStrm ); break;
+ case BIFF2_ID_DEFINEDNAME: importDefinedName( rStrm ); break;
+ }
+ break;
+ case BIFF3: switch( nRecId )
+ {
+ case BIFF_ID_CRN: importCrn( rStrm ); break;
+ case BIFF3_ID_EXTERNALNAME: importExternalName( rStrm ); break;
+ case BIFF_ID_EXTERNSHEET: importExternSheet( rStrm ); break;
+ case BIFF3_ID_DEFINEDNAME: importDefinedName( rStrm ); break;
+ case BIFF_ID_XCT: importXct( rStrm ); break;
+ }
+ break;
+ case BIFF4: switch( nRecId )
+ {
+ case BIFF_ID_CRN: importCrn( rStrm ); break;
+ case BIFF3_ID_EXTERNALNAME: importExternalName( rStrm ); break;
+ case BIFF_ID_EXTERNSHEET: importExternSheet( rStrm ); break;
+ case BIFF3_ID_DEFINEDNAME: importDefinedName( rStrm ); break;
+ case BIFF_ID_XCT: importXct( rStrm ); break;
+ }
+ break;
+ case BIFF5: switch( nRecId )
+ {
+ case BIFF_ID_CRN: importCrn( rStrm ); break;
+ case BIFF5_ID_EXTERNALNAME: importExternalName( rStrm ); break;
+ case BIFF_ID_EXTERNSHEET: importExternSheet( rStrm ); break;
+ case BIFF5_ID_DEFINEDNAME: importDefinedName( rStrm ); break;
+ case BIFF_ID_XCT: importXct( rStrm ); break;
+ }
+ break;
+ case BIFF8: switch( nRecId )
+ {
+ case BIFF_ID_CRN: importCrn( rStrm ); break;
+ case BIFF_ID_EXTERNALBOOK: importExternalBook( rStrm ); break;
+ case BIFF5_ID_EXTERNALNAME: importExternalName( rStrm ); break;
+ case BIFF_ID_EXTERNSHEET: importExternSheet( rStrm ); break;
+ case BIFF5_ID_DEFINEDNAME: importDefinedName( rStrm ); break;
+ case BIFF_ID_XCT: importXct( rStrm ); break;
+ }
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+}
+
+void BiffExternalLinkFragment::finalizeImport()
+{
+ getDefinedNames().finalizeImport();
+}
+
+// private --------------------------------------------------------------------
+
+void BiffExternalLinkFragment::importExternSheet( BiffInputStream& rStrm )
+{
+ mxContext.reset();
+ if( getBiff() == BIFF8 )
+ getExternalLinks().importExternSheet8( rStrm );
+ else
+ mxExtLink = getExternalLinks().importExternSheet( rStrm );
+}
+
+void BiffExternalLinkFragment::importExternalBook( BiffInputStream& rStrm )
+{
+ mxContext.reset();
+ mxExtLink = getExternalLinks().importExternalBook( rStrm );
+}
+
+void BiffExternalLinkFragment::importExternalName( BiffInputStream& rStrm )
+{
+ if( mxExtLink.get() )
+ mxExtLink->importExternalName( rStrm );
+}
+
+void BiffExternalLinkFragment::importXct( BiffInputStream& rStrm )
+{
+ mxContext.reset();
+ if( mxExtLink.get() && (mxExtLink->getLinkType() == LINKTYPE_EXTERNAL) )
+ {
+ sal_Int32 nSheet = -1;
+ switch( getBiff() )
+ {
+ case BIFF2:
+ break;
+ case BIFF3:
+ case BIFF4:
+ case BIFF5:
+ nSheet = mxExtLink->getSheetIndex();
+ break;
+ case BIFF8:
+ rStrm.skip( 2 );
+ nSheet = mxExtLink->getSheetIndex( rStrm.readInt16() );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+
+ // create a sheet data context to import the CRN records and set the cached cell values
+ mxContext.reset( new BiffExternalSheetDataContext( *this, SHEETTYPE_WORKSHEET, nSheet ) );
+ if( !mxContext->isValidSheet() )
+ mxContext.reset();
+ }
+}
+
+void BiffExternalLinkFragment::importCrn( BiffInputStream& rStrm )
+{
+ if( mxContext.get() )
+ mxContext->importCrn( rStrm );
+}
+
+void BiffExternalLinkFragment::importDefinedName( BiffInputStream& rStrm )
+{
+ if( mbImportDefNames )
+ getDefinedNames().importDefinedName( rStrm );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx
new file mode 100644
index 000000000000..4c5cb1bdfabc
--- /dev/null
+++ b/oox/source/xls/formulabase.cxx
@@ -0,0 +1,1459 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: formulabase.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/formulabase.hxx"
+#include <map>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/SingleReference.hpp>
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/FormulaLanguage.hpp>
+#include <com/sun/star/sheet/FormulaMapGroup.hpp>
+#include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp>
+#include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUStringToOString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::SingleReference;
+using ::com::sun::star::sheet::ComplexReference;
+using ::com::sun::star::sheet::FormulaToken;
+using ::com::sun::star::sheet::FormulaOpCodeMapEntry;
+using ::com::sun::star::sheet::XSpreadsheetDocument;
+using ::com::sun::star::sheet::XFormulaOpCodeMapper;
+using ::com::sun::star::sheet::XFormulaTokens;
+using namespace ::com::sun::star::sheet::ReferenceFlags;
+
+namespace oox {
+namespace xls {
+
+// reference helpers ==========================================================
+
+BinSingleRef2d::BinSingleRef2d() :
+ mnCol( 0 ),
+ mnRow( 0 ),
+ mbColRel( false ),
+ mbRowRel( false )
+{
+}
+
+void BinSingleRef2d::setOobData( sal_uInt16 nCol, sal_Int32 nRow, bool bRelativeAsOffset )
+{
+ mnCol = nCol & OOBIN_TOK_REF_COLMASK;
+ mnRow = nRow & OOBIN_TOK_REF_ROWMASK;
+ mbColRel = getFlag( nCol, OOBIN_TOK_REF_COLREL );
+ mbRowRel = getFlag( nCol, OOBIN_TOK_REF_ROWREL );
+ if( bRelativeAsOffset && mbColRel && (mnCol > (OOBIN_TOK_REF_COLMASK >> 1)) )
+ mnCol -= (OOBIN_TOK_REF_COLMASK + 1);
+ if( bRelativeAsOffset && mbRowRel && (mnRow > (OOBIN_TOK_REF_ROWMASK >> 1)) )
+ mnRow -= (OOBIN_TOK_REF_ROWMASK + 1);
+}
+
+void BinSingleRef2d::setBiff2Data( sal_uInt8 nCol, sal_uInt16 nRow, bool bRelativeAsOffset )
+{
+ mnCol = nCol;
+ mnRow = nRow & BIFF_TOK_REF_ROWMASK;
+ mbColRel = getFlag( nRow, BIFF_TOK_REF_COLREL );
+ mbRowRel = getFlag( nRow, BIFF_TOK_REF_ROWREL );
+ if( bRelativeAsOffset && mbColRel && (mnCol >= 0x80) )
+ mnCol -= 0x100;
+ if( bRelativeAsOffset && mbRowRel && (mnRow > (BIFF_TOK_REF_ROWMASK >> 1)) )
+ mnRow -= (BIFF_TOK_REF_ROWMASK + 1);
+}
+
+void BinSingleRef2d::setBiff8Data( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelativeAsOffset )
+{
+ mnCol = nCol & BIFF_TOK_REF_COLMASK;
+ mnRow = nRow;
+ mbColRel = getFlag( nCol, BIFF_TOK_REF_COLREL );
+ mbRowRel = getFlag( nCol, BIFF_TOK_REF_ROWREL );
+ if( bRelativeAsOffset && mbColRel && (mnCol > (BIFF_TOK_REF_COLMASK >> 1)) )
+ mnCol -= (BIFF_TOK_REF_COLMASK + 1);
+ if( bRelativeAsOffset && mbRowRel && (mnRow >= 0x8000) )
+ mnRow -= 0x10000;
+}
+
+void BinSingleRef2d::readOobData( RecordInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_Int32 nRow;
+ sal_uInt16 nCol;
+ rStrm >> nRow >> nCol;
+ setOobData( nCol, nRow, bRelativeAsOffset );
+}
+
+void BinSingleRef2d::readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_uInt16 nRow;
+ sal_uInt8 nCol;
+ rStrm >> nRow >> nCol;
+ setBiff2Data( nCol, nRow, bRelativeAsOffset );
+}
+
+void BinSingleRef2d::readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_uInt16 nRow, nCol;
+ rStrm >> nRow >> nCol;
+ setBiff8Data( nCol, nRow, bRelativeAsOffset );
+}
+
+// ----------------------------------------------------------------------------
+
+void BinComplexRef2d::readOobData( RecordInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_Int32 nRow1, nRow2;
+ sal_uInt16 nCol1, nCol2;
+ rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+ maRef1.setOobData( nCol1, nRow1, bRelativeAsOffset );
+ maRef2.setOobData( nCol2, nRow2, bRelativeAsOffset );
+}
+
+void BinComplexRef2d::readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_uInt16 nRow1, nRow2;
+ sal_uInt8 nCol1, nCol2;
+ rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+ maRef1.setBiff2Data( nCol1, nRow1, bRelativeAsOffset );
+ maRef2.setBiff2Data( nCol2, nRow2, bRelativeAsOffset );
+}
+
+void BinComplexRef2d::readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_uInt16 nRow1, nRow2, nCol1, nCol2;
+ rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+ maRef1.setBiff8Data( nCol1, nRow1, bRelativeAsOffset );
+ maRef2.setBiff8Data( nCol2, nRow2, bRelativeAsOffset );
+}
+
+// function data ==============================================================
+
+namespace {
+
+const size_t FUNCINFO_CLASSCOUNT = 5; /// Number of token class entries.
+
+const sal_uInt8 FUNCFLAG_VOLATILE = 0x01; /// Result is volatile (e.g. NOW() function).
+const sal_uInt8 FUNCFLAG_IMPORTONLY = 0x02; /// Only used in import filter.
+const sal_uInt8 FUNCFLAG_EXPORTONLY = 0x04; /// Only used in export filter.
+const sal_uInt8 FUNCFLAG_MACROCALL = 0x08; /// Function is simulated by macro call in Excel.
+const sal_uInt8 FUNCFLAG_EXTERNAL = 0x10; /// Function is external in Calc.
+
+typedef ::boost::shared_ptr< FunctionInfo > FunctionInfoRef;
+
+struct FunctionData
+{
+ const sal_Char* mpcOdfFuncName; /// ODF function name.
+ const sal_Char* mpcOoxFuncName; /// OOXML function name.
+ sal_uInt16 mnOobFuncId; /// OOBIN function identifier.
+ sal_uInt16 mnBiffFuncId; /// BIFF function identifier.
+ sal_uInt8 mnMinParamCount; /// Minimum number of parameters.
+ sal_uInt8 mnMaxParamCount; /// Maximum number of parameters.
+ sal_uInt8 mnRetClass; /// BIFF token class of the return value.
+ sal_uInt8 mpnParamClass[ FUNCINFO_CLASSCOUNT ]; /// Expected BIFF token classes of parameters.
+ sal_uInt8 mnFlags; /// Additional flags.
+
+ inline bool isSupported( bool bImportFilter ) const;
+};
+
+inline bool FunctionData::isSupported( bool bImportFilter ) const
+{
+ /* For import filters: the FUNCFLAG_EXPORTONLY flag must not be set,
+ for export filters: the FUNCFLAG_IMPORTONLY flag must not be set. */
+ return !getFlag( mnFlags, bImportFilter ? FUNCFLAG_EXPORTONLY : FUNCFLAG_IMPORTONLY );
+}
+
+const sal_uInt8 R = BIFF_TOKCLASS_REF;
+const sal_uInt8 V = BIFF_TOKCLASS_VAL;
+const sal_uInt8 A = BIFF_TOKCLASS_ARR;
+const sal_uInt8 ER = FUNCINFO_PARAM_EXCELONLY | BIFF_TOKCLASS_REF;
+const sal_uInt8 EV = FUNCINFO_PARAM_EXCELONLY | BIFF_TOKCLASS_VAL;
+const sal_uInt8 EA = FUNCINFO_PARAM_EXCELONLY | BIFF_TOKCLASS_ARR;
+const sal_uInt8 C = FUNCINFO_PARAM_CALCONLY;
+const sal_uInt8 I = FUNCINFO_PARAM_INVALID;
+const sal_uInt16 NOID = SAL_MAX_UINT16;
+const sal_uInt8 MX = SAL_MAX_UINT8;
+
+/** Functions new in BIFF2. */
+static const FunctionData saFuncTableBiff2[] =
+{
+ { "COUNT", "COUNT", 0, 0, 0, MX, V, { R }, 0 },
+ { "IF", "IF", 1, 1, 2, 3, R, { V, R }, 0 },
+ { "ISNA", "ISNA", 2, 2, 1, 1, V, { V }, 0 },
+ { "ISERROR", "ISERROR", 3, 3, 1, 1, V, { V }, 0 },
+ { "SUM", "SUM", 4, 4, 0, MX, V, { R }, 0 },
+ { "AVERAGE", "AVERAGE", 5, 5, 1, MX, V, { R }, 0 },
+ { "MIN", "MIN", 6, 6, 1, MX, V, { R }, 0 },
+ { "MAX", "MAX", 7, 7, 1, MX, V, { R }, 0 },
+ { "ROW", "ROW", 8, 8, 0, 1, V, { R }, 0 },
+ { "COLUMN", "COLUMN", 9, 9, 0, 1, V, { R }, 0 },
+ { "NA", "NA", 10, 10, 0, 0, V, {}, 0 },
+ { "NPV", "NPV", 11, 11, 2, MX, V, { V, R }, 0 },
+ { "STDEV", "STDEV", 12, 12, 1, MX, V, { R }, 0 },
+ { "DOLLAR", "DOLLAR", 13, 13, 1, 2, V, { V }, 0 },
+ { "FIXED", "FIXED", 14, 14, 1, 2, V, { V, V, C, I }, 0 },
+ { "SIN", "SIN", 15, 15, 1, 1, V, { V }, 0 },
+ { "COS", "COS", 16, 16, 1, 1, V, { V }, 0 },
+ { "TAN", "TAN", 17, 17, 1, 1, V, { V }, 0 },
+ { "COT", "TAN", 17, 17, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY },
+ { "ATAN", "ATAN", 18, 18, 1, 1, V, { V }, 0 },
+ { "ACOT", "ATAN", 18, 18, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY },
+ { "PI", "PI", 19, 19, 0, 0, V, {}, 0 },
+ { "SQRT", "SQRT", 20, 20, 1, 1, V, { V }, 0 },
+ { "EXP", "EXP", 21, 21, 1, 1, V, { V }, 0 },
+ { "LN", "LN", 22, 22, 1, 1, V, { V }, 0 },
+ { "LOG10", "LOG10", 23, 23, 1, 1, V, { V }, 0 },
+ { "ABS", "ABS", 24, 24, 1, 1, V, { V }, 0 },
+ { "INT", "INT", 25, 25, 1, 1, V, { V }, 0 },
+ { "SIGN", "SIGN", 26, 26, 1, 1, V, { V }, 0 },
+ { "ROUND", "ROUND", 27, 27, 2, 2, V, { V }, 0 },
+ { "LOOKUP", "LOOKUP", 28, 28, 2, 3, V, { V, R }, 0 },
+ { "INDEX", "INDEX", 29, 29, 2, 4, R, { R, V }, 0 },
+ { "REPT", "REPT", 30, 30, 2, 2, V, { V }, 0 },
+ { "MID", "MID", 31, 31, 3, 3, V, { V }, 0 },
+ { "LEN", "LEN", 32, 32, 1, 1, V, { V }, 0 },
+ { "VALUE", "VALUE", 33, 33, 1, 1, V, { V }, 0 },
+ { "TRUE", "TRUE", 34, 34, 0, 0, V, {}, 0 },
+ { "FALSE", "FALSE", 35, 35, 0, 0, V, {}, 0 },
+ { "AND", "AND", 36, 36, 1, MX, V, { R }, 0 },
+ { "OR", "OR", 37, 37, 1, MX, V, { R }, 0 },
+ { "NOT", "NOT", 38, 38, 1, 1, V, { V }, 0 },
+ { "MOD", "MOD", 39, 39, 2, 2, V, { V }, 0 },
+ { "DCOUNT", "DCOUNT", 40, 40, 3, 3, V, { R }, 0 },
+ { "DSUM", "DSUM", 41, 41, 3, 3, V, { R }, 0 },
+ { "DAVERAGE", "DAVERAGE", 42, 42, 3, 3, V, { R }, 0 },
+ { "DMIN", "DMIN", 43, 43, 3, 3, V, { R }, 0 },
+ { "DMAX", "DMAX", 44, 44, 3, 3, V, { R }, 0 },
+ { "DSTDEV", "DSTDEV", 45, 45, 3, 3, V, { R }, 0 },
+ { "VAR", "VAR", 46, 46, 1, MX, V, { R }, 0 },
+ { "DVAR", "DVAR", 47, 47, 3, 3, V, { R }, 0 },
+ { "TEXT", "TEXT", 48, 48, 2, 2, V, { V }, 0 },
+ { "LINEST", "LINEST", 49, 49, 1, 2, A, { R, R, C, C, I }, 0 },
+ { "TREND", "TREND", 50, 50, 1, 3, A, { R, R, R, C, I }, 0 },
+ { "LOGEST", "LOGEST", 51, 51, 1, 2, A, { R, R, C, C, I }, 0 },
+ { "GROWTH", "GROWTH", 52, 52, 1, 3, A, { R, R, R, C, I }, 0 },
+ { "PV", "PV", 56, 56, 3, 5, V, { V }, 0 },
+ { "FV", "FV", 57, 57, 3, 5, V, { V }, 0 },
+ { "NPER", "NPER", 58, 58, 3, 5, V, { V }, 0 },
+ { "PMT", "PMT", 59, 59, 3, 5, V, { V }, 0 },
+ { "RATE", "RATE", 60, 60, 3, 6, V, { V }, 0 },
+ { "MIRR", "MIRR", 61, 61, 3, 3, V, { R, V }, 0 },
+ { "IRR", "IRR", 62, 62, 1, 2, V, { R, V }, 0 },
+ { "RAND", "RAND", 63, 63, 0, 0, V, {}, FUNCFLAG_VOLATILE },
+ { "MATCH", "MATCH", 64, 64, 2, 3, V, { V, R }, 0 },
+ { "DATE", "DATE", 65, 65, 3, 3, V, { V }, 0 },
+ { "TIME", "TIME", 66, 66, 3, 3, V, { V }, 0 },
+ { "DAY", "DAY", 67, 67, 1, 1, V, { V }, 0 },
+ { "MONTH", "MONTH", 68, 68, 1, 1, V, { V }, 0 },
+ { "YEAR", "YEAR", 69, 69, 1, 1, V, { V }, 0 },
+ { "WEEKDAY", "WEEKDAY", 70, 70, 1, 1, V, { V, C, I }, 0 },
+ { "HOUR", "HOUR", 71, 71, 1, 1, V, { V }, 0 },
+ { "MINUTE", "MINUTE", 72, 72, 1, 1, V, { V }, 0 },
+ { "SECOND", "SECOND", 73, 73, 1, 1, V, { V }, 0 },
+ { "NOW", "NOW", 74, 74, 0, 0, V, {}, FUNCFLAG_VOLATILE },
+ { "AREAS", "AREAS", 75, 75, 1, 1, V, { R }, 0 },
+ { "ROWS", "ROWS", 76, 76, 1, 1, V, { R }, 0 },
+ { "COLUMNS", "COLUMNS", 77, 77, 1, 1, V, { R }, 0 },
+ { "OFFSET", "OFFSET", 78, 78, 3, 5, R, { R, V }, FUNCFLAG_VOLATILE },
+ { "SEARCH", "SEARCH", 82, 82, 2, 3, V, { V }, 0 },
+ { "TRANSPOSE", "TRANSPOSE", 83, 83, 1, 1, A, { A }, 0 },
+ { "TYPE", "TYPE", 86, 86, 1, 1, V, { V }, 0 },
+ { "ATAN2", "ATAN2", 97, 97, 2, 2, V, { V }, 0 },
+ { "ASIN", "ASIN", 98, 98, 1, 1, V, { V }, 0 },
+ { "ACOS", "ACOS", 99, 99, 1, 1, V, { V }, 0 },
+ { "CHOOSE", "CHOOSE", 100, 100, 2, MX, R, { V, R }, 0 },
+ { "HLOOKUP", "HLOOKUP", 101, 101, 3, 3, V, { V, R, R, C, I }, 0 },
+ { "VLOOKUP", "VLOOKUP", 102, 102, 3, 3, V, { V, R, R, C, I }, 0 },
+ { "ISREF", "ISREF", 105, 105, 1, 1, V, { R }, 0 },
+ { "LOG", "LOG", 109, 109, 1, 2, V, { V }, 0 },
+ { "CHAR", "CHAR", 111, 111, 1, 1, V, { V }, 0 },
+ { "LOWER", "LOWER", 112, 112, 1, 1, V, { V }, 0 },
+ { "UPPER", "UPPER", 113, 113, 1, 1, V, { V }, 0 },
+ { "PROPER", "PROPER", 114, 114, 1, 1, V, { V }, 0 },
+ { "LEFT", "LEFT", 115, 115, 1, 2, V, { V }, 0 },
+ { "RIGHT", "RIGHT", 116, 116, 1, 2, V, { V }, 0 },
+ { "EXACT", "EXACT", 117, 117, 2, 2, V, { V }, 0 },
+ { "TRIM", "TRIM", 118, 118, 1, 1, V, { V }, 0 },
+ { "REPLACE", "REPLACE", 119, 119, 4, 4, V, { V }, 0 },
+ { "SUBSTITUTE", "SUBSTITUTE", 120, 120, 3, 4, V, { V }, 0 },
+ { "CODE", "CODE", 121, 121, 1, 1, V, { V }, 0 },
+ { "FIND", "FIND", 124, 124, 2, 3, V, { V }, 0 },
+ { "CELL", "CELL", 125, 125, 1, 2, V, { V, R }, FUNCFLAG_VOLATILE },
+ { "ISERR", "ISERR", 126, 126, 1, 1, V, { V }, 0 },
+ { "ISTEXT", "ISTEXT", 127, 127, 1, 1, V, { V }, 0 },
+ { "ISNUMBER", "ISNUMBER", 128, 128, 1, 1, V, { V }, 0 },
+ { "ISBLANK", "ISBLANK", 129, 129, 1, 1, V, { V }, 0 },
+ { "T", "T", 130, 130, 1, 1, V, { R }, 0 },
+ { "N", "N", 131, 131, 1, 1, V, { R }, 0 },
+ { "DATEVALUE", "DATEVALUE", 140, 140, 1, 1, V, { V }, 0 },
+ { "TIMEVALUE", "TIMEVALUE", 141, 141, 1, 1, V, { V }, 0 },
+ { "SLN", "SLN", 142, 142, 3, 3, V, { V }, 0 },
+ { "SYD", "SYD", 143, 143, 4, 4, V, { V }, 0 },
+ { "DDB", "DDB", 144, 144, 4, 5, V, { V }, 0 },
+ { "INDIRECT", "INDIRECT", 148, 148, 1, 2, R, { V, EV, I }, FUNCFLAG_VOLATILE },
+ { "CLEAN", "CLEAN", 162, 162, 1, 1, V, { V }, 0 },
+ { "MDETERM", "MDETERM", 163, 163, 1, 1, V, { A }, 0 },
+ { "MINVERSE", "MINVERSE", 164, 164, 1, 1, A, { A }, 0 },
+ { "MMULT", "MMULT", 165, 165, 2, 2, A, { A }, 0 },
+ { "IPMT", "IPMT", 167, 167, 4, 6, V, { V }, 0 },
+ { "PPMT", "PPMT", 168, 168, 4, 6, V, { V }, 0 },
+ { "COUNTA", "COUNTA", 169, 169, 0, MX, V, { R }, 0 },
+ { "PRODUCT", "PRODUCT", 183, 183, 0, MX, V, { R }, 0 },
+ { "FACT", "FACT", 184, 184, 1, 1, V, { V }, 0 },
+ { "DPRODUCT", "DPRODUCT", 189, 189, 3, 3, V, { R }, 0 },
+ { "ISNONTEXT", "ISNONTEXT", 190, 190, 1, 1, V, { V }, 0 },
+ { "STDEVP", "STDEVP", 193, 193, 1, MX, V, { R }, 0 },
+ { "VARP", "VARP", 194, 194, 1, MX, V, { R }, 0 },
+ { "DSTDEVP", "DSTDEVP", 195, 195, 3, 3, V, { R }, 0 },
+ { "DVARP", "DVARP", 196, 196, 3, 3, V, { R }, 0 },
+ { "TRUNC", "TRUNC", 197, 197, 1, 1, V, { V, C, I }, 0 },
+ { "ISLOGICAL", "ISLOGICAL", 198, 198, 1, 1, V, { V }, 0 },
+ { "DCOUNTA", "DCOUNTA", 199, 199, 3, 3, V, { R }, 0 },
+ { 0, 0, 255, 255, 1, MX, R, { ER, R }, FUNCFLAG_IMPORTONLY } // EXTERNAL
+};
+
+/** Functions new in BIFF3. */
+static const FunctionData saFuncTableBiff3[] =
+{
+ { "LINEST", "LINEST", 49, 49, 1, 4, A, { R, R, V, V }, 0 }, // BIFF2: 1-2, BIFF3: 1-4,
+ { "TREND", "TREND", 50, 50, 1, 4, A, { R, R, R, V }, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { "LOGEST", "LOGEST", 51, 51, 1, 4, A, { R, R, V, V }, 0 }, // BIFF2: 1-2, BIFF3: 1-4,
+ { "GROWTH", "GROWTH", 52, 52, 1, 4, A, { R, R, R, V }, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { "TRUNC", "TRUNC", 197, 197, 1, 2, V, { V }, 0 }, // BIFF2: 1, BIFF3: 1-2
+ { "DOLLAR", "USDOLLAR", 204, 204, 1, 2, V, { V }, FUNCFLAG_IMPORTONLY },
+ { 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { V }, 0 },
+ { 0/*"SEARCH"*/, "SEARCHB", 206, 206, 2, 3, V, { V }, 0 },
+ { 0/*"REPLACE"*/, "REPLACEB", 207, 207, 4, 4, V, { V }, 0 },
+ { 0/*"LEFT"*/, "LEFTB", 208, 208, 1, 2, V, { V }, 0 },
+ { 0/*"RIGHT"*/, "RIGHTB", 209, 209, 1, 2, V, { V }, 0 },
+ { 0/*"MID"*/, "MIDB", 210, 210, 3, 3, V, { V }, 0 },
+ { 0/*"LEN"*/, "LENB", 211, 211, 1, 1, V, { V }, 0 },
+ { "ROUNDUP", "ROUNDUP", 212, 212, 2, 2, V, { V }, 0 },
+ { "ROUNDDOWN", "ROUNDDOWN", 213, 213, 2, 2, V, { V }, 0 },
+ { "ASC", "ASC", 214, 214, 1, 1, V, { V }, 0 },
+ { "JIS", "DBCS", 215, 215, 1, 1, V, { V }, 0 },
+ { "ADDRESS", "ADDRESS", 219, 219, 2, 5, V, { V, V, V, EV, V }, 0 },
+ { "DAYS360", "DAYS360", 220, 220, 2, 2, V, { V, V, C, I }, 0 },
+ { "TODAY", "TODAY", 221, 221, 0, 0, V, {}, FUNCFLAG_VOLATILE },
+ { "VDB", "VDB", 222, 222, 5, 7, V, { V }, 0 },
+ { "MEDIAN", "MEDIAN", 227, 227, 1, MX, V, { R }, 0 },
+ { "SUMPRODUCT", "SUMPRODUCT", 228, 228, 1, MX, V, { A }, 0 },
+ { "SINH", "SINH", 229, 229, 1, 1, V, { V }, 0 },
+ { "COSH", "COSH", 230, 230, 1, 1, V, { V }, 0 },
+ { "TANH", "TANH", 231, 231, 1, 1, V, { V }, 0 },
+ { "COTH", "TANH", 231, 231, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY },
+ { "ASINH", "ASINH", 232, 232, 1, 1, V, { V }, 0 },
+ { "ACOSH", "ACOSH", 233, 233, 1, 1, V, { V }, 0 },
+ { "ATANH", "ATANH", 234, 234, 1, 1, V, { V }, 0 },
+ { "ACOTH", "ATANH", 234, 234, 1, 1, V, { V }, FUNCFLAG_EXPORTONLY },
+ { "DGET", "DGET", 235, 235, 3, 3, V, { R }, 0 },
+ { "INFO", "INFO", 244, 244, 1, 1, V, { V }, FUNCFLAG_VOLATILE }
+};
+
+/** Functions new in BIFF4. */
+static const FunctionData saFuncTableBiff4[] =
+{
+ { "FIXED", "FIXED", 14, 14, 1, 3, V, { V }, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
+ { "RANK", "RANK", 216, 216, 2, 3, V, { V, R, V }, 0 },
+ { "DB", "DB", 247, 247, 4, 5, V, { V }, 0 },
+ { "FREQUENCY", "FREQUENCY", 252, 252, 2, 2, A, { R }, 0 },
+ { "ERROR.TYPE", "ERROR.TYPE", 261, 261, 1, 1, V, { V }, 0 },
+ { "AVEDEV", "AVEDEV", 269, 269, 1, MX, V, { R }, 0 },
+ { "BETADIST", "BETADIST", 270, 270, 3, 5, V, { V }, 0 },
+ { "GAMMALN", "GAMMALN", 271, 271, 1, 1, V, { V }, 0 },
+ { "BETAINV", "BETAINV", 272, 272, 3, 5, V, { V }, 0 },
+ { "BINOMDIST", "BINOMDIST", 273, 273, 4, 4, V, { V }, 0 },
+ { "LEGACY.CHIDIST", "CHIDIST", 274, 274, 2, 2, V, { V }, 0 },
+ { "LEGACY.CHIINV", "CHIINV", 275, 275, 2, 2, V, { V }, 0 },
+ { "COMBIN", "COMBIN", 276, 276, 2, 2, V, { V }, 0 },
+ { "CONFIDENCE", "CONFIDENCE", 277, 277, 3, 3, V, { V }, 0 },
+ { "CRITBINOM", "CRITBINOM", 278, 278, 3, 3, V, { V }, 0 },
+ { "EVEN", "EVEN", 279, 279, 1, 1, V, { V }, 0 },
+ { "EXPONDIST", "EXPONDIST", 280, 280, 3, 3, V, { V }, 0 },
+ { "LEGACY.FDIST", "FDIST", 281, 281, 3, 3, V, { V }, 0 },
+ { "LEGACY.FINV", "FINV", 282, 282, 3, 3, V, { V }, 0 },
+ { "FISHER", "FISHER", 283, 283, 1, 1, V, { V }, 0 },
+ { "FISHERINV", "FISHERINV", 284, 284, 1, 1, V, { V }, 0 },
+ { "FLOOR", "FLOOR", 285, 285, 2, 2, V, { V, V, C, I }, 0 },
+ { "GAMMADIST", "GAMMADIST", 286, 286, 4, 4, V, { V }, 0 },
+ { "GAMMAINV", "GAMMAINV", 287, 287, 3, 3, V, { V }, 0 },
+ { "CEILING", "CEILING", 288, 288, 2, 2, V, { V, V, C, I }, 0 },
+ { "HYPGEOMDIST", "HYPGEOMDIST", 289, 289, 4, 4, V, { V }, 0 },
+ { "LOGNORMDIST", "LOGNORMDIST", 290, 290, 3, 3, V, { V }, 0 },
+ { "LOGINV", "LOGINV", 291, 291, 3, 3, V, { V }, 0 },
+ { "NEGBINOMDIST", "NEGBINOMDIST", 292, 292, 3, 3, V, { V }, 0 },
+ { "NORMDIST", "NORMDIST", 293, 293, 4, 4, V, { V }, 0 },
+ { "LEGACY.NORMSDIST", "NORMSDIST", 294, 294, 1, 1, V, { V }, 0 },
+ { "NORMINV", "NORMINV", 295, 295, 3, 3, V, { V }, 0 },
+ { "LEGACY.NORMSINV", "NORMSINV", 296, 296, 1, 1, V, { V }, 0 },
+ { "STANDARDIZE", "STANDARDIZE", 297, 297, 3, 3, V, { V }, 0 },
+ { "ODD", "ODD", 298, 298, 1, 1, V, { V }, 0 },
+ { "PERMUT", "PERMUT", 299, 299, 2, 2, V, { V }, 0 },
+ { "POISSON", "POISSON", 300, 300, 3, 3, V, { V }, 0 },
+ { "TDIST", "TDIST", 301, 301, 3, 3, V, { V }, 0 },
+ { "WEIBULL", "WEIBULL", 302, 302, 4, 4, V, { V }, 0 },
+ { "SUMXMY2", "SUMXMY2", 303, 303, 2, 2, V, { A }, 0 },
+ { "SUMX2MY2", "SUMX2MY2", 304, 304, 2, 2, V, { A }, 0 },
+ { "SUMX2PY2", "SUMX2PY2", 305, 305, 2, 2, V, { A }, 0 },
+ { "LEGACY.CHITEST", "CHITEST", 306, 306, 2, 2, V, { A }, 0 },
+ { "CORREL", "CORREL", 307, 307, 2, 2, V, { A }, 0 },
+ { "COVAR", "COVAR", 308, 308, 2, 2, V, { A }, 0 },
+ { "FORECAST", "FORECAST", 309, 309, 3, 3, V, { V, A }, 0 },
+ { "FTEST", "FTEST", 310, 310, 2, 2, V, { A }, 0 },
+ { "INTERCEPT", "INTERCEPT", 311, 311, 2, 2, V, { A }, 0 },
+ { "PEARSON", "PEARSON", 312, 312, 2, 2, V, { A }, 0 },
+ { "RSQ", "RSQ", 313, 313, 2, 2, V, { A }, 0 },
+ { "STEYX", "STEYX", 314, 314, 2, 2, V, { A }, 0 },
+ { "SLOPE", "SLOPE", 315, 315, 2, 2, V, { A }, 0 },
+ { "TTEST", "TTEST", 316, 316, 4, 4, V, { A, A, V }, 0 },
+ { "PROB", "PROB", 317, 317, 3, 4, V, { A, A, V }, 0 },
+ { "DEVSQ", "DEVSQ", 318, 318, 1, MX, V, { R }, 0 },
+ { "GEOMEAN", "GEOMEAN", 319, 319, 1, MX, V, { R }, 0 },
+ { "HARMEAN", "HARMEAN", 320, 320, 1, MX, V, { R }, 0 },
+ { "SUMSQ", "SUMSQ", 321, 321, 0, MX, V, { R }, 0 },
+ { "KURT", "KURT", 322, 322, 1, MX, V, { R }, 0 },
+ { "SKEW", "SKEW", 323, 323, 1, MX, V, { R }, 0 },
+ { "ZTEST", "ZTEST", 324, 324, 2, 3, V, { R, V }, 0 },
+ { "LARGE", "LARGE", 325, 325, 2, 2, V, { R, V }, 0 },
+ { "SMALL", "SMALL", 326, 326, 2, 2, V, { R, V }, 0 },
+ { "QUARTILE", "QUARTILE", 327, 327, 2, 2, V, { R, V }, 0 },
+ { "PERCENTILE", "PERCENTILE", 328, 328, 2, 2, V, { R, V }, 0 },
+ { "PERCENTRANK", "PERCENTRANK", 329, 329, 2, 3, V, { R, V, EV, I }, 0 },
+ { "MODE", "MODE", 330, 330, 1, MX, V, { A }, 0 },
+ { "TRIMMEAN", "TRIMMEAN", 331, 331, 2, 2, V, { R, V }, 0 },
+ { "TINV", "TINV", 332, 332, 2, 2, V, { V }, 0 },
+
+ // *** Analysis add-in ***
+
+ { "HEX2BIN", "HEX2BIN", 384, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "HEX2DEC", "HEX2DEC", 385, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "HEX2OCT", "HEX2OCT", 386, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DEC2BIN", "DEC2BIN", 387, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DEC2HEX", "DEC2HEX", 388, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DEC2OCT", "DEC2OCT", 389, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "OCT2BIN", "OCT2BIN", 390, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "OCT2HEX", "OCT2HEX", 391, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "OCT2DEC", "OCT2DEC", 392, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "BIN2DEC", "BIN2DEC", 393, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "BIN2OCT", "BIN2OCT", 394, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "BIN2HEX", "BIN2HEX", 395, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMSUB", "IMSUB", 396, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMDIV", "IMDIV", 397, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMPOWER", "IMPOWER", 398, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMABS", "IMABS", 399, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMSQRT", "IMSQRT", 400, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMLN", "IMLN", 401, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMLOG2", "IMLOG2", 402, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMLOG10", "IMLOG10", 403, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMSIN", "IMSIN", 404, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMCOS", "IMCOS", 405, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMEXP", "IMEXP", 406, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMARGUMENT", "IMARGUMENT", 407, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMCONJUGATE", "IMCONJUGATE", 408, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMAGINARY", "IMAGINARY", 409, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMREAL", "IMREAL", 410, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "COMPLEX", "COMPLEX", 411, NOID, 2, 3, V, { V }, FUNCFLAG_EXTERNAL },
+ { "IMSUM", "IMSUM", 412, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL },
+ { "IMPRODUCT", "IMPRODUCT", 413, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL },
+ { "SERIESSUM", "SERIESSUM", 414, NOID, 4, 4, V, { V, V, V, R }, FUNCFLAG_EXTERNAL },
+ { "FACTDOUBLE", "FACTDOUBLE", 415, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "SQRTPI", "SQRTPI", 416, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "QUOTIENT", "QUOTIENT", 417, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DELTA", "DELTA", 418, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "GESTEP", "GESTEP", 419, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ISEVEN", "ISEVEN", 420, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "ISODD", "ISODD", 421, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "MROUND", "MROUND", 422, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ERF", "ERF", 423, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ERFC", "ERFC", 424, NOID, 1, 1, V, { V }, FUNCFLAG_EXTERNAL },
+ { "BESSELJ", "BESSELJ", 425, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "BESSELK", "BESSELK", 426, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "BESSELY", "BESSELY", 427, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "BESSELI", "BESSELI", 428, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "XIRR", "XIRR", 429, NOID, 2, 3, V, { A, R, V }, FUNCFLAG_EXTERNAL },
+ { "XNPV", "XNPV", 430, NOID, 3, 3, V, { V, A, R }, FUNCFLAG_EXTERNAL },
+ { "PRICEMAT", "PRICEMAT", 431, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL },
+ { "YIELDMAT", "YIELDMAT", 432, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL },
+ { "INTRATE", "INTRATE", 433, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL },
+ { "RECEIVED", "RECEIVED", 434, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DISC", "DISC", 435, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL },
+ { "PRICEDISC", "PRICEDISC", 436, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL },
+ { "YIELDDISC", "YIELDDISC", 437, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL },
+ { "TBILLEQ", "TBILLEQ", 438, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL },
+ { "TBILLPRICE", "TBILLPRICE", 439, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL },
+ { "TBILLYIELD", "TBILLYIELD", 440, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL },
+ { "PRICE", "PRICE", 441, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL },
+ { "YIELD", "YIELD", 442, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DOLLARDE", "DOLLARDE", 443, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DOLLARFR", "DOLLARFR", 444, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "NOMINAL", "NOMINAL", 445, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "EFFECT", "EFFECT", 446, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "CUMPRINC", "CUMPRINC", 447, NOID, 6, 6, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "CUMIPMT", "CUMIPMT", 448, NOID, 6, 6, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "EDATE", "EDATE", 449, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "EOMONTH", "EOMONTH", 450, NOID, 2, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "YEARFRAC", "YEARFRAC", 451, NOID, 2, 3, V, { V }, FUNCFLAG_EXTERNAL },
+ { "COUPDAYBS", "COUPDAYBS", 452, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL },
+ { "COUPDAYS", "COUPDAYS", 453, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL },
+ { "COUPDAYSNC", "COUPDAYSNC", 454, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL },
+ { "COUPNCD", "COUPNCD", 455, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL },
+ { "COUPNUM", "COUPNUM", 456, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL },
+ { "COUPPCD", "COUPPCD", 457, NOID, 3, 4, V, { V }, FUNCFLAG_EXTERNAL },
+ { "DURATION", "DURATION", 458, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "MDURATION", "MDURATION", 459, NOID, 5, 6, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ODDLPRICE", "ODDLPRICE", 460, NOID, 7, 8, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ODDLYIELD", "ODDLYIELD", 461, NOID, 8, 9, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ODDFPRICE", "ODDFPRICE", 462, NOID, 8, 9, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ODDFYIELD", "ODDFYIELD", 463, NOID, 8, 9, V, { V }, FUNCFLAG_EXTERNAL },
+ { "RANDBETWEEN", "RANDBETWEEN", 464, NOID, 2, 2, V, {}, FUNCFLAG_VOLATILE | FUNCFLAG_EXTERNAL },
+ { "WEEKNUM", "WEEKNUM", 465, NOID, 1, 2, V, { V }, FUNCFLAG_EXTERNAL },
+ { "AMORDEGRC", "AMORDEGRC", 466, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL },
+ { "AMORLINC", "AMORLINC", 467, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL },
+ { "CONVERT", "CONVERT", 468, NOID, 3, 3, V, { V }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "ACCRINT", "ACCRINT", 469, NOID, 6, 7, V, { V }, FUNCFLAG_EXTERNAL },
+ { "ACCRINTM", "ACCRINTM", 470, NOID, 4, 5, V, { V }, FUNCFLAG_EXTERNAL },
+ { "WORKDAY", "WORKDAY", 471, NOID, 2, 3, V, { V, V, A, C, I }, FUNCFLAG_EXTERNAL },
+ { "NETWORKDAYS", "NETWORKDAYS", 472, NOID, 2, 3, V, { V, V, A, C, I }, FUNCFLAG_EXTERNAL },
+ { "GCD", "GCD", 473, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "MULTINOMIAL", "MULTINOMIAL", 474, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL },
+ { "LCM", "LCM", 475, NOID, 1, MX, V, { R }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "FVSCHEDULE", "FVSCHEDULE", 476, NOID, 2, 2, V, { V, A }, FUNCFLAG_EXTERNAL }
+// { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { V }, FUNCFLAG_EXTERNAL }, // Euro conversion add-in
+};
+
+/** Functions new in BIFF5/BIFF7. */
+static const FunctionData saFuncTableBiff5[] =
+{
+ { "WEEKDAY", "WEEKDAY", 70, 70, 1, 2, V, { V }, 0 }, // BIFF2-4: 1, BIFF5: 1-2
+ { "HLOOKUP", "HLOOKUP", 101, 101, 3, 4, V, { V, R, R, V }, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { "VLOOKUP", "VLOOKUP", 102, 102, 3, 4, V, { V, R, R, V }, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { "DAYS360", "DAYS360", 220, 220, 2, 3, V, { V }, 0 }, // BIFF3-4: 2, BIFF5: 2-3
+ { 0, 0, 255, 255, 1, MX, R, { ER, R }, FUNCFLAG_EXPORTONLY }, // MACRO or EXTERNAL
+ { "CONCATENATE", "CONCATENATE", 336, 336, 0, MX, V, { V }, 0 },
+ { "POWER", "POWER", 337, 337, 2, 2, V, { V }, 0 },
+ { "RADIANS", "RADIANS", 342, 342, 1, 1, V, { V }, 0 },
+ { "DEGREES", "DEGREES", 343, 343, 1, 1, V, { V }, 0 },
+ { "SUBTOTAL", "SUBTOTAL", 344, 344, 2, MX, V, { V, R }, 0 },
+ { "SUMIF", "SUMIF", 345, 345, 2, 3, V, { R, V, R }, 0 },
+ { "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { R, V }, 0 },
+ { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { R }, 0 },
+ { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { V }, 0 },
+ { 0, "DATEDIF", 351, 351, 3, 3, V, { V }, FUNCFLAG_IMPORTONLY }, // not supported in Calc
+ { 0, "DATESTRING", 352, 352, 1, 1, V, { V }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOX spec
+ { 0, "NUMBERSTRING", 353, 353, 2, 2, V, { V }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOX spec
+ { "ROMAN", "ROMAN", 354, 354, 1, 2, V, { V }, 0 }
+};
+
+/** Functions new in BIFF8. */
+static const FunctionData saFuncTableBiff8[] =
+{
+ { "GETPIVOTDATA", "GETPIVOTDATA", 358, 358, 2, MX, V, { V, R, V }, FUNCFLAG_IMPORTONLY },
+ { "HYPERLINK", "HYPERLINK", 359, 359, 1, 2, V, { V }, 0 },
+ { 0, "PHONETIC", 360, 360, 1, 1, V, { R }, FUNCFLAG_IMPORTONLY },
+ { "AVERAGEA", "AVERAGEA", 361, 361, 1, MX, V, { R }, 0 },
+ { "MAXA", "MAXA", 362, 362, 1, MX, V, { R }, 0 },
+ { "MINA", "MINA", 363, 363, 1, MX, V, { R }, 0 },
+ { "STDEVPA", "STDEVPA", 364, 364, 1, MX, V, { R }, 0 },
+ { "VARPA", "VARPA", 365, 365, 1, MX, V, { R }, 0 },
+ { "STDEVA", "STDEVA", 366, 366, 1, MX, V, { R }, 0 },
+ { "VARA", "VARA", 367, 367, 1, MX, V, { R }, 0 },
+ { "COM.MICROSOFT.BAHTTEXT", "BAHTTEXT", 368, 368, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "THAIDAYOFWEEK", 369, 369, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "THAIDIGIT", 370, 370, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "THAIMONTHOFYEAR", 371, 371, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "THAINUMSOUND", 372, 372, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "THAINUMSTRING", 373, 373, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "THAISTRINGLENGTH", 374, 374, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "ISTHAIDIGIT", 375, 375, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "ROUNDBAHTDOWN", 376, 376, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "ROUNDBAHTUP", 377, 377, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "THAIYEAR", 378, 378, 1, 1, V, { V }, FUNCFLAG_MACROCALL },
+ { 0, "RTD", 379, 379, 3, 3, A, { V, V, R }, 0 }
+};
+
+/** Functions new in OOX. */
+static const FunctionData saFuncTableOox[] =
+{
+ { 0, "IFERROR", 480, NOID, 2, 2, V, { V, R }, 0 },
+ { 0, "COUNTIFS", 481, NOID, 3, MX, V, { R, V }, 0 },
+ { 0, "SUMIFS", 482, NOID, 3, MX, V, { R, V }, 0 },
+ { 0, "AVERAGEIF", 483, NOID, 2, 3, V, { R, V, R }, 0 },
+ { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { R, V }, 0 },
+ { 0, "CUBEKPIMEMBER", NOID, NOID, 3, 4, V, { V }, 0 },
+ { 0, "CUBEMEMBER", NOID, NOID, 2, 3, V, { V, A, V }, 0 },
+ { 0, "CUBEMEMBERPROPERTY",NOID, NOID, 3, 3, V, { V }, 0 },
+ { 0, "CUBERANKEDMEMBER", NOID, NOID, 3, 4, V, { V }, 0 },
+ { 0, "CUBESET", NOID, NOID, 2, 5, V, { V, R, V }, 0 },
+ { 0, "CUBESETCOUNT", NOID, NOID, 1, 1, V, { V }, 0 },
+ { 0, "CUBEVALUE", NOID, NOID, 2, 2, V, { V, R }, 0 }
+};
+
+/** Functions defined by OpenFormula, but not supported by Calc or by Excel. */
+static const FunctionData saFuncTableOdf[] =
+{
+ { "ARABIC", 0, NOID, NOID, 1, 1, V, { V }, 0 },
+ { "B", 0, NOID, NOID, 3, 4, V, { V }, 0 },
+ { "BASE", 0, NOID, NOID, 2, 3, V, { V }, 0 },
+ { "BITAND", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "BITOR", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "BITXOR", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { V }, 0 },
+ { "CHISQINV", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "COMBINA", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "DAYS", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "DDE", 0, NOID, NOID, 3, 4, V, { V }, 0 },
+ { "DECIMAL", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "FDIST", 0, NOID, NOID, 3, 4, V, { V }, 0 },
+ { "FINV", 0, NOID, NOID, 3, 3, V, { V }, 0 },
+ { "FORMULA", 0, NOID, NOID, 1, 1, V, { R }, 0 },
+ { "GAMMA", 0, NOID, NOID, 1, 1, V, { V }, 0 },
+ { "GAUSS", 0, NOID, NOID, 1, 1, V, { V }, 0 },
+ { "IFNA", 0, NOID, NOID, 2, 2, V, { V, R }, 0 },
+ { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { R }, 0 },
+ { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { V }, 0 },
+ { "MULTIPLE.OPERATIONS", 0, NOID, NOID, 3, 5, V, { R }, 0 },
+ { "MUNIT", 0, NOID, NOID, 1, 1, A, { V }, 0 },
+ { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "PDURATION", 0, NOID, NOID, 3, 3, V, { V }, 0 },
+ { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { V }, 0 },
+ { "PHI", 0, NOID, NOID, 1, 1, V, { V }, 0 },
+ { "RRI", 0, NOID, NOID, 3, 3, V, { V }, 0 },
+ { "SHEET", 0, NOID, NOID, 1, 1, V, { R }, 0 },
+ { "SHEETS", 0, NOID, NOID, 0, 1, V, { R }, 0 },
+ { "SKEWP", 0, NOID, NOID, 1, MX, V, { R }, 0 },
+ { "UNICHAR", 0, NOID, NOID, 1, 1, V, { V }, 0 },
+ { "UNICODE", 0, NOID, NOID, 1, 1, V, { V }, 0 },
+ { "XOR", 0, NOID, NOID, 1, MX, V, { R }, 0 }
+};
+
+} // namespace
+
+// function info parameter class iterator =====================================
+
+FuncInfoParamClassIterator::FuncInfoParamClassIterator( const FunctionInfo& rFuncInfo ) :
+ mpnParamClass( rFuncInfo.mpnParamClass ),
+ mpnParamClassEnd( rFuncInfo.mpnParamClass + FUNCINFO_CLASSCOUNT )
+{
+}
+
+FuncInfoParamClassIterator& FuncInfoParamClassIterator::operator++()
+{
+ if( (mpnParamClass + 1 < mpnParamClassEnd) && (mpnParamClass[ 1 ] != 0) )
+ ++mpnParamClass;
+ return *this;
+}
+
+// function provider implementation ===========================================
+
+class FunctionProviderImpl
+{
+public:
+ explicit FunctionProviderImpl(
+ ApiOpCodes& rOpCodes,
+ const Reference< XSpreadsheetDocument >& rxDocument,
+ bool bImportFilter );
+
+ explicit FunctionProviderImpl(
+ ApiOpCodes& rOpCodes,
+ const Reference< XSpreadsheetDocument >& rxDocument,
+ BiffType eBiff,
+ bool bImportFilter );
+
+ const FunctionInfo* getFuncInfoFromApiToken( const ApiToken& rToken ) const;
+ const FunctionInfo* getFuncInfoFromOoxFuncName( const OUString& rFuncName ) const;
+ const FunctionInfo* getFuncInfoFromOobFuncId( sal_uInt16 nFuncId ) const;
+ const FunctionInfo* getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const;
+ const FunctionInfo* getFuncInfoFromExternCallName( const OUString& rExtCallName ) const;
+
+ Sequence< FormulaOpCodeMapEntry > getOoxParserMap() const;
+
+private:
+ typedef ::std::map< OUString, FormulaToken > FormulaTokenMap;
+ typedef Sequence< FormulaOpCodeMapEntry > OpCodeEntrySequence;
+ typedef ::std::vector< FormulaOpCodeMapEntry > OpCodeEntryVector;
+
+ static bool fillEntrySeq( OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup );
+ static bool fillTokenMap( FormulaTokenMap& orTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup );
+
+ static bool initOpCode( sal_Int32& ornOpCode, const OpCodeEntrySequence& rEntrySeq, sal_Int32 nSpecialId );
+ static bool initOpCode( OpCodeEntryVector& orParserMap, sal_Int32& ornOpCode, const FormulaTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName );
+
+ void construct( const Reference< XSpreadsheetDocument >& rxDocument, bool bImportFilter );
+ void construct( const Reference< XSpreadsheetDocument >& rxDocument, BiffType eBiff, bool bImportFilter );
+
+ bool initFuncNames( const OpCodeEntrySequence& rEntrySeq );
+ void initOpCodes( const Reference< XSpreadsheetDocument >& rxDocument );
+
+ void initFuncOpCode( FunctionInfo& orFuncInfo, const FormulaTokenMap& rFuncTokens );
+ void initFuncMaps( const FunctionData* pBeg, const FunctionData* pEnd );
+
+private:
+ typedef RefMap< sal_Int32, FunctionInfo > OpCodeFuncMap;
+ typedef RefMap< OUString, FunctionInfo > FuncNameMap;
+ typedef RefMap< sal_uInt16, FunctionInfo > FuncIdMap;
+
+ ApiOpCodes& mrOpCodes; /// All needed API op-codes.
+ FormulaTokenMap maIntFuncTokens; /// Internal functions keyed by ODFF name.
+ FormulaTokenMap maExtFuncTokens; /// External functions keyed by ODFF name.
+ OpCodeFuncMap maOpCodeFuncs; /// Maps API op-codes to function data.
+ FuncNameMap maOoxFuncs; /// Maps OOXML function names to function data.
+ FuncNameMap maExtProgFuncs; /// Maps programmatical API function names to function data.
+ FuncIdMap maOobFuncs; /// Maps OOBIN function indexes to function data.
+ FuncIdMap maBiffFuncs; /// Maps BIFF function indexes to function data.
+ FuncNameMap maMacroFuncs; /// Maps BIFF macro function names to function data.
+ OpCodeEntryVector maParserMap; /// OOXML token mapping for formula parser service.
+ sal_uInt8 mnMaxParam; /// Maximum parameter count for current file type.
+ bool mbImportFilter; /// True = import filter, false = export filter.
+};
+
+// ----------------------------------------------------------------------------
+
+FunctionProviderImpl::FunctionProviderImpl( ApiOpCodes& rOpCodes,
+ const Reference< XSpreadsheetDocument >& rxDocument, bool bImportFilter ) :
+ mrOpCodes( rOpCodes ),
+ mnMaxParam( OOX_MAX_PARAMCOUNT )
+{
+ construct( rxDocument, bImportFilter );
+}
+
+FunctionProviderImpl::FunctionProviderImpl( ApiOpCodes& rOpCodes,
+ const Reference< XSpreadsheetDocument >& rxDocument, BiffType eBiff, bool bImportFilter ) :
+ mrOpCodes( rOpCodes ),
+ mnMaxParam( BIFF_MAX_PARAMCOUNT )
+{
+ construct( rxDocument, eBiff, bImportFilter );
+}
+
+const FunctionInfo* FunctionProviderImpl::getFuncInfoFromApiToken( const ApiToken& rToken ) const
+{
+ const FunctionInfo* pFuncInfo = 0;
+ if( (rToken.OpCode == mrOpCodes.OPCODE_EXTERNAL) && rToken.Data.hasValue() )
+ {
+ OUString aProgFuncName;
+ if( rToken.Data >>= aProgFuncName )
+ pFuncInfo = maExtProgFuncs.get( aProgFuncName ).get();
+ }
+ else
+ {
+ pFuncInfo = maOpCodeFuncs.get( rToken.OpCode ).get();
+ }
+ return pFuncInfo;
+}
+
+const FunctionInfo* FunctionProviderImpl::getFuncInfoFromOoxFuncName( const OUString& rFuncName ) const
+{
+ return maOoxFuncs.get( rFuncName ).get();
+}
+
+const FunctionInfo* FunctionProviderImpl::getFuncInfoFromOobFuncId( sal_uInt16 nFuncId ) const
+{
+ return maOobFuncs.get( nFuncId ).get();
+}
+
+const FunctionInfo* FunctionProviderImpl::getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const
+{
+ return maBiffFuncs.get( nFuncId ).get();
+}
+
+const FunctionInfo* FunctionProviderImpl::getFuncInfoFromExternCallName( const OUString& rExtCallName ) const
+{
+ return maMacroFuncs.get( rExtCallName ).get();
+}
+
+Sequence< FormulaOpCodeMapEntry > FunctionProviderImpl::getOoxParserMap() const
+{
+ return ContainerHelper::vectorToSequence( maParserMap );
+}
+
+// private --------------------------------------------------------------------
+
+bool FunctionProviderImpl::fillEntrySeq( OpCodeEntrySequence& orEntrySeq,
+ const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup )
+{
+ try
+ {
+ orEntrySeq = rxMapper->getAvailableMappings( ::com::sun::star::sheet::FormulaLanguage::ODFF, nMapGroup );
+ return orEntrySeq.hasElements();
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+bool FunctionProviderImpl::fillTokenMap( FormulaTokenMap& orTokenMap, OpCodeEntrySequence& orEntrySeq,
+ const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup )
+{
+ orTokenMap.clear();
+ if( fillEntrySeq( orEntrySeq, rxMapper, nMapGroup ) )
+ {
+ const FormulaOpCodeMapEntry* pEntry = orEntrySeq.getConstArray();
+ const FormulaOpCodeMapEntry* pEntryEnd = pEntry + orEntrySeq.getLength();
+ for( ; pEntry != pEntryEnd; ++pEntry )
+ orTokenMap[ pEntry->Name ] = pEntry->Token;
+ }
+ return !orTokenMap.empty();
+}
+
+bool FunctionProviderImpl::initOpCode( sal_Int32& ornOpCode,
+ const OpCodeEntrySequence& rEntrySeq, sal_Int32 nSpecialId )
+{
+ if( (0 <= nSpecialId) && (nSpecialId < rEntrySeq.getLength()) )
+ {
+ ornOpCode = rEntrySeq[ nSpecialId ].Token.OpCode;
+ return true;
+ }
+ OSL_ENSURE( false,
+ OStringBuffer( "FunctionProviderImpl::initOpCode - opcode for special offset " ).
+ append( nSpecialId ).append( " not found" ).getStr() );
+ return false;
+}
+
+bool FunctionProviderImpl::initOpCode( OpCodeEntryVector& orParserMap, sal_Int32& ornOpCode,
+ const FormulaTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName )
+{
+ OUString aOdfName = OUString::createFromAscii( pcOdfName );
+ FormulaTokenMap::const_iterator aIt = rTokenMap.find( aOdfName );
+ if( aIt != rTokenMap.end() )
+ {
+ ornOpCode = aIt->second.OpCode;
+ if( pcOoxName )
+ {
+ FormulaOpCodeMapEntry aEntry;
+ aEntry.Name = OUString::createFromAscii( pcOoxName );
+ aEntry.Token.OpCode = ornOpCode;
+ orParserMap.push_back( aEntry );
+ }
+ return true;
+ }
+ OSL_ENSURE( false,
+ OStringBuffer( "FunctionProviderImpl::initOpCode - opcode for \"" ).
+ append( OUStringToOString( aOdfName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( "\" not found" ).getStr() );
+ return false;
+}
+
+void FunctionProviderImpl::construct(
+ const Reference< XSpreadsheetDocument >& rxDocument, bool bImportFilter )
+{
+ construct( rxDocument, BIFF8, bImportFilter );
+ // additional functions for OOX
+ initFuncMaps( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ) );
+}
+
+void FunctionProviderImpl::construct(
+ const Reference< XSpreadsheetDocument >& rxDocument, BiffType eBiff, bool bImportFilter )
+{
+ mbImportFilter = bImportFilter;
+ OSL_ENSURE( mbImportFilter, "FunctionProviderImpl::construct - need special handling for macro call functions" );
+
+ // operator op-codes, special op-codes, function op-codes
+ initOpCodes( rxDocument );
+
+ /* Add functions supported in the current BIFF version only.
+ Function tables from later BIFF versions may overwrite single
+ functions from earlier tables. */
+ if( eBiff >= BIFF2 )
+ initFuncMaps( saFuncTableBiff2, STATIC_ARRAY_END( saFuncTableBiff2 ) );
+ if( eBiff >= BIFF3 )
+ initFuncMaps( saFuncTableBiff3, STATIC_ARRAY_END( saFuncTableBiff3 ) );
+ if( eBiff >= BIFF4 )
+ initFuncMaps( saFuncTableBiff4, STATIC_ARRAY_END( saFuncTableBiff4 ) );
+ if( eBiff >= BIFF5 )
+ initFuncMaps( saFuncTableBiff5, STATIC_ARRAY_END( saFuncTableBiff5 ) );
+ if( eBiff >= BIFF8 )
+ initFuncMaps( saFuncTableBiff8, STATIC_ARRAY_END( saFuncTableBiff8 ) );
+}
+
+bool FunctionProviderImpl::initFuncNames( const OpCodeEntrySequence& rEntrySeq )
+{
+ const FormulaOpCodeMapEntry* pEntry = rEntrySeq.getConstArray();
+ const FormulaOpCodeMapEntry* pEntryEnd = pEntry + rEntrySeq.getLength();
+ for( ; pEntry != pEntryEnd; ++pEntry )
+ {
+ if( pEntry->Token.OpCode == mrOpCodes.OPCODE_EXTERNAL )
+ maExtFuncTokens[ pEntry->Name ] = pEntry->Token;
+ else
+ maIntFuncTokens[ pEntry->Name ] = pEntry->Token;
+ }
+ return true;
+}
+
+void FunctionProviderImpl::initOpCodes( const Reference< XSpreadsheetDocument >& rxDocument )
+{
+ bool bIsValid = false;
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory( rxDocument, UNO_QUERY_THROW );
+ Reference< XFormulaOpCodeMapper > xMapper( xFactory->createInstance(
+ CREATE_OUSTRING( "com.sun.star.sheet.FormulaOpCodeMapper" ) ), UNO_QUERY_THROW );
+
+ // op-codes provided as attributes
+ mrOpCodes.OPCODE_EXTERNAL = xMapper->getOpCodeExternal();
+ mrOpCodes.OPCODE_UNKNOWN = xMapper->getOpCodeUnknown();
+
+ using namespace ::com::sun::star::sheet::FormulaMapGroup;
+ using namespace ::com::sun::star::sheet::FormulaMapGroupSpecialOffset;
+
+ OpCodeEntrySequence aEntrySeq;
+ FormulaTokenMap aTokenMap;
+ bIsValid =
+ // special
+ fillEntrySeq( aEntrySeq, xMapper, SPECIAL ) &&
+ initOpCode( mrOpCodes.OPCODE_PUSH, aEntrySeq, PUSH ) &&
+ initOpCode( mrOpCodes.OPCODE_MISSING, aEntrySeq, MISSING ) &&
+ initOpCode( mrOpCodes.OPCODE_SPACES, aEntrySeq, SPACES ) &&
+ initOpCode( mrOpCodes.OPCODE_NAME, aEntrySeq, NAME ) &&
+ initOpCode( mrOpCodes.OPCODE_DBAREA, aEntrySeq, DB_AREA ) &&
+ initOpCode( mrOpCodes.OPCODE_NLR, aEntrySeq, COL_ROW_NAME ) &&
+ initOpCode( mrOpCodes.OPCODE_MACRO, aEntrySeq, MACRO ) &&
+ initOpCode( mrOpCodes.OPCODE_BAD, aEntrySeq, BAD ) &&
+ initOpCode( mrOpCodes.OPCODE_NONAME, aEntrySeq, NO_NAME ) &&
+ // separators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, SEPARATORS ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_OPEN, aTokenMap, "(", "(" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_CLOSE, aTokenMap, ")", ")" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_SEP, aTokenMap, ";", "," ) &&
+ // array separators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, ARRAY_SEPARATORS ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_ARRAY_OPEN, aTokenMap, "{", "{" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_ARRAY_CLOSE, aTokenMap, "}", "}" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_ARRAY_ROWSEP, aTokenMap, "|", ";" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_ARRAY_COLSEP, aTokenMap, ";", "," ) &&
+ // unary operators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, UNARY_OPERATORS ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_PLUS_SIGN, aTokenMap, "+", 0 ) && // same op-code as OPCODE_ADD
+ initOpCode( maParserMap, mrOpCodes.OPCODE_MINUS_SIGN, aTokenMap, "-", "-" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_PERCENT, aTokenMap, "%", "%" ) &&
+ // binary operators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, BINARY_OPERATORS ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_ADD, aTokenMap, "+", "+" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_SUB, aTokenMap, "-", "-" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_MULT, aTokenMap, "*", "*" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_DIV, aTokenMap, "/", "/" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_POWER, aTokenMap, "^", "^" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_CONCAT, aTokenMap, "&", "&" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_EQUAL, aTokenMap, "=", "=" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_NOT_EQUAL, aTokenMap, "<>", "<>" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_LESS, aTokenMap, "<", "<" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_LESS_EQUAL, aTokenMap, "<=", "<=" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_GREATER, aTokenMap, ">", ">" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_GREATER_EQUAL, aTokenMap, ">=", ">=" ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_INTERSECT, aTokenMap, "!", " " ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_LIST, aTokenMap, "~", "," ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_RANGE, aTokenMap, ":", ":" ) &&
+ // functions
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, FUNCTIONS ) &&
+ initFuncNames( aEntrySeq ) &&
+ initOpCode( maParserMap, mrOpCodes.OPCODE_DDE, aTokenMap, "DDE", 0 );
+
+ // OPCODE_PLUS_SIGN and OPCODE_ADD should be equal, otherwise "+" has to be passed above
+ OSL_ENSURE( mrOpCodes.OPCODE_PLUS_SIGN == mrOpCodes.OPCODE_ADD,
+ "FunctionProviderImpl::initOpCodes - need opcode mapping for OPCODE_PLUS_SIGN" );
+ // OPCODE_LIST not supported in Calc core
+ mrOpCodes.OPCODE_LIST = mrOpCodes.OPCODE_SEP;
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( bIsValid, "FunctionProviderImpl::initOpCodes - opcodes not initialized" );
+}
+
+void FunctionProviderImpl::initFuncOpCode( FunctionInfo& orFuncInfo, const FormulaTokenMap& rFuncTokens )
+{
+ bool bRet = false;
+ if( orFuncInfo.mnOobFuncId == OOBIN_FUNC_EXTERNCALL )
+ {
+ orFuncInfo.mnApiOpCode = mrOpCodes.OPCODE_EXTERNAL;
+ bRet = true;
+ }
+ else if( orFuncInfo.maOdfFuncName.getLength() > 0 )
+ {
+ FormulaTokenMap::const_iterator aIt = rFuncTokens.find( orFuncInfo.maOdfFuncName );
+ if( aIt != rFuncTokens.end() )
+ {
+ orFuncInfo.mnApiOpCode = aIt->second.OpCode;
+ OSL_ENSURE( orFuncInfo.mnApiOpCode != mrOpCodes.OPCODE_NONAME,
+ OStringBuffer( "FunctionProviderImpl::initFuncOpCode - no valid op-code for \"" ).
+ append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( '"' ).getStr() );
+ OSL_ENSURE( orFuncInfo.maOoxFuncName.getLength() > 0,
+ OStringBuffer( "FunctionProviderImpl::initFuncOpCode - no valid OOX function name for \"" ).
+ append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( '"' ).getStr() );
+ bRet = (orFuncInfo.mnApiOpCode != mrOpCodes.OPCODE_EXTERNAL) ||
+ ((aIt->second.Data >>= orFuncInfo.maExtProgName) && (orFuncInfo.maExtProgName.getLength() > 0));
+ if( bRet )
+ {
+ // create the parser map entry
+ FormulaOpCodeMapEntry aEntry;
+ aEntry.Name = orFuncInfo.maOoxFuncName;
+ aEntry.Token = aIt->second;
+ maParserMap.push_back( aEntry );
+ }
+ }
+ OSL_ENSURE( bRet,
+ OStringBuffer( "FunctionProviderImpl::initFuncOpCode - opcode or external name for \"" ).
+ append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( "\" not found" ).getStr() );
+ }
+ if( !bRet || (orFuncInfo.mnApiOpCode == mrOpCodes.OPCODE_UNKNOWN) )
+ orFuncInfo.mnApiOpCode = mrOpCodes.OPCODE_NONAME;
+}
+
+void FunctionProviderImpl::initFuncMaps( const FunctionData* pBeg, const FunctionData* pEnd )
+{
+ for( const FunctionData* pIt = pBeg; pIt != pEnd; ++pIt )
+ {
+ if( pIt->isSupported( mbImportFilter ) )
+ {
+ // create a function info object
+ FunctionInfoRef xFuncInfo( new FunctionInfo );
+ if( pIt->mpcOdfFuncName )
+ xFuncInfo->maOdfFuncName = OUString::createFromAscii( pIt->mpcOdfFuncName );
+ if( pIt->mpcOoxFuncName )
+ xFuncInfo->maOoxFuncName = OUString::createFromAscii( pIt->mpcOoxFuncName );
+ if( getFlag( pIt->mnFlags, FUNCFLAG_MACROCALL ) )
+ xFuncInfo->maExternCallName = CREATE_OUSTRING( "_xlfn." ) + xFuncInfo->maOoxFuncName;
+ else if( getFlag( pIt->mnFlags, FUNCFLAG_EXTERNAL ) )
+ xFuncInfo->maExternCallName = xFuncInfo->maOoxFuncName;
+ xFuncInfo->mnOobFuncId = pIt->mnOobFuncId;
+ xFuncInfo->mnBiffFuncId = pIt->mnBiffFuncId;
+ xFuncInfo->mnMinParamCount = pIt->mnMinParamCount;
+ xFuncInfo->mnMaxParamCount = (pIt->mnMaxParamCount == MX) ? mnMaxParam : pIt->mnMaxParamCount;
+ xFuncInfo->mnRetClass = pIt->mnRetClass;
+ xFuncInfo->mpnParamClass = pIt->mpnParamClass;
+ xFuncInfo->mbVolatile = getFlag( pIt->mnFlags, FUNCFLAG_VOLATILE );
+
+ // get API opcode from BIFF function index or function name
+ initFuncOpCode( *xFuncInfo, getFlag( pIt->mnFlags, FUNCFLAG_EXTERNAL ) ? maExtFuncTokens : maIntFuncTokens );
+
+ // insert the function info into the maps
+ if( xFuncInfo->mnApiOpCode != mrOpCodes.OPCODE_NONAME )
+ {
+ if( (xFuncInfo->mnApiOpCode == mrOpCodes.OPCODE_EXTERNAL) && (xFuncInfo->maExtProgName.getLength() > 0) )
+ maExtProgFuncs[ xFuncInfo->maExtProgName ] = xFuncInfo;
+ else
+ maOpCodeFuncs[ xFuncInfo->mnApiOpCode ] = xFuncInfo;
+ }
+ if( xFuncInfo->maOoxFuncName.getLength() > 0 )
+ maOoxFuncs[ xFuncInfo->maOoxFuncName ] = xFuncInfo;
+ if( xFuncInfo->mnOobFuncId != NOID )
+ maOobFuncs[ xFuncInfo->mnOobFuncId ] = xFuncInfo;
+ if( xFuncInfo->mnBiffFuncId != NOID )
+ maBiffFuncs[ xFuncInfo->mnBiffFuncId ] = xFuncInfo;
+ if( xFuncInfo->maExternCallName.getLength() > 0 )
+ maMacroFuncs[ xFuncInfo->maExternCallName ] = xFuncInfo;
+ }
+ }
+}
+
+// function provider ==========================================================
+
+FunctionProvider::FunctionProvider( const WorkbookHelper& rHelper )
+{
+ bool bImportFilter = rHelper.getBaseFilter().isImportFilter();
+ switch( rHelper.getFilterType() )
+ {
+ case FILTER_OOX:
+ mxImpl.reset( new FunctionProviderImpl( *this, rHelper.getDocument(), bImportFilter ) );
+ break;
+ case FILTER_BIFF:
+ mxImpl.reset( new FunctionProviderImpl( *this, rHelper.getDocument(), rHelper.getBiff(), bImportFilter ) );
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+}
+
+FunctionProvider::FunctionProvider( const Reference< XSpreadsheetDocument >& rxDocument, bool bImportFilter )
+{
+ mxImpl.reset( new FunctionProviderImpl( *this, rxDocument, bImportFilter ) );
+}
+
+FunctionProvider::FunctionProvider( const Reference< XSpreadsheetDocument >& rxDocument, BiffType eBiff, bool bImportFilter )
+{
+ mxImpl.reset( new FunctionProviderImpl( *this, rxDocument, eBiff, bImportFilter ) );
+}
+
+FunctionProvider::~FunctionProvider()
+{
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromApiToken( const ApiToken& rToken ) const
+{
+ return mxImpl->getFuncInfoFromApiToken( rToken );
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromOoxFuncName( const OUString& rFuncName ) const
+{
+ return mxImpl->getFuncInfoFromOoxFuncName( rFuncName );
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromOobFuncId( sal_uInt16 nFuncId ) const
+{
+ return mxImpl->getFuncInfoFromOobFuncId( nFuncId );
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const
+{
+ return mxImpl->getFuncInfoFromBiffFuncId( nFuncId );
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromExternCallName( const OUString& rExtCallName ) const
+{
+ return mxImpl->getFuncInfoFromExternCallName( rExtCallName );
+}
+
+Sequence< FormulaOpCodeMapEntry > FunctionProvider::getOoxParserMap() const
+{
+ return mxImpl->getOoxParserMap();
+}
+
+// token sequence iterator ====================================================
+
+ApiTokenIterator::ApiTokenIterator( const ApiTokenSequence& rTokens, sal_Int32 nSpacesOpCode, bool bSkipSpaces ) :
+ mpToken( rTokens.getConstArray() ),
+ mpTokenEnd( rTokens.getConstArray() + rTokens.getLength() ),
+ mnSpacesOpCode( nSpacesOpCode ),
+ mbSkipSpaces( bSkipSpaces )
+{
+ skipSpaces();
+}
+
+ApiTokenIterator::ApiTokenIterator( const ApiTokenIterator& rIter, bool bSkipSpaces ) :
+ mpToken( rIter.mpToken ),
+ mpTokenEnd( rIter.mpTokenEnd ),
+ mnSpacesOpCode( rIter.mnSpacesOpCode ),
+ mbSkipSpaces( bSkipSpaces )
+{
+ skipSpaces();
+}
+
+ApiTokenIterator& ApiTokenIterator::operator++()
+{
+ if( is() )
+ {
+ ++mpToken;
+ skipSpaces();
+ }
+ return *this;
+}
+
+void ApiTokenIterator::skipSpaces()
+{
+ if( mbSkipSpaces )
+ while( is() && (mpToken->OpCode == mnSpacesOpCode) )
+ ++mpToken;
+}
+
+// formual contexts ===========================================================
+
+FormulaContext::FormulaContext( bool bRelativeAsOffset, bool bAlways3dRefs ) :
+ maBaseAddress( 0, 0, 0 ),
+ mbRelativeAsOffset( bRelativeAsOffset ),
+ mbAlways3dRefs( bAlways3dRefs )
+{
+}
+
+FormulaContext::~FormulaContext()
+{
+}
+
+void FormulaContext::setSharedFormula( const CellAddress& )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+TokensFormulaContext::TokensFormulaContext( bool bRelativeAsOffset, bool bAlways3dRefs ) :
+ FormulaContext( bRelativeAsOffset, bAlways3dRefs )
+{
+}
+
+void TokensFormulaContext::setTokens( const ApiTokenSequence& rTokens )
+{
+ maTokens = rTokens;
+}
+
+// ----------------------------------------------------------------------------
+
+SimpleFormulaContext::SimpleFormulaContext( const Reference< XFormulaTokens >& rxTokens,
+ bool bRelativeAsOffset, bool bAlways3dRefs ) :
+ FormulaContext( bRelativeAsOffset, bAlways3dRefs ),
+ mxTokens( rxTokens )
+{
+ OSL_ENSURE( mxTokens.is(), "SimpleFormulaContext::SimpleFormulaContext - missing XFormulaTokens interface" );
+}
+
+void SimpleFormulaContext::setTokens( const ApiTokenSequence& rTokens )
+{
+ mxTokens->setTokens( rTokens );
+}
+
+// formula parser/formula compiler base class =================================
+
+namespace {
+
+bool lclConvertToCellAddress( CellAddress& orAddress, const SingleReference& rSingleRef, sal_Int32 nExpectedSheet )
+{
+ orAddress = CellAddress( static_cast< sal_Int16 >( rSingleRef.Sheet ),
+ rSingleRef.Column, rSingleRef.Row );
+ return
+ ((nExpectedSheet < 0) || (nExpectedSheet == rSingleRef.Sheet)) &&
+ !getFlag( rSingleRef.Flags, COLUMN_DELETED | ROW_DELETED | SHEET_DELETED );
+}
+
+bool lclConvertToCellRange( CellRangeAddress& orRange, const ComplexReference& rComplexRef, sal_Int32 nExpectedSheet )
+{
+ orRange = CellRangeAddress( static_cast< sal_Int16 >( rComplexRef.Reference1.Sheet ),
+ rComplexRef.Reference1.Column, rComplexRef.Reference1.Row,
+ rComplexRef.Reference2.Column, rComplexRef.Reference2.Row );
+ return
+ (rComplexRef.Reference1.Sheet == rComplexRef.Reference2.Sheet) &&
+ ((nExpectedSheet < 0) || (nExpectedSheet == rComplexRef.Reference1.Sheet)) &&
+ !getFlag( rComplexRef.Reference1.Flags, COLUMN_DELETED | ROW_DELETED | SHEET_DELETED ) &&
+ !getFlag( rComplexRef.Reference2.Flags, COLUMN_DELETED | ROW_DELETED | SHEET_DELETED );
+}
+
+enum TokenToRangeListState { STATE_REF, STATE_SEP, STATE_OPEN, STATE_CLOSE, STATE_ERROR };
+
+TokenToRangeListState lclProcessRef( ApiCellRangeList& orRanges, const Any& rData, sal_Int32 nExpectedSheet )
+{
+ SingleReference aSingleRef;
+ if( rData >>= aSingleRef )
+ {
+ CellAddress aAddress;
+ // ignore invalid addresses (with #REF! errors), but to not stop parsing
+ if( lclConvertToCellAddress( aAddress, aSingleRef, nExpectedSheet ) )
+ orRanges.push_back( CellRangeAddress( aAddress.Sheet, aAddress.Column, aAddress.Row, aAddress.Column, aAddress.Row ) );
+ return STATE_REF;
+ }
+ ComplexReference aComplexRef;
+ if( rData >>= aComplexRef )
+ {
+ CellRangeAddress aRange;
+ // ignore invalid ranges (with #REF! errors), but to not stop parsing
+ if( lclConvertToCellRange( aRange, aComplexRef, nExpectedSheet ) )
+ orRanges.push_back( aRange );
+ return STATE_REF;
+ }
+ return STATE_ERROR;
+}
+
+TokenToRangeListState lclProcessOpen( sal_Int32& ornParenLevel )
+{
+ ++ornParenLevel;
+ return STATE_OPEN;
+}
+
+TokenToRangeListState lclProcessClose( sal_Int32& ornParenLevel )
+{
+ --ornParenLevel;
+ return (ornParenLevel >= 0) ? STATE_CLOSE : STATE_ERROR;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+FormulaProcessorBase::FormulaProcessorBase( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maFuncProv( rHelper )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OUString FormulaProcessorBase::generateAddress2dString( const CellAddress& rAddress, bool bAbsolute )
+{
+ return generateAddress2dString( BinAddress( rAddress ), bAbsolute );
+}
+
+OUString FormulaProcessorBase::generateAddress2dString( const BinAddress& rAddress, bool bAbsolute )
+{
+ OUStringBuffer aBuffer;
+ // column
+ for( sal_Int32 nTemp = rAddress.mnCol; nTemp >= 0; (nTemp /= 26) -= 1 )
+ aBuffer.insert( 0, sal_Unicode( 'A' + (nTemp % 26) ) );
+ if( bAbsolute )
+ aBuffer.insert( 0, sal_Unicode( '$' ) );
+ // row
+ if( bAbsolute )
+ aBuffer.append( sal_Unicode( '$' ) );
+ aBuffer.append( static_cast< sal_Int32 >( rAddress.mnRow + 1 ) );
+ return aBuffer.makeStringAndClear();
+}
+
+OUString FormulaProcessorBase::generateRange2dString( const CellRangeAddress& rRange, bool bAbsolute )
+{
+ return generateRange2dString( BinRange( rRange ), bAbsolute );
+}
+
+OUString FormulaProcessorBase::generateRange2dString( const BinRange& rRange, bool bAbsolute )
+{
+ OUStringBuffer aBuffer( generateAddress2dString( rRange.maFirst, bAbsolute ) );
+ if( (rRange.getColCount() > 1) || (rRange.getRowCount() > 1) )
+ aBuffer.append( sal_Unicode( ':' ) ).append( generateAddress2dString( rRange.maLast, bAbsolute ) );
+ return aBuffer.makeStringAndClear();
+}
+
+OUString FormulaProcessorBase::generateRangeList2dString( const ApiCellRangeList& rRanges,
+ bool bAbsolute, sal_Unicode cSeparator, bool bEncloseMultiple )
+{
+ OUStringBuffer aBuffer;
+ for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt )
+ {
+ if( aBuffer.getLength() > 0 )
+ aBuffer.append( cSeparator );
+ aBuffer.append( generateRange2dString( *aIt, bAbsolute ) );
+ }
+ if( bEncloseMultiple && (rRanges.size() > 1) )
+ aBuffer.insert( 0, sal_Unicode( '(' ) ).append( sal_Unicode( ')' ) );
+ return aBuffer.makeStringAndClear();
+}
+
+// ----------------------------------------------------------------------------
+
+Any FormulaProcessorBase::extractReference( const ApiTokenSequence& rTokens ) const
+{
+ ApiTokenIterator aTokenIt( rTokens, maFuncProv.OPCODE_SPACES, true );
+ if( aTokenIt.is() && (aTokenIt->OpCode == maFuncProv.OPCODE_PUSH) )
+ {
+ Any aRefAny = aTokenIt->Data;
+ if( !(++aTokenIt).is() && (aRefAny.has< SingleReference >() || aRefAny.has< ComplexReference >()) )
+ return aRefAny;
+ }
+ return Any();
+}
+
+void FormulaProcessorBase::extractCellRangeList( ApiCellRangeList& orRanges,
+ const ApiTokenSequence& rTokens, sal_Int32 nExpectedSheet ) const
+{
+ orRanges.clear();
+ TokenToRangeListState eState = STATE_OPEN;
+ sal_Int32 nParenLevel = 0;
+ for( ApiTokenIterator aIt( rTokens, maFuncProv.OPCODE_SPACES, true ); aIt.is() && (eState != STATE_ERROR); ++aIt )
+ {
+ sal_Int32 nOpCode = aIt->OpCode;
+ switch( eState )
+ {
+ case STATE_REF:
+ if( nOpCode == maFuncProv.OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == maFuncProv.OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
+ else eState = STATE_ERROR;
+ break;
+ case STATE_SEP:
+ if( nOpCode == maFuncProv.OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, nExpectedSheet );
+ else if( nOpCode == maFuncProv.OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == maFuncProv.OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel );
+ else if( nOpCode == maFuncProv.OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
+ else eState = STATE_ERROR;
+ break;
+ case STATE_OPEN:
+ if( nOpCode == maFuncProv.OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, nExpectedSheet );
+ else if( nOpCode == maFuncProv.OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == maFuncProv.OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel );
+ else if( nOpCode == maFuncProv.OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
+ else eState = STATE_ERROR;
+ break;
+ case STATE_CLOSE:
+ if( nOpCode == maFuncProv.OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == maFuncProv.OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
+ else eState = STATE_ERROR;
+ break;
+ default:;
+ }
+ }
+
+ if( eState == STATE_ERROR )
+ orRanges.clear();
+ else
+ getAddressConverter().validateCellRangeList( orRanges, false );
+}
+
+bool FormulaProcessorBase::extractString( OUString& orString, const ApiTokenSequence& rTokens ) const
+{
+ ApiTokenIterator aTokenIt( rTokens, maFuncProv.OPCODE_SPACES, true );
+ return aTokenIt.is() && (aTokenIt->OpCode == maFuncProv.OPCODE_PUSH) && (aTokenIt->Data >>= orString) && !(++aTokenIt).is();
+}
+
+void FormulaProcessorBase::convertStringToStringList(
+ ApiTokenSequence& orTokens, sal_Unicode cStringSep, bool bTrimLeadingSpaces ) const
+{
+ OUString aString;
+ if( extractString( aString, orTokens ) && (aString.getLength() > 0) )
+ {
+ ::std::vector< ApiToken > aNewTokens;
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = aString.getLength();
+ while( (0 <= nPos) && (nPos < nLen) )
+ {
+ OUString aEntry = aString.getToken( 0, cStringSep, nPos );
+ if( bTrimLeadingSpaces )
+ {
+ sal_Int32 nStart = 0;
+ while( (nStart < aEntry.getLength()) && (aEntry[ nStart ] == ' ') ) ++nStart;
+ aEntry = aEntry.copy( nStart );
+ }
+ if( !aNewTokens.empty() )
+ aNewTokens.push_back( ApiToken( maFuncProv.OPCODE_SEP, Any() ) );
+ aNewTokens.push_back( ApiToken( maFuncProv.OPCODE_PUSH, Any( aEntry ) ) );
+ }
+ orTokens = ContainerHelper::vectorToSequence( aNewTokens );
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx
new file mode 100644
index 000000000000..165d8f2b2873
--- /dev/null
+++ b/oox/source/xls/formulaparser.cxx
@@ -0,0 +1,2595 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: formulaparser.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/formulaparser.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/FormulaToken.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/SingleReference.hpp>
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/XFormulaParser.hpp>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/tablebuffer.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::SingleReference;
+using ::com::sun::star::sheet::ComplexReference;
+using ::com::sun::star::sheet::XFormulaParser;
+using namespace ::com::sun::star::sheet::ReferenceFlags;
+
+namespace oox {
+namespace xls {
+
+// parser implementation base =================================================
+
+class FormulaParserImpl : public WorkbookHelper
+{
+public:
+ explicit FormulaParserImpl(
+ const WorkbookHelper& rHelper,
+ const FunctionProvider& rFuncProv );
+
+ /** Converts an XML formula string. */
+ virtual void importOoxFormula(
+ FormulaContext& rContext,
+ const OUString& rFormulaString );
+
+ /** Imports and converts a OOBIN token array from the passed stream. */
+ virtual void importOobFormula(
+ FormulaContext& rContext,
+ RecordInputStream& rStrm );
+
+ /** Imports and converts a BIFF token array from the passed stream. */
+ virtual void importBiffFormula(
+ FormulaContext& rContext,
+ BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize );
+
+ /** Finalizes the passed token array after import (e.g. adjusts function
+ parameters) and sets the formula using the passed context. */
+ void setFormula(
+ FormulaContext& rContext,
+ const ApiTokenSequence& rTokens );
+
+protected:
+ /** Sets the current formula context used for import. */
+ inline FormulaContext& getFormulaContext() const { return *mpContext; }
+
+ /** Sets the current formula context used for import. */
+ void initializeImport( FormulaContext& rContext );
+ /** Finalizes the passed token array after import. */
+ void finalizeImport( const ApiTokenSequence& rTokens );
+ /** Finalizes the internal token storage after import. */
+ void finalizeImport();
+
+ /** Inserts a shared formula using the current formula context and passed base address. */
+ void setSharedFormula( const BinAddress& rBaseAddr );
+
+ // token array ------------------------------------------------------------
+
+ bool resetSpaces();
+ inline void incLeadingSpaces( sal_Int32 nSpaces ) { mnLeadingSpaces += nSpaces; }
+ inline void incOpeningSpaces( sal_Int32 nSpaces ) { mnOpeningSpaces += nSpaces; }
+ inline void incClosingSpaces( sal_Int32 nSpaces ) { mnClosingSpaces += nSpaces; }
+
+ size_t getFormulaSize() const;
+ Any& appendRawToken( sal_Int32 nOpCode );
+ Any& insertRawToken( sal_Int32 nOpCode, size_t nIndexFromEnd );
+ size_t appendSpacesToken( sal_Int32 nSpaces );
+ size_t insertSpacesToken( sal_Int32 nSpaces, size_t nIndexFromEnd );
+
+ size_t getOperandSize( size_t nOpCountFromEnd, size_t nOpIndex ) const;
+ void pushOperandSize( size_t nSize );
+ size_t popOperandSize();
+
+ ApiToken& getOperandToken( size_t nOpCountFromEnd, size_t nOpIndex, size_t nTokenIndex );
+ void removeOperand( size_t nOpCountFromEnd, size_t nOpIndex );
+ void removeLastOperands( size_t nOpCountFromEnd );
+
+ bool pushOperandToken( sal_Int32 nOpCode, sal_Int32 nSpaces );
+ bool pushAnyOperandToken( const Any& rAny, sal_Int32 nOpCode, sal_Int32 nSpaces );
+ template< typename Type >
+ bool pushValueOperandToken( const Type& rValue, sal_Int32 nOpCode, sal_Int32 nSpaces );
+ template< typename Type >
+ inline bool pushValueOperandToken( const Type& rValue, sal_Int32 nSpaces )
+ { return pushValueOperandToken( rValue, mrFuncProv.OPCODE_PUSH, nSpaces ); }
+ bool pushParenthesesOperandToken( sal_Int32 nOpeningSpaces, sal_Int32 nClosingSpaces );
+ bool pushUnaryPreOperatorToken( sal_Int32 nOpCode, sal_Int32 nSpaces );
+ bool pushUnaryPostOperatorToken( sal_Int32 nOpCode, sal_Int32 nSpaces );
+ bool pushBinaryOperatorToken( sal_Int32 nOpCode, sal_Int32 nSpaces );
+ bool pushParenthesesOperatorToken( sal_Int32 nOpeningSpaces, sal_Int32 nClosingSpaces );
+ bool pushFunctionOperatorToken( sal_Int32 nOpCode, size_t nParamCount, sal_Int32 nLeadingSpaces, sal_Int32 nClosingSpaces );
+ bool pushFunctionOperatorToken( const FunctionInfo& rFuncInfo, size_t nParamCount, sal_Int32 nLeadingSpaces, sal_Int32 nClosingSpaces );
+
+ bool pushOperand( sal_Int32 nOpCode );
+ bool pushAnyOperand( const Any& rAny, sal_Int32 nOpCode );
+ template< typename Type >
+ bool pushValueOperand( const Type& rValue, sal_Int32 nOpCode );
+ template< typename Type >
+ inline bool pushValueOperand( const Type& rValue )
+ { return pushValueOperand( rValue, mrFuncProv.OPCODE_PUSH ); }
+ bool pushBoolOperand( bool bValue );
+ bool pushErrorOperand( double fEncodedError );
+ bool pushBiffErrorOperand( sal_uInt8 nErrorCode );
+ bool pushParenthesesOperand();
+ bool pushReferenceOperand( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
+ bool pushReferenceOperand( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
+ bool pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
+ bool pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
+ bool pushNlrOperand( const BinSingleRef2d& rRef );
+ bool pushEmbeddedRefOperand( const DefinedNameBase& rName );
+ bool pushDefinedNameOperand( const DefinedNameRef& rxDefName );
+ bool pushDdeLinkOperand( const OUString& rDdeServer, const OUString& rDdeTopic, const OUString& rDdeItem );
+ bool pushExternalNameOperand( const ExternalNameRef& rxExtName, ExternalLinkType eLinkType );
+
+ bool pushUnaryPreOperator( sal_Int32 nOpCode );
+ bool pushUnaryPostOperator( sal_Int32 nOpCode );
+ bool pushBinaryOperator( sal_Int32 nOpCode );
+ bool pushParenthesesOperator();
+ bool pushFunctionOperator( sal_Int32 nOpCode, size_t nParamCount );
+ bool pushFunctionOperator( const FunctionInfo& rFuncInfo, size_t nParamCount );
+
+private:
+ // reference conversion ---------------------------------------------------
+
+ void initReference2d( SingleReference& orApiRef ) const;
+ void initReference3d( SingleReference& orApiRef, sal_Int32 nSheet ) const;
+ void convertColRow( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bRelativeAsOffset ) const;
+ void convertReference( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const;
+ void convertReference( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const;
+ void convertReference2d( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const;
+ void convertReference2d( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const;
+ void convertReference3d( SingleReference& orApiRef, sal_Int32 nSheet, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const;
+ void convertReference3d( ComplexReference& orApiRef, const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const;
+
+ // finalize token sequence ------------------------------------------------
+
+ typedef ::std::vector< const ApiToken* > ParameterPosVector;
+
+ void processTokens( const ApiToken* pToken, const ApiToken* pTokenEnd );
+ const ApiToken* processParameters( const FunctionInfo& rFuncInfo, const ApiToken* pToken, const ApiToken* pTokenEnd );
+
+ bool isEmptyParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
+ OUString getExternCallParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
+ const ApiToken* skipParentheses( const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
+ const ApiToken* findParameters( ParameterPosVector& rParams, const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
+ void appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam );
+ void appendRequiredParameters( const FunctionInfo& rFuncInfo, size_t nParamCount );
+
+ void appendFinalToken( const ApiToken& rToken );
+ Any& appendFinalToken( sal_Int32 nOpCode );
+
+protected:
+ const FunctionProvider& mrFuncProv; /// Function info provider.
+ const sal_Int32 mnMaxApiCol; /// Maximum column index in own document.
+ const sal_Int32 mnMaxApiRow; /// Maximum row index in own document.
+ const sal_Int32 mnMaxXlsCol; /// Maximum column index in imported document.
+ const sal_Int32 mnMaxXlsRow; /// Maximum row index in imported document.
+
+private:
+ typedef ::std::vector< ApiToken > ApiTokenVector;
+ typedef ::std::vector< size_t > SizeTypeVector;
+
+ ApiTokenVector maTokenStorage; /// Raw unordered token storage.
+ SizeTypeVector maTokenIndexes; /// Indexes into maTokenStorage.
+ SizeTypeVector maOperandSizeStack; /// Stack with token sizes per operand.
+ FormulaContext* mpContext; /// Current formula context.
+ sal_Int32 mnLeadingSpaces; /// Current number of spaces before next token.
+ sal_Int32 mnOpeningSpaces; /// Current number of spaces before opening parenthesis.
+ sal_Int32 mnClosingSpaces; /// Current number of spaces before closing parenthesis.
+};
+
+// ----------------------------------------------------------------------------
+
+FormulaParserImpl::FormulaParserImpl( const WorkbookHelper& rHelper, const FunctionProvider& rFuncProv ) :
+ WorkbookHelper( rHelper ),
+ mrFuncProv( rFuncProv ),
+ mnMaxApiCol( rHelper.getAddressConverter().getMaxApiAddress().Column ),
+ mnMaxApiRow( rHelper.getAddressConverter().getMaxApiAddress().Row ),
+ mnMaxXlsCol( rHelper.getAddressConverter().getMaxXlsAddress().Column ),
+ mnMaxXlsRow( rHelper.getAddressConverter().getMaxXlsAddress().Row ),
+ mpContext( 0 )
+{
+ maTokenStorage.reserve( 0x2000 );
+ maTokenIndexes.reserve( 0x2000 );
+ maOperandSizeStack.reserve( 256 );
+ resetSpaces();
+}
+
+void FormulaParserImpl::importOoxFormula( FormulaContext&, const OUString& )
+{
+ OSL_ENSURE( false, "FormulaParserImpl::importOoxFormula - not implemented" );
+}
+
+void FormulaParserImpl::importOobFormula( FormulaContext&, RecordInputStream& )
+{
+ OSL_ENSURE( false, "FormulaParserImpl::importOobFormula - not implemented" );
+}
+
+void FormulaParserImpl::importBiffFormula( FormulaContext&, BiffInputStream&, const sal_uInt16* )
+{
+ OSL_ENSURE( false, "FormulaParserImpl::importBiffFormula - not implemented" );
+}
+
+void FormulaParserImpl::setFormula( FormulaContext& rContext, const ApiTokenSequence& rTokens )
+{
+ initializeImport( rContext );
+ finalizeImport( rTokens );
+}
+
+void FormulaParserImpl::initializeImport( FormulaContext& rContext )
+{
+ maTokenStorage.clear();
+ maTokenIndexes.clear();
+ maOperandSizeStack.clear();
+ mpContext = &rContext;
+}
+
+void FormulaParserImpl::finalizeImport( const ApiTokenSequence& rTokens )
+{
+ maTokenStorage.clear();
+ const ApiToken* pToken = rTokens.getConstArray();
+ processTokens( pToken, pToken + rTokens.getLength() );
+ if( !maTokenStorage.empty() )
+ mpContext->setTokens( ContainerHelper::vectorToSequence( maTokenStorage ) );
+}
+
+void FormulaParserImpl::finalizeImport()
+{
+ ApiTokenSequence aTokens( static_cast< sal_Int32 >( maTokenIndexes.size() ) );
+ if( aTokens.hasElements() )
+ {
+ ApiToken* pToken = aTokens.getArray();
+ for( SizeTypeVector::const_iterator aIt = maTokenIndexes.begin(), aEnd = maTokenIndexes.end(); aIt != aEnd; ++aIt, ++pToken )
+ *pToken = maTokenStorage[ *aIt ];
+ }
+ finalizeImport( aTokens );
+}
+
+void FormulaParserImpl::setSharedFormula( const BinAddress& rBaseAddr )
+{
+ CellAddress aApiBaseAddr;
+ if( getAddressConverter().convertToCellAddress( aApiBaseAddr, rBaseAddr, mpContext->getBaseAddress().Sheet, false ) )
+ mpContext->setSharedFormula( aApiBaseAddr );
+}
+
+// token array ----------------------------------------------------------------
+
+bool FormulaParserImpl::resetSpaces()
+{
+ mnLeadingSpaces = mnOpeningSpaces = mnClosingSpaces = 0;
+ return true;
+}
+
+size_t FormulaParserImpl::getFormulaSize() const
+{
+ return maTokenIndexes.size();
+}
+
+Any& FormulaParserImpl::appendRawToken( sal_Int32 nOpCode )
+{
+ size_t nTokenIndex = maTokenStorage.size();
+ maTokenStorage.resize( nTokenIndex + 1 );
+ maTokenStorage.back().OpCode = nOpCode;
+ maTokenIndexes.push_back( nTokenIndex );
+ return maTokenStorage.back().Data;
+}
+
+Any& FormulaParserImpl::insertRawToken( sal_Int32 nOpCode, size_t nIndexFromEnd )
+{
+ size_t nTokenIndex = maTokenStorage.size();
+ maTokenStorage.resize( nTokenIndex + 1 );
+ maTokenStorage.back().OpCode = nOpCode;
+ maTokenIndexes.insert( maTokenIndexes.end() - nIndexFromEnd, nTokenIndex );
+ return maTokenStorage.back().Data;
+}
+
+size_t FormulaParserImpl::appendSpacesToken( sal_Int32 nSpaces )
+{
+ if( nSpaces > 0 )
+ {
+ appendRawToken( mrFuncProv.OPCODE_SPACES ) <<= nSpaces;
+ return 1;
+ }
+ return 0;
+}
+
+size_t FormulaParserImpl::insertSpacesToken( sal_Int32 nSpaces, size_t nIndexFromEnd )
+{
+ if( nSpaces > 0 )
+ {
+ insertRawToken( mrFuncProv.OPCODE_SPACES, nIndexFromEnd ) <<= nSpaces;
+ return 1;
+ }
+ return 0;
+}
+
+size_t FormulaParserImpl::getOperandSize( size_t nOpCountFromEnd, size_t nOpIndex ) const
+{
+ OSL_ENSURE( (nOpIndex < nOpCountFromEnd) && (nOpCountFromEnd <= maOperandSizeStack.size()),
+ "FormulaParserImpl::getOperandSize - invalid parameters" );
+ return maOperandSizeStack[ maOperandSizeStack.size() - nOpCountFromEnd + nOpIndex ];
+}
+
+void FormulaParserImpl::pushOperandSize( size_t nSize )
+{
+ maOperandSizeStack.push_back( nSize );
+}
+
+size_t FormulaParserImpl::popOperandSize()
+{
+ OSL_ENSURE( !maOperandSizeStack.empty(), "FormulaParserImpl::popOperandSize - invalid call" );
+ size_t nOpSize = maOperandSizeStack.back();
+ maOperandSizeStack.pop_back();
+ return nOpSize;
+}
+
+ApiToken& FormulaParserImpl::getOperandToken( size_t nOpCountFromEnd, size_t nOpIndex, size_t nTokenIndex )
+{
+ OSL_ENSURE( getOperandSize( nOpCountFromEnd, nOpIndex ) > nTokenIndex,
+ "FormulaParserImpl::getOperandToken - invalid parameters" );
+ SizeTypeVector::const_iterator aIndexIt = maTokenIndexes.end();
+ for( SizeTypeVector::const_iterator aEnd = maOperandSizeStack.end(), aIt = aEnd - nOpCountFromEnd + nOpIndex; aIt != aEnd; ++aIt )
+ aIndexIt -= *aIt;
+ return maTokenStorage[ *(aIndexIt + nTokenIndex) ];
+}
+
+void FormulaParserImpl::removeOperand( size_t nOpCountFromEnd, size_t nOpIndex )
+{
+ OSL_ENSURE( (nOpIndex < nOpCountFromEnd) && (nOpCountFromEnd <= maOperandSizeStack.size()),
+ "FormulaParserImpl::removeOperand - invalid parameters" );
+ // remove indexes into token storage, but do not touch storage itself
+ SizeTypeVector::iterator aSizeEnd = maOperandSizeStack.end();
+ SizeTypeVector::iterator aSizeIt = aSizeEnd - nOpCountFromEnd + nOpIndex;
+ size_t nRemainingSize = 0;
+ for( SizeTypeVector::iterator aIt = aSizeIt + 1; aIt != aSizeEnd; ++aIt )
+ nRemainingSize += *aIt;
+ maTokenIndexes.erase( maTokenIndexes.end() - nRemainingSize - *aSizeIt, maTokenIndexes.end() - nRemainingSize );
+ maOperandSizeStack.erase( aSizeIt );
+}
+
+void FormulaParserImpl::removeLastOperands( size_t nOpCountFromEnd )
+{
+ for( size_t nOpIndex = 0; nOpIndex < nOpCountFromEnd; ++nOpIndex )
+ removeOperand( 1, 0 );
+}
+
+bool FormulaParserImpl::pushOperandToken( sal_Int32 nOpCode, sal_Int32 nSpaces )
+{
+ size_t nSpacesSize = appendSpacesToken( nSpaces );
+ appendRawToken( nOpCode );
+ pushOperandSize( nSpacesSize + 1 );
+ return true;
+}
+
+bool FormulaParserImpl::pushAnyOperandToken( const Any& rAny, sal_Int32 nOpCode, sal_Int32 nSpaces )
+{
+ size_t nSpacesSize = appendSpacesToken( nSpaces );
+ appendRawToken( nOpCode ) = rAny;
+ pushOperandSize( nSpacesSize + 1 );
+ return true;
+}
+
+template< typename Type >
+bool FormulaParserImpl::pushValueOperandToken( const Type& rValue, sal_Int32 nOpCode, sal_Int32 nSpaces )
+{
+ size_t nSpacesSize = appendSpacesToken( nSpaces );
+ appendRawToken( nOpCode ) <<= rValue;
+ pushOperandSize( nSpacesSize + 1 );
+ return true;
+}
+
+bool FormulaParserImpl::pushParenthesesOperandToken( sal_Int32 nOpeningSpaces, sal_Int32 nClosingSpaces )
+{
+ size_t nSpacesSize = appendSpacesToken( nOpeningSpaces );
+ appendRawToken( mrFuncProv.OPCODE_OPEN );
+ nSpacesSize += appendSpacesToken( nClosingSpaces );
+ appendRawToken( mrFuncProv.OPCODE_CLOSE );
+ pushOperandSize( nSpacesSize + 2 );
+ return true;
+}
+
+bool FormulaParserImpl::pushUnaryPreOperatorToken( sal_Int32 nOpCode, sal_Int32 nSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 1;
+ if( bOk )
+ {
+ size_t nOpSize = popOperandSize();
+ size_t nSpacesSize = insertSpacesToken( nSpaces, nOpSize );
+ insertRawToken( nOpCode, nOpSize );
+ pushOperandSize( nOpSize + nSpacesSize + 1 );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushUnaryPostOperatorToken( sal_Int32 nOpCode, sal_Int32 nSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 1;
+ if( bOk )
+ {
+ size_t nOpSize = popOperandSize();
+ size_t nSpacesSize = appendSpacesToken( nSpaces );
+ appendRawToken( nOpCode );
+ pushOperandSize( nOpSize + nSpacesSize + 1 );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushBinaryOperatorToken( sal_Int32 nOpCode, sal_Int32 nSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 2;
+ if( bOk )
+ {
+ size_t nOp2Size = popOperandSize();
+ size_t nOp1Size = popOperandSize();
+ size_t nSpacesSize = insertSpacesToken( nSpaces, nOp2Size );
+ insertRawToken( nOpCode, nOp2Size );
+ pushOperandSize( nOp1Size + nSpacesSize + 1 + nOp2Size );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushParenthesesOperatorToken( sal_Int32 nOpeningSpaces, sal_Int32 nClosingSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 1;
+ if( bOk )
+ {
+ size_t nOpSize = popOperandSize();
+ size_t nSpacesSize = insertSpacesToken( nOpeningSpaces, nOpSize );
+ insertRawToken( mrFuncProv.OPCODE_OPEN, nOpSize );
+ nSpacesSize += appendSpacesToken( nClosingSpaces );
+ appendRawToken( mrFuncProv.OPCODE_CLOSE );
+ pushOperandSize( nOpSize + nSpacesSize + 2 );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushFunctionOperatorToken( sal_Int32 nOpCode, size_t nParamCount, sal_Int32 nLeadingSpaces, sal_Int32 nClosingSpaces )
+{
+ /* #i70925# if there are not enough tokens available on token stack, do
+ not exit with error, but reduce parameter count. */
+ nParamCount = ::std::min( maOperandSizeStack.size(), nParamCount );
+
+ // convert all parameters on stack to a single operand separated with OPCODE_SEP
+ bool bOk = true;
+ for( size_t nParam = 1; bOk && (nParam < nParamCount); ++nParam )
+ bOk = pushBinaryOperatorToken( mrFuncProv.OPCODE_SEP, 0 );
+
+ // add function parentheses and function name
+ return bOk &&
+ ((nParamCount > 0) ? pushParenthesesOperatorToken( 0, nClosingSpaces ) : pushParenthesesOperandToken( 0, nClosingSpaces )) &&
+ pushUnaryPreOperatorToken( nOpCode, nLeadingSpaces );
+}
+
+bool FormulaParserImpl::pushFunctionOperatorToken( const FunctionInfo& rFuncInfo, size_t nParamCount, sal_Int32 nLeadingSpaces, sal_Int32 nClosingSpaces )
+{
+ bool bOk = pushFunctionOperatorToken( rFuncInfo.mnApiOpCode, nParamCount, nLeadingSpaces, nClosingSpaces );
+ // try to create an external add-in call for the passed built-in function
+ if( bOk && (rFuncInfo.maExtProgName.getLength() > 0) )
+ getOperandToken( 1, 0, 0 ).Data <<= rFuncInfo.maExtProgName;
+ return bOk;
+}
+
+bool FormulaParserImpl::pushOperand( sal_Int32 nOpCode )
+{
+ return pushOperandToken( nOpCode, mnLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushAnyOperand( const Any& rAny, sal_Int32 nOpCode )
+{
+ return pushAnyOperandToken( rAny, nOpCode, mnLeadingSpaces ) && resetSpaces();
+}
+
+template< typename Type >
+bool FormulaParserImpl::pushValueOperand( const Type& rValue, sal_Int32 nOpCode )
+{
+ return pushValueOperandToken( rValue, nOpCode, mnLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushBoolOperand( bool bValue )
+{
+ if( const FunctionInfo* pFuncInfo = mrFuncProv.getFuncInfoFromOobFuncId( bValue ? OOBIN_FUNC_TRUE : OOBIN_FUNC_FALSE ) )
+ return pushFunctionOperator( pFuncInfo->mnApiOpCode, 0 );
+ return pushValueOperand< double >( bValue ? 1.0 : 0.0 );
+}
+
+bool FormulaParserImpl::pushErrorOperand( double fEncodedError )
+{
+ // HACK: enclose all error codes into an 1x1 matrix
+ // start token array with opening brace and leading spaces
+ pushOperand( mrFuncProv.OPCODE_ARRAY_OPEN );
+ size_t nOpSize = popOperandSize();
+ size_t nOldArraySize = maTokenIndexes.size();
+ // push a double containing the Calc error code
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= fEncodedError;
+ // close token array and set resulting operand size
+ appendRawToken( mrFuncProv.OPCODE_ARRAY_CLOSE );
+ pushOperandSize( nOpSize + maTokenIndexes.size() - nOldArraySize );
+ return true;
+}
+
+bool FormulaParserImpl::pushBiffErrorOperand( sal_uInt8 nErrorCode )
+{
+ return pushErrorOperand( BiffHelper::calcDoubleFromError( nErrorCode ) );
+}
+
+bool FormulaParserImpl::pushParenthesesOperand()
+{
+ return pushParenthesesOperandToken( mnOpeningSpaces, mnClosingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushReferenceOperand( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
+{
+ SingleReference aApiRef;
+ convertReference2d( aApiRef, rRef, bDeleted, bRelativeAsOffset );
+ return pushValueOperand( aApiRef );
+}
+
+bool FormulaParserImpl::pushReferenceOperand( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
+{
+ ComplexReference aApiRef;
+ convertReference2d( aApiRef, rRef.maRef1, rRef.maRef2, bDeleted, bRelativeAsOffset );
+ return pushValueOperand( aApiRef );
+}
+
+bool FormulaParserImpl::pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
+{
+ if( rSheetRange.is3dRange() )
+ {
+ // single-cell-range over several sheets, needs to create a ComplexReference
+ ComplexReference aApiRef;
+ convertReference3d( aApiRef, rSheetRange, rRef, rRef, bDeleted, bRelativeAsOffset );
+ return pushValueOperand( aApiRef );
+ }
+ SingleReference aApiRef;
+ convertReference3d( aApiRef, rSheetRange.isDeleted() ? -1 : rSheetRange.mnFirst, rRef, bDeleted, bRelativeAsOffset );
+ return pushValueOperand( aApiRef );
+}
+
+bool FormulaParserImpl::pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
+{
+ ComplexReference aApiRef;
+ convertReference3d( aApiRef, rSheetRange, rRef.maRef1, rRef.maRef2, bDeleted, bRelativeAsOffset );
+ return pushValueOperand( aApiRef );
+}
+
+bool FormulaParserImpl::pushNlrOperand( const BinSingleRef2d& rRef )
+{
+ SingleReference aApiRef;
+ convertReference2d( aApiRef, rRef, false, false );
+ return pushValueOperand( aApiRef, mrFuncProv.OPCODE_NLR );
+}
+
+bool FormulaParserImpl::pushEmbeddedRefOperand( const DefinedNameBase& rName )
+{
+ Any aRefAny = rName.getReference( mpContext->getBaseAddress() );
+ return aRefAny.hasValue() ? pushAnyOperand( aRefAny, mrFuncProv.OPCODE_PUSH ) : pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool FormulaParserImpl::pushDefinedNameOperand( const DefinedNameRef& rxDefName )
+{
+ if( !rxDefName )
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+ if( rxDefName->isMacroFunc( false ) )
+ return pushValueOperand( rxDefName->getOoxName(), mrFuncProv.OPCODE_MACRO );
+ if( rxDefName->getTokenIndex() >= 0 )
+ return pushValueOperand( rxDefName->getTokenIndex(), mrFuncProv.OPCODE_NAME );
+ return pushEmbeddedRefOperand( *rxDefName );
+}
+
+bool FormulaParserImpl::pushDdeLinkOperand( const OUString& rDdeServer, const OUString& rDdeTopic, const OUString& rDdeItem )
+{
+ // create the function call DDE("server";"topic";"item")
+ return
+ pushValueOperandToken( rDdeServer, 0 ) &&
+ pushValueOperandToken( rDdeTopic, 0 ) &&
+ pushValueOperandToken( rDdeItem, 0 ) &&
+ pushFunctionOperator( mrFuncProv.OPCODE_DDE, 3 );
+}
+
+bool FormulaParserImpl::pushExternalNameOperand( const ExternalNameRef& rxExtName, ExternalLinkType eLinkType )
+{
+ if( rxExtName.get() ) switch( eLinkType )
+ {
+ case LINKTYPE_INTERNAL:
+ case LINKTYPE_EXTERNAL:
+ return pushEmbeddedRefOperand( *rxExtName );
+
+ case LINKTYPE_ANALYSIS:
+ if( const FunctionInfo* pFuncInfo = mrFuncProv.getFuncInfoFromOoxFuncName( rxExtName->getOoxName() ) )
+ if( pFuncInfo->maExternCallName.getLength() > 0 )
+ return pushValueOperand( pFuncInfo->maExternCallName, mrFuncProv.OPCODE_MACRO );
+ break;
+
+ case LINKTYPE_DDE:
+ {
+ OUString aDdeServer, aDdeTopic, aDdeItem;
+ if( rxExtName->getDdeLinkData( aDdeServer, aDdeTopic, aDdeItem ) )
+ return pushDdeLinkOperand( aDdeServer, aDdeTopic, aDdeItem );
+ }
+ break;
+
+ default:
+ OSL_ENSURE( eLinkType != LINKTYPE_SELF, "FormulaParserImpl::pushExternalNameOperand - invalid call" );
+ }
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool FormulaParserImpl::pushUnaryPreOperator( sal_Int32 nOpCode )
+{
+ return pushUnaryPreOperatorToken( nOpCode, mnLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushUnaryPostOperator( sal_Int32 nOpCode )
+{
+ return pushUnaryPostOperatorToken( nOpCode, mnLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushBinaryOperator( sal_Int32 nOpCode )
+{
+ return pushBinaryOperatorToken( nOpCode, mnLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushParenthesesOperator()
+{
+ return pushParenthesesOperatorToken( mnOpeningSpaces, mnClosingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushFunctionOperator( sal_Int32 nOpCode, size_t nParamCount )
+{
+ return pushFunctionOperatorToken( nOpCode, nParamCount, mnLeadingSpaces, mnClosingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushFunctionOperator( const FunctionInfo& rFuncInfo, size_t nParamCount )
+{
+ return pushFunctionOperatorToken( rFuncInfo, nParamCount, mnLeadingSpaces, mnClosingSpaces ) && resetSpaces();
+}
+
+// reference conversion -------------------------------------------------------
+
+void FormulaParserImpl::initReference2d( SingleReference& orApiRef ) const
+{
+ if( mpContext->isAlways3dRefs() )
+ {
+ initReference3d( orApiRef, mpContext->getBaseAddress().Sheet );
+ }
+ else
+ {
+ orApiRef.Flags = SHEET_RELATIVE;
+ // #i10184# absolute sheet index needed for relative references in shared formulas
+ orApiRef.Sheet = mpContext->getBaseAddress().Sheet;
+ orApiRef.RelativeSheet = 0;
+ }
+}
+
+void FormulaParserImpl::initReference3d( SingleReference& orApiRef, sal_Int32 nSheet ) const
+{
+ orApiRef.Flags = SHEET_3D;
+ if( nSheet < 0 )
+ {
+ orApiRef.Sheet = 0;
+ orApiRef.Flags |= SHEET_DELETED;
+ }
+ else
+ {
+ orApiRef.Sheet = nSheet;
+ }
+}
+
+void FormulaParserImpl::convertReference( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ if( bDeleted )
+ {
+ orApiRef.Column = 0;
+ orApiRef.Row = 0;
+ // no explicit information about whether row or column is deleted
+ orApiRef.Flags |= COLUMN_DELETED | ROW_DELETED;
+ }
+ else
+ {
+ // column/row indexes and flags
+ setFlag( orApiRef.Flags, COLUMN_RELATIVE, rRef.mbColRel );
+ setFlag( orApiRef.Flags, ROW_RELATIVE, rRef.mbRowRel );
+ (rRef.mbColRel ? orApiRef.RelativeColumn : orApiRef.Column) = rRef.mnCol;
+ (rRef.mbRowRel ? orApiRef.RelativeRow : orApiRef.Row) = rRef.mnRow;
+ // convert absolute indexes to relative offsets used in API
+ if( !bRelativeAsOffset )
+ {
+ if( rRef.mbColRel )
+ orApiRef.RelativeColumn -= mpContext->getBaseAddress().Column;
+ if( rRef.mbRowRel )
+ orApiRef.RelativeRow -= mpContext->getBaseAddress().Row;
+ }
+ }
+}
+
+void FormulaParserImpl::convertReference( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ convertReference( orApiRef.Reference1, rRef1, bDeleted, bRelativeAsOffset );
+ convertReference( orApiRef.Reference2, rRef2, bDeleted, bRelativeAsOffset );
+ /* Handle references to complete rows or columns (e.g. $1:$2 or C:D),
+ need to expand or shrink to limits of own document. */
+ if( !bDeleted && !rRef1.mbColRel && !rRef2.mbColRel && (orApiRef.Reference1.Column == 0) && (orApiRef.Reference2.Column == mnMaxXlsCol) )
+ orApiRef.Reference2.Column = mnMaxApiCol;
+ if( !bDeleted && !rRef1.mbRowRel && !rRef2.mbRowRel && (orApiRef.Reference1.Row == 0) && (orApiRef.Reference2.Row == mnMaxXlsRow) )
+ orApiRef.Reference2.Row = mnMaxApiRow;
+}
+
+void FormulaParserImpl::convertReference2d( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ initReference2d( orApiRef );
+ convertReference( orApiRef, rRef, bDeleted, bRelativeAsOffset );
+}
+
+void FormulaParserImpl::convertReference2d( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ initReference2d( orApiRef.Reference1 );
+ initReference2d( orApiRef.Reference2 );
+ convertReference( orApiRef, rRef1, rRef2, bDeleted, bRelativeAsOffset );
+ // remove sheet name from second part of reference
+ setFlag( orApiRef.Reference2.Flags, SHEET_3D, false );
+}
+
+void FormulaParserImpl::convertReference3d( SingleReference& orApiRef, sal_Int32 nSheet, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ initReference3d( orApiRef, nSheet );
+ convertReference( orApiRef, rRef, bDeleted, bRelativeAsOffset );
+}
+
+void FormulaParserImpl::convertReference3d( ComplexReference& orApiRef, const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ initReference3d( orApiRef.Reference1, rSheetRange.isDeleted() ? -1 : rSheetRange.mnFirst );
+ initReference3d( orApiRef.Reference2, rSheetRange.isDeleted() ? -1 : rSheetRange.mnLast );
+ convertReference( orApiRef, rRef1, rRef2, bDeleted, bRelativeAsOffset );
+ // remove sheet name from second part of reference
+ setFlag( orApiRef.Reference2.Flags, SHEET_3D, rSheetRange.is3dRange() );
+}
+
+// finalize token sequence ----------------------------------------------------
+
+void FormulaParserImpl::processTokens( const ApiToken* pToken, const ApiToken* pTokenEnd )
+{
+ while( pToken < pTokenEnd )
+ {
+ // push the current token into the vector
+ appendFinalToken( *pToken );
+ // try to process a function, otherwise go to next token
+ if( const FunctionInfo* pFuncInfo = mrFuncProv.getFuncInfoFromApiToken( *pToken ) )
+ pToken = processParameters( *pFuncInfo, pToken + 1, pTokenEnd );
+ else
+ ++pToken;
+ }
+}
+
+const ApiToken* FormulaParserImpl::processParameters(
+ const FunctionInfo& rFuncInfo, const ApiToken* pToken, const ApiToken* pTokenEnd )
+{
+ // remember position of the token containing the function op-code
+ size_t nFuncNameIdx = maTokenStorage.size() - 1;
+
+ // process a function, if an OPCODE_OPEN token is following
+ OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_OPEN), "FormulaParserImpl::processParameters - OPCODE_OPEN expected" );
+ if( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_OPEN) )
+ {
+ // append the OPCODE_OPEN token to the vector
+ appendFinalToken( mrFuncProv.OPCODE_OPEN );
+
+ // store positions of OPCODE_OPEN, parameter separators, and OPCODE_CLOSE
+ ParameterPosVector aParams;
+ pToken = findParameters( aParams, pToken, pTokenEnd );
+ OSL_ENSURE( aParams.size() >= 2, "FormulaParserImpl::processParameters - missing tokens" );
+ size_t nParamCount = aParams.size() - 1;
+
+ if( (nParamCount == 1) && isEmptyParameter( aParams[ 0 ] + 1, aParams[ 1 ] ) )
+ {
+ /* Empty pair of parentheses -> function call without parameters,
+ process parameter, there might be spaces between parentheses. */
+ processTokens( aParams[ 0 ] + 1, aParams[ 1 ] );
+ }
+ else
+ {
+ const FunctionInfo* pRealFuncInfo = &rFuncInfo;
+ ParameterPosVector::const_iterator aPosIt = aParams.begin();
+
+ // preprocess add-ins, first parameter is reference to function name
+ if( rFuncInfo.mnOobFuncId == OOBIN_FUNC_EXTERNCALL )
+ {
+ OUString aName = getExternCallParameter( *aPosIt + 1, *(aPosIt + 1) );
+ if( const FunctionInfo* pExtFuncInfo = mrFuncProv.getFuncInfoFromExternCallName( aName ) )
+ {
+ maTokenStorage[ nFuncNameIdx ].OpCode = pExtFuncInfo->mnApiOpCode;
+ // insert programmatic add-in function name
+ if( pExtFuncInfo->mnApiOpCode == mrFuncProv.OPCODE_EXTERNAL )
+ maTokenStorage[ nFuncNameIdx ].Data <<= pExtFuncInfo->maExtProgName;
+ // prepare for following parameters
+ pRealFuncInfo = pExtFuncInfo;
+ --nParamCount;
+ ++aPosIt;
+ }
+ }
+
+ // process all parameters
+ FuncInfoParamClassIterator aClassIt( *pRealFuncInfo );
+ size_t nLastValidSize = maTokenStorage.size();
+ size_t nLastValidCount = 0;
+ for( size_t nParam = 0; nParam < nParamCount; ++nParam, ++aPosIt, ++aClassIt )
+ {
+ // add embedded Calc-only parameters
+ if( aClassIt.isCalcOnlyParam() )
+ {
+ appendCalcOnlyParameter( *pRealFuncInfo, nParam );
+ while( aClassIt.isCalcOnlyParam() ) ++aClassIt;
+ }
+
+ const ApiToken* pParamBegin = *aPosIt + 1;
+ const ApiToken* pParamEnd = *(aPosIt + 1);
+ bool bIsEmpty = isEmptyParameter( pParamBegin, pParamEnd );
+
+ if( !aClassIt.isExcelOnlyParam() )
+ {
+ // replace empty second and third parameter in IF function with zeros
+ if( (pRealFuncInfo->mnOobFuncId == OOBIN_FUNC_IF) && ((nParam == 1) || (nParam == 2)) && bIsEmpty )
+ {
+ appendFinalToken( mrFuncProv.OPCODE_PUSH ) <<= static_cast< double >( 0.0 );
+ bIsEmpty = false;
+ }
+ else
+ {
+ // process all tokens of the parameter
+ processTokens( pParamBegin, pParamEnd );
+ }
+ // append parameter separator token
+ appendFinalToken( mrFuncProv.OPCODE_SEP );
+ }
+
+ /* #84453# Update size of new token sequence with valid parameters
+ to be able to remove trailing optional empty parameters. */
+ if( !bIsEmpty || (nParam < pRealFuncInfo->mnMinParamCount) )
+ {
+ nLastValidSize = maTokenStorage.size();
+ nLastValidCount = nParam + 1;
+ }
+ }
+
+ // #84453# remove trailing optional empty parameters
+ maTokenStorage.resize( nLastValidSize );
+
+ // add trailing Calc-only parameters
+ if( aClassIt.isCalcOnlyParam() )
+ appendCalcOnlyParameter( *pRealFuncInfo, nLastValidCount );
+
+ // add optional parameters that are required in Calc
+ appendRequiredParameters( *pRealFuncInfo, nLastValidCount );
+
+ // remove last parameter separator token
+ if( maTokenStorage.back().OpCode == mrFuncProv.OPCODE_SEP )
+ maTokenStorage.pop_back();
+ }
+
+ /* Append the OPCODE_CLOSE token to the vector, but only if there is
+ no OPCODE_BAD token at the end, this token already contains the
+ trailing closing parentheses. */
+ if( (pTokenEnd - 1)->OpCode != mrFuncProv.OPCODE_BAD )
+ appendFinalToken( mrFuncProv.OPCODE_CLOSE );
+ }
+
+ /* Replace OPCODE_EXTERNAL with OPCODE_NONAME to get #NAME! error in cell,
+ if no matching add-in function was found. */
+ ApiToken& rFuncNameToken = maTokenStorage[ nFuncNameIdx ];
+ if( (rFuncNameToken.OpCode == mrFuncProv.OPCODE_EXTERNAL) && !rFuncNameToken.Data.hasValue() )
+ rFuncNameToken.OpCode = mrFuncProv.OPCODE_NONAME;
+
+ return pToken;
+}
+
+bool FormulaParserImpl::isEmptyParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ while( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_SPACES) ) ++pToken;
+ if( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_MISSING) ) ++pToken;
+ while( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_SPACES) ) ++pToken;
+ return pToken == pTokenEnd;
+}
+
+OUString FormulaParserImpl::getExternCallParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ OUString aExtCallName;
+ while( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_SPACES) ) ++pToken;
+ if( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_MACRO) ) (pToken++)->Data >>= aExtCallName;
+ while( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_SPACES) ) ++pToken;
+ return (pToken == pTokenEnd) ? aExtCallName : OUString();
+}
+
+const ApiToken* FormulaParserImpl::skipParentheses( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ // skip tokens between OPCODE_OPEN and OPCODE_CLOSE
+ OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_OPEN), "skipParentheses - OPCODE_OPEN expected" );
+ ++pToken;
+ while( (pToken < pTokenEnd) && (pToken->OpCode != mrFuncProv.OPCODE_CLOSE) )
+ {
+ if( pToken->OpCode == mrFuncProv.OPCODE_OPEN )
+ pToken = skipParentheses( pToken, pTokenEnd );
+ else
+ ++pToken;
+ }
+ // skip the OPCODE_CLOSE token
+ OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode == mrFuncProv.OPCODE_BAD), "skipParentheses - OPCODE_CLOSE expected" );
+ return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
+}
+
+const ApiToken* FormulaParserImpl::findParameters( ParameterPosVector& rParams,
+ const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ // push position of OPCODE_OPEN
+ OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_OPEN), "FormulaParserImpl::findParameters - OPCODE_OPEN expected" );
+ rParams.push_back( pToken++ );
+
+ // find positions of parameter separators
+ while( (pToken < pTokenEnd) && (pToken->OpCode != mrFuncProv.OPCODE_CLOSE) )
+ {
+ if( pToken->OpCode == mrFuncProv.OPCODE_OPEN )
+ pToken = skipParentheses( pToken, pTokenEnd );
+ else if( pToken->OpCode == mrFuncProv.OPCODE_SEP )
+ rParams.push_back( pToken++ );
+ else
+ ++pToken;
+ }
+
+ // push position of OPCODE_CLOSE
+ OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode == mrFuncProv.OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode == mrFuncProv.OPCODE_BAD), "FormulaParserImpl::findParameters - OPCODE_CLOSE expected" );
+ rParams.push_back( pToken );
+ return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
+}
+
+void FormulaParserImpl::appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam )
+{
+ (void)nParam; // prevent 'unused' warning
+ switch( rFuncInfo.mnOobFuncId )
+ {
+ case OOBIN_FUNC_FLOOR:
+ case OOBIN_FUNC_CEILING:
+ OSL_ENSURE( nParam == 2, "FormulaParserImpl::appendCalcOnlyParameter - unexpected parameter index" );
+ appendFinalToken( mrFuncProv.OPCODE_PUSH ) <<= static_cast< double >( 1.0 );
+ appendFinalToken( mrFuncProv.OPCODE_SEP );
+ break;
+ }
+}
+
+void FormulaParserImpl::appendRequiredParameters( const FunctionInfo& rFuncInfo, size_t nParamCount )
+{
+ switch( rFuncInfo.mnOobFuncId )
+ {
+ case OOBIN_FUNC_WEEKNUM:
+ if( nParamCount == 1 )
+ {
+ appendFinalToken( mrFuncProv.OPCODE_PUSH ) <<= static_cast< double >( 1.0 );
+ appendFinalToken( mrFuncProv.OPCODE_SEP );
+ }
+ break;
+ }
+}
+
+void FormulaParserImpl::appendFinalToken( const ApiToken& rToken )
+{
+ if( (rToken.OpCode == mrFuncProv.OPCODE_MACRO) && !rToken.Data.hasValue() )
+ {
+ appendFinalToken( mrFuncProv.OPCODE_ARRAY_OPEN );
+ appendFinalToken( mrFuncProv.OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( BIFF_ERR_NAME );
+ appendFinalToken( mrFuncProv.OPCODE_ARRAY_CLOSE );
+ }
+ else
+ maTokenStorage.push_back( rToken );
+}
+
+Any& FormulaParserImpl::appendFinalToken( sal_Int32 nOpCode )
+{
+ maTokenStorage.resize( maTokenStorage.size() + 1 );
+ maTokenStorage.back().OpCode = nOpCode;
+ return maTokenStorage.back().Data;
+}
+
+// OOX parser implementation ==================================================
+
+class OoxFormulaParserImpl : public FormulaParserImpl
+{
+public:
+ explicit OoxFormulaParserImpl(
+ const WorkbookHelper& rHelper,
+ const FunctionProvider& rFuncProv );
+
+ virtual void importOoxFormula(
+ FormulaContext& rContext,
+ const OUString& rFormulaString );
+
+ virtual void importOobFormula(
+ FormulaContext& rContext,
+ RecordInputStream& rStrm );
+
+private:
+ // import token contents and create API formula token ---------------------
+
+ bool importAttrToken( RecordInputStream& rStrm );
+ bool importSpaceToken( RecordInputStream& rStrm );
+ bool importTableToken( RecordInputStream& rStrm );
+ bool importArrayToken( RecordInputStream& rStrm );
+ bool importRefToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importAreaToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importRef3dToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importArea3dToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importMemAreaToken( RecordInputStream& rStrm, bool bAddData );
+ bool importMemFuncToken( RecordInputStream& rStrm );
+ bool importNameToken( RecordInputStream& rStrm );
+ bool importNameXToken( RecordInputStream& rStrm );
+ bool importFuncToken( RecordInputStream& rStrm );
+ bool importFuncVarToken( RecordInputStream& rStrm );
+ bool importExpToken( RecordInputStream& rStrm );
+
+ LinkSheetRange readSheetRange( RecordInputStream& rStrm );
+
+ void swapStreamPosition( RecordInputStream& rStrm );
+ void skipMemAreaAddData( RecordInputStream& rStrm );
+
+ // convert BIN token and push API operand or operator ---------------------
+
+ bool pushOobName( sal_Int32 nNameId );
+ bool pushOobExtName( sal_Int32 nRefId, sal_Int32 nNameId );
+ bool pushOobFunction( sal_uInt16 nFuncId );
+ bool pushOobFunction( sal_uInt16 nFuncId, sal_uInt8 nParamCount );
+
+private:
+ Reference< XFormulaParser > mxParser;
+ PropertySet maParserProps;
+ const OUString maRefPosProp;
+ sal_Int32 mnAddDataPos; /// Current stream position for additional data (tExp, tArray, tMemArea).
+};
+
+// ----------------------------------------------------------------------------
+
+OoxFormulaParserImpl::OoxFormulaParserImpl( const WorkbookHelper& rHelper, const FunctionProvider& rFuncProv ) :
+ FormulaParserImpl( rHelper, rFuncProv ),
+ maRefPosProp( CREATE_OUSTRING( "ReferencePosition" ) ),
+ mnAddDataPos( 0 )
+{
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW );
+ mxParser.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( mxParser.is(), "OoxFormulaParserImpl::OoxFormulaParserImpl - cannot create formula parser" );
+ maParserProps.set( mxParser );
+ maParserProps.setProperty( CREATE_OUSTRING( "CompileEnglish" ), true );
+ maParserProps.setProperty( CREATE_OUSTRING( "R1C1Notation" ), false );
+ maParserProps.setProperty( CREATE_OUSTRING( "Compatibility3DNotation" ), true );
+ maParserProps.setProperty( CREATE_OUSTRING( "IgnoreLeadingSpaces" ), false );
+ maParserProps.setProperty( CREATE_OUSTRING( "OpCodeMap" ), mrFuncProv.getOoxParserMap() );
+}
+
+void OoxFormulaParserImpl::importOoxFormula(
+ FormulaContext& rContext, const OUString& rFormulaString )
+{
+ if( mxParser.is() )
+ {
+ initializeImport( rContext );
+ maParserProps.setProperty( maRefPosProp, getFormulaContext().getBaseAddress() );
+ finalizeImport( mxParser->parseFormula( rFormulaString ) );
+ }
+}
+
+void OoxFormulaParserImpl::importOobFormula( FormulaContext& rContext, RecordInputStream& rStrm )
+{
+ initializeImport( rContext );
+
+ sal_Int32 nFmlaSize = rStrm.readInt32();
+ sal_Int32 nFmlaPos = rStrm.getRecPos();
+ sal_Int32 nFmlaEndPos = nFmlaPos + nFmlaSize;
+
+ rStrm.seek( nFmlaEndPos );
+ sal_Int32 nAddDataSize = rStrm.readInt32();
+ mnAddDataPos = rStrm.getRecPos();
+ sal_Int32 nAddDataEndPos = mnAddDataPos + nAddDataSize;
+ rStrm.seek( nFmlaPos );
+
+ bool bOk = (nFmlaSize >= 0) && (nAddDataSize >= 0);
+ bool bRelativeAsOffset = getFormulaContext().isRelativeAsOffset();
+
+ while( bOk && rStrm.isValid() && (rStrm.getRecPos() < nFmlaEndPos) )
+ {
+ sal_uInt8 nTokenId;
+ rStrm >> nTokenId;
+ sal_uInt8 nTokenClass = nTokenId & BIFF_TOKCLASS_MASK;
+ sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
+
+ if( nTokenClass == BIFF_TOKCLASS_NONE )
+ {
+ // base tokens
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_EXP: bOk = importExpToken( rStrm ); break;
+ case BIFF_TOKID_ADD: bOk = pushBinaryOperator( mrFuncProv.OPCODE_ADD ); break;
+ case BIFF_TOKID_SUB: bOk = pushBinaryOperator( mrFuncProv.OPCODE_SUB ); break;
+ case BIFF_TOKID_MUL: bOk = pushBinaryOperator( mrFuncProv.OPCODE_MULT ); break;
+ case BIFF_TOKID_DIV: bOk = pushBinaryOperator( mrFuncProv.OPCODE_DIV ); break;
+ case BIFF_TOKID_POWER: bOk = pushBinaryOperator( mrFuncProv.OPCODE_POWER ); break;
+ case BIFF_TOKID_CONCAT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_CONCAT ); break;
+ case BIFF_TOKID_LT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_LESS ); break;
+ case BIFF_TOKID_LE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_LESS_EQUAL ); break;
+ case BIFF_TOKID_EQ: bOk = pushBinaryOperator( mrFuncProv.OPCODE_EQUAL ); break;
+ case BIFF_TOKID_GE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_GREATER_EQUAL ); break;
+ case BIFF_TOKID_GT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_GREATER ); break;
+ case BIFF_TOKID_NE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_NOT_EQUAL ); break;
+ case BIFF_TOKID_ISECT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_INTERSECT ); break;
+ case BIFF_TOKID_LIST: bOk = pushBinaryOperator( mrFuncProv.OPCODE_LIST ); break;
+ case BIFF_TOKID_RANGE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_RANGE ); break;
+ case BIFF_TOKID_UPLUS: bOk = pushUnaryPreOperator( mrFuncProv.OPCODE_PLUS_SIGN ); break;
+ case BIFF_TOKID_UMINUS: bOk = pushUnaryPreOperator( mrFuncProv.OPCODE_MINUS_SIGN ); break;
+ case BIFF_TOKID_PERCENT: bOk = pushUnaryPostOperator( mrFuncProv.OPCODE_PERCENT ); break;
+ case BIFF_TOKID_PAREN: bOk = pushParenthesesOperator(); break;
+ case BIFF_TOKID_MISSARG: bOk = pushOperand( mrFuncProv.OPCODE_MISSING ); break;
+ case BIFF_TOKID_STR: bOk = pushValueOperand( rStrm.readString( false ) ); break;
+ case BIFF_TOKID_NLR: bOk = importTableToken( rStrm ); break;
+ case BIFF_TOKID_ATTR: bOk = importAttrToken( rStrm ); break;
+ case BIFF_TOKID_ERR: bOk = pushBiffErrorOperand( rStrm.readuInt8() ); break;
+ case BIFF_TOKID_BOOL: bOk = pushBoolOperand( rStrm.readuInt8() != BIFF_TOK_BOOL_FALSE ); break;
+ case BIFF_TOKID_INT: bOk = pushValueOperand< double >( rStrm.readuInt16() ); break;
+ case BIFF_TOKID_NUM: bOk = pushValueOperand( rStrm.readDouble() ); break;
+ default: bOk = false;
+ }
+ }
+ else
+ {
+ // classified tokens
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_ARRAY: bOk = importArrayToken( rStrm ); break;
+ case BIFF_TOKID_FUNC: bOk = importFuncToken( rStrm ); break;
+ case BIFF_TOKID_FUNCVAR: bOk = importFuncVarToken( rStrm ); break;
+ case BIFF_TOKID_NAME: bOk = importNameToken( rStrm ); break;
+ case BIFF_TOKID_REF: bOk = importRefToken( rStrm, false, false ); break;
+ case BIFF_TOKID_AREA: bOk = importAreaToken( rStrm, false, false ); break;
+ case BIFF_TOKID_MEMAREA: bOk = importMemAreaToken( rStrm, true ); break;
+ case BIFF_TOKID_MEMERR: bOk = importMemAreaToken( rStrm, false ); break;
+ case BIFF_TOKID_MEMNOMEM: bOk = importMemAreaToken( rStrm, false ); break;
+ case BIFF_TOKID_MEMFUNC: bOk = importMemFuncToken( rStrm ); break;
+ case BIFF_TOKID_REFERR: bOk = importRefToken( rStrm, true, false ); break;
+ case BIFF_TOKID_AREAERR: bOk = importAreaToken( rStrm, true, false ); break;
+ case BIFF_TOKID_REFN: bOk = importRefToken( rStrm, false, true ); break;
+ case BIFF_TOKID_AREAN: bOk = importAreaToken( rStrm, false, true ); break;
+ case BIFF_TOKID_MEMAREAN: bOk = importMemFuncToken( rStrm ); break;
+ case BIFF_TOKID_MEMNOMEMN: bOk = importMemFuncToken( rStrm ); break;
+ case BIFF_TOKID_NAMEX: bOk = importNameXToken( rStrm ); break;
+ case BIFF_TOKID_REF3D: bOk = importRef3dToken( rStrm, false, bRelativeAsOffset ); break;
+ case BIFF_TOKID_AREA3D: bOk = importArea3dToken( rStrm, false, bRelativeAsOffset ); break;
+ case BIFF_TOKID_REFERR3D: bOk = importRef3dToken( rStrm, true, bRelativeAsOffset ); break;
+ case BIFF_TOKID_AREAERR3D: bOk = importArea3dToken( rStrm, true, bRelativeAsOffset ); break;
+ default: bOk = false;
+ }
+ }
+ }
+
+ // build and finalize the token sequence
+ if( bOk && (rStrm.getRecPos() == nFmlaEndPos) && (mnAddDataPos == nAddDataEndPos) )
+ finalizeImport();
+
+ // seek behind token array
+ if( (nFmlaSize >= 0) && (nAddDataSize >= 0) )
+ rStrm.seek( nAddDataEndPos );
+}
+
+// import token contents and create API formula token -------------------------
+
+bool OoxFormulaParserImpl::importAttrToken( RecordInputStream& rStrm )
+{
+ bool bOk = true;
+ sal_uInt8 nType;
+ rStrm >> nType;
+ // equal flags in BIFF and OOBIN
+ switch( nType )
+ {
+ case OOBIN_TOK_ATTR_VOLATILE:
+ case OOBIN_TOK_ATTR_IF:
+ case OOBIN_TOK_ATTR_SKIP:
+ case OOBIN_TOK_ATTR_ASSIGN:
+ case OOBIN_TOK_ATTR_IFERROR:
+ rStrm.skip( 2 );
+ break;
+ case OOBIN_TOK_ATTR_CHOOSE:
+ rStrm.skip( 2 * rStrm.readuInt16() + 2 );
+ break;
+ case OOBIN_TOK_ATTR_SUM:
+ rStrm.skip( 2 );
+ bOk = pushOobFunction( OOBIN_FUNC_SUM, 1 );
+ break;
+ case OOBIN_TOK_ATTR_SPACE:
+ case OOBIN_TOK_ATTR_SPACE_VOLATILE:
+ bOk = importSpaceToken( rStrm );
+ break;
+ default:
+ bOk = false;
+ }
+ return bOk;
+}
+
+bool OoxFormulaParserImpl::importSpaceToken( RecordInputStream& rStrm )
+{
+ // equal constants in BIFF and OOX
+ sal_uInt8 nType, nCount;
+ rStrm >> nType >> nCount;
+ switch( nType )
+ {
+ case BIFF_TOK_ATTR_SPACE_SP:
+ case BIFF_TOK_ATTR_SPACE_BR:
+ incLeadingSpaces( nCount );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_OPEN:
+ case BIFF_TOK_ATTR_SPACE_BR_OPEN:
+ incOpeningSpaces( nCount );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_CLOSE:
+ case BIFF_TOK_ATTR_SPACE_BR_CLOSE:
+ incClosingSpaces( nCount );
+ break;
+ }
+ return true;
+}
+
+bool OoxFormulaParserImpl::importTableToken( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags, nTableId, nCol1, nCol2;
+ rStrm.skip( 3 );
+ rStrm >> nFlags >> nTableId;
+ rStrm.skip( 2 );
+ rStrm >> nCol1 >> nCol2;
+ TableRef xTable = getTables().getTable( nTableId );
+ sal_Int32 nTokenIndex = xTable.get() ? xTable->getTokenIndex() : -1;
+ if( nTokenIndex >= 0 )
+ {
+ sal_Int32 nWidth = xTable->getWidth();
+ sal_Int32 nHeight = xTable->getHeight();
+ sal_Int32 nStartCol = 0;
+ sal_Int32 nEndCol = nWidth - 1;
+ sal_Int32 nStartRow = 0;
+ sal_Int32 nEndRow = nHeight - 1;
+ bool bFixedStartRow = true;
+ bool bFixedHeight = false;
+
+ bool bSingleCol = getFlag( nFlags, OOBIN_TOK_TABLE_COLUMN );
+ bool bColRange = getFlag( nFlags, OOBIN_TOK_TABLE_COLRANGE );
+ bool bValidRef = !bSingleCol || !bColRange;
+ OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - illegal combination of single column and column range" );
+ if( bValidRef )
+ {
+ if( bSingleCol )
+ nStartCol = nEndCol = nCol1;
+ else if( bColRange )
+ { nStartCol = nCol1; nEndCol = nCol2; }
+ bValidRef = (nStartCol <= nEndCol) && (nEndCol < nWidth);
+ OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - invalid column range" );
+ }
+
+ if( bValidRef )
+ {
+ bool bAllRows = getFlag( nFlags, OOBIN_TOK_TABLE_ALL );
+ bool bHeaderRows = getFlag( nFlags, OOBIN_TOK_TABLE_HEADERS );
+ bool bDataRows = getFlag( nFlags, OOBIN_TOK_TABLE_DATA );
+ bool bTotalsRows = getFlag( nFlags, OOBIN_TOK_TABLE_TOTALS );
+ bool bThisRow = getFlag( nFlags, OOBIN_TOK_TABLE_THISROW );
+
+ sal_Int32 nStartDataRow = xTable->getHeaderRows();
+ sal_Int32 nEndDataRow = nEndRow - xTable->getTotalsRows();
+ bValidRef = (nStartRow <= nStartDataRow) && (nStartDataRow <= nEndDataRow) && (nEndDataRow <= nEndRow);
+ OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - invalid data row range" );
+ if( bValidRef )
+ {
+ if( bAllRows )
+ {
+ bValidRef = !bHeaderRows && !bDataRows && !bTotalsRows && !bThisRow;
+ OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#All] table token" );
+ }
+ else if( bHeaderRows )
+ {
+ bValidRef = !bTotalsRows && !bThisRow;
+ OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#Headers] table token" );
+ nEndRow = bDataRows ? nEndDataRow : (nStartDataRow - 1);
+ bFixedHeight = !bDataRows;
+ }
+ else if( bDataRows )
+ {
+ bValidRef = !bThisRow;
+ OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#Data] table token" );
+ nStartRow = nStartDataRow;
+ if( !bTotalsRows ) nEndRow = nEndDataRow;
+ }
+ else if( bTotalsRows )
+ {
+ bValidRef = !bThisRow;
+ OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#Totals] table token" );
+ nStartRow = nEndDataRow + 1;
+ bFixedStartRow = false;
+ bFixedHeight = !bDataRows;
+ }
+ else if( bThisRow )
+ {
+ nStartRow = nEndRow = getFormulaContext().getBaseAddress().Row - xTable->getRange().StartRow;
+ bFixedHeight = true;
+ }
+ else
+ {
+ // nothing is the same as [#Data]
+ nStartRow = nStartDataRow;
+ nEndRow = nEndDataRow;
+ }
+ }
+ if( bValidRef )
+ bValidRef = (0 <= nStartRow) && (nStartRow <= nEndRow) && (nEndRow < nHeight);
+ }
+ if( bValidRef )
+ {
+ // push single database area token, if table token refers to entire table
+ if( (nStartCol == 0) && (nEndCol + 1 == nWidth) && (nStartRow == 0) && (nEndRow + 1 == nHeight) )
+ return pushValueOperand( nTokenIndex, mrFuncProv.OPCODE_DBAREA );
+ // create an OFFSET function call to refer to a subrange of the table
+ const FunctionInfo* pRowsInfo = mrFuncProv.getFuncInfoFromOobFuncId( OOBIN_FUNC_ROWS );
+ const FunctionInfo* pColumnsInfo = mrFuncProv.getFuncInfoFromOobFuncId( OOBIN_FUNC_COLUMNS );
+ return
+ pRowsInfo && pColumnsInfo &&
+ pushValueOperandToken( nTokenIndex, mrFuncProv.OPCODE_DBAREA, 0 ) &&
+ (bFixedStartRow ?
+ pushValueOperandToken< double >( nStartRow, 0 ) :
+ (pushValueOperandToken( nTokenIndex, mrFuncProv.OPCODE_DBAREA, 0 ) &&
+ pushFunctionOperatorToken( *pRowsInfo, 1, 0, 0 ) &&
+ pushValueOperandToken< double >( nHeight - nStartRow, 0 ) &&
+ pushBinaryOperatorToken( mrFuncProv.OPCODE_SUB, 0 ))) &&
+ pushValueOperandToken< double >( nStartCol, 0 ) &&
+ (bFixedHeight ?
+ pushValueOperandToken< double >( nEndRow - nStartRow + 1, 0 ) :
+ (pushValueOperandToken( nTokenIndex, mrFuncProv.OPCODE_DBAREA, 0 ) &&
+ pushFunctionOperatorToken( *pRowsInfo, 1, 0, 0 ) &&
+ (((nStartRow == 0) && (nEndRow + 1 == nHeight)) ||
+ (pushValueOperandToken< double >( nHeight - (nEndRow - nStartRow + 1), 0 ) &&
+ pushBinaryOperatorToken( mrFuncProv.OPCODE_SUB, 0 ))))) &&
+ (((nStartCol == 0) && (nEndCol + 1 == nWidth)) ?
+ (pushValueOperandToken( nTokenIndex, mrFuncProv.OPCODE_DBAREA, 0 ) &&
+ pushFunctionOperatorToken( *pColumnsInfo, 1, 0, 0 )) :
+ pushValueOperandToken< double >( nEndCol - nStartCol + 1, 0 )) &&
+ pushOobFunction( OOBIN_FUNC_OFFSET, 5 );
+ }
+ }
+ return pushBiffErrorOperand( BIFF_ERR_REF );
+}
+
+bool OoxFormulaParserImpl::importArrayToken( RecordInputStream& rStrm )
+{
+ rStrm.skip( 14 );
+
+ // start token array with opening brace and leading spaces
+ pushOperand( mrFuncProv.OPCODE_ARRAY_OPEN );
+ size_t nOpSize = popOperandSize();
+ size_t nOldArraySize = getFormulaSize();
+
+ // read array size
+ swapStreamPosition( rStrm );
+ sal_Int32 nRows = rStrm.readInt32();
+ sal_Int32 nCols = rStrm.readInt32();
+ OSL_ENSURE( (nCols > 0) && (nRows > 0), "OoxFormulaParserImpl::importArrayToken - empty array" );
+
+ // read array values and build token array
+ for( sal_Int32 nRow = 0; rStrm.isValid() && (nRow < nRows); ++nRow )
+ {
+ if( nRow > 0 )
+ appendRawToken( mrFuncProv.OPCODE_ARRAY_ROWSEP );
+ for( sal_Int32 nCol = 0; rStrm.isValid() && (nCol < nCols); ++nCol )
+ {
+ if( nCol > 0 )
+ appendRawToken( mrFuncProv.OPCODE_ARRAY_COLSEP );
+ switch( rStrm.readuInt8() )
+ {
+ case OOBIN_TOK_ARRAY_DOUBLE:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= rStrm.readDouble();
+ break;
+ case OOBIN_TOK_ARRAY_STRING:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= rStrm.readString( false );
+ break;
+ case OOBIN_TOK_ARRAY_BOOL:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= static_cast< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
+ break;
+ case OOBIN_TOK_ARRAY_ERROR:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( rStrm.readuInt8() );
+ rStrm.skip( 3 );
+ break;
+ default:
+ OSL_ENSURE( false, "OoxFormulaParserImpl::importArrayToken - unknown data type" );
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( BIFF_ERR_NA );
+ }
+ }
+ }
+ swapStreamPosition( rStrm );
+
+ // close token array and set resulting operand size
+ appendRawToken( mrFuncProv.OPCODE_ARRAY_CLOSE );
+ pushOperandSize( nOpSize + getFormulaSize() - nOldArraySize );
+ return true;
+}
+
+bool OoxFormulaParserImpl::importRefToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinSingleRef2d aRef;
+ aRef.readOobData( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importAreaToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinComplexRef2d aRef;
+ aRef.readOobData( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importRef3dToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange( rStrm );
+ BinSingleRef2d aRef;
+ aRef.readOobData( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importArea3dToken( RecordInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange( rStrm );
+ BinComplexRef2d aRef;
+ aRef.readOobData( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importMemAreaToken( RecordInputStream& rStrm, bool bAddData )
+{
+ rStrm.skip( 6 );
+ if( bAddData )
+ skipMemAreaAddData( rStrm );
+ return true;
+}
+
+bool OoxFormulaParserImpl::importMemFuncToken( RecordInputStream& rStrm )
+{
+ rStrm.skip( 2 );
+ return true;
+}
+
+bool OoxFormulaParserImpl::importNameToken( RecordInputStream& rStrm )
+{
+ return pushOobName( rStrm.readInt32() );
+}
+
+bool OoxFormulaParserImpl::importNameXToken( RecordInputStream& rStrm )
+{
+ sal_Int32 nRefId = rStrm.readInt16();
+ sal_Int32 nNameId = rStrm.readInt32();
+ return pushOobExtName( nRefId, nNameId );
+}
+
+bool OoxFormulaParserImpl::importFuncToken( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFuncId;
+ rStrm >> nFuncId;
+ return pushOobFunction( nFuncId );
+}
+
+bool OoxFormulaParserImpl::importFuncVarToken( RecordInputStream& rStrm )
+{
+ sal_uInt8 nParamCount;
+ sal_uInt16 nFuncId;
+ rStrm >> nParamCount >> nFuncId;
+ return pushOobFunction( nFuncId, nParamCount );
+}
+
+bool OoxFormulaParserImpl::importExpToken( RecordInputStream& rStrm )
+{
+ BinAddress aBaseAddr;
+ rStrm >> aBaseAddr.mnRow;
+ swapStreamPosition( rStrm );
+ rStrm >> aBaseAddr.mnCol;
+ swapStreamPosition( rStrm );
+ setSharedFormula( aBaseAddr );
+ // formula has been set, exit parser by returning false
+ return false;
+}
+
+LinkSheetRange OoxFormulaParserImpl::readSheetRange( RecordInputStream& rStrm )
+{
+ return getExternalLinks().getSheetRange( rStrm.readInt16() );
+}
+
+void OoxFormulaParserImpl::swapStreamPosition( RecordInputStream& rStrm )
+{
+ sal_Int32 nRecPos = rStrm.getRecPos();
+ rStrm.seek( mnAddDataPos );
+ mnAddDataPos = nRecPos;
+}
+
+void OoxFormulaParserImpl::skipMemAreaAddData( RecordInputStream& rStrm )
+{
+ swapStreamPosition( rStrm );
+ rStrm.skip( 16 * rStrm.readInt32() );
+ swapStreamPosition( rStrm );
+}
+
+// convert BIN token and push API operand or operator -------------------------
+
+bool OoxFormulaParserImpl::pushOobName( sal_Int32 nNameId )
+{
+ // one-based in OOBIN formulas
+ return pushDefinedNameOperand( getDefinedNames().getByIndex( nNameId - 1 ) );
+}
+
+bool OoxFormulaParserImpl::pushOobExtName( sal_Int32 nRefId, sal_Int32 nNameId )
+{
+ if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
+ {
+ if( pExtLink->getLinkType() == LINKTYPE_SELF )
+ return pushOobName( nNameId );
+ // external name indexes are one-based in OOBIN
+ ExternalNameRef xExtName = pExtLink->getNameByIndex( nNameId - 1 );
+ return pushExternalNameOperand( xExtName, pExtLink->getLinkType() );
+ }
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool OoxFormulaParserImpl::pushOobFunction( sal_uInt16 nFuncId )
+{
+ if( const FunctionInfo* pFuncInfo = mrFuncProv.getFuncInfoFromOobFuncId( nFuncId ) )
+ if( pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount )
+ return pushFunctionOperator( *pFuncInfo, pFuncInfo->mnMinParamCount );
+ return pushFunctionOperator( mrFuncProv.OPCODE_NONAME, 0 );
+}
+
+bool OoxFormulaParserImpl::pushOobFunction( sal_uInt16 nFuncId, sal_uInt8 nParamCount )
+{
+ if( getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD ) )
+ nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
+ if( const FunctionInfo* pFuncInfo = mrFuncProv.getFuncInfoFromOobFuncId( nFuncId ) )
+ return pushFunctionOperator( *pFuncInfo, nParamCount );
+ return pushFunctionOperator( mrFuncProv.OPCODE_NONAME, nParamCount );
+}
+
+// BIFF parser implementation =================================================
+
+namespace {
+
+/** A natural language reference struct with relative flag. */
+struct BiffNlr
+{
+ sal_Int32 mnCol; /// Column index.
+ sal_Int32 mnRow; /// Row index.
+ bool mbRel; /// True = relative column/row reference.
+
+ explicit BiffNlr();
+
+ void readBiff8Data( BiffInputStream& rStrm );
+};
+
+BiffNlr::BiffNlr() :
+ mnCol( 0 ),
+ mnRow( 0 ),
+ mbRel( false )
+{
+}
+
+void BiffNlr::readBiff8Data( BiffInputStream& rStrm )
+{
+ sal_uInt16 nRow, nCol;
+ rStrm >> nRow >> nCol;
+ mnCol = nCol & BIFF_TOK_NLR_MASK;
+ mnRow = nRow;
+ mbRel = getFlag( nCol, BIFF_TOK_NLR_REL );
+}
+
+bool lclIsValidNlrStack( const BinAddress& rAddr1, const BinAddress& rAddr2, bool bRow )
+{
+ return bRow ?
+ ((rAddr1.mnRow == rAddr2.mnRow) && (rAddr1.mnCol + 1 == rAddr2.mnCol)) :
+ ((rAddr1.mnCol == rAddr2.mnCol) && (rAddr1.mnRow + 1 == rAddr2.mnRow));
+}
+
+bool lclIsValidNlrRange( const BiffNlr& rNlr, const BinRange& rRange, bool bRow )
+{
+ return bRow ?
+ ((rNlr.mnRow == rRange.maFirst.mnRow) && (rNlr.mnCol + 1 == rRange.maFirst.mnCol) && (rRange.maFirst.mnRow == rRange.maLast.mnRow)) :
+ ((rNlr.mnCol == rRange.maFirst.mnCol) && (rNlr.mnRow + 1 == rRange.maFirst.mnRow) && (rRange.maFirst.mnCol == rRange.maLast.mnCol));
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+class BiffFormulaParserImpl : public FormulaParserImpl
+{
+public:
+ explicit BiffFormulaParserImpl(
+ const WorkbookHelper& rHelper,
+ const FunctionProvider& rFuncProv );
+
+ virtual void importBiffFormula(
+ FormulaContext& rContext,
+ BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize );
+
+private:
+ // import token contents and create API formula token ---------------------
+
+ bool importTokenNotAvailable( BiffInputStream& rStrm );
+ bool importRefTokenNotAvailable( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importStrToken2( BiffInputStream& rStrm );
+ bool importStrToken8( BiffInputStream& rStrm );
+ bool importAttrToken( BiffInputStream& rStrm );
+ bool importSpaceToken3( BiffInputStream& rStrm );
+ bool importSpaceToken4( BiffInputStream& rStrm );
+ bool importSheetToken2( BiffInputStream& rStrm );
+ bool importSheetToken3( BiffInputStream& rStrm );
+ bool importEndSheetToken2( BiffInputStream& rStrm );
+ bool importEndSheetToken3( BiffInputStream& rStrm );
+ bool importNlrToken( BiffInputStream& rStrm );
+ bool importArrayToken( BiffInputStream& rStrm );
+ bool importRefToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importRefToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importAreaToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importAreaToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importRef3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importRef3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importArea3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importArea3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importMemAreaToken( BiffInputStream& rStrm, bool bAddData );
+ bool importMemFuncToken( BiffInputStream& rStrm );
+ bool importNameToken( BiffInputStream& rStrm );
+ bool importNameXToken( BiffInputStream& rStrm );
+ bool importFuncToken2( BiffInputStream& rStrm );
+ bool importFuncToken4( BiffInputStream& rStrm );
+ bool importFuncVarToken2( BiffInputStream& rStrm );
+ bool importFuncVarToken4( BiffInputStream& rStrm );
+ bool importFuncCEToken( BiffInputStream& rStrm );
+ bool importExpToken5( BiffInputStream& rStrm );
+
+ bool importNlrAddrToken( BiffInputStream& rStrm, bool bRow );
+ bool importNlrRangeToken( BiffInputStream& rStrm );
+ bool importNlrSAddrToken( BiffInputStream& rStrm, bool bRow );
+ bool importNlrSRangeToken( BiffInputStream& rStrm );
+ bool importNlrErrToken( BiffInputStream& rStrm, sal_uInt16 nSkip );
+
+ sal_Int32 readRefId( BiffInputStream& rStrm );
+ sal_uInt16 readNameId( BiffInputStream& rStrm );
+ LinkSheetRange readSheetRange5( BiffInputStream& rStrm );
+ LinkSheetRange readSheetRange8( BiffInputStream& rStrm );
+
+ void swapStreamPosition( BiffInputStream& rStrm );
+ void skipMemAreaAddData( BiffInputStream& rStrm );
+ bool readNlrSAddrAddData( BiffNlr& orNlr, BiffInputStream& rStrm, bool bRow );
+ bool readNlrSRangeAddData( BiffNlr& orNlr, bool& orbIsRow, BiffInputStream& rStrm );
+
+ // convert BIFF token and push API operand or operator --------------------
+
+ bool pushBiffReference( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
+ bool pushBiffReference( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
+ bool pushBiffNlrAddr( const BiffNlr& rNlr, bool bRow );
+ bool pushBiffNlrRange( const BiffNlr& rNlr, const BinRange& rRange );
+ bool pushBiffNlrSAddr( const BiffNlr& rNlr, bool bRow );
+ bool pushBiffNlrSRange( const BiffNlr& rNlr, const BinRange& rRange, bool bRow );
+ bool pushBiffName( sal_uInt16 nNameId );
+ bool pushBiffExtName( sal_Int32 nRefId, sal_uInt16 nNameId );
+ bool pushBiffFunction( sal_uInt16 nFuncId );
+ bool pushBiffFunction( sal_uInt16 nFuncId, sal_uInt8 nParamCount );
+
+ // ------------------------------------------------------------------------
+private:
+ typedef bool (BiffFormulaParserImpl::*ImportTokenFunc)( BiffInputStream& );
+ typedef bool (BiffFormulaParserImpl::*ImportRefTokenFunc)( BiffInputStream&, bool, bool );
+
+ ImportTokenFunc mpImportStrToken; /// Pointer to tStr import function (string constant).
+ ImportTokenFunc mpImportSpaceToken; /// Pointer to tAttrSpace import function (spaces/line breaks).
+ ImportTokenFunc mpImportSheetToken; /// Pointer to tSheet import function (external reference).
+ ImportTokenFunc mpImportEndSheetToken; /// Pointer to tEndSheet import function (end of external reference).
+ ImportTokenFunc mpImportNlrToken; /// Pointer to tNlr import function (natural language reference).
+ ImportRefTokenFunc mpImportRefToken; /// Pointer to tRef import function (2d cell reference).
+ ImportRefTokenFunc mpImportAreaToken; /// Pointer to tArea import function (2d area reference).
+ ImportRefTokenFunc mpImportRef3dToken; /// Pointer to tRef3d import function (3d cell reference).
+ ImportRefTokenFunc mpImportArea3dToken; /// Pointer to tArea3d import function (3d area reference).
+ ImportTokenFunc mpImportNameXToken; /// Pointer to tNameX import function (external name).
+ ImportTokenFunc mpImportFuncToken; /// Pointer to tFunc import function (function with fixed parameter count).
+ ImportTokenFunc mpImportFuncVarToken; /// Pointer to tFuncVar import function (function with variable parameter count).
+ ImportTokenFunc mpImportFuncCEToken; /// Pointer to tFuncCE import function (command macro call).
+ ImportTokenFunc mpImportExpToken; /// Pointer to tExp import function (array/shared formula).
+ sal_uInt32 mnAddDataPos; /// Current stream position for additional data (tArray, tMemArea, tNlr).
+ sal_Int32 mnCurrRefId; /// Current ref-id from tSheet token (BIFF2-BIFF4 only).
+ sal_uInt16 mnAttrDataSize; /// Size of one tAttr data element.
+ sal_uInt16 mnArraySize; /// Size of tArray data.
+ sal_uInt16 mnNameSize; /// Size of tName data.
+ sal_uInt16 mnMemAreaSize; /// Size of tMemArea data.
+ sal_uInt16 mnMemFuncSize; /// Size of tMemFunc data.
+ sal_uInt16 mnRefIdSize; /// Size of unused data following a reference identifier.
+};
+
+// ----------------------------------------------------------------------------
+
+BiffFormulaParserImpl::BiffFormulaParserImpl( const WorkbookHelper& rHelper, const FunctionProvider& rFuncProv ) :
+ FormulaParserImpl( rHelper, rFuncProv ),
+ mnAddDataPos( 0 ),
+ mnCurrRefId( 0 )
+{
+ switch( getBiff() )
+ {
+ case BIFF2:
+ mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
+ mpImportSpaceToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportSheetToken = &BiffFormulaParserImpl::importSheetToken2;
+ mpImportEndSheetToken = &BiffFormulaParserImpl::importEndSheetToken2;
+ mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
+ mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
+ mpImportRef3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
+ mpImportArea3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
+ mpImportNameXToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken2;
+ mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken2;
+ mpImportFuncCEToken = &BiffFormulaParserImpl::importFuncCEToken;
+ mpImportExpToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mnAttrDataSize = 1;
+ mnArraySize = 6;
+ mnNameSize = 5;
+ mnMemAreaSize = 4;
+ mnMemFuncSize = 1;
+ mnRefIdSize = 1;
+ break;
+ case BIFF3:
+ mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
+ mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken3;
+ mpImportSheetToken = &BiffFormulaParserImpl::importSheetToken3;
+ mpImportEndSheetToken = &BiffFormulaParserImpl::importEndSheetToken3;
+ mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
+ mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
+ mpImportRef3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
+ mpImportArea3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
+ mpImportNameXToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken2;
+ mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken2;
+ mpImportFuncCEToken = &BiffFormulaParserImpl::importFuncCEToken;
+ mpImportExpToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mnAttrDataSize = 2;
+ mnArraySize = 7;
+ mnNameSize = 8;
+ mnMemAreaSize = 6;
+ mnMemFuncSize = 2;
+ mnRefIdSize = 2;
+ break;
+ case BIFF4:
+ mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
+ mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken4;
+ mpImportSheetToken = &BiffFormulaParserImpl::importSheetToken3;
+ mpImportEndSheetToken = &BiffFormulaParserImpl::importEndSheetToken3;
+ mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
+ mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
+ mpImportRef3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
+ mpImportArea3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
+ mpImportNameXToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4;
+ mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4;
+ mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportExpToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mnAttrDataSize = 2;
+ mnArraySize = 7;
+ mnNameSize = 8;
+ mnMemAreaSize = 6;
+ mnMemFuncSize = 2;
+ mnRefIdSize = 2;
+ break;
+ case BIFF5:
+ mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
+ mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken4;
+ mpImportSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportEndSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
+ mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
+ mpImportRef3dToken = &BiffFormulaParserImpl::importRef3dToken5;
+ mpImportArea3dToken = &BiffFormulaParserImpl::importArea3dToken5;
+ mpImportNameXToken = &BiffFormulaParserImpl::importNameXToken;
+ mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4;
+ mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4;
+ mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportExpToken = &BiffFormulaParserImpl::importExpToken5;
+ mnAttrDataSize = 2;
+ mnArraySize = 7;
+ mnNameSize = 12;
+ mnMemAreaSize = 6;
+ mnMemFuncSize = 2;
+ mnRefIdSize = 8;
+ break;
+ case BIFF8:
+ mpImportStrToken = &BiffFormulaParserImpl::importStrToken8;
+ mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken4;
+ mpImportSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportEndSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportNlrToken = &BiffFormulaParserImpl::importNlrToken;
+ mpImportRefToken = &BiffFormulaParserImpl::importRefToken8;
+ mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken8;
+ mpImportRef3dToken = &BiffFormulaParserImpl::importRef3dToken8;
+ mpImportArea3dToken = &BiffFormulaParserImpl::importArea3dToken8;
+ mpImportNameXToken = &BiffFormulaParserImpl::importNameXToken;
+ mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4;
+ mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4;
+ mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable;
+ mpImportExpToken = &BiffFormulaParserImpl::importExpToken5;
+ mnAttrDataSize = 2;
+ mnArraySize = 7;
+ mnNameSize = 2;
+ mnMemAreaSize = 6;
+ mnMemFuncSize = 2;
+ mnRefIdSize = 0;
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+}
+
+void BiffFormulaParserImpl::importBiffFormula( FormulaContext& rContext,
+ BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize )
+{
+ initializeImport( rContext );
+ mnCurrRefId = 0;
+
+ sal_uInt16 nFmlaSize = pnFmlaSize ? *pnFmlaSize : ((getBiff() == BIFF2) ? rStrm.readuInt8() : rStrm.readuInt16());
+ sal_uInt32 nEndPos = mnAddDataPos = rStrm.getRecPos() + nFmlaSize;
+ bool bRelativeAsOffset = getFormulaContext().isRelativeAsOffset();
+
+ bool bOk = true;
+ while( bOk && rStrm.isValid() && (rStrm.getRecPos() < nEndPos) )
+ {
+ sal_uInt8 nTokenId;
+ rStrm >> nTokenId;
+ sal_uInt8 nTokenClass = nTokenId & BIFF_TOKCLASS_MASK;
+ sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
+
+ if( nTokenClass == BIFF_TOKCLASS_NONE )
+ {
+ // base tokens
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_EXP: bOk = (this->*mpImportExpToken)( rStrm ); break;
+ case BIFF_TOKID_TBL: bOk = false; /* multiple op. will be set externally */ break;
+ case BIFF_TOKID_ADD: bOk = pushBinaryOperator( mrFuncProv.OPCODE_ADD ); break;
+ case BIFF_TOKID_SUB: bOk = pushBinaryOperator( mrFuncProv.OPCODE_SUB ); break;
+ case BIFF_TOKID_MUL: bOk = pushBinaryOperator( mrFuncProv.OPCODE_MULT ); break;
+ case BIFF_TOKID_DIV: bOk = pushBinaryOperator( mrFuncProv.OPCODE_DIV ); break;
+ case BIFF_TOKID_POWER: bOk = pushBinaryOperator( mrFuncProv.OPCODE_POWER ); break;
+ case BIFF_TOKID_CONCAT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_CONCAT ); break;
+ case BIFF_TOKID_LT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_LESS ); break;
+ case BIFF_TOKID_LE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_LESS_EQUAL ); break;
+ case BIFF_TOKID_EQ: bOk = pushBinaryOperator( mrFuncProv.OPCODE_EQUAL ); break;
+ case BIFF_TOKID_GE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_GREATER_EQUAL ); break;
+ case BIFF_TOKID_GT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_GREATER ); break;
+ case BIFF_TOKID_NE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_NOT_EQUAL ); break;
+ case BIFF_TOKID_ISECT: bOk = pushBinaryOperator( mrFuncProv.OPCODE_INTERSECT ); break;
+ case BIFF_TOKID_LIST: bOk = pushBinaryOperator( mrFuncProv.OPCODE_LIST ); break;
+ case BIFF_TOKID_RANGE: bOk = pushBinaryOperator( mrFuncProv.OPCODE_RANGE ); break;
+ case BIFF_TOKID_UPLUS: bOk = pushUnaryPreOperator( mrFuncProv.OPCODE_PLUS_SIGN ); break;
+ case BIFF_TOKID_UMINUS: bOk = pushUnaryPreOperator( mrFuncProv.OPCODE_MINUS_SIGN ); break;
+ case BIFF_TOKID_PERCENT: bOk = pushUnaryPostOperator( mrFuncProv.OPCODE_PERCENT ); break;
+ case BIFF_TOKID_PAREN: bOk = pushParenthesesOperator(); break;
+ case BIFF_TOKID_MISSARG: bOk = pushOperand( mrFuncProv.OPCODE_MISSING ); break;
+ case BIFF_TOKID_STR: bOk = (this->*mpImportStrToken)( rStrm ); break;
+ case BIFF_TOKID_NLR: bOk = (this->*mpImportNlrToken)( rStrm ); break;
+ case BIFF_TOKID_ATTR: bOk = importAttrToken( rStrm ); break;
+ case BIFF_TOKID_SHEET: bOk = (this->*mpImportSheetToken)( rStrm ); break;
+ case BIFF_TOKID_ENDSHEET: bOk = (this->*mpImportEndSheetToken)( rStrm ); break;
+ case BIFF_TOKID_ERR: bOk = pushBiffErrorOperand( rStrm.readuInt8() ); break;
+ case BIFF_TOKID_BOOL: bOk = pushBoolOperand( rStrm.readuInt8() != BIFF_TOK_BOOL_FALSE ); break;
+ case BIFF_TOKID_INT: bOk = pushValueOperand< double >( rStrm.readuInt16() ); break;
+ case BIFF_TOKID_NUM: bOk = pushValueOperand( rStrm.readDouble() ); break;
+ default: bOk = false;
+ }
+ }
+ else
+ {
+ // classified tokens
+ switch( nBaseId )
+ {
+ case BIFF_TOKID_ARRAY: bOk = importArrayToken( rStrm ); break;
+ case BIFF_TOKID_FUNC: bOk = (this->*mpImportFuncToken)( rStrm ); break;
+ case BIFF_TOKID_FUNCVAR: bOk = (this->*mpImportFuncVarToken)( rStrm ); break;
+ case BIFF_TOKID_NAME: bOk = importNameToken( rStrm ); break;
+ case BIFF_TOKID_REF: bOk = (this->*mpImportRefToken)( rStrm, false, false ); break;
+ case BIFF_TOKID_AREA: bOk = (this->*mpImportAreaToken)( rStrm, false, false ); break;
+ case BIFF_TOKID_MEMAREA: bOk = importMemAreaToken( rStrm, true ); break;
+ case BIFF_TOKID_MEMERR: bOk = importMemAreaToken( rStrm, false ); break;
+ case BIFF_TOKID_MEMNOMEM: bOk = importMemAreaToken( rStrm, false ); break;
+ case BIFF_TOKID_MEMFUNC: bOk = importMemFuncToken( rStrm ); break;
+ case BIFF_TOKID_REFERR: bOk = (this->*mpImportRefToken)( rStrm, true, false ); break;
+ case BIFF_TOKID_AREAERR: bOk = (this->*mpImportAreaToken)( rStrm, true, false ); break;
+ case BIFF_TOKID_REFN: bOk = (this->*mpImportRefToken)( rStrm, false, true ); break;
+ case BIFF_TOKID_AREAN: bOk = (this->*mpImportAreaToken)( rStrm, false, true ); break;
+ case BIFF_TOKID_MEMAREAN: bOk = importMemFuncToken( rStrm ); break;
+ case BIFF_TOKID_MEMNOMEMN: bOk = importMemFuncToken( rStrm ); break;
+ case BIFF_TOKID_FUNCCE: bOk = (this->*mpImportFuncCEToken)( rStrm ); break;
+ case BIFF_TOKID_NAMEX: bOk = (this->*mpImportNameXToken)( rStrm ); break;
+ case BIFF_TOKID_REF3D: bOk = (this->*mpImportRef3dToken)( rStrm, false, bRelativeAsOffset ); break;
+ case BIFF_TOKID_AREA3D: bOk = (this->*mpImportArea3dToken)( rStrm, false, bRelativeAsOffset ); break;
+ case BIFF_TOKID_REFERR3D: bOk = (this->*mpImportRef3dToken)( rStrm, true, bRelativeAsOffset ); break;
+ case BIFF_TOKID_AREAERR3D: bOk = (this->*mpImportArea3dToken)( rStrm, true, bRelativeAsOffset ); break;
+ default: bOk = false;
+ }
+ }
+ }
+
+ // build and finalize the token sequence
+ if( bOk && (rStrm.getRecPos() == nEndPos) )
+ finalizeImport();
+
+ // seek behind additional token data of tArray, tMemArea, tNlr tokens
+ rStrm.seek( mnAddDataPos );
+}
+
+// import token contents and create API formula token -------------------------
+
+bool BiffFormulaParserImpl::importTokenNotAvailable( BiffInputStream& )
+{
+ // dummy function for pointer-to-member-function
+ return false;
+}
+
+bool BiffFormulaParserImpl::importRefTokenNotAvailable( BiffInputStream&, bool, bool )
+{
+ // dummy function for pointer-to-member-function
+ return false;
+}
+
+bool BiffFormulaParserImpl::importStrToken2( BiffInputStream& rStrm )
+{
+ return pushValueOperand( rStrm.readByteString( false, getTextEncoding() ) );
+}
+
+bool BiffFormulaParserImpl::importStrToken8( BiffInputStream& rStrm )
+{
+ // read flags field for empty strings also
+ return pushValueOperand( rStrm.readUniString( rStrm.readuInt8() ) );
+}
+
+bool BiffFormulaParserImpl::importAttrToken( BiffInputStream& rStrm )
+{
+ bool bOk = true;
+ sal_uInt8 nType;
+ rStrm >> nType;
+ switch( nType )
+ {
+ case BIFF_TOK_ATTR_VOLATILE:
+ case BIFF_TOK_ATTR_IF:
+ case BIFF_TOK_ATTR_SKIP:
+ case BIFF_TOK_ATTR_ASSIGN:
+ rStrm.skip( mnAttrDataSize );
+ break;
+ case BIFF_TOK_ATTR_CHOOSE:
+ rStrm.skip( mnAttrDataSize * (1 + ((getBiff() == BIFF2) ? rStrm.readuInt8() : rStrm.readuInt16())) );
+ break;
+ case BIFF_TOK_ATTR_SUM:
+ rStrm.skip( mnAttrDataSize );
+ bOk = pushBiffFunction( BIFF_FUNC_SUM, 1 );
+ break;
+ case BIFF_TOK_ATTR_SPACE:
+ case BIFF_TOK_ATTR_SPACE_VOLATILE:
+ bOk = (this->*mpImportSpaceToken)( rStrm );
+ break;
+ default:
+ bOk = false;
+ }
+ return bOk;
+}
+
+bool BiffFormulaParserImpl::importSpaceToken3( BiffInputStream& rStrm )
+{
+ rStrm.skip( 2 );
+ return true;
+}
+
+bool BiffFormulaParserImpl::importSpaceToken4( BiffInputStream& rStrm )
+{
+ sal_uInt8 nType, nCount;
+ rStrm >> nType >> nCount;
+ switch( nType )
+ {
+ case BIFF_TOK_ATTR_SPACE_SP:
+ case BIFF_TOK_ATTR_SPACE_BR:
+ incLeadingSpaces( nCount );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_OPEN:
+ case BIFF_TOK_ATTR_SPACE_BR_OPEN:
+ incOpeningSpaces( nCount );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_CLOSE:
+ case BIFF_TOK_ATTR_SPACE_BR_CLOSE:
+ incClosingSpaces( nCount );
+ break;
+ }
+ return true;
+}
+
+bool BiffFormulaParserImpl::importSheetToken2( BiffInputStream& rStrm )
+{
+ rStrm.skip( 4 );
+ mnCurrRefId = readRefId( rStrm );
+ return true;
+}
+
+bool BiffFormulaParserImpl::importSheetToken3( BiffInputStream& rStrm )
+{
+ rStrm.skip( 6 );
+ mnCurrRefId = readRefId( rStrm );
+ return true;
+}
+
+bool BiffFormulaParserImpl::importEndSheetToken2( BiffInputStream& rStrm )
+{
+ rStrm.skip( 3 );
+ mnCurrRefId = 0;
+ return true;
+}
+
+bool BiffFormulaParserImpl::importEndSheetToken3( BiffInputStream& rStrm )
+{
+ rStrm.skip( 4 );
+ mnCurrRefId = 0;
+ return true;
+}
+
+bool BiffFormulaParserImpl::importNlrToken( BiffInputStream& rStrm )
+{
+ bool bOk = true;
+ sal_uInt8 nNlrType;
+ rStrm >> nNlrType;
+ switch( nNlrType )
+ {
+ case BIFF_TOK_NLR_ERR: bOk = importNlrErrToken( rStrm, 4 ); break;
+ case BIFF_TOK_NLR_ROWR: bOk = importNlrAddrToken( rStrm, true ); break;
+ case BIFF_TOK_NLR_COLR: bOk = importNlrAddrToken( rStrm, false ); break;
+ case BIFF_TOK_NLR_ROWV: bOk = importNlrAddrToken( rStrm, true ); break;
+ case BIFF_TOK_NLR_COLV: bOk = importNlrAddrToken( rStrm, false ); break;
+ case BIFF_TOK_NLR_RANGE: bOk = importNlrRangeToken( rStrm ); break;
+ case BIFF_TOK_NLR_SRANGE: bOk = importNlrSRangeToken( rStrm ); break;
+ case BIFF_TOK_NLR_SROWR: bOk = importNlrSAddrToken( rStrm, true ); break;
+ case BIFF_TOK_NLR_SCOLR: bOk = importNlrSAddrToken( rStrm, false ); break;
+ case BIFF_TOK_NLR_SROWV: bOk = importNlrSAddrToken( rStrm, true ); break;
+ case BIFF_TOK_NLR_SCOLV: bOk = importNlrSAddrToken( rStrm, false ); break;
+ case BIFF_TOK_NLR_RANGEERR: bOk = importNlrErrToken( rStrm, 13 ); break;
+ case BIFF_TOK_NLR_SXNAME: bOk = importNlrErrToken( rStrm, 4 ); break;
+ default: bOk = false;
+ }
+ return bOk;
+}
+
+bool BiffFormulaParserImpl::importArrayToken( BiffInputStream& rStrm )
+{
+ rStrm.skip( mnArraySize );
+
+ // start token array with opening brace and leading spaces
+ pushOperand( mrFuncProv.OPCODE_ARRAY_OPEN );
+ size_t nOpSize = popOperandSize();
+ size_t nOldArraySize = getFormulaSize();
+ bool bBiff8 = getBiff() == BIFF8;
+
+ // read array size
+ swapStreamPosition( rStrm );
+ sal_uInt16 nCols = rStrm.readuInt8();
+ sal_uInt16 nRows = rStrm.readuInt16();
+ if( bBiff8 ) { ++nCols; ++nRows; } else if( nCols == 0 ) nCols = 256;
+ OSL_ENSURE( (nCols > 0) && (nRows > 0), "BiffFormulaParserImpl::importArrayToken - empty array" );
+
+ // read array values and build token array
+ for( sal_uInt16 nRow = 0; rStrm.isValid() && (nRow < nRows); ++nRow )
+ {
+ if( nRow > 0 )
+ appendRawToken( mrFuncProv.OPCODE_ARRAY_ROWSEP );
+ for( sal_uInt16 nCol = 0; rStrm.isValid() && (nCol < nCols); ++nCol )
+ {
+ if( nCol > 0 )
+ appendRawToken( mrFuncProv.OPCODE_ARRAY_COLSEP );
+ switch( rStrm.readuInt8() )
+ {
+ case BIFF_DATATYPE_EMPTY:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= OUString();
+ rStrm.skip( 8 );
+ break;
+ case BIFF_DATATYPE_DOUBLE:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= rStrm.readDouble();
+ break;
+ case BIFF_DATATYPE_STRING:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= bBiff8 ?
+ rStrm.readUniString() :
+ rStrm.readByteString( false, getTextEncoding() );
+ break;
+ case BIFF_DATATYPE_BOOL:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= static_cast< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
+ rStrm.skip( 7 );
+ break;
+ case BIFF_DATATYPE_ERROR:
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( rStrm.readuInt8() );
+ rStrm.skip( 7 );
+ break;
+ default:
+ OSL_ENSURE( false, "BiffFormulaParserImpl::importArrayToken - unknown data type" );
+ appendRawToken( mrFuncProv.OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( BIFF_ERR_NA );
+ }
+ }
+ }
+ swapStreamPosition( rStrm );
+
+ // close token array and set resulting operand size
+ appendRawToken( mrFuncProv.OPCODE_ARRAY_CLOSE );
+ pushOperandSize( nOpSize + getFormulaSize() - nOldArraySize );
+ return true;
+}
+
+bool BiffFormulaParserImpl::importRefToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinSingleRef2d aRef;
+ aRef.readBiff2Data( rStrm, bRelativeAsOffset );
+ return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importRefToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinSingleRef2d aRef;
+ aRef.readBiff8Data( rStrm, bRelativeAsOffset );
+ return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importAreaToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinComplexRef2d aRef;
+ aRef.readBiff2Data( rStrm, bRelativeAsOffset );
+ return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importAreaToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinComplexRef2d aRef;
+ aRef.readBiff8Data( rStrm, bRelativeAsOffset );
+ return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importRef3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange5( rStrm );
+ BinSingleRef2d aRef;
+ aRef.readBiff2Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importRef3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange8( rStrm );
+ BinSingleRef2d aRef;
+ aRef.readBiff8Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importArea3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange5( rStrm );
+ BinComplexRef2d aRef;
+ aRef.readBiff2Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importArea3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange8( rStrm );
+ BinComplexRef2d aRef;
+ aRef.readBiff8Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::importMemAreaToken( BiffInputStream& rStrm, bool bAddData )
+{
+ rStrm.skip( mnMemAreaSize );
+ if( bAddData )
+ skipMemAreaAddData( rStrm );
+ return true;
+}
+
+bool BiffFormulaParserImpl::importMemFuncToken( BiffInputStream& rStrm )
+{
+ rStrm.skip( mnMemFuncSize );
+ return true;
+}
+
+bool BiffFormulaParserImpl::importNameToken( BiffInputStream& rStrm )
+{
+ sal_uInt16 nNameId = readNameId( rStrm );
+ return (mnCurrRefId > 0) ? pushBiffExtName( mnCurrRefId, nNameId ) : pushBiffName( nNameId );
+}
+
+bool BiffFormulaParserImpl::importNameXToken( BiffInputStream& rStrm )
+{
+ sal_Int32 nRefId = readRefId( rStrm );
+ sal_uInt16 nNameId = readNameId( rStrm );
+ return pushBiffExtName( nRefId, nNameId );
+}
+
+bool BiffFormulaParserImpl::importFuncToken2( BiffInputStream& rStrm )
+{
+ sal_uInt8 nFuncId;
+ rStrm >> nFuncId;
+ return pushBiffFunction( nFuncId );
+}
+
+bool BiffFormulaParserImpl::importFuncToken4( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFuncId;
+ rStrm >> nFuncId;
+ return pushBiffFunction( nFuncId );
+}
+
+bool BiffFormulaParserImpl::importFuncVarToken2( BiffInputStream& rStrm )
+{
+ sal_uInt8 nParamCount, nFuncId;
+ rStrm >> nParamCount >> nFuncId;
+ return pushBiffFunction( nFuncId, nParamCount );
+}
+
+bool BiffFormulaParserImpl::importFuncVarToken4( BiffInputStream& rStrm )
+{
+ sal_uInt8 nParamCount;
+ sal_uInt16 nFuncId;
+ rStrm >> nParamCount >> nFuncId;
+ return pushBiffFunction( nFuncId, nParamCount & BIFF_TOK_FUNCVAR_COUNTMASK );
+}
+
+bool BiffFormulaParserImpl::importFuncCEToken( BiffInputStream& rStrm )
+{
+ sal_uInt8 nParamCount, nFuncId;
+ rStrm >> nParamCount >> nFuncId;
+ sal_uInt16 nCmdId = nFuncId;
+ setFlag( nCmdId, BIFF_TOK_FUNCVAR_CMD );
+ return pushBiffFunction( nCmdId, nParamCount );
+}
+
+bool BiffFormulaParserImpl::importExpToken5( BiffInputStream& rStrm )
+{
+ BinAddress aBaseAddr;
+ aBaseAddr.read( rStrm );
+ setSharedFormula( aBaseAddr );
+ // formula has been set, exit parser by returning false
+ return false;
+}
+
+bool BiffFormulaParserImpl::importNlrAddrToken( BiffInputStream& rStrm, bool bRow )
+{
+ BiffNlr aNlr;
+ aNlr.readBiff8Data( rStrm );
+ return pushBiffNlrAddr( aNlr, bRow );
+}
+
+bool BiffFormulaParserImpl::importNlrRangeToken( BiffInputStream& rStrm )
+{
+ BiffNlr aNlr;
+ aNlr.readBiff8Data( rStrm );
+ rStrm.skip( 1 );
+ BinRange aRange;
+ rStrm >> aRange;
+ return pushBiffNlrRange( aNlr, aRange );
+}
+
+bool BiffFormulaParserImpl::importNlrSAddrToken( BiffInputStream& rStrm, bool bRow )
+{
+ rStrm.skip( 4 );
+ BiffNlr aNlr;
+ return readNlrSAddrAddData( aNlr, rStrm, bRow ) ? pushBiffNlrSAddr( aNlr, bRow ) : pushBiffErrorOperand( BIFF_ERR_REF );
+}
+
+bool BiffFormulaParserImpl::importNlrSRangeToken( BiffInputStream& rStrm )
+{
+ rStrm.skip( 5 );
+ BinRange aRange;
+ rStrm >> aRange;
+ BiffNlr aNlr;
+ bool bRow;
+ return readNlrSRangeAddData( aNlr, bRow, rStrm ) ? pushBiffNlrSRange( aNlr, aRange, bRow ) : pushBiffErrorOperand( BIFF_ERR_REF );
+}
+
+bool BiffFormulaParserImpl::importNlrErrToken( BiffInputStream& rStrm, sal_uInt16 nIgnore )
+{
+ rStrm.skip( nIgnore );
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+sal_Int32 BiffFormulaParserImpl::readRefId( BiffInputStream& rStrm )
+{
+ sal_Int16 nRefId;
+ rStrm >> nRefId;
+ rStrm.skip( mnRefIdSize );
+ return nRefId;
+}
+
+sal_uInt16 BiffFormulaParserImpl::readNameId( BiffInputStream& rStrm )
+{
+ sal_uInt16 nNameId;
+ rStrm >> nNameId;
+ rStrm.skip( mnNameSize );
+ return nNameId;
+}
+
+LinkSheetRange BiffFormulaParserImpl::readSheetRange5( BiffInputStream& rStrm )
+{
+ sal_Int32 nRefId = readRefId( rStrm );
+ sal_Int16 nTab1, nTab2;
+ rStrm >> nTab1 >> nTab2;
+ return getExternalLinks().getSheetRange( nRefId, nTab1, nTab2 );
+}
+
+LinkSheetRange BiffFormulaParserImpl::readSheetRange8( BiffInputStream& rStrm )
+{
+ return getExternalLinks().getSheetRange( readRefId( rStrm ) );
+}
+
+void BiffFormulaParserImpl::swapStreamPosition( BiffInputStream& rStrm )
+{
+ sal_uInt32 nRecPos = rStrm.getRecPos();
+ rStrm.seek( mnAddDataPos );
+ mnAddDataPos = nRecPos;
+}
+
+void BiffFormulaParserImpl::skipMemAreaAddData( BiffInputStream& rStrm )
+{
+ swapStreamPosition( rStrm );
+ sal_uInt32 nCount = rStrm.readuInt16();
+ rStrm.skip( ((getBiff() == BIFF8) ? 8 : 6) * nCount );
+ swapStreamPosition( rStrm );
+}
+
+bool BiffFormulaParserImpl::readNlrSAddrAddData( BiffNlr& orNlr, BiffInputStream& rStrm, bool bRow )
+{
+ bool bIsRow;
+ return readNlrSRangeAddData( orNlr, bIsRow, rStrm ) && (bIsRow == bRow);
+}
+
+bool BiffFormulaParserImpl::readNlrSRangeAddData( BiffNlr& orNlr, bool& orbIsRow, BiffInputStream& rStrm )
+{
+ swapStreamPosition( rStrm );
+ // read number of cell addresses and relative flag
+ sal_uInt32 nCount;
+ rStrm >> nCount;
+ bool bRel = getFlag( nCount, BIFF_TOK_NLR_ADDREL );
+ nCount &= BIFF_TOK_NLR_ADDMASK;
+ sal_uInt32 nEndPos = rStrm.getRecPos() + 4 * nCount;
+ // read list of cell addresses
+ bool bValid = false;
+ if( nCount >= 2 )
+ {
+ // detect column/row orientation
+ BinAddress aAddr1, aAddr2;
+ rStrm >> aAddr1 >> aAddr2;
+ orbIsRow = aAddr1.mnRow == aAddr2.mnRow;
+ bValid = lclIsValidNlrStack( aAddr1, aAddr2, orbIsRow );
+ // read and verify additional cell positions
+ for( sal_uInt32 nIndex = 2; bValid && (nIndex < nCount); ++nIndex )
+ {
+ aAddr1 = aAddr2;
+ rStrm >> aAddr2;
+ bValid = rStrm.isValid() && lclIsValidNlrStack( aAddr1, aAddr2, orbIsRow );
+ }
+ // check that last imported position (aAddr2) is not at the end of the sheet
+ bValid = bValid && (orbIsRow ? (aAddr2.mnCol < mnMaxApiCol) : (aAddr2.mnRow < mnMaxApiRow));
+ // fill the NLR struct with the last imported position
+ if( bValid )
+ {
+ orNlr.mnCol = aAddr2.mnCol;
+ orNlr.mnRow = aAddr2.mnRow;
+ orNlr.mbRel = bRel;
+ }
+ }
+ // seek to end of additional data for this token
+ rStrm.seek( nEndPos );
+ swapStreamPosition( rStrm );
+
+ return bValid;
+}
+
+// convert BIFF token and push API operand or operator ------------------------
+
+bool BiffFormulaParserImpl::pushBiffReference( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
+{
+ return (mnCurrRefId > 0) ?
+ pushReferenceOperand( getExternalLinks().getSheetRange( mnCurrRefId, 0, 0 ), rRef, bDeleted, bRelativeAsOffset ) :
+ pushReferenceOperand( rRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::pushBiffReference( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
+{
+ return (mnCurrRefId > 0) ?
+ pushReferenceOperand( getExternalLinks().getSheetRange( mnCurrRefId, 0, 0 ), rRef, bDeleted, bRelativeAsOffset ) :
+ pushReferenceOperand( rRef, bDeleted, bRelativeAsOffset );
+}
+
+bool BiffFormulaParserImpl::pushBiffNlrAddr( const BiffNlr& rNlr, bool bRow )
+{
+ BinSingleRef2d aRef;
+ aRef.mnCol = rNlr.mnCol;
+ aRef.mnRow = rNlr.mnRow;
+ aRef.mbColRel = !bRow;
+ aRef.mbRowRel = bRow;
+ return pushNlrOperand( aRef );
+}
+
+bool BiffFormulaParserImpl::pushBiffNlrRange( const BiffNlr& rNlr, const BinRange& rRange )
+{
+ bool bRow = rNlr.mnRow == rRange.maFirst.mnRow;
+ return lclIsValidNlrRange( rNlr, rRange, bRow ) ?
+ pushBiffNlrAddr( rNlr, bRow ) : pushBiffErrorOperand( BIFF_ERR_REF );
+}
+
+bool BiffFormulaParserImpl::pushBiffNlrSAddr( const BiffNlr& rNlr, bool bRow )
+{
+ BinRange aRange;
+ aRange.maFirst.mnCol = rNlr.mnCol + (bRow ? 1 : 0);
+ aRange.maFirst.mnRow = rNlr.mnRow + (bRow ? 0 : 1);
+ aRange.maLast.mnCol = bRow ? mnMaxApiCol : rNlr.mnCol;
+ aRange.maLast.mnRow = bRow ? rNlr.mnRow : mnMaxApiRow;
+ return pushBiffNlrSRange( rNlr, aRange, bRow );
+}
+
+bool BiffFormulaParserImpl::pushBiffNlrSRange( const BiffNlr& rNlr, const BinRange& rRange, bool bRow )
+{
+ if( lclIsValidNlrRange( rNlr, rRange, bRow ) )
+ {
+ BinComplexRef2d aRef;
+ aRef.maRef1.mnCol = rRange.maFirst.mnCol;
+ aRef.maRef1.mnRow = rRange.maFirst.mnRow;
+ aRef.maRef2.mnCol = rRange.maLast.mnCol;
+ aRef.maRef2.mnRow = rRange.maLast.mnRow;
+ aRef.maRef1.mbColRel = aRef.maRef2.mbColRel = !bRow && rNlr.mbRel;
+ aRef.maRef1.mbRowRel = aRef.maRef2.mbRowRel = bRow && rNlr.mbRel;
+ return pushReferenceOperand( aRef, false, false );
+ }
+ return pushBiffErrorOperand( BIFF_ERR_REF );
+}
+
+bool BiffFormulaParserImpl::pushBiffName( sal_uInt16 nNameId )
+{
+ // one-based in BIFF formulas
+ return pushDefinedNameOperand( getDefinedNames().getByIndex( static_cast< sal_Int32 >( nNameId ) - 1 ) );
+}
+
+bool BiffFormulaParserImpl::pushBiffExtName( sal_Int32 nRefId, sal_uInt16 nNameId )
+{
+ if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
+ {
+ if( pExtLink->getLinkType() == LINKTYPE_SELF )
+ return pushBiffName( nNameId );
+ // external name indexes are one-based in BIFF
+ ExternalNameRef xExtName = pExtLink->getNameByIndex( static_cast< sal_Int32 >( nNameId ) - 1 );
+ return pushExternalNameOperand( xExtName, pExtLink->getLinkType() );
+ }
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool BiffFormulaParserImpl::pushBiffFunction( sal_uInt16 nFuncId )
+{
+ if( const FunctionInfo* pFuncInfo = mrFuncProv.getFuncInfoFromBiffFuncId( nFuncId ) )
+ if( pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount )
+ return pushFunctionOperator( *pFuncInfo, pFuncInfo->mnMinParamCount );
+ return pushFunctionOperator( mrFuncProv.OPCODE_NONAME, 0 );
+}
+
+bool BiffFormulaParserImpl::pushBiffFunction( sal_uInt16 nFuncId, sal_uInt8 nParamCount )
+{
+ if( getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD ) )
+ nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
+ if( const FunctionInfo* pFuncInfo = mrFuncProv.getFuncInfoFromBiffFuncId( nFuncId ) )
+ return pushFunctionOperator( *pFuncInfo, nParamCount );
+ return pushFunctionOperator( mrFuncProv.OPCODE_NONAME, nParamCount );
+}
+
+// ============================================================================
+
+FormulaParser::FormulaParser( const WorkbookHelper& rHelper ) :
+ FormulaProcessorBase( rHelper )
+{
+ switch( getFilterType() )
+ {
+ case FILTER_OOX: mxImpl.reset( new OoxFormulaParserImpl( rHelper, maFuncProv ) ); break;
+ case FILTER_BIFF: mxImpl.reset( new BiffFormulaParserImpl( rHelper, maFuncProv ) ); break;
+ case FILTER_UNKNOWN: break;
+ }
+}
+
+FormulaParser::~FormulaParser()
+{
+}
+
+void FormulaParser::importFormula( FormulaContext& rContext, const OUString& rFormulaString ) const
+{
+ mxImpl->importOoxFormula( rContext, rFormulaString );
+}
+
+void FormulaParser::importFormula( FormulaContext& rContext, RecordInputStream& rStrm ) const
+{
+ mxImpl->importOobFormula( rContext, rStrm );
+}
+
+void FormulaParser::importFormula( FormulaContext& rContext, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) const
+{
+ mxImpl->importBiffFormula( rContext, rStrm, pnFmlaSize );
+}
+
+void FormulaParser::convertErrorToFormula( FormulaContext& rContext, sal_uInt8 nErrorCode ) const
+{
+ ApiTokenSequence aTokens( 3 );
+ // HACK: enclose all error codes into an 1x1 matrix
+ aTokens[ 0 ].OpCode = maFuncProv.OPCODE_ARRAY_OPEN;
+ aTokens[ 1 ].OpCode = maFuncProv.OPCODE_PUSH;
+ aTokens[ 1 ].Data <<= BiffHelper::calcDoubleFromError( nErrorCode );
+ aTokens[ 2 ].OpCode = maFuncProv.OPCODE_ARRAY_CLOSE;
+ mxImpl->setFormula( rContext, aTokens );
+}
+
+void FormulaParser::convertNameToFormula( FormulaContext& rContext, sal_Int32 nTokenIndex ) const
+{
+ if( nTokenIndex >= 0 )
+ {
+ ApiTokenSequence aTokens( 1 );
+ aTokens[ 0 ].OpCode = maFuncProv.OPCODE_NAME;
+ aTokens[ 0 ].Data <<= nTokenIndex;
+ mxImpl->setFormula( rContext, aTokens );
+ }
+ else
+ convertErrorToFormula( rContext, BIFF_ERR_REF );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/headerfooterparser.cxx b/oox/source/xls/headerfooterparser.cxx
new file mode 100644
index 000000000000..663a17c5c89f
--- /dev/null
+++ b/oox/source/xls/headerfooterparser.cxx
@@ -0,0 +1,643 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: headerfooterparser.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/headerfooterparser.hxx"
+#include <vector>
+#include <set>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/FilenameDisplayFormat.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/themebuffer.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OUStringToOString;
+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::Exception;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::sheet::XHeaderFooterContent;
+using ::com::sun::star::text::XText;
+using ::com::sun::star::text::XTextCursor;
+using ::com::sun::star::text::XTextContent;
+using ::com::sun::star::text::XTextRange;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+enum HFPortionId
+{
+ HF_LEFT,
+ HF_CENTER,
+ HF_RIGHT,
+ HF_COUNT
+};
+
+// ----------------------------------------------------------------------------
+
+struct HFPortionInfo
+{
+ Reference< XText > mxText; /// XText interface of this portion.
+ Reference< XTextCursor > mxStart; /// Start position of current text range for formatting.
+ Reference< XTextCursor > mxEnd; /// End position of current text range for formatting.
+ double mfTotalHeight; /// Sum of heights of previous lines in points.
+ double mfCurrHeight; /// Height of the current text line in points.
+
+ bool initialize( const Reference< XText >& rxText );
+};
+
+bool HFPortionInfo::initialize( const Reference< XText >& rxText )
+{
+ mfTotalHeight = mfCurrHeight = 0.0;
+ mxText = rxText;
+ if( mxText.is() )
+ {
+ mxStart = mxText->createTextCursor();
+ mxEnd = mxText->createTextCursor();
+ }
+ bool bRet = mxText.is() && mxStart.is() && mxEnd.is();
+ OSL_ENSURE( bRet, "HFPortionInfo::initialize - missing interfaces" );
+ return bRet;
+}
+
+// ----------------------------------------------------------------------------
+
+class HeaderFooterParserImpl : public WorkbookHelper
+{
+public:
+ explicit HeaderFooterParserImpl( const WorkbookHelper& rHelper );
+
+ /** Parses the passed string and creates the header/footer contents. */
+ void parse(
+ const Reference< XHeaderFooterContent >& rxContext,
+ const OUString& rData );
+
+ /** Returns the total height of the converted header or footer in points. */
+ double getTotalHeight() const;
+
+private:
+ /** Returns the current edit engine text object. */
+ inline HFPortionInfo& getPortion() { return maPortions[ meCurrPortion ]; }
+ /** Returns the start cursor of the current text range. */
+ inline const Reference< XTextCursor >& getStartPos() { return getPortion().mxStart; }
+ /** Returns the end cursor of the current text range. */
+ inline const Reference< XTextCursor >& getEndPos() { return getPortion().mxEnd; }
+
+ /** Returns the current line height of the specified portion. */
+ double getCurrHeight( HFPortionId ePortion ) const;
+ /** Returns the current line height. */
+ double getCurrHeight() const;
+
+ /** Updates the current line height of the specified portion, using the current font size. */
+ void updateCurrHeight( HFPortionId ePortion );
+ /** Updates the current line height, using the current font size. */
+ void updateCurrHeight();
+
+ /** Sets the font attributes at the current selection. */
+ void setAttributes();
+ /** Appends and clears internal string buffer. */
+ void appendText();
+ /** Appends a line break and adjusts internal text height data. */
+ void appendLineBreak();
+
+ /** Creates a text field from the passed service name. */
+ Reference< XTextContent > createField( const OUString& rServiceName ) const;
+ /** Appends the passed text field. */
+ void appendField( const Reference< XTextContent >& rxContent );
+
+ /** Sets the passed font name if it is valid. */
+ void convertFontName( const OUString& rStyle );
+ /** Converts a font style given as string. */
+ void convertFontStyle( const OUString& rStyle );
+ /** Converts a font color given as string. */
+ void convertFontColor( const OUString& rColor );
+
+ /** Finalizes current portion: sets font attributes and updates text height data. */
+ void finalizePortion();
+ /** Changes current header/footer portion. */
+ void setNewPortion( HFPortionId ePortion );
+
+private:
+ typedef ::std::vector< HFPortionInfo > HFPortionInfoVec;
+ typedef ::std::set< OString > OStringSet;
+
+ OUString maPageNumberService;
+ OUString maPageCountService;
+ OUString maSheetNameService;
+ OUString maFileNameService;
+ OUString maDateTimeService;
+ OUString maIsDateProp;
+ OUString maFileFormatProp;
+ OStringSet maBoldNames; /// All names for bold font style in lowercase UTF-8.
+ OStringSet maItalicNames; /// All names for italic font style in lowercase UTF-8.
+ HFPortionInfoVec maPortions;
+ HFPortionId meCurrPortion; /// Identifier of current H/F portion.
+ OUStringBuffer maBuffer; /// Text data to append to current text range.
+ OoxFontData maFontData; /// Font attributes of current text range.
+};
+
+
+HeaderFooterParserImpl::HeaderFooterParserImpl( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maPageNumberService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageNumber" ) ),
+ maPageCountService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageCount" ) ),
+ maSheetNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.SheetName" ) ),
+ maFileNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.FileName" ) ),
+ maDateTimeService( CREATE_OUSTRING( "com.sun.star.text.TextField.DateTime" ) ),
+ maIsDateProp( CREATE_OUSTRING( "IsDate" ) ),
+ maFileFormatProp( CREATE_OUSTRING( "FileFormat" ) ),
+ maPortions( static_cast< size_t >( HF_COUNT ) ),
+ meCurrPortion( HF_CENTER )
+{
+ // different names for bold font style (lowercase)
+ maBoldNames.insert( CREATE_OSTRING( "bold" ) );
+ maBoldNames.insert( CREATE_OSTRING( "fett" ) );
+ maBoldNames.insert( CREATE_OSTRING( "demibold" ) );
+ maBoldNames.insert( CREATE_OSTRING( "halbfett" ) );
+ maBoldNames.insert( CREATE_OSTRING( "black" ) );
+ maBoldNames.insert( CREATE_OSTRING( "heavy" ) );
+
+ // different names for italic font style (lowercase)
+ maItalicNames.insert( CREATE_OSTRING( "italic" ) );
+ maItalicNames.insert( CREATE_OSTRING( "kursiv" ) );
+ maItalicNames.insert( CREATE_OSTRING( "oblique" ) );
+ maItalicNames.insert( CREATE_OSTRING( "schr\303\204g" ) ); // with uppercase A umlaut
+ maItalicNames.insert( CREATE_OSTRING( "schr\303\244g" ) ); // with lowercase A umlaut
+}
+
+void HeaderFooterParserImpl::parse( const Reference< XHeaderFooterContent >& rxContext, const OUString& rData )
+{
+ if( !rxContext.is() || (rData.getLength() == 0) ||
+ !maPortions[ HF_LEFT ].initialize( rxContext->getLeftText() ) ||
+ !maPortions[ HF_CENTER ].initialize( rxContext->getCenterText() ) ||
+ !maPortions[ HF_RIGHT ].initialize( rxContext->getRightText() ) )
+ return;
+
+ meCurrPortion = HF_CENTER;
+ maBuffer.setLength( 0 );
+ maFontData = getStyles().getDefaultFontData();
+ OUStringBuffer aFontName; // current font name
+ OUStringBuffer aFontStyle; // current font style
+ sal_Int32 nFontHeight = 0; // current font height
+
+ /** State of the parser. */
+ enum
+ {
+ STATE_TEXT, /// Literal text data.
+ STATE_TOKEN, /// Control token following a '&' character.
+ STATE_FONTNAME, /// Font name ('&' is followed by '"', reads until next '"' or ',').
+ STATE_FONTSTYLE, /// Font style name (font part after ',', reads until next '"').
+ STATE_FONTHEIGHT /// Font height ('&' is followed by num. digits, reads until non-digit).
+ }
+ eState = STATE_TEXT;
+
+ const sal_Unicode* pcChar = rData.getStr();
+ const sal_Unicode* pcEnd = pcChar + rData.getLength();
+ for( ; (pcChar != pcEnd) && (*pcChar != 0); ++pcChar )
+ {
+ sal_Unicode cChar = *pcChar;
+ switch( eState )
+ {
+ case STATE_TEXT:
+ {
+ switch( cChar )
+ {
+ case '&': // new token
+ appendText();
+ eState = STATE_TOKEN;
+ break;
+ case '\n': // line break
+ appendText();
+ appendLineBreak();
+ break;
+ default:
+ maBuffer.append( cChar );
+ }
+ }
+ break;
+
+ case STATE_TOKEN:
+ {
+ // default: back to text mode, may be changed in specific cases
+ eState = STATE_TEXT;
+ // ignore case of token codes
+ if( ('a' <= cChar) && (cChar <= 'z') )
+ (cChar -= 'a') += 'A';
+ switch( cChar )
+ {
+ case '&': maBuffer.append( cChar ); break; // the '&' character
+
+ case 'L': setNewPortion( HF_LEFT ); break; // left portion
+ case 'C': setNewPortion( HF_CENTER ); break; // center portion
+ case 'R': setNewPortion( HF_RIGHT ); break; // right portion
+
+ case 'P': // page number
+ appendField( createField( maPageNumberService ) );
+ break;
+ case 'N': // total page count
+ appendField( createField( maPageCountService ) );
+ break;
+ case 'A': // current sheet name
+ appendField( createField( maSheetNameService ) );
+ break;
+
+ case 'F': // file name
+ {
+ Reference< XTextContent > xContent = createField( maFileNameService );
+ PropertySet aPropSet( xContent );
+ aPropSet.setProperty( maFileFormatProp, ::com::sun::star::text::FilenameDisplayFormat::NAME_AND_EXT );
+ appendField( xContent );
+ }
+ break;
+ case 'Z': // file path (without file name), BIFF8 and OOX only
+ if( (getFilterType() == FILTER_OOX) || ((getFilterType() == FILTER_BIFF) && (getBiff() == BIFF8)) )
+ {
+ Reference< XTextContent > xContent = createField( maFileNameService );
+ PropertySet aPropSet( xContent );
+ // FilenameDisplayFormat::PATH not supported by Calc
+ aPropSet.setProperty( maFileFormatProp, ::com::sun::star::text::FilenameDisplayFormat::FULL );
+ appendField( xContent );
+ /* path only is not supported -- if we find a '&Z&F'
+ combination for path/name, skip the '&F' part */
+ if( (pcChar + 2 < pcEnd) && (pcChar[ 1 ] == '&') && ((pcChar[ 2 ] == 'f') || (pcChar[ 2 ] == 'F')) )
+ pcChar += 2;
+ }
+ break;
+ case 'D': // date
+ {
+ Reference< XTextContent > xContent = createField( maDateTimeService );
+ PropertySet aPropSet( xContent );
+ aPropSet.setProperty( maIsDateProp, true );
+ appendField( xContent );
+ }
+ break;
+ case 'T': // time
+ {
+ Reference< XTextContent > xContent = createField( maDateTimeService );
+ PropertySet aPropSet( xContent );
+ aPropSet.setProperty( maIsDateProp, false );
+ appendField( xContent );
+ }
+ break;
+
+ case 'B': // bold
+ setAttributes();
+ maFontData.mbBold = !maFontData.mbBold;
+ break;
+ case 'I': // italic
+ setAttributes();
+ maFontData.mbItalic = !maFontData.mbItalic;
+ break;
+ case 'U': // underline
+ setAttributes();
+ maFontData.mnUnderline = (maFontData.mnUnderline == XML_single) ? XML_none : XML_single;
+ break;
+ case 'E': // double underline
+ setAttributes();
+ maFontData.mnUnderline = (maFontData.mnUnderline == XML_double) ? XML_none : XML_double;
+ break;
+ case 'S': // strikeout
+ setAttributes();
+ maFontData.mbStrikeout = !maFontData.mbStrikeout;
+ break;
+ case 'X': // superscript
+ setAttributes();
+ maFontData.mnEscapement = (maFontData.mnEscapement == XML_superscript) ? XML_baseline : XML_superscript;
+ break;
+ case 'Y': // subsrcipt
+ setAttributes();
+ maFontData.mnEscapement = (maFontData.mnEscapement == XML_subscript) ? XML_baseline : XML_subscript;
+ break;
+ case 'O': // outlined
+ setAttributes();
+ maFontData.mbOutline = !maFontData.mbOutline;
+ break;
+ case 'H': // shadow
+ setAttributes();
+ maFontData.mbShadow = !maFontData.mbShadow;
+ break;
+
+ case 'K': // text color (not in BIFF)
+ if( (getFilterType() == FILTER_OOX) && (pcChar + 6 < pcEnd) )
+ {
+ setAttributes();
+ // eat the following 6 characters
+ convertFontColor( OUString( pcChar + 1, 6 ) );
+ pcChar += 6;
+ }
+ break;
+
+ case '\"': // font name
+ aFontName.setLength( 0 );
+ aFontStyle.setLength( 0 );
+ eState = STATE_FONTNAME;
+ break;
+ default:
+ if( ('0' <= cChar) && (cChar <= '9') ) // font size
+ {
+ nFontHeight = cChar - '0';
+ eState = STATE_FONTHEIGHT;
+ }
+ }
+ }
+ break;
+
+ case STATE_FONTNAME:
+ {
+ switch( cChar )
+ {
+ case '\"':
+ setAttributes();
+ convertFontName( aFontName.makeStringAndClear() );
+ eState = STATE_TEXT;
+ break;
+ case ',':
+ eState = STATE_FONTSTYLE;
+ break;
+ default:
+ aFontName.append( cChar );
+ }
+ }
+ break;
+
+ case STATE_FONTSTYLE:
+ {
+ switch( cChar )
+ {
+ case '\"':
+ setAttributes();
+ convertFontName( aFontName.makeStringAndClear() );
+ convertFontStyle( aFontStyle.makeStringAndClear() );
+ eState = STATE_TEXT;
+ break;
+ default:
+ aFontStyle.append( cChar );
+ }
+ }
+ break;
+
+ case STATE_FONTHEIGHT:
+ {
+ if( ('0' <= cChar) && (cChar <= '9') )
+ {
+ if( nFontHeight >= 0 )
+ {
+ nFontHeight *= 10;
+ nFontHeight += (cChar - '0');
+ if( nFontHeight > 1000 )
+ nFontHeight = -1;
+ }
+ }
+ else
+ {
+ if( nFontHeight > 0 )
+ {
+ setAttributes();
+ maFontData.mfHeight = nFontHeight;
+ }
+ --pcChar;
+ eState = STATE_TEXT;
+ }
+ }
+ break;
+ }
+ }
+
+ // finalize
+ finalizePortion();
+ maPortions[ HF_LEFT ].mfTotalHeight += getCurrHeight( HF_LEFT );
+ maPortions[ HF_CENTER ].mfTotalHeight += getCurrHeight( HF_CENTER );
+ maPortions[ HF_RIGHT ].mfTotalHeight += getCurrHeight( HF_RIGHT );
+}
+
+double HeaderFooterParserImpl::getTotalHeight() const
+{
+ return ::std::max( maPortions[ HF_LEFT ].mfTotalHeight,
+ ::std::max( maPortions[ HF_CENTER ].mfTotalHeight, maPortions[ HF_RIGHT ].mfTotalHeight ) );
+}
+
+// private --------------------------------------------------------------------
+
+double HeaderFooterParserImpl::getCurrHeight( HFPortionId ePortion ) const
+{
+ double fMaxHt = maPortions[ ePortion ].mfCurrHeight;
+ return (fMaxHt == 0.0) ? maFontData.mfHeight : fMaxHt;
+}
+
+double HeaderFooterParserImpl::getCurrHeight() const
+{
+ return getCurrHeight( meCurrPortion );
+}
+
+void HeaderFooterParserImpl::updateCurrHeight( HFPortionId ePortion )
+{
+ double& rfMaxHt = maPortions[ ePortion ].mfCurrHeight;
+ rfMaxHt = ::std::max( rfMaxHt, maFontData.mfHeight );
+}
+
+void HeaderFooterParserImpl::updateCurrHeight()
+{
+ updateCurrHeight( meCurrPortion );
+}
+
+void HeaderFooterParserImpl::setAttributes()
+{
+ Reference< XTextRange > xRange( getStartPos(), UNO_QUERY );
+ getEndPos()->gotoRange( xRange, sal_False );
+ getEndPos()->gotoEnd( sal_True );
+ if( !getEndPos()->isCollapsed() )
+ {
+ Font aFont( *this, maFontData );
+ aFont.finalizeImport();
+ PropertySet aPropSet( getEndPos() );
+ aFont.writeToPropertySet( aPropSet, FONT_PROPTYPE_RICHTEXT );
+ getStartPos()->gotoEnd( sal_False );
+ getEndPos()->gotoEnd( sal_False );
+ }
+}
+
+void HeaderFooterParserImpl::appendText()
+{
+ if( maBuffer.getLength() > 0 )
+ {
+ getEndPos()->gotoEnd( sal_False );
+ getEndPos()->setString( maBuffer.makeStringAndClear() );
+ updateCurrHeight();
+ }
+}
+
+void HeaderFooterParserImpl::appendLineBreak()
+{
+ getEndPos()->gotoEnd( sal_False );
+ getEndPos()->setString( OUString( sal_Unicode( '\n' ) ) );
+ getPortion().mfTotalHeight += getCurrHeight();
+ getPortion().mfCurrHeight = 0;
+}
+
+Reference< XTextContent > HeaderFooterParserImpl::createField( const OUString& rServiceName ) const
+{
+ Reference< XTextContent > xContent;
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW );
+ xContent.set( xFactory->createInstance( rServiceName ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false,
+ OStringBuffer( "HeaderFooterParserImpl::createField - error while creating text field \"" ).
+ append( OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( '"' ).getStr() );
+ }
+ return xContent;
+}
+
+void HeaderFooterParserImpl::appendField( const Reference< XTextContent >& rxContent )
+{
+ getEndPos()->gotoEnd( sal_False );
+ try
+ {
+ Reference< XTextRange > xRange( getEndPos(), UNO_QUERY_THROW );
+ getPortion().mxText->insertTextContent( xRange, rxContent, sal_False );
+ updateCurrHeight();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void HeaderFooterParserImpl::convertFontName( const OUString& rName )
+{
+ if( rName.getLength() > 0 )
+ {
+ // single dash is document default font
+ if( (rName.getLength() == 1) && (rName[ 0 ] == '-') )
+ maFontData.maName = getStyles().getDefaultFontData().maName;
+ else
+ maFontData.maName = rName;
+ }
+}
+
+void HeaderFooterParserImpl::convertFontStyle( const OUString& rStyle )
+{
+ maFontData.mbBold = maFontData.mbItalic = false;
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = rStyle.getLength();
+ while( (0 <= nPos) && (nPos < nLen) )
+ {
+ OString aToken = OUStringToOString( rStyle.getToken( 0, ' ', nPos ), RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase();
+ if( aToken.getLength() > 0 )
+ {
+ if( maBoldNames.count( aToken ) > 0 )
+ maFontData.mbBold = true;
+ else if( maItalicNames.count( aToken ) > 0 )
+ maFontData.mbItalic = true;
+ }
+ }
+}
+
+void HeaderFooterParserImpl::convertFontColor( const OUString& rColor )
+{
+ OSL_ENSURE( rColor.getLength() == 6, "HeaderFooterParserImpl::convertFontColor - invalid font color code" );
+ if( (rColor[ 2 ] == '+') || (rColor[ 2 ] == '-') )
+ // theme color: TTSNNN (TT = decimal theme index, S = +/-, NNN = decimal tint/shade in percent)
+ maFontData.maColor.set(
+ XML_theme, rColor.copy( 0, 2 ).toInt32(),
+ static_cast< double >( rColor.copy( 2 ).toInt32() ) / 100.0 );
+ else
+ // RGB color: RRGGBB
+ maFontData.maColor.set( XML_rgb, rColor.toInt32( 16 ) );
+}
+
+void HeaderFooterParserImpl::finalizePortion()
+{
+ appendText();
+ setAttributes();
+}
+
+void HeaderFooterParserImpl::setNewPortion( HFPortionId ePortion )
+{
+ if( ePortion != meCurrPortion )
+ {
+ finalizePortion();
+ meCurrPortion = ePortion;
+ maFontData = getStyles().getDefaultFontData();
+ }
+}
+
+// ============================================================================
+
+HeaderFooterParser::HeaderFooterParser( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mxImpl( new HeaderFooterParserImpl( rHelper ) )
+{
+}
+
+HeaderFooterParser::~HeaderFooterParser()
+{
+}
+
+void HeaderFooterParser::parse( const Reference< XHeaderFooterContent >& rxContext, const OUString& rData )
+{
+ mxImpl->parse( rxContext, rData );
+}
+
+double HeaderFooterParser::getTotalHeight() const
+{
+ return mxImpl->getTotalHeight();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/makefile.mk b/oox/source/xls/makefile.mk
new file mode 100644
index 000000000000..f46737cb307b
--- /dev/null
+++ b/oox/source/xls/makefile.mk
@@ -0,0 +1,106 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=xls
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/addressconverter.obj \
+ $(SLO)$/autofiltercontext.obj \
+ $(SLO)$/biffcodec.obj \
+ $(SLO)$/biffdetector.obj \
+ $(SLO)$/bifffragmenthandler.obj \
+ $(SLO)$/biffhelper.obj \
+ $(SLO)$/biffinputstream.obj \
+ $(SLO)$/biffoutputstream.obj \
+ $(SLO)$/condformatbuffer.obj \
+ $(SLO)$/condformatcontext.obj \
+ $(SLO)$/connectionsfragment.obj \
+ $(SLO)$/defnamesbuffer.obj \
+ $(SLO)$/excelfilter.obj \
+ $(SLO)$/externallinkbuffer.obj \
+ $(SLO)$/externallinkfragment.obj \
+ $(SLO)$/formulabase.obj \
+ $(SLO)$/formulaparser.obj \
+ $(SLO)$/headerfooterparser.obj \
+ $(SLO)$/numberformatsbuffer.obj \
+ $(SLO)$/ooxcontexthandler.obj \
+ $(SLO)$/ooxcontexthelper.obj \
+ $(SLO)$/ooxfragmenthandler.obj \
+ $(SLO)$/pagesettings.obj \
+ $(SLO)$/pivotcachefragment.obj \
+ $(SLO)$/pivottablebuffer.obj \
+ $(SLO)$/pivottablefragment.obj \
+ $(SLO)$/querytablefragment.obj \
+ $(SLO)$/richstring.obj \
+ $(SLO)$/richstringcontext.obj \
+ $(SLO)$/sharedformulabuffer.obj \
+ $(SLO)$/sharedstringsbuffer.obj \
+ $(SLO)$/sharedstringsfragment.obj \
+ $(SLO)$/sheetcellrangemap.obj \
+ $(SLO)$/sheetdatacontext.obj \
+ $(SLO)$/stylesbuffer.obj \
+ $(SLO)$/stylesfragment.obj \
+ $(SLO)$/stylespropertyhelper.obj \
+ $(SLO)$/tablebuffer.obj \
+ $(SLO)$/tablefragment.obj \
+ $(SLO)$/themebuffer.obj \
+ $(SLO)$/unitconverter.obj \
+ $(SLO)$/validationpropertyhelper.obj \
+ $(SLO)$/viewsettings.obj \
+ $(SLO)$/webquerybuffer.obj \
+ $(SLO)$/workbookfragment.obj \
+ $(SLO)$/workbookhelper.obj \
+ $(SLO)$/workbooksettings.obj \
+ $(SLO)$/worksheetbuffer.obj \
+ $(SLO)$/worksheetfragment.obj \
+ $(SLO)$/worksheethelper.obj \
+ $(SLO)$/worksheetsettings.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/xls/numberformatsbuffer.cxx b/oox/source/xls/numberformatsbuffer.cxx
new file mode 100644
index 000000000000..3433a7885704
--- /dev/null
+++ b/oox/source/xls/numberformatsbuffer.cxx
@@ -0,0 +1,2124 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: numberformatsbuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ * * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/numberformatsbuffer.hxx"
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormats.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/i18n/NumberFormatIndex.hpp>
+#include <osl/thread.h>
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OStringToOUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::lang::Locale;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::util::XNumberFormatsSupplier;
+using ::com::sun::star::util::XNumberFormats;
+using ::com::sun::star::util::XNumberFormatTypes;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+/** Stores the number format used in Calc for an Excel built-in number format. */
+struct BuiltinFormat
+{
+ sal_Int32 mnNumFmtId; /// Built-in number format index.
+ const sal_Char* mpcFmtCode; /// Format string, UTF-8, may be 0 (mnPredefId is used then).
+ sal_Int16 mnPredefId; /// Predefined format index, if mpcFmtCode is 0.
+ sal_Int32 mnReuseId; /// Use this format, if mpcFmtCode is 0 and mnPredefId is -1.
+};
+
+/** Defines a literal built-in number format. */
+#define NUMFMT_STRING( INDEX, FORMATCODE ) \
+ { INDEX, FORMATCODE, -1, -1 }
+
+/** Defines a built-in number format that maps to an own predefined format. */
+#define NUMFMT_PREDEF( INDEX, PREDEFINED ) \
+ { INDEX, 0, ::com::sun::star::i18n::NumberFormatIndex::PREDEFINED, -1 }
+
+/** Defines a built-in number format that is the same as the specified in nReuseId. */
+#define NUMFMT_REUSE( INDEX, REUSED_INDEX ) \
+ { INDEX, 0, -1, REUSED_INDEX }
+
+/** Terminates a built-in number format table. */
+#define NUMFMT_ENDTABLE() \
+ { -1, 0, -1, -1 }
+
+/** Defines builtin date and time formats 14...22.
+ @param SYSTEMDATE Complete short system date (for formats 14 and 22).
+ @param DAY Day format (for formats 15 and 16).
+ @param DAYSEP Separator between day and month (for formats 15 and 16).
+ @param MONTH Month format (for formats 15...17).
+ @param MONTHSEP Separator between month and year (for formats 15 and 17).
+ @param YEAR Year format (for formats 15 and 17).
+ @param HOUR12 Hour format for 12-hour AM/PM formats (formats 18 and 19).
+ @param HOUR24 Hour format for 24-hour formats (formats 20...22). */
+#define NUMFMT_ALLDATETIMES( SYSTEMDATE, DAY, DAYSEP, MONTH, MONTHSEP, YEAR, HOUR12, HOUR24 ) \
+ NUMFMT_STRING( 14, SYSTEMDATE ), \
+ NUMFMT_STRING( 15, DAY DAYSEP MONTH MONTHSEP YEAR ), \
+ NUMFMT_STRING( 16, DAY DAYSEP MONTH ), \
+ NUMFMT_STRING( 17, MONTH MONTHSEP YEAR ), \
+ NUMFMT_STRING( 18, HOUR12 ":mm AM/PM" ), \
+ NUMFMT_STRING( 19, HOUR12 ":mm:ss AM/PM" ), \
+ NUMFMT_STRING( 20, HOUR24 ":mm" ), \
+ NUMFMT_STRING( 21, HOUR24 ":mm:ss" ), \
+ NUMFMT_STRING( 22, SYSTEMDATE " " HOUR24 ":mm" )
+
+/** Defines builtin time formats INDEX and INDEX+1 for CJK locales.
+ @param INDEX First number format index.
+ @param HOURFORMAT Hour format.
+ @param HOUR Hour symbol.
+ @param MINUTE Minute symbol.
+ @param SECOND Second symbol. */
+#define NUMFMT_TIME_CJK( INDEX, HOURFORMAT, HOUR, MINUTE, SECOND ) \
+ NUMFMT_STRING( INDEX + 0, HOURFORMAT "\"" HOUR "\"mm\"" MINUTE "\"" ), \
+ NUMFMT_STRING( INDEX + 1, HOURFORMAT "\"" HOUR "\"mm\"" MINUTE "\"ss\"" SECOND "\"" )
+
+/** Defines builtin time formats 32...35 for CJK locales.
+ @param HOUR12 Hour format for 12-hour AM/PM formats (formats 34 and 35).
+ @param HOUR24 Hour format for 24-hour formats (formats 32 and 33).
+ @param HOUR Hour symbol.
+ @param MINUTE Minute symbol.
+ @param SECOND Second symbol. */
+#define NUMFMT_ALLTIMES_CJK( HOUR12, HOUR24, HOUR, MINUTE, SECOND ) \
+ NUMFMT_TIME_CJK( 32, HOUR24, HOUR, MINUTE, SECOND ), \
+ NUMFMT_TIME_CJK( 34, "AM/PM" HOUR12, HOUR, MINUTE, SECOND )
+
+/** Defines builtin currency formats INDEX...INDEX+3 in the following format:
+ "symbol, [minus], number".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number.
+ @param MODIF Leading modifier for each portion (e.g. "t" for Thai formats). */
+#define NUMFMT_CURRENCY_SYMBOL_MINUS_NUMBER( INDEX, SYMBOL, SPACE, MODIF ) \
+ NUMFMT_STRING( INDEX + 0, MODIF SYMBOL SPACE "#,##0;" MODIF SYMBOL SPACE "-#,##0" ), \
+ NUMFMT_STRING( INDEX + 1, MODIF SYMBOL SPACE "#,##0;" "[RED]" MODIF SYMBOL SPACE "-#,##0" ), \
+ NUMFMT_STRING( INDEX + 2, MODIF SYMBOL SPACE "#,##0.00;" MODIF SYMBOL SPACE "-#,##0.00" ), \
+ NUMFMT_STRING( INDEX + 3, MODIF SYMBOL SPACE "#,##0.00;" "[RED]" MODIF SYMBOL SPACE "-#,##0.00" )
+
+/** Defines builtin accounting formats INDEX...INDEX+3 in the following format:
+ "symbol, [minus], number".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ACCOUNTING_SYMBOL_MINUS_NUMBER( INDEX, SYMBOL, SPACE ) \
+ NUMFMT_STRING( INDEX + 0, "_ " "* #,##0_ ;" "_ " "* -#,##0_ ;" "_ " "* \"-\"_ ;" "_ @_ " ), \
+ NUMFMT_STRING( INDEX + 1, "_ " SYMBOL SPACE "* #,##0_ ;" "_ " SYMBOL SPACE "* -#,##0_ ;" "_ " SYMBOL SPACE "* \"-\"_ ;" "_ @_ " ), \
+ NUMFMT_STRING( INDEX + 2, "_ " "* #,##0.00_ ;" "_ " "* -#,##0.00_ ;" "_ " "* \"-\"?\?_ ;" "_ @_ " ), \
+ NUMFMT_STRING( INDEX + 3, "_ " SYMBOL SPACE "* #,##0.00_ ;" "_ " SYMBOL SPACE "* -#,##0.00_ ;" "_ " SYMBOL SPACE "* \"-\"?\?_ ;" "_ @_ " )
+
+/** Defines builtin currency formats 5...8 (with currency symbol), 37...40
+ (blind currency symbol), and 41...44 (accounting), in the following format:
+ "symbol, [minus], number".
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( SYMBOL, SPACE ) \
+ NUMFMT_CURRENCY_SYMBOL_MINUS_NUMBER( 5, SYMBOL, SPACE, "" ), \
+ NUMFMT_CURRENCY_SYMBOL_MINUS_NUMBER( 37, "", "", "" ), \
+ NUMFMT_ACCOUNTING_SYMBOL_MINUS_NUMBER( 41, SYMBOL, SPACE )
+
+/** Defines builtin currency formats INDEX...INDEX+3 in the following format:
+ "symbol, number, [minus]".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number.
+ @param MODIF Leading modifier for each portion (e.g. "t" for Thai formats). */
+#define NUMFMT_CURRENCY_SYMBOL_NUMBER_MINUS( INDEX, SYMBOL, SPACE, MODIF ) \
+ NUMFMT_STRING( INDEX + 0, MODIF SYMBOL SPACE "#,##0_-;" MODIF SYMBOL SPACE "#,##0-" ), \
+ NUMFMT_STRING( INDEX + 1, MODIF SYMBOL SPACE "#,##0_-;" "[RED]" MODIF SYMBOL SPACE "#,##0-" ), \
+ NUMFMT_STRING( INDEX + 2, MODIF SYMBOL SPACE "#,##0.00_-;" MODIF SYMBOL SPACE "#,##0.00-" ), \
+ NUMFMT_STRING( INDEX + 3, MODIF SYMBOL SPACE "#,##0.00_-;" "[RED]" MODIF SYMBOL SPACE "#,##0.00-" )
+
+/** Defines builtin accounting formats INDEX...INDEX+3 in the following format:
+ "symbol, number, [minus]".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ACCOUNTING_SYMBOL_NUMBER_MINUS( INDEX, SYMBOL, SPACE ) \
+ NUMFMT_STRING( INDEX + 0, "_-" "* #,##0_-;" "_-" "* #,##0-;" "_-" "* \"-\"_-;" "_-@_-" ), \
+ NUMFMT_STRING( INDEX + 1, "_-" SYMBOL SPACE "* #,##0_-;" "_-" SYMBOL SPACE "* #,##0-;" "_-" SYMBOL SPACE "* \"-\"_-;" "_-@_-" ), \
+ NUMFMT_STRING( INDEX + 2, "_-" "* #,##0.00_-;" "_-" "* #,##0.00-;" "_-" "* \"-\"?\?_-;" "_-@_-" ), \
+ NUMFMT_STRING( INDEX + 3, "_-" SYMBOL SPACE "* #,##0.00_-;" "_-" SYMBOL SPACE "* #,##0.00-;" "_-" SYMBOL SPACE "* \"-\"?\?_-;" "_-@_-" )
+
+/** Defines builtin currency formats 5...8 (with currency symbol), 37...40
+ (blind currency symbol), and 41...44 (accounting), in the following format:
+ "symbol, number, [minus]".
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( SYMBOL, SPACE ) \
+ NUMFMT_CURRENCY_SYMBOL_NUMBER_MINUS( 5, SYMBOL, SPACE, "" ), \
+ NUMFMT_CURRENCY_SYMBOL_NUMBER_MINUS( 37, "", "", "" ), \
+ NUMFMT_ACCOUNTING_SYMBOL_NUMBER_MINUS( 41, SYMBOL, SPACE )
+
+/** Defines builtin currency formats INDEX...INDEX+3 in the following format:
+ "number, symbol, [minus]".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between number and currency symbol.
+ @param MODIF Leading modifier for each portion (e.g. "t" for Thai formats). */
+#define NUMFMT_CURRENCY_NUMBER_SYMBOL_MINUS( INDEX, SYMBOL, SPACE, MODIF ) \
+ NUMFMT_STRING( INDEX + 0, MODIF "#,##0" SPACE SYMBOL "_-;" MODIF "#,##0" SPACE SYMBOL "-" ), \
+ NUMFMT_STRING( INDEX + 1, MODIF "#,##0" SPACE SYMBOL "_-;" "[RED]" MODIF "#,##0" SPACE SYMBOL "-" ), \
+ NUMFMT_STRING( INDEX + 2, MODIF "#,##0.00" SPACE SYMBOL "_-;" MODIF "#,##0.00" SPACE SYMBOL "-" ), \
+ NUMFMT_STRING( INDEX + 3, MODIF "#,##0.00" SPACE SYMBOL "_-;" "[RED]" MODIF "#,##0.00" SPACE SYMBOL "-" )
+
+/** Defines builtin accounting formats INDEX...INDEX+3 in the following format:
+ "number, symbol, [minus]".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param BLINDS Blind currency symbol.
+ @param SPACE Space character(s) between number and currency symbol. */
+#define NUMFMT_ACCOUNTING_NUMBER_SYMBOL_MINUS( INDEX, SYMBOL, BLINDS, SPACE ) \
+ NUMFMT_STRING( INDEX + 0, "_-* #,##0" SPACE BLINDS "_-;_-* #,##0" SPACE BLINDS "-;_-* \"-\"" SPACE BLINDS "_-;_-@_-" ), \
+ NUMFMT_STRING( INDEX + 1, "_-* #,##0" SPACE SYMBOL "_-;_-* #,##0" SPACE SYMBOL "-;_-* \"-\"" SPACE SYMBOL "_-;_-@_-" ), \
+ NUMFMT_STRING( INDEX + 2, "_-* #,##0.00" SPACE BLINDS "_-;_-* #,##0.00" SPACE BLINDS "-;_-* \"-\"?\?" SPACE BLINDS "_-;_-@_-" ), \
+ NUMFMT_STRING( INDEX + 3, "_-* #,##0.00" SPACE SYMBOL "_-;_-* #,##0.00" SPACE SYMBOL "-;_-* \"-\"?\?" SPACE SYMBOL "_-;_-@_-" )
+
+/** Defines builtin currency formats 5...8 (with currency symbol), 37...40
+ (blind currency symbol), and 41...44 (accounting), in the following format:
+ "number, symbol, [minus]".
+ @param SYMBOL Currency symbol.
+ @param BLINDS Blind currency symbol.
+ @param SPACE Space character(s) between number and currency symbol. */
+#define NUMFMT_ALLCURRENCIES_NUMBER_SYMBOL_MINUS( SYMBOL, BLINDS, SPACE ) \
+ NUMFMT_CURRENCY_NUMBER_SYMBOL_MINUS( 5, SYMBOL, SPACE, "" ), \
+ NUMFMT_CURRENCY_NUMBER_SYMBOL_MINUS( 37, BLINDS, SPACE, "" ), \
+ NUMFMT_ACCOUNTING_NUMBER_SYMBOL_MINUS( 41, SYMBOL, BLINDS, SPACE )
+
+/** Defines builtin currency formats INDEX...INDEX+3 in the following format:
+ "[minus], symbol, number".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number.
+ @param MODIF Leading modifier for each portion (e.g. "t" for Thai formats). */
+#define NUMFMT_CURRENCY_MINUS_SYMBOL_NUMBER( INDEX, SYMBOL, SPACE, MODIF ) \
+ NUMFMT_STRING( INDEX + 0, MODIF SYMBOL SPACE "#,##0;" MODIF "-" SYMBOL SPACE "#,##0" ), \
+ NUMFMT_STRING( INDEX + 1, MODIF SYMBOL SPACE "#,##0;" "[RED]" MODIF "-" SYMBOL SPACE "#,##0" ), \
+ NUMFMT_STRING( INDEX + 2, MODIF SYMBOL SPACE "#,##0.00;" MODIF "-" SYMBOL SPACE "#,##0.00" ), \
+ NUMFMT_STRING( INDEX + 3, MODIF SYMBOL SPACE "#,##0.00;" "[RED]" MODIF "-" SYMBOL SPACE "#,##0.00" )
+
+/** Defines builtin accounting formats INDEX...INDEX+3 in the following order:
+ "[minus], symbol, number".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ACCOUNTING_MINUS_SYMBOL_NUMBER( INDEX, SYMBOL, SPACE ) \
+ NUMFMT_STRING( INDEX + 0, "_-" "* #,##0_-;" "-" "* #,##0_-;" "_-" "* \"-\"_-;" "_-@_-" ), \
+ NUMFMT_STRING( INDEX + 1, "_-" SYMBOL SPACE "* #,##0_-;" "-" SYMBOL SPACE "* #,##0_-;" "_-" SYMBOL SPACE "* \"-\"_-;" "_-@_-" ), \
+ NUMFMT_STRING( INDEX + 2, "_-" "* #,##0.00_-;" "-" "* #,##0.00_-;" "_-" "* \"-\"?\?_-;" "_-@_-" ), \
+ NUMFMT_STRING( INDEX + 3, "_-" SYMBOL SPACE "* #,##0.00_-;" "-" SYMBOL SPACE "* #,##0.00_-;" "_-" SYMBOL SPACE "* \"-\"?\?_-;" "_-@_-" )
+
+/** Defines builtin currency formats 5...8 (with currency symbol), 37...40
+ (blind currency symbol), and 41...44 (accounting), in the following order:
+ "[minus], symbol, number".
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( SYMBOL, SPACE ) \
+ NUMFMT_CURRENCY_MINUS_SYMBOL_NUMBER( 5, SYMBOL, SPACE, "" ), \
+ NUMFMT_CURRENCY_MINUS_SYMBOL_NUMBER( 37, "", "", "" ), \
+ NUMFMT_ACCOUNTING_MINUS_SYMBOL_NUMBER( 41, SYMBOL, SPACE )
+
+/** Defines builtin currency formats INDEX...INDEX+3 in the following format:
+ "[minus], number, symbol".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between number and currency symbol.
+ @param MODIF Leading modifier for each portion (e.g. "t" for Thai formats). */
+#define NUMFMT_CURRENCY_MINUS_NUMBER_SYMBOL( INDEX, SYMBOL, SPACE, MODIF ) \
+ NUMFMT_STRING( INDEX + 0, MODIF "#,##0" SPACE SYMBOL ";" MODIF "-#,##0" SPACE SYMBOL ), \
+ NUMFMT_STRING( INDEX + 1, MODIF "#,##0" SPACE SYMBOL ";" "[RED]" MODIF "-#,##0" SPACE SYMBOL ), \
+ NUMFMT_STRING( INDEX + 2, MODIF "#,##0.00" SPACE SYMBOL ";" MODIF "-#,##0.00" SPACE SYMBOL ), \
+ NUMFMT_STRING( INDEX + 3, MODIF "#,##0.00" SPACE SYMBOL ";" "[RED]" MODIF "-#,##0.00" SPACE SYMBOL )
+
+/** Defines builtin accounting formats INDEX...INDEX+3 in the following format:
+ "[minus], number, symbol".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param BLINDS Blind currency symbol.
+ @param SPACE Space character(s) between number and currency symbol. */
+#define NUMFMT_ACCOUNTING_MINUS_NUMBER_SYMBOL( INDEX, SYMBOL, BLINDS, SPACE ) \
+ NUMFMT_STRING( INDEX + 0, "_-* #,##0" SPACE BLINDS "_-;-* #,##0" SPACE BLINDS "_-;_-* \"-\"" SPACE BLINDS "_-;_-@_-" ), \
+ NUMFMT_STRING( INDEX + 1, "_-* #,##0" SPACE SYMBOL "_-;-* #,##0" SPACE SYMBOL "_-;_-* \"-\"" SPACE SYMBOL "_-;_-@_-" ), \
+ NUMFMT_STRING( INDEX + 2, "_-* #,##0.00" SPACE BLINDS "_-;-* #,##0.00" SPACE BLINDS "_-;_-* \"-\"?\?" SPACE BLINDS "_-;_-@_-" ), \
+ NUMFMT_STRING( INDEX + 3, "_-* #,##0.00" SPACE SYMBOL "_-;-* #,##0.00" SPACE SYMBOL "_-;_-* \"-\"?\?" SPACE SYMBOL "_-;_-@_-" )
+
+/** Defines builtin currency formats 5...8 (with currency symbol), 37...40
+ (blind currency symbol), and 41...44 (accounting), in the following format:
+ "[minus], number, symbol".
+ @param SYMBOL Currency symbol.
+ @param BLINDS Blind currency symbol.
+ @param SPACE Space character(s) between number and currency symbol. */
+#define NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( SYMBOL, BLINDS, SPACE ) \
+ NUMFMT_CURRENCY_MINUS_NUMBER_SYMBOL( 5, SYMBOL, SPACE, "" ), \
+ NUMFMT_CURRENCY_MINUS_NUMBER_SYMBOL( 37, BLINDS, SPACE, "" ), \
+ NUMFMT_ACCOUNTING_MINUS_NUMBER_SYMBOL( 41, SYMBOL, BLINDS, SPACE )
+
+/** Defines builtin currency formats INDEX...INDEX+3 in the following format:
+ "[opening parenthesis], symbol, number, [closing parenthesis].".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number.
+ @param MODIF Leading modifier for each portion (e.g. "t" for Thai formats). */
+#define NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( INDEX, SYMBOL, SPACE, MODIF ) \
+ NUMFMT_STRING( INDEX + 0, MODIF SYMBOL SPACE "#,##0_);" MODIF "(" SYMBOL SPACE "#,##0)" ), \
+ NUMFMT_STRING( INDEX + 1, MODIF SYMBOL SPACE "#,##0_);" "[RED]" MODIF "(" SYMBOL SPACE "#,##0)" ), \
+ NUMFMT_STRING( INDEX + 2, MODIF SYMBOL SPACE "#,##0.00_);" MODIF "(" SYMBOL SPACE "#,##0.00)" ), \
+ NUMFMT_STRING( INDEX + 3, MODIF SYMBOL SPACE "#,##0.00_);" "[RED]" MODIF "(" SYMBOL SPACE "#,##0.00)" )
+
+/** Defines builtin accounting formats INDEX...INDEX+3 in the following format:
+ "[opening parenthesis], symbol, number, [closing parenthesis].".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ACCOUNTING_OPEN_SYMBOL_NUMBER_CLOSE( INDEX, SYMBOL, SPACE ) \
+ NUMFMT_STRING( INDEX + 0, "_(" "* #,##0_);" "_(" "* (#,##0);" "_(" "* \"-\"_);" "_(@_)" ), \
+ NUMFMT_STRING( INDEX + 1, "_(" SYMBOL SPACE "* #,##0_);" "_(" SYMBOL SPACE "* (#,##0);" "_(" SYMBOL SPACE "* \"-\"_);" "_(@_)" ), \
+ NUMFMT_STRING( INDEX + 2, "_(" "* #,##0.00_);" "_(" "* (#,##0.00);" "_(" "* \"-\"?\?_);" "_(@_)" ), \
+ NUMFMT_STRING( INDEX + 3, "_(" SYMBOL SPACE "* #,##0.00_);" "_(" SYMBOL SPACE "* (#,##0.00);" "_(" SYMBOL SPACE "* \"-\"?\?_);" "_(@_)" )
+
+/** Defines builtin currency formats 5...8 (with currency symbol), 37...40
+ (blind currency symbol), and 41...44 (accounting), in the following format:
+ "[opening parenthesis], symbol, number, [closing parenthesis].".
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between currency symbol and number. */
+#define NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( SYMBOL, SPACE ) \
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 5, SYMBOL, SPACE, "" ), \
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 37, "", "", "" ), \
+ NUMFMT_ACCOUNTING_OPEN_SYMBOL_NUMBER_CLOSE( 41, SYMBOL, SPACE )
+
+/** Defines builtin currency formats INDEX...INDEX+3 in the following format:
+ "[opening parenthesis], number, symbol, [closing parenthesis].".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param SPACE Space character(s) between number and currency symbol.
+ @param MODIF Leading modifier for each portion (e.g. "t" for Thai formats). */
+#define NUMFMT_CURRENCY_OPEN_NUMBER_SYMBOL_CLOSE( INDEX, SYMBOL, SPACE, MODIF ) \
+ NUMFMT_STRING( INDEX + 0, MODIF "#,##0" SPACE SYMBOL "_);" MODIF "(#,##0" SPACE SYMBOL ")" ), \
+ NUMFMT_STRING( INDEX + 1, MODIF "#,##0" SPACE SYMBOL "_);" "[RED]" MODIF "(#,##0" SPACE SYMBOL ")" ), \
+ NUMFMT_STRING( INDEX + 2, MODIF "#,##0.00" SPACE SYMBOL "_);" MODIF "(#,##0.00" SPACE SYMBOL ")" ), \
+ NUMFMT_STRING( INDEX + 3, MODIF "#,##0.00" SPACE SYMBOL "_);" "[RED]" MODIF "(#,##0.00" SPACE SYMBOL ")" )
+
+/** Defines builtin accounting formats INDEX...INDEX+3 in the following format:
+ "[opening parenthesis], number, symbol, [closing parenthesis].".
+ @param INDEX First number format index.
+ @param SYMBOL Currency symbol.
+ @param BLINDS Blind currency symbol.
+ @param SPACE Space character(s) between number and currency symbol. */
+#define NUMFMT_ACCOUNTING_OPEN_NUMBER_SYMBOL_CLOSE( INDEX, SYMBOL, BLINDS, SPACE ) \
+ NUMFMT_STRING( INDEX + 0, "_ * #,##0_)" SPACE BLINDS "_ ;_ * (#,##0)" SPACE BLINDS "_ ;_ * \"-\"_)" SPACE BLINDS "_ ;_ @_ " ), \
+ NUMFMT_STRING( INDEX + 1, "_ * #,##0_)" SPACE SYMBOL "_ ;_ * (#,##0)" SPACE SYMBOL "_ ;_ * \"-\"_)" SPACE SYMBOL "_ ;_ @_ " ), \
+ NUMFMT_STRING( INDEX + 2, "_ * #,##0.00_)" SPACE BLINDS "_ ;_ * (#,##0.00)" SPACE BLINDS "_ ;_ * \"-\"?\?_)" SPACE BLINDS "_ ;_ @_ " ), \
+ NUMFMT_STRING( INDEX + 3, "_ * #,##0.00_)" SPACE SYMBOL "_ ;_ * (#,##0.00)" SPACE SYMBOL "_ ;_ * \"-\"?\?_)" SPACE SYMBOL "_ ;_ @_ " )
+
+/** Defines builtin currency formats 5...8 (with currency symbol), 37...40
+ (blind currency symbol), and 41...44 (accounting), in the following format:
+ "[opening parenthesis], number, symbol, [closing parenthesis].".
+ @param SYMBOL Currency symbol.
+ @param BLINDS Blind currency symbol.
+ @param SPACE Space character(s) between number and currency symbol. */
+#define NUMFMT_ALLCURRENCIES_OPEN_NUMBER_SYMBOL_CLOSE( SYMBOL, BLINDS, SPACE ) \
+ NUMFMT_CURRENCY_OPEN_NUMBER_SYMBOL_CLOSE( 5, SYMBOL, SPACE, "" ), \
+ NUMFMT_CURRENCY_OPEN_NUMBER_SYMBOL_CLOSE( 37, BLINDS, SPACE, "" ), \
+ NUMFMT_ACCOUNTING_OPEN_NUMBER_SYMBOL_CLOSE( 41, SYMBOL, BLINDS, SPACE )
+
+// currency unit characters
+#define UTF8_BAHT "\340\270\277"
+#define UTF8_COLON "\342\202\241"
+#define UTF8_CURR_AR_AE "\330\257.\330\245."
+#define UTF8_CURR_AR_BH "\330\257.\330\250."
+#define UTF8_CURR_AR_DZ "\330\257.\330\254."
+#define UTF8_CURR_AR_EG "\330\254.\331\205."
+#define UTF8_CURR_AR_IQ "\330\257.\330\271."
+#define UTF8_CURR_AR_JO "\330\257.\330\247."
+#define UTF8_CURR_AR_KW "\330\257.\331\203."
+#define UTF8_CURR_AR_LB "\331\204.\331\204."
+#define UTF8_CURR_AR_LY "\330\257.\331\204."
+#define UTF8_CURR_AR_MA "\330\257.\331\205."
+#define UTF8_CURR_AR_OM "\330\261.\330\271."
+#define UTF8_CURR_AR_QA "\330\261.\331\202."
+#define UTF8_CURR_AR_SA "\330\261.\330\263."
+#define UTF8_CURR_AR_SY "\331\204.\330\263."
+#define UTF8_CURR_AR_TN "\330\257.\330\252."
+#define UTF8_CURR_AR_YE "\330\261.\331\212."
+#define UTF8_CURR_BN_IN "\340\246\237\340\246\276"
+#define UTF8_CURR_FA_IR "\330\261\331\212\330\247\331\204"
+#define UTF8_CURR_GU_IN "\340\252\260\340\253\202"
+#define UTF8_CURR_HI_IN "\340\244\260\340\245\201"
+#define UTF8_CURR_KN_IN "\340\262\260\340\263\202"
+#define UTF8_CURR_ML_IN "\340\264\225"
+#define UTF8_CURR_PA_IN "\340\250\260\340\251\201"
+#define UTF8_CURR_TA_IN "\340\256\260\340\257\202"
+#define UTF8_CURR_TE_IN "\340\260\260\340\261\202"
+#define UTF8_DONG "\342\202\253"
+#define UTF8_EURO "\342\202\254"
+#define UTF8_POUND_GB "\302\243"
+#define UTF8_RUFIYAA "\336\203"
+#define UTF8_SHEQEL "\342\202\252"
+#define UTF8_TUGRUG "\342\202\256"
+#define UTF8_WON "\342\202\251"
+#define UTF8_YEN_CN "\357\277\245"
+#define UTF8_YEN_JP "\302\245"
+
+// Unicode characters for currency units
+#define UTF8_CCARON_LC "\304\215"
+#define UTF8_LSTROKE_LC "\305\202"
+// Armenian
+#define UTF8_HY_DA_LC "\325\244"
+#define UTF8_HY_REH_LC "\326\200"
+// Cyrillic
+#define UTF8_CYR_G_LC "\320\263"
+#define UTF8_CYR_L_LC "\320\273"
+#define UTF8_CYR_M_LC "\320\274"
+#define UTF8_CYR_N_LC "\320\275"
+#define UTF8_CYR_O_LC "\320\276"
+#define UTF8_CYR_R_LC "\321\200"
+#define UTF8_CYR_S_LC "\321\201"
+#define UTF8_CYR_W_LC "\320\262"
+
+// Japanese/Chinese date/time characters
+#define UTF8_CJ_YEAR "\345\271\264"
+#define UTF8_CJ_MON "\346\234\210"
+#define UTF8_CJ_DAY "\346\227\245"
+#define UTF8_CJ_HOUR "\346\231\202"
+#define UTF8_CJ_MIN "\345\210\206"
+#define UTF8_CJ_SEC "\347\247\222"
+
+// Chinese Simplified date/time characters
+#define UTF8_CS_YEAR "\345\271\264"
+#define UTF8_CS_MON "\346\234\210"
+#define UTF8_CS_DAY "\346\227\245"
+#define UTF8_CS_HOUR "\346\227\266"
+#define UTF8_CS_MIN "\345\210\206"
+#define UTF8_CS_SEC "\347\247\222"
+
+// Korean date/time characters
+#define UTF8_KO_YEAR "\353\205\204"
+#define UTF8_KO_MON "\354\233\224"
+#define UTF8_KO_DAY "\354\235\274"
+#define UTF8_KO_HOUR "\354\213\234"
+#define UTF8_KO_MIN "\353\266\204"
+#define UTF8_KO_SEC "\354\264\210"
+
+// ----------------------------------------------------------------------------
+
+/** Default number format table. Last parent of all other tables, used for unknown locales. */
+static const BuiltinFormat spBuiltinFormats_BASE[] =
+{
+ // 0..13 numeric and currency formats
+ NUMFMT_PREDEF( 0, NUMBER_STANDARD ), // General
+ NUMFMT_PREDEF( 1, NUMBER_INT ), // 0
+ NUMFMT_PREDEF( 2, NUMBER_DEC2 ), // 0.00
+ NUMFMT_PREDEF( 3, NUMBER_1000INT ), // #,##0
+ NUMFMT_PREDEF( 4, NUMBER_1000DEC2 ), // #,##0.00
+ NUMFMT_PREDEF( 5, CURRENCY_1000INT ), // #,##0[symbol]
+ NUMFMT_PREDEF( 6, CURRENCY_1000INT_RED ), // #,##0[symbol];[RED]-#,##0[symbol]
+ NUMFMT_PREDEF( 7, CURRENCY_1000DEC2 ), // #,##0.00[symbol]
+ NUMFMT_PREDEF( 8, CURRENCY_1000DEC2_RED ), // #,##0.00[symbol];[RED]-#,##0.00[symbol]
+ NUMFMT_PREDEF( 9, PERCENT_INT ), // 0%
+ NUMFMT_PREDEF( 10, PERCENT_DEC2 ), // 0.00%
+ NUMFMT_PREDEF( 11, SCIENTIFIC_000E00 ), // 0.00E+00
+ NUMFMT_PREDEF( 12, FRACTION_1 ), // # ?/?
+ NUMFMT_PREDEF( 13, FRACTION_2 ), // # ??/??
+
+ // 14...22 date and time formats
+ NUMFMT_PREDEF( 14, DATE_SYS_DDMMYYYY ),
+ NUMFMT_PREDEF( 15, DATE_SYS_DMMMYY ),
+ NUMFMT_PREDEF( 16, DATE_SYS_DDMMM ),
+ NUMFMT_PREDEF( 17, DATE_SYS_MMYY ),
+ NUMFMT_PREDEF( 18, TIME_HHMMAMPM ),
+ NUMFMT_PREDEF( 19, TIME_HHMMSSAMPM ),
+ NUMFMT_PREDEF( 20, TIME_HHMM ),
+ NUMFMT_PREDEF( 21, TIME_HHMMSS ),
+ NUMFMT_PREDEF( 22, DATETIME_SYSTEM_SHORT_HHMM ),
+
+ // 23...36 international formats
+ NUMFMT_REUSE( 23, 0 ),
+ NUMFMT_REUSE( 24, 0 ),
+ NUMFMT_REUSE( 25, 0 ),
+ NUMFMT_REUSE( 26, 0 ),
+ NUMFMT_REUSE( 27, 14 ),
+ NUMFMT_REUSE( 28, 14 ),
+ NUMFMT_REUSE( 29, 14 ),
+ NUMFMT_REUSE( 30, 14 ),
+ NUMFMT_REUSE( 31, 14 ),
+ NUMFMT_REUSE( 32, 21 ),
+ NUMFMT_REUSE( 33, 21 ),
+ NUMFMT_REUSE( 34, 21 ),
+ NUMFMT_REUSE( 35, 21 ),
+ NUMFMT_REUSE( 36, 14 ),
+
+ // 37...44 accounting formats, defaults without currency symbol here
+ NUMFMT_CURRENCY_MINUS_SYMBOL_NUMBER( 37, "", "", "" ),
+ NUMFMT_ACCOUNTING_MINUS_SYMBOL_NUMBER( 41, "", "" ),
+
+ // 45...49 more special formats
+ NUMFMT_STRING( 45, "mm:ss" ),
+ NUMFMT_STRING( 46, "[h]:mm:ss" ),
+ NUMFMT_STRING( 47, "mm:ss.0" ),
+ NUMFMT_STRING( 48, "##0.0E+0" ),
+ NUMFMT_PREDEF( 49, TEXT ),
+
+ // 50...81 international formats
+ NUMFMT_REUSE( 50, 14 ),
+ NUMFMT_REUSE( 51, 14 ),
+ NUMFMT_REUSE( 52, 14 ),
+ NUMFMT_REUSE( 53, 14 ),
+ NUMFMT_REUSE( 54, 14 ),
+ NUMFMT_REUSE( 55, 14 ),
+ NUMFMT_REUSE( 56, 14 ),
+ NUMFMT_REUSE( 57, 14 ),
+ NUMFMT_REUSE( 58, 14 ),
+ NUMFMT_REUSE( 59, 1 ),
+ NUMFMT_REUSE( 60, 2 ),
+ NUMFMT_REUSE( 61, 3 ),
+ NUMFMT_REUSE( 62, 4 ),
+ NUMFMT_REUSE( 63, 5 ),
+ NUMFMT_REUSE( 64, 6 ),
+ NUMFMT_REUSE( 65, 7 ),
+ NUMFMT_REUSE( 66, 8 ),
+ NUMFMT_REUSE( 67, 9 ),
+ NUMFMT_REUSE( 68, 10 ),
+ NUMFMT_REUSE( 69, 12 ),
+ NUMFMT_REUSE( 70, 13 ),
+ NUMFMT_REUSE( 71, 14 ),
+ NUMFMT_REUSE( 72, 14 ),
+ NUMFMT_REUSE( 73, 15 ),
+ NUMFMT_REUSE( 74, 16 ),
+ NUMFMT_REUSE( 75, 17 ),
+ NUMFMT_REUSE( 76, 20 ),
+ NUMFMT_REUSE( 77, 21 ),
+ NUMFMT_REUSE( 78, 22 ),
+ NUMFMT_REUSE( 79, 45 ),
+ NUMFMT_REUSE( 80, 46 ),
+ NUMFMT_REUSE( 81, 47 ),
+
+ // 82...163 not used, must not occur in a file (Excel may crash)
+
+ NUMFMT_ENDTABLE()
+};
+
+// ----------------------------------------------------------------------------
+
+/** Arabic, U.A.E. */
+static const BuiltinFormat spBuiltinFormats_ar_AE[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_AE "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Bahrain. */
+static const BuiltinFormat spBuiltinFormats_ar_BH[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_BH "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Algeria. */
+static const BuiltinFormat spBuiltinFormats_ar_DZ[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_DZ "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Egypt. */
+static const BuiltinFormat spBuiltinFormats_ar_EG[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_EG "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Iraq. */
+static const BuiltinFormat spBuiltinFormats_ar_IQ[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_IQ "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Jordan. */
+static const BuiltinFormat spBuiltinFormats_ar_JO[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_JO "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Kuwait. */
+static const BuiltinFormat spBuiltinFormats_ar_KW[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_KW "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Lebanon. */
+static const BuiltinFormat spBuiltinFormats_ar_LB[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_LB "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Libya. */
+static const BuiltinFormat spBuiltinFormats_ar_LY[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_LY "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Morocco. */
+static const BuiltinFormat spBuiltinFormats_ar_MA[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_MA "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Oman. */
+static const BuiltinFormat spBuiltinFormats_ar_OM[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_OM "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Qatar. */
+static const BuiltinFormat spBuiltinFormats_ar_QA[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_QA "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Saudi Arabia. */
+static const BuiltinFormat spBuiltinFormats_ar_SA[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_SA "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Syria. */
+static const BuiltinFormat spBuiltinFormats_ar_SY[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_SY "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Tunisia. */
+static const BuiltinFormat spBuiltinFormats_ar_TN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_TN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Arabic, Yemen. */
+static const BuiltinFormat spBuiltinFormats_ar_YE[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_AR_YE "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Belarusian, Belarus. */
+static const BuiltinFormat spBuiltinFormats_be_BY[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"" UTF8_CYR_R_LC ".\"", "_" UTF8_CYR_R_LC "_.", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Bulgarian, Bulgaria. */
+static const BuiltinFormat spBuiltinFormats_bg_BG[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.M.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"" UTF8_CYR_L_LC UTF8_CYR_W_LC "\"", "_" UTF8_CYR_L_LC "_" UTF8_CYR_W_LC, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Bengali, India. */
+static const BuiltinFormat spBuiltinFormats_bn_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_BN_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Czech, Czech Republic. */
+static const BuiltinFormat spBuiltinFormats_cs_CZ[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"K" UTF8_CCARON_LC "\"", "_K_" UTF8_CCARON_LC, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Danish, Denmark. */
+static const BuiltinFormat spBuiltinFormats_da_DK[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"kr\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** German, Austria. */
+static const BuiltinFormat spBuiltinFormats_de_AT[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** German, Switzerland. */
+static const BuiltinFormat spBuiltinFormats_de_CH[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ". ", "MMM", " ", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"SFr.\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** German, Germany. */
+static const BuiltinFormat spBuiltinFormats_de_DE[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ". ", "MMM", " ", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** German, Liechtenstein. */
+static const BuiltinFormat spBuiltinFormats_de_LI[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ". ", "MMM", " ", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"CHF\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** German, Luxembourg. */
+static const BuiltinFormat spBuiltinFormats_de_LU[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Divehi, Maldives. */
+static const BuiltinFormat spBuiltinFormats_div_MV[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_NUMBER_SYMBOL_MINUS( "\"" UTF8_RUFIYAA ".\"", "_" UTF8_RUFIYAA "_.", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Greek, Greece. */
+static const BuiltinFormat spBuiltinFormats_el_GR[] =
+{
+ NUMFMT_ALLDATETIMES( "D/M/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Australia. */
+static const BuiltinFormat spBuiltinFormats_en_AU[] =
+{
+ NUMFMT_ALLDATETIMES( "D/MM/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Belize. */
+static const BuiltinFormat spBuiltinFormats_en_BZ[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"BZ$\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Canada. */
+static const BuiltinFormat spBuiltinFormats_en_CA[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Caribbean. */
+static const BuiltinFormat spBuiltinFormats_en_CB[] =
+{
+ NUMFMT_ALLDATETIMES( "MM/DD/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, United Kingdom. */
+static const BuiltinFormat spBuiltinFormats_en_GB[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_POUND_GB, "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Ireland. */
+static const BuiltinFormat spBuiltinFormats_en_IE[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_EURO, "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Jamaica. */
+static const BuiltinFormat spBuiltinFormats_en_JM[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "\"J$\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, New Zealand. */
+static const BuiltinFormat spBuiltinFormats_en_NZ[] =
+{
+ NUMFMT_ALLDATETIMES( "D/MM/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Philippines. */
+static const BuiltinFormat spBuiltinFormats_en_PH[] =
+{
+ NUMFMT_ALLDATETIMES( "M/D/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"Php\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Trinidad and Tobago. */
+static const BuiltinFormat spBuiltinFormats_en_TT[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"TT$\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, USA. */
+static const BuiltinFormat spBuiltinFormats_en_US[] =
+{
+ NUMFMT_ALLDATETIMES( "M/D/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, South Africa. */
+static const BuiltinFormat spBuiltinFormats_en_ZA[] =
+{
+ NUMFMT_ALLDATETIMES( "YYYY/MM/DD", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\\R", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** English, Zimbabwe. */
+static const BuiltinFormat spBuiltinFormats_en_ZW[] =
+{
+ NUMFMT_ALLDATETIMES( "M/D/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"Z$\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Argentina. */
+static const BuiltinFormat spBuiltinFormats_es_AR[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "$", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Bolivia. */
+static const BuiltinFormat spBuiltinFormats_es_BO[] =
+{
+ // slashes must be quoted to prevent conversion to minus
+ NUMFMT_ALLDATETIMES( "DD\\/MM\\/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"$b\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Chile. */
+static const BuiltinFormat spBuiltinFormats_es_CL[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "$", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Colombia. */
+static const BuiltinFormat spBuiltinFormats_es_CO[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "$", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Costa Rica. */
+static const BuiltinFormat spBuiltinFormats_es_CR[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( UTF8_COLON, "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Dominican Republic. */
+static const BuiltinFormat spBuiltinFormats_es_DO[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"RD$\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Ecuador. */
+static const BuiltinFormat spBuiltinFormats_es_EC[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "$", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Spain. */
+static const BuiltinFormat spBuiltinFormats_es_ES[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Guatemala. */
+static const BuiltinFormat spBuiltinFormats_es_GT[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\\Q", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Honduras. */
+static const BuiltinFormat spBuiltinFormats_es_HN[] =
+{
+ // slashes must be quoted to prevent conversion to minus
+ NUMFMT_ALLDATETIMES( "DD\\/MM\\/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"L.\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Mexico. */
+static const BuiltinFormat spBuiltinFormats_es_MX[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Nicaragua. */
+static const BuiltinFormat spBuiltinFormats_es_NI[] =
+{
+ // slashes must be quoted to prevent conversion to minus
+ NUMFMT_ALLDATETIMES( "DD\\/MM\\/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"C$\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Panama. */
+static const BuiltinFormat spBuiltinFormats_es_PA[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"B/.\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Peru. */
+static const BuiltinFormat spBuiltinFormats_es_PE[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"S/.\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Puerto Rico. */
+static const BuiltinFormat spBuiltinFormats_es_PR[] =
+{
+ // slashes must be quoted to prevent conversion to minus
+ NUMFMT_ALLDATETIMES( "DD\\/MM\\/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "$", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Paraguay. */
+static const BuiltinFormat spBuiltinFormats_es_PY[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"Gs\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, El Salvador. */
+static const BuiltinFormat spBuiltinFormats_es_SV[] =
+{
+ // slashes must be quoted to prevent conversion to minus
+ NUMFMT_ALLDATETIMES( "DD\\/MM\\/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Uruguay. */
+static const BuiltinFormat spBuiltinFormats_es_UY[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"$U\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Spanish, Venezuela. */
+static const BuiltinFormat spBuiltinFormats_es_VE[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "Bs", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Estonian, Estonia. */
+static const BuiltinFormat spBuiltinFormats_et_EE[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "D.MM.YYYY", "D", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"kr\"", "_k_r", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Farsi, Iran. */
+static const BuiltinFormat spBuiltinFormats_fa_IR[] =
+{
+ NUMFMT_ALLDATETIMES( "YYYY/MM/DD", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"" UTF8_CURR_FA_IR "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Finnish, Finland. */
+static const BuiltinFormat spBuiltinFormats_fi_FI[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_STRING( 9, "0\\ %" ),
+ NUMFMT_STRING( 10, "0.00\\ %" ),
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Faroese, Faroe Islands. */
+static const BuiltinFormat spBuiltinFormats_fo_FO[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"kr\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** French, Belgium. */
+static const BuiltinFormat spBuiltinFormats_fr_BE[] =
+{
+ NUMFMT_ALLDATETIMES( "D/MM/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** French, Canada. */
+static const BuiltinFormat spBuiltinFormats_fr_CA[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "YYYY-MM-DD", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_NUMBER_SYMBOL_CLOSE( "$", "_$", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** French, Switzerland. */
+static const BuiltinFormat spBuiltinFormats_fr_CH[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"SFr.\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** French, France. */
+static const BuiltinFormat spBuiltinFormats_fr_FR[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** French, Luxembourg. */
+static const BuiltinFormat spBuiltinFormats_fr_LU[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** French, Monaco. */
+static const BuiltinFormat spBuiltinFormats_fr_MC[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Galizian, Spain. */
+static const BuiltinFormat spBuiltinFormats_gl_ES[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Gujarati, India. */
+static const BuiltinFormat spBuiltinFormats_gu_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_GU_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Hebrew, Israel. */
+static const BuiltinFormat spBuiltinFormats_he_IL[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( UTF8_SHEQEL, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Hindi, India. */
+static const BuiltinFormat spBuiltinFormats_hi_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_HI_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Croatian, Bosnia and Herzegowina. */
+static const BuiltinFormat spBuiltinFormats_hr_BA[] =
+{
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"KM\"", "_K_M", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Croatian, Croatia. */
+static const BuiltinFormat spBuiltinFormats_hr_HR[] =
+{
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"kn\"", "_k_n", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Hungarian, Hungary. */
+static const BuiltinFormat spBuiltinFormats_hu_HU[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ // MMM is rendered differently in Calc and Excel (see #i41488#)
+ NUMFMT_ALLDATETIMES( "YYYY.MM.DD", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"Ft\"", "_F_t", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Armenian, Armenia. */
+static const BuiltinFormat spBuiltinFormats_hy_AM[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"" UTF8_HY_DA_LC UTF8_HY_REH_LC ".\"", "_" UTF8_HY_DA_LC "_" UTF8_HY_REH_LC "_.", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Indonesian, Indonesia. */
+static const BuiltinFormat spBuiltinFormats_id_ID[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"Rp\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Icelandic, Iceland. */
+static const BuiltinFormat spBuiltinFormats_is_IS[] =
+{
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"kr.\"", "_k_r_.", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Italian, Switzerland. */
+static const BuiltinFormat spBuiltinFormats_it_CH[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"SFr.\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Italian, Italy. */
+static const BuiltinFormat spBuiltinFormats_it_IT[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Georgian, Georgia. */
+static const BuiltinFormat spBuiltinFormats_ka_GE[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"Lari\"", "_L_a_r_i", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Kazakh, Kazakhstan. */
+static const BuiltinFormat spBuiltinFormats_kk_KZ[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "\\T", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Kannada, India. */
+static const BuiltinFormat spBuiltinFormats_kn_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_KN_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Kyrgyz, Kyrgyzstan. */
+static const BuiltinFormat spBuiltinFormats_ky_KG[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"" UTF8_CYR_S_LC UTF8_CYR_O_LC UTF8_CYR_M_LC "\"", "_" UTF8_CYR_S_LC "_" UTF8_CYR_O_LC "_" UTF8_CYR_M_LC, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Lithuanian, Lithuania. */
+static const BuiltinFormat spBuiltinFormats_lt_LT[] =
+{
+ NUMFMT_ALLDATETIMES( "YYYY.MM.DD", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"Lt\"", "_L_t", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Latvian, Latvia. */
+static const BuiltinFormat spBuiltinFormats_lv_LV[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "YYYY.MM.DD", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "\"Ls\"", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Malayalam, India. */
+static const BuiltinFormat spBuiltinFormats_ml_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_ML_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Mongolian, Mongolia. */
+static const BuiltinFormat spBuiltinFormats_mn_MN[] =
+{
+ NUMFMT_ALLDATETIMES( "YY.MM.DD", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_TUGRUG, "_" UTF8_TUGRUG, "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Malay, Brunei Darussalam. */
+static const BuiltinFormat spBuiltinFormats_ms_BN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "$", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Malay, Malaysia. */
+static const BuiltinFormat spBuiltinFormats_ms_MY[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\\R", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Maltese, Malta. */
+static const BuiltinFormat spBuiltinFormats_mt_MT[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "\"Lm\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Dutch, Belgium. */
+static const BuiltinFormat spBuiltinFormats_nl_BE[] =
+{
+ // slashes must be quoted to prevent conversion to minus
+ NUMFMT_ALLDATETIMES( "D\\/MM\\/YYYY", "D", "\\/", "MMM", "\\/", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Dutch, Netherlands. */
+static const BuiltinFormat spBuiltinFormats_nl_NL[] =
+{
+ NUMFMT_ALLDATETIMES( "D-M-YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Norwegian (Bokmal and Nynorsk), Norway. */
+static const BuiltinFormat spBuiltinFormats_no_NO[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"kr\"", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Punjabi, India. */
+static const BuiltinFormat spBuiltinFormats_pa_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YY", "DD", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_PA_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Polish, Poland. */
+static const BuiltinFormat spBuiltinFormats_pl_PL[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ // MMM is rendered differently in Calc and Excel (see #i72300#)
+ NUMFMT_ALLDATETIMES( "YYYY-MM-DD", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"z" UTF8_LSTROKE_LC "\"", "_z_" UTF8_LSTROKE_LC, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Portugese, Brazil. */
+static const BuiltinFormat spBuiltinFormats_pt_BR[] =
+{
+ NUMFMT_ALLDATETIMES( "D/M/YYYY", "D", "/", "MMM", "/", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"R$\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Portugese, Portugal. */
+static const BuiltinFormat spBuiltinFormats_pt_PT[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Romanian, Romania. */
+static const BuiltinFormat spBuiltinFormats_ro_RO[] =
+{
+ // space character is group separator, literal spaces must be quoted (but see #i75367#)
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"lei\"", "_l_e_i", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Russian, Russian Federation. */
+static const BuiltinFormat spBuiltinFormats_ru_RU[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"" UTF8_CYR_R_LC ".\"", "_" UTF8_CYR_R_LC "_.", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Slovak, Slovakia. */
+static const BuiltinFormat spBuiltinFormats_sk_SK[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"Sk\"", "_S_k", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Slovenian, Slovenia. */
+static const BuiltinFormat spBuiltinFormats_sl_SI[] =
+{
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"SIT\"", "_S_I_T", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Swedish, Finland. */
+static const BuiltinFormat spBuiltinFormats_sv_FI[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_STRING( 9, "0\\ %" ),
+ NUMFMT_STRING( 10, "0.00\\ %" ),
+ NUMFMT_ALLDATETIMES( "D.M.YYYY", "D", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_EURO, "_" UTF8_EURO, "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Swedish, Sweden. */
+static const BuiltinFormat spBuiltinFormats_sv_SE[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "YYYY-MM-DD", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"kr\"", "_k_r", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Swahili, Tanzania. */
+static const BuiltinFormat spBuiltinFormats_sw_TZ[] =
+{
+ NUMFMT_ALLDATETIMES( "M/D/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\\S", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Tamil, India. */
+static const BuiltinFormat spBuiltinFormats_ta_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YYYY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_TA_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Telugu, India. */
+static const BuiltinFormat spBuiltinFormats_te_IN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD-MM-YY", "DD", "-", "MMM", "-", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( "\"" UTF8_CURR_TE_IN "\"", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Thai, Thailand. */
+static const BuiltinFormat spBuiltinFormats_th_TH[] =
+{
+ NUMFMT_ALLDATETIMES( "D/M/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_BAHT, "" ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 63, UTF8_BAHT, "", "t" ),
+ NUMFMT_STRING( 59, "t0" ),
+ NUMFMT_STRING( 60, "t0.00" ),
+ NUMFMT_STRING( 61, "t#,##0" ),
+ NUMFMT_STRING( 62, "t#,##0.00" ),
+ NUMFMT_STRING( 67, "t0%" ),
+ NUMFMT_STRING( 68, "t0.00%" ),
+ NUMFMT_STRING( 69, "t# ?/?" ),
+ NUMFMT_STRING( 70, "t# ?\?/?\?" ),
+ NUMFMT_STRING( 71, "tD/M/EE" ),
+ NUMFMT_STRING( 72, "tD-MMM-E" ),
+ NUMFMT_STRING( 73, "tD-MMM" ),
+ NUMFMT_STRING( 74, "tMMM-E" ),
+ NUMFMT_STRING( 75, "th:mm" ),
+ NUMFMT_STRING( 76, "th:mm:ss" ),
+ NUMFMT_STRING( 77, "tD/M/EE h:mm" ),
+ NUMFMT_STRING( 78, "tmm:ss" ),
+ NUMFMT_STRING( 79, "t[h]:mm:ss" ),
+ NUMFMT_STRING( 80, "tmm:ss.0" ),
+ NUMFMT_STRING( 81, "D/M/E" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Turkish, Turkey. */
+static const BuiltinFormat spBuiltinFormats_tr_TR[] =
+{
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"TL\"", "_T_L", " " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Tatar, Russian Federation. */
+static const BuiltinFormat spBuiltinFormats_tt_RU[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"" UTF8_CYR_R_LC ".\"", "_" UTF8_CYR_R_LC "_.", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Ukrainian, Ukraine. */
+static const BuiltinFormat spBuiltinFormats_uk_UA[] =
+{
+ // space character is group separator, literal spaces must be quoted
+ NUMFMT_ALLDATETIMES( "DD.MM.YYYY", "DD", ".", "MMM", ".", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( "\"" UTF8_CYR_G_LC UTF8_CYR_R_LC UTF8_CYR_N_LC ".\"", "_" UTF8_CYR_G_LC "_" UTF8_CYR_R_LC "_" UTF8_CYR_N_LC "_.", "\\ " ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Urdu, Pakistan. */
+static const BuiltinFormat spBuiltinFormats_ur_PK[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_NUMBER_MINUS( "\"Rs\"", "" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Vietnamese, Viet Nam. */
+static const BuiltinFormat spBuiltinFormats_vi_VN[] =
+{
+ NUMFMT_ALLDATETIMES( "DD/MM/YYYY", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_NUMBER_SYMBOL( UTF8_DONG, "_" UTF8_DONG, " " ),
+ NUMFMT_ENDTABLE()
+};
+
+// CJK ------------------------------------------------------------------------
+
+/** Base table for CJK locales. */
+static const BuiltinFormat spBuiltinFormats_CJK[] =
+{
+ NUMFMT_REUSE( 29, 28 ),
+ NUMFMT_REUSE( 36, 27 ),
+ NUMFMT_REUSE( 50, 27 ),
+ NUMFMT_REUSE( 51, 28 ),
+ NUMFMT_REUSE( 52, 34 ),
+ NUMFMT_REUSE( 53, 35 ),
+ NUMFMT_REUSE( 54, 28 ),
+ NUMFMT_REUSE( 55, 34 ),
+ NUMFMT_REUSE( 56, 35 ),
+ NUMFMT_REUSE( 57, 27 ),
+ NUMFMT_REUSE( 58, 28 ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Japanese, Japan. */
+static const BuiltinFormat spBuiltinFormats_ja_JP[] =
+{
+ NUMFMT_ALLDATETIMES( "YYYY/MM/DD", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_YEN_JP, "" ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 23, "$", "", "" ),
+ NUMFMT_STRING( 27, "[$-411]GE.MM.DD" ),
+ NUMFMT_STRING( 28, "[$-411]GGGE\"" UTF8_CJ_YEAR "\"MM\"" UTF8_CJ_MON "\"DD\"" UTF8_CJ_DAY "\"" ),
+ NUMFMT_STRING( 30, "MM/DD/YY" ),
+ NUMFMT_STRING( 31, "YYYY\"" UTF8_CJ_YEAR "\"MM\"" UTF8_CJ_MON "\"DD\"" UTF8_CJ_DAY "\"" ),
+ NUMFMT_TIME_CJK( 32, "h", UTF8_CJ_HOUR, UTF8_CJ_MIN, UTF8_CJ_SEC ),
+ NUMFMT_STRING( 34, "YYYY\"" UTF8_CJ_YEAR "\"MM\"" UTF8_CJ_MON "\"" ),
+ NUMFMT_STRING( 35, "MM\"" UTF8_CJ_MON "\"DD\"" UTF8_CJ_DAY "\"" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Korean, South Korea. */
+static const BuiltinFormat spBuiltinFormats_ko_KR[] =
+{
+ NUMFMT_ALLDATETIMES( "YYYY-MM-DD", "DD", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( UTF8_WON, "" ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 23, "$", "", "" ),
+ NUMFMT_STRING( 27, "YYYY" UTF8_CJ_YEAR " MM" UTF8_CJ_MON " DD" UTF8_CJ_DAY ),
+ NUMFMT_STRING( 28, "MM-DD" ),
+ NUMFMT_STRING( 30, "MM-DD-YY" ),
+ NUMFMT_STRING( 31, "YYYY" UTF8_KO_YEAR " MM" UTF8_KO_MON " DD" UTF8_KO_DAY ),
+ NUMFMT_TIME_CJK( 32, "h", UTF8_KO_HOUR, UTF8_KO_MIN, UTF8_KO_SEC ),
+ // slashes must be quoted to prevent conversion to minus
+ NUMFMT_STRING( 34, "YYYY\\/MM\\/DD" ),
+ NUMFMT_REUSE( 35, 14 ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Chinese, China. */
+static const BuiltinFormat spBuiltinFormats_zh_CN[] =
+{
+ NUMFMT_ALLDATETIMES( "YYYY-M-D", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_SYMBOL_MINUS_NUMBER( UTF8_YEN_CN, "" ),
+ NUMFMT_ALLTIMES_CJK( "h", "h", UTF8_CS_HOUR, UTF8_CS_MIN, UTF8_CS_SEC ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 23, "$", "", "" ),
+ NUMFMT_STRING( 27, "YYYY\"" UTF8_CS_YEAR "\"M\"" UTF8_CS_MON "\"" ),
+ NUMFMT_STRING( 28, "M\"" UTF8_CS_MON "\"D\"" UTF8_CS_DAY "\"" ),
+ NUMFMT_STRING( 30, "M-D-YY" ),
+ NUMFMT_STRING( 31, "YYYY\"" UTF8_CS_YEAR "\"M\"" UTF8_CS_MON "\"D\"" UTF8_CS_DAY "\"" ),
+ NUMFMT_REUSE( 52, 27 ),
+ NUMFMT_REUSE( 53, 28 ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Chinese, Hong Kong. */
+static const BuiltinFormat spBuiltinFormats_zh_HK[] =
+{
+ NUMFMT_ALLDATETIMES( "D/M/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\"HK$\"", "" ),
+ NUMFMT_ALLTIMES_CJK( "h", "h", UTF8_CJ_HOUR, UTF8_CJ_MIN, UTF8_CJ_SEC ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 23, "\"US$\"", "", "" ),
+ NUMFMT_STRING( 27, "[$-404]D/M/E" ),
+ NUMFMT_STRING( 28, "[$-404]D\"" UTF8_CJ_DAY "\"M\"" UTF8_CJ_MON "\"E\"" UTF8_CJ_YEAR "\"" ),
+ NUMFMT_STRING( 30, "M/D/YY" ),
+ NUMFMT_STRING( 31, "D\"" UTF8_CJ_DAY "\"M\"" UTF8_CJ_MON "\"YYYY\"" UTF8_CJ_YEAR "\"" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Chinese, Macau. */
+static const BuiltinFormat spBuiltinFormats_zh_MO[] =
+{
+ NUMFMT_ALLDATETIMES( "D/M/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "\\P", "" ),
+ NUMFMT_ALLTIMES_CJK( "h", "h", UTF8_CJ_HOUR, UTF8_CJ_MIN, UTF8_CJ_SEC ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 23, "\"US$\"", "", "" ),
+ NUMFMT_STRING( 27, "[$-404]D/M/E" ),
+ NUMFMT_STRING( 28, "[$-404]D\"" UTF8_CJ_DAY "\"M\"" UTF8_CJ_MON "\"E\"" UTF8_CJ_YEAR "\"" ),
+ NUMFMT_STRING( 30, "M/D/YY" ),
+ NUMFMT_STRING( 31, "D\"" UTF8_CJ_DAY "\"M\"" UTF8_CJ_MON "\"YYYY\"" UTF8_CJ_YEAR "\"" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Chinese, Singapore. */
+static const BuiltinFormat spBuiltinFormats_zh_SG[] =
+{
+ NUMFMT_ALLDATETIMES( "D/M/YYYY", "D", "-", "MMM", "-", "YY", "h", "h" ),
+ NUMFMT_ALLCURRENCIES_OPEN_SYMBOL_NUMBER_CLOSE( "$", "" ),
+ NUMFMT_ALLTIMES_CJK( "h", "h", UTF8_CS_HOUR, UTF8_CS_MIN, UTF8_CS_SEC ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 23, "$", "", "" ),
+ NUMFMT_STRING( 27, "YYYY\"" UTF8_CS_YEAR "\"M\"" UTF8_CS_MON "\"" ),
+ NUMFMT_STRING( 28, "M\"" UTF8_CS_MON "\"D\"" UTF8_CS_DAY "\"" ),
+ NUMFMT_STRING( 30, "M/D/YY" ),
+ NUMFMT_STRING( 31, "D\"" UTF8_CS_DAY "\"M\"" UTF8_CS_MON "\"YYYY\"" UTF8_CS_YEAR "\"" ),
+ NUMFMT_ENDTABLE()
+};
+
+/** Chinese, Taiwan. */
+static const BuiltinFormat spBuiltinFormats_zh_TW[] =
+{
+ NUMFMT_ALLDATETIMES( "YYYY/M/D", "D", "-", "MMM", "-", "YY", "hh", "hh" ),
+ NUMFMT_ALLCURRENCIES_MINUS_SYMBOL_NUMBER( "$", "" ),
+ NUMFMT_ALLTIMES_CJK( "hh", "hh", UTF8_CJ_HOUR, UTF8_CJ_MIN, UTF8_CJ_SEC ),
+ NUMFMT_CURRENCY_OPEN_SYMBOL_NUMBER_CLOSE( 23, "\"US$\"", "", "" ),
+ NUMFMT_STRING( 27, "[$-404]E/M/D" ),
+ NUMFMT_STRING( 28, "[$-404]E\"" UTF8_CJ_YEAR "\"M\"" UTF8_CJ_MON "\"D\"" UTF8_CJ_DAY "\"" ),
+ NUMFMT_STRING( 30, "M/D/YY" ),
+ NUMFMT_STRING( 31, "YYYY\"" UTF8_CJ_YEAR "\"M\"" UTF8_CJ_MON "\"D\"" UTF8_CJ_DAY "\"" ),
+ NUMFMT_ENDTABLE()
+};
+
+// ----------------------------------------------------------------------------
+
+/** Specifies a built-in number format table for a specific locale. */
+struct BuiltinFormatTable
+{
+ const sal_Char* mpcLocale; /// The locale for this table.
+ const sal_Char* mpcParent; /// The locale of the parent table.
+ const BuiltinFormat* mpFormats; /// The number format table (may be 0, if equal to parent).
+};
+
+static const BuiltinFormatTable spBuiltinFormatTables[] =
+{ // locale parent format table
+ { "*", "", spBuiltinFormats_BASE }, // Base table
+ { "af-ZA", "*", spBuiltinFormats_en_ZA }, // Afrikaans, South Africa
+ { "ar-AE", "*", spBuiltinFormats_ar_AE }, // Arabic, U.A.E.
+ { "ar-BH", "*", spBuiltinFormats_ar_BH }, // Arabic, Bahrain
+ { "ar-DZ", "*", spBuiltinFormats_ar_DZ }, // Arabic, Algeria
+ { "ar-EG", "*", spBuiltinFormats_ar_EG }, // Arabic, Egypt
+ { "ar-IQ", "*", spBuiltinFormats_ar_IQ }, // Arabic, Iraq
+ { "ar-JO", "*", spBuiltinFormats_ar_JO }, // Arabic, Jordan
+ { "ar-KW", "*", spBuiltinFormats_ar_KW }, // Arabic, Kuwait
+ { "ar-LB", "*", spBuiltinFormats_ar_LB }, // Arabic, Lebanon
+ { "ar-LY", "*", spBuiltinFormats_ar_LY }, // Arabic, Libya
+ { "ar-MA", "*", spBuiltinFormats_ar_MA }, // Arabic, Morocco
+ { "ar-OM", "*", spBuiltinFormats_ar_OM }, // Arabic, Oman
+ { "ar-QA", "*", spBuiltinFormats_ar_QA }, // Arabic, Qatar
+ { "ar-SA", "*", spBuiltinFormats_ar_SA }, // Arabic, Saudi Arabia
+ { "ar-SY", "*", spBuiltinFormats_ar_SY }, // Arabic, Syria
+ { "ar-TN", "*", spBuiltinFormats_ar_TN }, // Arabic, Tunisia
+ { "ar-YE", "*", spBuiltinFormats_ar_YE }, // Arabic, Yemen
+ { "be-BY", "*", spBuiltinFormats_be_BY }, // Belarusian, Belarus
+ { "bg-BG", "*", spBuiltinFormats_bg_BG }, // Bulgarian, Bulgaria
+ { "bn-IN", "*", spBuiltinFormats_bn_IN }, // Bengali, India
+ { "ca-ES", "*", spBuiltinFormats_es_ES }, // Catalan, Spain
+ { "cs-CZ", "*", spBuiltinFormats_cs_CZ }, // Czech, Czech Republic
+ { "cy-GB", "*", spBuiltinFormats_en_GB }, // Welsh, United Kingdom
+ { "da-DK", "*", spBuiltinFormats_da_DK }, // Danish, Denmark
+ { "de-AT", "*", spBuiltinFormats_de_AT }, // German, Austria
+ { "de-CH", "*", spBuiltinFormats_de_CH }, // German, Switzerland
+ { "de-DE", "*", spBuiltinFormats_de_DE }, // German, Germany
+ { "de-LI", "*", spBuiltinFormats_de_LI }, // German, Liechtenstein
+ { "de-LU", "*", spBuiltinFormats_de_LU }, // German, Luxembourg
+ { "div-MV", "*", spBuiltinFormats_div_MV }, // Divehi, Maldives
+ { "el-GR", "*", spBuiltinFormats_el_GR }, // Greek, Greece
+ { "en-AU", "*", spBuiltinFormats_en_AU }, // English, Australia
+ { "en-BZ", "*", spBuiltinFormats_en_BZ }, // English, Belize
+ { "en-CA", "*", spBuiltinFormats_en_CA }, // English, Canada
+ { "en-CB", "*", spBuiltinFormats_en_CB }, // English, Caribbean
+ { "en-GB", "*", spBuiltinFormats_en_GB }, // English, United Kingdom
+ { "en-IE", "*", spBuiltinFormats_en_IE }, // English, Ireland
+ { "en-JM", "*", spBuiltinFormats_en_JM }, // English, Jamaica
+ { "en-NZ", "*", spBuiltinFormats_en_NZ }, // English, New Zealand
+ { "en-PH", "*", spBuiltinFormats_en_PH }, // English, Philippines
+ { "en-TT", "*", spBuiltinFormats_en_TT }, // English, Trinidad and Tobago
+ { "en-US", "*", spBuiltinFormats_en_US }, // English, USA
+ { "en-ZA", "*", spBuiltinFormats_en_ZA }, // English, South Africa
+ { "en-ZW", "*", spBuiltinFormats_en_ZW }, // English, Zimbabwe
+ { "es-AR", "*", spBuiltinFormats_es_AR }, // Spanish, Argentina
+ { "es-BO", "*", spBuiltinFormats_es_BO }, // Spanish, Bolivia
+ { "es-CL", "*", spBuiltinFormats_es_CL }, // Spanish, Chile
+ { "es-CO", "*", spBuiltinFormats_es_CO }, // Spanish, Colombia
+ { "es-CR", "*", spBuiltinFormats_es_CR }, // Spanish, Costa Rica
+ { "es-DO", "*", spBuiltinFormats_es_DO }, // Spanish, Dominican Republic
+ { "es-EC", "*", spBuiltinFormats_es_EC }, // Spanish, Ecuador
+ { "es-ES", "*", spBuiltinFormats_es_ES }, // Spanish, Spain
+ { "es-GT", "*", spBuiltinFormats_es_GT }, // Spanish, Guatemala
+ { "es-HN", "*", spBuiltinFormats_es_HN }, // Spanish, Honduras
+ { "es-MX", "*", spBuiltinFormats_es_MX }, // Spanish, Mexico
+ { "es-NI", "*", spBuiltinFormats_es_NI }, // Spanish, Nicaragua
+ { "es-PA", "*", spBuiltinFormats_es_PA }, // Spanish, Panama
+ { "es-PE", "*", spBuiltinFormats_es_PE }, // Spanish, Peru
+ { "es-PR", "*", spBuiltinFormats_es_PR }, // Spanish, Puerto Rico
+ { "es-PY", "*", spBuiltinFormats_es_PY }, // Spanish, Paraguay
+ { "es-SV", "*", spBuiltinFormats_es_SV }, // Spanish, El Salvador
+ { "es-UY", "*", spBuiltinFormats_es_UY }, // Spanish, Uruguay
+ { "es-VE", "*", spBuiltinFormats_es_VE }, // Spanish, Venezuela
+ { "et-EE", "*", spBuiltinFormats_et_EE }, // Estonian, Estonia
+ { "fa-IR", "*", spBuiltinFormats_fa_IR }, // Farsi, Iran
+ { "fi-FI", "*", spBuiltinFormats_fi_FI }, // Finnish, Finland
+ { "fo-FO", "*", spBuiltinFormats_fo_FO }, // Faroese, Faroe Islands
+ { "fr-BE", "*", spBuiltinFormats_fr_BE }, // French, Belgium
+ { "fr-CA", "*", spBuiltinFormats_fr_CA }, // French, Canada
+ { "fr-CH", "*", spBuiltinFormats_fr_CH }, // French, Switzerland
+ { "fr-FR", "*", spBuiltinFormats_fr_FR }, // French, France
+ { "fr-LU", "*", spBuiltinFormats_fr_LU }, // French, Luxembourg
+ { "fr-MC", "*", spBuiltinFormats_fr_MC }, // French, Monaco
+ { "gl-ES", "*", spBuiltinFormats_gl_ES }, // Galizian, Spain
+ { "gu-IN", "*", spBuiltinFormats_gu_IN }, // Gujarati, India
+ { "he-IL", "*", spBuiltinFormats_he_IL }, // Hebrew, Israel
+ { "hi-IN", "*", spBuiltinFormats_hi_IN }, // Hindi, India
+ { "hr-BA", "*", spBuiltinFormats_hr_BA }, // Croatian, Bosnia and Herzegowina
+ { "hr-HR", "*", spBuiltinFormats_hr_HR }, // Croatian, Croatia
+ { "hu-HU", "*", spBuiltinFormats_hu_HU }, // Hungarian, Hungary
+ { "hy-AM", "*", spBuiltinFormats_hy_AM }, // Armenian, Armenia
+ { "id-ID", "*", spBuiltinFormats_id_ID }, // Indonesian, Indonesia
+ { "is-IS", "*", spBuiltinFormats_is_IS }, // Icelandic, Iceland
+ { "it-CH", "*", spBuiltinFormats_it_CH }, // Italian, Switzerland
+ { "it-IT", "*", spBuiltinFormats_it_IT }, // Italian, Italy
+ { "ka-GE", "*", spBuiltinFormats_ka_GE }, // Georgian, Georgia
+ { "kk-KZ", "*", spBuiltinFormats_kk_KZ }, // Kazakh, Kazakhstan
+ { "kn-IN", "*", spBuiltinFormats_kn_IN }, // Kannada, India
+ { "kok-IN", "*", spBuiltinFormats_hi_IN }, // Konkani, India
+ { "ky-KG", "*", spBuiltinFormats_ky_KG }, // Kyrgyz, Kyrgyzstan
+ { "lt-LT", "*", spBuiltinFormats_lt_LT }, // Lithuanian, Lithuania
+ { "lv-LV", "*", spBuiltinFormats_lv_LV }, // Latvian, Latvia
+ { "mi-NZ", "*", spBuiltinFormats_en_NZ }, // Maori, New Zealand
+ { "ml-IN", "*", spBuiltinFormats_ml_IN }, // Malayalam, India
+ { "mn-MN", "*", spBuiltinFormats_mn_MN }, // Mongolian, Mongolia
+ { "mr-IN", "*", spBuiltinFormats_hi_IN }, // Marathi, India
+ { "ms-BN", "*", spBuiltinFormats_ms_BN }, // Malay, Brunei Darussalam
+ { "ms-MY", "*", spBuiltinFormats_ms_MY }, // Malay, Malaysia
+ { "mt-MT", "*", spBuiltinFormats_mt_MT }, // Maltese, Malta
+ { "nb-NO", "*", spBuiltinFormats_no_NO }, // Norwegian Bokmal, Norway
+ { "nl-BE", "*", spBuiltinFormats_nl_BE }, // Dutch, Belgium
+ { "nl-NL", "*", spBuiltinFormats_nl_NL }, // Dutch, Netherlands
+ { "nn-NO", "*", spBuiltinFormats_no_NO }, // Norwegian Nynorsk, Norway
+ { "nso-ZA", "*", spBuiltinFormats_en_ZA }, // Northern Sotho, South Africa
+ { "pa-IN", "*", spBuiltinFormats_pa_IN }, // Punjabi, India
+ { "pl-PL", "*", spBuiltinFormats_pl_PL }, // Polish, Poland
+ { "pt-BR", "*", spBuiltinFormats_pt_BR }, // Portugese, Brazil
+ { "pt-PT", "*", spBuiltinFormats_pt_PT }, // Portugese, Portugal
+ { "qu-BO", "*", spBuiltinFormats_es_BO }, // Quechua, Bolivia
+ { "qu-EC", "*", spBuiltinFormats_es_EC }, // Quechua, Ecuador
+ { "qu-PE", "*", spBuiltinFormats_es_PE }, // Quechua, Peru
+ { "ro-RO", "*", spBuiltinFormats_ro_RO }, // Romanian, Romania
+ { "ru-RU", "*", spBuiltinFormats_ru_RU }, // Russian, Russian Federation
+ { "sa-IN", "*", spBuiltinFormats_hi_IN }, // Sanskrit, India
+ { "se-FI", "*", spBuiltinFormats_fi_FI }, // Sami, Finland
+ { "se-NO", "*", spBuiltinFormats_no_NO }, // Sami, Norway
+ { "se-SE", "*", spBuiltinFormats_sv_SE }, // Sami, Sweden
+ { "sk-SK", "*", spBuiltinFormats_sk_SK }, // Slovak, Slovakia
+ { "sl-SI", "*", spBuiltinFormats_sl_SI }, // Slovenian, Slovenia
+ { "sv-FI", "*", spBuiltinFormats_sv_FI }, // Swedish, Finland
+ { "sv-SE", "*", spBuiltinFormats_sv_SE }, // Swedish, Sweden
+ { "sw-TZ", "*", spBuiltinFormats_sw_TZ }, // Swahili, Tanzania
+ { "syr-SY", "*", spBuiltinFormats_ar_SY }, // Syriac, Syria
+ { "syr-TR", "*", spBuiltinFormats_tr_TR }, // Syriac, Turkey
+ { "ta-IN", "*", spBuiltinFormats_ta_IN }, // Tamil, India
+ { "te-IN", "*", spBuiltinFormats_te_IN }, // Telugu, India
+ { "th-TH", "*", spBuiltinFormats_th_TH }, // Thai, Thailand
+ { "tn-ZA", "*", spBuiltinFormats_en_ZA }, // Tswana, South Africa
+ { "tr-TR", "*", spBuiltinFormats_tr_TR }, // Turkish, Turkey
+ { "tt-RU", "*", spBuiltinFormats_tt_RU }, // Tatar, Russian Federation
+ { "uk-UA", "*", spBuiltinFormats_uk_UA }, // Ukrainian, Ukraine
+ { "ur-PK", "*", spBuiltinFormats_ur_PK }, // Urdu, Pakistan
+ { "vi-VN", "*", spBuiltinFormats_vi_VN }, // Vietnamese, Viet Nam
+ { "xh-ZA", "*", spBuiltinFormats_en_ZA }, // Xhosa, South Africa
+ { "zu-ZA", "*", spBuiltinFormats_en_ZA }, // Zulu, South Africa
+
+ { "*CJK", "*", spBuiltinFormats_CJK }, // CJK base table
+ { "ja-JP", "*CJK", spBuiltinFormats_ja_JP }, // Japanese, Japan
+ { "ko-KR", "*CJK", spBuiltinFormats_ko_KR }, // Korean, South Korea
+ { "zh-CN", "*CJK", spBuiltinFormats_zh_CN }, // Chinese, China
+ { "zh-HK", "*CJK", spBuiltinFormats_zh_HK }, // Chinese, Hong Kong
+ { "zh-MO", "*CJK", spBuiltinFormats_zh_MO }, // Chinese, Macau
+ { "zh-SG", "*CJK", spBuiltinFormats_zh_SG }, // Chinese, Singapore
+ { "zh-TW", "*CJK", spBuiltinFormats_zh_TW } // Chinese, Taiwan
+};
+
+// ============================================================================
+
+/** Functor for converting an XML number format to an API number format index. */
+class NumberFormatFunctor
+{
+public:
+ explicit NumberFormatFunctor( const WorkbookHelper& rHelper );
+
+ inline bool is() const { return mxNumFmts.is(); }
+
+ inline void operator()( NumberFormat& rNumFmt ) const
+ { rNumFmt.finalizeImport( mxNumFmts, maEnUsLocale ); }
+
+private:
+ Reference< XNumberFormats > mxNumFmts;
+ Locale maEnUsLocale;
+};
+
+// ----------------------------------------------------------------------------
+
+NumberFormatFunctor::NumberFormatFunctor( const WorkbookHelper& rHelper ) :
+ maEnUsLocale( CREATE_OUSTRING( "en" ), CREATE_OUSTRING( "US" ), OUString() )
+{
+ try
+ {
+ Reference< XNumberFormatsSupplier > xNumFmtsSupp( rHelper.getDocument(), UNO_QUERY_THROW );
+ mxNumFmts = xNumFmtsSupp->getNumberFormats();
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( mxNumFmts.is(), "NumberFormatFunctor::NumberFormatFunctor - cannot get number formats" );
+}
+
+} // namespace
+
+// ============================================================================
+
+OoxNumFmtData::OoxNumFmtData() :
+ mnPredefId( -1 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+sal_Int32 lclCreatePredefinedFormat( const Reference< XNumberFormats >& rxNumFmts,
+ sal_Int16 nPredefId, const Locale& rToLocale )
+{
+ sal_Int32 nIndex = 0;
+ try
+ {
+ Reference< XNumberFormatTypes > xNumFmtTypes( rxNumFmts, UNO_QUERY_THROW );
+ nIndex = (nPredefId >= 0) ?
+ xNumFmtTypes->getFormatIndex( nPredefId, rToLocale ) :
+ xNumFmtTypes->getStandardIndex( rToLocale );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false,
+ OStringBuffer( "lclCreatePredefinedFormat - cannot create predefined number format " ).
+ append( OString::valueOf( static_cast< sal_Int32 >( nPredefId ) ) ).getStr() );
+ }
+ return nIndex;
+}
+
+sal_Int32 lclCreateFormat( const Reference< XNumberFormats >& rxNumFmts,
+ const OUString& rFmtCode, const Locale& rToLocale, const Locale& rFromLocale )
+{
+ sal_Int32 nIndex = 0;
+ try
+ {
+ nIndex = rxNumFmts->addNewConverted( rFmtCode, rFromLocale, rToLocale );
+ }
+ catch( Exception& )
+ {
+ // BIFF2-BIFF4 stores standard format explicitly in stream
+ static const OUString saGeneral = CREATE_OUSTRING( "general" );
+ if( rFmtCode.equalsIgnoreAsciiCase( saGeneral ) )
+ {
+ nIndex = lclCreatePredefinedFormat( rxNumFmts, 0, rToLocale );
+ }
+ else
+ {
+ OSL_ENSURE( false,
+ OStringBuffer( "lclCreateFormat - cannot create number format '" ).
+ append( OUStringToOString( rFmtCode, osl_getThreadTextEncoding() ) ).
+ append( '\'' ).getStr() );
+ }
+ }
+ return nIndex;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+NumberFormat::NumberFormat( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void NumberFormat::setFormatCode( const OUString& rFmtCode )
+{
+ maOoxData.maFmtCode = rFmtCode;
+}
+
+void NumberFormat::setFormatCode( const Locale& rLocale, const sal_Char* pcFmtCode )
+{
+ maOoxData.maLocale = rLocale;
+ maOoxData.maFmtCode = OStringToOUString( OString( pcFmtCode ), RTL_TEXTENCODING_UTF8 );
+ maOoxData.mnPredefId = -1;
+}
+
+void NumberFormat::setPredefinedId( const Locale& rLocale, sal_Int16 nPredefId )
+{
+ maOoxData.maLocale = rLocale;
+ maOoxData.maFmtCode = OUString();
+ maOoxData.mnPredefId = nPredefId;
+}
+
+void NumberFormat::finalizeImport( const Reference< XNumberFormats >& rxNumFmts, const Locale& rFromLocale )
+{
+ if( rxNumFmts.is() && (maOoxData.maFmtCode.getLength() > 0) )
+ maApiData.mnIndex = lclCreateFormat( rxNumFmts, maOoxData.maFmtCode, maOoxData.maLocale, rFromLocale );
+ else
+ maApiData.mnIndex = lclCreatePredefinedFormat( rxNumFmts, maOoxData.mnPredefId, maOoxData.maLocale );
+}
+
+void NumberFormat::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ getStylesPropertyHelper().writeNumFmtProperties( rPropSet, maApiData );
+}
+
+// ============================================================================
+
+NumberFormatsBuffer::NumberFormatsBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnNextBiffIndex( 0 )
+{
+ // get the current locale
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XMultiServiceFactory > xConfigProv(
+ xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationProvider" ) ),
+ UNO_QUERY_THROW );
+
+ // try user-defined locale setting
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= CREATE_OUSTRING( "org.openoffice.Setup/L10N/" );
+ Reference< XNameAccess > xConfigNA( xConfigProv->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationAccess" ), aArgs ), UNO_QUERY_THROW );
+ xConfigNA->getByName( CREATE_OUSTRING( "ooSetupSystemLocale" ) ) >>= maLocaleStr;
+
+ // if set to "use system", get locale from system
+ if( maLocaleStr.getLength() == 0 )
+ {
+ aArgs[ 0 ] <<= CREATE_OUSTRING( "org.openoffice.System/L10N/" );
+ xConfigNA.set( xConfigProv->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationAccess" ), aArgs ), UNO_QUERY_THROW );
+ xConfigNA->getByName( CREATE_OUSTRING( "Locale" ) ) >>= maLocaleStr;
+ }
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "NumberFormatsBuffer::NumberFormatsBuffer - cannot get system locale" );
+ }
+
+ // create built-in formats for current locale
+ insertBuiltinFormats();
+}
+
+NumberFormatRef NumberFormatsBuffer::createNumFmt( sal_Int32 nNumFmtId, const OUString& rFmtCode )
+{
+ NumberFormatRef xNumFmt;
+ if( nNumFmtId >= 0 )
+ {
+ xNumFmt.reset( new NumberFormat( *this ) );
+ maNumFmts[ nNumFmtId ] = xNumFmt;
+ xNumFmt->setFormatCode( rFmtCode );
+ }
+ return xNumFmt;
+}
+
+NumberFormatRef NumberFormatsBuffer::importNumFmt( const AttributeList& rAttribs )
+{
+ sal_Int32 nNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 );
+ OUString aFmtCode = rAttribs.getString( XML_formatCode );
+ return createNumFmt( nNumFmtId, aFmtCode );
+}
+
+void NumberFormatsBuffer::importNumFmt( RecordInputStream& rStrm )
+{
+ sal_Int32 nNumFmtId = rStrm.readuInt16();
+ OUString aFmtCode = rStrm.readString();
+ createNumFmt( nNumFmtId, aFmtCode );
+}
+
+void NumberFormatsBuffer::importFormat( BiffInputStream& rStrm )
+{
+ OUString aFmtCode;
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ aFmtCode = rStrm.readByteString( false, getTextEncoding() );
+ break;
+ case BIFF4:
+ // in BIFF4 the index field exists, but is undefined
+ aFmtCode = rStrm.skip( 2 ).readByteString( false, getTextEncoding() );
+ break;
+ case BIFF5:
+ mnNextBiffIndex = rStrm.readuInt16();
+ aFmtCode = rStrm.readByteString( false, getTextEncoding() );
+ break;
+ case BIFF8:
+ mnNextBiffIndex = rStrm.readuInt16();
+ aFmtCode = rStrm.readUniString();
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+
+ createNumFmt( mnNextBiffIndex, aFmtCode );
+ ++mnNextBiffIndex;
+}
+
+void NumberFormatsBuffer::finalizeImport()
+{
+ maNumFmts.forEach( NumberFormatFunctor( *this ) );
+}
+
+void NumberFormatsBuffer::writeToPropertySet( PropertySet& rPropSet, sal_Int32 nNumFmtId ) const
+{
+ if( const NumberFormat* pNumFmt = maNumFmts.get( nNumFmtId ).get() )
+ pNumFmt->writeToPropertySet( rPropSet );
+}
+
+void NumberFormatsBuffer::insertBuiltinFormats()
+{
+ // build a map containing pointers to all tables
+ typedef ::std::map< OUString, const BuiltinFormatTable* > BuiltinMap;
+ BuiltinMap aBuiltinMap;
+ for( const BuiltinFormatTable* pTable = spBuiltinFormatTables;
+ pTable != STATIC_ARRAY_END( spBuiltinFormatTables ); ++pTable )
+ aBuiltinMap[ OUString::createFromAscii( pTable->mpcLocale ) ] = pTable;
+
+ // convert locale string to locale struct
+ Locale aSysLocale;
+ sal_Int32 nDashPos = maLocaleStr.indexOf( '-' );
+ if( nDashPos < 0 ) nDashPos = maLocaleStr.getLength();
+ aSysLocale.Language = maLocaleStr.copy( 0, nDashPos );
+ if( nDashPos + 1 < maLocaleStr.getLength() )
+ aSysLocale.Country = maLocaleStr.copy( nDashPos + 1 );
+
+ // build a list of table pointers for the current locale, with all parent tables
+ typedef ::std::vector< const BuiltinFormatTable* > BuiltinVec;
+ BuiltinVec aBuiltinVec;
+ BuiltinMap::const_iterator aMIt = aBuiltinMap.find( maLocaleStr ), aMEnd = aBuiltinMap.end();
+ OSL_ENSURE( aMIt != aMEnd,
+ OStringBuffer( "NumberFormatsBuffer::insertBuiltinFormats - locale '" ).
+ append( OUStringToOString( maLocaleStr, RTL_TEXTENCODING_ASCII_US ) ).
+ append( "' not supported (#i29949#)" ).getStr() );
+ // start with default table, if no table has been found
+ if( aMIt == aMEnd )
+ aMIt = aBuiltinMap.find( CREATE_OUSTRING( "*" ) );
+ OSL_ENSURE( aMIt != aMEnd, "NumberFormatsBuffer::insertBuiltinFormats - default map not found" );
+ // insert all tables into the vector
+ for( ; aMIt != aMEnd; aMIt = aBuiltinMap.find( OUString::createFromAscii( aMIt->second->mpcParent ) ) )
+ aBuiltinVec.push_back( aMIt->second );
+
+ // insert the default formats in the format map (in reverse order from default table to system locale)
+ typedef ::std::map< sal_Int32, sal_Int32 > ReuseMap;
+ ReuseMap aReuseMap;
+ for( BuiltinVec::reverse_iterator aVIt = aBuiltinVec.rbegin(), aVEnd = aBuiltinVec.rend(); aVIt != aVEnd; ++aVIt )
+ {
+ // do not put the current system locale for default table
+ Locale aLocale;
+ if( (*aVIt)->mpcLocale[ 0 ] != '\0' )
+ aLocale = aSysLocale;
+ for( const BuiltinFormat* pBuiltin = (*aVIt)->mpFormats; pBuiltin && (pBuiltin->mnNumFmtId >= 0); ++pBuiltin )
+ {
+ NumberFormatRef& rxNumFmt = maNumFmts[ pBuiltin->mnNumFmtId ];
+ rxNumFmt.reset( new NumberFormat( *this ) );
+
+ bool bReuse = false;
+ if( pBuiltin->mpcFmtCode )
+ rxNumFmt->setFormatCode( aLocale, pBuiltin->mpcFmtCode );
+ else if( pBuiltin->mnPredefId >= 0 )
+ rxNumFmt->setPredefinedId( aLocale, pBuiltin->mnPredefId );
+ else
+ bReuse = pBuiltin->mnReuseId >= 0;
+
+ if( bReuse )
+ aReuseMap[ pBuiltin->mnNumFmtId ] = pBuiltin->mnReuseId;
+ else
+ aReuseMap.erase( pBuiltin->mnNumFmtId );
+ }
+ }
+
+ // copy reused number formats
+ for( ReuseMap::const_iterator aRIt = aReuseMap.begin(), aREnd = aReuseMap.end(); aRIt != aREnd; ++aRIt )
+ maNumFmts[ aRIt->first ] = maNumFmts[ aRIt->second ];
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/pagesettings.cxx b/oox/source/xls/pagesettings.cxx
new file mode 100644
index 000000000000..6cb32f961352
--- /dev/null
+++ b/oox/source/xls/pagesettings.cxx
@@ -0,0 +1,641 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pagesettings.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/pagesettings.hxx"
+#include <algorithm>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/ooxtokens.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::container::XNamed;
+using ::com::sun::star::sheet::XHeaderFooterContent;
+using ::com::sun::star::style::XStyle;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const double OOX_MARGIN_DEFAULT_LR = 0.748; /// Left/right default margin in inches.
+const double OOX_MARGIN_DEFAULT_TB = 0.984; /// Top/bottom default margin in inches.
+const double OOX_MARGIN_DEFAULT_HF = 0.512; /// Header/footer default margin in inches.
+
+const sal_uInt16 OOBIN_HEADERFOOTER_DIFFEVEN = 0x0001;
+const sal_uInt16 OOBIN_HEADERFOOTER_DIFFFIRST = 0x0002;
+const sal_uInt16 OOBIN_HEADERFOOTER_SCALEDOC = 0x0004;
+const sal_uInt16 OOBIN_HEADERFOOTER_ALIGNMARGIN = 0x0008;
+
+const sal_uInt16 OOBIN_PAGESETUP_INROWS = 0x0001;
+const sal_uInt16 OOBIN_PAGESETUP_LANDSCAPE = 0x0002;
+const sal_uInt16 OOBIN_PAGESETUP_INVALID = 0x0004;
+const sal_uInt16 OOBIN_PAGESETUP_BLACKWHITE = 0x0008;
+const sal_uInt16 OOBIN_PAGESETUP_DRAFTQUALITY = 0x0010;
+const sal_uInt16 OOBIN_PAGESETUP_PRINTNOTES = 0x0020;
+const sal_uInt16 OOBIN_PAGESETUP_DEFAULTORIENT = 0x0040;
+const sal_uInt16 OOBIN_PAGESETUP_USEFIRSTPAGE = 0x0080;
+const sal_uInt16 OOBIN_PAGESETUP_NOTES_END = 0x0100; // different to BIFF flag
+
+const sal_uInt16 OOBIN_PRINTOPT_HORCENTER = 0x0001;
+const sal_uInt16 OOBIN_PRINTOPT_VERCENTER = 0x0002;
+const sal_uInt16 OOBIN_PRINTOPT_PRINTHEADING = 0x0004;
+const sal_uInt16 OOBIN_PRINTOPT_PRINTGRID = 0x0008;
+
+const sal_uInt16 BIFF_PAGESETUP_INROWS = 0x0001;
+const sal_uInt16 BIFF_PAGESETUP_PORTRAIT = 0x0002;
+const sal_uInt16 BIFF_PAGESETUP_INVALID = 0x0004;
+const sal_uInt16 BIFF_PAGESETUP_BLACKWHITE = 0x0008;
+const sal_uInt16 BIFF_PAGESETUP_DRAFTQUALITY = 0x0010;
+const sal_uInt16 BIFF_PAGESETUP_PRINTNOTES = 0x0020;
+const sal_uInt16 BIFF_PAGESETUP_DEFAULTORIENT = 0x0040;
+const sal_uInt16 BIFF_PAGESETUP_USEFIRSTPAGE = 0x0080;
+const sal_uInt16 BIFF_PAGESETUP_NOTES_END = 0x0200;
+
+} // namespace
+
+// ============================================================================
+
+OoxPageData::OoxPageData() :
+ mfLeftMargin( OOX_MARGIN_DEFAULT_LR ),
+ mfRightMargin( OOX_MARGIN_DEFAULT_LR ),
+ mfTopMargin( OOX_MARGIN_DEFAULT_TB ),
+ mfBottomMargin( OOX_MARGIN_DEFAULT_TB ),
+ mfHeaderMargin( OOX_MARGIN_DEFAULT_HF ),
+ mfFooterMargin( OOX_MARGIN_DEFAULT_HF ),
+ mnPaperSize( 1 ),
+ mnCopies( 1 ),
+ mnScale( 100 ),
+ mnFirstPage( 1 ),
+ mnFitToWidth( 1 ),
+ mnFitToHeight( 1 ),
+ mnHorPrintRes( 600 ),
+ mnVerPrintRes( 600 ),
+ mnOrientation( XML_default ),
+ mnPageOrder( XML_downThenOver ),
+ mnCellComments( XML_none ),
+ mnPrintErrors( XML_displayed ),
+ mbUseEvenHF( false ),
+ mbUseFirstHF( false ),
+ mbValidSettings( true ),
+ mbUseFirstPage( false ),
+ mbBlackWhite( false ),
+ mbDraftQuality( false ),
+ mbFitToPages( false ),
+ mbHorCenter( false ),
+ mbVerCenter( false ),
+ mbPrintGrid( false ),
+ mbPrintHeadings( false )
+{
+}
+
+void OoxPageData::setBinPrintErrors( sal_uInt8 nPrintErrors )
+{
+ static const sal_Int32 spnErrorIds[] = { XML_displayed, XML_none, XML_dash, XML_NA };
+ mnPrintErrors = STATIC_ARRAY_SELECT( spnErrorIds, nPrintErrors, XML_none );
+}
+
+// ============================================================================
+
+PageSettings::PageSettings( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void PageSettings::importPageMargins( const AttributeList& rAttribs )
+{
+ maOoxData.mfLeftMargin = rAttribs.getDouble( XML_left, OOX_MARGIN_DEFAULT_LR );
+ maOoxData.mfRightMargin = rAttribs.getDouble( XML_right, OOX_MARGIN_DEFAULT_LR );
+ maOoxData.mfTopMargin = rAttribs.getDouble( XML_top, OOX_MARGIN_DEFAULT_TB );
+ maOoxData.mfBottomMargin = rAttribs.getDouble( XML_bottom, OOX_MARGIN_DEFAULT_TB );
+ maOoxData.mfHeaderMargin = rAttribs.getDouble( XML_header, OOX_MARGIN_DEFAULT_HF );
+ maOoxData.mfFooterMargin = rAttribs.getDouble( XML_footer, OOX_MARGIN_DEFAULT_HF );
+}
+
+void PageSettings::importPageSetup( const AttributeList& rAttribs )
+{
+ maOoxData.maRelId = rAttribs.getString( R_TOKEN( id ) );
+ maOoxData.mnPaperSize = rAttribs.getInteger( XML_paperSize, 1 );
+ maOoxData.mnCopies = rAttribs.getInteger( XML_copies, 1 );
+ maOoxData.mnScale = rAttribs.getInteger( XML_scale, 100 );
+ maOoxData.mnFirstPage = rAttribs.getInteger( XML_firstPageNumber, 1 );
+ maOoxData.mnFitToWidth = rAttribs.getInteger( XML_fitToWidth, 1 );
+ maOoxData.mnFitToHeight = rAttribs.getInteger( XML_fitToHeight, 1 );
+ maOoxData.mnHorPrintRes = rAttribs.getInteger( XML_horizontalDpi, 600 );
+ maOoxData.mnVerPrintRes = rAttribs.getInteger( XML_verticalDpi, 600 );
+ maOoxData.mnOrientation = rAttribs.getToken( XML_orientation, XML_default );
+ maOoxData.mnPageOrder = rAttribs.getToken( XML_pageOrder, XML_downThenOver );
+ maOoxData.mnCellComments = rAttribs.getToken( XML_cellComments, XML_none );
+ maOoxData.mnPrintErrors = rAttribs.getToken( XML_errors, XML_displayed );
+ maOoxData.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true );
+ maOoxData.mbUseFirstPage = rAttribs.getBool( XML_useFirstPageNumber, false );
+ maOoxData.mbBlackWhite = rAttribs.getBool( XML_blackAndWhite, false );
+ maOoxData.mbDraftQuality = rAttribs.getBool( XML_draft, false );
+}
+
+void PageSettings::importPrintOptions( const AttributeList& rAttribs )
+{
+ maOoxData.mbHorCenter = rAttribs.getBool( XML_horizontalCentered, false );
+ maOoxData.mbVerCenter = rAttribs.getBool( XML_verticalCentered, false );
+ maOoxData.mbPrintGrid = rAttribs.getBool( XML_gridLines, false );
+ maOoxData.mbPrintHeadings = rAttribs.getBool( XML_headings, false );
+}
+
+void PageSettings::importHeaderFooter( const AttributeList& rAttribs )
+{
+ maOoxData.mbUseEvenHF = rAttribs.getBool( XML_differentOddEven, false );
+ maOoxData.mbUseFirstHF = rAttribs.getBool( XML_differentFirst, false );
+}
+
+void PageSettings::importHeaderFooterCharacters( const OUString& rChars, sal_Int32 nElement )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( oddHeader ): maOoxData.maOddHeader += rChars; break;
+ case XLS_TOKEN( oddFooter ): maOoxData.maOddFooter += rChars; break;
+ case XLS_TOKEN( evenHeader ): maOoxData.maEvenHeader += rChars; break;
+ case XLS_TOKEN( evenFooter ): maOoxData.maEvenFooter += rChars; break;
+ case XLS_TOKEN( firstHeader ): maOoxData.maFirstHeader += rChars; break;
+ case XLS_TOKEN( firstFooter ): maOoxData.maFirstFooter += rChars; break;
+ }
+}
+
+void PageSettings::importPageMargins( RecordInputStream& rStrm )
+{
+ rStrm >> maOoxData.mfLeftMargin >> maOoxData.mfRightMargin
+ >> maOoxData.mfTopMargin >> maOoxData.mfBottomMargin
+ >> maOoxData.mfHeaderMargin >> maOoxData.mfFooterMargin;
+}
+
+void PageSettings::importPageSetup( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> maOoxData.mnPaperSize >> maOoxData.mnScale
+ >> maOoxData.mnHorPrintRes >> maOoxData.mnVerPrintRes
+ >> maOoxData.mnCopies >> maOoxData.mnFirstPage
+ >> maOoxData.mnFitToWidth >> maOoxData.mnFitToHeight
+ >> nFlags >> maOoxData.maRelId;
+ maOoxData.setBinPrintErrors( extractValue< sal_uInt8 >( nFlags, 9, 2 ) );
+ maOoxData.mnOrientation = getFlagValue( nFlags, OOBIN_PAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, OOBIN_PAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
+ maOoxData.mnPageOrder = getFlagValue( nFlags, OOBIN_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
+ maOoxData.mnCellComments = getFlagValue( nFlags, OOBIN_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, OOBIN_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
+ maOoxData.mbValidSettings = !getFlag( nFlags, OOBIN_PAGESETUP_INVALID );
+ maOoxData.mbUseFirstPage = getFlag( nFlags, OOBIN_PAGESETUP_USEFIRSTPAGE );
+ maOoxData.mbBlackWhite = getFlag( nFlags, OOBIN_PAGESETUP_BLACKWHITE );
+ maOoxData.mbDraftQuality = getFlag( nFlags, OOBIN_PAGESETUP_DRAFTQUALITY );
+}
+
+void PageSettings::importPrintOptions( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ maOoxData.mbHorCenter = getFlag( nFlags, OOBIN_PRINTOPT_HORCENTER );
+ maOoxData.mbVerCenter = getFlag( nFlags, OOBIN_PRINTOPT_VERCENTER );
+ maOoxData.mbPrintGrid = getFlag( nFlags, OOBIN_PRINTOPT_PRINTGRID );
+ maOoxData.mbPrintHeadings = getFlag( nFlags, OOBIN_PRINTOPT_PRINTHEADING );
+}
+
+void PageSettings::importHeaderFooter( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags
+ >> maOoxData.maOddHeader >> maOoxData.maOddFooter
+ >> maOoxData.maEvenHeader >> maOoxData.maEvenFooter
+ >> maOoxData.maFirstHeader >> maOoxData.maFirstFooter;
+ maOoxData.mbUseEvenHF = getFlag( nFlags, OOBIN_HEADERFOOTER_DIFFEVEN );
+ maOoxData.mbUseFirstHF = getFlag( nFlags, OOBIN_HEADERFOOTER_DIFFFIRST );
+}
+
+void PageSettings::importLeftMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maOoxData.mfLeftMargin;
+}
+
+void PageSettings::importRightMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maOoxData.mfRightMargin;
+}
+
+void PageSettings::importTopMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maOoxData.mfTopMargin;
+}
+
+void PageSettings::importBottomMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maOoxData.mfBottomMargin;
+}
+
+void PageSettings::importPageSetup( BiffInputStream& rStrm )
+{
+ sal_uInt16 nPaperSize, nScale, nFirstPage, nFitToWidth, nFitToHeight, nFlags;
+ rStrm >> nPaperSize >> nScale >> nFirstPage >> nFitToWidth >> nFitToHeight >> nFlags;
+
+ maOoxData.mnPaperSize = nPaperSize; // equal in BIFF and OOX
+ maOoxData.mnScale = nScale;
+ maOoxData.mnFirstPage = nFirstPage;
+ maOoxData.mnFitToWidth = nFitToWidth;
+ maOoxData.mnFitToHeight = nFitToHeight;
+ maOoxData.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_PORTRAIT, XML_portrait, XML_landscape );
+ maOoxData.mnPageOrder = getFlagValue( nFlags, BIFF_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
+ maOoxData.mbValidSettings = !getFlag( nFlags, BIFF_PAGESETUP_INVALID );
+ maOoxData.mbUseFirstPage = true;
+ maOoxData.mbBlackWhite = getFlag( nFlags, BIFF_PAGESETUP_BLACKWHITE );
+
+ if( getBiff() >= BIFF5 )
+ {
+ sal_uInt16 nHorPrintRes, nVerPrintRes, nCopies;
+ rStrm >> nHorPrintRes >> nVerPrintRes >> maOoxData.mfHeaderMargin >> maOoxData.mfFooterMargin >> nCopies;
+
+ maOoxData.mnCopies = nCopies;
+ maOoxData.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_DEFAULTORIENT, XML_default, maOoxData.mnOrientation );
+ maOoxData.mnHorPrintRes = nHorPrintRes;
+ maOoxData.mnVerPrintRes = nVerPrintRes;
+ maOoxData.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, XML_asDisplayed, XML_none );
+ maOoxData.mbUseFirstPage = getFlag( nFlags, BIFF_PAGESETUP_USEFIRSTPAGE );
+ maOoxData.mbDraftQuality = getFlag( nFlags, BIFF_PAGESETUP_DRAFTQUALITY );
+
+ if( getBiff() == BIFF8 )
+ {
+ maOoxData.setBinPrintErrors( extractValue< sal_uInt8 >( nFlags, 10, 2 ) );
+ maOoxData.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
+ }
+ }
+}
+
+void PageSettings::importHorCenter( BiffInputStream& rStrm )
+{
+ maOoxData.mbHorCenter = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importVerCenter( BiffInputStream& rStrm )
+{
+ maOoxData.mbVerCenter = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importPrintHeaders( BiffInputStream& rStrm )
+{
+ maOoxData.mbPrintHeadings = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importPrintGridLines( BiffInputStream& rStrm )
+{
+ maOoxData.mbPrintGrid = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importHeader( BiffInputStream& rStrm )
+{
+ if( rStrm.getRecLeft() > 0 )
+ maOoxData.maOddHeader = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteString( false, getTextEncoding() );
+ else
+ maOoxData.maOddHeader = OUString();
+}
+
+void PageSettings::importFooter( BiffInputStream& rStrm )
+{
+ if( rStrm.getRecLeft() > 0 )
+ maOoxData.maOddFooter = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteString( false, getTextEncoding() );
+ else
+ maOoxData.maOddFooter = OUString();
+}
+
+void PageSettings::setFitToPagesMode( bool bFitToPages )
+{
+ maOoxData.mbFitToPages = bFitToPages;
+}
+
+void PageSettings::finalizeImport()
+{
+ OUStringBuffer aStyleNameBuffer( CREATE_OUSTRING( "PageStyle_" ) );
+ Reference< XNamed > xSheetName( getXSpreadsheet(), UNO_QUERY );
+ if( xSheetName.is() )
+ aStyleNameBuffer.append( xSheetName->getName() );
+ else
+ aStyleNameBuffer.append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) );
+ OUString aStyleName = aStyleNameBuffer.makeStringAndClear();
+
+ Reference< XStyle > xStyle = createStyleObject( aStyleName, true );
+ PropertySet aStyleProps( xStyle );
+ getPageSettingsPropertyHelper().writePageSettingsProperties( aStyleProps, maOoxData, getSheetType() );
+
+ PropertySet aSheetProps( getXSpreadsheet() );
+ aSheetProps.setProperty( CREATE_OUSTRING( "PageStyle" ), aStyleName );
+}
+
+// ============================================================================
+
+namespace {
+
+/** Property names for page style settings. */
+const sal_Char* const sppcPageNames[] =
+{
+ "IsLandscape",
+ "FirstPageNumber",
+ "PrintDownFirst",
+ "PrintAnnotations",
+ "CenterHorizontally",
+ "CenterVertically",
+ "PrintGrid",
+ "PrintHeaders",
+ "LeftMargin",
+ "RightMargin",
+ "TopMargin",
+ "BottomMargin",
+ "HeaderIsOn",
+ "HeaderIsShared",
+ "HeaderIsDynamicHeight",
+ "HeaderHeight",
+ "HeaderBodyDistance",
+ "FooterIsOn",
+ "FooterIsShared",
+ "FooterIsDynamicHeight",
+ "FooterHeight",
+ "FooterBodyDistance",
+ 0
+};
+
+/** Paper size in 1/100 millimeters. */
+struct ApiPaperSize
+{
+ sal_Int32 mnWidth;
+ sal_Int32 mnHeight;
+};
+
+#define IN2MM100( v ) static_cast< sal_Int32 >( (v) * 2540.0 + 0.5 )
+#define MM2MM100( v ) static_cast< sal_Int32 >( (v) * 100.0 + 0.5 )
+
+static const ApiPaperSize spPaperSizeTable[] =
+{
+ { 0, 0 }, // 0 - (undefined)
+ { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 1 - Letter paper
+ { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 2 - Letter small paper
+ { IN2MM100( 11 ), IN2MM100( 17 ) }, // 3 - Tabloid paper
+ { IN2MM100( 17 ), IN2MM100( 11 ) }, // 4 - Ledger paper
+ { IN2MM100( 8.5 ), IN2MM100( 14 ) }, // 5 - Legal paper
+ { IN2MM100( 5.5 ), IN2MM100( 8.5 ) }, // 6 - Statement paper
+ { IN2MM100( 7.25 ), IN2MM100( 10.5 ) }, // 7 - Executive paper
+ { MM2MM100( 297 ), MM2MM100( 420 ) }, // 8 - A3 paper
+ { MM2MM100( 210 ), MM2MM100( 297 ) }, // 9 - A4 paper
+ { MM2MM100( 210 ), MM2MM100( 297 ) }, // 10 - A4 small paper
+ { MM2MM100( 148 ), MM2MM100( 210 ) }, // 11 - A5 paper
+ { MM2MM100( 250 ), MM2MM100( 353 ) }, // 12 - B4 paper
+ { MM2MM100( 176 ), MM2MM100( 250 ) }, // 13 - B5 paper
+ { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 14 - Folio paper
+ { MM2MM100( 215 ), MM2MM100( 275 ) }, // 15 - Quarto paper
+ { IN2MM100( 10 ), IN2MM100( 14 ) }, // 16 - Standard paper
+ { IN2MM100( 11 ), IN2MM100( 17 ) }, // 17 - Standard paper
+ { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 18 - Note paper
+ { IN2MM100( 3.875 ), IN2MM100( 8.875 ) }, // 19 - #9 envelope
+ { IN2MM100( 4.125 ), IN2MM100( 9.5 ) }, // 20 - #10 envelope
+ { IN2MM100( 4.5 ), IN2MM100( 10.375 ) }, // 21 - #11 envelope
+ { IN2MM100( 4.75 ), IN2MM100( 11 ) }, // 22 - #12 envelope
+ { IN2MM100( 5 ), IN2MM100( 11.5 ) }, // 23 - #14 envelope
+ { IN2MM100( 17 ), IN2MM100( 22 ) }, // 24 - C paper
+ { IN2MM100( 22 ), IN2MM100( 34 ) }, // 25 - D paper
+ { IN2MM100( 34 ), IN2MM100( 44 ) }, // 26 - E paper
+ { MM2MM100( 110 ), MM2MM100( 220 ) }, // 27 - DL envelope
+ { MM2MM100( 162 ), MM2MM100( 229 ) }, // 28 - C5 envelope
+ { MM2MM100( 324 ), MM2MM100( 458 ) }, // 29 - C3 envelope
+ { MM2MM100( 229 ), MM2MM100( 324 ) }, // 30 - C4 envelope
+ { MM2MM100( 114 ), MM2MM100( 162 ) }, // 31 - C6 envelope
+ { MM2MM100( 114 ), MM2MM100( 229 ) }, // 32 - C65 envelope
+ { MM2MM100( 250 ), MM2MM100( 353 ) }, // 33 - B4 envelope
+ { MM2MM100( 176 ), MM2MM100( 250 ) }, // 34 - B5 envelope
+ { MM2MM100( 176 ), MM2MM100( 125 ) }, // 35 - B6 envelope
+ { MM2MM100( 110 ), MM2MM100( 230 ) }, // 36 - Italy envelope
+ { IN2MM100( 3.875 ), IN2MM100( 7.5 ) }, // 37 - Monarch envelope
+ { IN2MM100( 3.625 ), IN2MM100( 6.5 ) }, // 38 - 6 3/4 envelope
+ { IN2MM100( 14.875 ), IN2MM100( 11 ) }, // 39 - US standard fanfold
+ { IN2MM100( 8.5 ), IN2MM100( 12 ) }, // 40 - German standard fanfold
+ { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 41 - German legal fanfold
+ { MM2MM100( 250 ), MM2MM100( 353 ) }, // 42 - ISO B4
+ { MM2MM100( 200 ), MM2MM100( 148 ) }, // 43 - Japanese double postcard
+ { IN2MM100( 9 ), IN2MM100( 11 ) }, // 44 - Standard paper
+ { IN2MM100( 10 ), IN2MM100( 11 ) }, // 45 - Standard paper
+ { IN2MM100( 15 ), IN2MM100( 11 ) }, // 46 - Standard paper
+ { MM2MM100( 220 ), MM2MM100( 220 ) }, // 47 - Invite envelope
+ { 0, 0 }, // 48 - (undefined)
+ { 0, 0 }, // 49 - (undefined)
+ { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 50 - Letter extra paper
+ { IN2MM100( 9.275 ), IN2MM100( 15 ) }, // 51 - Legal extra paper
+ { IN2MM100( 11.69 ), IN2MM100( 18 ) }, // 52 - Tabloid extra paper
+ { MM2MM100( 236 ), MM2MM100( 322 ) }, // 53 - A4 extra paper
+ { IN2MM100( 8.275 ), IN2MM100( 11 ) }, // 54 - Letter transverse paper
+ { MM2MM100( 210 ), MM2MM100( 297 ) }, // 55 - A4 transverse paper
+ { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 56 - Letter extra transverse paper
+ { MM2MM100( 227 ), MM2MM100( 356 ) }, // 57 - SuperA/SuperA/A4 paper
+ { MM2MM100( 305 ), MM2MM100( 487 ) }, // 58 - SuperB/SuperB/A3 paper
+ { IN2MM100( 8.5 ), IN2MM100( 12.69 ) }, // 59 - Letter plus paper
+ { MM2MM100( 210 ), MM2MM100( 330 ) }, // 60 - A4 plus paper
+ { MM2MM100( 148 ), MM2MM100( 210 ) }, // 61 - A5 transverse paper
+ { MM2MM100( 182 ), MM2MM100( 257 ) }, // 62 - JIS B5 transverse paper
+ { MM2MM100( 322 ), MM2MM100( 445 ) }, // 63 - A3 extra paper
+ { MM2MM100( 174 ), MM2MM100( 235 ) }, // 64 - A5 extra paper
+ { MM2MM100( 201 ), MM2MM100( 276 ) }, // 65 - ISO B5 extra paper
+ { MM2MM100( 420 ), MM2MM100( 594 ) }, // 66 - A2 paper
+ { MM2MM100( 297 ), MM2MM100( 420 ) }, // 67 - A3 transverse paper
+ { MM2MM100( 322 ), MM2MM100( 445 ) } // 68 - A3 extra transverse paper
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+PageSettingsPropertyHelper::HFHelperData::HFHelperData( const OUString& rLeftProp, const OUString& rRightProp ) :
+ maLeftProp( rLeftProp ),
+ maRightProp( rRightProp ),
+ mnHeight( 0 ),
+ mnBodyDist( 0 ),
+ mbHasContent( false ),
+ mbShareOddEven( false ),
+ mbDynamicHeight( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PageSettingsPropertyHelper::PageSettingsPropertyHelper( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maHFParser( rHelper ),
+ maPageProps( sppcPageNames ),
+ maHeaderData( CREATE_OUSTRING( "LeftPageHeaderContent" ), CREATE_OUSTRING( "RightPageHeaderContent" ) ),
+ maFooterData( CREATE_OUSTRING( "LeftPageFooterContent" ), CREATE_OUSTRING( "RightPageFooterContent" ) )
+{
+}
+
+void PageSettingsPropertyHelper::writePageSettingsProperties(
+ PropertySet& rPropSet, const OoxPageData& rData, WorksheetType eSheetType )
+{
+ // printout scaling
+ if( rData.mbFitToPages )
+ {
+ // fit to number of pages
+ rPropSet.setProperty( CREATE_OUSTRING( "ScaleToPagesX" ), getLimitedValue< sal_Int16, sal_Int32 >( rData.mnFitToWidth, 0, 1000 ) );
+ rPropSet.setProperty( CREATE_OUSTRING( "ScaleToPagesY" ), getLimitedValue< sal_Int16, sal_Int32 >( rData.mnFitToHeight, 0, 1000 ) );
+ }
+ else
+ {
+ // scale may be 0 which indicates uninitialized
+ sal_Int16 nScale = (rData.mbValidSettings && (rData.mnScale > 0)) ? getLimitedValue< sal_Int16, sal_Int32 >( rData.mnScale, 10, 400 ) : 100;
+ rPropSet.setProperty( CREATE_OUSTRING( "PageScale" ), nScale );
+ }
+
+ // paper orientation
+ bool bLandscape = rData.mnOrientation == XML_landscape;
+ // default orientation for current sheet type (chart sheets default to landscape)
+ if( !rData.mbValidSettings || (rData.mnOrientation == XML_default) ) switch( eSheetType )
+ {
+ case SHEETTYPE_WORKSHEET: bLandscape = false; break;
+ case SHEETTYPE_CHART: bLandscape = true; break;
+ case SHEETTYPE_MACRO: bLandscape = false; break;
+ }
+
+ // paper size
+ if( rData.mbValidSettings && (0 < rData.mnPaperSize) && (rData.mnPaperSize < static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( spPaperSizeTable ) )) )
+ {
+ const ApiPaperSize& rPaperSize = spPaperSizeTable[ rData.mnPaperSize ];
+ ::com::sun::star::awt::Size aSize( rPaperSize.mnWidth, rPaperSize.mnHeight );
+ if( bLandscape )
+ ::std::swap( aSize.Width, aSize.Height );
+ rPropSet.setProperty( CREATE_OUSTRING( "Size" ), aSize );
+ }
+
+ // header/footer
+ convertHeaderFooterData( rPropSet, maHeaderData, rData.maOddHeader, rData.maEvenHeader, rData.mbUseEvenHF, rData.mfTopMargin, rData.mfHeaderMargin );
+ convertHeaderFooterData( rPropSet, maFooterData, rData.maOddFooter, rData.maEvenFooter, rData.mbUseEvenHF, rData.mfBottomMargin, rData.mfFooterMargin );
+
+ // write all properties to property set
+ const UnitConverter& rUnitConv = getUnitConverter();
+ maPageProps
+ << bLandscape
+ << getLimitedValue< sal_Int16, sal_Int32 >( rData.mbUseFirstPage ? rData.mnFirstPage : 0, 0, 9999 )
+ << (rData.mnPageOrder == XML_downThenOver)
+ << (rData.mnCellComments == XML_asDisplayed)
+ << rData.mbHorCenter
+ << rData.mbVerCenter
+ << rData.mbPrintGrid
+ << rData.mbPrintHeadings
+ << rUnitConv.calcMm100FromInches( rData.mfLeftMargin )
+ << rUnitConv.calcMm100FromInches( rData.mfRightMargin )
+ // #i23296# In Calc, "TopMargin" property is distance to top of header if enabled
+ << rUnitConv.calcMm100FromInches( maHeaderData.mbHasContent ? rData.mfHeaderMargin : rData.mfTopMargin )
+ // #i23296# In Calc, "BottomMargin" property is distance to bottom of footer if enabled
+ << rUnitConv.calcMm100FromInches( maFooterData.mbHasContent ? rData.mfFooterMargin : rData.mfBottomMargin )
+ << maHeaderData.mbHasContent
+ << maHeaderData.mbShareOddEven
+ << maHeaderData.mbDynamicHeight
+ << maHeaderData.mnHeight
+ << maHeaderData.mnBodyDist
+ << maFooterData.mbHasContent
+ << maFooterData.mbShareOddEven
+ << maFooterData.mbDynamicHeight
+ << maFooterData.mnHeight
+ << maFooterData.mnBodyDist
+ >> rPropSet;
+}
+
+void PageSettingsPropertyHelper::convertHeaderFooterData(
+ PropertySet& rPropSet, HFHelperData& rHFData,
+ const OUString rOddContent, const OUString rEvenContent, bool bUseEvenContent,
+ double fPageMargin, double fContentMargin )
+{
+ bool bHasOddContent = rOddContent.getLength() > 0;
+ bool bHasEvenContent = bUseEvenContent && (rEvenContent.getLength() > 0);
+
+ sal_Int32 nOddHeight = bHasOddContent ? writeHeaderFooter( rPropSet, rHFData.maRightProp, rOddContent ) : 0;
+ sal_Int32 nEvenHeight = bHasEvenContent ? writeHeaderFooter( rPropSet, rHFData.maLeftProp, rEvenContent ) : 0;
+
+ rHFData.mnHeight = 750;
+ rHFData.mnBodyDist = 250;
+ rHFData.mbHasContent = bHasOddContent || bHasEvenContent;
+ rHFData.mbShareOddEven = !bUseEvenContent;
+ rHFData.mbDynamicHeight = true;
+
+ if( rHFData.mbHasContent )
+ {
+ // use maximum height of odd/even header/footer
+ rHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight );
+ /* Calc contains distance between bottom of header and top of page
+ body in "HeaderBodyDistance" property, and distance between bottom
+ of page body and top of footer in "FooterBodyDistance" property */
+ rHFData.mnBodyDist = getUnitConverter().calcMm100FromInches( fPageMargin - fContentMargin ) - rHFData.mnHeight;
+ /* #i23296# Distance less than 0 means, header or footer overlays page
+ body. As this is not possible in Calc, set fixed header or footer
+ height (crop header/footer) to get correct top position of page body. */
+ rHFData.mbDynamicHeight = rHFData.mnBodyDist >= 0;
+ /* "HeaderHeight" property is in fact distance from top of header to
+ top of page body (including "HeaderBodyDistance").
+ "FooterHeight" property is in fact distance from bottom of page
+ body to bottom of footer (including "FooterBodyDistance"). */
+ rHFData.mnHeight += rHFData.mnBodyDist;
+ // negative body distance not allowed
+ rHFData.mnBodyDist = ::std::max< sal_Int32 >( rHFData.mnBodyDist, 0 );
+ }
+}
+
+sal_Int32 PageSettingsPropertyHelper::writeHeaderFooter(
+ PropertySet& rPropSet, const OUString& rPropName, const OUString& rContent )
+{
+ OSL_ENSURE( rContent.getLength() > 0, "PageSettingsPropertyHelper::writeHeaderFooter - empty h/f string found" );
+ sal_Int32 nHeight = 0;
+ if( rContent.getLength() > 0 )
+ {
+ Reference< XHeaderFooterContent > xHFContent;
+ if( rPropSet.getProperty( xHFContent, rPropName ) && xHFContent.is() )
+ {
+ maHFParser.parse( xHFContent, rContent );
+ rPropSet.setProperty( rPropName, xHFContent );
+ nHeight = getUnitConverter().calcMm100FromPoints( maHFParser.getTotalHeight() );
+ }
+ }
+ return nHeight;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/pivotcachefragment.cxx b/oox/source/xls/pivotcachefragment.cxx
new file mode 100644
index 000000000000..adc7fe2076cb
--- /dev/null
+++ b/oox/source/xls/pivotcachefragment.cxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pivotcachefragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/pivotcachefragment.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/addressconverter.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::xml::sax::SAXException;
+
+namespace oox {
+namespace xls {
+
+OoxPivotCacheFragment::OoxPivotCacheFragment( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath,
+ sal_uInt32 nCacheId ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath ),
+ mnCacheId( nCacheId ),
+ mbValidSource( false )
+{
+}
+
+bool OoxPivotCacheFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT: return nElement == XLS_TOKEN( pivotCacheDefinition );
+ case XLS_TOKEN( pivotCacheDefinition ): return (nElement == XLS_TOKEN( cacheSource ) ||
+ nElement == XLS_TOKEN( cacheFields ));
+ case XLS_TOKEN( cacheSource ): return nElement == XLS_TOKEN( worksheetSource );
+ case XLS_TOKEN( cacheFields ): return nElement == XLS_TOKEN( cacheField );
+ case XLS_TOKEN( cacheField ): return nElement == XLS_TOKEN( sharedItems );
+ case XLS_TOKEN( sharedItems ): return nElement == XLS_TOKEN( s );
+ }
+ return false;
+}
+
+void OoxPivotCacheFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch ( getCurrentContext() )
+ {
+ case XLS_TOKEN( pivotCacheDefinition ):
+ importPivotCacheDefinition( rAttribs );
+ break;
+ case XLS_TOKEN( cacheSource ):
+ importCacheSource( rAttribs );
+ break;
+ case XLS_TOKEN( worksheetSource ):
+ if ( mbValidSource )
+ importWorksheetSource( rAttribs );
+ break;
+ case XLS_TOKEN( cacheFields ):
+ if ( mbValidSource )
+ maPCacheData.maFields.reserve( rAttribs.getUnsignedInteger(XML_count, 1) );
+ break;
+ case XLS_TOKEN( cacheField ):
+ if ( mbValidSource )
+ importCacheField( rAttribs );
+ break;
+ case XLS_TOKEN( sharedItems ):
+ if ( mbValidSource )
+ maPCacheData.maFields.back().maItems.reserve( rAttribs.getUnsignedInteger(XML_count, 1) );
+ break;
+ case XLS_TOKEN( s ):
+ if ( mbValidSource )
+ maPCacheData.maFields.back().maItems.push_back( rAttribs.getString( XML_v ) );
+ break;
+ }
+}
+
+void OoxPivotCacheFragment::finalizeImport()
+{
+ if( mbValidSource )
+ getPivotTables().setPivotCache( mnCacheId, maPCacheData );
+}
+
+void OoxPivotCacheFragment::importPivotCacheDefinition( const AttributeList& /*rAttribs*/ )
+{
+}
+
+void OoxPivotCacheFragment::importCacheSource( const AttributeList& rAttribs )
+{
+ switch ( rAttribs.getToken(XML_type) )
+ {
+ case XML_worksheet:
+ maPCacheData.meSourceType = PivotCacheData::WORKSHEET;
+ maPCacheData.mpSourceProp.reset( new PivotCacheData::WorksheetSource );
+ mbValidSource = true;
+ break;
+ case XML_external:
+ maPCacheData.meSourceType = PivotCacheData::EXTERNAL;
+ maPCacheData.mpSourceProp.reset( new PivotCacheData::ExternalSource );
+ mbValidSource = true;
+ break;
+ default:
+ // unsupported case source type.
+ break;
+ }
+}
+
+void OoxPivotCacheFragment::importWorksheetSource( const AttributeList& rAttribs )
+{
+ if ( maPCacheData.meSourceType != PivotCacheData::WORKSHEET )
+ return;
+
+ PivotCacheData::WorksheetSource* pSrc = static_cast<PivotCacheData::WorksheetSource*>(
+ maPCacheData.mpSourceProp.get() );
+
+ pSrc->maSrcRange = rAttribs.getString( XML_ref );
+ pSrc->maSheetName = rAttribs.getString( XML_sheet );
+}
+
+void OoxPivotCacheFragment::importCacheField( const AttributeList& rAttribs )
+{
+ PivotCacheField aField;
+ aField.maName = rAttribs.getString( XML_name );
+ maPCacheData.maFields.push_back(aField);
+}
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/pivottablebuffer.cxx b/oox/source/xls/pivottablebuffer.cxx
new file mode 100644
index 000000000000..08e61b8a16d5
--- /dev/null
+++ b/oox/source/xls/pivottablebuffer.cxx
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pivottablebuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/pivottablebuffer.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XElementAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/XCellRangeData.hpp>
+#include <com/sun/star/sheet/XDataPilotDescriptor.hpp>
+#include <com/sun/star/sheet/XDataPilotField.hpp>
+#include <com/sun/star/sheet/XDataPilotTables.hpp>
+#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::container::XNamed;
+using ::com::sun::star::sheet::XCellRangeData;
+using ::com::sun::star::sheet::XDataPilotDescriptor;
+using ::com::sun::star::sheet::XDataPilotField;
+using ::com::sun::star::sheet::XDataPilotTables;
+using ::com::sun::star::sheet::XDataPilotTablesSupplier;
+using ::com::sun::star::sheet::XSheetFilterDescriptor;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::table::XCellRange;
+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 ::rtl::OUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+PivotCacheData::PivotCacheData() :
+ meSourceType( WORKSHEET ),
+ mpSourceProp( static_cast<BaseSource*>(NULL) )
+{
+}
+
+PivotCacheData::WorksheetSource* PivotCacheData::getWorksheetSource() const
+{
+ if ( meSourceType != WORKSHEET )
+ return NULL;
+ return static_cast<WorksheetSource*>( mpSourceProp.get() );
+}
+
+PivotCacheData::ExternalSource* PivotCacheData::getExternalSource() const
+{
+ if ( meSourceType != EXTERNAL )
+ return NULL;
+ return static_cast<ExternalSource*>( mpSourceProp.get() );
+}
+
+// ============================================================================
+
+PivotTableField::PivotTableField() :
+ meAxis( ROW ),
+ mbDataField( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PivotTableData::PivotTableData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PivotTableBuffer::PivotTableBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+const PivotCacheData* PivotTableBuffer::getPivotCache( sal_uInt32 nCacheId ) const
+{
+ PivotCacheMapType::const_iterator itr = maPivotCacheMap.find(nCacheId),
+ itrEnd = maPivotCacheMap.end();
+
+ if ( itr != itrEnd )
+ return &itr->second;
+
+ return NULL;
+}
+
+void PivotTableBuffer::setPivotCache( sal_uInt32 nCacheId, const PivotCacheData& aData )
+{
+ maPivotCacheMap.insert( PivotCacheMapType::value_type(nCacheId, aData) );
+}
+
+PivotTableData* PivotTableBuffer::getPivotTable( const OUString& aName )
+{
+ PivotTableMapType::iterator itr = maPivotTableMap.find(aName),
+ itrEnd = maPivotTableMap.end();
+
+ if ( itr != itrEnd )
+ return &itr->second;
+
+ return NULL;
+}
+
+void PivotTableBuffer::setPivotTable( const OUString& aName, const PivotTableData& aData )
+{
+ maPivotTableMap.insert( PivotTableMapType::value_type(aName, aData) );
+ maCellRangeMap.addCellRange( aData.maRange );
+}
+
+bool PivotTableBuffer::isOverlapping( const CellAddress& aCellAddress ) const
+{
+ return maCellRangeMap.isOverlapping(aCellAddress);
+}
+
+void PivotTableBuffer::finalizeImport() const
+{
+ PivotTableMapType::const_iterator itr = maPivotTableMap.begin(), itrEnd = maPivotTableMap.end();
+ for ( ; itr != itrEnd; ++itr )
+ writePivotTable( itr->first, itr->second );
+}
+
+void PivotTableBuffer::writePivotTable( const OUString& aName, const PivotTableData& aData ) const
+{
+ using namespace ::com::sun::star::sheet;
+
+ const PivotCacheData* pCache = getPivotCache( aData.mnCacheId );
+ if ( !pCache )
+ {
+ OSL_ENSURE( false, "OoxPivotTableFragment::commit: pivot cache data not found" );
+ return;
+ }
+
+ const CellRangeAddress& aRange = aData.maRange;
+ Reference< XSpreadsheet > xSheet = getSheet( aRange.Sheet );
+ if ( !xSheet.is() )
+ return;
+
+ try
+ {
+ Reference< XDataPilotTablesSupplier > xDPTSupplier( xSheet, UNO_QUERY_THROW );
+
+ Reference< XDataPilotTables > xDPTables( xDPTSupplier->getDataPilotTables(), UNO_QUERY_THROW );
+ Reference< XDataPilotDescriptor > xDPDesc( xDPTables->createDataPilotDescriptor(), UNO_QUERY_THROW );
+ if ( pCache->meSourceType != PivotCacheData::WORKSHEET )
+ return;
+
+ PivotCacheData::WorksheetSource* pSrc = pCache->getWorksheetSource();
+ if ( !pSrc )
+ return;
+
+ OUString sheetname = pSrc->maSheetName;
+ OUString srcrange = pSrc->maSrcRange;
+
+ CellRangeAddress aSrcRange;
+ if ( !getSourceRange( pSrc->maSheetName, pSrc->maSrcRange, aSrcRange ) )
+ return;
+
+ xDPDesc->setSourceRange(aSrcRange);
+ Reference< XIndexAccess > xIA = xDPDesc->getDataPilotFields();
+
+ bool bPageAxisExists = false;
+
+ // Go through all fields in pivot table, and register them.
+ sal_Int32 nCount = ::std::min( xIA->getCount(), static_cast<sal_Int32>(aData.maFields.size()) );
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ Reference< XDataPilotField > xField( xIA->getByIndex(i), UNO_QUERY_THROW );
+ PropertySet aProp( xField );
+ Reference< XNamed > xNamed( xField, UNO_QUERY_THROW );
+
+ PivotTableField::AxisType eAxis = aData.maFields[i].meAxis;
+ if ( aData.maFields[i].mbDataField )
+ eAxis = PivotTableField::VALUES;
+
+ switch ( eAxis )
+ {
+ case PivotTableField::COLUMN:
+ aProp.setProperty( CREATE_OUSTRING("Orientation"), DataPilotFieldOrientation_COLUMN );
+ break;
+ case PivotTableField::ROW:
+ aProp.setProperty( CREATE_OUSTRING("Orientation"), DataPilotFieldOrientation_ROW );
+ break;
+ case PivotTableField::PAGE:
+ bPageAxisExists = true;
+ aProp.setProperty( CREATE_OUSTRING("Orientation"), DataPilotFieldOrientation_PAGE );
+ break;
+ case PivotTableField::VALUES:
+ aProp.setProperty( CREATE_OUSTRING("Orientation"), DataPilotFieldOrientation_DATA );
+ break;
+ default:
+ OSL_ENSURE( false, "OoxPivotTableFragment::commit: unhandled case" );
+ }
+ }
+ CellAddress aCell;
+ aCell.Sheet = aData.maRange.Sheet;
+ aCell.Column = aData.maRange.StartColumn;
+ aCell.Row = aData.maRange.StartRow;
+ if ( bPageAxisExists )
+ aCell.Row -= 2;
+
+ xDPTables->insertNewByName( aName, aCell, xDPDesc );
+ }
+ catch ( const Exception& )
+ {
+ OSL_ENSURE( false, "OoxPivotTableFragment::commit: exception thrown");
+ return;
+ }
+}
+
+bool PivotTableBuffer::getSourceRange( const OUString& aSheetName, const OUString& aRefName,
+ CellRangeAddress& rRange ) const
+{
+ sal_Int32 nCount = getWorksheets().getInternalSheetCount();
+ for ( sal_Int32 nSheet = 0; nSheet < nCount; ++nSheet )
+ {
+ Reference< XNamed > xNamed( getSheet( nSheet ), UNO_QUERY );
+ if ( xNamed.is() && !aSheetName.compareTo( xNamed->getName() ) )
+ return getAddressConverter().convertToCellRange(
+ rRange, aRefName, static_cast< sal_Int16 >( nSheet ), true );
+ }
+ return false;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/pivottablefragment.cxx b/oox/source/xls/pivottablefragment.cxx
new file mode 100644
index 000000000000..48f99cb4d41c
--- /dev/null
+++ b/oox/source/xls/pivottablefragment.cxx
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pivottablefragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/pivottablefragment.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+
+#define DEBUG_OOX_PIVOTTABLE 1
+
+#include <vector>
+#include <stdexcept>
+#if DEBUG_OOX_PIVOTTABLE
+#include <stdio.h>
+#endif
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::xml::sax::SAXException;
+
+namespace oox {
+namespace xls {
+
+OoxPivotTableFragment::OoxPivotTableFragment(
+ const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorksheetFragmentBase( rHelper, rFragmentPath ),
+ mbValidRange( false )
+{
+}
+
+bool OoxPivotTableFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT: return (nElement == XLS_TOKEN( pivotTableDefinition ));
+ case XLS_TOKEN( pivotTableDefinition ): return (nElement == XLS_TOKEN( location )) ||
+ (nElement == XLS_TOKEN( pivotFields )) ||
+ (nElement == XLS_TOKEN( rowFields )) ||
+ (nElement == XLS_TOKEN( rowItems )) ||
+ (nElement == XLS_TOKEN( colFields )) ||
+ (nElement == XLS_TOKEN( colItems )) ||
+ (nElement == XLS_TOKEN( pageFields )) ||
+ (nElement == XLS_TOKEN( dataFields )) ||
+ (nElement == XLS_TOKEN( pivotTableStyleInfo ));
+ case XLS_TOKEN( pivotFields ): return (nElement == XLS_TOKEN( pivotField ));
+ case XLS_TOKEN( pivotField ): return (nElement == XLS_TOKEN( items ));
+ case XLS_TOKEN( items ): return (nElement == XLS_TOKEN( item ));
+ case XLS_TOKEN( rowFields ): return (nElement == XLS_TOKEN( field ));
+ case XLS_TOKEN( colFields ): return (nElement == XLS_TOKEN( field ));
+ case XLS_TOKEN( pageFields ): return (nElement == XLS_TOKEN( pageField ));
+ case XLS_TOKEN( dataFields ): return (nElement == XLS_TOKEN( dataField ));
+ case XLS_TOKEN( colItems ): return (nElement == XLS_TOKEN( i ));
+ case XLS_TOKEN( rowItems ): return (nElement == XLS_TOKEN( i ));
+ }
+ return false;
+}
+
+void OoxPivotTableFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch ( getCurrentContext() )
+ {
+ case XLS_TOKEN( pivotTableDefinition ):
+ importPivotTableDefinition( rAttribs );
+ break;
+ case XLS_TOKEN( location ):
+ importLocation( rAttribs );
+ break;
+ case XLS_TOKEN( pivotFields ):
+ importPivotFields( rAttribs );
+ break;
+ case XLS_TOKEN( pivotField ):
+ importPivotField( rAttribs );
+ break;
+ }
+}
+
+void OoxPivotTableFragment::finalizeImport()
+{
+ if( mbValidRange )
+ getPivotTables().setPivotTable( maName, maData );
+}
+
+void OoxPivotTableFragment::importLocation( const AttributeList& rAttribs )
+{
+ CellRangeAddress aRange;
+ OUString aRangeName = rAttribs.getString( XML_ref );
+ mbValidRange = getAddressConverter().convertToCellRange(
+ aRange, aRangeName, getSheetIndex(), true );
+
+ if ( mbValidRange )
+ maData.maRange = aRange;
+}
+
+void OoxPivotTableFragment::importPivotTableDefinition( const AttributeList& rAttribs )
+{
+ if ( !rAttribs.hasAttribute( XML_cacheId ) )
+ return;
+
+ maName = rAttribs.getString( XML_name );
+ maData.mnCacheId = rAttribs.getInteger( XML_cacheId, 0 );
+
+ // name="PivotTable3"
+ // cacheId="0"
+ // applyNumberFormats="0"
+ // applyBorderFormats="0"
+ // applyFontFormats="0"
+ // applyPatternFormats="0"
+ // applyAlignmentFormats="0"
+ // applyWidthHeightFormats="1"
+ // dataCaption="Values"
+ // updatedVersion="3"
+ // minRefreshableVersion="3"
+ // showCalcMbrs="0"
+ // useAutoFormatting="1"
+ // itemPrintTitles="1"
+ // createdVersion="3"
+ // indent="0"
+ // outline="1"
+ // outlineData="1"
+ // multipleFieldFilters="0"
+}
+
+void OoxPivotTableFragment::importPivotFields( const AttributeList& rAttribs )
+{
+ maData.maFields.reserve( rAttribs.getUnsignedInteger( XML_count, 1 ) );
+}
+
+void OoxPivotTableFragment::importPivotField( const AttributeList& rAttribs )
+{
+ maData.maFields.push_back( PivotTableField() );
+ PivotTableField& rField = maData.maFields.back();
+ rField.mbDataField = rAttribs.getBool( XML_dataField, false );
+
+ // Possible values are: axisCol, axisRow, axisPage, axisValues
+ switch ( rAttribs.getToken( XML_axis ) )
+ {
+ case XML_axisCol:
+ rField.meAxis = PivotTableField::COLUMN;
+ break;
+ case XML_axisRow:
+ rField.meAxis = PivotTableField::ROW;
+ break;
+ case XML_axisPage:
+ rField.meAxis = PivotTableField::PAGE;
+ break;
+ case XML_axisValues:
+ rField.meAxis = PivotTableField::VALUES;
+ break;
+ default:
+ break;
+ }
+}
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/querytablefragment.cxx b/oox/source/xls/querytablefragment.cxx
new file mode 100644
index 000000000000..703ec9f9f156
--- /dev/null
+++ b/oox/source/xls/querytablefragment.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: querytablefragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/querytablefragment.hxx"
+#include "oox/xls/webquerybuffer.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::xml::sax::SAXException;
+
+namespace oox {
+namespace xls {
+
+OoxQueryTableFragment::OoxQueryTableFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+bool OoxQueryTableFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT: return (nElement == XLS_TOKEN( queryTable ));
+ }
+ return false;
+}
+
+void OoxQueryTableFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch ( getCurrentContext() )
+ {
+ case XLS_TOKEN( queryTable ):
+ importQueryTable( rAttribs );
+ break;
+ }
+}
+
+void OoxQueryTableFragment::importQueryTable( const AttributeList& rAttribs )
+{
+ getWebQueries().importQueryTable( rAttribs );
+}
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx
new file mode 100644
index 000000000000..97cc1cbe82c2
--- /dev/null
+++ b/oox/source/xls/richstring.cxx
@@ -0,0 +1,605 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: richstring.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/richstring.hxx"
+#include <com/sun/star/text/XText.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::text::XText;
+using ::com::sun::star::text::XTextRange;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt8 OOBIN_STRINGFLAG_FONTS = 0x01;
+const sal_uInt8 OOBIN_STRINGFLAG_PHONETICS = 0x02;
+
+} // namespace
+
+// ============================================================================
+
+RichStringPortion::RichStringPortion( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnFontId( -1 )
+{
+}
+
+void RichStringPortion::setText( const OUString& rText )
+{
+ maText = rText;
+}
+
+FontRef RichStringPortion::importFont( const AttributeList& )
+{
+ mxFont.reset( new Font( *this, false ) );
+ return mxFont;
+}
+
+void RichStringPortion::setFontId( sal_Int32 nFontId )
+{
+ mnFontId = nFontId;
+}
+
+void RichStringPortion::finalizeImport()
+{
+ if( mxFont.get() )
+ mxFont->finalizeImport();
+ else if( mnFontId >= 0 )
+ mxFont = getStyles().getFont( mnFontId );
+}
+
+void RichStringPortion::convert( const Reference< XText >& rxText, sal_Int32 nXfId )
+{
+ Reference< XTextRange > xRange = rxText->getEnd();
+ xRange->setString( maText );
+ if( mxFont.get() )
+ {
+ PropertySet aPropSet( xRange );
+ mxFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_RICHTEXT );
+ }
+ if( const Font* pFont = getStyles().getFontFromCellXf( nXfId ).get() )
+ {
+ if( pFont->needsRichTextFormat() )
+ {
+ PropertySet aPropSet( xRange );
+ pFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_RICHTEXT );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void BinFontPortionData::read( RecordInputStream& rStrm )
+{
+ mnPos = rStrm.readuInt16();
+ mnFontId = rStrm.readuInt16();
+}
+
+void BinFontPortionData::read( BiffInputStream& rStrm, bool b16Bit )
+{
+ if( b16Bit )
+ {
+ mnPos = rStrm.readuInt16();
+ mnFontId = rStrm.readuInt16();
+ }
+ else
+ {
+ mnPos = rStrm.readuInt8();
+ mnFontId = rStrm.readuInt8();
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void BinFontPortionList::appendPortion( const BinFontPortionData& rPortion )
+{
+ // #i33341# real life -- same character index may occur several times
+ OSL_ENSURE( empty() || (back().mnPos <= rPortion.mnPos), "BinFontPortionList::appendPortion - wrong char order" );
+ if( empty() || (back().mnPos < rPortion.mnPos) )
+ push_back( rPortion );
+ else
+ back().mnFontId = rPortion.mnFontId;
+}
+
+void BinFontPortionList::importPortions( RecordInputStream& rStrm )
+{
+ sal_Int32 nCount = rStrm.readInt32();
+ clear();
+ if( nCount > 0 )
+ {
+ reserve( getLimitedValue< size_t, sal_Int32 >( nCount, 0, rStrm.getRecLeft() / 4 ) );
+ /* #i33341# real life -- same character index may occur several times
+ -> use appendPortion() to validate string position. */
+ BinFontPortionData aPortion;
+ for( sal_Int32 nIndex = 0; rStrm.isValid() && (nIndex < nCount); ++nIndex )
+ {
+ aPortion.read( rStrm );
+ appendPortion( aPortion );
+ }
+ }
+}
+
+void BinFontPortionList::importPortions( BiffInputStream& rStrm, sal_uInt16 nCount, bool b16Bit )
+{
+ clear();
+ reserve( nCount );
+ /* #i33341# real life -- same character index may occur several times
+ -> use appendPortion() to validate string position. */
+ BinFontPortionData aPortion;
+ for( sal_uInt16 nIndex = 0; rStrm.isValid() && (nIndex < nCount); ++nIndex )
+ {
+ aPortion.read( rStrm, b16Bit );
+ appendPortion( aPortion );
+ }
+}
+
+void BinFontPortionList::importPortions( BiffInputStream& rStrm, bool b16Bit )
+{
+ sal_uInt16 nCount = b16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
+ importPortions( rStrm, nCount, b16Bit );
+}
+
+// ============================================================================
+
+OoxPhoneticData::OoxPhoneticData() :
+ mnFontId( -1 ),
+ mnType( XML_fullwidthKatakana ),
+ mnAlignment( XML_left )
+{
+}
+
+void OoxPhoneticData::setBinData( sal_Int32 nType, sal_Int32 nAlignment )
+{
+ static const sal_Int32 spnTypeIds[] = { XML_halfwidthKatakana, XML_fullwidthKatakana, XML_hiragana, XML_noConversion };
+ mnType = STATIC_ARRAY_SELECT( spnTypeIds, nType, XML_fullwidthKatakana );
+
+ static const sal_Int32 spnAlignments[] = { XML_noControl, XML_left, XML_center, XML_distributed };
+ mnAlignment = STATIC_ARRAY_SELECT( spnAlignments, nAlignment, XML_left );
+}
+
+// ----------------------------------------------------------------------------
+
+PhoneticSettings::PhoneticSettings( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void PhoneticSettings::importPhoneticPr( const AttributeList& rAttribs )
+{
+ maOoxData.mnFontId = rAttribs.getInteger( XML_fontId, -1 );
+ maOoxData.mnType = rAttribs.getToken( XML_type, XML_fullwidthKatakana );
+ maOoxData.mnAlignment = rAttribs.getToken( XML_alignment, XML_left );
+}
+
+void PhoneticSettings::importPhoneticPr( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFontId;
+ sal_Int32 nType, nAlignment;
+ rStrm >> nFontId >> nType >> nAlignment;
+ maOoxData.mnFontId = nFontId;
+ maOoxData.setBinData( nType, nAlignment );
+}
+
+void PhoneticSettings::importPhoneticPr( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFontId, nFlags;
+ rStrm >> nFontId >> nFlags;
+ maOoxData.mnFontId = nFontId;
+ maOoxData.setBinData( extractValue< sal_Int32 >( nFlags, 0, 2 ), extractValue< sal_Int32 >( nFlags, 2, 2 ) );
+ // following: range list with cells showing phonetic text
+}
+
+void PhoneticSettings::importStringData( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFontId, nFlags;
+ rStrm >> nFontId >> nFlags;
+ maOoxData.mnFontId = nFontId;
+ maOoxData.setBinData( extractValue< sal_Int32 >( nFlags, 0, 2 ), extractValue< sal_Int32 >( nFlags, 2, 2 ) );
+}
+
+void PhoneticSettings::importStringData( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFontId, nFlags;
+ rStrm >> nFontId >> nFlags;
+ maOoxData.mnFontId = nFontId;
+ maOoxData.setBinData( extractValue< sal_Int32 >( nFlags, 0, 2 ), extractValue< sal_Int32 >( nFlags, 2, 2 ) );
+}
+
+// ============================================================================
+
+RichStringPhonetic::RichStringPhonetic( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnBasePos( -1 ),
+ mnBaseEnd( -1 )
+{
+}
+
+void RichStringPhonetic::setText( const OUString& rText )
+{
+ maText = rText;
+}
+
+void RichStringPhonetic::importPhoneticRun( const AttributeList& rAttribs )
+{
+ mnBasePos = rAttribs.getInteger( XML_sb, -1 );
+ mnBaseEnd = rAttribs.getInteger( XML_eb, -1 );
+}
+
+void RichStringPhonetic::setBaseRange( sal_Int32 nBasePos, sal_Int32 nBaseEnd )
+{
+ mnBasePos = nBasePos;
+ mnBaseEnd = nBaseEnd;
+}
+
+// ----------------------------------------------------------------------------
+
+void BinPhoneticPortionData::read( RecordInputStream& rStrm )
+{
+ mnPos = rStrm.readuInt16();
+ mnBasePos = rStrm.readuInt16();
+ mnBaseLen = rStrm.readuInt16();
+}
+
+void BinPhoneticPortionData::read( BiffInputStream& rStrm )
+{
+ mnPos = rStrm.readuInt16();
+ mnBasePos = rStrm.readuInt16();
+ mnBaseLen = rStrm.readuInt16();
+}
+
+// ----------------------------------------------------------------------------
+
+void BinPhoneticPortionList::appendPortion( const BinPhoneticPortionData& rPortion )
+{
+ // same character index may occur several times
+ OSL_ENSURE( empty() || ((back().mnPos <= rPortion.mnPos) &&
+ (back().mnBasePos + back().mnBaseLen <= rPortion.mnBasePos)),
+ "BinPhoneticPortionList::appendPortion - wrong char order" );
+ if( empty() || (back().mnPos < rPortion.mnPos) )
+ {
+ push_back( rPortion );
+ }
+ else if( back().mnPos == rPortion.mnPos )
+ {
+ back().mnBasePos = rPortion.mnBasePos;
+ back().mnBaseLen = rPortion.mnBaseLen;
+ }
+}
+
+void BinPhoneticPortionList::importPortions( RecordInputStream& rStrm )
+{
+ sal_Int32 nCount = rStrm.readInt32();
+ clear();
+ if( nCount > 0 )
+ {
+ reserve( getLimitedValue< size_t, sal_Int32 >( nCount, 0, rStrm.getRecLeft() / 6 ) );
+ BinPhoneticPortionData aPortion;
+ for( sal_Int32 nIndex = 0; rStrm.isValid() && (nIndex < nCount); ++nIndex )
+ {
+ aPortion.read( rStrm );
+ appendPortion( aPortion );
+ }
+ }
+}
+
+OUString BinPhoneticPortionList::importPortions( BiffInputStream& rStrm, sal_uInt32 nPhoneticSize )
+{
+ OUString aPhoneticText;
+ sal_uInt16 nPortionCount, nTextLen1, nTextLen2;
+ rStrm >> nPortionCount >> nTextLen1 >> nTextLen2;
+ OSL_ENSURE( nTextLen1 == nTextLen2, "BinPhoneticPortionList::importPortions - wrong phonetic text length" );
+ if( (nTextLen1 == nTextLen2) && (nTextLen1 > 0) )
+ {
+ sal_uInt32 nMinSize = static_cast< sal_uInt32 >( 2 * nTextLen1 + 6 * nPortionCount + 14 );
+ OSL_ENSURE( nMinSize <= nPhoneticSize, "BinPhoneticPortionList::importPortions - wrong size of phonetic data" );
+ if( nMinSize <= nPhoneticSize )
+ {
+ aPhoneticText = rStrm.readUnicodeArray( nTextLen1 );
+ clear();
+ reserve( nPortionCount );
+ BinPhoneticPortionData aPortion;
+ for( sal_uInt16 nPortion = 0; nPortion < nPortionCount; ++nPortion )
+ {
+ aPortion.read( rStrm );
+ appendPortion( aPortion );
+ }
+ }
+ }
+ return aPhoneticText;
+}
+
+// ============================================================================
+
+RichString::RichString( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maPhonSettings( rHelper )
+{
+}
+
+RichStringPortionRef RichString::importText( const AttributeList& )
+{
+ return createPortion();
+}
+
+RichStringPortionRef RichString::importRun( const AttributeList& )
+{
+ return createPortion();
+}
+
+RichStringPhoneticRef RichString::importPhoneticRun( const AttributeList& rAttribs )
+{
+ RichStringPhoneticRef xPhonetic = createPhonetic();
+ xPhonetic->importPhoneticRun( rAttribs );
+ return xPhonetic;
+}
+
+void RichString::importPhoneticPr( const AttributeList& rAttribs )
+{
+ maPhonSettings.importPhoneticPr( rAttribs );
+}
+
+void RichString::importString( RecordInputStream& rStrm, bool bRich )
+{
+ sal_uInt8 nFlags = bRich ? rStrm.readuInt8() : 0;
+ OUString aBaseText = rStrm.readString();
+
+ if( rStrm.isValid() && getFlag( nFlags, OOBIN_STRINGFLAG_FONTS ) )
+ {
+ BinFontPortionList aPortions;
+ aPortions.importPortions( rStrm );
+ createFontPortions( aBaseText, aPortions );
+ }
+ else
+ {
+ createPortion()->setText( aBaseText );
+ }
+
+ if( rStrm.isValid() && getFlag( nFlags, OOBIN_STRINGFLAG_PHONETICS ) )
+ {
+ OUString aPhoneticText = rStrm.readString();
+ BinPhoneticPortionList aPortions;
+ aPortions.importPortions( rStrm );
+ maPhonSettings.importStringData( rStrm );
+ createPhoneticPortions( aPhoneticText, aPortions, aBaseText.getLength() );
+ }
+}
+
+void RichString::importByteString( BiffInputStream& rStrm, rtl_TextEncoding eDefaultTextEnc, BiffStringFlags nFlags )
+{
+ OSL_ENSURE( !getFlag( nFlags, BIFF_STR_KEEPFONTS ), "RichString::importString - keep fonts not implemented" );
+ OSL_ENSURE( !getFlag( nFlags, static_cast< BiffStringFlags >( ~(BIFF_STR_8BITLENGTH | BIFF_STR_EXTRAFONTS) ) ), "RichString::importByteString - unknown flag" );
+ bool b8BitLength = getFlag( nFlags, BIFF_STR_8BITLENGTH );
+
+ OString aBaseText = rStrm.readByteString( !b8BitLength );
+
+ if( rStrm.isValid() && getFlag( nFlags, BIFF_STR_EXTRAFONTS ) )
+ {
+ BinFontPortionList aPortions;
+ aPortions.importPortions( rStrm, false );
+ createFontPortions( aBaseText, eDefaultTextEnc, aPortions );
+ }
+ else
+ {
+ createPortion()->setText( OStringToOUString( aBaseText, eDefaultTextEnc ) );
+ }
+}
+
+void RichString::importUniString( BiffInputStream& rStrm, BiffStringFlags nFlags )
+{
+ OSL_ENSURE( !getFlag( nFlags, BIFF_STR_KEEPFONTS ), "RichString::importUniString - keep fonts not implemented" );
+ OSL_ENSURE( !getFlag( nFlags, static_cast< BiffStringFlags >( ~(BIFF_STR_8BITLENGTH | BIFF_STR_SMARTFLAGS) ) ), "RichString::importUniString - unknown flag" );
+ bool b8BitLength = getFlag( nFlags, BIFF_STR_8BITLENGTH );
+
+ // --- string header ---
+ sal_uInt16 nChars = b8BitLength ? rStrm.readuInt8() : rStrm.readuInt16();
+ sal_uInt8 nFlagField = 0;
+ if( (nChars > 0) || !getFlag( nFlags, BIFF_STR_SMARTFLAGS ) )
+ rStrm >> nFlagField;
+
+ bool b16Bit, bFonts, bPhonetic;
+ sal_uInt16 nFontCount;
+ sal_uInt32 nPhoneticSize;
+ rStrm.readExtendedUniStringHeader( b16Bit, bFonts, bPhonetic, nFontCount, nPhoneticSize, nFlagField );
+
+ // --- character array ---
+ OUString aBaseText = rStrm.readRawUniString( nChars, b16Bit );
+
+ // --- formatting ---
+ // #122185# bRich flag may be set, but format runs may be missing
+ if( rStrm.isValid() && (nFontCount > 0) )
+ {
+ BinFontPortionList aPortions;
+ aPortions.importPortions( rStrm, nFontCount, true );
+ createFontPortions( aBaseText, aPortions );
+ }
+ else
+ {
+ createPortion()->setText( aBaseText );
+ }
+
+ // --- Asian phonetic information ---
+ // #122185# bPhonetic flag may be set, but phonetic info may be missing
+ if( rStrm.isValid() && (nPhoneticSize > 0) )
+ {
+ sal_uInt32 nPhoneticEnd = rStrm.getRecPos() + nPhoneticSize;
+ OSL_ENSURE( nPhoneticSize > 14, "RichString::importUniString - wrong size of phonetic data" );
+ if( nPhoneticSize > 14 )
+ {
+ sal_uInt16 nId, nSize;
+ rStrm >> nId >> nSize;
+ OSL_ENSURE( nId == 1, "RichString::importUniString - unknown phonetic data identifier" );
+ sal_uInt32 nMinSize = static_cast< sal_uInt32 >( nSize + 4 );
+ OSL_ENSURE( nMinSize <= nPhoneticSize, "RichString::importUniString - wrong size of phonetic data" );
+ if( (nId == 1) && (nMinSize <= nPhoneticSize) )
+ {
+ maPhonSettings.importStringData( rStrm );
+ BinPhoneticPortionList aPortions;
+ OUString aPhoneticText = aPortions.importPortions( rStrm, nPhoneticSize );
+ createPhoneticPortions( aPhoneticText, aPortions, aBaseText.getLength() );
+ }
+ }
+ rStrm.seek( nPhoneticEnd );
+ }
+}
+
+void RichString::finalizeImport()
+{
+ maFontPortions.forEachMem( &RichStringPortion::finalizeImport );
+}
+
+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;
+ }
+}
+
+// private --------------------------------------------------------------------
+
+RichStringPortionRef RichString::createPortion()
+{
+ RichStringPortionRef xPortion( new RichStringPortion( *this ) );
+ maFontPortions.push_back( xPortion );
+ return xPortion;
+}
+
+RichStringPhoneticRef RichString::createPhonetic()
+{
+ RichStringPhoneticRef xPhonetic( new RichStringPhonetic( *this ) );
+ maPhonPortions.push_back( xPhonetic );
+ return xPhonetic;
+}
+
+void RichString::createFontPortions( const OString& rText, rtl_TextEncoding eDefaultTextEnc, BinFontPortionList& rPortions )
+{
+ maFontPortions.clear();
+ sal_Int32 nStrLen = rText.getLength();
+ if( nStrLen > 0 )
+ {
+ // add leading and trailing string position to ease the following loop
+ if( rPortions.empty() || (rPortions.front().mnPos > 0) )
+ rPortions.insert( rPortions.begin(), BinFontPortionData( 0, -1 ) );
+ if( rPortions.back().mnPos < nStrLen )
+ rPortions.push_back( BinFontPortionData( nStrLen, -1 ) );
+
+ // create all string portions according to the font id vector
+ for( BinFontPortionList::const_iterator aIt = rPortions.begin(); aIt->mnPos < nStrLen; ++aIt )
+ {
+ sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos;
+ if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) )
+ {
+ // convert byte string to unicode string, using current font encoding
+ FontRef xFont = getStyles().getFont( aIt->mnFontId );
+ rtl_TextEncoding eTextEnc = xFont.get() ? xFont->getFontEncoding() : eDefaultTextEnc;
+ OUString aUniStr = OStringToOUString( rText.copy( aIt->mnPos, nPortionLen ), eTextEnc );
+ // create string portion
+ RichStringPortionRef xPortion = createPortion();
+ xPortion->setText( aUniStr );
+ xPortion->setFontId( aIt->mnFontId );
+ }
+ }
+ }
+}
+
+void RichString::createFontPortions( const OUString& rText, BinFontPortionList& rPortions )
+{
+ maFontPortions.clear();
+ sal_Int32 nStrLen = rText.getLength();
+ if( nStrLen > 0 )
+ {
+ // add leading and trailing string position to ease the following loop
+ if( rPortions.empty() || (rPortions.front().mnPos > 0) )
+ rPortions.insert( rPortions.begin(), BinFontPortionData( 0, -1 ) );
+ if( rPortions.back().mnPos < nStrLen )
+ rPortions.push_back( BinFontPortionData( nStrLen, -1 ) );
+
+ // create all string portions according to the font id vector
+ for( BinFontPortionList::const_iterator aIt = rPortions.begin(); aIt->mnPos < nStrLen; ++aIt )
+ {
+ sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos;
+ if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) )
+ {
+ RichStringPortionRef xPortion = createPortion();
+ xPortion->setText( rText.copy( aIt->mnPos, nPortionLen ) );
+ xPortion->setFontId( aIt->mnFontId );
+ }
+ }
+ }
+}
+
+void RichString::createPhoneticPortions( const ::rtl::OUString& rText, BinPhoneticPortionList& rPortions, sal_Int32 nBaseLen )
+{
+ maPhonPortions.clear();
+ sal_Int32 nStrLen = rText.getLength();
+ if( nStrLen > 0 )
+ {
+ // no portions - assign phonetic text to entire base text
+ if( rPortions.empty() )
+ rPortions.push_back( BinPhoneticPortionData( 0, 0, nBaseLen ) );
+ // add trailing string position to ease the following loop
+ if( rPortions.back().mnPos < nStrLen )
+ rPortions.push_back( BinPhoneticPortionData( nStrLen, nBaseLen, 0 ) );
+
+ // create all phonetic portions according to the portions vector
+ for( BinPhoneticPortionList::const_iterator aIt = rPortions.begin(); aIt->mnPos < nStrLen; ++aIt )
+ {
+ sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos;
+ if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) )
+ {
+ RichStringPhoneticRef xPhonetic = createPhonetic();
+ xPhonetic->setText( rText.copy( aIt->mnPos, nPortionLen ) );
+ xPhonetic->setBaseRange( aIt->mnBasePos, aIt->mnBasePos + aIt->mnBaseLen );
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/richstringcontext.cxx b/oox/source/xls/richstringcontext.cxx
new file mode 100644
index 000000000000..fd9b21572cb6
--- /dev/null
+++ b/oox/source/xls/richstringcontext.cxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: richstringcontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/richstringcontext.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxRichStringContext::onCanCreateContext( sal_Int32 nElement ) const
+{
+ sal_Int32 nCurrContext = getCurrentContext();
+ switch( nCurrContext )
+ {
+ case XLS_TOKEN( si ):
+ case XLS_TOKEN( is ):
+ case XLS_TOKEN( text ):
+ return (nElement == XLS_TOKEN( t )) ||
+ (nElement == XLS_TOKEN( r )) ||
+ (nElement == XLS_TOKEN( rPh )) ||
+ (nElement == XLS_TOKEN( phoneticPr ));
+ case XLS_TOKEN( r ):
+ return (nElement == XLS_TOKEN( rPr )) ||
+ (nElement == XLS_TOKEN( t ));
+ case XLS_TOKEN( rPh ):
+ return (nElement == XLS_TOKEN( t ));
+ case XLS_TOKEN( rPr ):
+ return Font::isSupportedContext( nElement, nCurrContext );
+ }
+ return false;
+}
+
+void OoxRichStringContext::onStartElement( const AttributeList& rAttribs )
+{
+ sal_Int32 nCurrContext = getCurrentContext();
+ switch( nCurrContext )
+ {
+ case XLS_TOKEN( t ):
+ if( !isPreviousContext( XLS_TOKEN( r ) ) && !isPreviousContext( XLS_TOKEN( rPh ) ) )
+ mxPortion = mxString->importText( rAttribs );
+ break;
+ case XLS_TOKEN( r ):
+ mxPortion = mxString->importRun( rAttribs );
+ break;
+ case XLS_TOKEN( rPr ):
+ if( mxPortion.get() ) mxFont = mxPortion->importFont( rAttribs );
+ break;
+ case XLS_TOKEN( rPh ):
+ mxPhonetic = mxString->importPhoneticRun( rAttribs );
+ break;
+ case XLS_TOKEN( phoneticPr ):
+ mxString->importPhoneticPr( rAttribs );
+ break;
+ default:
+ if( isPreviousContext( XLS_TOKEN( rPr ) ) && mxFont.get() )
+ mxFont->importAttribs( nCurrContext, rAttribs );
+ }
+}
+
+void OoxRichStringContext::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( t ):
+ switch( getPreviousContext() )
+ {
+ case XLS_TOKEN( rPh ):
+ if( mxPhonetic.get() ) mxPhonetic->setText( rChars );
+ break;
+ default:
+ if( mxPortion.get() ) mxPortion->setText( rChars );
+ }
+ break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/sharedformulabuffer.cxx b/oox/source/xls/sharedformulabuffer.cxx
new file mode 100644
index 000000000000..5a09ec22c407
--- /dev/null
+++ b/oox/source/xls/sharedformulabuffer.cxx
@@ -0,0 +1,220 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sharedformulabuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/sharedformulabuffer.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/formulaparser.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::sheet::XFormulaTokens;
+using ::com::sun::star::sheet::XNamedRange;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+bool operator==( const CellAddress& rAddr1, const CellAddress& rAddr2 )
+{
+ return
+ (rAddr1.Sheet == rAddr2.Sheet) &&
+ (rAddr1.Column == rAddr2.Column) &&
+ (rAddr1.Row == rAddr2.Row);
+}
+
+bool lclContains( const CellRangeAddress& rRange, const CellAddress& rAddr )
+{
+ return
+ (rRange.Sheet == rAddr.Sheet) &&
+ (rRange.StartColumn <= rAddr.Column) && (rAddr.Column <= rRange.EndColumn) &&
+ (rRange.StartRow <= rAddr.Row) && (rAddr.Row <= rRange.EndRow);
+}
+
+} // namespace
+
+// ============================================================================
+
+ExtCellFormulaContext::ExtCellFormulaContext( const WorksheetHelper& rHelper,
+ const Reference< XFormulaTokens >& rxTokens, const CellAddress& rCellPos ) :
+ SimpleFormulaContext( rxTokens, false, false ),
+ WorksheetHelper( rHelper )
+{
+ setBaseAddress( rCellPos );
+}
+
+void ExtCellFormulaContext::setSharedFormula( const CellAddress& rBaseAddr )
+{
+ getSharedFormulas().setSharedFormulaCell( *this, rBaseAddr );
+}
+
+// ============================================================================
+
+SharedFormulaBuffer::SharedFormulaBuffer( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void SharedFormulaBuffer::importSharedFmla( const OUString& rFormula, const OUString& rSharedRange, sal_Int32 nSharedId, const CellAddress& rBaseAddr )
+{
+ CellRangeAddress aFmlaRange;
+ if( getAddressConverter().convertToCellRange( aFmlaRange, rSharedRange, getSheetIndex(), true ) )
+ {
+ // create the defined name representing the shared formula
+ OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" );
+ BinAddress aMapKey( nSharedId, 0 );
+ Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey );
+ // convert the formula definition
+ Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY );
+ if( xTokens.is() )
+ {
+ SimpleFormulaContext aContext( xTokens, true, false );
+ aContext.setBaseAddress( rBaseAddr );
+ getFormulaParser().importFormula( aContext, rFormula );
+ updateCachedCell( rBaseAddr, aMapKey );
+ }
+ }
+}
+
+void SharedFormulaBuffer::importSharedFmla( RecordInputStream& rStrm, const CellAddress& rBaseAddr )
+{
+ BinRange aRange;
+ rStrm >> aRange;
+ CellRangeAddress aFmlaRange;
+ if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true ) )
+ {
+ // create the defined name representing the shared formula
+ OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" );
+ BinAddress aMapKey( rBaseAddr );
+ Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey );
+ // load the formula definition
+ Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY );
+ if( xTokens.is() )
+ {
+ SimpleFormulaContext aContext( xTokens, true, false );
+ aContext.setBaseAddress( rBaseAddr );
+ getFormulaParser().importFormula( aContext, rStrm );
+ updateCachedCell( rBaseAddr, aMapKey );
+ }
+ }
+}
+
+void SharedFormulaBuffer::importSharedFmla( BiffInputStream& rStrm, const CellAddress& rBaseAddr )
+{
+ BinRange aRange;
+ aRange.read( rStrm, false ); // always 8bit column indexes
+ CellRangeAddress aFmlaRange;
+ if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true ) )
+ {
+ // create the defined name representing the shared formula
+ OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" );
+ BinAddress aMapKey( rBaseAddr );
+ Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey );
+ // load the formula definition
+ Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY );
+ if( xTokens.is() )
+ {
+ rStrm.skip( 2 ); // flags
+ SimpleFormulaContext aContext( xTokens, true, false );
+ aContext.setBaseAddress( rBaseAddr );
+ getFormulaParser().importFormula( aContext, rStrm );
+ updateCachedCell( rBaseAddr, aMapKey );
+ }
+ }
+}
+
+void SharedFormulaBuffer::setSharedFormulaCell( ExtCellFormulaContext& rContext, const CellAddress& rBaseAddr )
+{
+ if( !implSetSharedFormulaCell( rContext, BinAddress( rBaseAddr ) ) )
+ if( rContext.getBaseAddress() == rBaseAddr )
+ mxLastContext.reset( new ExtCellFormulaContext( rContext ) );
+}
+
+void SharedFormulaBuffer::setSharedFormulaCell( ExtCellFormulaContext& rContext, sal_Int32 nSharedId )
+{
+ implSetSharedFormulaCell( rContext, BinAddress( nSharedId, 0 ) );
+}
+
+Reference< XNamedRange > SharedFormulaBuffer::createDefinedName( const BinAddress& rMapKey )
+{
+ OSL_ENSURE( maIndexMap.count( rMapKey ) == 0, "SharedFormulaBuffer::createDefinedName - shared formula exists already" );
+ // create the defined name representing the shared formula
+ OUString aName = OUStringBuffer().appendAscii( "__shared_" ).
+ append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ).
+ append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ).
+ append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear();
+ Reference< XNamedRange > xNamedRange = getDefinedNames().createDefinedName( aName );
+ sal_Int32 nTokenIndex = getDefinedNames().getTokenIndex( xNamedRange );
+ if( nTokenIndex >= 0 )
+ maIndexMap[ rMapKey ] = nTokenIndex;
+ return xNamedRange;
+}
+
+bool SharedFormulaBuffer::implSetSharedFormulaCell( ExtCellFormulaContext& rContext, const BinAddress& rMapKey )
+{
+ TokenIndexMap::const_iterator aIt = maIndexMap.find( rMapKey );
+ sal_Int32 nTokenIndex = (aIt == maIndexMap.end()) ? -1 : aIt->second;
+ if( nTokenIndex >= 0 )
+ {
+ getFormulaParser().convertNameToFormula( rContext, nTokenIndex );
+ return true;
+ }
+ return false;
+}
+
+void SharedFormulaBuffer::updateCachedCell( const CellAddress& rBaseAddr, const BinAddress& rMapKey )
+{
+ if( mxLastContext.get() && (mxLastContext->getBaseAddress() == rBaseAddr) )
+ implSetSharedFormulaCell( *mxLastContext, rMapKey );
+ mxLastContext.reset();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/sharedstringsbuffer.cxx b/oox/source/xls/sharedstringsbuffer.cxx
new file mode 100644
index 000000000000..85a6662e3004
--- /dev/null
+++ b/oox/source/xls/sharedstringsbuffer.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sharedstringsbuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::text::XText;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+SharedStringsBuffer::SharedStringsBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+RichStringRef SharedStringsBuffer::createRichString()
+{
+ RichStringRef xString( new RichString( *this ) );
+ maStrings.push_back( xString );
+ return xString;
+}
+
+void SharedStringsBuffer::importSst( BiffInputStream& rStrm )
+{
+ sal_Int32 nStringCount = rStrm.skip( 4 ).readInt32();
+ if( nStringCount > 0 )
+ {
+ maStrings.clear();
+ maStrings.reserve( static_cast< size_t >( nStringCount ) );
+ for( ; rStrm.isValid() && (nStringCount > 0); --nStringCount )
+ {
+ RichStringRef xString( new RichString( *this ) );
+ maStrings.push_back( xString );
+ xString->importUniString( rStrm );
+ }
+ }
+}
+
+void SharedStringsBuffer::finalizeImport()
+{
+ maStrings.forEachMem( &RichString::finalizeImport );
+}
+
+void SharedStringsBuffer::convertString( const Reference< XText >& rxText, sal_Int32 nStringId, sal_Int32 nXfId ) const
+{
+ if( rxText.is() )
+ if( const RichString* pString = maStrings.get( nStringId ).get() )
+ pString->convert( rxText, nXfId );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/sharedstringsfragment.cxx b/oox/source/xls/sharedstringsfragment.cxx
new file mode 100644
index 000000000000..8b7b1c5d6b6e
--- /dev/null
+++ b/oox/source/xls/sharedstringsfragment.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sharedstringsfragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/sharedstringsfragment.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/richstringcontext.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XFastContextHandler;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+OoxSharedStringsFragment::OoxSharedStringsFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxSharedStringsFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nElement == XLS_TOKEN( sst ));
+ case XLS_TOKEN( sst ):
+ return (nElement == XLS_TOKEN( si ));
+ }
+ return false;
+}
+
+Reference< XFastContextHandler > OoxSharedStringsFragment::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( si ):
+ return new OoxRichStringContext( *this, getSharedStrings().createRichString() );
+ }
+ return this;
+}
+
+bool OoxSharedStringsFragment::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nRecId == OOBIN_ID_SST);
+ case OOBIN_ID_SST:
+ return (nRecId == OOBIN_ID_SI);
+ }
+ return false;
+}
+
+void OoxSharedStringsFragment::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_SI: getSharedStrings().createRichString()->importString( rStrm, true ); break;
+ }
+}
+
+// oox.xls.OoxFragmentHandler interface ---------------------------------------
+
+void OoxSharedStringsFragment::finalizeImport()
+{
+ getSharedStrings().finalizeImport();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/sheetcellrangemap.cxx b/oox/source/xls/sheetcellrangemap.cxx
new file mode 100644
index 000000000000..aeb35953a558
--- /dev/null
+++ b/oox/source/xls/sheetcellrangemap.cxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sheetcellrangemap.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2007 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/sheetcellrangemap.hxx"
+
+#define DEBUG_OOX_CELLRANGE_MAP 0
+
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#if DEBUG_OOX_CELLRANGE_MAP
+#include <stdio.h>
+#endif
+
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+
+namespace oox {
+namespace xls {
+
+SheetCellRangeMap::SheetCellRangeMap()
+{
+}
+
+SheetCellRangeMap::~SheetCellRangeMap() throw()
+{
+}
+
+void SheetCellRangeMap::addCellRange( const CellRangeAddress& aRangeAddr )
+{
+ size_t nAreaId = maAreas.size();
+
+ // First, find the sheet ID.
+ SheetMapType::iterator posSheet = maSheetMap.find(aRangeAddr.Sheet);
+ if ( posSheet == maSheetMap.end() )
+ {
+ maSheetMap.insert( SheetMapType::value_type(aRangeAddr.Sheet, SheetSet()) );
+ posSheet = maSheetMap.find(aRangeAddr.Sheet);
+ OSL_ENSURE( posSheet != maSheetMap.end(), "SheetCellRangeMap::addCellRange: insertion failure" );
+ }
+ SheetSet& rSheet = posSheet->second;
+
+ addRange(rSheet.maColRanges, aRangeAddr.StartColumn, aRangeAddr.EndColumn, nAreaId);
+ addRange(rSheet.maRowRanges, aRangeAddr.StartRow, aRangeAddr.EndRow, nAreaId);
+
+#if DEBUG_OOX_CELLRANGE_MAP
+ fprintf(stdout, "SheetCellRangeMap::addCellRange: adding (sheet: %d) (col: %ld - %ld) (row: %ld - %ld) (area: %d)\n",
+ aRangeAddr.Sheet, aRangeAddr.StartColumn, aRangeAddr.EndColumn, aRangeAddr.StartRow, aRangeAddr.EndRow, nAreaId);fflush(stdout);
+#endif
+
+ maAreas.push_back(aRangeAddr);
+}
+
+bool SheetCellRangeMap::isOverlapping( const CellAddress& aCellAddr ) const
+{
+ if ( maAreas.empty() )
+ return false;
+
+ SheetMapType::const_iterator pos = maSheetMap.find(aCellAddr.Sheet);
+ if ( pos == maSheetMap.end() )
+ // There is no cell range registered for this sheet.
+ return false;
+
+ const SheetSet& rSheet = pos->second;
+ return searchColumns( rSheet, aCellAddr );
+}
+
+void SheetCellRangeMap::addRange( StartEndMapType& rRangeMap, sal_Int32 nStart, sal_Int32 nEnd, size_t nAreaId )
+{
+ StartEndMapType::iterator posStart = rRangeMap.find(nStart);
+ if ( posStart == rRangeMap.end() )
+ {
+ EndAreaIdMapType aMap;
+ rRangeMap.insert( StartEndMapType::value_type(nStart, aMap) );
+ posStart = rRangeMap.find(nStart);
+ OSL_ENSURE( posStart != rRangeMap.end(), "TableBuffer::addRangeToSet: insertion failure" );
+ }
+ EndAreaIdMapType& rEndMap = posStart->second;
+
+ EndAreaIdMapType::iterator posEnd = rEndMap.find(nEnd);
+ if ( posEnd == rEndMap.end() )
+ {
+ AreaIdSetType aSet;
+ rEndMap.insert( EndAreaIdMapType::value_type(nEnd, aSet) );
+ posEnd = rEndMap.find(nEnd);
+ OSL_ENSURE( posEnd != rEndMap.end(), "TableBuffer::addRangeToSet: insertion failure" );
+ }
+
+ AreaIdSetType& rSet = posEnd->second;
+ rSet.push_back(nAreaId);
+}
+
+bool SheetCellRangeMap::expandSearch( const EndAreaIdMapType& rEndMap, const CellAddress& rCellAddr, bool bColumn ) const
+{
+ sal_Int32 nId = bColumn ? rCellAddr.Column : rCellAddr.Row;
+
+ EndAreaIdMapType::const_reverse_iterator itr, itrBeg = rEndMap.rbegin(), itrEnd = rEndMap.rend();
+ for ( itr = itrBeg; itr != itrEnd; ++itr )
+ {
+ if ( itr->first >= nId )
+ {
+ // The point is in-range.
+ const AreaIdSetType& rSet = itr->second;
+ AreaIdSetType::const_iterator itr2 = rSet.begin(), itr2End = rSet.end();
+ for ( ; itr2 != itr2End; ++itr2 )
+ {
+ OSL_ENSURE( maAreas.size() > *itr2, "SheetCellRangeMap::expandSearch: size mismatch" );
+ const CellRangeAddress& rRange = maAreas[*itr2];
+ if ( bColumn && rCellAddr.Row >= rRange.StartRow && rCellAddr.Row <= rRange.EndRow )
+ return true;
+ if ( !bColumn && rCellAddr.Column >= rRange.StartColumn && rCellAddr.Column <= rRange.EndColumn )
+ return true;
+ }
+ }
+ else if ( itr->first < nId )
+ // No more enclosing ranges.
+ return false;
+ }
+ return false;
+}
+
+bool SheetCellRangeMap::searchColumns( const SheetSet& rSheet, const CellAddress& aCellAddr ) const
+{
+ StartEndMapType::const_iterator itr, itrBeg = rSheet.maColRanges.begin(), itrEnd = rSheet.maColRanges.end();
+ for ( itr = itrBeg; itr != itrEnd; ++itr )
+ {
+ if ( itr->first <= aCellAddr.Column )
+ {
+ if ( expandSearch(itr->second, aCellAddr, true) )
+ return true;
+ }
+ else if ( itr->first > aCellAddr.Column )
+ return false;
+ }
+ return false;
+}
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx
new file mode 100644
index 000000000000..b605326f2f07
--- /dev/null
+++ b/oox/source/xls/sheetdatacontext.cxx
@@ -0,0 +1,1160 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sheetdatacontext.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/sheetdatacontext.hxx"
+#include <com/sun/star/table/CellContentType.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include <com/sun/star/sheet/XArrayFormulaTokens.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/pivottablebuffer.hxx"
+#include "oox/xls/richstringcontext.hxx"
+#include "oox/xls/sharedformulabuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+using ::rtl::OUString;
+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 ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::table::CellContentType_EMPTY;
+using ::com::sun::star::table::XCell;
+using ::com::sun::star::table::XCellRange;
+using ::com::sun::star::sheet::XFormulaTokens;
+using ::com::sun::star::sheet::XArrayFormulaTokens;
+using ::com::sun::star::text::XText;
+using ::com::sun::star::xml::sax::XFastContextHandler;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+// record constants -----------------------------------------------------------
+
+const sal_uInt16 OOBIN_CELL_SHOWPHONETIC = 0x0100;
+
+const sal_uInt8 OOBIN_DATATABLE_ROW = 0x01;
+const sal_uInt8 OOBIN_DATATABLE_2D = 0x02;
+const sal_uInt8 OOBIN_DATATABLE_REF1DEL = 0x04;
+const sal_uInt8 OOBIN_DATATABLE_REF2DEL = 0x08;
+
+const sal_uInt16 OOBIN_ROW_THICKTOP = 0x0001;
+const sal_uInt16 OOBIN_ROW_THICKBOTTOM = 0x0002;
+const sal_uInt16 OOBIN_ROW_COLLAPSED = 0x0800;
+const sal_uInt16 OOBIN_ROW_HIDDEN = 0x1000;
+const sal_uInt16 OOBIN_ROW_CUSTOMHEIGHT = 0x2000;
+const sal_uInt16 OOBIN_ROW_CUSTOMFORMAT = 0x4000;
+
+const sal_uInt8 BIFF_BOOLERR_BOOL = 0;
+const sal_uInt8 BIFF_BOOLERR_ERROR = 1;
+
+const sal_uInt16 BIFF_DATATABLE_ROW = 0x0004;
+const sal_uInt16 BIFF_DATATABLE_2D = 0x0008;
+const sal_uInt16 BIFF_DATATABLE_REF1DEL = 0x0010;
+const sal_uInt16 BIFF_DATATABLE_REF2DEL = 0x0020;
+
+const sal_uInt8 BIFF_FORMULA_RES_STRING = 0; /// Result is a string.
+const sal_uInt8 BIFF_FORMULA_RES_BOOL = 1; /// Result is Boolean value.
+const sal_uInt8 BIFF_FORMULA_RES_ERROR = 2; /// Result is error code.
+const sal_uInt8 BIFF_FORMULA_RES_EMPTY = 3; /// Result is empty cell (BIFF8 only).
+const sal_uInt16 BIFF_FORMULA_SHARED = 0x0008; /// Shared formula cell.
+
+const sal_uInt8 BIFF2_ROW_CUSTOMFORMAT = 0x01;
+const sal_uInt16 BIFF_ROW_DEFAULTHEIGHT = 0x8000;
+const sal_uInt16 BIFF_ROW_HEIGHTMASK = 0x7FFF;
+const sal_uInt32 BIFF_ROW_COLLAPSED = 0x00000010;
+const sal_uInt32 BIFF_ROW_HIDDEN = 0x00000020;
+const sal_uInt32 BIFF_ROW_CUSTOMHEIGHT = 0x00000040;
+const sal_uInt32 BIFF_ROW_CUSTOMFORMAT = 0x00000080;
+const sal_uInt32 BIFF_ROW_THICKTOP = 0x10000000;
+const sal_uInt32 BIFF_ROW_THICKBOTTOM = 0x20000000;
+const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000;
+
+const sal_Int32 BIFF_XF_EXTENDED_IDS = 63;
+const sal_uInt8 BIFF2_XF_MASK = 0x3F;
+
+// ----------------------------------------------------------------------------
+
+/** Formula context for cell formulas. */
+class CellFormulaContext : public SimpleFormulaContext
+{
+public:
+ explicit CellFormulaContext(
+ const Reference< XFormulaTokens >& rxTokens,
+ const CellAddress& rCellPos );
+};
+
+CellFormulaContext::CellFormulaContext( const Reference< XFormulaTokens >& rxTokens, const CellAddress& rCellPos ) :
+ SimpleFormulaContext( rxTokens, false, false )
+{
+ setBaseAddress( rCellPos );
+}
+
+// ----------------------------------------------------------------------------
+
+/** Uses the XArrayFormulaTokens interface to set a token sequence. */
+class ArrayFormulaContext : public FormulaContext
+{
+public:
+ explicit ArrayFormulaContext(
+ const Reference< XArrayFormulaTokens >& rxTokens,
+ const CellRangeAddress& rArrayRange );
+
+ virtual void setTokens( const ApiTokenSequence& rTokens );
+
+private:
+ Reference< XArrayFormulaTokens > mxTokens;
+};
+
+ArrayFormulaContext::ArrayFormulaContext(
+ const Reference< XArrayFormulaTokens >& rxTokens, const CellRangeAddress& rArrayRange ) :
+ FormulaContext( false, false ),
+ mxTokens( rxTokens )
+{
+ OSL_ENSURE( mxTokens.is(), "ArrayFormulaContext::ArrayFormulaContext - missing XArrayFormulaTokens interface" );
+ setBaseAddress( CellAddress( rArrayRange.Sheet, rArrayRange.StartColumn, rArrayRange.StartRow ) );
+}
+
+void ArrayFormulaContext::setTokens( const ApiTokenSequence& rTokens )
+{
+ mxTokens->setArrayTokens( rTokens );
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace
+
+// ============================================================================
+
+OoxSheetDataContext::OoxSheetDataContext( const OoxWorksheetFragmentBase& rFragment ) :
+ OoxWorksheetContextBase( rFragment )
+{
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxSheetDataContext::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( sheetData ):
+ return (nElement == XLS_TOKEN( row ));
+ case XLS_TOKEN( row ):
+ return (nElement == XLS_TOKEN( c ));
+ case XLS_TOKEN( c ):
+ return maCurrCell.mxCell.is() &&
+ ((nElement == XLS_TOKEN( v )) ||
+ (nElement == XLS_TOKEN( is )) ||
+ (nElement == XLS_TOKEN( f )));
+ }
+ return false;
+}
+
+Reference< XFastContextHandler > OoxSheetDataContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( is ):
+ mxInlineStr.reset( new RichString( *this ) );
+ return new OoxRichStringContext( *this, mxInlineStr );
+ }
+ return this;
+}
+
+void OoxSheetDataContext::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( row ): importRow( rAttribs ); break;
+ case XLS_TOKEN( c ): importCell( rAttribs ); break;
+ case XLS_TOKEN( f ): importFormula( rAttribs ); break;
+ }
+}
+
+void OoxSheetDataContext::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( v ):
+ maCurrCell.maValueStr = rChars;
+ maCurrCell.mbHasValueStr = true;
+ break;
+
+ case XLS_TOKEN( f ):
+ if( maCurrCell.mxCell.is() ) try
+ {
+ switch( maCurrCell.mnFormulaType )
+ {
+ case XML_normal:
+ if( rChars.getLength() > 0 )
+ {
+ Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW );
+ CellFormulaContext aContext( xTokens, maCurrCell.maAddress );
+ getFormulaParser().importFormula( aContext, rChars );
+ }
+ break;
+
+ case XML_array:
+ if( (maCurrCell.maFormulaRef.getLength() > 0) && (rChars.getLength() > 0) )
+ {
+ CellRangeAddress aArrayRange;
+ Reference< XArrayFormulaTokens > xTokens( getCellRange( maCurrCell.maFormulaRef, &aArrayRange ), UNO_QUERY_THROW );
+ ArrayFormulaContext aContext( xTokens, aArrayRange );
+ getFormulaParser().importFormula( aContext, rChars );
+ }
+ break;
+
+ case XML_shared:
+ if( maCurrCell.mnSharedId >= 0 )
+ {
+ if( rChars.getLength() > 0 )
+ getSharedFormulas().importSharedFmla( rChars, maCurrCell.maFormulaRef, maCurrCell.mnSharedId, maCurrCell.maAddress );
+ Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW );
+ ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress );
+ getSharedFormulas().setSharedFormulaCell( aContext, maCurrCell.mnSharedId );
+ }
+ break;
+
+ case XML_dataTable:
+ if( maCurrCell.maFormulaRef.getLength() > 0 )
+ {
+ CellRangeAddress aTableRange;
+ if( getAddressConverter().convertToCellRange( aTableRange, maCurrCell.maFormulaRef, getSheetIndex(), true ) )
+ setTableOperation( aTableRange, maTableData );
+ }
+ break;
+
+ default:
+ OSL_ENSURE( false, "OoxSheetDataContext::onEndElement - unknown formula type" );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ break;
+
+ case XLS_TOKEN( c ):
+ if( maCurrCell.mxCell.is() )
+ {
+ if( maCurrCell.mxCell->getType() == CellContentType_EMPTY )
+ {
+ if( maCurrCell.mbHasValueStr )
+ {
+ // implemented in WorksheetHelper class
+ setOoxCell( maCurrCell );
+ }
+ else if( (maCurrCell.mnCellType == XML_inlineStr) && mxInlineStr.get() )
+ {
+ // convert font settings
+ mxInlineStr->finalizeImport();
+ // write string to cell
+ Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
+ if( xText.is() )
+ mxInlineStr->convert( xText, maCurrCell.mnXfId );
+ }
+ else
+ {
+ // empty cell, update cell type
+ maCurrCell.mnCellType = XML_TOKEN_INVALID;
+ }
+ }
+
+ // store the cell formatting data
+ setCellFormat( maCurrCell );
+ }
+ break;
+ }
+}
+
+bool OoxSheetDataContext::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_SHEETDATA:
+ return (nRecId == OOBIN_ID_ROW);
+ case OOBIN_ID_ROW:
+ return (nRecId == OOBIN_ID_ARRAY) ||
+ (nRecId == OOBIN_ID_CELL_BOOL) ||
+ (nRecId == OOBIN_ID_CELL_BLANK) ||
+ (nRecId == OOBIN_ID_CELL_DOUBLE) ||
+ (nRecId == OOBIN_ID_CELL_ERROR) ||
+ (nRecId == OOBIN_ID_CELL_RK) ||
+ (nRecId == OOBIN_ID_CELL_RSTRING) ||
+ (nRecId == OOBIN_ID_CELL_SI) ||
+ (nRecId == OOBIN_ID_CELL_STRING) ||
+ (nRecId == OOBIN_ID_DATATABLE) ||
+ (nRecId == OOBIN_ID_FORMULA_BOOL) ||
+ (nRecId == OOBIN_ID_FORMULA_DOUBLE) ||
+ (nRecId == OOBIN_ID_FORMULA_ERROR) ||
+ (nRecId == OOBIN_ID_FORMULA_STRING) ||
+ (nRecId == OOBIN_ID_SHAREDFMLA);
+ }
+ return false;
+}
+
+void OoxSheetDataContext::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_ARRAY: importArray( rStrm ); break;
+ case OOBIN_ID_CELL_BOOL: importCellBool( rStrm, false ); break;
+ case OOBIN_ID_CELL_BLANK: importCellBlank( rStrm ); break;
+ case OOBIN_ID_CELL_DOUBLE: importCellDouble( rStrm, false ); break;
+ case OOBIN_ID_CELL_ERROR: importCellError( rStrm, false ); break;
+ case OOBIN_ID_CELL_RK: importCellRk( rStrm ); break;
+ case OOBIN_ID_CELL_RSTRING: importCellRString( rStrm ); break;
+ case OOBIN_ID_CELL_SI: importCellSi( rStrm ); break;
+ case OOBIN_ID_CELL_STRING: importCellString( rStrm, false ); break;
+ case OOBIN_ID_DATATABLE: importDataTable( rStrm ); break;
+ case OOBIN_ID_FORMULA_BOOL: importCellBool( rStrm, true ); break;
+ case OOBIN_ID_FORMULA_DOUBLE: importCellDouble( rStrm, true ); break;
+ case OOBIN_ID_FORMULA_ERROR: importCellError( rStrm, true ); break;
+ case OOBIN_ID_FORMULA_STRING: importCellString( rStrm, true ); break;
+ case OOBIN_ID_ROW: importRow( rStrm ); break;
+ case OOBIN_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void OoxSheetDataContext::importRow( const AttributeList& rAttribs )
+{
+ OoxRowData aData;
+ aData.mnFirstRow = aData.mnLastRow = rAttribs.getInteger( XML_r, -1 );
+ aData.mfHeight = rAttribs.getDouble( XML_ht, -1.0 );
+ aData.mnXfId = rAttribs.getInteger( XML_s, -1 );
+ aData.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
+ aData.mbCustomHeight = rAttribs.getBool( XML_customHeight, false );
+ aData.mbCustomFormat = rAttribs.getBool( XML_customFormat, false );
+ aData.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
+ aData.mbHidden = rAttribs.getBool( XML_hidden, false );
+ aData.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
+ aData.mbThickTop = rAttribs.getBool( XML_thickTop, false );
+ aData.mbThickBottom = rAttribs.getBool( XML_thickBot, false );
+ // set row properties in the current sheet
+ setRowData( aData );
+}
+
+void OoxSheetDataContext::importCell( const AttributeList& rAttribs )
+{
+ maCurrCell.reset();
+ maCurrCell.mxCell = getCell( rAttribs.getString( XML_r ), &maCurrCell.maAddress );
+ maCurrCell.mnCellType = rAttribs.getToken( XML_t, XML_n );
+ maCurrCell.mnXfId = rAttribs.getInteger( XML_s, -1 );
+ maCurrCell.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
+ mxInlineStr.reset();
+
+ if( maCurrCell.mxCell.is() && getPivotTables().isOverlapping( maCurrCell.maAddress ) )
+ // This cell overlaps a pivot table. Skip it.
+ maCurrCell.mxCell.clear();
+}
+
+void OoxSheetDataContext::importFormula( const AttributeList& rAttribs )
+{
+ maCurrCell.maFormulaRef = rAttribs.getString( XML_ref );
+ maCurrCell.mnFormulaType = rAttribs.getToken( XML_t, XML_normal );
+ maCurrCell.mnSharedId = rAttribs.getInteger( XML_si, -1 );
+ maTableData.maRef1 = rAttribs.getString( XML_r1 );
+ maTableData.maRef2 = rAttribs.getString( XML_r2 );
+ maTableData.mb2dTable = rAttribs.getBool( XML_dt2D, false );
+ maTableData.mbRowTable = rAttribs.getBool( XML_dtr, false );
+ maTableData.mbRef1Deleted = rAttribs.getBool( XML_del1, false );
+ maTableData.mbRef2Deleted = rAttribs.getBool( XML_del2, false );
+}
+
+void OoxSheetDataContext::importCellHeader( RecordInputStream& rStrm )
+{
+ maCurrCell.reset();
+ sal_uInt16 nXfId, nFlags;
+ rStrm >> maCurrPos.mnCol >> nXfId >> nFlags;
+
+ maCurrCell.mxCell = getCell( maCurrPos, &maCurrCell.maAddress );
+ maCurrCell.mnXfId = nXfId;
+ maCurrCell.mbShowPhonetic = getFlag( nFlags, OOBIN_CELL_SHOWPHONETIC );
+}
+
+void OoxSheetDataContext::importCellBool( RecordInputStream& rStrm, bool bFormula )
+{
+ importCellHeader( rStrm );
+ maCurrCell.mnCellType = XML_b;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ bool bValue = rStrm.readuInt8() != 0;
+ if( bFormula )
+ {
+ importCellFormula( rStrm );
+ }
+ else
+ {
+ setBooleanCell( maCurrCell.mxCell, bValue );
+ // #108770# set 'Standard' number format for all Boolean cells
+ maCurrCell.mnNumFmtId = 0;
+ }
+ }
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellBlank( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellDouble( RecordInputStream& rStrm, bool bFormula )
+{
+ importCellHeader( rStrm );
+ maCurrCell.mnCellType = XML_n;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ double fValue = rStrm.readDouble();
+ if( bFormula )
+ importCellFormula( rStrm );
+ else
+ maCurrCell.mxCell->setValue( fValue );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellError( RecordInputStream& rStrm, bool bFormula )
+{
+ importCellHeader( rStrm );
+ maCurrCell.mnCellType = XML_e;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ sal_uInt8 nErrorCode = rStrm.readuInt8();
+ if( bFormula )
+ importCellFormula( rStrm );
+ else
+ setErrorCell( maCurrCell.mxCell, nErrorCode );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellRk( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ maCurrCell.mnCellType = XML_n;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellRString( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ maCurrCell.mnCellType = XML_inlineStr;
+ Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
+ if( xText.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ RichString aString( *this );
+ aString.importString( rStrm, true );
+ aString.finalizeImport();
+ aString.convert( xText, maCurrCell.mnXfId );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellSi( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ maCurrCell.mnCellType = XML_s;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ setSharedStringCell( maCurrCell.mxCell, rStrm.readInt32(), maCurrCell.mnXfId );
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellString( RecordInputStream& rStrm, bool bFormula )
+{
+ importCellHeader( rStrm );
+ maCurrCell.mnCellType = XML_inlineStr;
+ Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
+ if( xText.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ RichString aString( *this );
+ aString.importString( rStrm, false );
+ aString.finalizeImport();
+ if( bFormula )
+ importCellFormula( rStrm );
+ else
+ aString.convert( xText, maCurrCell.mnXfId );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void OoxSheetDataContext::importCellFormula( RecordInputStream& rStrm )
+{
+ rStrm.skip( 2 );
+ Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY );
+ if( xTokens.is() )
+ {
+ ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress );
+ getFormulaParser().importFormula( aContext, rStrm );
+ }
+}
+
+void OoxSheetDataContext::importRow( RecordInputStream& rStrm )
+{
+ OoxRowData aData;
+
+ sal_uInt16 nHeight, nFlags;
+ rStrm >> maCurrPos.mnRow >> aData.mnXfId >> nHeight >> nFlags;
+
+ // row index is 0-based in OOBIN, but OoxRowData expects 1-based
+ aData.mnFirstRow = aData.mnLastRow = maCurrPos.mnRow + 1;
+ // row height is in twips in OOBIN, convert to points
+ aData.mfHeight = nHeight / 20.0;
+ aData.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 );
+ aData.mbCustomHeight = getFlag( nFlags, OOBIN_ROW_CUSTOMHEIGHT );
+ aData.mbCustomFormat = getFlag( nFlags, OOBIN_ROW_CUSTOMFORMAT );
+ // 'show phonetic' missing in OOBIN (bug in Excel 2007)
+ aData.mbHidden = getFlag( nFlags, OOBIN_ROW_HIDDEN );
+ aData.mbCollapsed = getFlag( nFlags, OOBIN_ROW_COLLAPSED );
+ aData.mbThickTop = getFlag( nFlags, OOBIN_ROW_THICKTOP );
+ aData.mbThickBottom = getFlag( nFlags, OOBIN_ROW_THICKBOTTOM );
+ // set row properties in the current sheet
+ setRowData( aData );
+}
+
+void OoxSheetDataContext::importArray( RecordInputStream& rStrm )
+{
+ BinRange aRange;
+ rStrm >> aRange;
+ CellRangeAddress aArrayRange;
+ Reference< XCellRange > xRange = getCellRange( aRange, &aArrayRange );
+ Reference< XArrayFormulaTokens > xTokens( xRange, UNO_QUERY );
+ if( xRange.is() && xTokens.is() )
+ {
+ rStrm.skip( 1 );
+ ArrayFormulaContext aContext( xTokens, aArrayRange );
+ getFormulaParser().importFormula( aContext, rStrm );
+ }
+}
+
+void OoxSheetDataContext::importSharedFmla( RecordInputStream& rStrm )
+{
+ getSharedFormulas().importSharedFmla( rStrm, maCurrCell.maAddress );
+}
+
+void OoxSheetDataContext::importDataTable( RecordInputStream& rStrm )
+{
+ BinRange aRange;
+ rStrm >> aRange;
+ CellRangeAddress aTableRange;
+ if( getAddressConverter().convertToCellRange( aTableRange, aRange, getSheetIndex(), true ) )
+ {
+ OoxDataTableData aTableData;
+ BinAddress aRef1, aRef2;
+ sal_uInt8 nFlags;
+ rStrm >> aRef1 >> aRef2 >> nFlags;
+ aTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
+ aTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
+ aTableData.mbRowTable = getFlag( nFlags, OOBIN_DATATABLE_ROW );
+ aTableData.mb2dTable = getFlag( nFlags, OOBIN_DATATABLE_2D );
+ aTableData.mbRef1Deleted = getFlag( nFlags, OOBIN_DATATABLE_REF1DEL );
+ aTableData.mbRef2Deleted = getFlag( nFlags, OOBIN_DATATABLE_REF2DEL );
+ setTableOperation( aTableRange, aTableData );
+ }
+}
+
+// ============================================================================
+
+OoxExternalSheetDataContext::OoxExternalSheetDataContext(
+ const OoxWorkbookFragmentBase& rFragment, WorksheetType eSheetType, sal_Int32 nSheet ) :
+ OoxWorksheetContextBase( rFragment, ISegmentProgressBarRef(), eSheetType, nSheet )
+{
+}
+
+// oox.xls.ContextHelper interface --------------------------------------------
+
+bool OoxExternalSheetDataContext::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( sheetData ):
+ return (nElement == XLS_TOKEN( row ));
+ case XLS_TOKEN( row ):
+ return (nElement == XLS_TOKEN( cell ));
+ case XLS_TOKEN( cell ):
+ return (nElement == XLS_TOKEN( v )) && maCurrCell.mxCell.is();
+ }
+ return false;
+}
+
+void OoxExternalSheetDataContext::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( cell ):
+ importCell( rAttribs );
+ break;
+ }
+}
+
+void OoxExternalSheetDataContext::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( v ):
+ maCurrCell.maValueStr = rChars;
+ maCurrCell.mbHasValueStr = true;
+ break;
+
+ case XLS_TOKEN( cell ):
+ if( maCurrCell.mxCell.is() )
+ setOoxCell( maCurrCell, true );
+ break;
+ }
+}
+
+bool OoxExternalSheetDataContext::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_EXTSHEETDATA:
+ return (nRecId == OOBIN_ID_EXTROW);
+ case OOBIN_ID_EXTROW:
+ return (nRecId == OOBIN_ID_EXTCELL_BOOL) ||
+ (nRecId == OOBIN_ID_EXTCELL_DOUBLE) ||
+ (nRecId == OOBIN_ID_EXTCELL_ERROR) ||
+ (nRecId == OOBIN_ID_EXTCELL_STRING);
+ }
+ return false;
+}
+
+void OoxExternalSheetDataContext::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_EXTCELL_BOOL: importExtCellBool( rStrm ); break;
+ case OOBIN_ID_EXTCELL_DOUBLE: importExtCellDouble( rStrm ); break;
+ case OOBIN_ID_EXTCELL_ERROR: importExtCellError( rStrm ); break;
+ case OOBIN_ID_EXTCELL_STRING: importExtCellString( rStrm ); break;
+ case OOBIN_ID_EXTROW: rStrm >> maCurrPos.mnRow; break;
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void OoxExternalSheetDataContext::importCell( const AttributeList& rAttribs )
+{
+ maCurrCell.reset();
+ maCurrCell.mxCell = getCell( rAttribs.getString( XML_r ), &maCurrCell.maAddress );
+ maCurrCell.mnCellType = rAttribs.getToken( XML_t, XML_n );
+}
+
+void OoxExternalSheetDataContext::importCellHeader( RecordInputStream& rStrm )
+{
+ maCurrCell.reset();
+ rStrm >> maCurrPos.mnCol;
+ maCurrCell.mxCell = getCell( maCurrPos, &maCurrCell.maAddress );
+}
+
+void OoxExternalSheetDataContext::importExtCellBool( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ if( maCurrCell.mxCell.is() )
+ setBooleanCell( maCurrCell.mxCell, rStrm.readuInt8() != 0 );
+}
+
+void OoxExternalSheetDataContext::importExtCellDouble( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ if( maCurrCell.mxCell.is() )
+ maCurrCell.mxCell->setValue( rStrm.readDouble() );
+}
+
+void OoxExternalSheetDataContext::importExtCellError( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ if( maCurrCell.mxCell.is() )
+ setErrorCell( maCurrCell.mxCell, rStrm.readuInt8() );
+}
+
+void OoxExternalSheetDataContext::importExtCellString( RecordInputStream& rStrm )
+{
+ importCellHeader( rStrm );
+ if( maCurrCell.mxCell.is() )
+ setStringCell( maCurrCell.mxCell, rStrm.readString(), true );
+}
+
+// ============================================================================
+// ============================================================================
+
+BiffSheetDataContext::BiffSheetDataContext( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper ),
+ mnBiff2XfId( 0 )
+{
+ mnArrayIgnoreSize = (getBiff() == BIFF2) ? 1 : ((getBiff() <= BIFF4) ? 2 : 6);
+ switch( getBiff() )
+ {
+ case BIFF2:
+ mnFormulaIgnoreSize = 9; // double formula result, 1 byte flags
+ mnArrayIgnoreSize = 1; // recalc-always flag
+ break;
+ case BIFF3:
+ case BIFF4:
+ mnFormulaIgnoreSize = 10; // double formula result, 2 byte flags
+ mnArrayIgnoreSize = 2; // 2 byte flags
+ break;
+ case BIFF5:
+ case BIFF8:
+ mnFormulaIgnoreSize = 14; // double formula result, 2 byte flags, 4 bytes nothing
+ mnArrayIgnoreSize = 6; // 2 byte flags, 4 bytes nothing
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+}
+
+void BiffSheetDataContext::importRecord( BiffInputStream& rStrm )
+{
+ sal_uInt16 nRecId = rStrm.getRecId();
+ switch( nRecId )
+ {
+ // records in all BIFF versions
+ case BIFF2_ID_ARRAY: // #i72713#
+ case BIFF3_ID_ARRAY: importArray( rStrm ); break;
+ case BIFF2_ID_BLANK:
+ case BIFF3_ID_BLANK: importBlank( rStrm ); break;
+ case BIFF2_ID_BOOLERR:
+ case BIFF3_ID_BOOLERR: importBoolErr( rStrm ); break;
+ case BIFF2_ID_INTEGER: importInteger( rStrm ); break;
+ case BIFF_ID_IXFE: rStrm >> mnBiff2XfId; break;
+ case BIFF2_ID_LABEL:
+ case BIFF3_ID_LABEL: importLabel( rStrm ); break;
+ case BIFF2_ID_NUMBER:
+ case BIFF3_ID_NUMBER: importNumber( rStrm ); break;
+ case BIFF_ID_RK: importRk( rStrm ); break;
+
+ // BIFF specific records
+ default: switch( getBiff() )
+ {
+ case BIFF2: switch( nRecId )
+ {
+ case BIFF2_ID_DATATABLE: importDataTable( rStrm ); break;
+ case BIFF2_ID_DATATABLE2: importDataTable( rStrm ); break;
+ case BIFF2_ID_FORMULA: importFormula( rStrm ); break;
+ case BIFF2_ID_ROW: importRow( rStrm ); break;
+ }
+ break;
+
+ case BIFF3: switch( nRecId )
+ {
+ case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
+ case BIFF3_ID_FORMULA: importFormula( rStrm ); break;
+ case BIFF3_ID_ROW: importRow( rStrm ); break;
+ }
+ break;
+
+ case BIFF4: switch( nRecId )
+ {
+ case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
+ case BIFF4_ID_FORMULA: importFormula( rStrm ); break;
+ case BIFF3_ID_ROW: importRow( rStrm ); break;
+ }
+ break;
+
+ case BIFF5: switch( nRecId )
+ {
+ case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
+ case BIFF3_ID_FORMULA:
+ case BIFF4_ID_FORMULA:
+ case BIFF5_ID_FORMULA: importFormula( rStrm ); break;
+ case BIFF_ID_MULTBLANK: importMultBlank( rStrm ); break;
+ case BIFF_ID_MULTRK: importMultRk( rStrm ); break;
+ case BIFF3_ID_ROW: importRow( rStrm ); break;
+ case BIFF_ID_RSTRING: importLabel( rStrm ); break;
+ case BIFF_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
+ }
+ break;
+
+ case BIFF8: switch( nRecId )
+ {
+ case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
+ case BIFF3_ID_FORMULA:
+ case BIFF4_ID_FORMULA:
+ case BIFF5_ID_FORMULA: importFormula( rStrm ); break;
+ case BIFF_ID_LABELSST: importLabelSst( rStrm ); break;
+ case BIFF_ID_MULTBLANK: importMultBlank( rStrm ); break;
+ case BIFF_ID_MULTRK: importMultRk( rStrm ); break;
+ case BIFF3_ID_ROW: importRow( rStrm ); break;
+ case BIFF_ID_RSTRING: importLabel( rStrm ); break;
+ case BIFF_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
+ }
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void BiffSheetDataContext::setCurrCell( const BinAddress& rAddr )
+{
+ maCurrCell.reset();
+ maCurrCell.mxCell = getCell( rAddr, &maCurrCell.maAddress );
+}
+
+void BiffSheetDataContext::importXfId( BiffInputStream& rStrm, bool bBiff2 )
+{
+ if( bBiff2 )
+ {
+ sal_uInt8 nBiff2XfId;
+ rStrm >> nBiff2XfId;
+ rStrm.skip( 2 );
+ maCurrCell.mnXfId = nBiff2XfId & BIFF2_XF_MASK;
+ if( maCurrCell.mnXfId == BIFF_XF_EXTENDED_IDS )
+ maCurrCell.mnXfId = mnBiff2XfId;
+ }
+ else
+ {
+ maCurrCell.mnXfId = rStrm.readuInt16();
+ }
+}
+
+void BiffSheetDataContext::importCellHeader( BiffInputStream& rStrm, bool bBiff2 )
+{
+ BinAddress aAddr;
+ rStrm >> aAddr;
+ setCurrCell( aAddr );
+ importXfId( rStrm, bBiff2 );
+}
+
+void BiffSheetDataContext::importBlank( BiffInputStream& rStrm )
+{
+ importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK );
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm )
+{
+ importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BOOLERR );
+ if( maCurrCell.mxCell.is() )
+ {
+ sal_uInt8 nValue, nType;
+ rStrm >> nValue >> nType;
+ switch( nType )
+ {
+ case BIFF_BOOLERR_BOOL:
+ maCurrCell.mnCellType = XML_b;
+ setBooleanCell( maCurrCell.mxCell, nValue != 0 );
+ // #108770# set 'Standard' number format for all Boolean cells
+ maCurrCell.mnNumFmtId = 0;
+ break;
+ case BIFF_BOOLERR_ERROR:
+ maCurrCell.mnCellType = XML_e;
+ setErrorCell( maCurrCell.mxCell, nValue );
+ break;
+ default:
+ OSL_ENSURE( false, "BiffSheetDataContext::importBoolErr - unknown cell type" );
+ }
+ }
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importFormula( BiffInputStream& rStrm )
+{
+ importCellHeader( rStrm, getBiff() == BIFF2 );
+ maCurrCell.mnCellType = XML_n;
+ Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY );
+ if( xTokens.is() )
+ {
+ rStrm.skip( mnFormulaIgnoreSize );
+ ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress );
+ getFormulaParser().importFormula( aContext, rStrm );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importInteger( BiffInputStream& rStrm )
+{
+ importCellHeader( rStrm, true );
+ maCurrCell.mnCellType = XML_n;
+ if( maCurrCell.mxCell.is() )
+ maCurrCell.mxCell->setValue( rStrm.readuInt16() );
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importLabel( BiffInputStream& rStrm )
+{
+ bool bBiff2Xf = rStrm.getRecId() == BIFF2_ID_LABEL;
+ importCellHeader( rStrm, bBiff2Xf );
+ maCurrCell.mnCellType = XML_inlineStr;
+ Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
+ if( xText.is() )
+ {
+ /* the deep secrets of BIFF type and record identifier...
+ record id BIFF XF type String type
+ 0x0004 2-7 3 byte 8-bit length, byte string
+ 0x0004 8 3 byte 16-bit length, unicode string
+ 0x0204 2-7 2 byte 16-bit length, byte string
+ 0x0204 8 2 byte 16-bit length, unicode string */
+
+ RichString aString( *this );
+ if( getBiff() == BIFF8 )
+ {
+ aString.importUniString( rStrm );
+ }
+ else
+ {
+ // #i63105# use text encoding from FONT record
+ rtl_TextEncoding eTextEnc = getTextEncoding();
+ if( const Font* pFont = getStyles().getFontFromCellXf( maCurrCell.mnXfId ).get() )
+ eTextEnc = pFont->getFontEncoding();
+ BiffStringFlags nFlags = bBiff2Xf ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT;
+ setFlag( nFlags, BIFF_STR_EXTRAFONTS, rStrm.getRecId() == BIFF_ID_RSTRING );
+ aString.importByteString( rStrm, eTextEnc, nFlags );
+ }
+ aString.finalizeImport();
+ aString.convert( xText, maCurrCell.mnXfId );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importLabelSst( BiffInputStream& rStrm )
+{
+ importCellHeader( rStrm, false );
+ maCurrCell.mnCellType = XML_s;
+ if( maCurrCell.mxCell.is() )
+ setSharedStringCell( maCurrCell.mxCell, rStrm.readInt32(), maCurrCell.mnXfId );
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importMultBlank( BiffInputStream& rStrm )
+{
+ BinAddress aAddr;
+ for( rStrm >> aAddr; rStrm.getRecLeft() > 2; ++aAddr.mnCol )
+ {
+ setCurrCell( aAddr );
+ importXfId( rStrm, false );
+ setCellFormat( maCurrCell );
+ }
+}
+
+void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm )
+{
+ BinAddress aAddr;
+ for( rStrm >> aAddr; rStrm.getRecLeft() > 2; ++aAddr.mnCol )
+ {
+ setCurrCell( aAddr );
+ maCurrCell.mnCellType = XML_n;
+ importXfId( rStrm, false );
+ sal_Int32 nRkValue = rStrm.readInt32();
+ if( maCurrCell.mxCell.is() )
+ maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( nRkValue ) );
+ setCellFormat( maCurrCell );
+ }
+}
+
+void BiffSheetDataContext::importNumber( BiffInputStream& rStrm )
+{
+ importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER );
+ maCurrCell.mnCellType = XML_n;
+ if( maCurrCell.mxCell.is() )
+ maCurrCell.mxCell->setValue( rStrm.readDouble() );
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importRk( BiffInputStream& rStrm )
+{
+ importCellHeader( rStrm, false );
+ maCurrCell.mnCellType = XML_n;
+ if( maCurrCell.mxCell.is() )
+ maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
+ setCellFormat( maCurrCell );
+}
+
+void BiffSheetDataContext::importRow( BiffInputStream& rStrm )
+{
+ OoxRowData aData;
+
+ sal_uInt16 nRow, nHeight;
+ rStrm >> nRow;
+ rStrm.skip( 4 );
+ rStrm >> nHeight;
+ if( getBiff() == BIFF2 )
+ {
+ aData.mbCustomFormat = rStrm.skip( 2 ).readuInt8() == BIFF2_ROW_CUSTOMFORMAT;
+ if( aData.mbCustomFormat )
+ aData.mnXfId = rStrm.skip( 5 ).readuInt16();
+ }
+ else
+ {
+ sal_uInt32 nFlags = rStrm.skip( 4 ).readuInt32();
+ aData.mnXfId = extractValue< sal_Int32 >( nFlags, 16, 12 );
+ aData.mnLevel = extractValue< sal_Int32 >( nFlags, 0, 3 );
+ aData.mbCustomFormat = getFlag( nFlags, BIFF_ROW_CUSTOMFORMAT );
+ aData.mbCustomHeight = getFlag( nFlags, BIFF_ROW_CUSTOMHEIGHT );
+ aData.mbShowPhonetic = getFlag( nFlags, BIFF_ROW_SHOWPHONETIC );
+ aData.mbHidden = getFlag( nFlags, BIFF_ROW_HIDDEN );
+ aData.mbCollapsed = getFlag( nFlags, BIFF_ROW_COLLAPSED );
+ aData.mbThickTop = getFlag( nFlags, BIFF_ROW_THICKTOP );
+ aData.mbThickBottom = getFlag( nFlags, BIFF_ROW_THICKBOTTOM );
+ }
+
+ // row index is 0-based in BIFF, but OoxRowData expects 1-based
+ aData.mnFirstRow = aData.mnLastRow = nRow + 1;
+ // row height is in twips in BIFF, convert to points
+ aData.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0;
+ // set row properties in the current sheet
+ setRowData( aData );
+}
+
+void BiffSheetDataContext::importArray( BiffInputStream& rStrm )
+{
+ BinRange aRange;
+ aRange.read( rStrm, false ); // columns always 8-bit
+ CellRangeAddress aArrayRange;
+ Reference< XCellRange > xRange = getCellRange( aRange, &aArrayRange );
+ Reference< XArrayFormulaTokens > xTokens( xRange, UNO_QUERY );
+ if( xRange.is() && xTokens.is() )
+ {
+ rStrm.skip( mnArrayIgnoreSize );
+ ArrayFormulaContext aContext( xTokens, aArrayRange );
+ getFormulaParser().importFormula( aContext, rStrm );
+ }
+}
+
+void BiffSheetDataContext::importSharedFmla( BiffInputStream& rStrm )
+{
+ getSharedFormulas().importSharedFmla( rStrm, maCurrCell.maAddress );
+}
+
+void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm )
+{
+ BinRange aRange;
+ aRange.read( rStrm, false ); // columns always 8-bit
+ CellRangeAddress aTableRange;
+ if( getAddressConverter().convertToCellRange( aTableRange, aRange, getSheetIndex(), true ) )
+ {
+ OoxDataTableData aTableData;
+ BinAddress aRef1, aRef2;
+ switch( rStrm.getRecId() )
+ {
+ case BIFF2_ID_DATATABLE:
+ rStrm.skip( 1 );
+ aTableData.mbRowTable = rStrm.readuInt8() != 0;
+ aTableData.mb2dTable = false;
+ rStrm >> aRef1;
+ break;
+ case BIFF2_ID_DATATABLE2:
+ rStrm.skip( 2 );
+ aTableData.mb2dTable = true;
+ rStrm >> aRef1 >> aRef2;
+ break;
+ case BIFF3_ID_DATATABLE:
+ {
+ sal_uInt16 nFlags;
+ rStrm >> nFlags >> aRef1 >> aRef2;
+ aTableData.mbRowTable = getFlag( nFlags, BIFF_DATATABLE_ROW );
+ aTableData.mb2dTable = getFlag( nFlags, BIFF_DATATABLE_2D );
+ aTableData.mbRef1Deleted = getFlag( nFlags, BIFF_DATATABLE_REF1DEL );
+ aTableData.mbRef2Deleted = getFlag( nFlags, BIFF_DATATABLE_REF2DEL );
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "BiffSheetDataContext::importDataTable - unknown record id" );
+ }
+ aTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
+ aTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
+ setTableOperation( aTableRange, aTableData );
+ }
+}
+
+// ============================================================================
+
+BiffExternalSheetDataContext::BiffExternalSheetDataContext(
+ const WorkbookHelper& rHelper, WorksheetType eSheetType, sal_Int32 nSheet ) :
+ WorksheetHelperRoot( rHelper, ISegmentProgressBarRef(), eSheetType, nSheet )
+{
+}
+
+void BiffExternalSheetDataContext::importCrn( BiffInputStream& rStrm )
+{
+ sal_uInt8 nCol2, nCol1;
+ sal_uInt16 nRow;
+ rStrm >> nCol2 >> nCol1 >> nRow;
+ bool bLoop = true;
+ for( BinAddress aAddr( nCol1, nRow ); bLoop && rStrm.isValid() && (aAddr.mnCol <= nCol2); ++aAddr.mnCol )
+ {
+ Reference< XCell > xCell = getCell( aAddr );
+ bLoop = xCell.is();
+ if( bLoop ) switch( rStrm.readuInt8() )
+ {
+ case BIFF_DATATYPE_EMPTY:
+ rStrm.skip( 8 );
+ setEmptyStringCell( xCell );
+ break;
+ case BIFF_DATATYPE_DOUBLE:
+ xCell->setValue( rStrm.readDouble() );
+ break;
+ case BIFF_DATATYPE_STRING:
+ {
+ OUString aText = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteString( false, getTextEncoding() );
+ setStringCell( xCell, aText, true );
+ }
+ break;
+ case BIFF_DATATYPE_BOOL:
+ setBooleanCell( xCell, rStrm.readuInt8() != 0 );
+ rStrm.skip( 7 );
+ break;
+ case BIFF_DATATYPE_ERROR:
+ setErrorCell( xCell, rStrm.readuInt8() );
+ rStrm.skip( 7 );
+ break;
+ default:
+ OSL_ENSURE( false, "BiffExternalSheetDataContext::importCrn - unknown data type" );
+ bLoop = false;
+ }
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx
new file mode 100644
index 000000000000..66b1ea9e8035
--- /dev/null
+++ b/oox/source/xls/stylesbuffer.cxx
@@ -0,0 +1,3214 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: stylesbuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/stylesbuffer.hxx"
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XFont2.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <rtl/tencinfo.h>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/condformatbuffer.hxx"
+#include "oox/xls/ooxtokens.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+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;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+// OOXML constants ------------------------------------------------------------
+
+// OOX predefined color indexes (also used in BIFF3-BIFF8)
+const sal_Int32 OOX_COLOR_USEROFFSET = 0; /// First user defined color in palette (OOX).
+const sal_Int32 BIFF_COLOR_USEROFFSET = 8; /// First user defined color in palette (BIFF).
+
+// OOX font family (also used in BIFF)
+const sal_Int32 OOX_FONTFAMILY_NONE = 0;
+const sal_Int32 OOX_FONTFAMILY_ROMAN = 1;
+const sal_Int32 OOX_FONTFAMILY_SWISS = 2;
+const sal_Int32 OOX_FONTFAMILY_MODERN = 3;
+const sal_Int32 OOX_FONTFAMILY_SCRIPT = 4;
+const sal_Int32 OOX_FONTFAMILY_DECORATIVE = 5;
+
+// OOX font charset (also used in BIFF)
+const sal_Int32 OOX_FONTCHARSET_UNUSED = -1;
+const sal_Int32 OOX_FONTCHARSET_ANSI = 0;
+
+// OOX cell text direction (also used in BIFF)
+const sal_Int32 OOX_XF_TEXTDIR_CONTEXT = 0;
+const sal_Int32 OOX_XF_TEXTDIR_LTR = 1;
+const sal_Int32 OOX_XF_TEXTDIR_RTL = 2;
+
+// OOX cell rotation (also used in BIFF)
+const sal_Int32 OOX_XF_ROTATION_NONE = 0;
+const sal_Int32 OOX_XF_ROTATION_90CCW = 90;
+const sal_Int32 OOX_XF_ROTATION_90CW = 180;
+const sal_Int32 OOX_XF_ROTATION_STACKED = 255;
+
+// OOX cell indentation
+const sal_Int32 OOX_XF_INDENT_NONE = 0;
+
+// OOX built-in cell styles (also used in BIFF)
+const sal_Int32 OOX_STYLE_NORMAL = 0; /// Default cell style.
+const sal_Int32 OOX_STYLE_ROWLEVEL = 1; /// RowLevel_x cell style.
+const sal_Int32 OOX_STYLE_COLLEVEL = 2; /// ColLevel_x cell style.
+
+const sal_Int32 OOX_STYLE_LEVELCOUNT = 7; /// Number of outline level styles.
+
+// OOBIN constants ------------------------------------------------------------
+
+// OOBIN color types
+const sal_uInt8 OOBIN_COLOR_AUTO = 1;
+const sal_uInt8 OOBIN_COLOR_INDEXED = 3;
+const sal_uInt8 OOBIN_COLOR_RGB = 5;
+const sal_uInt8 OOBIN_COLOR_THEME = 7;
+
+// OOBIN diagonal borders
+const sal_uInt8 OOBIN_BORDER_DIAG_TLBR = 0x01; /// Top-left to bottom-right.
+const sal_uInt8 OOBIN_BORDER_DIAG_BLTR = 0x02; /// Bottom-left to top-right.
+
+// OOBIN gradient fill
+const sal_Int32 OOBIN_FILL_GRADIENT = 40;
+
+// OOBIN XF flags
+const sal_uInt32 OOBIN_XF_WRAPTEXT = 0x00400000;
+const sal_uInt32 OOBIN_XF_JUSTLASTLINE = 0x00800000;
+const sal_uInt32 OOBIN_XF_SHRINK = 0x01000000;
+const sal_uInt32 OOBIN_XF_LOCKED = 0x10000000;
+const sal_uInt32 OOBIN_XF_HIDDEN = 0x20000000;
+
+// OOBIN XF attribute used flags
+const sal_uInt16 OOBIN_XF_NUMFMT_USED = 0x0001;
+const sal_uInt16 OOBIN_XF_FONT_USED = 0x0002;
+const sal_uInt16 OOBIN_XF_ALIGN_USED = 0x0004;
+const sal_uInt16 OOBIN_XF_BORDER_USED = 0x0008;
+const sal_uInt16 OOBIN_XF_AREA_USED = 0x0010;
+const sal_uInt16 OOBIN_XF_PROT_USED = 0x0020;
+
+// OOBIN DXF constants
+const sal_uInt16 OOBIN_DXF_FILL_PATTERN = 0;
+const sal_uInt16 OOBIN_DXF_FILL_FGCOLOR = 1;
+const sal_uInt16 OOBIN_DXF_FILL_BGCOLOR = 2;
+const sal_uInt16 OOBIN_DXF_FILL_GRADIENT = 3;
+const sal_uInt16 OOBIN_DXF_FILL_STOP = 4;
+const sal_uInt16 OOBIN_DXF_FONT_COLOR = 5;
+const sal_uInt16 OOBIN_DXF_BORDER_TOP = 6;
+const sal_uInt16 OOBIN_DXF_BORDER_BOTTOM = 7;
+const sal_uInt16 OOBIN_DXF_BORDER_LEFT = 8;
+const sal_uInt16 OOBIN_DXF_BORDER_RIGHT = 9;
+const sal_uInt16 OOBIN_DXF_BORDER_DIAG = 10;
+const sal_uInt16 OOBIN_DXF_BORDER_VERT = 11;
+const sal_uInt16 OOBIN_DXF_BORDER_HOR = 12;
+const sal_uInt16 OOBIN_DXF_BORDER_DIAGUP = 13;
+const sal_uInt16 OOBIN_DXF_BORDER_DIAGDOWN = 14;
+const sal_uInt16 OOBIN_DXF_FONT_NAME = 24;
+const sal_uInt16 OOBIN_DXF_FONT_WEIGHT = 25;
+const sal_uInt16 OOBIN_DXF_FONT_UNDERLINE = 26;
+const sal_uInt16 OOBIN_DXF_FONT_ESCAPEMENT = 27;
+const sal_uInt16 OOBIN_DXF_FONT_ITALIC = 28;
+const sal_uInt16 OOBIN_DXF_FONT_STRIKE = 29;
+const sal_uInt16 OOBIN_DXF_FONT_OUTLINE = 30;
+const sal_uInt16 OOBIN_DXF_FONT_SHADOW = 31;
+const sal_uInt16 OOBIN_DXF_FONT_CONDENSE = 32;
+const sal_uInt16 OOBIN_DXF_FONT_EXTEND = 33;
+const sal_uInt16 OOBIN_DXF_FONT_HEIGHT = 36;
+const sal_uInt16 OOBIN_DXF_FONT_SCHEME = 37;
+const sal_uInt16 OOBIN_DXF_NUMFMT_CODE = 38;
+const sal_uInt16 OOBIN_DXF_NUMFMT_ID = 41;
+
+// OOBIN CELLSTYLE flags
+const sal_uInt16 OOBIN_CELLSTYLE_BUILTIN = 0x0001;
+const sal_uInt16 OOBIN_CELLSTYLE_HIDDEN = 0x0002;
+const sal_uInt16 OOBIN_CELLSTYLE_CUSTOM = 0x0004;
+
+// OOBIN and BIFF constants ---------------------------------------------------
+
+// BIFF predefined color indexes
+const sal_uInt16 BIFF2_COLOR_BLACK = 0; /// Black (text) in BIFF2.
+const sal_uInt16 BIFF2_COLOR_WHITE = 1; /// White (background) in BIFF2.
+
+// BIFF font flags, also used in OOBIN
+const sal_uInt16 BIFF_FONTFLAG_BOLD = 0x0001;
+const sal_uInt16 BIFF_FONTFLAG_ITALIC = 0x0002;
+const sal_uInt16 BIFF_FONTFLAG_UNDERLINE = 0x0004;
+const sal_uInt16 BIFF_FONTFLAG_STRIKEOUT = 0x0008;
+const sal_uInt16 BIFF_FONTFLAG_OUTLINE = 0x0010;
+const sal_uInt16 BIFF_FONTFLAG_SHADOW = 0x0020;
+const sal_uInt16 BIFF_FONTFLAG_CONDENSE = 0x0040;
+
+// BIFF font weight
+const sal_uInt16 BIFF_FONTWEIGHT_BOLD = 450;
+
+// BIFF font underline, also used in OOBIN
+const sal_uInt8 BIFF_FONTUNDERL_NONE = 0;
+const sal_uInt8 BIFF_FONTUNDERL_SINGLE = 1;
+const sal_uInt8 BIFF_FONTUNDERL_DOUBLE = 2;
+const sal_uInt8 BIFF_FONTUNDERL_SINGLE_ACC = 33;
+const sal_uInt8 BIFF_FONTUNDERL_DOUBLE_ACC = 34;
+
+// BIFF XF flags
+const sal_uInt16 BIFF_XF_LOCKED = 0x0001;
+const sal_uInt16 BIFF_XF_HIDDEN = 0x0002;
+const sal_uInt16 BIFF_XF_STYLE = 0x0004;
+const sal_uInt16 BIFF_XF_STYLEPARENT = 0x0FFF; /// Syles don't have a parent.
+const sal_uInt16 BIFF_XF_WRAPTEXT = 0x0008; /// Automatic line break.
+const sal_uInt16 BIFF_XF_JUSTLASTLINE = 0x0080;
+const sal_uInt16 BIFF_XF_SHRINK = 0x0010; /// Shrink to fit into cell.
+const sal_uInt16 BIFF_XF_MERGE = 0x0020;
+
+// BIFF XF attribute used flags
+const sal_uInt8 BIFF_XF_NUMFMT_USED = 0x01;
+const sal_uInt8 BIFF_XF_FONT_USED = 0x02;
+const sal_uInt8 BIFF_XF_ALIGN_USED = 0x04;
+const sal_uInt8 BIFF_XF_BORDER_USED = 0x08;
+const sal_uInt8 BIFF_XF_AREA_USED = 0x10;
+const sal_uInt8 BIFF_XF_PROT_USED = 0x20;
+
+// BIFF XF text orientation
+const sal_uInt8 BIFF_XF_ORIENT_NONE = 0;
+const sal_uInt8 BIFF_XF_ORIENT_STACKED = 1; /// Stacked top to bottom.
+const sal_uInt8 BIFF_XF_ORIENT_90CCW = 2; /// 90 degr. counterclockwise.
+const sal_uInt8 BIFF_XF_ORIENT_90CW = 3; /// 90 degr. clockwise.
+
+// BIFF XF line styles
+const sal_uInt8 BIFF_LINE_NONE = 0;
+const sal_uInt8 BIFF_LINE_THIN = 1;
+
+// BIFF XF patterns
+const sal_uInt8 BIFF_PATT_NONE = 0;
+const sal_uInt8 BIFF_PATT_125 = 17;
+
+// BIFF2 XF flags
+const sal_uInt8 BIFF2_XF_VALFMT_MASK = 0x3F;
+const sal_uInt8 BIFF2_XF_LOCKED = 0x40;
+const sal_uInt8 BIFF2_XF_HIDDEN = 0x80;
+const sal_uInt8 BIFF2_XF_LEFTLINE = 0x08;
+const sal_uInt8 BIFF2_XF_RIGHTLINE = 0x10;
+const sal_uInt8 BIFF2_XF_TOPLINE = 0x20;
+const sal_uInt8 BIFF2_XF_BOTTOMLINE = 0x40;
+const sal_uInt8 BIFF2_XF_BACKGROUND = 0x80;
+
+// BIFF8 diagonal borders
+const sal_uInt32 BIFF_XF_DIAG_TLBR = 0x40000000; /// Top-left to bottom-right.
+const sal_uInt32 BIFF_XF_DIAG_BLTR = 0x80000000; /// Bottom-left to top-right.
+
+// BIFF STYLE flags
+const sal_uInt16 BIFF_STYLE_BUILTIN = 0x8000;
+const sal_uInt16 BIFF_STYLE_XFMASK = 0x0FFF;
+
+// BIFF conditional formatting
+const sal_uInt32 BIFF_CFRULE_BORDER_LEFT = 0x00000400;
+const sal_uInt32 BIFF_CFRULE_BORDER_RIGHT = 0x00000800;
+const sal_uInt32 BIFF_CFRULE_BORDER_TOP = 0x00001000;
+const sal_uInt32 BIFF_CFRULE_BORDER_BOTTOM = 0x00002000;
+const sal_uInt32 BIFF_CFRULE_FILL_PATTERN = 0x00010000;
+const sal_uInt32 BIFF_CFRULE_FILL_PATTCOLOR = 0x00020000;
+const sal_uInt32 BIFF_CFRULE_FILL_FILLCOLOR = 0x00040000;
+const sal_uInt32 BIFF_CFRULE_FONTBLOCK = 0x04000000;
+const sal_uInt32 BIFF_CFRULE_ALIGNBLOCK = 0x08000000;
+const sal_uInt32 BIFF_CFRULE_BORDERBLOCK = 0x10000000;
+const sal_uInt32 BIFF_CFRULE_FILLBLOCK = 0x20000000;
+const sal_uInt32 BIFF_CFRULE_PROTBLOCK = 0x40000000;
+
+const sal_uInt32 BIFF_CFRULE_FONT_STYLE = 0x00000002; /// Font posture or weight modified?
+const sal_uInt32 BIFF_CFRULE_FONT_OUTLINE = 0x00000008; /// Font outline modified?
+const sal_uInt32 BIFF_CFRULE_FONT_SHADOW = 0x00000010; /// Font shadow modified?
+const sal_uInt32 BIFF_CFRULE_FONT_STRIKEOUT = 0x00000080; /// Font cancellation modified?
+const sal_uInt32 BIFF_CFRULE_FONT_UNDERL = 0x00000001; /// Font underline type modified?
+const sal_uInt32 BIFF_CFRULE_FONT_ESCAPEM = 0x00000001; /// Font escapement type modified?
+
+// ----------------------------------------------------------------------------
+
+sal_Int32 lclGetRgbColor( sal_uInt8 nR, sal_uInt8 nG, sal_uInt8 nB, sal_uInt8 nA )
+{
+ sal_Int32 nValue = nA;
+ nValue <<= 8;
+ nValue |= nR;
+ nValue <<= 8;
+ nValue |= nG;
+ nValue <<= 8;
+ nValue |= nB;
+ return nValue;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+OoxColor::OoxColor() :
+ mfTint( 0.0 ),
+ mnType( XML_auto ),
+ mnValue( 0 )
+{
+}
+
+OoxColor::OoxColor( sal_Int32 nType, sal_Int32 nValue, double fTint ) :
+ mfTint( fTint ),
+ mnType( nType ),
+ mnValue( nValue )
+{
+}
+
+bool OoxColor::isAuto() const
+{
+ return mnType == XML_auto;
+}
+
+void OoxColor::set( sal_Int32 nType, sal_Int32 nValue, double fTint )
+{
+ mfTint = fTint;
+ mnType = nType;
+ mnValue = nValue;
+}
+
+void OoxColor::importColor( const AttributeList& rAttribs )
+{
+ mfTint = rAttribs.getDouble( XML_tint, 0.0 );
+ if( rAttribs.getBool( XML_auto, false ) )
+ {
+ mnType = XML_auto;
+ }
+ else if( rAttribs.hasAttribute( XML_rgb ) )
+ {
+ mnType = XML_rgb;
+ mnValue = rAttribs.getHex( XML_rgb, API_RGB_TRANSPARENT );
+ }
+ else if( rAttribs.hasAttribute( XML_theme ) )
+ {
+ mnType = XML_theme;
+ mnValue = rAttribs.getInteger( XML_theme, -1 );
+ }
+ else if( rAttribs.hasAttribute( XML_indexed ) )
+ {
+ mnType = XML_indexed;
+ mnValue = rAttribs.getInteger( XML_indexed, -1 );
+ }
+ else
+ {
+ mnType = XML_auto;
+ OSL_ENSURE( false, "OoxColor::importColor - unknown color type" );
+ }
+}
+
+void OoxColor::importColor( RecordInputStream& rStrm )
+{
+ switch( rStrm.readuInt8() )
+ {
+ case OOBIN_COLOR_AUTO:
+ mnType = XML_auto;
+ mfTint = 0.0;
+ rStrm.skip( 7 );
+ break;
+ case OOBIN_COLOR_INDEXED:
+ mnType = XML_indexed;
+ mnValue = rStrm.readuInt8();
+ mfTint = 0.0;
+ rStrm.skip( 6 );
+ break;
+ case OOBIN_COLOR_RGB:
+ rStrm.skip( 3 );
+ importColorRgb( rStrm );
+ break;
+ case OOBIN_COLOR_THEME:
+ mnType = XML_theme;
+ mnValue = rStrm.readuInt8();
+ // scale tint from signed 16-bit to double range -1.0 ... 1.0
+ mfTint = static_cast< double >( rStrm.readInt16() ) / 0x7FFF;
+ rStrm.skip( 4 );
+ break;
+ default:
+ OSL_ENSURE( false, "OoxColor::importColor - unknown color type" );
+ mnType = XML_auto;
+ mfTint = 0.0;
+ rStrm.skip( 7 );
+ }
+}
+
+void OoxColor::importColorId( RecordInputStream& rStrm )
+{
+ mfTint = 0.0;
+ mnType = XML_indexed;
+ rStrm >> mnValue;
+}
+
+void OoxColor::importColorRgb( RecordInputStream& rStrm )
+{
+ mfTint = 0.0;
+ mnType = XML_rgb;
+ sal_uInt8 nR, nG, nB, nA;
+ rStrm >> nR >> nG >> nB >> nA;
+ mnValue = lclGetRgbColor( nR, nG, nB, nA );
+}
+
+void OoxColor::importColorId( BiffInputStream& rStrm, bool b16Bit )
+{
+ mfTint = 0.0;
+ mnType = XML_indexed;
+ mnValue = b16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
+}
+
+void OoxColor::importColorRgb( BiffInputStream& rStrm )
+{
+ mfTint = 0.0;
+ mnType = XML_rgb;
+ sal_uInt8 nR, nG, nB, nA;
+ rStrm >> nR >> nG >> nB >> nA;
+ mnValue = lclGetRgbColor( nR, nG, nB, nA );
+}
+
+RecordInputStream& operator>>( RecordInputStream& rStrm, OoxColor& orColor )
+{
+ orColor.importColor( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+namespace {
+
+/** Standard EGA colors, bright. */
+#define PALETTE_EGA_COLORS_LIGHT \
+ 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
+/** Standard EGA colors, dark. */
+#define PALETTE_EGA_COLORS_DARK \
+ 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080
+
+/** Default color table for BIFF2. */
+static const sal_Int32 spnDefColors2[] =
+{
+/* 0 */ PALETTE_EGA_COLORS_LIGHT
+};
+
+/** Default color table for BIFF3/BIFF4. */
+static const sal_Int32 spnDefColors3[] =
+{
+/* 0 */ PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ PALETTE_EGA_COLORS_DARK
+};
+
+/** Default color table for BIFF5. */
+static const sal_Int32 spnDefColors5[] =
+{
+/* 0 */ PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ PALETTE_EGA_COLORS_DARK,
+/* 24 */ 0x8080FF, 0x802060, 0xFFFFC0, 0xA0E0E0, 0x600080, 0xFF8080, 0x0080C0, 0xC0C0FF,
+/* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
+/* 40 */ 0x00CFFF, 0x69FFFF, 0xE0FFE0, 0xFFFF80, 0xA6CAF0, 0xDD9CB3, 0xB38FEE, 0xE3E3E3,
+/* 48 */ 0x2A6FF9, 0x3FB8CD, 0x488436, 0x958C41, 0x8E5E42, 0xA0627A, 0x624FAC, 0x969696,
+/* 56 */ 0x1D2FBE, 0x286676, 0x004500, 0x453E01, 0x6A2813, 0x85396A, 0x4A3285, 0x424242
+};
+
+/** Default color table for BIFF8/OOX. */
+static const sal_Int32 spnDefColors8[] =
+{
+/* 0 */ PALETTE_EGA_COLORS_LIGHT,
+/* 8 */ PALETTE_EGA_COLORS_LIGHT,
+/* 16 */ PALETTE_EGA_COLORS_DARK,
+/* 24 */ 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF,
+/* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
+/* 40 */ 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99,
+/* 48 */ 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696,
+/* 56 */ 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333
+};
+
+#undef PALETTE_EGA_COLORS_LIGHT
+#undef PALETTE_EGA_COLORS_DARK
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ColorPalette::ColorPalette( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnWindowColor( ThemeBuffer::getSystemWindowColor() ),
+ mnWinTextColor( ThemeBuffer::getSystemWindowTextColor() )
+{
+ // default colors
+ switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) );
+ mnAppendIndex = OOX_COLOR_USEROFFSET;
+ break;
+ case FILTER_BIFF:
+ switch( getBiff() )
+ {
+ case BIFF2: maColors.insert( maColors.begin(), spnDefColors2, STATIC_ARRAY_END( spnDefColors2 ) ); break;
+ case BIFF3:
+ case BIFF4: maColors.insert( maColors.begin(), spnDefColors3, STATIC_ARRAY_END( spnDefColors3 ) ); break;
+ case BIFF5: maColors.insert( maColors.begin(), spnDefColors5, STATIC_ARRAY_END( spnDefColors5 ) ); break;
+ case BIFF8: maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) ); break;
+ case BIFF_UNKNOWN: break;
+ }
+ mnAppendIndex = BIFF_COLOR_USEROFFSET;
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+}
+
+void ColorPalette::importPaletteColor( const AttributeList& rAttribs )
+{
+ appendColor( rAttribs.getHex( XML_rgb, API_RGB_TRANSPARENT ) );
+}
+
+void ColorPalette::importPaletteColor( RecordInputStream& rStrm )
+{
+ OoxColor aColor;
+ aColor.importColorRgb( rStrm );
+ appendColor( aColor.mnValue );
+}
+
+void ColorPalette::importPalette( BiffInputStream& rStrm )
+{
+ sal_uInt16 nCount;
+ rStrm >> nCount;
+ OSL_ENSURE( rStrm.getRecLeft() == static_cast< sal_uInt32 >( 4 * nCount ),
+ "ColorPalette::importPalette - wrong palette size" );
+
+ // fill palette from BIFF_COLOR_USEROFFSET
+ mnAppendIndex = BIFF_COLOR_USEROFFSET;
+ OoxColor aColor;
+ for( sal_uInt16 nIndex = 0; rStrm.isValid() && (nIndex < nCount); ++nIndex )
+ {
+ aColor.importColorRgb( rStrm );
+ appendColor( aColor.mnValue );
+ }
+}
+
+sal_Int32 ColorPalette::getColor( sal_Int32 nIndex ) const
+{
+ sal_Int32 nColor = API_RGB_TRANSPARENT;
+ if( (0 <= nIndex) && (static_cast< size_t >( nIndex ) < maColors.size()) )
+ {
+ nColor = maColors[ nIndex ];
+ }
+ else switch( nIndex )
+ {
+ case OOX_COLOR_WINDOWTEXT3:
+ case OOX_COLOR_WINDOWTEXT:
+ case OOX_COLOR_CHWINDOWTEXT: nColor = mnWinTextColor; break;
+ case OOX_COLOR_WINDOWBACK3:
+ case OOX_COLOR_WINDOWBACK:
+ case OOX_COLOR_CHWINDOWBACK: nColor = mnWindowColor; break;
+// case OOX_COLOR_BUTTONBACK:
+// case OOX_COLOR_CHBORDERAUTO:
+// case OOX_COLOR_NOTEBACK:
+// case OOX_COLOR_NOTETEXT:
+ case OOX_COLOR_FONTAUTO: nColor = API_RGB_TRANSPARENT; break;
+ default:
+ OSL_ENSURE( false, "ColorPalette::getColor - unknown color index" );
+ }
+ return nColor;
+}
+
+void ColorPalette::appendColor( sal_Int32 nRGBValue )
+{
+ if( mnAppendIndex < maColors.size() )
+ maColors[ mnAppendIndex ] = nRGBValue;
+ else
+ maColors.push_back( nRGBValue );
+ ++mnAppendIndex;
+}
+
+// ============================================================================
+
+OoxFontData::OoxFontData() :
+ mnScheme( XML_none ),
+ mnFamily( OOX_FONTFAMILY_NONE ),
+ mnCharSet( OOX_FONTCHARSET_ANSI ),
+ mfHeight( 0.0 ),
+ mnUnderline( XML_none ),
+ mnEscapement( XML_baseline ),
+ mbBold( false ),
+ mbItalic( false ),
+ mbStrikeout( false ),
+ mbOutline( false ),
+ mbShadow( false )
+{
+}
+
+void OoxFontData::setBinScheme( sal_uInt8 nScheme )
+{
+ static const sal_Int32 spnSchemes[] = { XML_none, XML_major, XML_minor };
+ mnScheme = STATIC_ARRAY_SELECT( spnSchemes, nScheme, XML_none );
+}
+
+void OoxFontData::setBiffHeight( sal_uInt16 nHeight )
+{
+ mfHeight = nHeight / 20.0; // convert twips to points
+}
+
+void OoxFontData::setBiffWeight( sal_uInt16 nWeight )
+{
+ mbBold = nWeight >= BIFF_FONTWEIGHT_BOLD;
+}
+
+void OoxFontData::setBiffUnderline( sal_uInt16 nUnderline )
+{
+ switch( nUnderline )
+ {
+ case BIFF_FONTUNDERL_NONE: mnUnderline = XML_none; break;
+ case BIFF_FONTUNDERL_SINGLE: mnUnderline = XML_single; break;
+ case BIFF_FONTUNDERL_DOUBLE: mnUnderline = XML_double; break;
+ case BIFF_FONTUNDERL_SINGLE_ACC: mnUnderline = XML_singleAccounting; break;
+ case BIFF_FONTUNDERL_DOUBLE_ACC: mnUnderline = XML_doubleAccounting; break;
+ default: mnUnderline = XML_none;
+ }
+}
+
+void OoxFontData::setBiffEscapement( sal_uInt16 nEscapement )
+{
+ static const sal_Int32 spnEscapes[] = { XML_baseline, XML_superscript, XML_subscript };
+ mnEscapement = STATIC_ARRAY_SELECT( spnEscapes, nEscapement, XML_baseline );
+}
+
+// ============================================================================
+
+Font::Font( const WorkbookHelper& rHelper, bool bDxf ) :
+ WorkbookHelper( rHelper ),
+ maOoxData( rHelper.getTheme().getDefaultFontData() ),
+ maUsedFlags( !bDxf ),
+ mbDxf( bDxf )
+{
+}
+
+Font::Font( const WorkbookHelper& rHelper, const OoxFontData& rFontData ) :
+ WorkbookHelper( rHelper ),
+ maOoxData( rFontData ),
+ maUsedFlags( true ),
+ mbDxf( false )
+{
+}
+
+bool Font::isSupportedContext( sal_Int32 nElement, sal_Int32 nParentContext )
+{
+ switch( nParentContext )
+ {
+ case XLS_TOKEN( font ):
+ return (nElement == XLS_TOKEN( name )) ||
+ (nElement == XLS_TOKEN( scheme )) ||
+ (nElement == XLS_TOKEN( charset )) ||
+ (nElement == XLS_TOKEN( family )) ||
+ (nElement == XLS_TOKEN( sz )) ||
+ (nElement == XLS_TOKEN( color )) ||
+ (nElement == XLS_TOKEN( u )) ||
+ (nElement == XLS_TOKEN( vertAlign )) ||
+ (nElement == XLS_TOKEN( b )) ||
+ (nElement == XLS_TOKEN( i )) ||
+ (nElement == XLS_TOKEN( outline )) ||
+ (nElement == XLS_TOKEN( shadow )) ||
+ (nElement == XLS_TOKEN( strike ));
+
+ case XLS_TOKEN( rPr ):
+ return (nElement == XLS_TOKEN( rFont )) ||
+ (nElement == XLS_TOKEN( scheme )) ||
+ (nElement == XLS_TOKEN( charset )) ||
+ (nElement == XLS_TOKEN( family )) ||
+ (nElement == XLS_TOKEN( sz )) ||
+ (nElement == XLS_TOKEN( color )) ||
+ (nElement == XLS_TOKEN( u )) ||
+ (nElement == XLS_TOKEN( vertAlign )) ||
+ (nElement == XLS_TOKEN( b )) ||
+ (nElement == XLS_TOKEN( i )) ||
+ (nElement == XLS_TOKEN( outline )) ||
+ (nElement == XLS_TOKEN( shadow )) ||
+ (nElement == XLS_TOKEN( strike )) ||
+ (nElement == XLS_TOKEN( vertAlign ));
+ }
+ return false;
+}
+
+void Font::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ const OoxFontData& rDefFontData = getTheme().getDefaultFontData();
+ switch( nElement )
+ {
+ case XLS_TOKEN( name ):
+ case XLS_TOKEN( rFont ):
+ if( rAttribs.hasAttribute( XML_val ) )
+ {
+ maOoxData.maName = rAttribs.getString( XML_val );
+ maUsedFlags.mbNameUsed = true;
+ }
+ break;
+ case XLS_TOKEN( scheme ):
+ maOoxData.mnScheme = rAttribs.getToken( XML_val, rDefFontData.mnScheme );
+ break;
+ case XLS_TOKEN( family ):
+ maOoxData.mnFamily = rAttribs.getInteger( XML_val, rDefFontData.mnFamily );
+ break;
+ case XLS_TOKEN( charset ):
+ maOoxData.mnCharSet = rAttribs.getInteger( XML_val, rDefFontData.mnCharSet );
+ break;
+ case XLS_TOKEN( sz ):
+ maOoxData.mfHeight = rAttribs.getDouble( XML_val, rDefFontData.mfHeight );
+ maUsedFlags.mbHeightUsed = true;
+ break;
+ case XLS_TOKEN( color ):
+ maOoxData.maColor.importColor( rAttribs );
+ maUsedFlags.mbColorUsed = true;
+ break;
+ case XLS_TOKEN( u ):
+ maOoxData.mnUnderline = rAttribs.getToken( XML_val, XML_single );
+ maUsedFlags.mbUnderlineUsed = true;
+ break;
+ case XLS_TOKEN( vertAlign ):
+ maOoxData.mnEscapement = rAttribs.getToken( XML_val, XML_baseline );
+ maUsedFlags.mbEscapementUsed = true;
+ break;
+ case XLS_TOKEN( b ):
+ maOoxData.mbBold = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbWeightUsed = true;
+ break;
+ case XLS_TOKEN( i ):
+ maOoxData.mbItalic = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbPostureUsed = true;
+ break;
+ case XLS_TOKEN( strike ):
+ maOoxData.mbStrikeout = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbStrikeoutUsed = true;
+ break;
+ case XLS_TOKEN( outline ):
+ maOoxData.mbOutline = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbOutlineUsed = true;
+ break;
+ case XLS_TOKEN( shadow ):
+ maOoxData.mbShadow = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbShadowUsed = true;
+ break;
+ }
+}
+
+void Font::importFont( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( !mbDxf, "Font::importFont - unexpected conditional formatting flag" );
+
+ sal_uInt16 nHeight, nFlags, nWeight, nEscapement;
+ sal_uInt8 nUnderline, nFamily, nCharSet, nScheme;
+ rStrm >> nHeight >> nFlags >> nWeight >> nEscapement >> nUnderline >> nFamily >> nCharSet;
+ rStrm.skip( 1 );
+ rStrm >> maOoxData.maColor >> nScheme >> maOoxData.maName;
+
+ // equal constants in BIFF and OOBIN for weight, underline, and escapement
+ maOoxData.setBinScheme( nScheme );
+ maOoxData.setBiffHeight( nHeight );
+ maOoxData.setBiffWeight( nWeight );
+ maOoxData.setBiffUnderline( nUnderline );
+ maOoxData.setBiffEscapement( nEscapement );
+ maOoxData.mnFamily = nFamily;
+ maOoxData.mnCharSet = nCharSet;
+ // equal flags in BIFF and OOBIN
+ maOoxData.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
+ maOoxData.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT );
+ maOoxData.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE );
+ maOoxData.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW );
+}
+
+void Font::importDxfName( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfName - missing conditional formatting flag" );
+ maOoxData.maName = rStrm.readString( false );
+ maUsedFlags.mbColorUsed = true;
+}
+
+void Font::importDxfColor( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfColor - missing conditional formatting flag" );
+ rStrm >> maOoxData.maColor;
+ maUsedFlags.mbColorUsed = true;
+}
+
+void Font::importDxfScheme( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfScheme - missing conditional formatting flag" );
+ maOoxData.setBinScheme( rStrm.readuInt8() );
+ maUsedFlags.mbSchemeUsed = true;
+}
+
+void Font::importDxfHeight( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfHeight - missing conditional formatting flag" );
+ maOoxData.setBiffHeight( rStrm.readuInt16() );
+ maUsedFlags.mbHeightUsed = true;
+}
+
+void Font::importDxfWeight( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfWeight - missing conditional formatting flag" );
+ maOoxData.setBiffWeight( rStrm.readuInt16() );
+ maUsedFlags.mbWeightUsed = true;
+}
+
+void Font::importDxfUnderline( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfUnderline - missing conditional formatting flag" );
+ maOoxData.setBiffUnderline( rStrm.readuInt16() );
+ maUsedFlags.mbUnderlineUsed = true;
+}
+
+void Font::importDxfEscapement( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfEscapement - missing conditional formatting flag" );
+ maOoxData.setBiffEscapement( rStrm.readuInt16() );
+ maUsedFlags.mbEscapementUsed = true;
+}
+
+void Font::importDxfFlag( sal_Int32 nElement, RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfFlag - missing conditional formatting flag" );
+ bool bFlag = rStrm.readuInt8() != 0;
+ switch( nElement )
+ {
+ case XML_i:
+ maOoxData.mbItalic = bFlag;
+ maUsedFlags.mbPostureUsed = true;
+ break;
+ case XML_strike:
+ maOoxData.mbStrikeout = bFlag;
+ maUsedFlags.mbStrikeoutUsed = true;
+ break;
+ case XML_outline:
+ maOoxData.mbOutline = bFlag;
+ maUsedFlags.mbOutlineUsed = true;
+ break;
+ case XML_shadow:
+ maOoxData.mbShadow = bFlag;
+ maUsedFlags.mbShadowUsed = true;
+ break;
+ default:
+ OSL_ENSURE( false, "Font::importDxfFlag - unexpected element identifier" );
+ }
+}
+
+void Font::importFont( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !mbDxf, "Font::importFont - unexpected conditional formatting flag" );
+ switch( getBiff() )
+ {
+ case BIFF2:
+ importFontData2( rStrm );
+ importFontName2( rStrm );
+ break;
+ case BIFF3:
+ case BIFF4:
+ importFontData2( rStrm );
+ importFontColor( rStrm );
+ importFontName2( rStrm );
+ break;
+ case BIFF5:
+ importFontData2( rStrm );
+ importFontColor( rStrm );
+ importFontData5( rStrm );
+ importFontName2( rStrm );
+ break;
+ case BIFF8:
+ importFontData2( rStrm );
+ importFontColor( rStrm );
+ importFontData5( rStrm );
+ importFontName8( rStrm );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+}
+
+void Font::importFontColor( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !mbDxf, "Font::importFontColor - unexpected conditional formatting flag" );
+ maOoxData.maColor.importColorId( rStrm );
+}
+
+void Font::importCfRule( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importCfRule - missing conditional formatting flag" );
+
+ sal_Int32 nHeight, nColor;
+ sal_uInt32 nStyle, nFontFlags1, nFontFlags2, nFontFlags3;
+ sal_uInt16 nWeight, nEscapement;
+ sal_uInt8 nUnderline;
+
+ OSL_ENSURE( rStrm.getRecLeft() >= 118, "Font::importCfRule - missing record data" );
+ sal_uInt32 nRecPos = rStrm.getRecPos();
+ maOoxData.maName = rStrm.readUniString( rStrm.readuInt8() );
+ maUsedFlags.mbNameUsed = maOoxData.maName.getLength() > 0;
+ OSL_ENSURE( rStrm.isValid() && (rStrm.getRecPos() <= nRecPos + 64), "Font::importCfRule - font name too long" );
+ rStrm.seek( nRecPos + 64 );
+ rStrm >> nHeight >> nStyle >> nWeight >> nEscapement >> nUnderline;
+ rStrm.skip( 3 );
+ rStrm >> nColor;
+ rStrm.skip( 4 );
+ rStrm >> nFontFlags1 >> nFontFlags2 >> nFontFlags3;
+ rStrm.skip( 18 );
+
+ if( (maUsedFlags.mbColorUsed = (0 <= nColor) && (nColor <= 0x7FFF)) == true )
+ maOoxData.maColor.set( XML_indexed, nColor );
+ if( (maUsedFlags.mbHeightUsed = (0 < nHeight) && (nHeight <= 0x7FFF)) == true )
+ maOoxData.setBiffHeight( static_cast< sal_uInt16 >( nHeight ) );
+ if( (maUsedFlags.mbUnderlineUsed = !getFlag( nFontFlags3, BIFF_CFRULE_FONT_UNDERL )) == true )
+ maOoxData.setBiffUnderline( nUnderline );
+ if( (maUsedFlags.mbEscapementUsed = !getFlag( nFontFlags2, BIFF_CFRULE_FONT_ESCAPEM )) == true )
+ maOoxData.setBiffEscapement( nEscapement );
+ if( (maUsedFlags.mbWeightUsed = maUsedFlags.mbPostureUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STYLE )) == true )
+ {
+ maOoxData.setBiffWeight( nWeight );
+ maOoxData.mbItalic = getFlag( nStyle, BIFF_CFRULE_FONT_STYLE );
+ }
+ if( (maUsedFlags.mbStrikeoutUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STRIKEOUT )) == true )
+ maOoxData.mbStrikeout = getFlag( nStyle, BIFF_CFRULE_FONT_STRIKEOUT );
+ if( (maUsedFlags.mbOutlineUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_OUTLINE )) == true )
+ maOoxData.mbOutline = getFlag( nStyle, BIFF_CFRULE_FONT_OUTLINE );
+ if( (maUsedFlags.mbShadowUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_SHADOW )) == true )
+ maOoxData.mbShadow = getFlag( nStyle, BIFF_CFRULE_FONT_SHADOW );
+}
+
+rtl_TextEncoding Font::getFontEncoding() const
+{
+ // #i63105# cells use text encoding from FONT record character set
+ // #i67768# BIFF2-BIFF4 FONT records do not contain character set
+ // #i71033# do not use maApiData, this function is used before finalizeImport()
+ rtl_TextEncoding eFontEnc = RTL_TEXTENCODING_DONTKNOW;
+ if( (0 <= maOoxData.mnCharSet) && (maOoxData.mnCharSet <= SAL_MAX_UINT8) )
+ eFontEnc = rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maOoxData.mnCharSet ) );
+ return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? getTextEncoding() : eFontEnc;
+}
+
+void Font::finalizeImport()
+{
+ namespace cssawt = ::com::sun::star::awt;
+
+ // font name
+ maApiData.maDesc.Name = maOoxData.maName;
+
+ // font family
+ switch( maOoxData.mnFamily )
+ {
+ case OOX_FONTFAMILY_NONE: maApiData.maDesc.Family = cssawt::FontFamily::DONTKNOW; break;
+ case OOX_FONTFAMILY_ROMAN: maApiData.maDesc.Family = cssawt::FontFamily::ROMAN; break;
+ case OOX_FONTFAMILY_SWISS: maApiData.maDesc.Family = cssawt::FontFamily::SWISS; break;
+ case OOX_FONTFAMILY_MODERN: maApiData.maDesc.Family = cssawt::FontFamily::MODERN; break;
+ case OOX_FONTFAMILY_SCRIPT: maApiData.maDesc.Family = cssawt::FontFamily::SCRIPT; break;
+ case OOX_FONTFAMILY_DECORATIVE: maApiData.maDesc.Family = cssawt::FontFamily::DECORATIVE; break;
+ }
+
+ // character set
+ if( (0 <= maOoxData.mnCharSet) && (maOoxData.mnCharSet <= 255) )
+ maApiData.maDesc.CharSet = static_cast< sal_Int16 >(
+ rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maOoxData.mnCharSet ) ) );
+
+ // color, height, weight, slant, strikeout, outline, shadow
+ maApiData.mnColor = getStyles().getColor( maOoxData.maColor, API_RGB_TRANSPARENT );
+ maApiData.maDesc.Height = static_cast< sal_Int16 >( maOoxData.mfHeight * 20.0 );
+ maApiData.maDesc.Weight = maOoxData.mbBold ? cssawt::FontWeight::BOLD : cssawt::FontWeight::NORMAL;
+ maApiData.maDesc.Slant = maOoxData.mbItalic ? cssawt::FontSlant_ITALIC : cssawt::FontSlant_NONE;
+ maApiData.maDesc.Strikeout = maOoxData.mbStrikeout ? cssawt::FontStrikeout::SINGLE : cssawt::FontStrikeout::NONE;
+ maApiData.mbOutline = maOoxData.mbOutline;
+ maApiData.mbShadow = maOoxData.mbShadow;
+
+ // underline
+ switch( maOoxData.mnUnderline )
+ {
+ case XML_double: maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break;
+ case XML_doubleAccounting: maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break;
+ case XML_none: maApiData.maDesc.Underline = cssawt::FontUnderline::NONE; break;
+ case XML_single: maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break;
+ case XML_singleAccounting: maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break;
+ }
+
+ // escapement
+ switch( maOoxData.mnEscapement )
+ {
+ case XML_baseline:
+ maApiData.mnEscapement = API_ESCAPE_NONE;
+ maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_NONE;
+ break;
+ case XML_superscript:
+ maApiData.mnEscapement = API_ESCAPE_SUPERSCRIPT;
+ maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
+ break;
+ case XML_subscript:
+ maApiData.mnEscapement = API_ESCAPE_SUBSCRIPT;
+ maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
+ break;
+ }
+
+ // supported script types
+ if( maUsedFlags.mbNameUsed )
+ {
+ Reference< XDevice > xDevice = getReferenceDevice();
+ if( xDevice.is() )
+ {
+ Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY );
+ if( xFont.is() )
+ {
+ // #91658# CJK fonts
+ maApiData.mbHasAsian =
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x3041 ) ) ) || // 3040-309F: Hiragana
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x30A1 ) ) ) || // 30A0-30FF: Katakana
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x3111 ) ) ) || // 3100-312F: Bopomofo
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x3131 ) ) ) || // 3130-318F: Hangul Compatibility Jamo
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x3301 ) ) ) || // 3300-33FF: CJK Compatibility
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x3401 ) ) ) || // 3400-4DBF: CJK Unified Ideographs Extension A
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x4E01 ) ) ) || // 4E00-9FAF: CJK Unified Ideographs
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x7E01 ) ) ) || // 4E00-9FAF: CJK unified ideographs
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xA001 ) ) ) || // A001-A48F: Yi Syllables
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xAC01 ) ) ) || // AC00-D7AF: Hangul Syllables
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xCC01 ) ) ) || // AC00-D7AF: Hangul Syllables
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xF901 ) ) ) || // F900-FAFF: CJK Compatibility Ideographs
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xFF71 ) ) ); // FF00-FFEF: Halfwidth/Fullwidth Forms
+ // #113783# CTL fonts
+ maApiData.mbHasCmplx =
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x05D1 ) ) ) || // 0590-05FF: Hebrew
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x0631 ) ) ) || // 0600-06FF: Arabic
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x0721 ) ) ) || // 0700-074F: Syriac
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x0911 ) ) ) || // 0900-0DFF: Indic scripts
+ xFont->hasGlyphs( OUString( sal_Unicode( 0x0E01 ) ) ) || // 0E00-0E7F: Thai
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xFB21 ) ) ) || // FB1D-FB4F: Hebrew Presentation Forms
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xFB51 ) ) ) || // FB50-FDFF: Arabic Presentation Forms-A
+ xFont->hasGlyphs( OUString( sal_Unicode( 0xFE71 ) ) ); // FE70-FEFF: Arabic Presentation Forms-B
+ // Western fonts
+ maApiData.mbHasWstrn =
+ (!maApiData.mbHasAsian && !maApiData.mbHasCmplx) ||
+ xFont->hasGlyphs( OUString( sal_Unicode( 'A' ) ) );
+ }
+ }
+ }
+}
+
+const FontDescriptor& Font::getFontDescriptor() const
+{
+ return maApiData.maDesc;
+}
+
+bool Font::needsRichTextFormat() const
+{
+ return maApiData.mnEscapement != API_ESCAPE_NONE;
+}
+
+void Font::writeToPropertySet( PropertySet& rPropSet, FontPropertyType ePropType ) const
+{
+ getStylesPropertyHelper().writeFontProperties( rPropSet, maApiData, maUsedFlags, ePropType );
+}
+
+void Font::importFontData2( BiffInputStream& rStrm )
+{
+ sal_uInt16 nHeight, nFlags;
+ rStrm >> nHeight >> nFlags;
+
+ maOoxData.setBiffHeight( nHeight );
+ maOoxData.mnFamily = OOX_FONTFAMILY_NONE;
+ maOoxData.mnCharSet = OOX_FONTCHARSET_UNUSED; // ensure to not use font charset in byte string import
+ maOoxData.mnUnderline = getFlagValue( nFlags, BIFF_FONTFLAG_UNDERLINE, XML_single, XML_none );
+ maOoxData.mnEscapement = XML_none;
+ maOoxData.mbBold = getFlag( nFlags, BIFF_FONTFLAG_BOLD );
+ maOoxData.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
+ maOoxData.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT );
+ maOoxData.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE );
+ maOoxData.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW );
+}
+
+void Font::importFontData5( BiffInputStream& rStrm )
+{
+ sal_uInt16 nWeight, nEscapement;
+ sal_uInt8 nUnderline, nFamily, nCharSet;
+ rStrm >> nWeight >> nEscapement >> nUnderline >> nFamily >> nCharSet;
+ rStrm.skip( 1 );
+
+ maOoxData.setBiffWeight( nWeight );
+ maOoxData.setBiffUnderline( nUnderline );
+ maOoxData.setBiffEscapement( nEscapement );
+ // equal constants in XML and BIFF for family and charset
+ maOoxData.mnFamily = nFamily;
+ maOoxData.mnCharSet = nCharSet;
+}
+
+void Font::importFontName2( BiffInputStream& rStrm )
+{
+ maOoxData.maName = rStrm.readByteString( false, getTextEncoding() );
+}
+
+void Font::importFontName8( BiffInputStream& rStrm )
+{
+ maOoxData.maName = rStrm.readUniString( rStrm.readuInt8() );
+}
+
+// ============================================================================
+
+OoxAlignmentData::OoxAlignmentData() :
+ mnHorAlign( XML_general ),
+ mnVerAlign( XML_bottom ),
+ mnTextDir( OOX_XF_TEXTDIR_CONTEXT ),
+ mnRotation( OOX_XF_ROTATION_NONE ),
+ mnIndent( OOX_XF_INDENT_NONE ),
+ mbWrapText( false ),
+ mbShrink( false ),
+ mbJustLastLine( false )
+{
+}
+
+void OoxAlignmentData::setBinHorAlign( sal_uInt8 nHorAlign )
+{
+ static const sal_Int32 spnHorAligns[] = {
+ XML_general, XML_left, XML_center, XML_right,
+ XML_fill, XML_justify, XML_centerContinuous, XML_distributed };
+ mnHorAlign = STATIC_ARRAY_SELECT( spnHorAligns, nHorAlign, XML_general );
+}
+
+void OoxAlignmentData::setBinVerAlign( sal_uInt8 nVerAlign )
+{
+ static const sal_Int32 spnVerAligns[] = {
+ XML_top, XML_center, XML_bottom, XML_justify, XML_distributed };
+ mnVerAlign = STATIC_ARRAY_SELECT( spnVerAligns, nVerAlign, XML_bottom );
+}
+
+void OoxAlignmentData::setBinTextOrient( sal_uInt8 nTextOrient )
+{
+ static const sal_Int32 spnRotations[] = {
+ OOX_XF_ROTATION_NONE, OOX_XF_ROTATION_STACKED,
+ OOX_XF_ROTATION_90CCW, OOX_XF_ROTATION_90CW };
+ mnRotation = STATIC_ARRAY_SELECT( spnRotations, nTextOrient, OOX_XF_ROTATION_NONE );
+}
+
+// ============================================================================
+
+Alignment::Alignment( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void Alignment::importAlignment( const AttributeList& rAttribs )
+{
+ maOoxData.mnHorAlign = rAttribs.getToken( XML_horizontal, XML_general );
+ maOoxData.mnVerAlign = rAttribs.getToken( XML_vertical, XML_bottom );
+ maOoxData.mnTextDir = rAttribs.getInteger( XML_readingOrder, OOX_XF_TEXTDIR_CONTEXT );
+ maOoxData.mnRotation = rAttribs.getInteger( XML_textRotation, OOX_XF_ROTATION_NONE );
+ maOoxData.mnIndent = rAttribs.getInteger( XML_indent, OOX_XF_INDENT_NONE );
+ maOoxData.mbWrapText = rAttribs.getBool( XML_wrapText, false );
+ maOoxData.mbShrink = rAttribs.getBool( XML_shrinkToFit, false );
+ maOoxData.mbJustLastLine = rAttribs.getBool( XML_justifyLastLine, false );
+}
+
+void Alignment::setBinData( sal_uInt32 nFlags )
+{
+ maOoxData.setBinHorAlign( extractValue< sal_uInt8 >( nFlags, 16, 3 ) );
+ maOoxData.setBinVerAlign( extractValue< sal_uInt8 >( nFlags, 19, 3 ) );
+ maOoxData.mnTextDir = extractValue< sal_Int32 >( nFlags, 26, 2 );
+ maOoxData.mnRotation = extractValue< sal_Int32 >( nFlags, 0, 8 );
+ maOoxData.mnIndent = extractValue< sal_uInt8 >( nFlags, 8, 8 );
+ maOoxData.mbWrapText = getFlag( nFlags, OOBIN_XF_WRAPTEXT );
+ maOoxData.mbShrink = getFlag( nFlags, OOBIN_XF_SHRINK );
+ maOoxData.mbJustLastLine = getFlag( nFlags, OOBIN_XF_JUSTLASTLINE );
+}
+
+void Alignment::setBiff2Data( sal_uInt8 nFlags )
+{
+ maOoxData.setBinHorAlign( extractValue< sal_uInt8 >( nFlags, 0, 3 ) );
+}
+
+void Alignment::setBiff3Data( sal_uInt16 nAlign )
+{
+ maOoxData.setBinHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maOoxData.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); // new in BIFF3
+}
+
+void Alignment::setBiff4Data( sal_uInt16 nAlign )
+{
+ maOoxData.setBinHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maOoxData.setBinVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 2 ) ); // new in BIFF4
+ maOoxData.setBinTextOrient( extractValue< sal_uInt8 >( nAlign, 6, 2 ) ); // new in BIFF4
+ maOoxData.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT );
+}
+
+void Alignment::setBiff5Data( sal_uInt16 nAlign )
+{
+ maOoxData.setBinHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maOoxData.setBinVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) );
+ maOoxData.setBinTextOrient( extractValue< sal_uInt8 >( nAlign, 8, 2 ) );
+ maOoxData.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT );
+}
+
+void Alignment::setBiff8Data( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib )
+{
+ maOoxData.setBinHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maOoxData.setBinVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) );
+ maOoxData.mnTextDir = extractValue< sal_Int32 >( nMiscAttrib, 6, 2 ); // new in BIFF8
+ maOoxData.mnRotation = extractValue< sal_Int32 >( nAlign, 8, 8 ); // new in BIFF8
+ maOoxData.mnIndent = extractValue< sal_uInt8 >( nMiscAttrib, 0, 4 ); // new in BIFF8
+ maOoxData.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT );
+ maOoxData.mbShrink = getFlag( nMiscAttrib, BIFF_XF_SHRINK ); // new in BIFF8
+ maOoxData.mbJustLastLine = getFlag( nAlign, BIFF_XF_JUSTLASTLINE ); // new in BIFF8(?)
+}
+
+void Alignment::finalizeImport()
+{
+ namespace csstab = ::com::sun::star::table;
+ namespace csstxt = ::com::sun::star::text;
+
+ // horizontal alignment
+ switch( maOoxData.mnHorAlign )
+ {
+ case XML_center: maApiData.meHorJustify = csstab::CellHoriJustify_CENTER; break;
+ case XML_centerContinuous: maApiData.meHorJustify = csstab::CellHoriJustify_CENTER; break;
+ case XML_distributed: maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK; break;
+ case XML_fill: maApiData.meHorJustify = csstab::CellHoriJustify_REPEAT; break;
+ case XML_general: maApiData.meHorJustify = csstab::CellHoriJustify_STANDARD; break;
+ case XML_justify: maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK; break;
+ case XML_left: maApiData.meHorJustify = csstab::CellHoriJustify_LEFT; break;
+ case XML_right: maApiData.meHorJustify = csstab::CellHoriJustify_RIGHT; break;
+ }
+
+ // vertical alignment
+ switch( maOoxData.mnVerAlign )
+ {
+ case XML_bottom: maApiData.meVerJustify = csstab::CellVertJustify_BOTTOM; break;
+ case XML_center: maApiData.meVerJustify = csstab::CellVertJustify_CENTER; break;
+ case XML_distributed: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break;
+ case XML_justify: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break;
+ case XML_top: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break;
+ }
+
+ /* indentation: expressed as number of blocks of 3 space characters in
+ OOX, and as multiple of 10 points in BIFF. */
+ sal_Int32 nIndent = 0;
+ switch( getFilterType() )
+ {
+ case FILTER_OOX: nIndent = getUnitConverter().calcMm100FromSpaces( 3.0 * maOoxData.mnIndent ); break;
+ case FILTER_BIFF: nIndent = getUnitConverter().calcMm100FromPoints( 10.0 * maOoxData.mnIndent ); break;
+ case FILTER_UNKNOWN: break;
+ }
+ if( (0 <= nIndent) && (nIndent <= SAL_MAX_INT16) )
+ maApiData.mnIndent = static_cast< sal_Int16 >( nIndent );
+
+ // complex text direction
+ switch( maOoxData.mnTextDir )
+ {
+ case OOX_XF_TEXTDIR_CONTEXT: maApiData.mnWritingMode = csstxt::WritingMode2::PAGE; break;
+ case OOX_XF_TEXTDIR_LTR: maApiData.mnWritingMode = csstxt::WritingMode2::LR_TB; break;
+ case OOX_XF_TEXTDIR_RTL: maApiData.mnWritingMode = csstxt::WritingMode2::RL_TB; break;
+ }
+
+ // rotation: 0-90 means 0 to 90 degrees ccw, 91-180 means 1 to 90 degrees cw, 255 means stacked
+ sal_Int32 nOoxRot = maOoxData.mnRotation;
+ maApiData.mnRotation = ((0 <= nOoxRot) && (nOoxRot <= 90)) ?
+ (100 * nOoxRot) :
+ (((91 <= nOoxRot) && (nOoxRot <= 180)) ? (100 * (450 - nOoxRot)) : 0);
+
+ // "Orientation" property used for character stacking
+ maApiData.meOrientation = (nOoxRot == OOX_XF_ROTATION_STACKED) ?
+ csstab::CellOrientation_STACKED : csstab::CellOrientation_STANDARD;
+
+ // alignment flags
+ maApiData.mbWrapText = maOoxData.mbWrapText;
+ maApiData.mbShrink = maOoxData.mbShrink;
+
+}
+
+void Alignment::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ getStylesPropertyHelper().writeAlignmentProperties( rPropSet, maApiData );
+}
+
+// ============================================================================
+
+OoxProtectionData::OoxProtectionData() :
+ mbLocked( true ), // default in Excel and Calc
+ mbHidden( false )
+{
+}
+
+// ============================================================================
+
+Protection::Protection( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void Protection::importProtection( const AttributeList& rAttribs )
+{
+ maOoxData.mbLocked = rAttribs.getBool( XML_locked, true );
+ maOoxData.mbHidden = rAttribs.getBool( XML_hidden, false );
+}
+
+void Protection::setBinData( sal_uInt32 nFlags )
+{
+ maOoxData.mbLocked = getFlag( nFlags, OOBIN_XF_LOCKED );
+ maOoxData.mbHidden = getFlag( nFlags, OOBIN_XF_HIDDEN );
+}
+
+void Protection::setBiff2Data( sal_uInt8 nNumFmt )
+{
+ maOoxData.mbLocked = getFlag( nNumFmt, BIFF2_XF_LOCKED );
+ maOoxData.mbHidden = getFlag( nNumFmt, BIFF2_XF_HIDDEN );
+}
+
+void Protection::setBiff3Data( sal_uInt16 nProt )
+{
+ maOoxData.mbLocked = getFlag( nProt, BIFF_XF_LOCKED );
+ maOoxData.mbHidden = getFlag( nProt, BIFF_XF_HIDDEN );
+}
+
+void Protection::finalizeImport()
+{
+ maApiData.maCellProt.IsLocked = maOoxData.mbLocked;
+ maApiData.maCellProt.IsFormulaHidden = maOoxData.mbHidden;
+}
+
+void Protection::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ getStylesPropertyHelper().writeProtectionProperties( rPropSet, maApiData );
+}
+
+// ============================================================================
+
+OoxBorderLineData::OoxBorderLineData( bool bDxf ) :
+ maColor( XML_indexed, OOX_COLOR_WINDOWTEXT ),
+ mnStyle( XML_none ),
+ mbUsed( !bDxf )
+{
+}
+
+void OoxBorderLineData::setBiffStyle( sal_Int32 nLineStyle )
+{
+ static const sal_Int32 spnStyleIds[] = {
+ XML_none, XML_thin, XML_medium, XML_dashed,
+ XML_dotted, XML_thick, XML_double, XML_hair,
+ XML_mediumDashed, XML_dashDot, XML_mediumDashDot, XML_dashDotDot,
+ XML_mediumDashDotDot, XML_slantDashDot };
+ mnStyle = STATIC_ARRAY_SELECT( spnStyleIds, nLineStyle, XML_none );
+}
+
+void OoxBorderLineData::setBiffData( sal_uInt8 nLineStyle, sal_uInt16 nLineColor )
+{
+ maColor.set( XML_indexed, nLineColor );
+ setBiffStyle( nLineStyle );
+}
+
+// ============================================================================
+
+OoxBorderData::OoxBorderData( bool bDxf ) :
+ maLeft( bDxf ),
+ maRight( bDxf ),
+ maTop( bDxf ),
+ maBottom( bDxf ),
+ maDiagonal( bDxf ),
+ mbDiagTLtoBR( false ),
+ mbDiagBLtoTR( false )
+{
+}
+
+// ============================================================================
+
+namespace {
+
+inline void lclSetBorderLineWidth( BorderLine& rBorderLine,
+ sal_Int16 nOuter, sal_Int16 nDist = API_LINE_NONE, sal_Int16 nInner = API_LINE_NONE )
+{
+ rBorderLine.OuterLineWidth = nOuter;
+ rBorderLine.LineDistance = nDist;
+ rBorderLine.InnerLineWidth = nInner;
+}
+
+inline sal_Int32 lclGetBorderLineWidth( const BorderLine& rBorderLine )
+{
+ return rBorderLine.OuterLineWidth + rBorderLine.LineDistance + rBorderLine.InnerLineWidth;
+}
+
+const BorderLine* lclGetThickerLine( const BorderLine& rBorderLine1, sal_Bool bValid1, const BorderLine& rBorderLine2, sal_Bool bValid2 )
+{
+ if( bValid1 && bValid2 )
+ return (lclGetBorderLineWidth( rBorderLine1 ) < lclGetBorderLineWidth( rBorderLine2 )) ? &rBorderLine2 : &rBorderLine1;
+ if( bValid1 )
+ return &rBorderLine1;
+ if( bValid2 )
+ return &rBorderLine2;
+ return 0;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+Border::Border( const WorkbookHelper& rHelper, bool bDxf ) :
+ WorkbookHelper( rHelper ),
+ maOoxData( bDxf ),
+ mbDxf( bDxf )
+{
+}
+
+bool Border::isSupportedContext( sal_Int32 nElement, sal_Int32 nParentContext )
+{
+ switch( nParentContext )
+ {
+ case XLS_TOKEN( border ):
+ return (nElement == XLS_TOKEN( left )) ||
+ (nElement == XLS_TOKEN( right )) ||
+ (nElement == XLS_TOKEN( top )) ||
+ (nElement == XLS_TOKEN( bottom )) ||
+ (nElement == XLS_TOKEN( diagonal ));
+ case XLS_TOKEN( left ):
+ case XLS_TOKEN( right ):
+ case XLS_TOKEN( top ):
+ case XLS_TOKEN( bottom ):
+ case XLS_TOKEN( diagonal ):
+ return (nElement == XLS_TOKEN( color ));
+ }
+ return false;
+}
+
+void Border::importBorder( const AttributeList& rAttribs )
+{
+ maOoxData.mbDiagTLtoBR = rAttribs.getBool( XML_diagonalDown, false );
+ maOoxData.mbDiagBLtoTR = rAttribs.getBool( XML_diagonalUp, false );
+}
+
+void Border::importStyle( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( OoxBorderLineData* pBorderLine = getBorderLine( nElement ) )
+ {
+ pBorderLine->mnStyle = rAttribs.getToken( XML_style, XML_none );
+ pBorderLine->mbUsed = true;
+ }
+}
+
+void Border::importColor( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( OoxBorderLineData* pBorderLine = getBorderLine( nElement ) )
+ pBorderLine->maColor.importColor( rAttribs );
+}
+
+void Border::importBorder( RecordInputStream& rStrm )
+{
+ sal_uInt8 nFlags = rStrm.readuInt8();
+ maOoxData.mbDiagTLtoBR = getFlag( nFlags, OOBIN_BORDER_DIAG_TLBR );
+ maOoxData.mbDiagBLtoTR = getFlag( nFlags, OOBIN_BORDER_DIAG_BLTR );
+ maOoxData.maTop.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maOoxData.maTop.maColor;
+ maOoxData.maBottom.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maOoxData.maBottom.maColor;
+ maOoxData.maLeft.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maOoxData.maLeft.maColor;
+ maOoxData.maRight.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maOoxData.maRight.maColor;
+ maOoxData.maDiagonal.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maOoxData.maDiagonal.maColor;
+}
+
+void Border::importDxfBorder( sal_Int32 nElement, RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Border::importDxfBorder - missing conditional formatting flag" );
+ if( OoxBorderLineData* pBorderLine = getBorderLine( nElement ) )
+ {
+ sal_uInt16 nStyle;
+ rStrm >> pBorderLine->maColor >> nStyle;
+ pBorderLine->setBiffStyle( nStyle );
+ pBorderLine->mbUsed = true;
+ }
+}
+
+void Border::setBiff2Data( sal_uInt8 nFlags )
+{
+ OSL_ENSURE( !mbDxf, "Border::setBiff2Data - unexpected conditional formatting flag" );
+ maOoxData.maLeft.setBiffData( getFlagValue( nFlags, BIFF2_XF_LEFTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maOoxData.maRight.setBiffData( getFlagValue( nFlags, BIFF2_XF_RIGHTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maOoxData.maTop.setBiffData( getFlagValue( nFlags, BIFF2_XF_TOPLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maOoxData.maBottom.setBiffData( getFlagValue( nFlags, BIFF2_XF_BOTTOMLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maOoxData.maDiagonal.mbUsed = false;
+}
+
+void Border::setBiff3Data( sal_uInt32 nBorder )
+{
+ OSL_ENSURE( !mbDxf, "Border::setBiff3Data - unexpected conditional formatting flag" );
+ maOoxData.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 8, 3 ), extractValue< sal_uInt16 >( nBorder, 11, 5 ) );
+ maOoxData.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 24, 3 ), extractValue< sal_uInt16 >( nBorder, 27, 5 ) );
+ maOoxData.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 3, 5 ) );
+ maOoxData.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder, 16, 3 ), extractValue< sal_uInt16 >( nBorder, 19, 5 ) );
+ maOoxData.maDiagonal.mbUsed = false;
+}
+
+void Border::setBiff5Data( sal_uInt32 nBorder, sal_uInt32 nArea )
+{
+ OSL_ENSURE( !mbDxf, "Border::setBiff5Data - unexpected conditional formatting flag" );
+ maOoxData.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 3, 3 ), extractValue< sal_uInt16 >( nBorder, 16, 7 ) );
+ maOoxData.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 6, 3 ), extractValue< sal_uInt16 >( nBorder, 23, 7 ) );
+ maOoxData.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 9, 7 ) );
+ maOoxData.maBottom.setBiffData( extractValue< sal_uInt8 >( nArea, 22, 3 ), extractValue< sal_uInt16 >( nArea, 25, 7 ) );
+ maOoxData.maDiagonal.mbUsed = false;
+}
+
+void Border::setBiff8Data( sal_uInt32 nBorder1, sal_uInt32 nBorder2 )
+{
+ OSL_ENSURE( !mbDxf, "Border::setBiff8Data - unexpected conditional formatting flag" );
+ maOoxData.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder1, 0, 4 ), extractValue< sal_uInt16 >( nBorder1, 16, 7 ) );
+ maOoxData.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder1, 4, 4 ), extractValue< sal_uInt16 >( nBorder1, 23, 7 ) );
+ maOoxData.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder1, 8, 4 ), extractValue< sal_uInt16 >( nBorder2, 0, 7 ) );
+ maOoxData.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder1, 12, 4 ), extractValue< sal_uInt16 >( nBorder2, 7, 7 ) );
+ maOoxData.mbDiagTLtoBR = getFlag( nBorder1, BIFF_XF_DIAG_TLBR );
+ maOoxData.mbDiagBLtoTR = getFlag( nBorder1, BIFF_XF_DIAG_BLTR );
+ if( maOoxData.mbDiagTLtoBR || maOoxData.mbDiagBLtoTR )
+ maOoxData.maDiagonal.setBiffData( extractValue< sal_uInt8 >( nBorder2, 21, 4 ), extractValue< sal_uInt16 >( nBorder2, 14, 7 ) );
+}
+
+void Border::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags )
+{
+ OSL_ENSURE( mbDxf, "Border::importCfRule - missing conditional formatting flag" );
+ OSL_ENSURE( getFlag( nFlags, BIFF_CFRULE_BORDERBLOCK ), "Border::importCfRule - missing border block flag" );
+ sal_uInt16 nStyle;
+ sal_uInt32 nColor;
+ rStrm >> nStyle >> nColor;
+ rStrm.skip( 2 );
+ maOoxData.maLeft.setBiffData( extractValue< sal_uInt8 >( nStyle, 0, 4 ), extractValue< sal_uInt16 >( nColor, 0, 7 ) );
+ maOoxData.maRight.setBiffData( extractValue< sal_uInt8 >( nStyle, 4, 4 ), extractValue< sal_uInt16 >( nColor, 7, 7 ) );
+ maOoxData.maTop.setBiffData( extractValue< sal_uInt8 >( nStyle, 8, 4 ), extractValue< sal_uInt16 >( nColor, 16, 7 ) );
+ maOoxData.maBottom.setBiffData( extractValue< sal_uInt8 >( nStyle, 12, 4 ), extractValue< sal_uInt16 >( nColor, 23, 7 ) );
+ maOoxData.maLeft.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_LEFT );
+ maOoxData.maRight.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_RIGHT );
+ maOoxData.maTop.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_TOP );
+ maOoxData.maBottom.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_BOTTOM );
+}
+
+void Border::finalizeImport()
+{
+ maApiData.mbBorderUsed = maOoxData.maLeft.mbUsed || maOoxData.maRight.mbUsed || maOoxData.maTop.mbUsed || maOoxData.maBottom.mbUsed;
+ maApiData.mbDiagUsed = maOoxData.maDiagonal.mbUsed;
+
+ maApiData.maBorder.IsLeftLineValid = convertBorderLine( maApiData.maBorder.LeftLine, maOoxData.maLeft );
+ maApiData.maBorder.IsRightLineValid = convertBorderLine( maApiData.maBorder.RightLine, maOoxData.maRight );
+ maApiData.maBorder.IsTopLineValid = convertBorderLine( maApiData.maBorder.TopLine, maOoxData.maTop );
+ maApiData.maBorder.IsBottomLineValid = convertBorderLine( maApiData.maBorder.BottomLine, maOoxData.maBottom );
+
+ if( !mbDxf )
+ {
+ maApiData.maBorder.IsVerticalLineValid = maApiData.maBorder.IsLeftLineValid || maApiData.maBorder.IsRightLineValid;
+ if( const BorderLine* pVertLine = lclGetThickerLine( maApiData.maBorder.LeftLine, maApiData.maBorder.IsLeftLineValid, maApiData.maBorder.RightLine, maApiData.maBorder.IsRightLineValid ) )
+ maApiData.maBorder.VerticalLine = *pVertLine;
+
+ maApiData.maBorder.IsHorizontalLineValid = maApiData.maBorder.IsTopLineValid || maApiData.maBorder.IsBottomLineValid;
+ if( const BorderLine* pHorLine = lclGetThickerLine( maApiData.maBorder.TopLine, maApiData.maBorder.IsTopLineValid, maApiData.maBorder.BottomLine, maApiData.maBorder.IsBottomLineValid ) )
+ maApiData.maBorder.HorizontalLine = *pHorLine;
+ }
+
+ if( maOoxData.mbDiagTLtoBR )
+ convertBorderLine( maApiData.maTLtoBR, maOoxData.maDiagonal );
+ if( maOoxData.mbDiagBLtoTR )
+ convertBorderLine( maApiData.maBLtoTR, maOoxData.maDiagonal );
+}
+
+void Border::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ getStylesPropertyHelper().writeBorderProperties( rPropSet, maApiData );
+}
+
+OoxBorderLineData* Border::getBorderLine( sal_Int32 nElement )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( left ): return &maOoxData.maLeft;
+ case XLS_TOKEN( right ): return &maOoxData.maRight;
+ case XLS_TOKEN( top ): return &maOoxData.maTop;
+ case XLS_TOKEN( bottom ): return &maOoxData.maBottom;
+ case XLS_TOKEN( diagonal ): return &maOoxData.maDiagonal;
+ }
+ return 0;
+}
+
+bool Border::convertBorderLine( BorderLine& rBorderLine, const OoxBorderLineData& rLineData )
+{
+ rBorderLine.Color = getStyles().getColor( rLineData.maColor, API_RGB_BLACK );
+ switch( rLineData.mnStyle )
+ {
+ case XML_dashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
+ case XML_dashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
+ case XML_dashed: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
+ case XML_dotted: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
+ case XML_double: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN, API_LINE_THIN, API_LINE_THIN ); break;
+ case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); break;
+ case XML_medium: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
+ case XML_mediumDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
+ case XML_mediumDashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
+ case XML_mediumDashed: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
+ case XML_none: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break;
+ case XML_slantDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
+ case XML_thick: lclSetBorderLineWidth( rBorderLine, API_LINE_THICK ); break;
+ case XML_thin: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
+ default: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break;
+ }
+ return rLineData.mbUsed;
+}
+
+
+// ============================================================================
+
+OoxPatternFillData::OoxPatternFillData( bool bDxf ) :
+ maPatternColor( XML_indexed, OOX_COLOR_WINDOWTEXT ),
+ maFillColor( XML_indexed, OOX_COLOR_WINDOWBACK ),
+ mnPattern( XML_none ),
+ mbPattColorUsed( !bDxf ),
+ mbFillColorUsed( !bDxf ),
+ mbPatternUsed( !bDxf )
+{
+}
+
+void OoxPatternFillData::setBinPattern( sal_Int32 nPattern )
+{
+ static const sal_Int32 spnPatternIds[] = {
+ XML_none, XML_solid, XML_mediumGray, XML_darkGray,
+ XML_lightGray, XML_darkHorizontal, XML_darkVertical, XML_darkDown,
+ XML_darkUp, XML_darkGrid, XML_darkTrellis, XML_lightHorizontal,
+ XML_lightVertical, XML_lightDown, XML_lightUp, XML_lightGrid,
+ XML_lightTrellis, XML_gray125, XML_gray0625 };
+ mnPattern = STATIC_ARRAY_SELECT( spnPatternIds, nPattern, XML_none );
+}
+
+void OoxPatternFillData::setBiffData( sal_uInt16 nPatternColor, sal_uInt16 nFillColor, sal_uInt8 nPattern )
+{
+ maPatternColor.set( XML_indexed, static_cast< sal_Int32 >( nPatternColor ) );
+ maFillColor.set( XML_indexed, static_cast< sal_Int32 >( nFillColor ) );
+ // patterns equal in BIFF and OOBIN
+ setBinPattern( nPattern );
+}
+
+// ----------------------------------------------------------------------------
+
+OoxGradientFillData::OoxGradientFillData() :
+ mnType( XML_linear ),
+ mfAngle( 0.0 ),
+ mfLeft( 0.0 ),
+ mfRight( 0.0 ),
+ mfTop( 0.0 ),
+ mfBottom( 0.0 )
+{
+}
+
+void OoxGradientFillData::readGradient( RecordInputStream& rStrm )
+{
+ sal_Int32 nType;
+ rStrm >> nType >> mfAngle >> mfLeft >> mfRight >> mfTop >> mfBottom;
+ static const sal_Int32 spnTypes[] = { XML_linear, XML_path };
+ mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
+}
+
+void OoxGradientFillData::readGradientStop( RecordInputStream& rStrm, bool bDxf )
+{
+ OoxColor aColor;
+ double fPosition;
+ if( bDxf )
+ {
+ rStrm.skip( 2 );
+ rStrm >> fPosition >> aColor;
+ }
+ else
+ {
+ rStrm >> aColor >> fPosition;
+ }
+ if( rStrm.isValid() && (fPosition >= 0.0) )
+ maColors[ fPosition ] = aColor;
+}
+
+// ============================================================================
+
+namespace {
+
+inline sal_Int32 lclGetMixedColorComp( sal_Int32 nPatt, sal_Int32 nFill, sal_Int32 nAlpha )
+{
+ return ((nPatt - nFill) * nAlpha) / 0x80 + nFill;
+}
+
+sal_Int32 lclGetMixedColor( sal_Int32 nPattColor, sal_Int32 nFillColor, sal_Int32 nAlpha )
+{
+ return
+ (lclGetMixedColorComp( nPattColor & 0xFF0000, nFillColor & 0xFF0000, nAlpha ) & 0xFF0000) |
+ (lclGetMixedColorComp( nPattColor & 0x00FF00, nFillColor & 0x00FF00, nAlpha ) & 0x00FF00) |
+ (lclGetMixedColorComp( nPattColor & 0x0000FF, nFillColor & 0x0000FF, nAlpha ) & 0x0000FF);
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+Fill::Fill( const WorkbookHelper& rHelper, bool bDxf ) :
+ WorkbookHelper( rHelper ),
+ mbDxf( bDxf )
+{
+}
+
+bool Fill::isSupportedContext( sal_Int32 nElement, sal_Int32 nParentContext )
+{
+ switch( nParentContext )
+ {
+ case XLS_TOKEN( fill ):
+ return (nElement == XLS_TOKEN( patternFill )) ||
+ (nElement == XLS_TOKEN( gradientFill ));
+ case XLS_TOKEN( patternFill ):
+ return (nElement == XLS_TOKEN( fgColor )) ||
+ (nElement == XLS_TOKEN( bgColor ));
+ case XLS_TOKEN( gradientFill ):
+ return (nElement == XLS_TOKEN( stop ));
+ case XLS_TOKEN( stop ):
+ return (nElement == XLS_TOKEN( color ));
+ }
+ return false;
+}
+
+void Fill::importPatternFill( const AttributeList& rAttribs )
+{
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->mnPattern = rAttribs.getToken( XML_patternType, XML_none );
+ if( mbDxf )
+ mxOoxPattData->mbPatternUsed = rAttribs.hasAttribute( XML_patternType );
+}
+
+void Fill::importFgColor( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( mxOoxPattData.get(), "Fill::importFgColor - missing pattern data" );
+ if( mxOoxPattData.get() )
+ {
+ mxOoxPattData->maPatternColor.importColor( rAttribs );
+ mxOoxPattData->mbPattColorUsed = true;
+ }
+}
+
+void Fill::importBgColor( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( mxOoxPattData.get(), "Fill::importBgColor - missing pattern data" );
+ if( mxOoxPattData.get() )
+ {
+ mxOoxPattData->maFillColor.importColor( rAttribs );
+ mxOoxPattData->mbFillColorUsed = true;
+ }
+}
+
+void Fill::importGradientFill( const AttributeList& rAttribs )
+{
+ mxOoxGradData.reset( new OoxGradientFillData );
+ mxOoxGradData->mnType = rAttribs.getToken( XML_type, XML_linear );
+ mxOoxGradData->mfAngle = rAttribs.getDouble( XML_degree, 0.0 );
+ mxOoxGradData->mfLeft = rAttribs.getDouble( XML_left, 0.0 );
+ mxOoxGradData->mfRight = rAttribs.getDouble( XML_right, 0.0 );
+ mxOoxGradData->mfTop = rAttribs.getDouble( XML_top, 0.0 );
+ mxOoxGradData->mfBottom = rAttribs.getDouble( XML_bottom, 0.0 );
+}
+
+void Fill::importColor( const AttributeList& rAttribs, double fPosition )
+{
+ OSL_ENSURE( mxOoxGradData.get(), "Fill::importColor - missing gradient data" );
+ if( mxOoxGradData.get() && (fPosition >= 0.0) )
+ mxOoxGradData->maColors[ fPosition ].importColor( rAttribs );
+}
+
+void Fill::importFill( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( !mbDxf, "Fill::importFill - unexpected conditional formatting flag" );
+ sal_Int32 nPattern = rStrm.readInt32();
+ if( nPattern == OOBIN_FILL_GRADIENT )
+ {
+ mxOoxGradData.reset( new OoxGradientFillData );
+ sal_Int32 nStopCount;
+ rStrm.skip( 16 );
+ mxOoxGradData->readGradient( rStrm );
+ rStrm >> nStopCount;
+ for( sal_Int32 nStop = 0; (nStop < nStopCount) && rStrm.isValid(); ++nStop )
+ mxOoxGradData->readGradientStop( rStrm, false );
+ }
+ else
+ {
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->setBinPattern( nPattern );
+ rStrm >> mxOoxPattData->maPatternColor >> mxOoxPattData->maFillColor;
+ }
+}
+
+void Fill::importDxfPattern( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfPattern - missing conditional formatting flag" );
+ if( !mxOoxPattData )
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->setBinPattern( rStrm.readuInt8() );
+ mxOoxPattData->mbPatternUsed = true;
+}
+
+void Fill::importDxfFgColor( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfFgColor - missing conditional formatting flag" );
+ if( !mxOoxPattData )
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->maPatternColor.importColor( rStrm );
+ mxOoxPattData->mbPattColorUsed = true;
+}
+
+void Fill::importDxfBgColor( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfBgColor - missing conditional formatting flag" );
+ if( !mxOoxPattData )
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->maFillColor.importColor( rStrm );
+ mxOoxPattData->mbFillColorUsed = true;
+}
+
+void Fill::importDxfGradient( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfGradient - missing conditional formatting flag" );
+ if( !mxOoxGradData )
+ mxOoxGradData.reset( new OoxGradientFillData );
+ mxOoxGradData->readGradient( rStrm );
+}
+
+void Fill::importDxfStop( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfStop - missing conditional formatting flag" );
+ if( !mxOoxGradData )
+ mxOoxGradData.reset( new OoxGradientFillData );
+ mxOoxGradData->readGradientStop( rStrm, true );
+}
+
+void Fill::setBiff2Data( sal_uInt8 nFlags )
+{
+ OSL_ENSURE( !mbDxf, "Fill::setBiff2Data - unexpected conditional formatting flag" );
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->setBiffData(
+ BIFF2_COLOR_BLACK,
+ BIFF2_COLOR_WHITE,
+ getFlagValue( nFlags, BIFF2_XF_BACKGROUND, BIFF_PATT_125, BIFF_PATT_NONE ) );
+}
+
+void Fill::setBiff3Data( sal_uInt16 nArea )
+{
+ OSL_ENSURE( !mbDxf, "Fill::setBiff3Data - unexpected conditional formatting flag" );
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->setBiffData(
+ extractValue< sal_uInt16 >( nArea, 6, 5 ),
+ extractValue< sal_uInt16 >( nArea, 11, 5 ),
+ extractValue< sal_uInt8 >( nArea, 0, 6 ) );
+}
+
+void Fill::setBiff5Data( sal_uInt32 nArea )
+{
+ OSL_ENSURE( !mbDxf, "Fill::setBiff5Data - unexpected conditional formatting flag" );
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->setBiffData(
+ extractValue< sal_uInt16 >( nArea, 0, 7 ),
+ extractValue< sal_uInt16 >( nArea, 7, 7 ),
+ extractValue< sal_uInt8 >( nArea, 16, 6 ) );
+}
+
+void Fill::setBiff8Data( sal_uInt32 nBorder2, sal_uInt16 nArea )
+{
+ OSL_ENSURE( !mbDxf, "Fill::setBiff8Data - unexpected conditional formatting flag" );
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ mxOoxPattData->setBiffData(
+ extractValue< sal_uInt16 >( nArea, 0, 7 ),
+ extractValue< sal_uInt16 >( nArea, 7, 7 ),
+ extractValue< sal_uInt8 >( nBorder2, 26, 6 ) );
+}
+
+void Fill::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags )
+{
+ OSL_ENSURE( mbDxf, "Fill::importCfRule - missing conditional formatting flag" );
+ OSL_ENSURE( getFlag( nFlags, BIFF_CFRULE_FILLBLOCK ), "Fill::importCfRule - missing fill block flag" );
+ mxOoxPattData.reset( new OoxPatternFillData( mbDxf ) );
+ sal_uInt32 nFillData;
+ rStrm >> nFillData;
+ mxOoxPattData->setBiffData(
+ extractValue< sal_uInt16 >( nFillData, 16, 7 ),
+ extractValue< sal_uInt16 >( nFillData, 23, 7 ),
+ extractValue< sal_uInt8 >( nFillData, 10, 6 ) );
+ mxOoxPattData->mbPattColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTCOLOR );
+ mxOoxPattData->mbFillColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_FILLCOLOR );
+ mxOoxPattData->mbPatternUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTERN );
+}
+
+void Fill::finalizeImport()
+{
+ if( mxOoxPattData.get() )
+ {
+ // finalize the OOX data struct
+ OoxPatternFillData& rOoxData = *mxOoxPattData;
+ if( mbDxf )
+ {
+ if( rOoxData.mbFillColorUsed && (!rOoxData.mbPatternUsed || (rOoxData.mnPattern == XML_solid)) )
+ {
+ rOoxData.maPatternColor = rOoxData.maFillColor;
+ rOoxData.mnPattern = XML_solid;
+ rOoxData.mbPattColorUsed = rOoxData.mbPatternUsed = true;
+ }
+ else if( !rOoxData.mbFillColorUsed && rOoxData.mbPatternUsed && (rOoxData.mnPattern == XML_solid) )
+ {
+ rOoxData.mbPatternUsed = false;
+ }
+ }
+
+ // convert to API fill settings
+ maApiData.mbUsed = rOoxData.mbPatternUsed;
+ if( rOoxData.mnPattern == XML_none )
+ {
+ maApiData.mnColor = API_RGB_TRANSPARENT;
+ maApiData.mbTransparent = true;
+ }
+ else
+ {
+ sal_Int32 nAlpha = 0x80;
+ switch( rOoxData.mnPattern )
+ {
+ case XML_darkDown: nAlpha = 0x40; break;
+ case XML_darkGray: nAlpha = 0x60; break;
+ case XML_darkGrid: nAlpha = 0x40; break;
+ case XML_darkHorizontal: nAlpha = 0x40; break;
+ case XML_darkTrellis: nAlpha = 0x60; break;
+ case XML_darkUp: nAlpha = 0x40; break;
+ case XML_darkVertical: nAlpha = 0x40; break;
+ case XML_gray0625: nAlpha = 0x08; break;
+ case XML_gray125: nAlpha = 0x10; break;
+ case XML_lightDown: nAlpha = 0x20; break;
+ case XML_lightGray: nAlpha = 0x20; break;
+ case XML_lightGrid: nAlpha = 0x38; break;
+ case XML_lightHorizontal: nAlpha = 0x20; break;
+ case XML_lightTrellis: nAlpha = 0x30; break;
+ case XML_lightUp: nAlpha = 0x20; break;
+ case XML_lightVertical: nAlpha = 0x20; break;
+ case XML_mediumGray: nAlpha = 0x40; break;
+ case XML_solid: nAlpha = 0x80; break;
+ }
+
+ if( !rOoxData.mbPattColorUsed )
+ rOoxData.maPatternColor.set( XML_auto, 0 );
+ sal_Int32 nPattColor = getStyles().getColor(
+ rOoxData.maPatternColor, ThemeBuffer::getSystemWindowTextColor() );
+
+ if( !rOoxData.mbFillColorUsed )
+ rOoxData.maFillColor.set( XML_auto, 0 );
+ sal_Int32 nFillColor = getStyles().getColor(
+ rOoxData.maFillColor, ThemeBuffer::getSystemWindowColor() );
+
+ maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha );
+ maApiData.mbTransparent = false;
+ }
+ }
+ else if( mxOoxGradData.get() && !mxOoxGradData->maColors.empty() )
+ {
+ OoxGradientFillData& rOoxData = *mxOoxGradData;
+ maApiData.mbUsed = true; // no support for differential attributes
+ OoxGradientFillData::OoxColorMap::const_iterator aIt = rOoxData.maColors.begin();
+ OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
+ maApiData.mnColor = getStyles().getColor( aIt->second, API_RGB_TRANSPARENT );
+ if( ++aIt != rOoxData.maColors.end() )
+ {
+ OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
+ sal_Int32 nEndColor = getStyles().getColor( aIt->second, API_RGB_TRANSPARENT );
+ maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 );
+ maApiData.mbTransparent = false;
+ }
+ }
+}
+
+void Fill::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ getStylesPropertyHelper().writeSolidFillProperties( rPropSet, maApiData );
+}
+
+// ============================================================================
+
+OoxXfData::OoxXfData() :
+ mnStyleXfId( -1 ),
+ mnFontId( -1 ),
+ mnNumFmtId( -1 ),
+ mnBorderId( -1 ),
+ mnFillId( -1 ),
+ mbCellXf( true ),
+ mbFontUsed( false ),
+ mbNumFmtUsed( false ),
+ mbAlignUsed( false ),
+ mbProtUsed( false ),
+ mbBorderUsed( false ),
+ mbAreaUsed( false )
+{
+}
+
+// ============================================================================
+
+Xf::Xf( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maAlignment( rHelper ),
+ maProtection( rHelper )
+{
+}
+
+void Xf::setAllUsedFlags( bool bUsed )
+{
+ maOoxData.mbAlignUsed = maOoxData.mbProtUsed = maOoxData.mbFontUsed =
+ maOoxData.mbNumFmtUsed = maOoxData.mbBorderUsed = maOoxData.mbAreaUsed = bUsed;
+}
+
+void Xf::importXf( const AttributeList& rAttribs, bool bCellXf )
+{
+ maOoxData.mbCellXf = bCellXf;
+ maOoxData.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 );
+ maOoxData.mnFontId = rAttribs.getInteger( XML_fontId, -1 );
+ maOoxData.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 );
+ maOoxData.mnBorderId = rAttribs.getInteger( XML_borderId, -1 );
+ maOoxData.mnFillId = rAttribs.getInteger( XML_fillId, -1 );
+
+ /* Default value of the apply*** attributes is dependent on context:
+ true in cellStyleXfs element, false in cellXfs element... */
+ maOoxData.mbAlignUsed = rAttribs.getBool( XML_applyAlignment, !maOoxData.mbCellXf );
+ maOoxData.mbProtUsed = rAttribs.getBool( XML_applyProtection, !maOoxData.mbCellXf );
+ maOoxData.mbFontUsed = rAttribs.getBool( XML_applyFont, !maOoxData.mbCellXf );
+ maOoxData.mbNumFmtUsed = rAttribs.getBool( XML_applyNumberFormat, !maOoxData.mbCellXf );
+ maOoxData.mbBorderUsed = rAttribs.getBool( XML_applyBorder, !maOoxData.mbCellXf );
+ maOoxData.mbAreaUsed = rAttribs.getBool( XML_applyFill, !maOoxData.mbCellXf );
+}
+
+void Xf::importAlignment( const AttributeList& rAttribs )
+{
+ maAlignment.importAlignment( rAttribs );
+}
+
+void Xf::importProtection( const AttributeList& rAttribs )
+{
+ maProtection.importProtection( rAttribs );
+}
+
+void Xf::importXf( RecordInputStream& rStrm, bool bCellXf )
+{
+ maOoxData.mbCellXf = bCellXf;
+ maOoxData.mnStyleXfId = rStrm.readuInt16();
+ maOoxData.mnNumFmtId = rStrm.readuInt16();
+ maOoxData.mnFontId = rStrm.readuInt16();
+ maOoxData.mnFillId = rStrm.readuInt16();
+ maOoxData.mnBorderId = rStrm.readuInt16();
+ sal_uInt32 nFlags = rStrm.readuInt32();
+ maAlignment.setBinData( nFlags );
+ maProtection.setBinData( nFlags );
+ // used flags, see comments in Xf::setBiffUsedFlags()
+ sal_uInt16 nUsedFlags = rStrm.readuInt16();
+ maOoxData.mbFontUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, OOBIN_XF_FONT_USED );
+ maOoxData.mbNumFmtUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, OOBIN_XF_NUMFMT_USED );
+ maOoxData.mbAlignUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, OOBIN_XF_ALIGN_USED );
+ maOoxData.mbProtUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, OOBIN_XF_PROT_USED );
+ maOoxData.mbBorderUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, OOBIN_XF_BORDER_USED );
+ maOoxData.mbAreaUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, OOBIN_XF_AREA_USED );
+}
+
+void Xf::importXf( BiffInputStream& rStrm )
+{
+ BorderRef xBorder = getStyles().createBorder( &maOoxData.mnBorderId );
+ FillRef xFill = getStyles().createFill( &maOoxData.mnFillId );
+
+ switch( getBiff() )
+ {
+ case BIFF2:
+ {
+ sal_uInt8 nFontId, nNumFmtId, nFlags;
+ rStrm >> nFontId;
+ rStrm.skip( 1 );
+ rStrm >> nNumFmtId >> nFlags;
+
+ // only cell XFs in BIFF2, no parent style, used flags always true
+ setAllUsedFlags( true );
+
+ // attributes
+ maAlignment.setBiff2Data( nFlags );
+ maProtection.setBiff2Data( nNumFmtId );
+ xBorder->setBiff2Data( nFlags );
+ xFill->setBiff2Data( nFlags );
+ maOoxData.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maOoxData.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId & BIFF2_XF_VALFMT_MASK );
+ }
+ break;
+
+ case BIFF3:
+ {
+ sal_uInt32 nBorder;
+ sal_uInt16 nTypeProt, nAlign, nArea;
+ sal_uInt8 nFontId, nNumFmtId;
+ rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent
+ maOoxData.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); // new in BIFF3
+ maOoxData.mnStyleXfId = extractValue< sal_Int32 >( nAlign, 4, 12 ); // new in BIFF3
+ // attribute used flags
+ setBiffUsedFlags( extractValue< sal_uInt8 >( nTypeProt, 10, 6 ) ); // new in BIFF3
+
+ // attributes
+ maAlignment.setBiff3Data( nAlign );
+ maProtection.setBiff3Data( nTypeProt );
+ xBorder->setBiff3Data( nBorder );
+ xFill->setBiff3Data( nArea );
+ maOoxData.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maOoxData.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId );
+ }
+ break;
+
+ case BIFF4:
+ {
+ sal_uInt32 nBorder;
+ sal_uInt16 nTypeProt, nAlign, nArea;
+ sal_uInt8 nFontId, nNumFmtId;
+ rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent
+ maOoxData.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE );
+ maOoxData.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 );
+ // attribute used flags
+ setBiffUsedFlags( extractValue< sal_uInt8 >( nAlign, 10, 6 ) );
+
+ // attributes
+ maAlignment.setBiff4Data( nAlign );
+ maProtection.setBiff3Data( nTypeProt );
+ xBorder->setBiff3Data( nBorder );
+ xFill->setBiff3Data( nArea );
+ maOoxData.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maOoxData.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId );
+ }
+ break;
+
+ case BIFF5:
+ {
+ sal_uInt32 nArea, nBorder;
+ sal_uInt16 nFontId, nNumFmtId, nTypeProt, nAlign;
+ rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder;
+
+ // XF type/parent
+ maOoxData.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE );
+ maOoxData.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 );
+ // attribute used flags
+ setBiffUsedFlags( extractValue< sal_uInt8 >( nAlign, 10, 6 ) );
+
+ // attributes
+ maAlignment.setBiff5Data( nAlign );
+ maProtection.setBiff3Data( nTypeProt );
+ xBorder->setBiff5Data( nBorder, nArea );
+ xFill->setBiff5Data( nArea );
+ maOoxData.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maOoxData.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId );
+ }
+ break;
+
+ case BIFF8:
+ {
+ sal_uInt32 nBorder1, nBorder2;
+ sal_uInt16 nFontId, nNumFmtId, nTypeProt, nAlign, nMiscAttrib, nArea;
+ rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea;
+
+ // XF type/parent
+ maOoxData.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE );
+ maOoxData.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 );
+ // attribute used flags
+ setBiffUsedFlags( extractValue< sal_uInt8 >( nMiscAttrib, 10, 6 ) );
+
+ // attributes
+ maAlignment.setBiff8Data( nAlign, nMiscAttrib );
+ maProtection.setBiff3Data( nTypeProt );
+ xBorder->setBiff8Data( nBorder1, nBorder2 );
+ xFill->setBiff8Data( nBorder2, nArea );
+ maOoxData.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maOoxData.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId );
+ }
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+}
+
+void Xf::finalizeImport()
+{
+ // alignment and protection
+ maAlignment.finalizeImport();
+ maProtection.finalizeImport();
+ // update used flags from cell style
+ if( maOoxData.mbCellXf )
+ if( const Xf* pStyleXf = getStyles().getStyleXf( maOoxData.mnStyleXfId ).get() )
+ updateUsedFlags( *pStyleXf );
+}
+
+FontRef Xf::getFont() const
+{
+ return getStyles().getFont( maOoxData.mnFontId );
+}
+
+bool Xf::hasAnyUsedFlags() const
+{
+ return
+ maOoxData.mbAlignUsed || maOoxData.mbProtUsed || maOoxData.mbFontUsed ||
+ maOoxData.mbNumFmtUsed || maOoxData.mbBorderUsed || maOoxData.mbAreaUsed;
+}
+
+void Xf::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ StylesBuffer& rStyles = getStyles();
+
+ // create and set cell style
+ if( maOoxData.mbCellXf )
+ {
+ const OUString& rStyleName = rStyles.createCellStyle( maOoxData.mnStyleXfId );
+ rPropSet.setProperty( CREATE_OUSTRING( "CellStyle" ), rStyleName );
+ }
+
+ if( maOoxData.mbFontUsed )
+ rStyles.writeFontToPropertySet( rPropSet, maOoxData.mnFontId );
+ if( maOoxData.mbNumFmtUsed )
+ rStyles.writeNumFmtToPropertySet( rPropSet, maOoxData.mnNumFmtId );
+ if( maOoxData.mbAlignUsed )
+ maAlignment.writeToPropertySet( rPropSet );
+ if( maOoxData.mbProtUsed )
+ maProtection.writeToPropertySet( rPropSet );
+ if( maOoxData.mbBorderUsed )
+ rStyles.writeBorderToPropertySet( rPropSet, maOoxData.mnBorderId );
+ if( maOoxData.mbAreaUsed )
+ rStyles.writeFillToPropertySet( rPropSet, maOoxData.mnFillId );
+}
+
+void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags )
+{
+ /* Notes about finding the used flags:
+ - In cell XFs a *set* bit means a used attribute.
+ - In style XFs a *cleared* bit means a used attribute.
+ The boolean flags always store true, if the attribute is used.
+ The "maOoxData.mbCellXf == getFlag(...)" construct evaluates to true in
+ both mentioned cases: cell XF and set bit; or style XF and cleared bit.
+ */
+ maOoxData.mbFontUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, BIFF_XF_FONT_USED );
+ maOoxData.mbNumFmtUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED );
+ maOoxData.mbAlignUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED );
+ maOoxData.mbProtUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, BIFF_XF_PROT_USED );
+ maOoxData.mbBorderUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, BIFF_XF_BORDER_USED );
+ maOoxData.mbAreaUsed = maOoxData.mbCellXf == getFlag( nUsedFlags, BIFF_XF_AREA_USED );
+}
+
+void Xf::updateUsedFlags( const Xf& rStyleXf )
+{
+ /* Enables the used flags, if the formatting attributes differ from the
+ passed style XF. In cell XFs Excel uses the cell attributes, if they
+ differ from the parent style XF.
+ #109899# ...or if the respective flag is not set in parent style XF.
+ */
+ const OoxXfData& rStyleData = rStyleXf.maOoxData;
+ if( !maOoxData.mbFontUsed )
+ maOoxData.mbFontUsed = !rStyleData.mbFontUsed || (maOoxData.mnFontId != rStyleData.mnFontId);
+ if( !maOoxData.mbNumFmtUsed )
+ maOoxData.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maOoxData.mnNumFmtId != rStyleData.mnNumFmtId);
+ if( !maOoxData.mbAlignUsed )
+ maOoxData.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == rStyleXf.maAlignment.getApiData());
+ if( !maOoxData.mbProtUsed )
+ maOoxData.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == rStyleXf.maProtection.getApiData());
+ if( !maOoxData.mbBorderUsed )
+ maOoxData.mbBorderUsed = !rStyleData.mbBorderUsed || (maOoxData.mnBorderId != rStyleData.mnBorderId);
+ if( !maOoxData.mbAreaUsed )
+ maOoxData.mbAreaUsed = !rStyleData.mbAreaUsed || (maOoxData.mnFillId != rStyleData.mnFillId);
+}
+
+// ============================================================================
+
+Dxf::Dxf( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+FontRef Dxf::importFont( const AttributeList& )
+{
+ createFont( true );
+ return mxFont;
+}
+
+void Dxf::importNumFmt( const AttributeList& rAttribs )
+{
+ mxNumFmt = getStyles().importNumFmt( rAttribs );
+}
+
+void Dxf::importAlignment( const AttributeList& rAttribs )
+{
+ mxAlignment.reset( new Alignment( *this ) );
+ mxAlignment->importAlignment( rAttribs );
+}
+
+void Dxf::importProtection( const AttributeList& rAttribs )
+{
+ mxProtection.reset( new Protection( *this ) );
+ mxProtection->importProtection( rAttribs );
+}
+
+BorderRef Dxf::importBorder( const AttributeList& rAttribs )
+{
+ createBorder( true );
+ mxBorder->importBorder( rAttribs );
+ return mxBorder;
+}
+
+FillRef Dxf::importFill( const AttributeList& )
+{
+ createFill( true );
+ return mxFill;
+}
+
+void Dxf::importDxf( RecordInputStream& rStrm )
+{
+ sal_Int32 nNumFmtId = -1;
+ OUString aFmtCode;
+ sal_uInt16 nRecCount;
+ rStrm.skip( 4 ); // flags
+ rStrm >> nRecCount;
+ for( sal_uInt16 nRec = 0; rStrm.isValid() && (nRec < nRecCount); ++nRec )
+ {
+ sal_uInt16 nSubRecId, nSubRecSize;
+ sal_Int32 nRecEnd = rStrm.getRecPos();
+ rStrm >> nSubRecId >> nSubRecSize;
+ nRecEnd += nSubRecSize;
+ switch( nSubRecId )
+ {
+ case OOBIN_DXF_FILL_PATTERN: createFill( false ); mxFill->importDxfPattern( rStrm ); break;
+ case OOBIN_DXF_FILL_FGCOLOR: createFill( false ); mxFill->importDxfFgColor( rStrm ); break;
+ case OOBIN_DXF_FILL_BGCOLOR: createFill( false ); mxFill->importDxfBgColor( rStrm ); break;
+ case OOBIN_DXF_FILL_GRADIENT: createFill( false ); mxFill->importDxfGradient( rStrm ); break;
+ case OOBIN_DXF_FILL_STOP: createFill( false ); mxFill->importDxfStop( rStrm ); break;
+ case OOBIN_DXF_FONT_COLOR: createFont( false ); mxFont->importDxfColor( rStrm ); break;
+ case OOBIN_DXF_BORDER_TOP: createBorder( false ); mxBorder->importDxfBorder( XLS_TOKEN( top ), rStrm ); break;
+ case OOBIN_DXF_BORDER_BOTTOM: createBorder( false ); mxBorder->importDxfBorder( XLS_TOKEN( bottom ), rStrm ); break;
+ case OOBIN_DXF_BORDER_LEFT: createBorder( false ); mxBorder->importDxfBorder( XLS_TOKEN( left ), rStrm ); break;
+ case OOBIN_DXF_BORDER_RIGHT: createBorder( false ); mxBorder->importDxfBorder( XLS_TOKEN( right ), rStrm ); break;
+ case OOBIN_DXF_FONT_NAME: createFont( false ); mxFont->importDxfName( rStrm ); break;
+ case OOBIN_DXF_FONT_WEIGHT: createFont( false ); mxFont->importDxfWeight( rStrm ); break;
+ case OOBIN_DXF_FONT_UNDERLINE: createFont( false ); mxFont->importDxfUnderline( rStrm ); break;
+ case OOBIN_DXF_FONT_ESCAPEMENT: createFont( false ); mxFont->importDxfEscapement( rStrm ); break;
+ case OOBIN_DXF_FONT_ITALIC: createFont( false ); mxFont->importDxfFlag( XML_i, rStrm ); break;
+ case OOBIN_DXF_FONT_STRIKE: createFont( false ); mxFont->importDxfFlag( XML_strike, rStrm ); break;
+ case OOBIN_DXF_FONT_OUTLINE: createFont( false ); mxFont->importDxfFlag( XML_outline, rStrm ); break;
+ case OOBIN_DXF_FONT_SHADOW: createFont( false ); mxFont->importDxfFlag( XML_shadow, rStrm ); break;
+ case OOBIN_DXF_FONT_HEIGHT: createFont( false ); mxFont->importDxfHeight( rStrm ); break;
+ case OOBIN_DXF_FONT_SCHEME: createFont( false ); mxFont->importDxfScheme( rStrm ); break;
+ case OOBIN_DXF_NUMFMT_CODE: aFmtCode = rStrm.readString( false ); break;
+ case OOBIN_DXF_NUMFMT_ID: nNumFmtId = rStrm.readuInt16(); break;
+ }
+ rStrm.seek( nRecEnd );
+ }
+ OSL_ENSURE( rStrm.isValid() && (rStrm.getRecLeft() == 0), "Dxf::importDxf - unexpected remaining data" );
+ mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode );
+}
+
+void Dxf::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags )
+{
+ if( getFlag( nFlags, BIFF_CFRULE_FONTBLOCK ) )
+ {
+ createFont( true );
+ mxFont->importCfRule( rStrm );
+ }
+ if( getFlag( nFlags, BIFF_CFRULE_ALIGNBLOCK ) )
+ {
+ rStrm.skip( 8 );
+ }
+ if( getFlag( nFlags, BIFF_CFRULE_BORDERBLOCK ) )
+ {
+ createBorder( true );
+ mxBorder->importCfRule( rStrm, nFlags );
+ }
+ if( getFlag( nFlags, BIFF_CFRULE_FILLBLOCK ) )
+ {
+ createFill( true );
+ mxFill->importCfRule( rStrm, nFlags );
+ }
+ if( getFlag( nFlags, BIFF_CFRULE_PROTBLOCK ) )
+ {
+ rStrm.skip( 2 );
+ }
+}
+
+void Dxf::finalizeImport()
+{
+ if( mxFont.get() )
+ mxFont->finalizeImport();
+ // number format already finalized by the number formats buffer
+ if( mxAlignment.get() )
+ mxAlignment->finalizeImport();
+ if( mxProtection.get() )
+ mxProtection->finalizeImport();
+ if( mxBorder.get() )
+ mxBorder->finalizeImport();
+ if( mxFill.get() )
+ mxFill->finalizeImport();
+}
+
+const OUString& Dxf::createDxfStyle( sal_Int32 nDxfId )
+{
+ if( maFinalName.getLength() == 0 )
+ {
+ maFinalName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear();
+ Reference< XStyle > xStyle = createStyleObject( maFinalName, false );
+ // write style formatting properties
+ PropertySet aPropSet( xStyle );
+ if( mxFont.get() )
+ mxFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_CELL );
+ if( mxNumFmt.get() )
+ mxNumFmt->writeToPropertySet( aPropSet );
+ if( mxAlignment.get() )
+ mxAlignment->writeToPropertySet( aPropSet );
+ if( mxProtection.get() )
+ mxProtection->writeToPropertySet( aPropSet );
+ if( mxBorder.get() )
+ mxBorder->writeToPropertySet( aPropSet );
+ if( mxFill.get() )
+ mxFill->writeToPropertySet( aPropSet );
+ }
+ return maFinalName;
+}
+
+void Dxf::createFont( bool bAlwaysNew )
+{
+ if( bAlwaysNew || !mxFont )
+ mxFont.reset( new Font( *this, true ) );
+}
+
+void Dxf::createBorder( bool bAlwaysNew )
+{
+ if( bAlwaysNew || !mxBorder )
+ mxBorder.reset( new Border( *this, true ) );
+}
+
+void Dxf::createFill( bool bAlwaysNew )
+{
+ if( bAlwaysNew || !mxFill )
+ mxFill.reset( new Fill( *this, true ) );
+}
+
+// ============================================================================
+
+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",
+ "Currency",
+ "Percent",
+ "Comma_0", // new in BIFF4
+ "Currency_0",
+ "Hyperlink", // new in BIFF8
+ "Followed_Hyperlink"
+};
+const sal_Int32 snLegacyStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( sppcLegacyStyleNames ) );
+
+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",
+ "Currency",
+ "Percent",
+ "Comma [0]", // new in BIFF4
+ "Currency [0]",
+ "Hyperlink", // new in BIFF8
+ "Followed Hyperlink",
+ "Note", // new in OOX
+ "Warning Text",
+ "",
+ "",
+ "",
+ "Title",
+ "Heading 1",
+ "Heading 2",
+ "Heading 3",
+ "Heading 4",
+ "Input",
+ "Output",
+ "Calculation",
+ "Check Cell",
+ "Linked Cell",
+ "Total",
+ "Good",
+ "Bad",
+ "Neutral",
+ "Accent1",
+ "20% - Accent1",
+ "40% - Accent1",
+ "60% - Accent1",
+ "Accent2",
+ "20% - Accent2",
+ "40% - Accent2",
+ "60% - Accent2",
+ "Accent3",
+ "20% - Accent3",
+ "40% - Accent3",
+ "60% - Accent3",
+ "Accent4",
+ "20% - Accent4",
+ "40% - Accent4",
+ "60% - Accent4",
+ "Accent5",
+ "20% - Accent5",
+ "40% - Accent5",
+ "60% - Accent5",
+ "Accent6",
+ "20% - Accent6",
+ "40% - Accent6",
+ "60% - Accent6",
+ "Explanatory Text"
+};
+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 )
+{
+ 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 );
+ }
+ 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
+ return aStyleName.makeStringAndClear();
+}
+
+bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar )
+{
+#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
+
+ // try the other builtin styles
+ OUString aPrefix = OUString::createFromAscii( spcStyleNamePrefix );
+ sal_Int32 nPrefixLen = aPrefix.getLength();
+ sal_Int32 nFoundId = 0;
+ sal_Int32 nNextChar = 0;
+ if( rStyleName.matchIgnoreAsciiCase( aPrefix ) )
+ {
+ OUString aShortName;
+ for( sal_Int32 nId = 0; nId < snStyleNamesCount; ++nId )
+ {
+#if OOX_XLS_USE_DEFAULT_STYLE
+ if( nId != OOX_STYLE_NORMAL )
+ {
+#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
+ }
+#endif
+ }
+ }
+
+ if( nNextChar > 0 )
+ {
+ if( pnBuiltinId ) *pnBuiltinId = nFoundId;
+ if( pnNextChar ) *pnNextChar = nNextChar;
+ return true;
+ }
+
+ if( pnBuiltinId ) *pnBuiltinId = -1;
+ if( pnNextChar ) *pnNextChar = 0;
+ return false;
+}
+
+bool lclGetBuiltinStyleId( sal_Int32& rnBuiltinId, sal_Int32& rnLevel, const OUString& rStyleName )
+{
+ sal_Int32 nBuiltinId;
+ sal_Int32 nNextChar;
+ if( lclIsBuiltinStyleName( rStyleName, &nBuiltinId, &nNextChar ) )
+ {
+ if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) )
+ {
+ OUString aLevel = rStyleName.copy( nNextChar );
+ sal_Int32 nLevel = aLevel.toInt32();
+ if( (0 < nLevel) && (nLevel <= OOX_STYLE_LEVELCOUNT) )
+ {
+ rnBuiltinId = nBuiltinId;
+ rnLevel = nLevel;
+ return true;
+ }
+ }
+ else if( rStyleName.getLength() == nNextChar )
+ {
+ rnBuiltinId = nBuiltinId;
+ rnLevel = 0;
+ return true;
+ }
+ }
+ rnBuiltinId = -1;
+ rnLevel = 0;
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+OoxCellStyleData::OoxCellStyleData() :
+ mnXfId( -1 ),
+ mnBuiltinId( -1 ),
+ mnLevel( 0 ),
+ mbBuiltin( false ),
+ mbCustom( false ),
+ mbHidden( false )
+{
+}
+
+bool OoxCellStyleData::isDefaultStyle() const
+{
+ return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL);
+}
+
+OUString OoxCellStyleData::createStyleName() const
+{
+ return isBuiltin() ? lclGetBuiltinStyleName( mnBuiltinId, maName, mnLevel ) : maName;
+}
+
+// ============================================================================
+
+CellStyle::CellStyle( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void CellStyle::importCellStyle( const AttributeList& rAttribs )
+{
+ maOoxData.maName = rAttribs.getString( XML_name );
+ maOoxData.mnXfId = rAttribs.getInteger( XML_xfId, -1 );
+ maOoxData.mnBuiltinId = rAttribs.getInteger( XML_builtinId, -1 );
+ maOoxData.mnLevel = rAttribs.getInteger( XML_iLevel, 0 );
+ maOoxData.mbBuiltin = rAttribs.hasAttribute( XML_builtinId );
+ maOoxData.mbCustom = rAttribs.getBool( XML_customBuiltin, false );
+ maOoxData.mbHidden = rAttribs.getBool( XML_hidden, false );
+}
+
+void CellStyle::importCellStyle( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> maOoxData.mnXfId >> nFlags;
+ maOoxData.mnBuiltinId = rStrm.readuInt8();
+ maOoxData.mnLevel = rStrm.readuInt8();
+ rStrm >> maOoxData.maName;
+ maOoxData.mbBuiltin = getFlag( nFlags, OOBIN_CELLSTYLE_BUILTIN );
+ maOoxData.mbCustom = getFlag( nFlags, OOBIN_CELLSTYLE_CUSTOM );
+ maOoxData.mbHidden = getFlag( nFlags, OOBIN_CELLSTYLE_HIDDEN );
+}
+
+void CellStyle::importStyle( BiffInputStream& rStrm )
+{
+ sal_uInt16 nStyleXf;
+ rStrm >> nStyleXf;
+ maOoxData.mnXfId = static_cast< sal_Int32 >( nStyleXf & BIFF_STYLE_XFMASK );
+ maOoxData.mbBuiltin = getFlag( nStyleXf, BIFF_STYLE_BUILTIN );
+ if( maOoxData.mbBuiltin )
+ {
+ maOoxData.mnBuiltinId = rStrm.readuInt8();
+ maOoxData.mnLevel = rStrm.readuInt8();
+ }
+ else
+ {
+ maOoxData.maName = (getBiff() == BIFF8) ?
+ rStrm.readUniString() : rStrm.readByteString( false, getTextEncoding() );
+ }
+}
+
+const OUString& CellStyle::createCellStyle( sal_Int32 nXfId, bool bSkipDefaultBuiltin )
+{
+ if( maFinalName.getLength() == 0 )
+ {
+ bool bBuiltin = maOoxData.isBuiltin();
+ if( !bSkipDefaultBuiltin || !bBuiltin || maOoxData.mbCustom )
+ {
+ // name of the style (generate unique name for builtin styles)
+ maFinalName = maOoxData.createStyleName();
+ // #i1624# #i1768# ignore unnamed user styles
+ if( maFinalName.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( maFinalName, 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( maFinalName, false, bRenameExisting );
+#if OOX_XLS_USE_DEFAULT_STYLE
+ }
+#endif
+
+ // 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
+ }
+ }
+ }
+ return maFinalName;
+}
+
+// ============================================================================
+
+namespace {
+
+sal_Int32 lclTintToColor( sal_Int32 nColor, double fTint )
+{
+ if( nColor == 0x000000 )
+ return 0x010101 * static_cast< sal_Int32 >( ::std::max( fTint, 0.0 ) * 255.0 );
+ if( nColor == 0xFFFFFF )
+ return 0x010101 * static_cast< sal_Int32 >( ::std::min( fTint + 1.0, 1.0 ) * 255.0 );
+
+ sal_Int32 nR = (nColor >> 16) & 0xFF;
+ sal_Int32 nG = (nColor >> 8) & 0xFF;
+ sal_Int32 nB = nColor & 0xFF;
+
+ double fMean = (::std::min( ::std::min( nR, nG ), nB ) + ::std::max( ::std::max( nR, nG ), nB )) / 2.0;
+ double fTintTh = (fMean <= 127.5) ? ((127.5 - fMean) / (255.0 - fMean)) : (127.5 / fMean - 1.0);
+ if( (fTintTh < 0.0) || ((fTintTh == 0.0) && (fTint <= 0.0)) )
+ {
+ double fTintMax = 255.0 / fMean - 1.0;
+ double fRTh = fTintTh / fTintMax * (255.0 - nR) + nR;
+ double fGTh = fTintTh / fTintMax * (255.0 - nG) + nG;
+ double fBTh = fTintTh / fTintMax * (255.0 - nB) + nB;
+ if( fTint <= fTintTh )
+ {
+ double fFactor = (fTint + 1.0) / (fTintTh + 1.0);
+ nR = static_cast< sal_Int32 >( fFactor * fRTh + 0.5 );
+ nG = static_cast< sal_Int32 >( fFactor * fGTh + 0.5 );
+ nB = static_cast< sal_Int32 >( fFactor * fBTh + 0.5 );
+ }
+ else
+ {
+ double fFactor = (fTint > 0.0) ? (fTint * fTintMax / fTintTh) : (fTint / fTintTh);
+ nR = static_cast< sal_Int32 >( fFactor * fRTh + (1.0 - fFactor) * nR + 0.5 );
+ nG = static_cast< sal_Int32 >( fFactor * fGTh + (1.0 - fFactor) * nG + 0.5 );
+ nB = static_cast< sal_Int32 >( fFactor * fBTh + (1.0 - fFactor) * nB + 0.5 );
+ }
+ }
+ else
+ {
+ double fTintMin = fMean / (fMean - 255.0);
+ double fRTh = (1.0 - fTintTh / fTintMin) * nR;
+ double fGTh = (1.0 - fTintTh / fTintMin) * nG;
+ double fBTh = (1.0 - fTintTh / fTintMin) * nB;
+ if( fTint <= fTintTh )
+ {
+ double fFactor = (fTint < 0.0) ? (fTint * -fTintMin / fTintTh) : (fTint / fTintTh);
+ nR = static_cast< sal_Int32 >( fFactor * fRTh + (1.0 - fFactor) * nR + 0.5 );
+ nG = static_cast< sal_Int32 >( fFactor * fGTh + (1.0 - fFactor) * nG + 0.5 );
+ nB = static_cast< sal_Int32 >( fFactor * fBTh + (1.0 - fFactor) * nB + 0.5 );
+ }
+ else
+ {
+ double fFactor = (1.0 - fTint) / (1.0 - fTintTh);
+ nR = static_cast< sal_Int32 >( 255.5 - fFactor * (255.0 - fRTh) );
+ nG = static_cast< sal_Int32 >( 255.5 - fFactor * (255.0 - fGTh) );
+ nB = static_cast< sal_Int32 >( 255.5 - fFactor * (255.0 - fBTh) );
+ }
+ }
+
+ return (nR << 16) | (nG << 8) | nB;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maPalette( rHelper ),
+ maNumFmts( rHelper ),
+ maDefStyleName( lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ) ),
+ mnDefStyleXf( -1 )
+{
+}
+
+FontRef StylesBuffer::createFont( sal_Int32* opnFontId )
+{
+ if( opnFontId ) *opnFontId = static_cast< sal_Int32 >( maFonts.size() );
+ FontRef xFont( new Font( *this, false ) );
+ maFonts.push_back( xFont );
+ return xFont;
+}
+
+NumberFormatRef StylesBuffer::createNumFmt( sal_Int32 nNumFmtId, const OUString& rFmtCode )
+{
+ return maNumFmts.createNumFmt( nNumFmtId, rFmtCode );
+}
+
+BorderRef StylesBuffer::createBorder( sal_Int32* opnBorderId )
+{
+ if( opnBorderId ) *opnBorderId = static_cast< sal_Int32 >( maBorders.size() );
+ BorderRef xBorder( new Border( *this, false ) );
+ maBorders.push_back( xBorder );
+ return xBorder;
+}
+
+FillRef StylesBuffer::createFill( sal_Int32* opnFillId )
+{
+ if( opnFillId ) *opnFillId = static_cast< sal_Int32 >( maFills.size() );
+ FillRef xFill( new Fill( *this, false ) );
+ maFills.push_back( xFill );
+ return xFill;
+}
+
+XfRef StylesBuffer::createCellXf( sal_Int32* opnXfId )
+{
+ if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maCellXfs.size() );
+ XfRef xXf( new Xf( *this ) );
+ maCellXfs.push_back( xXf );
+ return xXf;
+}
+
+XfRef StylesBuffer::createStyleXf( sal_Int32* opnXfId )
+{
+ if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maStyleXfs.size() );
+ XfRef xXf( new Xf( *this ) );
+ maStyleXfs.push_back( xXf );
+ return xXf;
+}
+
+DxfRef StylesBuffer::createDxf( sal_Int32* opnDxfId )
+{
+ if( opnDxfId ) *opnDxfId = static_cast< sal_Int32 >( maDxfs.size() );
+ DxfRef xDxf( new Dxf( *this ) );
+ maDxfs.push_back( xDxf );
+ return xDxf;
+}
+
+void StylesBuffer::importPaletteColor( const AttributeList& rAttribs )
+{
+ maPalette.importPaletteColor( rAttribs );
+}
+
+FontRef StylesBuffer::importFont( const AttributeList& )
+{
+ return createFont();
+}
+
+NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs )
+{
+ return maNumFmts.importNumFmt( rAttribs );
+}
+
+BorderRef StylesBuffer::importBorder( const AttributeList& rAttribs )
+{
+ BorderRef xBorder = createBorder();
+ xBorder->importBorder( rAttribs );
+ return xBorder;
+}
+
+FillRef StylesBuffer::importFill( const AttributeList& )
+{
+ return createFill();
+}
+
+XfRef StylesBuffer::importXf( sal_Int32 nContext, const AttributeList& rAttribs )
+{
+ XfRef xXf;
+ switch( nContext )
+ {
+ case XLS_TOKEN( cellXfs ):
+ xXf = createCellXf();
+ xXf->importXf( rAttribs, true );
+ break;
+ case XLS_TOKEN( cellStyleXfs ):
+ xXf = createStyleXf();
+ xXf->importXf( rAttribs, false );
+ break;
+ }
+ return xXf;
+}
+
+DxfRef StylesBuffer::importDxf( const AttributeList& )
+{
+ return createDxf();
+}
+
+CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs )
+{
+ CellStyleRef xCellStyle( new CellStyle( *this ) );
+ xCellStyle->importCellStyle( rAttribs );
+ insertCellStyle( xCellStyle );
+ return xCellStyle;
+}
+
+void StylesBuffer::importPaletteColor( RecordInputStream& rStrm )
+{
+ maPalette.importPaletteColor( rStrm );
+}
+
+void StylesBuffer::importFont( RecordInputStream& rStrm )
+{
+ createFont()->importFont( rStrm );
+}
+
+void StylesBuffer::importNumFmt( RecordInputStream& rStrm )
+{
+ maNumFmts.importNumFmt( rStrm );
+}
+
+void StylesBuffer::importBorder( RecordInputStream& rStrm )
+{
+ createBorder()->importBorder( rStrm );
+}
+
+void StylesBuffer::importFill( RecordInputStream& rStrm )
+{
+ createFill()->importFill( rStrm );
+}
+
+void StylesBuffer::importXf( sal_Int32 nContext, RecordInputStream& rStrm )
+{
+ switch( nContext )
+ {
+ case OOBIN_ID_CELLXFS:
+ createCellXf()->importXf( rStrm, true );
+ break;
+ case OOBIN_ID_CELLSTYLEXFS:
+ createStyleXf()->importXf( rStrm, false );
+ break;
+ }
+}
+
+void StylesBuffer::importDxf( RecordInputStream& rStrm )
+{
+ createDxf()->importDxf( rStrm );
+}
+
+void StylesBuffer::importCellStyle( RecordInputStream& rStrm )
+{
+ CellStyleRef xCellStyle( new CellStyle( *this ) );
+ xCellStyle->importCellStyle( rStrm );
+ insertCellStyle( xCellStyle );
+}
+
+void StylesBuffer::importPalette( BiffInputStream& rStrm )
+{
+ maPalette.importPalette( rStrm );
+}
+
+void StylesBuffer::importFont( BiffInputStream& rStrm )
+{
+ /* Font with index 4 is not stored in BIFF. This means effectively, first
+ font in the BIFF file has index 0, fourth font has index 3, and fifth
+ font has index 5. Insert a dummy font to correctly map passed font
+ identifiers. */
+ if( maFonts.size() == 4 )
+ maFonts.push_back( maFonts.front() );
+
+ FontRef xFont = createFont();
+ xFont->importFont( rStrm );
+
+ /* #i71033# Set stream text encoding from application font, if CODEPAGE
+ record is missing. Must be done now (not while finalizeImport() runs),
+ to be able to read all following byte strings correctly (e.g. cell
+ style names). */
+ if( maFonts.size() == 1 )
+ setAppFontEncoding( xFont->getFontEncoding() );
+}
+
+void StylesBuffer::importFontColor( BiffInputStream& rStrm )
+{
+ if( !maFonts.empty() )
+ maFonts.back()->importFontColor( rStrm );
+}
+
+void StylesBuffer::importFormat( BiffInputStream& rStrm )
+{
+ maNumFmts.importFormat( rStrm );
+}
+
+void StylesBuffer::importXf( BiffInputStream& rStrm )
+{
+ XfRef xXf( new Xf( *this ) );
+ // store XF in both lists (except BIFF2 which does not support cell styles)
+ maCellXfs.push_back( xXf );
+ if( getBiff() != BIFF2 )
+ maStyleXfs.push_back( xXf );
+ xXf->importXf( rStrm );
+}
+
+void StylesBuffer::importStyle( BiffInputStream& rStrm )
+{
+ CellStyleRef xCellStyle( new CellStyle( *this ) );
+ xCellStyle->importStyle( rStrm );
+ insertCellStyle( xCellStyle );
+}
+
+void StylesBuffer::finalizeImport()
+{
+ // fonts first, are needed to finalize unit converter and XFs below
+ maFonts.forEachMem( &Font::finalizeImport );
+ // finalize unit converter after default font is known
+ getUnitConverter().finalizeImport();
+ // number formats
+ maNumFmts.finalizeImport();
+ // borders and fills
+ maBorders.forEachMem( &Border::finalizeImport );
+ maFills.forEachMem( &Fill::finalizeImport );
+
+ /* Style XFs and cell XFs. The BIFF format stores cell XFs and style XFs
+ mixed in a single list. The import filter has stored the XFs in both
+ lists to make the getStyleXf() function working correctly (e.g. for
+ retrieving the default font, see getDefaultFont() function), except for
+ BIFF2 which does not support cell styles at all. Therefore, if in BIFF
+ filter mode, we do not need to finalize the cell styles list. */
+ if( getFilterType() == FILTER_OOX )
+ maStyleXfs.forEachMem( &Xf::finalizeImport );
+ maCellXfs.forEachMem( &Xf::finalizeImport );
+
+ // conditional formatting
+ 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 );
+}
+
+sal_Int32 StylesBuffer::getColor( const OoxColor& rColor, sal_Int32 nAuto ) const
+{
+ sal_Int32 nColor = API_RGB_TRANSPARENT;
+ switch( rColor.mnType )
+ {
+ case XML_auto:
+ nColor = nAuto;
+ break;
+ case XML_rgb:
+ nColor = rColor.mnValue & 0xFFFFFF;
+ break;
+ case XML_theme:
+ nColor = getTheme().getColorByIndex( rColor.mnValue );
+ break;
+ case XML_indexed:
+ nColor = maPalette.getColor( rColor.mnValue );
+ break;
+ default:
+ OSL_ENSURE( false, "StylesBuffer::getColor - unknown color type" );
+ }
+ if( (rColor.mnType != XML_auto) && (nColor != API_RGB_TRANSPARENT) && (rColor.mfTint >= -1.0) && (rColor.mfTint != 0.0) && (rColor.mfTint <= 1.0) )
+ nColor = lclTintToColor( nColor, rColor.mfTint );
+ return nColor;
+}
+
+FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const
+{
+ return maFonts.get( nFontId );
+}
+
+XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const
+{
+ return maCellXfs.get( nXfId );
+}
+
+XfRef StylesBuffer::getStyleXf( sal_Int32 nXfId ) const
+{
+ return maStyleXfs.get( nXfId );
+}
+
+DxfRef StylesBuffer::getDxf( sal_Int32 nDxfId ) const
+{
+ return maDxfs.get( nDxfId );
+}
+
+FontRef StylesBuffer::getFontFromCellXf( sal_Int32 nXfId ) const
+{
+ FontRef xFont;
+ if( const Xf* pXf = getCellXf( nXfId ).get() )
+ xFont = pXf->getFont();
+ return xFont;
+}
+
+FontRef StylesBuffer::getDefaultFont() const
+{
+ FontRef xDefFont;
+ if( const Xf* pXf = getStyleXf( mnDefStyleXf ).get() )
+ xDefFont = pXf->getFont();
+ // no font from styles - try first loaded font (e.g. BIFF2)
+ if( !xDefFont )
+ xDefFont = maFonts.get( 0 );
+ OSL_ENSURE( xDefFont.get(), "StylesBuffer::getDefaultFont - no default font found" );
+ return xDefFont;
+}
+
+const OoxFontData& StylesBuffer::getDefaultFontData() const
+{
+ FontRef xDefFont = getDefaultFont();
+ return xDefFont.get() ? xDefFont->getFontData() : getTheme().getDefaultFontData();
+}
+
+const OUString& StylesBuffer::createCellStyle( sal_Int32 nXfId ) const
+{
+ if( CellStyle* pCellStyle = maCellStyles.get( nXfId ).get() )
+ return pCellStyle->createCellStyle( nXfId );
+ // on error: fallback to default style
+ return maDefStyleName;
+}
+
+const OUString& StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
+{
+ if( Dxf* pDxf = maDxfs.get( nDxfId ).get() )
+ return pDxf->createDxfStyle( nDxfId );
+ // on error: fallback to default style
+ return maDefStyleName;
+}
+
+#if OOX_XLS_USE_DEFAULT_STYLE
+#else
+const OUString& StylesBuffer::getDefaultStyleName() const
+{
+ return createCellStyle( mnDefStyleXf );
+}
+#endif
+
+void StylesBuffer::writeFontToPropertySet( PropertySet& rPropSet, sal_Int32 nFontId ) const
+{
+ if( Font* pFont = maFonts.get( nFontId ).get() )
+ pFont->writeToPropertySet( rPropSet, FONT_PROPTYPE_CELL );
+}
+
+void StylesBuffer::writeNumFmtToPropertySet( PropertySet& rPropSet, sal_Int32 nNumFmtId ) const
+{
+ maNumFmts.writeToPropertySet( rPropSet, nNumFmtId );
+}
+
+void StylesBuffer::writeBorderToPropertySet( PropertySet& rPropSet, sal_Int32 nBorderId ) const
+{
+ if( Border* pBorder = maBorders.get( nBorderId ).get() )
+ pBorder->writeToPropertySet( rPropSet );
+}
+
+void StylesBuffer::writeFillToPropertySet( PropertySet& rPropSet, sal_Int32 nFillId ) const
+{
+ if( Fill* pFill = maFills.get( nFillId ).get() )
+ pFill->writeToPropertySet( rPropSet );
+}
+
+void StylesBuffer::writeCellXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const
+{
+ if( Xf* pXf = maCellXfs.get( nXfId ).get() )
+ pXf->writeToPropertySet( rPropSet );
+}
+
+void StylesBuffer::writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const
+{
+ if( Xf* pXf = maStyleXfs.get( nXfId ).get() )
+ pXf->writeToPropertySet( rPropSet );
+}
+
+void StylesBuffer::insertCellStyle( CellStyleRef xCellStyle )
+{
+ if( xCellStyle->getXfId() >= 0 )
+ {
+ maCellStyles[ xCellStyle->getXfId() ] = xCellStyle;
+ if( xCellStyle->isDefaultStyle() )
+ mnDefStyleXf = xCellStyle->getXfId();
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/stylesfragment.cxx b/oox/source/xls/stylesfragment.cxx
new file mode 100644
index 000000000000..0ef9400dcbec
--- /dev/null
+++ b/oox/source/xls/stylesfragment.cxx
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: stylesfragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/stylesfragment.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+OoxStylesFragment::OoxStylesFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath ),
+ mfGradPos( -1.0 )
+{
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxStylesFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ sal_Int32 nCurrContext = getCurrentContext();
+ switch( nCurrContext )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nElement == XLS_TOKEN( styleSheet ));
+ case XLS_TOKEN( styleSheet ):
+ return (nElement == XLS_TOKEN( colors )) ||
+ (nElement == XLS_TOKEN( fonts )) ||
+ (nElement == XLS_TOKEN( numFmts )) ||
+ (nElement == XLS_TOKEN( borders )) ||
+ (nElement == XLS_TOKEN( fills )) ||
+ (nElement == XLS_TOKEN( cellXfs )) ||
+ (nElement == XLS_TOKEN( cellStyleXfs )) ||
+ (nElement == XLS_TOKEN( dxfs )) ||
+ (nElement == XLS_TOKEN( cellStyles ));
+
+ case XLS_TOKEN( colors ):
+ return (nElement == XLS_TOKEN( indexedColors ));
+ case XLS_TOKEN( indexedColors ):
+ return (nElement == XLS_TOKEN( rgbColor ));
+
+ case XLS_TOKEN( fonts ):
+ return (nElement == XLS_TOKEN( font ));
+ case XLS_TOKEN( font ):
+ return mxFont.get() && Font::isSupportedContext( nElement, nCurrContext );
+
+ case XLS_TOKEN( numFmts ):
+ return (nElement == XLS_TOKEN( numFmt ));
+
+ case XLS_TOKEN( borders ):
+ return (nElement == XLS_TOKEN( border ));
+ case XLS_TOKEN( border ):
+ case XLS_TOKEN( left ):
+ case XLS_TOKEN( right ):
+ case XLS_TOKEN( top ):
+ case XLS_TOKEN( bottom ):
+ case XLS_TOKEN( diagonal ):
+ return mxBorder.get() && Border::isSupportedContext( nElement, nCurrContext );
+
+ case XLS_TOKEN( fills ):
+ return (nElement == XLS_TOKEN( fill ));
+ case XLS_TOKEN( fill ):
+ case XLS_TOKEN( patternFill ):
+ case XLS_TOKEN( gradientFill ):
+ case XLS_TOKEN( stop ):
+ return mxFill.get() && Fill::isSupportedContext( nElement, nCurrContext );
+
+ case XLS_TOKEN( cellStyleXfs ):
+ case XLS_TOKEN( cellXfs ):
+ return (nElement == XLS_TOKEN( xf ));
+ case XLS_TOKEN( xf ):
+ return mxXf.get() &&
+ ((nElement == XLS_TOKEN( alignment )) ||
+ (nElement == XLS_TOKEN( protection )));
+
+ case XLS_TOKEN( dxfs ):
+ return (nElement == XLS_TOKEN( dxf ));
+ case XLS_TOKEN( dxf ):
+ return mxDxf.get() &&
+ ((nElement == XLS_TOKEN( font )) ||
+ (nElement == XLS_TOKEN( numFmt )) ||
+ (nElement == XLS_TOKEN( alignment )) ||
+ (nElement == XLS_TOKEN( protection )) ||
+ (nElement == XLS_TOKEN( border )) ||
+ (nElement == XLS_TOKEN( fill )));
+
+ case XLS_TOKEN( cellStyles ):
+ return (nElement == XLS_TOKEN( cellStyle ));
+ }
+ return false;
+}
+
+void OoxStylesFragment::onStartElement( const AttributeList& rAttribs )
+{
+ sal_Int32 nCurrContext = getCurrentContext();
+ sal_Int32 nPrevContext = getPreviousContext();
+
+ switch( nCurrContext )
+ {
+ case XLS_TOKEN( color ):
+ switch( nPrevContext )
+ {
+ case XLS_TOKEN( font ):
+ OSL_ENSURE( mxFont.get(), "OoxStylesFragment::onStartElement - missing font object" );
+ mxFont->importAttribs( nCurrContext, rAttribs );
+ break;
+ case XLS_TOKEN( stop ):
+ OSL_ENSURE( mxFill.get(), "OoxStylesFragment::onStartElement - missing fill object" );
+ mxFill->importColor( rAttribs, mfGradPos );
+ break;
+ default:
+ OSL_ENSURE( mxBorder.get(), "OoxStylesFragment::onStartElement - missing border object" );
+ mxBorder->importColor( nPrevContext, rAttribs );
+ }
+ break;
+ case XLS_TOKEN( rgbColor ):
+ getStyles().importPaletteColor( rAttribs );
+ break;
+
+ case XLS_TOKEN( font ):
+ mxFont = mxDxf.get() ? mxDxf->importFont( rAttribs ) : getStyles().importFont( rAttribs );
+ break;
+
+ case XLS_TOKEN( numFmt ):
+ if( mxDxf.get() )
+ mxDxf->importNumFmt( rAttribs );
+ else
+ getStyles().importNumFmt( rAttribs );
+ break;
+
+ case XLS_TOKEN( alignment ):
+ OSL_ENSURE( mxXf.get() || mxDxf.get(), "OoxStylesFragment::onStartElement - missing formatting object" );
+ if( mxXf.get() )
+ mxXf->importAlignment( rAttribs );
+#if 0
+ else if( mxDxf.get() )
+ mxDxf->importAlignment( rAttribs );
+#endif
+ break;
+
+ case XLS_TOKEN( protection ):
+ OSL_ENSURE( mxXf.get() || mxDxf.get(), "OoxStylesFragment::onStartElement - missing formatting object" );
+ if( mxXf.get() )
+ mxXf->importProtection( rAttribs );
+#if 0
+ else if( mxDxf.get() )
+ mxDxf->importProtection( rAttribs );
+#endif
+ break;
+
+ case XLS_TOKEN( border ):
+ mxBorder = mxDxf.get() ? mxDxf->importBorder( rAttribs ) : getStyles().importBorder( rAttribs );
+ break;
+
+ case XLS_TOKEN( fill ):
+ mxFill = mxDxf.get() ? mxDxf->importFill( rAttribs ) : getStyles().importFill( rAttribs );
+ break;
+ case XLS_TOKEN( patternFill ):
+ OSL_ENSURE( mxFill.get(), "OoxStylesFragment::onStartElement - missing fill object" );
+ mxFill->importPatternFill( rAttribs );
+ break;
+ case XLS_TOKEN( fgColor ):
+ OSL_ENSURE( mxFill.get(), "OoxStylesFragment::onStartElement - missing fill object" );
+ mxFill->importFgColor( rAttribs );
+ break;
+ case XLS_TOKEN( bgColor ):
+ OSL_ENSURE( mxFill.get(), "OoxStylesFragment::onStartElement - missing fill object" );
+ mxFill->importBgColor( rAttribs );
+ break;
+ case XLS_TOKEN( gradientFill ):
+ OSL_ENSURE( mxFill.get(), "OoxStylesFragment::onStartElement - missing fill object" );
+ mxFill->importGradientFill( rAttribs );
+ break;
+ case XLS_TOKEN( stop ):
+ mfGradPos = rAttribs.getDouble( XML_position, -1.0 );
+ break;
+
+ case XLS_TOKEN( xf ):
+ mxXf = getStyles().importXf( nPrevContext, rAttribs );
+ break;
+ case XLS_TOKEN( dxf ):
+ mxDxf = getStyles().importDxf( rAttribs );
+ break;
+
+ case XLS_TOKEN( cellStyle ):
+ getStyles().importCellStyle( rAttribs );
+ break;
+
+ default: switch( nPrevContext )
+ {
+ case XLS_TOKEN( font ):
+ OSL_ENSURE( mxFont.get(), "OoxStylesFragment::onStartElement - missing font object" );
+ mxFont->importAttribs( nCurrContext, rAttribs );
+ break;
+ case XLS_TOKEN( border ):
+ OSL_ENSURE( mxBorder.get(), "OoxStylesFragment::onStartElement - missing border object" );
+ mxBorder->importStyle( nCurrContext, rAttribs );
+ break;
+ }
+ }
+}
+
+void OoxStylesFragment::onEndElement( const OUString& /*rChars*/ )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( font ): mxFont.reset(); break;
+ case XLS_TOKEN( border ): mxBorder.reset(); break;
+ case XLS_TOKEN( fill ): mxFill.reset(); break;
+ case XLS_TOKEN( xf ): mxXf.reset(); break;
+ case XLS_TOKEN( dxf ): mxDxf.reset(); break;
+ }
+}
+
+bool OoxStylesFragment::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nRecId == OOBIN_ID_STYLESHEET);
+ case OOBIN_ID_STYLESHEET:
+ return (nRecId == OOBIN_ID_COLORS) ||
+ (nRecId == OOBIN_ID_FONTS) ||
+ (nRecId == OOBIN_ID_NUMFMTS) ||
+ (nRecId == OOBIN_ID_BORDERS) ||
+ (nRecId == OOBIN_ID_FILLS) ||
+ (nRecId == OOBIN_ID_CELLSTYLEXFS) ||
+ (nRecId == OOBIN_ID_CELLXFS) ||
+ (nRecId == OOBIN_ID_DXFS) ||
+ (nRecId == OOBIN_ID_CELLSTYLES);
+ case OOBIN_ID_COLORS:
+ return (nRecId == OOBIN_ID_INDEXEDCOLORS);
+ case OOBIN_ID_INDEXEDCOLORS:
+ return (nRecId == OOBIN_ID_RGBCOLOR);
+ case OOBIN_ID_FONTS:
+ return (nRecId == OOBIN_ID_FONT);
+ case OOBIN_ID_NUMFMTS:
+ return (nRecId == OOBIN_ID_NUMFMT);
+ case OOBIN_ID_BORDERS:
+ return (nRecId == OOBIN_ID_BORDER);
+ case OOBIN_ID_FILLS:
+ return (nRecId == OOBIN_ID_FILL);
+ case OOBIN_ID_CELLSTYLEXFS:
+ case OOBIN_ID_CELLXFS:
+ return (nRecId == OOBIN_ID_XF);
+ case OOBIN_ID_DXFS:
+ return (nRecId == OOBIN_ID_DXF);
+ case OOBIN_ID_CELLSTYLES:
+ return (nRecId == OOBIN_ID_CELLSTYLE);
+ }
+ return false;
+}
+
+void OoxStylesFragment::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_RGBCOLOR: getStyles().importPaletteColor( rStrm ); break;
+ case OOBIN_ID_FONT: getStyles().importFont( rStrm ); break;
+ case OOBIN_ID_NUMFMT: getStyles().importNumFmt( rStrm ); break;
+ case OOBIN_ID_BORDER: getStyles().importBorder( rStrm ); break;
+ case OOBIN_ID_FILL: getStyles().importFill( rStrm ); break;
+ case OOBIN_ID_XF: getStyles().importXf( getPreviousContext(), rStrm ); break;
+ case OOBIN_ID_DXF: getStyles().importDxf( rStrm ); break;
+ case OOBIN_ID_CELLSTYLE: getStyles().importCellStyle( rStrm ); break;
+ }
+}
+
+// oox.xls.OoxFragmentHandler interface ---------------------------------------
+
+void OoxStylesFragment::finalizeImport()
+{
+ getStyles().finalizeImport();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/stylespropertyhelper.cxx b/oox/source/xls/stylespropertyhelper.cxx
new file mode 100644
index 000000000000..91a8099de426
--- /dev/null
+++ b/oox/source/xls/stylespropertyhelper.cxx
@@ -0,0 +1,386 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: stylespropertyhelper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ * * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/stylespropertyhelper.hxx"
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontPitch.hpp>
+#include <com/sun/star/awt/FontType.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+ApiFontUsedFlags::ApiFontUsedFlags( bool bAllUsed ) :
+ mbNameUsed( bAllUsed ),
+ mbColorUsed( bAllUsed ),
+ mbSchemeUsed( bAllUsed ),
+ mbHeightUsed( bAllUsed ),
+ mbUnderlineUsed( bAllUsed ),
+ mbEscapementUsed( bAllUsed ),
+ mbWeightUsed( bAllUsed ),
+ mbPostureUsed( bAllUsed ),
+ mbStrikeoutUsed( bAllUsed ),
+ mbOutlineUsed( bAllUsed ),
+ mbShadowUsed( bAllUsed )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ApiFontData::ApiFontData() :
+ maDesc(
+ CREATE_OUSTRING( "Calibri" ),
+ 220, // height 11 points
+ 0,
+ OUString(),
+ ::com::sun::star::awt::FontFamily::DONTKNOW,
+ RTL_TEXTENCODING_DONTKNOW,
+ ::com::sun::star::awt::FontPitch::DONTKNOW,
+ 100.0,
+ ::com::sun::star::awt::FontWeight::NORMAL,
+ ::com::sun::star::awt::FontSlant_NONE,
+ ::com::sun::star::awt::FontUnderline::NONE,
+ ::com::sun::star::awt::FontStrikeout::NONE,
+ 0.0,
+ sal_False,
+ sal_False,
+ ::com::sun::star::awt::FontType::DONTKNOW ),
+ mnColor( API_RGB_TRANSPARENT ),
+ mnEscapement( API_ESCAPE_NONE ),
+ mnEscapeHeight( API_ESCAPEHEIGHT_NONE ),
+ mbOutline( false ),
+ mbShadow( false ),
+ mbHasWstrn( true ),
+ mbHasAsian( false )
+{
+}
+
+// ============================================================================
+
+ApiNumFmtData::ApiNumFmtData() :
+ mnIndex( 0 )
+{
+}
+
+// ============================================================================
+
+ApiAlignmentData::ApiAlignmentData() :
+ meHorJustify( ::com::sun::star::table::CellHoriJustify_STANDARD ),
+ meVerJustify( ::com::sun::star::table::CellVertJustify_STANDARD ),
+ meOrientation( ::com::sun::star::table::CellOrientation_STANDARD ),
+ mnRotation( 0 ),
+ mnWritingMode( ::com::sun::star::text::WritingMode2::PAGE ),
+ mnIndent( 0 ),
+ mbWrapText( false ),
+ mbShrink( false )
+{
+}
+
+bool operator==( const ApiAlignmentData& rLeft, const ApiAlignmentData& rRight )
+{
+ return
+ (rLeft.meHorJustify == rRight.meHorJustify) &&
+ (rLeft.meVerJustify == rRight.meVerJustify) &&
+ (rLeft.meOrientation == rRight.meOrientation) &&
+ (rLeft.mnRotation == rRight.mnRotation) &&
+ (rLeft.mnWritingMode == rRight.mnWritingMode) &&
+ (rLeft.mnIndent == rRight.mnIndent) &&
+ (rLeft.mbWrapText == rRight.mbWrapText) &&
+ (rLeft.mbShrink == rRight.mbShrink);
+}
+
+// ============================================================================
+
+ApiProtectionData::ApiProtectionData() :
+ maCellProt( sal_True, sal_False, sal_False, sal_False )
+{
+}
+
+bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight )
+{
+ return
+ (rLeft.maCellProt.IsLocked == rRight.maCellProt.IsLocked) &&
+ (rLeft.maCellProt.IsFormulaHidden == rRight.maCellProt.IsFormulaHidden) &&
+ (rLeft.maCellProt.IsHidden == rRight.maCellProt.IsHidden) &&
+ (rLeft.maCellProt.IsPrintHidden == rRight.maCellProt.IsPrintHidden);
+}
+
+// ============================================================================
+
+ApiBorderData::ApiBorderData() :
+ mbBorderUsed( false ),
+ mbDiagUsed( false )
+{
+}
+
+// ============================================================================
+
+ApiSolidFillData::ApiSolidFillData() :
+ mnColor( API_RGB_TRANSPARENT ),
+ mbTransparent( true ),
+ mbUsed( false )
+{
+}
+
+// ============================================================================
+
+namespace {
+
+/** Property names for Western font name settings. */
+const sal_Char* const sppcWstrnFontNameNames[] =
+{
+ "CharFontName",
+ "CharFontFamily",
+ "CharFontCharSet",
+ 0
+};
+
+/** Property names for Asian font name settings. */
+const sal_Char* const sppcAsianFontNameNames[] =
+{
+ "CharFontNameAsian",
+ "CharFontFamilyAsian",
+ "CharFontCharSetAsian",
+ 0
+};
+
+/** Property names for Complex font name settings. */
+const sal_Char* const sppcCmplxFontNameNames[] =
+{
+ "CharFontNameComplex",
+ "CharFontFamilyComplex",
+ "CharFontCharSetComplex",
+ 0
+};
+
+/** Property names for font height settings. */
+const sal_Char* const sppcFontHeightNames[] =
+{
+ "CharHeight",
+ "CharHeightAsian",
+ "CharHeightComplex",
+ 0
+};
+
+/** Property names for font weight settings. */
+const sal_Char* const sppcFontWeightNames[] =
+{
+ "CharWeight",
+ "CharWeightAsian",
+ "CharWeightComplex",
+ 0
+};
+
+/** Property names for font posture settings. */
+const sal_Char* const sppcFontPostureNames[] =
+{
+ "CharPosture",
+ "CharPostureAsian",
+ "CharPostureComplex",
+ 0
+};
+
+/** Property names for font escapement settings. */
+const sal_Char* const sppcFontEscapeNames[] =
+{
+ "CharEscapement",
+ "CharEscapementHeight",
+ 0
+};
+
+/** Property names for alignment. */
+const sal_Char* const sppcAlignmentNames[] =
+{
+ "HoriJustify",
+ "VertJustify",
+ "WritingMode",
+ "RotateAngle",
+ "RotateReference",
+ "Orientation",
+ "ParaIndent",
+ "IsTextWrapped",
+ "ShrinkToFit",
+ 0
+};
+
+/** Property names for diagonal cell borders. */
+const sal_Char* const sppcDiagBorderNames[] =
+{
+ "DiagonalTLBR",
+ "DiagonalBLTR",
+ 0
+};
+
+/** Property names for cell fill. */
+const sal_Char* const sppcSolidFillNames[] =
+{
+ "CellBackColor",
+ "IsCellBackgroundTransparent",
+ 0
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+StylesPropertyHelper::StylesPropertyHelper( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maWstrnFontNameProps( sppcWstrnFontNameNames ),
+ maAsianFontNameProps( sppcAsianFontNameNames ),
+ maCmplxFontNameProps( sppcCmplxFontNameNames ),
+ maFontHeightProps( sppcFontHeightNames ),
+ maFontWeightProps( sppcFontWeightNames ),
+ maFontPostureProps( sppcFontPostureNames ),
+ maFontEscapeProps( sppcFontEscapeNames ),
+ maAlignProps( sppcAlignmentNames ),
+ maDiagBorderProps( sppcDiagBorderNames ),
+ maSolidFillProps( sppcSolidFillNames ),
+ maCharColorProp( CREATE_OUSTRING( "CharColor" ) ),
+ maCharUnderlineProp( CREATE_OUSTRING( "CharUnderline" ) ),
+ maCharStrikeoutProp( CREATE_OUSTRING( "CharStrikeout" ) ),
+ maCharContouredProp( CREATE_OUSTRING( "CharContoured" ) ),
+ maCharShadowedProp( CREATE_OUSTRING( "CharShadowed" ) ),
+ maNumFmtProp( CREATE_OUSTRING( "NumberFormat" ) ),
+ maCellProtProp( CREATE_OUSTRING( "CellProtection" ) ),
+ maBorderProp( CREATE_OUSTRING( "TableBorder" ) )
+{
+}
+
+void StylesPropertyHelper::writeFontProperties( PropertySet& rPropSet,
+ const ApiFontData& rFontData, const ApiFontUsedFlags& rUsedFlags, FontPropertyType ePropType )
+{
+ // font name properties
+ if( rUsedFlags.mbNameUsed )
+ {
+ if( rFontData.mbHasWstrn )
+ maWstrnFontNameProps << rFontData.maDesc.Name << rFontData.maDesc.Family << rFontData.maDesc.CharSet >> rPropSet;
+ if( rFontData.mbHasAsian )
+ maAsianFontNameProps << rFontData.maDesc.Name << rFontData.maDesc.Family << rFontData.maDesc.CharSet >> rPropSet;
+ if( rFontData.mbHasCmplx )
+ maCmplxFontNameProps << rFontData.maDesc.Name << rFontData.maDesc.Family << rFontData.maDesc.CharSet >> rPropSet;
+ }
+ // font height
+ if( rUsedFlags.mbHeightUsed )
+ {
+ float fHeight = static_cast< float >( rFontData.maDesc.Height / 20.0 ); // twips to points
+ maFontHeightProps << fHeight << fHeight << fHeight >> rPropSet;
+ }
+ // font weight
+ if( rUsedFlags.mbWeightUsed )
+ {
+ float fWeight = rFontData.maDesc.Weight;
+ maFontWeightProps << fWeight << fWeight << fWeight >> rPropSet;
+ }
+ // font posture
+ if( rUsedFlags.mbPostureUsed )
+ maFontPostureProps << rFontData.maDesc.Slant << rFontData.maDesc.Slant << rFontData.maDesc.Slant >> rPropSet;
+ // character color
+ if( rUsedFlags.mbColorUsed )
+ rPropSet.setProperty( maCharColorProp, rFontData.mnColor );
+ // underline style
+ if( rUsedFlags.mbUnderlineUsed )
+ rPropSet.setProperty( maCharUnderlineProp, rFontData.maDesc.Underline );
+ // strike out style
+ if( rUsedFlags.mbStrikeoutUsed )
+ rPropSet.setProperty( maCharStrikeoutProp, rFontData.maDesc.Strikeout );
+ // outline style
+ if( rUsedFlags.mbOutlineUsed )
+ rPropSet.setProperty( maCharContouredProp, rFontData.mbOutline );
+ // shadow style
+ if( rUsedFlags.mbShadowUsed )
+ rPropSet.setProperty( maCharShadowedProp, rFontData.mbShadow );
+ // escapement
+ if( rUsedFlags.mbEscapementUsed && (ePropType == FONT_PROPTYPE_RICHTEXT) )
+ maFontEscapeProps << rFontData.mnEscapement << rFontData.mnEscapeHeight >> rPropSet;
+}
+
+void StylesPropertyHelper::writeNumFmtProperties(
+ PropertySet& rPropSet, const ApiNumFmtData& rNumFmtData )
+{
+ rPropSet.setProperty( maNumFmtProp, rNumFmtData.mnIndex );
+}
+
+void StylesPropertyHelper::writeAlignmentProperties(
+ PropertySet& rPropSet, const ApiAlignmentData& rAlignData )
+{
+ maAlignProps
+ << rAlignData.meHorJustify
+ << rAlignData.meVerJustify
+ << rAlignData.mnWritingMode
+ << rAlignData.mnRotation
+ << ::com::sun::star::table::CellVertJustify_STANDARD // rotation reference
+ << rAlignData.meOrientation
+ << rAlignData.mnIndent
+ << rAlignData.mbWrapText
+ << rAlignData.mbShrink
+ >> rPropSet;
+}
+
+void StylesPropertyHelper::writeProtectionProperties(
+ PropertySet& rPropSet, const ApiProtectionData& rProtData )
+{
+ rPropSet.setProperty( maCellProtProp, rProtData.maCellProt );
+}
+
+void StylesPropertyHelper::writeBorderProperties(
+ PropertySet& rPropSet, const ApiBorderData& rBorderData )
+{
+ if( rBorderData.mbBorderUsed )
+ rPropSet.setProperty( maBorderProp, rBorderData.maBorder );
+ if( rBorderData.mbDiagUsed )
+ maDiagBorderProps << rBorderData.maTLtoBR << rBorderData.maBLtoTR >> rPropSet;
+}
+
+void StylesPropertyHelper::writeSolidFillProperties(
+ PropertySet& rPropSet, const ApiSolidFillData& rFillData )
+{
+ if( rFillData.mbUsed )
+ maSolidFillProps << rFillData.mnColor << rFillData.mbTransparent >> rPropSet;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/tablebuffer.cxx b/oox/source/xls/tablebuffer.cxx
new file mode 100644
index 000000000000..5865422f62e5
--- /dev/null
+++ b/oox/source/xls/tablebuffer.cxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tablebuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/tablebuffer.hxx"
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/addressconverter.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::container::XNameAccess;
+using ::com::sun::star::sheet::XDatabaseRanges;
+using ::com::sun::star::sheet::XDatabaseRange;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+OoxTableData::OoxTableData() :
+ mnId( -1 ),
+ mnType( XML_worksheet ),
+ mnHeaderRows( 1 ),
+ mnTotalsRows( 0 )
+{
+}
+
+// ============================================================================
+
+Table::Table( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnTokenIndex( -1 )
+{
+}
+
+void Table::importTable( const AttributeList& rAttribs, sal_Int16 nSheet )
+{
+ if( getAddressConverter().convertToCellRange( maOoxData.maRange, rAttribs.getString( XML_ref ), nSheet, true ) )
+ {
+ maOoxData.maProgName = rAttribs.getString( XML_name );
+ maOoxData.maDisplayName = rAttribs.getString( XML_displayName );
+ maOoxData.mnId = rAttribs.getInteger( XML_id, -1 );
+ maOoxData.mnType = rAttribs.getToken( XML_tableType, XML_worksheet );
+ maOoxData.mnHeaderRows = rAttribs.getInteger( XML_headerRowCount, 1 );
+ maOoxData.mnTotalsRows = rAttribs.getInteger( XML_totalsRowCount, 0 );
+ }
+}
+
+void Table::importTable( RecordInputStream& rStrm, sal_Int16 nSheet )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ if( getAddressConverter().convertToCellRange( maOoxData.maRange, aBinRange, nSheet, true ) )
+ {
+ sal_Int32 nType;
+ rStrm >> nType >> maOoxData.mnId >> maOoxData.mnHeaderRows >> maOoxData.mnTotalsRows;
+ rStrm.skip( 32 );
+ rStrm >> maOoxData.maProgName >> maOoxData.maDisplayName;
+
+ static const sal_Int32 spnTypes[] = { XML_worksheet, XML_TOKEN_INVALID, XML_TOKEN_INVALID, XML_queryTable };
+ maOoxData.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
+ }
+}
+
+void Table::finalizeImport()
+{
+ if( maOoxData.maDisplayName.getLength() > 0 ) try
+ {
+ // find an unused name
+ Reference< XDatabaseRanges > xDatabaseRanges = getDatabaseRanges();
+ Reference< XNameAccess > xNameAccess( xDatabaseRanges, UNO_QUERY_THROW );
+ OUString aName = ContainerHelper::getUnusedName( xNameAccess, maOoxData.maDisplayName, '_' );
+ xDatabaseRanges->addNewByName( aName, maOoxData.maRange );
+ Reference< XDatabaseRange > xDatabaseRange( xDatabaseRanges->getByName( aName ), UNO_QUERY_THROW );
+ PropertySet aPropSet( xDatabaseRange );
+ if( !aPropSet.getProperty( mnTokenIndex, CREATE_OUSTRING( "TokenIndex" ) ) )
+ mnTokenIndex = -1;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "Table::finalizeImport - cannot create database range" );
+ }
+}
+
+// ============================================================================
+
+TableBuffer::TableBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+TableRef TableBuffer::importTable( const AttributeList& rAttribs, sal_Int16 nSheet )
+{
+ TableRef xTable( new Table( *this ) );
+ xTable->importTable( rAttribs, nSheet );
+ insertTable( xTable );
+ return xTable;
+}
+
+TableRef TableBuffer::importTable( RecordInputStream& rStrm, sal_Int16 nSheet )
+{
+ TableRef xTable( new Table( *this ) );
+ xTable->importTable( rStrm, nSheet );
+ insertTable( xTable );
+ return xTable;
+}
+
+void TableBuffer::finalizeImport()
+{
+ maTables.forEachMem( &Table::finalizeImport );
+}
+
+TableRef TableBuffer::getTable( sal_Int32 nTableId ) const
+{
+ return maTables.get( nTableId );
+}
+
+// private --------------------------------------------------------------------
+
+void TableBuffer::insertTable( TableRef xTable )
+{
+ sal_Int32 nTableId = xTable->getTableId();
+ if( nTableId > 0 )
+ {
+ OSL_ENSURE( maTables.find( nTableId ) == maTables.end(), "TableBuffer::insertTable - multiple table identifier" );
+ maTables[ nTableId ] = xTable;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/tablefragment.cxx b/oox/source/xls/tablefragment.cxx
new file mode 100644
index 000000000000..53097159a05d
--- /dev/null
+++ b/oox/source/xls/tablefragment.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tablefragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/tablefragment.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+OoxTableFragment::OoxTableFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorksheetFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxTableFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nElement == XLS_TOKEN( table ));
+ }
+ return false;
+}
+
+void OoxTableFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( table ): mxTable = getTables().importTable( rAttribs, getSheetIndex() ); break;
+ }
+}
+
+bool OoxTableFragment::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nRecId == OOBIN_ID_TABLE);
+ }
+ return false;
+}
+
+void OoxTableFragment::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_TABLE: mxTable = getTables().importTable( rStrm, getSheetIndex() ); break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/themebuffer.cxx b/oox/source/xls/themebuffer.cxx
new file mode 100644
index 000000000000..1a930aa26845
--- /dev/null
+++ b/oox/source/xls/themebuffer.cxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: themebuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/stylespropertyhelper.hxx"
+
+using ::oox::drawingml::ClrScheme;
+using ::oox::drawingml::Theme;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+/** Specifies default theme fonts for a specific locale. */
+struct BuiltinThemeFont
+{
+ const sal_Char* mpcLocale; /// The locale for this font setting.
+ const sal_Char* mpcHeadFont; /// Default heading font.
+ const sal_Char* mpcBodyFont; /// Default body font.
+};
+
+#define FONT_JA "\357\274\255\357\274\263 \357\274\260\343\202\264\343\202\267\343\203\203\343\202\257"
+#define FONT_KO "\353\247\221\354\235\200 \352\263\240\353\224\225"
+#define FONT_CS "\345\256\213\344\275\223"
+#define FONT_CT "\346\226\260\347\264\260\346\230\216\351\253\224"
+
+static const BuiltinThemeFont spBuiltinThemeFonts[] =
+{ // locale headings font body font
+ { "*", "Cambria", "Calibri" }, // Default
+ { "ar", "Times New Roman", "Arial" }, // Arabic
+ { "bn", "Vrinda", "Vrinda" }, // Bengali
+ { "div", "MV Boli", "MV Boli" }, // Divehi
+ { "fa", "Times New Roman", "Arial" }, // Farsi
+ { "gu", "Shruti", "Shruti" }, // Gujarati
+ { "he", "Times New Roman", "Arial" }, // Hebrew
+ { "hi", "Mangal", "Mangal" }, // Hindi
+ { "ja", FONT_JA, FONT_JA }, // Japanese
+ { "kn", "Tunga", "Tunga" }, // Kannada
+ { "ko", FONT_KO, FONT_KO }, // Korean
+ { "kok", "Mangal", "Mangal" }, // Konkani
+ { "ml", "Kartika", "Kartika" }, // Malayalam
+ { "mr", "Mangal", "Mangal" }, // Marathi
+ { "pa", "Raavi", "Raavi" }, // Punjabi
+ { "sa", "Mangal", "Mangal" }, // Sanskrit
+ { "syr", "Estrangelo Edessa", "Estrangelo Edessa" }, // Syriac
+ { "ta", "Latha", "Latha" }, // Tamil
+ { "te", "Gautami", "Gautami" }, // Telugu
+ { "th", "Tahoma", "Tahoma" }, // Thai
+ { "ur", "Times New Roman", "Arial" }, // Urdu
+ { "vi", "Times New Roman", "Arial" }, // Vietnamese
+ { "zh", FONT_CS, FONT_CS }, // Chinese, Simplified
+ { "zh-HK", FONT_CT, FONT_CT }, // Chinese, Hong Kong
+ { "zh-MO", FONT_CT, FONT_CT }, // Chinese, Macau
+ { "zh-TW", FONT_CT, FONT_CT } // Chinese, Taiwan
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ThemeBuffer::ThemeBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mxDefFontData( new OoxFontData )
+{
+ switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ //! TODO: locale dependent font name
+ mxDefFontData->maName = CREATE_OUSTRING( "Cambria" );
+ mxDefFontData->mfHeight = 11.0;
+ break;
+ case FILTER_BIFF:
+ //! TODO: BIFF dependent font name
+ mxDefFontData->maName = CREATE_OUSTRING( "Arial" );
+ mxDefFontData->mfHeight = 10.0;
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+}
+
+ThemeBuffer::~ThemeBuffer()
+{
+}
+
+Theme& ThemeBuffer::getCoreTheme() const
+{
+ if( !mxTheme )
+ mxTheme.reset( new Theme );
+ return *mxTheme;
+}
+
+sal_Int32 ThemeBuffer::getColorByToken( sal_Int32 nToken ) const
+{
+ sal_Int32 nColor = 0;
+ if( const ClrScheme* pClrScheme = getCoreTheme().getClrScheme().get() )
+ if( pClrScheme->getColor( nToken, nColor ) )
+ return nColor;
+ return 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 };
+
+ sal_Int32 nColor = 0;
+ if( const ClrScheme* pClrScheme = getCoreTheme().getClrScheme().get() )
+ if( pClrScheme->getColor( STATIC_ARRAY_SELECT( spnColorTokens, nIndex, XML_TOKEN_INVALID ), nColor ) )
+ return nColor;
+ return API_RGB_TRANSPARENT;
+}
+
+sal_Int32 ThemeBuffer::getSystemColor( sal_Int32 nElement, sal_Int32 nDefaultColor )
+{
+ sal_Int32 nColor = 0;
+ return ClrScheme::getSystemColor( nColor, nElement ) ? nColor : nDefaultColor;
+}
+
+sal_Int32 ThemeBuffer::getSystemWindowColor()
+{
+ return getSystemColor( XML_window, 0xFFFFFF );
+}
+
+sal_Int32 ThemeBuffer::getSystemWindowTextColor()
+{
+ return getSystemColor( XML_windowText, 0x000000 );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/unitconverter.cxx b/oox/source/xls/unitconverter.cxx
new file mode 100644
index 000000000000..66f92142413b
--- /dev/null
+++ b/oox/source/xls/unitconverter.cxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unitconverter.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/unitconverter.hxx"
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/DeviceInfo.hpp>
+#include <com/sun/star/awt/XFont.hpp>
+#include "oox/xls/stylesbuffer.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::awt::FontDescriptor;
+using ::com::sun::star::awt::XDevice;
+using ::com::sun::star::awt::DeviceInfo;
+using ::com::sun::star::awt::XFont;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const double MM100_PER_INCH = 2540.0;
+const double INCH_PER_MM100 = 1.0 / MM100_PER_INCH;
+
+const double POINT_PER_INCH = 72.0;
+const double INCH_PER_POINT = 1.0 / POINT_PER_INCH;
+
+const double MM100_PER_POINT = MM100_PER_INCH * INCH_PER_POINT;
+const double POINT_PER_MM100 = 1.0 / MM100_PER_POINT;
+
+const double TWIP_PER_POINT = 20.0;
+const double POINT_PER_TWIP = 1.0 / TWIP_PER_POINT;
+
+const double MM100_PER_TWIP = MM100_PER_POINT * POINT_PER_TWIP;
+const double TWIP_PER_MM100 = 1.0 / MM100_PER_TWIP;
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+UnitConverter::UnitConverter( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mfPixelPerMm100X( 0.08 ),
+ mfPixelPerMm100Y( 0.08 ),
+ mnDigitWidth( 200 ),
+ mnSpaceWidth( 100 )
+{
+ // map error code names to BIFF error codes
+ maErrorCodes[ CREATE_OUSTRING( "#NULL!" ) ] = BIFF_ERR_NULL;
+ maErrorCodes[ CREATE_OUSTRING( "#DIV/0!" ) ] = BIFF_ERR_DIV0;
+ maErrorCodes[ CREATE_OUSTRING( "#VALUE!" ) ] = BIFF_ERR_VALUE;
+ maErrorCodes[ CREATE_OUSTRING( "#REF!" ) ] = BIFF_ERR_REF;
+ maErrorCodes[ CREATE_OUSTRING( "#NAME?" ) ] = BIFF_ERR_NAME;
+ maErrorCodes[ CREATE_OUSTRING( "#NUM!" ) ] = BIFF_ERR_NUM;
+ maErrorCodes[ CREATE_OUSTRING( "#NA" ) ] = BIFF_ERR_NA;
+}
+
+void UnitConverter::finalizeImport()
+{
+ Reference< XDevice > xDevice = getReferenceDevice();
+ if( xDevice.is() )
+ {
+ // get pixel metric first, needed to get character widths below
+ DeviceInfo aInfo = xDevice->getInfo();
+ mfPixelPerMm100X = aInfo.PixelPerMeterX / 100000.0;
+ mfPixelPerMm100Y = aInfo.PixelPerMeterY / 100000.0;
+
+ // get character widths from default font
+ if( const Font* pDefFont = getStyles().getDefaultFont().get() )
+ {
+ // XDevice expects pixels in font descriptor, but font contains twips
+ FontDescriptor aDesc = pDefFont->getFontDescriptor();
+ aDesc.Height = static_cast< sal_Int16 >( calcPixelsXFromMm100( calcMm100FromTwips( aDesc.Height ) ) );
+ Reference< XFont > xFont = xDevice->getFont( aDesc );
+ if( xFont.is() )
+ {
+ // get maximum width of all digits
+ sal_Int32 nDigitWidth = 0;
+ for( sal_Unicode cChar = '0'; cChar <= '9'; ++cChar )
+ nDigitWidth = ::std::max( nDigitWidth, calcMm100FromPixelsX( xFont->getCharWidth( cChar ) ) );
+ if( nDigitWidth > 0 )
+ mnDigitWidth = nDigitWidth;
+ // get width of space character
+ sal_Int32 nSpaceWidth = calcMm100FromPixelsX( xFont->getCharWidth( ' ' ) );
+ if( nSpaceWidth > 0 )
+ mnSpaceWidth = nSpaceWidth;
+ }
+ }
+ }
+}
+
+// conversion -----------------------------------------------------------------
+
+sal_Int32 UnitConverter::calcMm100FromInches( double fInches ) const
+{
+ return static_cast< sal_Int32 >( fInches * MM100_PER_INCH );
+}
+
+sal_Int32 UnitConverter::calcMm100FromPoints( double fPoints ) const
+{
+ return static_cast< sal_Int32 >( fPoints * MM100_PER_POINT + 0.5 );
+}
+
+sal_Int32 UnitConverter::calcMm100FromTwips( double fTwips ) const
+{
+ return static_cast< sal_Int32 >( fTwips * MM100_PER_TWIP + 0.5 );
+}
+
+sal_Int32 UnitConverter::calcMm100FromPixelsX( double fPixels ) const
+{
+ return static_cast< sal_Int32 >( fPixels / mfPixelPerMm100X + 0.5 );
+}
+
+sal_Int32 UnitConverter::calcMm100FromPixelsY( double fPixels ) const
+{
+ return static_cast< sal_Int32 >( fPixels / mfPixelPerMm100Y + 0.5 );
+}
+
+sal_Int32 UnitConverter::calcMm100FromDigits( double fChars ) const
+{
+ return static_cast< sal_Int32 >( fChars * mnDigitWidth + 0.5 );
+}
+
+sal_Int32 UnitConverter::calcMm100FromSpaces( double fSpaces ) const
+{
+ return static_cast< sal_Int32 >( fSpaces * mnSpaceWidth + 0.5 );
+}
+
+double UnitConverter::calcInchesFromMm100( sal_Int32 nMm100 ) const
+{
+ return nMm100 * INCH_PER_MM100;
+}
+
+double UnitConverter::calcPointsFromMm100( sal_Int32 nMm100 ) const
+{
+ return nMm100 * POINT_PER_MM100;
+}
+
+double UnitConverter::calcTwipsFromMm100( sal_Int32 nMm100 ) const
+{
+ return nMm100 * TWIP_PER_MM100;
+}
+
+double UnitConverter::calcPixelsXFromMm100( sal_Int32 nMm100 ) const
+{
+ return nMm100 * mfPixelPerMm100X;
+}
+
+double UnitConverter::calcPixelsYFromMm100( sal_Int32 nMm100 ) const
+{
+ return nMm100 * mfPixelPerMm100Y;
+}
+
+double UnitConverter::calcDigitsFromMm100( sal_Int32 nMm100 ) const
+{
+ return static_cast< double >( nMm100 ) / mnDigitWidth;
+}
+
+double UnitConverter::calcSpacesFromMm100( sal_Int32 nMm100 ) const
+{
+ return static_cast< double >( nMm100 ) / mnSpaceWidth;
+}
+
+sal_uInt8 UnitConverter::calcBiffErrorCode( const OUString& rErrorCode ) const
+{
+ ErrorCodeMap::const_iterator aIt = maErrorCodes.find( rErrorCode );
+ return (aIt == maErrorCodes.end()) ? BIFF_ERR_NA : aIt->second;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/validationpropertyhelper.cxx b/oox/source/xls/validationpropertyhelper.cxx
new file mode 100644
index 000000000000..8784fad81cb0
--- /dev/null
+++ b/oox/source/xls/validationpropertyhelper.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: validationpropertyhelper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ * * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/validationpropertyhelper.hxx"
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/TableValidationVisibility.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/sheet/XMultiFormulaTokens.hpp>
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/ooxtokens.hxx"
+#include "oox/xls/worksheethelper.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::beans::XPropertySet;
+using ::com::sun::star::sheet::ValidationType;
+using ::com::sun::star::sheet::ValidationAlertStyle;
+using ::com::sun::star::sheet::ConditionOperator;
+using ::com::sun::star::sheet::XSheetCondition;
+using ::com::sun::star::sheet::XMultiFormulaTokens;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_Char* const sppcPropNames[] =
+{
+ "Type",
+ "ShowInputMessage",
+ "InputTitle",
+ "InputMessage",
+ "ShowErrorMessage",
+ "ErrorTitle",
+ "ErrorMessage",
+ "ErrorAlertStyle",
+ "ShowList",
+ "IgnoreBlankCells",
+ 0
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ValidationPropertyHelper::ValidationPropertyHelper( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maValProps( sppcPropNames ),
+ maValidationProp( CREATE_OUSTRING( "Validation" ) )
+{
+}
+
+void ValidationPropertyHelper::writeValidationProperties( PropertySet& rPropSet, const OoxValidationData& rValData )
+{
+ Reference< XPropertySet > xValidation;
+ if( rPropSet.getProperty( xValidation, maValidationProp ) && xValidation.is() )
+ {
+ PropertySet aValProps( xValidation );
+ namespace csss = ::com::sun::star::sheet;
+
+ // convert validation type to API enum
+ ValidationType eType = csss::ValidationType_ANY;
+ switch( rValData.mnType )
+ {
+ case XML_custom: eType = csss::ValidationType_CUSTOM; break;
+ case XML_date: eType = csss::ValidationType_DATE; break;
+ case XML_decimal: eType = csss::ValidationType_DECIMAL; break;
+ case XML_list: eType = csss::ValidationType_LIST; break;
+ case XML_none: eType = csss::ValidationType_ANY; break;
+ case XML_textLength: eType = csss::ValidationType_TEXT_LEN; break;
+ case XML_time: eType = csss::ValidationType_TIME; break;
+ case XML_whole: eType = csss::ValidationType_WHOLE; break;
+ default: OSL_ENSURE( false, "ValidationPropertyHelper::writeValidationProperties - unknown validation type" );
+ }
+
+ // convert error alert style to API enum
+ ValidationAlertStyle nAlertStyle = csss::ValidationAlertStyle_STOP;
+ switch( rValData.mnErrorStyle )
+ {
+ case XML_information: nAlertStyle = csss::ValidationAlertStyle_INFO; break;
+ case XML_stop: nAlertStyle = csss::ValidationAlertStyle_STOP; break;
+ case XML_warning: nAlertStyle = csss::ValidationAlertStyle_WARNING; break;
+ default: OSL_ENSURE( false, "ValidationPropertyHelper::writeValidationProperties - unknown error style" );
+ }
+
+ // convert dropdown style to API visibility constants
+ sal_Int16 nVisibility = rValData.mbNoDropDown ? csss::TableValidationVisibility::INVISIBLE : csss::TableValidationVisibility::UNSORTED;
+
+ // write all properties
+ maValProps
+ << eType
+ << rValData.mbShowInputMsg << rValData.maInputTitle << rValData.maInputMessage
+ << rValData.mbShowErrorMsg << rValData.maErrorTitle << rValData.maErrorMessage
+ << nAlertStyle << nVisibility << rValData.mbAllowBlank
+ >> aValProps;
+
+ try
+ {
+ // condition operator
+ Reference< XSheetCondition > xSheetCond( xValidation, UNO_QUERY_THROW );
+ xSheetCond->setOperator( convertToApiOperator( rValData.mnOperator ) );
+
+ // condition formulas
+ Reference< XMultiFormulaTokens > xTokens( xValidation, UNO_QUERY_THROW );
+ xTokens->setTokens( 0, rValData.maTokens1 );
+ xTokens->setTokens( 1, rValData.maTokens2 );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // write back validation settings to cell range(s)
+ rPropSet.setProperty( maValidationProp, xValidation );
+ }
+}
+
+ConditionOperator ValidationPropertyHelper::convertToApiOperator( sal_Int32 nToken )
+{
+ using namespace ::com::sun::star::sheet;
+ switch( nToken )
+ {
+ case XML_between: return ConditionOperator_BETWEEN;
+ case XML_equal: return ConditionOperator_EQUAL;
+ case XML_greaterThan: return ConditionOperator_GREATER;
+ case XML_greaterThanOrEqual: return ConditionOperator_GREATER_EQUAL;
+ case XML_lessThan: return ConditionOperator_LESS;
+ case XML_lessThanOrEqual: return ConditionOperator_LESS_EQUAL;
+ case XML_notBetween: return ConditionOperator_NOT_BETWEEN;
+ case XML_notEqual: return ConditionOperator_NOT_EQUAL;
+ }
+ return ConditionOperator_NONE;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx
new file mode 100644
index 000000000000..7ec207015ae6
--- /dev/null
+++ b/oox/source/xls/viewsettings.cxx
@@ -0,0 +1,789 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewsettings.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/viewsettings.hxx"
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/document/XViewDataSupplier.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertysequence.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/ooxtokens.hxx"
+#include "oox/xls/unitconverter.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+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;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 OOX_BOOKVIEW_TABBARRATIO_DEF = 600; /// Default tabbar ratio.
+const sal_Int32 OOX_SHEETVIEW_NORMALZOOM_DEF = 100; /// Default zoom for normal view.
+const sal_Int32 OOX_SHEETVIEW_SHEETLAYZOOM_DEF = 60; /// Default zoom for pagebreak preview.
+const sal_Int32 OOX_SHEETVIEW_PAGELAYZOOM_DEF = 100; /// Default zoom for page layout view.
+
+const sal_uInt8 OOBIN_PANE_FROZEN = 0x01;
+const sal_uInt8 OOBIN_PANE_FROZENNOSPLIT = 0x02;
+
+const sal_uInt16 OOBIN_SHEETVIEW_WINPROTECTED = 0x0001;
+const sal_uInt16 OOBIN_SHEETVIEW_SHOWFORMULAS = 0x0002;
+const sal_uInt16 OOBIN_SHEETVIEW_SHOWGRID = 0x0004;
+const sal_uInt16 OOBIN_SHEETVIEW_SHOWHEADINGS = 0x0008;
+const sal_uInt16 OOBIN_SHEETVIEW_SHOWZEROS = 0x0010;
+const sal_uInt16 OOBIN_SHEETVIEW_RIGHTTOLEFT = 0x0020;
+const sal_uInt16 OOBIN_SHEETVIEW_SELECTED = 0x0040;
+const sal_uInt16 OOBIN_SHEETVIEW_SHOWRULER = 0x0080;
+const sal_uInt16 OOBIN_SHEETVIEW_SHOWOUTLINE = 0x0100;
+const sal_uInt16 OOBIN_SHEETVIEW_DEFGRIDCOLOR = 0x0200;
+const sal_uInt16 OOBIN_SHEETVIEW_SHOWWHITESPACE = 0x0400;
+
+const sal_uInt8 OOBIN_WBVIEW_HIDDEN = 0x01;
+const sal_uInt8 OOBIN_WBVIEW_MINIMIZED = 0x02;
+const sal_uInt8 OOBIN_WBVIEW_SHOWHORSCROLL = 0x08;
+const sal_uInt8 OOBIN_WBVIEW_SHOWVERSCROLL = 0x10;
+const sal_uInt8 OOBIN_WBVIEW_SHOWTABBAR = 0x20;
+const sal_uInt8 OOBIN_WBVIEW_AUTOFILTERGROUP = 0x40;
+
+const sal_uInt8 BIFF_PANE_BOTTOMRIGHT = 0; /// Bottom-right pane.
+const sal_uInt8 BIFF_PANE_TOPRIGHT = 1; /// Right, or top-right pane.
+const sal_uInt8 BIFF_PANE_BOTTOMLEFT = 2; /// Bottom, or bottom-left pane.
+const sal_uInt8 BIFF_PANE_TOPLEFT = 3; /// Single, top, left, or top-left pane.
+
+const sal_uInt16 BIFF_WINDOW1_HIDDEN = 0x0001;
+const sal_uInt16 BIFF_WINDOW1_MINIMIZED = 0x0002;
+const sal_uInt16 BIFF_WINDOW1_SHOWHORSCROLL = 0x0008;
+const sal_uInt16 BIFF_WINDOW1_SHOWVERSCROLL = 0x0010;
+const sal_uInt16 BIFF_WINDOW1_SHOWTABBAR = 0x0020;
+
+const sal_uInt16 BIFF_WINDOW2_SHOWFORMULAS = 0x0001;
+const sal_uInt16 BIFF_WINDOW2_SHOWGRID = 0x0002;
+const sal_uInt16 BIFF_WINDOW2_SHOWHEADINGS = 0x0004;
+const sal_uInt16 BIFF_WINDOW2_FROZEN = 0x0008;
+const sal_uInt16 BIFF_WINDOW2_SHOWZEROS = 0x0010;
+const sal_uInt16 BIFF_WINDOW2_DEFGRIDCOLOR = 0x0020;
+const sal_uInt16 BIFF_WINDOW2_RIGHTTOLEFT = 0x0040;
+const sal_uInt16 BIFF_WINDOW2_SHOWOUTLINE = 0x0080;
+const sal_uInt16 BIFF_WINDOW2_FROZENNOSPLIT = 0x0100;
+const sal_uInt16 BIFF_WINDOW2_SELECTED = 0x0200;
+const sal_uInt16 BIFF_WINDOW2_DISPLAYED = 0x0400;
+const sal_uInt16 BIFF_WINDOW2_PAGEBREAKMODE = 0x0800;
+
+// Attention: view settings in Calc do not use com.sun.star.view.DocumentZoomType!
+const sal_Int16 API_ZOOMTYPE_PERCENT = 0; /// Zoom value in percent.
+
+const sal_Int32 API_ZOOMVALUE_MIN = 20; /// Minimum zoom in Calc.
+const sal_Int32 API_ZOOMVALUE_MAX = 400; /// Maximum zoom in Calc.
+
+// no predefined constants for split mode
+const sal_Int16 API_SPLITMODE_NONE = 0; /// No splits in window.
+const sal_Int16 API_SPLITMODE_SPLIT = 1; /// Window is split.
+const sal_Int16 API_SPLITMODE_FREEZE = 2; /// Window has frozen panes.
+
+// no predefined constants for pane idetifiers
+const sal_Int16 API_SPLITPANE_TOPLEFT = 0; /// Top-left, or top pane.
+const sal_Int16 API_SPLITPANE_TOPRIGHT = 1; /// Top-right pane.
+const sal_Int16 API_SPLITPANE_BOTTOMLEFT = 2; /// Bottom-left, bottom, left, or single pane.
+const sal_Int16 API_SPLITPANE_BOTTOMRIGHT = 3; /// Bottom-right, or right pane.
+
+// ----------------------------------------------------------------------------
+
+/** Property names for document view settings. */
+const sal_Char* const sppcDocNames[] =
+{
+ "Tables",
+ "ActiveTable",
+ "HasHorizontalScrollBar",
+ "HasVerticalScrollBar",
+ "HasSheetTabs",
+ "RelativeHorizontalTabbarWidth",
+ "ShowObjects",
+ "ShowCharts",
+ "ShowDrawing",
+ 0
+};
+
+/** Property names for sheet view settings that are document-global in Calc. */
+const sal_Char* const sppcGlobalSheetNames[] =
+{
+ "GridColor",
+ "ZoomType",
+ "ZoomValue",
+ "PageViewZoomValue",
+ "ShowPageBreakPreview",
+ "ShowFormulas",
+ "ShowGrid",
+ "HasColumnRowHeaders",
+ "ShowZeroValues",
+ "IsOutlineSymbolsSet",
+ 0
+};
+
+/** Property names for sheet view settings. */
+const sal_Char* const sppcSheetNames[] =
+{
+ "TableSelected",
+ "CursorPositionX",
+ "CursorPositionY",
+ "HorizontalSplitMode",
+ "VerticalSplitMode",
+ "HorizontalSplitPositionTwips",
+ "VerticalSplitPositionTwips",
+ "ActiveSplitRange",
+ "PositionLeft",
+ "PositionTop",
+ "PositionRight",
+ "PositionBottom",
+ 0
+};
+
+// ----------------------------------------------------------------------------
+
+/** Returns the OOXML pane identifier from the passed OOBIN or BIFF pane id. */
+sal_Int32 lclGetOoxPaneId( sal_Int32 nBinPaneId, sal_Int32 nDefaultPaneId )
+{
+ static const sal_Int32 spnPaneIds[] = { XML_bottomRight, XML_topRight, XML_bottomLeft, XML_topLeft };
+ return STATIC_ARRAY_SELECT( spnPaneIds, nBinPaneId, nDefaultPaneId );
+}
+
+} // namespace
+
+// ============================================================================
+
+OoxSheetSelectionData::OoxSheetSelectionData() :
+ mnActiveCellId( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OoxSheetViewData::OoxSheetViewData() :
+ maGridColor( XML_indexed, OOX_COLOR_WINDOWTEXT ),
+ mnWorkbookViewId( 0 ),
+ mnViewType( XML_normal ),
+ mnActivePaneId( XML_topLeft ),
+ mnPaneState( XML_split ),
+ mfSplitX( 0.0 ),
+ mfSplitY( 0.0 ),
+ mnCurrentZoom( 0 ),
+ mnNormalZoom( 0 ),
+ mnSheetLayoutZoom( 0 ),
+ mnPageLayoutZoom( 0 ),
+ mbSelected( false ),
+ mbRightToLeft( false ),
+ mbDefGridColor( true ),
+ mbShowFormulas( false ),
+ mbShowGrid( true ),
+ mbShowHeadings( true ),
+ mbShowZeros( true ),
+ mbShowOutline( true )
+{
+}
+
+bool OoxSheetViewData::isPageBreakPreview() const
+{
+ return mnViewType == XML_pageBreakPreview;
+}
+
+sal_Int32 OoxSheetViewData::getNormalZoom() const
+{
+ const sal_Int32& rnZoom = isPageBreakPreview() ? mnNormalZoom : mnCurrentZoom;
+ sal_Int32 nZoom = (rnZoom > 0) ? rnZoom : OOX_SHEETVIEW_NORMALZOOM_DEF;
+ return getLimitedValue< sal_Int32 >( nZoom, API_ZOOMVALUE_MIN, API_ZOOMVALUE_MAX );
+}
+
+sal_Int32 OoxSheetViewData::getPageBreakZoom() const
+{
+ const sal_Int32& rnZoom = isPageBreakPreview() ? mnCurrentZoom : mnSheetLayoutZoom;
+ sal_Int32 nZoom = (rnZoom > 0) ? rnZoom : OOX_SHEETVIEW_SHEETLAYZOOM_DEF;
+ return getLimitedValue< sal_Int32 >( nZoom, API_ZOOMVALUE_MIN, API_ZOOMVALUE_MAX );
+}
+
+const OoxSheetSelectionData* OoxSheetViewData::getSelectionData( sal_Int32 nPaneId ) const
+{
+ return maSelMap.get( nPaneId ).get();
+}
+
+const OoxSheetSelectionData* OoxSheetViewData::getActiveSelectionData() const
+{
+ return getSelectionData( mnActivePaneId );
+}
+
+OoxSheetSelectionData& OoxSheetViewData::createSelectionData( sal_Int32 nPaneId )
+{
+ OoxSelectionDataMap::mapped_type& rxSelData = maSelMap[ nPaneId ];
+ if( !rxSelData )
+ rxSelData.reset( new OoxSheetSelectionData );
+ return *rxSelData;
+}
+
+// ----------------------------------------------------------------------------
+
+SheetViewSettings::SheetViewSettings( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void SheetViewSettings::importSheetView( const AttributeList& rAttribs )
+{
+ OoxSheetViewData& rData = *createSheetViewData();
+ rData.maGridColor.set( XML_indexed, rAttribs.getInteger( XML_colorId, OOX_COLOR_WINDOWTEXT ) );
+ rData.maFirstPos = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_topLeftCell ), getSheetIndex(), false );
+ rData.mnWorkbookViewId = rAttribs.getToken( XML_workbookViewId, 0 );
+ rData.mnViewType = rAttribs.getToken( XML_view, XML_normal );
+ rData.mnCurrentZoom = rAttribs.getInteger( XML_zoomScale, 100 );
+ rData.mnNormalZoom = rAttribs.getInteger( XML_zoomScaleNormal, 0 );
+ rData.mnSheetLayoutZoom = rAttribs.getInteger( XML_zoomScaleSheetLayoutView, 0 );
+ rData.mnPageLayoutZoom = rAttribs.getInteger( XML_zoomScalePageLayoutView, 0 );
+ rData.mbSelected = rAttribs.getBool( XML_tabSelected, false );
+ rData.mbRightToLeft = rAttribs.getBool( XML_rightToLeft, false );
+ rData.mbDefGridColor = rAttribs.getBool( XML_defaultGridColor, true );
+ rData.mbShowFormulas = rAttribs.getBool( XML_showFormulas, false );
+ rData.mbShowGrid = rAttribs.getBool( XML_showGridLines, true );
+ rData.mbShowHeadings = rAttribs.getBool( XML_showRowColHeaders, true );
+ rData.mbShowZeros = rAttribs.getBool( XML_showZeros, true );
+ rData.mbShowOutline = rAttribs.getBool( XML_showOutlineSymbols, true );
+}
+
+void SheetViewSettings::importPane( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( !maSheetDatas.empty(), "SheetViewSettings::importPane - missing view data" );
+ if( !maSheetDatas.empty() )
+ {
+ OoxSheetViewData& rData = *maSheetDatas.back();
+ rData.maSecondPos = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_topLeftCell ), getSheetIndex(), false );
+ rData.mnActivePaneId = rAttribs.getToken( XML_activePane, XML_topLeft );
+ rData.mnPaneState = rAttribs.getToken( XML_state, XML_split );
+ rData.mfSplitX = rAttribs.getDouble( XML_xSplit, 0.0 );
+ rData.mfSplitY = rAttribs.getDouble( XML_ySplit, 0.0 );
+ }
+}
+
+void SheetViewSettings::importSelection( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( !maSheetDatas.empty(), "SheetViewSettings::importSelection - missing view data" );
+ if( !maSheetDatas.empty() )
+ {
+ // pane this selection belongs to
+ sal_Int32 nPaneId = rAttribs.getToken( XML_pane, XML_topLeft );
+ OoxSheetSelectionData& rSelData = maSheetDatas.back()->createSelectionData( nPaneId );
+ // cursor position
+ rSelData.maActiveCell = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_activeCell ), getSheetIndex(), false );
+ rSelData.mnActiveCellId = rAttribs.getInteger( XML_activeCellId, 0 );
+ // selection
+ rSelData.maSelection.clear();
+ getAddressConverter().convertToCellRangeList( rSelData.maSelection, rAttribs.getString( XML_sqref ), getSheetIndex(), false );
+ }
+}
+
+void SheetViewSettings::importSheetView( RecordInputStream& rStrm )
+{
+ OoxSheetViewData& rData = *createSheetViewData();
+ sal_uInt16 nFlags;
+ sal_Int32 nViewType;
+ BinAddress aFirstPos;
+ rStrm >> nFlags >> nViewType >> aFirstPos;
+ rData.maGridColor.importColorId( rStrm );
+ rData.mnCurrentZoom = rStrm.readuInt16();
+ rData.mnNormalZoom = rStrm.readuInt16();
+ rData.mnSheetLayoutZoom = rStrm.readuInt16();
+ rData.mnPageLayoutZoom = rStrm.readuInt16();
+ rStrm >> rData.mnWorkbookViewId;
+
+ rData.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
+ static const sal_Int32 spnViewTypes[] = { XML_normal, XML_pageBreakPreview, XML_pageLayout };
+ rData.mnViewType = STATIC_ARRAY_SELECT( spnViewTypes, nViewType, XML_normal );
+ rData.mbSelected = getFlag( nFlags, OOBIN_SHEETVIEW_SELECTED );
+ rData.mbRightToLeft = getFlag( nFlags, OOBIN_SHEETVIEW_RIGHTTOLEFT );
+ rData.mbDefGridColor = getFlag( nFlags, OOBIN_SHEETVIEW_DEFGRIDCOLOR );
+ rData.mbShowFormulas = getFlag( nFlags, OOBIN_SHEETVIEW_SHOWFORMULAS );
+ rData.mbShowGrid = getFlag( nFlags, OOBIN_SHEETVIEW_SHOWGRID );
+ rData.mbShowHeadings = getFlag( nFlags, OOBIN_SHEETVIEW_SHOWHEADINGS );
+ rData.mbShowZeros = getFlag( nFlags, OOBIN_SHEETVIEW_SHOWZEROS );
+ rData.mbShowOutline = getFlag( nFlags, OOBIN_SHEETVIEW_SHOWOUTLINE );
+}
+
+void SheetViewSettings::importPane( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetDatas.empty(), "SheetViewSettings::importPane - missing view data" );
+ if( !maSheetDatas.empty() )
+ {
+ OoxSheetViewData& rData = *maSheetDatas.back();
+
+ BinAddress aSecondPos;
+ sal_Int32 nActivePaneId;
+ sal_uInt8 nFlags;
+ rStrm >> rData.mfSplitX >> rData.mfSplitY >> aSecondPos >> nActivePaneId >> nFlags;
+
+ rData.maSecondPos = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false );
+ rData.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft );
+ rData.mnPaneState = getFlagValue( nFlags, OOBIN_PANE_FROZEN, getFlagValue( nFlags, OOBIN_PANE_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split );
+ }
+}
+
+void SheetViewSettings::importSelection( RecordInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetDatas.empty(), "SheetViewSettings::importSelection - missing view data" );
+ if( !maSheetDatas.empty() )
+ {
+ // pane this selection belongs to
+ sal_Int32 nPaneId = rStrm.readInt32();
+ OoxSheetSelectionData& rSelData = maSheetDatas.back()->createSelectionData( lclGetOoxPaneId( nPaneId, -1 ) );
+ // cursor position
+ BinAddress aActiveCell;
+ rStrm >> aActiveCell >> rSelData.mnActiveCellId;
+ rSelData.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false );
+ // selection
+ BinRangeList aSelection;
+ rStrm >> aSelection;
+ rSelData.maSelection.clear();
+ getAddressConverter().convertToCellRangeList( rSelData.maSelection, aSelection, getSheetIndex(), false );
+ }
+}
+
+void SheetViewSettings::importWindow2( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( maSheetDatas.empty(), "SheetViewSettings::importWindow2 - multiple WINDOW2 records" );
+ OoxSheetViewData& rData = *createSheetViewData();
+ if( getBiff() == BIFF2 )
+ {
+ rData.mbShowFormulas = rStrm.readuInt8() != 0;
+ rData.mbShowGrid = rStrm.readuInt8() != 0;
+ rData.mbShowHeadings = rStrm.readuInt8() != 0;
+ rData.mnPaneState = (rStrm.readuInt8() == 0) ? XML_split : XML_frozen;
+ rData.mbShowZeros = rStrm.readuInt8() != 0;
+ BinAddress aFirstPos;
+ rStrm >> aFirstPos;
+ rData.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
+ rData.mbDefGridColor = rStrm.readuInt8() != 0;
+ rData.maGridColor.importColorRgb( rStrm );
+ }
+ else
+ {
+ sal_uInt16 nFlags;
+ BinAddress aFirstPos;
+ rStrm >> nFlags >> aFirstPos;
+
+ rData.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
+ rData.mnViewType = getFlagValue( nFlags, BIFF_WINDOW2_PAGEBREAKMODE, XML_pageBreakPreview, XML_normal );
+ rData.mnPaneState = getFlagValue( nFlags, BIFF_WINDOW2_FROZEN, getFlagValue( nFlags, BIFF_WINDOW2_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split );
+ rData.mbSelected = getFlag( nFlags, BIFF_WINDOW2_SELECTED );
+ rData.mbRightToLeft = getFlag( nFlags, BIFF_WINDOW2_RIGHTTOLEFT );
+ rData.mbDefGridColor = getFlag( nFlags, BIFF_WINDOW2_DEFGRIDCOLOR );
+ rData.mbShowFormulas = getFlag( nFlags, BIFF_WINDOW2_SHOWFORMULAS );
+ rData.mbShowGrid = getFlag( nFlags, BIFF_WINDOW2_SHOWGRID );
+ rData.mbShowHeadings = getFlag( nFlags, BIFF_WINDOW2_SHOWHEADINGS );
+ rData.mbShowZeros = getFlag( nFlags, BIFF_WINDOW2_SHOWZEROS );
+ rData.mbShowOutline = getFlag( nFlags, BIFF_WINDOW2_SHOWOUTLINE );
+
+ if( getBiff() == BIFF8 )
+ {
+ rData.maGridColor.importColorId( rStrm );
+ // zoom data not included in chart sheets
+ if( rStrm.getRecLeft() >= 6 )
+ {
+ rStrm.skip( 2 );
+ sal_uInt16 nPageZoom, nNormalZoom;
+ rStrm >> nPageZoom >> nNormalZoom;
+ rData.mnSheetLayoutZoom = nPageZoom;
+ rData.mnNormalZoom = nNormalZoom;
+ }
+ }
+ else
+ {
+ rData.maGridColor.importColorRgb( rStrm );
+ }
+ }
+}
+
+void SheetViewSettings::importPane( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetDatas.empty(), "SheetViewSettings::importPane - missing leading WINDOW2 record" );
+ if( !maSheetDatas.empty() )
+ {
+ sal_uInt8 nActivePaneId;
+ sal_uInt16 nSplitX, nSplitY;
+ BinAddress aSecondPos;
+ rStrm >> nSplitX >> nSplitY >> aSecondPos >> nActivePaneId;
+
+ OoxSheetViewData& rData = *maSheetDatas.back();
+ rData.mfSplitX = nSplitX;
+ rData.mfSplitY = nSplitY;
+ rData.maSecondPos = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false );
+ rData.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft );
+ }
+}
+
+void SheetViewSettings::importScl( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetDatas.empty(), "SheetViewSettings::importScl - missing leading WINDOW2 record" );
+ if( !maSheetDatas.empty() )
+ {
+ sal_uInt16 nNum, nDenom;
+ rStrm >> nNum >> nDenom;
+ OSL_ENSURE( nDenom > 0, "SheetViewSettings::importScl - invalid denominator" );
+ if( nDenom > 0 )
+ maSheetDatas.back()->mnCurrentZoom = getLimitedValue< sal_Int32, sal_uInt16 >( (nNum * 100) / nDenom, 10, 400 );
+ }
+}
+
+void SheetViewSettings::importSelection( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetDatas.empty(), "SheetViewSettings::importPane - missing leading WINDOW2 record" );
+ if( !maSheetDatas.empty() )
+ {
+ // pane this selection belongs to
+ sal_uInt8 nPaneId = rStrm.readuInt8();
+ OoxSheetSelectionData& rSelData = maSheetDatas.back()->createSelectionData( lclGetOoxPaneId( nPaneId, -1 ) );
+ // cursor position
+ BinAddress aActiveCell;
+ sal_uInt16 nActiveCellId;
+ rStrm >> aActiveCell >> nActiveCellId;
+ rSelData.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false );
+ rSelData.mnActiveCellId = nActiveCellId;
+ // selection
+ rSelData.maSelection.clear();
+ BinRangeList aSelection;
+ aSelection.read( rStrm, false );
+ getAddressConverter().convertToCellRangeList( rSelData.maSelection, aSelection, getSheetIndex(), false );
+ }
+}
+
+void SheetViewSettings::finalizeImport()
+{
+ // force creation of sheet view data to get the Excel defaults
+ OoxSheetViewDataRef xData = maSheetDatas.empty() ? createSheetViewData() : maSheetDatas.front();
+
+ // mirrored sheet (this is not a view setting in Calc)
+ // #i59590# real life: Excel ignores mirror flag in chart sheets
+ if( xData->mbRightToLeft && (getSheetType() != SHEETTYPE_CHART) )
+ {
+ PropertySet aPropSet( getXSpreadsheet() );
+ aPropSet.setProperty( CREATE_OUSTRING( "TableLayout" ), ::com::sun::star::text::WritingMode2::RL_TB );
+ }
+
+ // sheet selected (active sheet must be selected)
+ bool bSelected = xData->mbSelected || (getSheetIndex() == getViewSettings().getActiveSheetIndex());
+
+ // current cursor position (selection not supported via API)
+ const OoxSheetSelectionData* pSelData = xData->getActiveSelectionData();
+ CellAddress aCursor = pSelData ? pSelData->maActiveCell : xData->maFirstPos;
+
+ // freeze/split position
+ sal_Int16 nHSplitMode = API_SPLITMODE_NONE;
+ sal_Int16 nVSplitMode = API_SPLITMODE_NONE;
+ sal_Int32 nHSplitPos = 0;
+ sal_Int32 nVSplitPos = 0;
+ if( (xData->mnPaneState == XML_frozen) || (xData->mnPaneState == XML_frozenSplit) )
+ {
+ /* Frozen panes: handle split position as row/column positions.
+ #i35812# Excel uses number of visible rows/columns in the
+ frozen area (rows/columns scolled outside are not incuded),
+ Calc uses absolute position of first unfrozen row/column. */
+ const CellAddress& rMaxApiPos = getAddressConverter().getMaxApiAddress();
+ if( (xData->mfSplitX >= 1.0) && (xData->maFirstPos.Column + xData->mfSplitX <= rMaxApiPos.Column) )
+ nHSplitPos = static_cast< sal_Int32 >( xData->maFirstPos.Column + xData->mfSplitX );
+ nHSplitMode = (nHSplitPos > 0) ? API_SPLITMODE_FREEZE : API_SPLITMODE_NONE;
+ if( (xData->mfSplitY >= 1.0) && (xData->maFirstPos.Row + xData->mfSplitY <= rMaxApiPos.Row) )
+ nVSplitPos = static_cast< sal_Int32 >( xData->maFirstPos.Row + xData->mfSplitY );
+ nVSplitMode = (nVSplitPos > 0) ? API_SPLITMODE_FREEZE : API_SPLITMODE_NONE;
+ }
+ else if( xData->mnPaneState == XML_split )
+ {
+ // split window: view settings API uses twips...
+ nHSplitPos = getLimitedValue< sal_Int32, double >( xData->mfSplitX + 0.5, 0, SAL_MAX_INT32 );
+ nHSplitMode = (nHSplitPos > 0) ? API_SPLITMODE_SPLIT : API_SPLITMODE_NONE;
+ nVSplitPos = getLimitedValue< sal_Int32, double >( xData->mfSplitY + 0.5, 0, SAL_MAX_INT32 );
+ nVSplitMode = (nVSplitPos > 0) ? API_SPLITMODE_SPLIT : API_SPLITMODE_NONE;
+ }
+
+ // active pane
+ sal_Int16 nActivePane = API_SPLITPANE_BOTTOMLEFT;
+ switch( xData->mnActivePaneId )
+ {
+ // no horizontal split -> always use left panes
+ // no vertical split -> always use *bottom* panes
+ case XML_topLeft:
+ nActivePane = (nVSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMLEFT : API_SPLITPANE_TOPLEFT;
+ break;
+ case XML_topRight:
+ nActivePane = (nHSplitMode == API_SPLITMODE_NONE) ?
+ ((nVSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMLEFT : API_SPLITPANE_TOPLEFT) :
+ ((nVSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMRIGHT : API_SPLITPANE_TOPRIGHT);
+ break;
+ case XML_bottomLeft:
+ nActivePane = API_SPLITPANE_BOTTOMLEFT;
+ break;
+ case XML_bottomRight:
+ nActivePane = (nHSplitMode == API_SPLITMODE_NONE) ? API_SPLITPANE_BOTTOMLEFT : API_SPLITPANE_BOTTOMRIGHT;
+ break;
+ }
+
+ // automatic grid color
+ if( xData->mbDefGridColor )
+ xData->maGridColor.set( XML_auto, 0 );
+
+ // write the sheet view settings into the property sequence
+ PropertySequence aSheetProps( sppcSheetNames, sppcGlobalSheetNames );
+ aSheetProps
+ << bSelected
+ << aCursor.Column
+ << aCursor.Row
+ << nHSplitMode
+ << nVSplitMode
+ << nHSplitPos
+ << nVSplitPos
+ << nActivePane
+ << xData->maFirstPos.Column
+ << xData->maFirstPos.Row
+ << xData->maSecondPos.Column
+ << ((nVSplitPos > 0) ? xData->maSecondPos.Row : xData->maFirstPos.Row)
+ << getStyles().getColor( xData->maGridColor, API_RGB_TRANSPARENT )
+ << API_ZOOMTYPE_PERCENT
+ << static_cast< sal_Int16 >( xData->getNormalZoom() )
+ << static_cast< sal_Int16 >( xData->getPageBreakZoom() )
+ << xData->isPageBreakPreview()
+ << xData->mbShowFormulas
+ << xData->mbShowGrid
+ << xData->mbShowHeadings
+ << xData->mbShowZeros
+ << xData->mbShowOutline;
+
+ // store sheet view settings in global view settings object
+ getViewSettings().setSheetViewSettings( getSheetIndex(), xData, Any( aSheetProps.createPropertySequence() ) );
+}
+
+// private --------------------------------------------------------------------
+
+OoxSheetViewDataRef SheetViewSettings::createSheetViewData()
+{
+ OoxSheetViewDataRef xData( new OoxSheetViewData );
+ maSheetDatas.push_back( xData );
+ return xData;
+}
+
+// ============================================================================
+
+OoxWorkbookViewData::OoxWorkbookViewData() :
+ mnWinX( 0 ),
+ mnWinY( 0 ),
+ mnWinWidth( 0 ),
+ mnWinHeight( 0 ),
+ mnActiveSheet( 0 ),
+ mnFirstVisSheet( 0 ),
+ mnTabBarWidth( OOX_BOOKVIEW_TABBARRATIO_DEF ),
+ mnVisibility( XML_visible ),
+ mbShowTabBar( true ),
+ mbShowHorScroll( true ),
+ mbShowVerScroll( true ),
+ mbMinimized( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ViewSettings::ViewSettings( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void ViewSettings::importWorkbookView( const AttributeList& rAttribs )
+{
+ OoxWorkbookViewData& rData = createWorkbookViewData();
+ rData.mnWinX = rAttribs.getInteger( XML_xWindow, 0 );
+ rData.mnWinY = rAttribs.getInteger( XML_yWindow, 0 );
+ rData.mnWinWidth = rAttribs.getInteger( XML_windowWidth, 0 );
+ rData.mnWinHeight = rAttribs.getInteger( XML_windowHeight, 0 );
+ rData.mnActiveSheet = rAttribs.getInteger( XML_activeTab, 0 );
+ rData.mnFirstVisSheet = rAttribs.getInteger( XML_firstSheet, 0 );
+ rData.mnTabBarWidth = rAttribs.getInteger( XML_tabRatio, 600 );
+ rData.mnVisibility = rAttribs.getToken( XML_visibility, XML_visible );
+ rData.mbShowTabBar = rAttribs.getBool( XML_showSheetTabs, true );
+ rData.mbShowHorScroll = rAttribs.getBool( XML_showHorizontalScroll, true );
+ rData.mbShowVerScroll = rAttribs.getBool( XML_showVerticalScroll, true );
+ rData.mbMinimized = rAttribs.getBool( XML_minimized, false );
+}
+
+void ViewSettings::importWorkbookView( RecordInputStream& rStrm )
+{
+ OoxWorkbookViewData& rData = createWorkbookViewData();
+ sal_uInt8 nFlags;
+ rStrm >> rData.mnWinX >> rData.mnWinY >> rData.mnWinWidth >> rData.mnWinHeight >> rData.mnTabBarWidth >> rData.mnFirstVisSheet >> rData.mnActiveSheet >> nFlags;
+ rData.mnVisibility = getFlagValue( nFlags, OOBIN_WBVIEW_HIDDEN, XML_hidden, XML_visible );
+ rData.mbShowTabBar = getFlag( nFlags, OOBIN_WBVIEW_SHOWTABBAR );
+ rData.mbShowHorScroll = getFlag( nFlags, OOBIN_WBVIEW_SHOWHORSCROLL );
+ rData.mbShowVerScroll = getFlag( nFlags, OOBIN_WBVIEW_SHOWVERSCROLL );
+ rData.mbMinimized = getFlag( nFlags, OOBIN_WBVIEW_MINIMIZED );
+}
+
+void ViewSettings::importWindow1( BiffInputStream& rStrm )
+{
+ sal_uInt16 nWinX, nWinY, nWinWidth, nWinHeight;
+ rStrm >> nWinX >> nWinY >> nWinWidth >> nWinHeight;
+
+ // WINDOW1 record occures in every sheet in BIFF4W
+ OSL_ENSURE( maBookDatas.empty() || ((getBiff() == BIFF4) && isWorkbookFile()),
+ "ViewSettings::importWindow1 - multiple WINDOW1 records" );
+ OoxWorkbookViewData& rData = createWorkbookViewData();
+ rData.mnWinX = nWinX;
+ rData.mnWinY = nWinY;
+ rData.mnWinWidth = nWinWidth;
+ rData.mnWinHeight = nWinHeight;
+
+ if( getBiff() <= BIFF4 )
+ {
+ sal_uInt8 nHidden;
+ rStrm >> nHidden;
+ rData.mnVisibility = (nHidden == 0) ? XML_visible : XML_hidden;
+ }
+ else
+ {
+ sal_uInt16 nFlags, nActiveTab, nFirstVisTab, nSelectCnt, nTabBarWidth;
+ rStrm >> nFlags >> nActiveTab >> nFirstVisTab >> nSelectCnt >> nTabBarWidth;
+
+ rData.mnActiveSheet = nActiveTab;
+ rData.mnFirstVisSheet = nFirstVisTab;
+ rData.mnTabBarWidth = nTabBarWidth;
+ rData.mnVisibility = getFlagValue( nFlags, BIFF_WINDOW1_HIDDEN, XML_hidden, XML_visible );
+ rData.mbMinimized = getFlag( nFlags, BIFF_WINDOW1_MINIMIZED );
+ rData.mbShowHorScroll = getFlag( nFlags, BIFF_WINDOW1_SHOWHORSCROLL );
+ rData.mbShowVerScroll = getFlag( nFlags, BIFF_WINDOW1_SHOWVERSCROLL );
+ rData.mbShowTabBar = getFlag( nFlags, BIFF_WINDOW1_SHOWTABBAR );
+ }
+}
+
+void ViewSettings::setSheetViewSettings( sal_Int32 nSheet, const OoxSheetViewDataRef& rxViewData, const Any& rProperties )
+{
+ maSheetDatas[ nSheet ] = rxViewData;
+ maSheetProps[ nSheet ] = rProperties;
+}
+
+void ViewSettings::finalizeImport()
+{
+ const WorksheetBuffer& rWorksheets = getWorksheets();
+ if( rWorksheets.getInternalSheetCount() <= 0 ) return;
+
+ // force creation of workbook view data to get the Excel defaults
+ const OoxWorkbookViewData& rData = maBookDatas.empty() ? createWorkbookViewData() : *maBookDatas.front();
+
+ // show object mode is part of workbook settings
+ sal_Int16 nShowMode = getWorkbookSettings().getApiShowObjectMode();
+
+ // view settings for all sheets
+ Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer();
+ if( !xSheetsNC.is() ) return;
+ for( SheetPropertiesMap::const_iterator aIt = maSheetProps.begin(), aEnd = maSheetProps.end(); aIt != aEnd; ++aIt )
+ ContainerHelper::insertByName( xSheetsNC, rWorksheets.getFinalSheetName( aIt->first ), aIt->second );
+
+ // use data of active sheet to set sheet properties that are document-global in Calc
+ sal_Int32 nActiveSheet = getActiveSheetIndex();
+ OoxSheetViewDataRef& rxActiveSheetData = maSheetDatas[ nActiveSheet ];
+ OSL_ENSURE( rxActiveSheetData.get(), "ViewSettings::finalizeImport - missing active sheet view settings" );
+ if( !rxActiveSheetData )
+ rxActiveSheetData.reset( new OoxSheetViewData );
+
+ PropertySequence aDocProps( sppcDocNames, sppcGlobalSheetNames );
+ aDocProps
+ << xSheetsNC
+ << rWorksheets.getFinalSheetName( nActiveSheet )
+ << rData.mbShowHorScroll
+ << rData.mbShowVerScroll
+ << rData.mbShowTabBar
+ << double( rData.mnTabBarWidth / 1000.0 )
+ << nShowMode << nShowMode << nShowMode
+ << getStyles().getColor( rxActiveSheetData->maGridColor, API_RGB_TRANSPARENT )
+ << API_ZOOMTYPE_PERCENT
+ << static_cast< sal_Int16 >( rxActiveSheetData->getNormalZoom() )
+ << static_cast< sal_Int16 >( rxActiveSheetData->getPageBreakZoom() )
+ << rxActiveSheetData->isPageBreakPreview()
+ << rxActiveSheetData->mbShowFormulas
+ << rxActiveSheetData->mbShowGrid
+ << rxActiveSheetData->mbShowHeadings
+ << rxActiveSheetData->mbShowZeros
+ << rxActiveSheetData->mbShowOutline;
+
+ Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer();
+ if( xContainer.is() ) try
+ {
+ xContainer->insertByIndex( 0, Any( aDocProps.createPropertySequence() ) );
+ Reference< XIndexAccess > xIAccess( xContainer, UNO_QUERY_THROW );
+ Reference< XViewDataSupplier > xViewDataSuppl( getDocument(), UNO_QUERY_THROW );
+ xViewDataSuppl->setViewData( xIAccess );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "ViewSettings::finalizeImport - cannot create document view settings" );
+ }
+}
+
+sal_Int32 ViewSettings::getActiveSheetIndex() const
+{
+ sal_Int32 nSheetCount = getLimitedValue< sal_Int32, sal_Int32 >( getWorksheets().getInternalSheetCount(), 1, SAL_MAX_INT32 );
+ return maBookDatas.empty() ? 0 : getLimitedValue< sal_Int32, sal_Int32 >( maBookDatas.front()->mnActiveSheet, 0, nSheetCount - 1 );
+}
+
+// private --------------------------------------------------------------------
+
+OoxWorkbookViewData& ViewSettings::createWorkbookViewData()
+{
+ OoxWorkbookViewDataRef xData( new OoxWorkbookViewData );
+ maBookDatas.push_back( xData );
+ return *xData;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/webquerybuffer.cxx b/oox/source/xls/webquerybuffer.cxx
new file mode 100644
index 000000000000..c4ce7953dacd
--- /dev/null
+++ b/oox/source/xls/webquerybuffer.cxx
@@ -0,0 +1,207 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: webquerybuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/webquerybuffer.hxx"
+#include "oox/helper/attributelist.hxx"
+
+#define DEBUG_OOX_WEBQUERY_BUFFER 1
+
+#if DEBUG_OOX_WEBQUERY_BUFFER
+#include <stdio.h>
+#endif
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace xls {
+
+const sal_Int32 Connection::CONNECTION_ODBC_SOURCE = 1;
+const sal_Int32 Connection::CONNECTION_DAO_SOURCE = 2;
+const sal_Int32 Connection::CONNECTION_FILE_SOURCE = 3;
+const sal_Int32 Connection::CONNECTION_WEBQUERY = 4;
+const sal_Int32 Connection::CONNECTION_OLEDB_SOURCE = 5;
+const sal_Int32 Connection::CONNECTION_TEXT_SOURCE = 6;
+const sal_Int32 Connection::CONNECTION_ADO_RECORD_SET = 7;
+const sal_Int32 Connection::CONNECTION_DSP = 8;
+
+// ============================================================================
+
+WebQueryBuffer::WebQueryBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+ maQueryTableMap.clear();
+}
+
+void WebQueryBuffer::importQueryTable( const AttributeList& rAttribs )
+{
+ OUString aName = rAttribs.getString( XML_name );
+ if ( !aName.getLength() )
+ return;
+
+ QueryTable aQTable;
+ aQTable.mnConnectionId = rAttribs.getInteger( XML_connectionId, 0 );
+
+ maQueryTableMap.insert( QueryTableHashMap::value_type( aName, aQTable ) );
+
+ // All documented attributes of queryTable:
+ // adjustColumnWidth (bool)
+ // applyAlignmentFormats (bool)
+ // applyBorderFormats (bool)
+ // applyFontFormats (bool)
+ // applyNumberFormats (bool)
+ // applyPatternFormats (bool)
+ // applyWidthHeightFormats (bool)
+ // autoFormatId (unsigned int)
+ // backgroundRefresh (bool)
+ // connectionId (unsigned int)
+ // disableEdit (bool)
+ // disableRefresh (bool)
+ // fillFormulas (bool)
+ // firstBackgroundRefresh (bool)
+ // growShrinkType (insertClear, insertDelete, overwriteClear)
+ // headers (bool)
+ // intermediate (bool)
+ // name (string)
+ // preserveFormatting(bool)
+ // refreshOnLoad (bool)
+ // removeDataOnSave (bool)
+ // rowNumbers (bool)
+}
+
+void WebQueryBuffer::importConnection( const AttributeList& rAttribs )
+{
+ if ( !rAttribs.hasAttribute( XML_id ) || !rAttribs.hasAttribute( XML_name ) )
+ {
+ mnCurConnId = -1;
+ return;
+ }
+
+ sal_uInt32 nId = rAttribs.getUnsignedInteger( XML_id, 0 );
+ if ( maConnections.size() < (nId + 1) )
+ maConnections.resize(nId + 1);
+
+ Connection aConn;
+ aConn.maName = rAttribs.getString( XML_name );
+ aConn.mnType = rAttribs.getInteger( XML_type, 0 );
+ maConnections[nId] = aConn;
+ mnCurConnId = nId;
+
+ // All documented attributes of connection.
+ // background (bool)
+ // credentials (integrated, none, prompt, stored)
+ // deleted (bool)
+ // description (string)
+ // id (unsigned int)
+ // interval (unsigned int)
+ // keepAlive (bool)
+ // minRefreshableVersion (unsigned byte)
+ // name (string)
+ // new (bool)
+ // odcFile (string)
+ // onlyUseConnectionFile (bool)
+ // reconnectionMethod (unsigned int)
+ // refreshedVersion (unsigned byte)
+ // refreshOnLoad (bool)
+ // saveData (bool)
+ // savePassword (bool)
+ // singleSignOnId (string)
+ // sourceFile (string)
+ // type (unsigned int)
+}
+
+void WebQueryBuffer::importWebPr( const AttributeList& rAttribs )
+{
+ if ( 0 > mnCurConnId )
+ return;
+
+ Connection& rConn = maConnections[mnCurConnId];
+ rConn.mpProperties.reset( new WebProperties );
+ WebProperties* pWebPr = static_cast< WebProperties* >( rConn.mpProperties.get() );
+ pWebPr->maURL = rAttribs.getString( XML_url );
+
+ // All available attributes:
+ // consecutive (bool)
+ // editPage (string)
+ // firstRow (bool)
+ // htmlFormat (all, none, rtf)
+ // htmlTables (bool)
+ // parsePre (bool)
+ // post (string)
+ // sourceData (bool)
+ // textDates (bool)
+ // url (string)
+ // xl2000 (bool)
+ // xl97 (bool)
+ // xml (bool)
+}
+
+void WebQueryBuffer::dump() const
+{
+#if DEBUG_OOX_WEBQUERY_BUFFER
+ fprintf(stdout, "----------------------------------------\n");
+ {
+ using ::std::vector;
+ vector< Connection >::const_iterator itr = maConnections.begin(), itrEnd = maConnections.end();
+ sal_Int32 nId = 0;
+ for (; itr != itrEnd; ++itr, ++nId)
+ {
+ if ( itr->mnType == Connection::CONNECTION_WEBQUERY )
+ {
+ WebProperties* pWebPr = static_cast< WebProperties* >( itr->mpProperties.get() );
+ fprintf(stdout, "WebQueryBuffer::dump: id = %d url = %s\n",
+ (int)nId,
+ OUStringToOString(pWebPr->maURL, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ }
+
+ QueryTableHashMap::const_iterator itr = maQueryTableMap.begin(), itrEnd = maQueryTableMap.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ fprintf(stdout, "WebQueryBuffer::dump: name = %s connection ID = %d\n",
+ OUStringToOString(itr->first, RTL_TEXTENCODING_UTF8).getStr(),
+ (int)(itr->second.mnConnectionId));
+ }
+
+ fprintf(stdout, "----------------------------------------\n");
+ fflush(stdout);
+#endif
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx
new file mode 100644
index 000000000000..838711bb1198
--- /dev/null
+++ b/oox/source/xls/workbookfragment.cxx
@@ -0,0 +1,756 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: workbookfragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/workbookfragment.hxx"
+#include <com/sun/star/table/CellAddress.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/progressbar.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/drawingml/themefragmenthandler.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/connectionsfragment.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/externallinkfragment.hxx"
+#include "oox/xls/pivotcachefragment.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/sharedstringsfragment.hxx"
+#include "oox/xls/stylesfragment.hxx"
+#include "oox/xls/tablebuffer.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+#include "oox/xls/worksheetfragment.hxx"
+
+using ::rtl::OUString;
+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 ::com::sun::star::table::CellAddress;
+using ::oox::core::FragmentHandlerRef;
+using ::oox::core::Relation;
+using ::oox::drawingml::ThemeFragmentHandler;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const double PROGRESS_LENGTH_GLOBALS = 0.1; /// 10% of progress bar for globals import.
+
+const sal_uInt16 BIFF_FILEPASS_BIFF2 = 0x0000;
+const sal_uInt16 BIFF_FILEPASS_BIFF8 = 0x0001;
+const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF = 0x0001;
+const sal_uInt16 BIFF_FILEPASS_BIFF8_STRONG = 0x0002;
+
+} // namespace
+
+// ============================================================================
+
+OoxWorkbookFragment::OoxWorkbookFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxWorkbookFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nElement == XLS_TOKEN( workbook ));
+ case XLS_TOKEN( workbook ):
+ return (nElement == XLS_TOKEN( workbookPr )) ||
+ (nElement == XLS_TOKEN( calcPr )) ||
+ (nElement == XLS_TOKEN( sheets )) ||
+ (nElement == XLS_TOKEN( bookViews )) ||
+ (nElement == XLS_TOKEN( externalReferences )) ||
+ (nElement == XLS_TOKEN( definedNames )) ||
+ (nElement == XLS_TOKEN( pivotCaches ));
+ case XLS_TOKEN( sheets ):
+ return (nElement == XLS_TOKEN( sheet ));
+ case XLS_TOKEN( bookViews ):
+ return (nElement == XLS_TOKEN( workbookView ));
+ case XLS_TOKEN( externalReferences ):
+ return (nElement == XLS_TOKEN( externalReference ));
+ case XLS_TOKEN( definedNames ):
+ return (nElement == XLS_TOKEN( definedName ));
+ case XLS_TOKEN( pivotCaches ):
+ return (nElement == XLS_TOKEN( pivotCache ));
+ }
+ return false;
+}
+
+void OoxWorkbookFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break;
+ case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break;
+ case XLS_TOKEN( sheet ): getWorksheets().importSheet( rAttribs ); break;
+ case XLS_TOKEN( workbookView ): getViewSettings().importWorkbookView( rAttribs ); break;
+ case XLS_TOKEN( externalReference ): importExternalReference( rAttribs ); break;
+ case XLS_TOKEN( definedName ): importDefinedName( rAttribs ); break;
+ case XLS_TOKEN( pivotCache ): importPivotCache( rAttribs ); break;
+ }
+}
+
+void OoxWorkbookFragment::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( definedName ):
+ if( mxCurrName.get() ) mxCurrName->setFormula( rChars );
+ break;
+ }
+}
+
+bool OoxWorkbookFragment::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nRecId == OOBIN_ID_WORKBOOK);
+ case OOBIN_ID_WORKBOOK:
+ return (nRecId == OOBIN_ID_WORKBOOKPR) ||
+ (nRecId == OOBIN_ID_CALCPR) ||
+ (nRecId == OOBIN_ID_SHEETS) ||
+ (nRecId == OOBIN_ID_BOOKVIEWS) ||
+ (nRecId == OOBIN_ID_EXTERNALREFS) ||
+ (nRecId == OOBIN_ID_DEFINEDNAME);
+ case OOBIN_ID_SHEETS:
+ return (nRecId == OOBIN_ID_SHEET);
+ case OOBIN_ID_BOOKVIEWS:
+ return (nRecId == OOBIN_ID_WORKBOOKVIEW);
+ case OOBIN_ID_EXTERNALREFS:
+ return (nRecId == OOBIN_ID_EXTERNALREF) ||
+ (nRecId == OOBIN_ID_EXTERNALSELF) ||
+ (nRecId == OOBIN_ID_EXTERNALSHEETS);
+ }
+ return false;
+}
+
+void OoxWorkbookFragment::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_WORKBOOKPR: getWorkbookSettings().importWorkbookPr( rStrm ); break;
+ case OOBIN_ID_CALCPR: getWorkbookSettings().importCalcPr( rStrm ); break;
+ case OOBIN_ID_SHEET: getWorksheets().importSheet( rStrm ); break;
+ case OOBIN_ID_WORKBOOKVIEW: getViewSettings().importWorkbookView( rStrm ); break;
+ case OOBIN_ID_EXTERNALREF: importExternalRef( rStrm ); break;
+ case OOBIN_ID_EXTERNALSELF: getExternalLinks().importExternalSelf( rStrm ); break;
+ case OOBIN_ID_EXTERNALSHEETS: getExternalLinks().importExternalSheets( rStrm ); break;
+ case OOBIN_ID_DEFINEDNAME: getDefinedNames().importDefinedName( rStrm ); break;
+ }
+}
+
+// oox.xls.OoxFragmentHandler interface ---------------------------------------
+
+void OoxWorkbookFragment::finalizeImport()
+{
+ ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
+
+ // read the theme substream
+ OUString aThemeFragmentPath = getFragmentPathFromType( CREATE_RELATIONS_TYPE( "theme" ) );
+ if( aThemeFragmentPath.getLength() > 0 )
+ importOoxFragment( new ThemeFragmentHandler( getFilter(), aThemeFragmentPath, getTheme().getCoreTheme() ) );
+ xGlobalSegment->setPosition( 0.25 );
+
+ // read the styles substream (requires finalized theme buffer)
+ OUString aStylesFragmentPath = getFragmentPathFromType( CREATE_RELATIONS_TYPE( "styles" ) );
+ if( aStylesFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxStylesFragment( *this, aStylesFragmentPath ) );
+ xGlobalSegment->setPosition( 0.5 );
+
+ // read the shared string table substream (requires finalized styles buffer)
+ OUString aSstFragmentPath = getFragmentPathFromType( CREATE_RELATIONS_TYPE( "sharedStrings" ) );
+ if( aSstFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxSharedStringsFragment( *this, aSstFragmentPath ) );
+ xGlobalSegment->setPosition( 0.75 );
+
+ // read the connections substream
+ OUString aConnFragmentPath = getFragmentPathFromType( CREATE_RELATIONS_TYPE( "connections" ) );
+ if( aConnFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxConnectionsFragment( *this, aConnFragmentPath ) );
+ xGlobalSegment->setPosition( 1.0 );
+
+ /* Create fragments for all sheets, before importing them. Needed to do
+ 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;
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ sal_Int32 nSheetCount = rWorksheets.getInternalSheetCount();
+ for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet )
+ {
+ if( const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getSheetRelId( nSheet ) ) )
+ {
+ // get fragment path of the sheet
+ OUString aFragmentPath = getFragmentPathFromTarget( pRelation->maTarget );
+ OSL_ENSURE( aFragmentPath.getLength() > 0, "OoxWorkbookFragment::finalizeImport - cannot access sheet fragment" );
+ if( aFragmentPath.getLength() > 0 )
+ {
+ ::rtl::Reference< OoxWorksheetFragmentBase > xFragment;
+ double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet);
+ ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength );
+ // create the fragment according to the sheet type
+ if( pRelation->maType == CREATE_RELATIONS_TYPE( "worksheet" ) )
+ xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nSheet ) );
+ // 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() );
+ }
+ }
+ }
+
+ // create all defined names and database ranges
+ getDefinedNames().finalizeImport();
+ getTables().finalizeImport();
+
+ // load all worksheets
+ for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet )
+ {
+ SheetFragmentMap::iterator aIt = aSheetFragments.find( nSheet );
+ if( aIt != aSheetFragments.end() )
+ {
+ // import the sheet fragment
+ importOoxFragment( aIt->second );
+ // delete fragment object, will free all allocated sheet buffers
+ aSheetFragments.erase( aIt );
+ }
+ }
+
+ // final conversions, e.g. calculation settings and view settings
+ finalizeWorkbookImport();
+
+ getPivotTables().finalizeImport();
+}
+
+// private --------------------------------------------------------------------
+
+void OoxWorkbookFragment::importExternalReference( const AttributeList& rAttribs )
+{
+ if( ExternalLink* pExtLink = getExternalLinks().importExternalReference( rAttribs ).get() )
+ importExternalLinkFragment( *pExtLink );
+}
+
+void OoxWorkbookFragment::importDefinedName( const AttributeList& rAttribs )
+{
+ mxCurrName = getDefinedNames().importDefinedName( rAttribs );
+}
+
+void OoxWorkbookFragment::importPivotCache( const AttributeList& rAttribs )
+{
+ OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ) ) );
+ if( (aFragmentPath.getLength() > 0) && rAttribs.hasAttribute( XML_cacheId ) )
+ {
+ sal_uInt32 nCacheId = rAttribs.getUnsignedInteger( XML_cacheId, 0 );
+ importOoxFragment( new OoxPivotCacheFragment( *this, aFragmentPath, nCacheId ) );
+ }
+}
+
+void OoxWorkbookFragment::importExternalRef( RecordInputStream& rStrm )
+{
+ if( ExternalLink* pExtLink = getExternalLinks().importExternalRef( rStrm ).get() )
+ importExternalLinkFragment( *pExtLink );
+}
+
+void OoxWorkbookFragment::importExternalLinkFragment( ExternalLink& rExtLink )
+{
+ OUString aFragmentPath = getFragmentPathFromRelId( rExtLink.getRelId() );
+ if( aFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxExternalLinkFragment( *this, aFragmentPath, rExtLink ) );
+}
+
+// ============================================================================
+
+namespace {
+
+BiffDecoderRef lclImportFilePass_XOR( const WorkbookHelper& rHelper, BiffInputStream& rStrm )
+{
+ BiffDecoderRef xDecoder;
+ OSL_ENSURE( rStrm.getRecLeft() == 4, "lclImportFilePass_XOR - wrong record size" );
+ if( rStrm.getRecLeft() == 4 )
+ {
+ sal_uInt16 nBaseKey, nHash;
+ rStrm >> nBaseKey >> nHash;
+ xDecoder.reset( new BiffDecoder_XOR( rHelper, nBaseKey, nHash ) );
+ }
+ return xDecoder;
+}
+
+BiffDecoderRef lclImportFilePass_RCF( const WorkbookHelper& rHelper, BiffInputStream& rStrm )
+{
+ BiffDecoderRef xDecoder;
+ OSL_ENSURE( rStrm.getRecLeft() == 48, "lclImportFilePass_RCF - wrong record size" );
+ if( rStrm.getRecLeft() == 48 )
+ {
+ sal_uInt8 pnDocId[ 16 ];
+ sal_uInt8 pnSaltData[ 16 ];
+ sal_uInt8 pnSaltHash[ 16 ];
+ rStrm.read( pnDocId, 16 );
+ rStrm.read( pnSaltData, 16 );
+ rStrm.read( pnSaltHash, 16 );
+ xDecoder.reset( new BiffDecoder_RCF( rHelper, pnDocId, pnSaltData, pnSaltHash ) );
+ }
+ return xDecoder;
+}
+
+BiffDecoderRef lclImportFilePass_Strong( const WorkbookHelper& /*rHelper*/, BiffInputStream& /*rStrm*/ )
+{
+ // not supported
+ return BiffDecoderRef();
+}
+
+BiffDecoderRef lclImportFilePass2( const WorkbookHelper& rHelper, BiffInputStream& rStrm )
+{
+ return lclImportFilePass_XOR( rHelper, rStrm );
+}
+
+BiffDecoderRef lclImportFilePass8( const WorkbookHelper& rHelper, BiffInputStream& rStrm )
+{
+ BiffDecoderRef xDecoder;
+
+ switch( rStrm.readuInt16() )
+ {
+ case BIFF_FILEPASS_BIFF2:
+ xDecoder = lclImportFilePass_XOR( rHelper, rStrm );
+ break;
+
+ case BIFF_FILEPASS_BIFF8:
+ switch( rStrm.skip( 2 ).readuInt16() )
+ {
+ case BIFF_FILEPASS_BIFF8_RCF:
+ xDecoder = lclImportFilePass_RCF( rHelper, rStrm );
+ break;
+ case BIFF_FILEPASS_BIFF8_STRONG:
+ xDecoder = lclImportFilePass_Strong( rHelper, rStrm );
+ break;
+ default:
+ OSL_ENSURE( false, "lclImportFilePass8 - unknown BIFF8 encryption sub mode" );
+ }
+ break;
+
+ default:
+ OSL_ENSURE( false, "lclImportFilePass8 - unknown encryption mode" );
+ }
+
+ return xDecoder;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+BiffWorkbookFragment::BiffWorkbookFragment( const WorkbookHelper& rHelper ) :
+ BiffWorkbookFragmentBase( rHelper )
+{
+}
+
+bool BiffWorkbookFragment::importFragment( BiffInputStream& rStrm )
+{
+ bool bRet = false;
+
+ BiffFragmentType eFragment = startFragment( rStrm, getBiff() );
+ switch( eFragment )
+ {
+ case BIFF_FRAGMENT_GLOBALS:
+ {
+ // import workbook globals fragment and create sheets in document
+ ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
+ bRet = importGlobalsFragment( rStrm, *xGlobalsProgress );
+ // 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.getInternalSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet )
+ {
+ // try to start a new sheet fragment
+ double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet);
+ ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
+ BiffFragmentType eSheetFragment = startFragment( rStrm, getBiff() );
+ bNextSheet = importSheetFragment( rStrm, *xSheetProgress, eSheetFragment, nSheet );
+ }
+ }
+ break;
+
+ case BIFF_FRAGMENT_WORKSPACE:
+ {
+ bRet = importWorkspaceFragment( rStrm );
+ // sheets are embedded in workspace fragment, nothing to do here
+ }
+ break;
+
+ case BIFF_FRAGMENT_WORKSHEET:
+ case BIFF_FRAGMENT_CHART:
+ case BIFF_FRAGMENT_MACRO:
+ {
+ /* Single sheet without globals
+ - #i62752# possible in all BIFF versions
+ - do not return false in bRet on missing/broken sheets. */
+ getWorksheets().initializeSingleSheet();
+ importSheetFragment( rStrm, getProgressBar(), eFragment, 0 );
+ // success, even if stream is broken
+ bRet = true;
+ }
+ break;
+
+ default:;
+ }
+
+ // final conversions, e.g. calculation settings and view settings
+ finalizeWorkbookImport();
+
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importWorkspaceFragment( BiffInputStream& rStrm )
+{
+ // enable workbook mode, has not been set yet in BIFF4 workspace files
+ setIsWorkbookFile();
+
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ bool bRet = true;
+
+ // import the workspace globals
+ ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
+ bool bLoop = true;
+ while( bRet && bLoop && rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ {
+ switch( rStrm.getRecId() )
+ {
+ case BIFF_ID_SHEET: rWorksheets.importSheet( rStrm ); break;
+ case BIFF_ID_CODEPAGE: setCodePage( rStrm.readuInt16() ); break;
+ case BIFF_ID_FILEPASS: bRet = importFilePass( rStrm ); break;
+ case BIFF_ID_SHEETHEADER: rStrm.rewindRecord(); bLoop = false; break;
+ }
+ }
+ xGlobalsProgress->setPosition( 1.0 );
+
+ // load sheet fragments (do not return false in bRet on missing/broken sheets)
+ bool bNextSheet = bRet;
+ for( sal_Int32 nSheet = 0, nSheetCount = rWorksheets.getInternalSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet )
+ {
+ // try to start a new sheet fragment (with leading SHEETHEADER record)
+ bNextSheet = rStrm.startNextRecord() && (rStrm.getRecId() == BIFF_ID_SHEETHEADER);
+ if( bNextSheet )
+ {
+ double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet);
+ ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
+ /* Read current sheet name (sheet substreams may not be in the
+ same order as SHEET records are). */
+ OUString aSheetName = rStrm.skip( 4 ).readByteString( false, getTextEncoding() );
+ sal_Int32 nCurrSheet = rWorksheets.getFinalSheetIndex( aSheetName );
+ // load the sheet fragment records
+ BiffFragmentType eSheetFragment = startFragment( rStrm, getBiff() );
+ bNextSheet = importSheetFragment( rStrm, *xSheetProgress, eSheetFragment, nCurrSheet );
+ // do not return false in bRet on missing/broken sheets
+ }
+ }
+
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importGlobalsFragment( BiffInputStream& rStrm, ISegmentProgressBar& rProgressBar )
+{
+ WorkbookSettings& rWorkbookSett = getWorkbookSettings();
+ ViewSettings& rViewSett = getViewSettings();
+ SharedStringsBuffer& rSharedStrings = getSharedStrings();
+ StylesBuffer& rStyles = getStyles();
+ WorksheetBuffer& rWorksheets = getWorksheets();
+
+ // collect records that need to be loaded in a second pass
+ typedef ::std::vector< sal_Int64 > RecordHandleVec;
+ RecordHandleVec aExtLinkRecs;
+
+ bool bRet = true;
+ bool bLoop = true;
+ while( bRet && bLoop && rStrm.startNextRecord() )
+ {
+ sal_uInt16 nRecId = rStrm.getRecId();
+ bool bExtLinkRec = false;
+
+ /* #i56376# BIFF5-BIFF8: If an EOF record for globals is missing,
+ simulate it. The issue is about a document where the sheet fragment
+ starts directly after the EXTSST record, without terminating the
+ globals fragment with an EOF record. */
+ if( isBofRecord( nRecId ) || (nRecId == BIFF_ID_EOF) )
+ {
+ bLoop = false;
+ }
+ else switch( nRecId )
+ {
+ // records in all BIFF versions
+ case BIFF_ID_CODEPAGE: setCodePage( rStrm.readuInt16() ); break;
+ case BIFF_ID_DATEMODE: rWorkbookSett.importDateMode( rStrm ); break;
+ case BIFF_ID_FILEPASS: bRet = importFilePass( rStrm ); break;
+ case BIFF_ID_PRECISION: rWorkbookSett.importPrecision( rStrm ); break;
+ case BIFF_ID_WINDOW1: rViewSett.importWindow1( rStrm ); break;
+
+ // BIFF specific records
+ default: switch( getBiff() )
+ {
+ case BIFF2: switch( nRecId )
+ {
+ case BIFF2_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF2_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF2_ID_FONT: rStyles.importFont( rStrm ); break;
+ case BIFF_ID_FONTCOLOR: rStyles.importFontColor( rStrm ); break;
+ case BIFF2_ID_FORMAT: rStyles.importFormat( rStrm ); break;
+ case BIFF2_ID_XF: rStyles.importXf( rStrm ); break;
+ }
+ break;
+
+ case BIFF3: switch( nRecId )
+ {
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF3_ID_FONT: rStyles.importFont( rStrm ); break;
+ case BIFF2_ID_FORMAT: rStyles.importFormat( rStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF3_ID_XF: rStyles.importXf( rStrm ); break;
+ }
+ break;
+
+ case BIFF4: switch( nRecId )
+ {
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF3_ID_FONT: rStyles.importFont( rStrm ); break;
+ case BIFF4_ID_FORMAT: rStyles.importFormat( rStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF4_ID_XF: rStyles.importXf( rStrm ); break;
+ }
+ break;
+
+ case BIFF5: switch( nRecId )
+ {
+ case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( rStrm ); break;
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF5_ID_FONT: rStyles.importFont( rStrm ); break;
+ case BIFF4_ID_FORMAT: rStyles.importFormat( rStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break;
+ case BIFF_ID_SHEET: rWorksheets.importSheet( rStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF5_ID_XF: rStyles.importXf( rStrm ); break;
+ }
+ break;
+
+ case BIFF8: switch( nRecId )
+ {
+ case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( rStrm ); break;
+ case BIFF_ID_CODENAME: rWorkbookSett.importCodeName( rStrm ); break;
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNALBOOK: bExtLinkRec = true; break;
+ case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF5_ID_FONT: rStyles.importFont( rStrm ); break;
+ case BIFF4_ID_FORMAT: rStyles.importFormat( rStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break;
+ case BIFF_ID_SHEET: rWorksheets.importSheet( rStrm ); break;
+ case BIFF_ID_SST: rSharedStrings.importSst( rStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break;
+ case BIFF_ID_USESELFS: rWorkbookSett.importUsesElfs( rStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF5_ID_XF: rStyles.importXf( rStrm ); break;
+ }
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+ }
+
+ if( bExtLinkRec )
+ aExtLinkRecs.push_back( rStrm.getRecHandle() );
+ }
+
+ // finalize global buffers
+ rProgressBar.setPosition( 0.5 );
+ rSharedStrings.finalizeImport();
+ rStyles.finalizeImport();
+
+ /* Import external link data (EXTERNSHEET, EXTERNALNAME, DEFINEDNAME)
+ which need existing internal sheets (SHEET records). The SHEET records
+ may follow the external links records in some BIFF versions. */
+ if( bRet && !aExtLinkRecs.empty() )
+ {
+ // remember current stream position (the EOF record)
+ sal_Int64 nEofHandle = rStrm.getRecHandle();
+ // this fragment class implements import of external link records
+ BiffExternalLinkFragment aLinkFragment( *this, true );
+ // import all records by using their cached record handle
+ for( RecordHandleVec::const_iterator aIt = aExtLinkRecs.begin(), aEnd = aExtLinkRecs.end(); (aIt != aEnd) && rStrm.startRecordByHandle( *aIt ); ++aIt )
+ aLinkFragment.importRecord( rStrm );
+ // finalize global buffers
+ aLinkFragment.finalizeImport();
+ // seek back to the EOF record of the workbook globals fragment
+ bRet = rStrm.startRecordByHandle( nEofHandle );
+ }
+
+ // #i56376# missing EOF - rewind before worksheet BOF record (see above)
+ if( bRet && isBofRecord( rStrm.getRecId() ) )
+ rStrm.rewindRecord();
+
+ rProgressBar.setPosition( 1.0 );
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importSheetFragment( BiffInputStream& rStrm, ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int32 nSheet )
+{
+ // find the sheet type for this fragment
+ WorksheetType eSheetType = SHEETTYPE_WORKSHEET;
+ bool bSkipSheet = false;
+ switch( eFragment )
+ {
+ case BIFF_FRAGMENT_WORKSHEET: eSheetType = SHEETTYPE_WORKSHEET; break;
+ case BIFF_FRAGMENT_CHART: eSheetType = SHEETTYPE_CHART; break;
+ case BIFF_FRAGMENT_MACRO: eSheetType = SHEETTYPE_MACRO; break;
+ case BIFF_FRAGMENT_EMPTYSHEET: bSkipSheet = true; break;
+ default: return false;
+ }
+
+ // skip this worksheet fragment (e.g. fragment type is BIFF_FRAGMENT_EMPTYSHEET)
+ if( bSkipSheet )
+ {
+ rProgressBar.setPosition( 1.0 );
+ return skipFragment( rStrm );
+ }
+
+ /* #i11183# Clear buffers that are used per-sheet, e.g. external links in
+ BIFF4W and BIFF5 files, or defined names in BIFF4W files. */
+ createBuffersPerSheet();
+
+ // preprocess some records
+ switch( getBiff() )
+ {
+ // load the workbook globals fragment records in BIFF2-BIFF4
+ case BIFF2:
+ 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 = rStrm.getRecHandle();
+ // import the global records
+ ISegmentProgressBarRef xGlobalsProgress = rProgressBar.createSegment( PROGRESS_LENGTH_GLOBALS );
+ importGlobalsFragment( rStrm, *xGlobalsProgress );
+ // rewind stream to fragment BOF record
+ rStrm.startRecordByHandle( nRecHandle );
+ }
+ break;
+
+ // load the external link records for this sheet in BIFF5
+ case BIFF5:
+ {
+ // remember current record to seek back below
+ sal_Int64 nRecHandle = rStrm.getRecHandle();
+ // fragment implementing import of external link records
+ BiffExternalLinkFragment( *this, false ).importFragment( rStrm );
+ // rewind stream to fragment BOF record
+ rStrm.startRecordByHandle( nRecHandle );
+ }
+ break;
+
+ case BIFF8:
+ break;
+
+ case BIFF_UNKNOWN:
+ break;
+ }
+
+ // create the worksheet fragment
+ ISegmentProgressBarRef xSheetProgress = rProgressBar.createSegment( rProgressBar.getFreeLength() );
+ ::boost::shared_ptr< BiffWorksheetFragmentBase > xFragment;
+ switch( eSheetType )
+ {
+ case SHEETTYPE_WORKSHEET:
+ case SHEETTYPE_MACRO:
+ xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nSheet ) );
+ break;
+ case SHEETTYPE_CHART:
+ xFragment.reset( new BiffWorksheetFragmentBase( *this, xSheetProgress, eSheetType, nSheet ) );
+ break;
+ }
+ // load the sheet fragment records
+ return xFragment->isValidSheet() && xFragment->importFragment( rStrm );
+}
+
+bool BiffWorkbookFragment::importFilePass( BiffInputStream& rStrm )
+{
+ rStrm.enableDecoder( false );
+ BiffDecoderRef xDecoder = (getBiff() == BIFF8) ?
+ lclImportFilePass8( *this, rStrm ) : lclImportFilePass2( *this, rStrm );
+
+ // set decoder at import stream
+ rStrm.setDecoder( xDecoder );
+ //! TODO remember encryption state for export
+// rStrm.GetRoot().GetExtDocOptions().GetDocSettings().mbEncrypted = true;
+
+ return xDecoder.get() && xDecoder->isValid();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx
new file mode 100644
index 000000000000..72c599a75437
--- /dev/null
+++ b/oox/source/xls/workbookhelper.cxx
@@ -0,0 +1,876 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: workbookhelper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/workbookhelper.hxx"
+#include <osl/thread.h>
+#include <osl/time.h>
+#include <rtl/strbuf.hxx>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include "oox/helper/progressbar.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/binaryfilterbase.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/pivottablebuffer.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/stylespropertyhelper.hxx"
+#include "oox/xls/tablebuffer.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+#include "oox/xls/validationpropertyhelper.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/webquerybuffer.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+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 ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::container::XNameContainer;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::awt::XDevice;
+using ::com::sun::star::document::XActionLockable;
+using ::com::sun::star::sheet::XSpreadsheetDocument;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::sheet::XNamedRanges;
+using ::com::sun::star::sheet::XDatabaseRanges;
+using ::com::sun::star::style::XStyle;
+using ::com::sun::star::style::XStyleFamiliesSupplier;
+using ::oox::core::BinaryFilterBase;
+using ::oox::core::FilterBase;
+using ::oox::core::FragmentHandler;
+using ::oox::core::XmlFilterBase;
+
+// Set this define to 1 to show the load/save time of a document in an assertion.
+#define OOX_SHOW_LOADSAVE_TIME 0
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+#if OSL_DEBUG_LEVEL > 0
+
+struct WorkbookDataDebug
+{
+#if OOX_SHOW_LOADSAVE_TIME
+ TimeValue maStartTime;
+#endif
+ sal_Int32 mnDebugCount;
+
+ explicit WorkbookDataDebug();
+ ~WorkbookDataDebug();
+};
+
+WorkbookDataDebug::WorkbookDataDebug() :
+ mnDebugCount( 0 )
+{
+#if OOX_SHOW_LOADSAVE_TIME
+ osl_getSystemTime( &maStartTime );
+#endif
+}
+
+WorkbookDataDebug::~WorkbookDataDebug()
+{
+#if OOX_SHOW_LOADSAVE_TIME
+ TimeValue aEndTime;
+ osl_getSystemTime( &aEndTime );
+ sal_Int32 nMillis = (aEndTime.Seconds - maStartTime.Seconds) * 1000 + static_cast< sal_Int32 >( aEndTime.Nanosec - maStartTime.Nanosec ) / 1000000;
+ OSL_ENSURE( false, OStringBuffer( "load/save time = " ).append( nMillis / 1000.0 ).append( " seconds" ).getStr() );
+#endif
+ OSL_ENSURE( mnDebugCount == 0, "WorkbookDataDebug::~WorkbookDataDebug - failed to delete some objects" );
+}
+
+#endif
+
+// ============================================================================
+
+class WorkbookData
+#if OSL_DEBUG_LEVEL > 0
+ : public WorkbookDataDebug
+#endif
+{
+public:
+ explicit WorkbookData( XmlFilterBase& rFilter );
+ explicit WorkbookData( BinaryFilterBase& rFilter, BiffType eBiff );
+ ~WorkbookData();
+
+ /** Returns true, if this helper refers to a valid document. */
+ inline bool isValid() const { return mxDoc.is(); }
+
+ // filter -----------------------------------------------------------------
+
+ /** Returns the base filter object (base class of all filters). */
+ inline FilterBase& getBaseFilter() const { return mrBaseFilter; }
+ /** Returns the filter progress bar. */
+ inline SegmentProgressBar& getProgressBar() const { return *mxProgressBar; }
+ /** Returns the file type of the current filter. */
+ inline FilterType getFilterType() const { return meFilterType; }
+ /** Returns true, if the file is a multi-sheet document, or false if single-sheet. */
+ inline bool isWorkbookFile() const { return mbWorkbook; }
+
+ // document model ---------------------------------------------------------
+
+ /** Returns a reference to the source/target spreadsheet document model. */
+ inline Reference< XSpreadsheetDocument > getDocument() const { return mxDoc; }
+ /** Returns a reference to the specified spreadsheet in the document model. */
+ Reference< XSpreadsheet > getSheet( sal_Int32 nSheet ) const;
+ /** Returns the reference device of the document. */
+ Reference< XDevice > getReferenceDevice() const;
+ /** Returns the container for defined names from the Calc document. */
+ Reference< XNamedRanges > getNamedRanges() const;
+ /** Returns the container for database ranges from the Calc document. */
+ Reference< XDatabaseRanges > getDatabaseRanges() const;
+ /** Returns the container for DDE links from the Calc document. */
+ Reference< XNameAccess > getDdeLinks() const;
+ /** Returns the cell or page styles container from the Calc document. */
+ Reference< XNameContainer > getStyleFamily( bool bPageStyles ) const;
+ /** Returns the specified cell or page style from the Calc document. */
+ Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const;
+ /** Creates a com.sun.star.style.Style object and returns its final name. */
+ Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting );
+
+ // buffers ----------------------------------------------------------------
+
+ /** Returns the global workbook settings object. */
+ inline WorkbookSettings& getWorkbookSettings() const { return *mxWorkbookSettings; }
+ /** Returns the workbook and sheet view settings object. */
+ inline ViewSettings& getViewSettings() const { return *mxViewSettings; }
+ /** Returns the worksheet buffer containing sheet names and properties. */
+ inline WorksheetBuffer& getWorksheets() const { return *mxWorksheets; }
+ /** Returns the office theme object read from the theme substorage. */
+ inline ThemeBuffer& getTheme() const { return *mxTheme; }
+ /** Returns all cell formatting objects read from the styles substream. */
+ inline StylesBuffer& getStyles() const { return *mxStyles; }
+ /** Returns the shared strings read from the shared strings substream. */
+ inline SharedStringsBuffer& getSharedStrings() const { return *mxSharedStrings; }
+ /** Returns the external links read from the external links substream. */
+ inline ExternalLinkBuffer& getExternalLinks() const { return *mxExtLinks; }
+ /** Returns the defined names read from the workbook globals. */
+ inline DefinedNamesBuffer& getDefinedNames() const { return *mxDefNames; }
+ /** Returns the tables collection (equivalent to Calc's database ranges). */
+ inline TableBuffer& getTables() const { return *mxTables; }
+ /** Returns the web queries. */
+ inline WebQueryBuffer& getWebQueries() const { return *mxWebQueries; }
+ /** Returns the pivot tables. */
+ inline PivotTableBuffer& getPivotTables() const { return *mxPivotTables; }
+
+ // converters -------------------------------------------------------------
+
+ /** Returns the import formula parser. */
+ inline FormulaParser& getFormulaParser() const { return *mxFmlaParser; }
+ /** Returns the measurement unit converter. */
+ inline UnitConverter& getUnitConverter() const { return *mxUnitConverter; }
+ /** Returns the converter for string to cell address/range conversion. */
+ inline AddressConverter& getAddressConverter() const { return *mxAddrConverter; }
+ /** Returns the converter for properties related to cell styles. */
+ inline StylesPropertyHelper& getStylesPropertyHelper() const { return *mxStylesPropHlp; }
+ /** Returns the converter for properties related to page/print settings. */
+ inline PageSettingsPropertyHelper& getPageSettingsPropertyHelper() const { return *mxPageSettPropHlp; }
+ /** Returns the converter for properties related to data validation. */
+ inline ValidationPropertyHelper& getValidationPropertyHelper() const { return *mxValidationPropHlp; }
+
+ // OOX specific -----------------------------------------------------------
+
+ /** Returns the base OOX filter object. */
+ inline XmlFilterBase& getOoxFilter() const { return *mpOoxFilter; }
+
+ // BIFF specific ----------------------------------------------------------
+
+ /** Returns the base BIFF filter object. */
+ inline BinaryFilterBase& getBiffFilter() const { return *mpBiffFilter; }
+ /** Returns the BIFF type in binary filter. */
+ inline BiffType getBiff() const { return meBiff; }
+ /** Returns the text encoding used to import/export byte strings. */
+ inline rtl_TextEncoding getTextEncoding() const { return meTextEnc; }
+ /** Sets the text encoding to import/export byte strings. */
+ void setTextEncoding( rtl_TextEncoding eTextEnc );
+ /** Sets code page read from a CODEPAGE record for byte string import. */
+ void setCodePage( sal_uInt16 nCodePage );
+ /** Sets text encoding from the default application font, if CODEPAGE record is missing. */
+ void setAppFontEncoding( rtl_TextEncoding eAppFontEnc );
+ /** 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();
+ /** Looks for a password provided via API, or queries it via GUI. */
+ OUString queryPassword();
+
+private:
+ /** Initializes some basic members and sets needed document properties. */
+ void initialize();
+ /** Finalizes the filter process (sets some needed document properties). */
+ void finalize();
+
+private:
+ typedef ::std::auto_ptr< SegmentProgressBar > ProgressBarPtr;
+ typedef ::std::auto_ptr< WorkbookSettings > WorkbookSettPtr;
+ typedef ::std::auto_ptr< ViewSettings > ViewSettingsPtr;
+ typedef ::std::auto_ptr< WorksheetBuffer > WorksheetBfrPtr;
+ typedef ::std::auto_ptr< ThemeBuffer > ThemeBfrPtr;
+ typedef ::std::auto_ptr< StylesBuffer > StylesBfrPtr;
+ typedef ::std::auto_ptr< SharedStringsBuffer > SharedStrBfrPtr;
+ typedef ::std::auto_ptr< ExternalLinkBuffer > ExtLinkBfrPtr;
+ typedef ::std::auto_ptr< DefinedNamesBuffer > DefNamesBfrPtr;
+ typedef ::std::auto_ptr< TableBuffer > TableBfrPtr;
+ typedef ::std::auto_ptr< WebQueryBuffer > WebQueryBfrPtr;
+ typedef ::std::auto_ptr< PivotTableBuffer > PivotTableBfrPtr;
+ typedef ::std::auto_ptr< UnitConverter > UnitConvPtr;
+ typedef ::std::auto_ptr< AddressConverter > AddressConvPtr;
+ typedef ::std::auto_ptr< StylesPropertyHelper > StylesPropHlpPtr;
+ typedef ::std::auto_ptr< PageSettingsPropertyHelper > PageSettPropHlpPtr;
+ typedef ::std::auto_ptr< ValidationPropertyHelper > ValidationPropHlpPtr;
+ typedef ::std::auto_ptr< FormulaParser > FormulaParserPtr;
+
+ OUString maRefDeviceProp; /// Property name for reference device.
+ OUString maNamedRangesProp; /// Property name for defined names.
+ OUString maDatabaseRangesProp; /// Property name for database ranges.
+ OUString maDdeLinksProp; /// Property name for DDE links.
+ OUString maCellStylesProp; /// Property name for cell styles.
+ OUString maPageStylesProp; /// Property name for page styles.
+ OUString maCellStyleServ; /// Service name for a cell style.
+ OUString maPageStyleServ; /// Service name for a page style.
+ Reference< XSpreadsheetDocument > mxDoc; /// Document model.
+ FilterBase& mrBaseFilter; /// Base filter object.
+ FilterType meFilterType; /// File type of the filter.
+ ProgressBarPtr mxProgressBar; /// The progress bar.
+ bool mbWorkbook; /// True = multi-sheet file.
+
+ // buffers
+ WorkbookSettPtr mxWorkbookSettings; /// Global workbook settings.
+ ViewSettingsPtr mxViewSettings; /// Workbook and sheet view settings.
+ WorksheetBfrPtr mxWorksheets; /// Sheet info buffer.
+ ThemeBfrPtr mxTheme; /// Formatting theme from theme substream.
+ StylesBfrPtr mxStyles; /// All cell style objects from styles substream.
+ SharedStrBfrPtr mxSharedStrings; /// All strings from shared strings substream.
+ ExtLinkBfrPtr mxExtLinks; /// All external links.
+ DefNamesBfrPtr mxDefNames; /// All defined names.
+ TableBfrPtr mxTables; /// All tables (database ranges).
+ WebQueryBfrPtr mxWebQueries; /// Web queries buffer.
+ PivotTableBfrPtr mxPivotTables; /// Pivot tables buffer.
+
+ // converters/helpers
+ FormulaParserPtr mxFmlaParser; /// Import formula parser.
+ UnitConvPtr mxUnitConverter; /// General unit converter.
+ AddressConvPtr mxAddrConverter; /// Cell address and cell range address converter.
+ StylesPropHlpPtr mxStylesPropHlp; /// Helper for all styles properties.
+ PageSettPropHlpPtr mxPageSettPropHlp; /// Helper for page/print properties.
+ ValidationPropHlpPtr mxValidationPropHlp; /// Helper for data validation properties.
+
+ // OOX specific
+ XmlFilterBase* mpOoxFilter; /// Base OOX filter object.
+
+ // BIFF specific
+ BinaryFilterBase* mpBiffFilter; /// Base BIFF filter object.
+ ::rtl::OUString maPassword; /// Password for stream encoder/decoder.
+ BiffType meBiff; /// BIFF version for BIFF import/export.
+ rtl_TextEncoding meTextEnc; /// BIFF byte string text encoding.
+ bool mbHasCodePage; /// True = CODEPAGE record exists in imported stream.
+ bool mbHasPassword; /// True = password already querried.
+};
+
+// ----------------------------------------------------------------------------
+
+WorkbookData::WorkbookData( XmlFilterBase& rFilter ) :
+ mrBaseFilter( rFilter ),
+ meFilterType( FILTER_OOX ),
+ mpOoxFilter( &rFilter ),
+ meBiff( BIFF_UNKNOWN )
+{
+ initialize();
+}
+
+WorkbookData::WorkbookData( BinaryFilterBase& rFilter, BiffType eBiff ) :
+ mrBaseFilter( rFilter ),
+ meFilterType( FILTER_BIFF ),
+ mpBiffFilter( &rFilter ),
+ meBiff( eBiff )
+{
+ initialize();
+}
+
+WorkbookData::~WorkbookData()
+{
+ finalize();
+}
+
+// document model -------------------------------------------------------------
+
+Reference< XDevice > WorkbookData::getReferenceDevice() const
+{
+ PropertySet aPropSet( mxDoc );
+ Reference< XDevice > xDevice;
+ aPropSet.getProperty( xDevice, maRefDeviceProp );
+ return xDevice;
+}
+
+Reference< XNamedRanges > WorkbookData::getNamedRanges() const
+{
+ PropertySet aPropSet( mxDoc );
+ Reference< XNamedRanges > xNamedRanges;
+ aPropSet.getProperty( xNamedRanges, maNamedRangesProp );
+ return xNamedRanges;
+}
+
+Reference< XDatabaseRanges > WorkbookData::getDatabaseRanges() const
+{
+ PropertySet aPropSet( mxDoc );
+ Reference< XDatabaseRanges > xDatabaseRanges;
+ aPropSet.getProperty( xDatabaseRanges, maDatabaseRangesProp );
+ return xDatabaseRanges;
+}
+
+Reference< XNameAccess > WorkbookData::getDdeLinks() const
+{
+ PropertySet aPropSet( mxDoc );
+ Reference< XNameAccess > xDdeLinks;
+ aPropSet.getProperty( xDdeLinks, maDdeLinksProp );
+ return xDdeLinks;
+}
+
+Reference< XNameContainer > WorkbookData::getStyleFamily( bool bPageStyles ) const
+{
+ Reference< XNameContainer > xStylesNC;
+ try
+ {
+ Reference< XStyleFamiliesSupplier > xFamiliesSup( mxDoc, UNO_QUERY_THROW );
+ Reference< XNameAccess > xFamiliesNA( xFamiliesSup->getStyleFamilies(), UNO_QUERY_THROW );
+ xStylesNC.set( xFamiliesNA->getByName( bPageStyles ? maPageStylesProp : maCellStylesProp ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xStylesNC.is(), "WorkbookData::getStyleFamily - cannot access style family" );
+ return xStylesNC;
+}
+
+Reference< XStyle > WorkbookData::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
+{
+ Reference< XStyle > xStyle;
+ Reference< XNameContainer > xStylesNC = getStyleFamily( bPageStyle );
+ if( xStylesNC.is() ) try
+ {
+ xStyle.set( xStylesNC->getByName( rStyleName ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xStyle.is(), "WorkbookData::getStyleObject - cannot access style object" );
+ return xStyle;
+}
+
+Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting )
+{
+ Reference< XStyle > xStyle;
+ Reference< XNameContainer > xStylesNC = getStyleFamily( bPageStyle );
+ if( xStylesNC.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory( mxDoc, UNO_QUERY_THROW );
+ xStyle.set( xFactory->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW );
+ orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, Any( xStyle ), orStyleName, ' ', bRenameOldExisting );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xStyle.is(), "WorkbookData::createStyleObject - cannot create style" );
+ return xStyle;
+}
+
+// BIFF specific --------------------------------------------------------------
+
+void WorkbookData::setTextEncoding( rtl_TextEncoding eTextEnc )
+{
+ if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ meTextEnc = eTextEnc;
+}
+
+void WorkbookData::setCodePage( sal_uInt16 nCodePage )
+{
+ setTextEncoding( BiffHelper::calcTextEncodingFromCodePage( nCodePage ) );
+ mbHasCodePage = true;
+}
+
+void WorkbookData::setAppFontEncoding( rtl_TextEncoding eAppFontEnc )
+{
+ if( !mbHasCodePage )
+ setTextEncoding( eAppFontEnc );
+}
+
+void WorkbookData::setIsWorkbookFile()
+{
+ OSL_ENSURE( meBiff == BIFF4, "WorkbookData::setIsWorkbookFile - invalid call" );
+ mbWorkbook = true;
+}
+
+void WorkbookData::createBuffersPerSheet()
+{
+ switch( meBiff )
+ {
+ case BIFF2:
+ case BIFF3:
+ break;
+
+ case BIFF4:
+ // #i11183# sheets in BIFF4W files have own styles or names
+ if( mbWorkbook )
+ {
+ mxStyles.reset( new StylesBuffer( WorkbookHelper( *this ) ) );
+ mxDefNames.reset( new DefinedNamesBuffer( WorkbookHelper( *this ) ) );
+ mxExtLinks.reset( new ExternalLinkBuffer( WorkbookHelper( *this ) ) );
+ }
+ break;
+
+ case BIFF5:
+ // BIFF5 stores external references per sheet
+ mxExtLinks.reset( new ExternalLinkBuffer( WorkbookHelper( *this ) ) );
+ break;
+
+ case BIFF8:
+ break;
+
+ case BIFF_UNKNOWN:
+ break;
+ }
+}
+
+OUString WorkbookData::queryPassword()
+{
+ if( !mbHasPassword )
+ {
+ //! TODO
+ maPassword = OUString();
+ // set to true, even if dialog has been cancelled (never ask twice)
+ mbHasPassword = true;
+ }
+ return maPassword;
+}
+
+// private --------------------------------------------------------------------
+
+void WorkbookData::initialize()
+{
+ maRefDeviceProp = CREATE_OUSTRING( "ReferenceDevice" );
+ maNamedRangesProp = CREATE_OUSTRING( "NamedRanges" );
+ maDatabaseRangesProp = CREATE_OUSTRING( "DatabaseRanges" );
+ maDdeLinksProp = CREATE_OUSTRING( "DDELinks" );
+ maCellStylesProp = CREATE_OUSTRING( "CellStyles" );
+ maPageStylesProp = CREATE_OUSTRING( "PageStyles" );
+ maCellStyleServ = CREATE_OUSTRING( "com.sun.star.style.CellStyle" );
+ maPageStyleServ = CREATE_OUSTRING( "com.sun.star.style.PageStyle" );
+ mbWorkbook = false;
+ meTextEnc = osl_getThreadTextEncoding();
+ mbHasCodePage = false;
+ mbHasPassword = false;
+
+ // the spreadsheet document
+ mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY );
+ OSL_ENSURE( mxDoc.is(), "WorkbookData::initialize - no spreadsheet document" );
+
+ mxWorkbookSettings.reset( new WorkbookSettings( WorkbookHelper( *this ) ) );
+ mxViewSettings.reset( new ViewSettings( WorkbookHelper( *this ) ) );
+ mxWorksheets.reset( new WorksheetBuffer( WorkbookHelper( *this ) ) );
+ mxTheme.reset( new ThemeBuffer( WorkbookHelper( *this ) ) );
+ mxStyles.reset( new StylesBuffer( WorkbookHelper( *this ) ) );
+ mxSharedStrings.reset( new SharedStringsBuffer( WorkbookHelper( *this ) ) );
+ mxExtLinks.reset( new ExternalLinkBuffer( WorkbookHelper( *this ) ) );
+ mxDefNames.reset( new DefinedNamesBuffer( WorkbookHelper( *this ) ) );
+ mxTables.reset( new TableBuffer( WorkbookHelper( *this ) ) );
+ mxWebQueries.reset( new WebQueryBuffer( WorkbookHelper( *this ) ) );
+ mxPivotTables.reset( new PivotTableBuffer( WorkbookHelper( *this ) ) );
+
+ mxUnitConverter.reset( new UnitConverter( WorkbookHelper( *this ) ) );
+ mxAddrConverter.reset( new AddressConverter( WorkbookHelper( *this ) ) );
+ mxStylesPropHlp.reset( new StylesPropertyHelper( WorkbookHelper( *this ) ) );
+ mxPageSettPropHlp.reset( new PageSettingsPropertyHelper( WorkbookHelper( *this ) ) );
+ mxValidationPropHlp.reset( new ValidationPropertyHelper( WorkbookHelper( *this ) ) );
+
+ // set some document properties needed during import
+ if( mrBaseFilter.isImportFilter() )
+ {
+ PropertySet aPropSet( mxDoc );
+ // enable editing read-only documents (e.g. from read-only files)
+ aPropSet.setProperty( CREATE_OUSTRING( "IsChangeReadOnlyEnabled" ), true );
+ // #i76026# disable Undo while loading the document
+ aPropSet.setProperty( CREATE_OUSTRING( "IsUndoEnabled" ), false );
+ // #i79826# disable calculating automatic row height while loading the document
+ aPropSet.setProperty( CREATE_OUSTRING( "IsAdjustHeightEnabled" ), false );
+ // disable automatic update of linked sheets and DDE links
+ aPropSet.setProperty( CREATE_OUSTRING( "IsExecuteLinkEnabled" ), false );
+ // #i79890# disable automatic update of defined names
+ Reference< XActionLockable > xLockable( getNamedRanges(), UNO_QUERY );
+ if( xLockable.is() )
+ xLockable->addActionLock();
+
+ //! TODO: localize progress bar text
+ mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Loading..." ) ) );
+ mxFmlaParser.reset( new FormulaParser( WorkbookHelper( *this ) ) );
+ }
+ else if( mrBaseFilter.isExportFilter() )
+ {
+ //! TODO: localize progress bar text
+ mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Saving..." ) ) );
+ }
+}
+
+void WorkbookData::finalize()
+{
+ // set some document properties needed after import
+ if( mrBaseFilter.isImportFilter() )
+ {
+ PropertySet aPropSet( mxDoc );
+ // #i74668# do not insert default sheets
+ aPropSet.setProperty( CREATE_OUSTRING( "IsLoaded" ), true );
+ // #i79890# enable automatic update of defined names (before IsAdjustHeightEnabled!)
+ Reference< XActionLockable > xLockable( getNamedRanges(), UNO_QUERY );
+ if( xLockable.is() )
+ xLockable->removeActionLock();
+ // enable automatic update of linked sheets and DDE links
+ aPropSet.setProperty( CREATE_OUSTRING( "IsExecuteLinkEnabled" ), true );
+ // #i79826# enable updating automatic row height after loading the document
+ aPropSet.setProperty( CREATE_OUSTRING( "IsAdjustHeightEnabled" ), true );
+ // #i76026# enable Undo after loading the document
+ aPropSet.setProperty( CREATE_OUSTRING( "IsUndoEnabled" ), true );
+ // disable editing read-only documents (e.g. from read-only files)
+ aPropSet.setProperty( CREATE_OUSTRING( "IsChangeReadOnlyEnabled" ), false );
+ }
+}
+
+// ============================================================================
+
+WorkbookHelper::WorkbookHelper( WorkbookData& rBookData ) :
+#if OSL_DEBUG_LEVEL > 0
+ WorkbookHelperDebug( rBookData.mnDebugCount ),
+#endif
+ mrBookData( rBookData )
+{
+}
+
+WorkbookHelper::~WorkbookHelper()
+{
+}
+
+// filter ---------------------------------------------------------------------
+
+FilterBase& WorkbookHelper::getBaseFilter() const
+{
+ return mrBookData.getBaseFilter();
+}
+
+FilterType WorkbookHelper::getFilterType() const
+{
+ return mrBookData.getFilterType();
+}
+
+SegmentProgressBar& WorkbookHelper::getProgressBar() const
+{
+ return mrBookData.getProgressBar();
+}
+
+bool WorkbookHelper::isWorkbookFile() const
+{
+ return mrBookData.isWorkbookFile();
+}
+
+void WorkbookHelper::finalizeWorkbookImport()
+{
+ // workbook settings, document and sheet view settings
+ mrBookData.getWorkbookSettings().finalizeImport();
+ mrBookData.getViewSettings().finalizeImport();
+}
+
+// document model -------------------------------------------------------------
+
+Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const
+{
+ return mrBookData.getDocument();
+}
+
+Reference< XSpreadsheet > WorkbookHelper::getSheet( sal_Int32 nSheet ) const
+{
+ Reference< XSpreadsheet > xSheet;
+ try
+ {
+ Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
+ xSheet.set( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ return xSheet;
+}
+
+Reference< XDevice > WorkbookHelper::getReferenceDevice() const
+{
+ return mrBookData.getReferenceDevice();
+}
+
+Reference< XNamedRanges > WorkbookHelper::getNamedRanges() const
+{
+ return mrBookData.getNamedRanges();
+}
+
+Reference< XDatabaseRanges > WorkbookHelper::getDatabaseRanges() const
+{
+ return mrBookData.getDatabaseRanges();
+}
+
+Reference< XNameAccess > WorkbookHelper::getDdeLinks() const
+{
+ return mrBookData.getDdeLinks();
+}
+
+Reference< XNameContainer > WorkbookHelper::getStyleFamily( bool bPageStyles ) const
+{
+ return mrBookData.getStyleFamily( bPageStyles );
+}
+
+Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
+{
+ return mrBookData.getStyleObject( rStyleName, bPageStyle );
+}
+
+Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle, bool bRenameOldExisting )
+{
+ return mrBookData.createStyleObject( orStyleName, bPageStyle, bRenameOldExisting );
+}
+
+// buffers --------------------------------------------------------------------
+
+WorkbookSettings& WorkbookHelper::getWorkbookSettings() const
+{
+ return mrBookData.getWorkbookSettings();
+}
+
+ViewSettings& WorkbookHelper::getViewSettings() const
+{
+ return mrBookData.getViewSettings();
+}
+
+WorksheetBuffer& WorkbookHelper::getWorksheets() const
+{
+ return mrBookData.getWorksheets();
+}
+
+ThemeBuffer& WorkbookHelper::getTheme() const
+{
+ return mrBookData.getTheme();
+}
+
+StylesBuffer& WorkbookHelper::getStyles() const
+{
+ return mrBookData.getStyles();
+}
+
+SharedStringsBuffer& WorkbookHelper::getSharedStrings() const
+{
+ return mrBookData.getSharedStrings();
+}
+
+ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const
+{
+ return mrBookData.getExternalLinks();
+}
+
+DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const
+{
+ return mrBookData.getDefinedNames();
+}
+
+TableBuffer& WorkbookHelper::getTables() const
+{
+ return mrBookData.getTables();
+}
+
+WebQueryBuffer& WorkbookHelper::getWebQueries() const
+{
+ return mrBookData.getWebQueries();
+}
+
+PivotTableBuffer& WorkbookHelper::getPivotTables() const
+{
+ return mrBookData.getPivotTables();
+}
+
+// converters -----------------------------------------------------------------
+
+FormulaParser& WorkbookHelper::getFormulaParser() const
+{
+ return mrBookData.getFormulaParser();
+}
+
+UnitConverter& WorkbookHelper::getUnitConverter() const
+{
+ return mrBookData.getUnitConverter();
+}
+
+AddressConverter& WorkbookHelper::getAddressConverter() const
+{
+ return mrBookData.getAddressConverter();
+}
+
+StylesPropertyHelper& WorkbookHelper::getStylesPropertyHelper() const
+{
+ return mrBookData.getStylesPropertyHelper();
+}
+
+PageSettingsPropertyHelper& WorkbookHelper::getPageSettingsPropertyHelper() const
+{
+ return mrBookData.getPageSettingsPropertyHelper();
+}
+
+ValidationPropertyHelper& WorkbookHelper::getValidationPropertyHelper() const
+{
+ return mrBookData.getValidationPropertyHelper();
+}
+
+// OOX specific ---------------------------------------------------------------
+
+XmlFilterBase& WorkbookHelper::getOoxFilter() const
+{
+ OSL_ENSURE( mrBookData.getFilterType() == FILTER_OOX, "WorkbookHelper::getOoxFilter - invalid call" );
+ return mrBookData.getOoxFilter();
+}
+
+bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
+{
+ return getOoxFilter().importFragment( rxHandler );
+}
+
+// BIFF specific --------------------------------------------------------------
+
+BinaryFilterBase& WorkbookHelper::getBiffFilter() const
+{
+ OSL_ENSURE( mrBookData.getFilterType() == FILTER_BIFF, "WorkbookHelper::getBiffFilter - invalid call" );
+ return mrBookData.getBiffFilter();
+}
+
+BiffType WorkbookHelper::getBiff() const
+{
+ return mrBookData.getBiff();
+}
+
+rtl_TextEncoding WorkbookHelper::getTextEncoding() const
+{
+ return mrBookData.getTextEncoding();
+}
+
+void WorkbookHelper::setTextEncoding( rtl_TextEncoding eTextEnc )
+{
+ mrBookData.setTextEncoding( eTextEnc );
+}
+
+void WorkbookHelper::setCodePage( sal_uInt16 nCodePage )
+{
+ mrBookData.setCodePage( nCodePage );
+}
+
+void WorkbookHelper::setAppFontEncoding( rtl_TextEncoding eAppFontEnc )
+{
+ mrBookData.setAppFontEncoding( eAppFontEnc );
+}
+
+void WorkbookHelper::setIsWorkbookFile()
+{
+ mrBookData.setIsWorkbookFile();
+}
+
+void WorkbookHelper::createBuffersPerSheet()
+{
+ mrBookData.createBuffersPerSheet();
+}
+
+OUString WorkbookHelper::queryPassword() const
+{
+ return mrBookData.queryPassword();
+}
+
+// ============================================================================
+
+namespace prv {
+
+WorkbookDataOwner::WorkbookDataOwner( WorkbookDataRef xBookData ) :
+ mxBookData( xBookData )
+{
+}
+
+WorkbookDataOwner::~WorkbookDataOwner()
+{
+}
+
+} // namespace prv
+
+// ----------------------------------------------------------------------------
+
+WorkbookHelperRoot::WorkbookHelperRoot( ::oox::core::XmlFilterBase& rFilter ) :
+ prv::WorkbookDataOwner( prv::WorkbookDataRef( new WorkbookData( rFilter ) ) ),
+ WorkbookHelper( *mxBookData )
+{
+}
+
+WorkbookHelperRoot::WorkbookHelperRoot( ::oox::core::BinaryFilterBase& rFilter, BiffType eBiff ) :
+ prv::WorkbookDataOwner( prv::WorkbookDataRef( new WorkbookData( rFilter, eBiff ) ) ),
+ WorkbookHelper( *mxBookData )
+{
+}
+
+bool WorkbookHelperRoot::isValid() const
+{
+ return mxBookData->isValid();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx
new file mode 100644
index 000000000000..bb758dbb9511
--- /dev/null
+++ b/oox/source/xls/workbooksettings.cxx
@@ -0,0 +1,297 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: workbooksettings.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/workbooksettings.hxx"
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/sheet/XCalculatable.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::util::Date;
+using ::com::sun::star::util::XNumberFormatsSupplier;
+using ::com::sun::star::sheet::XCalculatable;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 OOBIN_WORKBOOKPR_DATE1904 = 0x00000001;
+const sal_uInt32 OOBIN_WORKBOOKPR_STRIPEXT = 0x00000080;
+
+const sal_uInt16 OOBIN_CALCPR_A1 = 0x0002;
+const sal_uInt16 OOBIN_CALCPR_ITERATE = 0x0004;
+const sal_uInt16 OOBIN_CALCPR_FULLPRECISION = 0x0008;
+const sal_uInt16 OOBIN_CALCPR_CALCCOMPLETED = 0x0010;
+const sal_uInt16 OOBIN_CALCPR_CALCONSAVE = 0x0020;
+const sal_uInt16 OOBIN_CALCPR_CONCURRENT = 0x0040;
+const sal_uInt16 OOBIN_CALCPR_MANUALPROC = 0x0080;
+
+// no predefined constants for show objects mode
+const sal_Int16 API_SHOWMODE_SHOW = 0; /// Show drawing objects.
+const sal_Int16 API_SHOWMODE_HIDE = 1; /// Hide drawing objects.
+const sal_Int16 API_SHOWMODE_PLACEHOLDER = 2; /// Show placeholders for drawing objects.
+
+} // namespace
+
+// ============================================================================
+
+OoxWorkbookPrData::OoxWorkbookPrData() :
+ mnShowObjectMode( XML_all ),
+ mnUpdateLinksMode( XML_userSet ),
+ mnDefaultThemeVer( -1 ),
+ mbDateMode1904( false ),
+ mbSaveExtLinkValues( true )
+{
+}
+
+void OoxWorkbookPrData::setBinObjectMode( sal_uInt16 nObjMode )
+{
+ static const sal_Int32 spnObjModes[] = { XML_all, XML_placeholders, XML_none };
+ mnShowObjectMode = STATIC_ARRAY_SELECT( spnObjModes, nObjMode, XML_all );
+}
+
+// ============================================================================
+
+OoxCalcPrData::OoxCalcPrData() :
+ mfIterateDelta( 0.001 ),
+ mnCalcId( -1 ),
+ mnRefMode( XML_A1 ),
+ mnCalcMode( XML_auto ),
+ mnIterateCount( 100 ),
+ mnProcCount( -1 ),
+ mbCalcOnSave( true ),
+ mbCalcCompleted( true ),
+ mbFullPrecision( true ),
+ mbIterate( false ),
+ mbConcurrent( true ),
+ mbUseNlr( false )
+{
+}
+
+// ============================================================================
+
+WorkbookSettings::WorkbookSettings( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void WorkbookSettings::importWorkbookPr( const AttributeList& rAttribs )
+{
+ maOoxBookData.maCodeName = rAttribs.getString( XML_codePage );
+ maOoxBookData.mnShowObjectMode = rAttribs.getToken( XML_showObjects, XML_all );
+ maOoxBookData.mnUpdateLinksMode = rAttribs.getToken( XML_updateLinks, XML_userSet );
+ maOoxBookData.mnDefaultThemeVer = rAttribs.getInteger( XML_defaultThemeVersion, -1 );
+ maOoxBookData.mbDateMode1904 = rAttribs.getBool( XML_date1904, false );
+ maOoxBookData.mbSaveExtLinkValues = rAttribs.getBool( XML_saveExternalLinkValues, true );
+}
+
+void WorkbookSettings::importCalcPr( const AttributeList& rAttribs )
+{
+ maOoxCalcData.mfIterateDelta = rAttribs.getDouble( XML_iterateDelta, 0.0001 );
+ maOoxCalcData.mnCalcId = rAttribs.getInteger( XML_calcId, -1 );
+ maOoxCalcData.mnRefMode = rAttribs.getToken( XML_refMode, XML_A1 );
+ maOoxCalcData.mnCalcMode = rAttribs.getToken( XML_calcMode, XML_auto );
+ maOoxCalcData.mnIterateCount = rAttribs.getInteger( XML_iterateCount, 100 );
+ maOoxCalcData.mnProcCount = rAttribs.getInteger( XML_concurrentManualCount, -1 );
+ maOoxCalcData.mbCalcOnSave = rAttribs.getBool( XML_calcOnSave, true );
+ maOoxCalcData.mbCalcCompleted = rAttribs.getBool( XML_calcCompleted, true );
+ maOoxCalcData.mbFullPrecision = rAttribs.getBool( XML_fullPrecision, true );
+ maOoxCalcData.mbIterate = rAttribs.getBool( XML_iterate, false );
+ maOoxCalcData.mbConcurrent = rAttribs.getBool( XML_concurrentCalc, true );
+}
+
+void WorkbookSettings::importWorkbookPr( RecordInputStream& rStrm )
+{
+ sal_uInt32 nFlags;
+ rStrm >> nFlags >> maOoxBookData.mnDefaultThemeVer >> maOoxBookData.maCodeName;
+ maOoxBookData.setBinObjectMode( extractValue< sal_uInt16 >( nFlags, 13, 2 ) );
+ maOoxBookData.mbDateMode1904 = getFlag( nFlags, OOBIN_WORKBOOKPR_DATE1904 );
+ // set flag means: strip external link values
+ maOoxBookData.mbSaveExtLinkValues = !getFlag( nFlags, OOBIN_WORKBOOKPR_STRIPEXT );
+}
+
+void WorkbookSettings::importCalcPr( RecordInputStream& rStrm )
+{
+ sal_Int32 nCalcMode, nProcCount;
+ sal_uInt16 nFlags;
+ rStrm >> maOoxCalcData.mnCalcId >> nCalcMode >> maOoxCalcData.mnIterateCount >> maOoxCalcData.mfIterateDelta >> nProcCount >> nFlags;
+
+ static const sal_Int32 spnCalcModes[] = { XML_manual, XML_auto, XML_autoNoTable };
+ maOoxCalcData.mnRefMode = getFlagValue( nFlags, OOBIN_CALCPR_A1, XML_A1, XML_R1C1 );
+ maOoxCalcData.mnCalcMode = STATIC_ARRAY_SELECT( spnCalcModes, nCalcMode, XML_auto );
+ maOoxCalcData.mnProcCount = getFlagValue< sal_Int32 >( nFlags, OOBIN_CALCPR_MANUALPROC, nProcCount, -1 );
+ maOoxCalcData.mbCalcOnSave = getFlag( nFlags, OOBIN_CALCPR_CALCONSAVE );
+ maOoxCalcData.mbCalcCompleted = getFlag( nFlags, OOBIN_CALCPR_CALCCOMPLETED );
+ maOoxCalcData.mbFullPrecision = getFlag( nFlags, OOBIN_CALCPR_FULLPRECISION );
+ maOoxCalcData.mbIterate = getFlag( nFlags, OOBIN_CALCPR_ITERATE );
+ maOoxCalcData.mbConcurrent = getFlag( nFlags, OOBIN_CALCPR_CONCURRENT );
+}
+
+void WorkbookSettings::setSaveExtLinkValues( bool bSaveExtLinks )
+{
+ maOoxBookData.mbSaveExtLinkValues = bSaveExtLinks;
+}
+
+void WorkbookSettings::importBookBool( BiffInputStream& rStrm )
+{
+ // value of 0 means save external values, value of 1 means strip external values
+ maOoxBookData.mbSaveExtLinkValues = rStrm.readuInt16() == 0;
+}
+
+void WorkbookSettings::importCalcCount( BiffInputStream& rStrm )
+{
+ maOoxCalcData.mnIterateCount = rStrm.readuInt16();
+}
+
+void WorkbookSettings::importCalcMode( BiffInputStream& rStrm )
+{
+ sal_Int16 nCalcMode = rStrm.readInt16() + 1;
+ static const sal_Int32 spnCalcModes[] = { XML_autoNoTable, XML_manual, XML_auto };
+ maOoxCalcData.mnCalcMode = STATIC_ARRAY_SELECT( spnCalcModes, nCalcMode, XML_auto );
+}
+
+void WorkbookSettings::importCodeName( BiffInputStream& rStrm )
+{
+ maOoxBookData.maCodeName = rStrm.readUniString();
+}
+
+void WorkbookSettings::importDateMode( BiffInputStream& rStrm )
+{
+ maOoxBookData.mbDateMode1904 = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::importDelta( BiffInputStream& rStrm )
+{
+ rStrm >> maOoxCalcData.mfIterateDelta;
+}
+
+void WorkbookSettings::importHideObj( BiffInputStream& rStrm )
+{
+ maOoxBookData.setBinObjectMode( rStrm.readuInt16() );
+}
+
+void WorkbookSettings::importIteration( BiffInputStream& rStrm )
+{
+ maOoxCalcData.mbIterate = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::importPrecision( BiffInputStream& rStrm )
+{
+ maOoxCalcData.mbFullPrecision = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::importRefMode( BiffInputStream& rStrm )
+{
+ maOoxCalcData.mnRefMode = (rStrm.readuInt16() == 0) ? XML_R1C1 : XML_A1;
+}
+
+void WorkbookSettings::importSaveRecalc( BiffInputStream& rStrm )
+{
+ maOoxCalcData.mbCalcOnSave = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::importUncalced( BiffInputStream& )
+{
+ // existence of this record indicates incomplete recalc
+ maOoxCalcData.mbCalcCompleted = false;
+}
+
+void WorkbookSettings::importUsesElfs( BiffInputStream& rStrm )
+{
+ maOoxCalcData.mbUseNlr = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::finalizeImport()
+{
+ // default settings
+ PropertySet aPropSet( getDocument() );
+ switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ case FILTER_BIFF:
+ aPropSet.setProperty( CREATE_OUSTRING( "IgnoreCase" ), true ); // always in Excel
+ aPropSet.setProperty( CREATE_OUSTRING( "RegularExpressions" ), false ); // not supported in Excel
+ break;
+ case FILTER_UNKNOWN:
+ break;
+ }
+
+ // calculation settings
+ Date aNullDate = maOoxBookData.mbDateMode1904 ? Date( 1, 1, 1904 ) : Date( 30, 12, 1899 );
+
+ aPropSet.setProperty( CREATE_OUSTRING( "NullDate" ), aNullDate );
+ aPropSet.setProperty( CREATE_OUSTRING( "IsIterationEnabled" ), maOoxCalcData.mbIterate );
+ aPropSet.setProperty( CREATE_OUSTRING( "IterationCount" ), maOoxCalcData.mnIterateCount );
+ aPropSet.setProperty( CREATE_OUSTRING( "IterationEpsilon" ), maOoxCalcData.mfIterateDelta );
+ aPropSet.setProperty( CREATE_OUSTRING( "CalcAsShown" ), !maOoxCalcData.mbFullPrecision );
+ aPropSet.setProperty( CREATE_OUSTRING( "LookUpLabels" ), maOoxCalcData.mbUseNlr );
+
+ Reference< XNumberFormatsSupplier > xNumFmtsSupp( getDocument(), UNO_QUERY );
+ if( xNumFmtsSupp.is() )
+ {
+ PropertySet aNumFmtProp( xNumFmtsSupp->getNumberFormatSettings() );
+ aNumFmtProp.setProperty( CREATE_OUSTRING( "NullDate" ), aNullDate );
+ }
+
+ Reference< XCalculatable > xCalculatable( getDocument(), UNO_QUERY );
+ if( xCalculatable.is() )
+ xCalculatable->enableAutomaticCalculation( (maOoxCalcData.mnCalcMode == XML_auto) || (maOoxCalcData.mnCalcMode == XML_autoNoTable) );
+}
+
+sal_Int16 WorkbookSettings::getApiShowObjectMode() const
+{
+ switch( maOoxBookData.mnShowObjectMode )
+ {
+ case XML_all: return API_SHOWMODE_SHOW;
+ case XML_none: return API_SHOWMODE_HIDE;
+ // #i80528# placeholders not supported anymore, but this is handled internally in Calc
+ case XML_placeholders: return API_SHOWMODE_PLACEHOLDER;
+ }
+ return API_SHOWMODE_SHOW;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/worksheetbuffer.cxx b/oox/source/xls/worksheetbuffer.cxx
new file mode 100644
index 000000000000..d52d75bab6b0
--- /dev/null
+++ b/oox/source/xls/worksheetbuffer.cxx
@@ -0,0 +1,333 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: worksheetbuffer.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheetbuffer.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/XCharacterClassification.hpp>
+#include <com/sun/star/i18n/KParseTokens.hpp>
+#include <com/sun/star/i18n/KParseType.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XExternalSheetName.hpp>
+#include <com/sun/star/sheet/XSheetLinkable.hpp>
+#include <comphelper/processfactory.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"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/ooxtokens.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+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 ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::container::XNamed;
+using ::com::sun::star::lang::Locale;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::i18n::ParseResult;
+using ::com::sun::star::sheet::XSpreadsheetDocument;
+using ::com::sun::star::sheet::XSpreadsheets;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::sheet::XExternalSheetName;
+using ::com::sun::star::sheet::XSheetLinkable;
+
+namespace oox {
+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
+
+// ============================================================================
+
+OoxSheetInfo::OoxSheetInfo() :
+ mnSheetId( -1 ),
+ mnState( XML_visible )
+{
+}
+
+// ============================================================================
+
+WorksheetBuffer::WorksheetBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maIsVisibleProp( CREATE_OUSTRING( "IsVisible" ) )
+{
+ // character classification service for conversion to valid sheet names
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ mxCharClass.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.i18n.CharacterClassification" ) ), UNO_QUERY );
+ OSL_ENSURE( mxCharClass.is(), "WorksheetBuffer::WorksheetBuffer - no character classification service" );
+}
+
+void WorksheetBuffer::initializeSingleSheet()
+{
+ OSL_ENSURE( maSheetInfos.empty(), "WorksheetBuffer::initializeSingleSheet - invalid call" );
+ OoxSheetInfo aSheetInfo;
+ aSheetInfo.maName = lclGetBaseFileName( getBaseFilter().getFileUrl() );
+ insertSheet( aSheetInfo );
+}
+
+void WorksheetBuffer::importSheet( const AttributeList& rAttribs )
+{
+ OoxSheetInfo aSheetInfo;
+ aSheetInfo.maId = rAttribs.getString( R_TOKEN( id ) );
+ aSheetInfo.maName = rAttribs.getString( XML_name );
+ aSheetInfo.mnSheetId = rAttribs.getInteger( XML_sheetId, -1 );
+ aSheetInfo.mnState = rAttribs.getToken( XML_state, XML_visible );
+ insertSheet( aSheetInfo );
+}
+
+void WorksheetBuffer::importSheet( RecordInputStream& rStrm )
+{
+ sal_Int32 nState;
+ OoxSheetInfo aSheetInfo;
+ rStrm >> nState >> aSheetInfo.mnSheetId >> aSheetInfo.maId >> aSheetInfo.maName;
+ static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden };
+ aSheetInfo.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible );
+ insertSheet( aSheetInfo );
+}
+
+void WorksheetBuffer::importSheet( BiffInputStream& rStrm )
+{
+ sal_uInt16 nState = 0;
+ if( getBiff() >= BIFF5 )
+ {
+ rStrm.skip( 4 );
+ rStrm >> nState;
+ }
+
+ OoxSheetInfo aSheetInfo;
+ aSheetInfo.maName = (getBiff() == BIFF8) ?
+ rStrm.readUniString( rStrm.readuInt8() ) :
+ rStrm.readByteString( false, getTextEncoding() );
+ static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden };
+ aSheetInfo.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible );
+ insertSheet( aSheetInfo );
+}
+
+sal_Int32 WorksheetBuffer::insertExternalSheet( const OUString& rTargetUrl, const OUString& rSheetName )
+{
+ // try to find existing external sheet (needed for BIFF4W and BIFF5)
+ ExternalSheetName aExtSheet( rTargetUrl, rSheetName );
+ ExternalSheetMap::iterator aIt = maExternalSheets.find( aExtSheet );
+ if( aIt != maExternalSheets.end() )
+ return aIt->second;
+
+ // create a new external sheet
+ sal_Int16& rnSheet = maExternalSheets[ aExtSheet ];
+ rnSheet = getTotalSheetCount();
+ insertSheet( OUString(), rnSheet, false );
+
+ try
+ {
+ Reference< XSpreadsheet > xSheet = getSheet( rnSheet );
+ // use base file name as sheet name, if sheet name is missing (e.g. links to BIFF2-BIFF4 files)
+ OUString aSheetName = rSheetName;
+ if( aSheetName.getLength() == 0 )
+ aSheetName = lclGetBaseFileName( rTargetUrl );
+ // link the sheet
+ Reference< XSheetLinkable > xLinkable( xSheet, UNO_QUERY_THROW );
+ xLinkable->link( rTargetUrl, aSheetName, OUString(), OUString(), ::com::sun::star::sheet::SheetLinkMode_VALUE );
+ // set the special external sheet name
+ Reference< XExternalSheetName > xSheetName( xSheet, UNO_QUERY_THROW );
+ xSheetName->setExternalName( xLinkable->getLinkUrl(), xLinkable->getLinkSheetName() );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // return sheet index
+ return rnSheet;
+}
+
+sal_Int32 WorksheetBuffer::getInternalSheetCount() const
+{
+ return static_cast< sal_Int32 >( maSheetInfos.size() );
+}
+
+OUString WorksheetBuffer::getSheetRelId( sal_Int32 nSheet ) const
+{
+ OUString aRelId;
+ if( const OoxSheetInfo* pInfo = getSheetInfo( nSheet ) )
+ aRelId = pInfo->maId;
+ return aRelId;
+}
+
+OUString WorksheetBuffer::getFinalSheetName( sal_Int32 nSheet ) const
+{
+ OUString aName;
+ if( const OoxSheetInfo* pInfo = getSheetInfo( nSheet ) )
+ aName = pInfo->maFinalName;
+ return aName;
+}
+
+OUString WorksheetBuffer::getFinalSheetName( const OUString& rName ) const
+{
+ for( SheetInfoVec::const_iterator aIt = maSheetInfos.begin(), aEnd = maSheetInfos.end(); aIt != aEnd; ++aIt )
+ // TODO: handle encoded characters
+ if( aIt->maName.equalsIgnoreAsciiCase( rName ) )
+ return aIt->maFinalName;
+ return OUString();
+}
+
+sal_Int32 WorksheetBuffer::getFinalSheetIndex( const OUString& rName ) const
+{
+ for( SheetInfoVec::const_iterator aIt = maSheetInfos.begin(), aEnd = maSheetInfos.end(); aIt != aEnd; ++aIt )
+ // TODO: handle encoded characters
+ if( aIt->maName.equalsIgnoreAsciiCase( rName ) )
+ return static_cast< sal_Int32 >( aIt - maSheetInfos.begin() );
+ return -1;
+}
+
+// private --------------------------------------------------------------------
+
+sal_Int16 WorksheetBuffer::getTotalSheetCount() const
+{
+ try
+ {
+ Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
+ return static_cast< sal_Int16 >( xSheetsIA->getCount() );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "WorksheetBuffer::getTotalSheetCount - cannot get sheet count" );
+ }
+ return 1;
+}
+
+const OoxSheetInfo* WorksheetBuffer::getSheetInfo( sal_Int32 nSheet ) const
+{
+ return ((0 <= nSheet) && (static_cast< size_t >( nSheet ) < maSheetInfos.size())) ?
+ &maSheetInfos[ static_cast< size_t >( nSheet ) ] : 0;
+}
+
+OUString WorksheetBuffer::convertToValidSheetName( const OUString& rName, sal_Unicode cReplaceChar ) const
+{
+ if( !mxCharClass.is() ) return rName;
+
+ using namespace ::com::sun::star::i18n::KParseTokens;
+ using namespace ::com::sun::star::i18n::KParseType;
+
+ OUStringBuffer aFinalName( rName );
+ Locale aLocale( CREATE_OUSTRING( "en" ), CREATE_OUSTRING( "US" ), OUString() );
+ sal_Int32 nStartFlags = ANY_LETTER_OR_NUMBER | ASC_UNDERSCORE;
+ sal_Int32 nContFlags = nStartFlags;
+ OUString aStartChars;
+ OUString aContChars( sal_Unicode( ' ' ) );
+ sal_Int32 nStartPos = 0;
+ while( nStartPos < aFinalName.getLength() )
+ {
+ ParseResult aRes = mxCharClass->parsePredefinedToken(
+ IDENTNAME, rName, nStartPos, aLocale, nStartFlags, aStartChars, nContFlags, aContChars );
+ if( aRes.EndPos < aFinalName.getLength() )
+ {
+ aFinalName.setCharAt( aRes.EndPos, cReplaceChar );
+ nStartFlags = nContFlags;
+ aStartChars = aContChars;
+ }
+ nStartPos = aRes.EndPos + 1;
+ }
+ return aFinalName.makeStringAndClear();
+}
+
+OUString WorksheetBuffer::insertSheet( const OUString& rName, sal_Int16 nSheet, bool bVisible )
+{
+ OUString aFinalName = (rName.getLength() == 0) ? CREATE_OUSTRING( "Sheet" ) : convertToValidSheetName( rName, '_' );
+ try
+ {
+ Reference< XSpreadsheets > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xSheetsIA( xSheets, UNO_QUERY_THROW );
+ Reference< XNameAccess > xSheetsNA( xSheets, UNO_QUERY_THROW );
+ PropertySet aPropSet;
+ if( nSheet < xSheetsIA->getCount() )
+ {
+ // existing sheet - try to rename
+ Reference< XNamed > xSheetName( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW );
+ if( xSheetName->getName() != aFinalName )
+ {
+ aFinalName = ContainerHelper::getUnusedName( xSheetsNA, aFinalName, ' ' );
+ xSheetName->setName( aFinalName );
+ }
+ aPropSet.set( xSheetName );
+ }
+ else
+ {
+ // new sheet - insert with unused name
+ aFinalName = ContainerHelper::getUnusedName( xSheetsNA, aFinalName, ' ' );
+ xSheets->insertNewByName( aFinalName, nSheet );
+ aPropSet.set( xSheetsIA->getByIndex( nSheet ) );
+ }
+
+ // sheet properties
+ aPropSet.setProperty( maIsVisibleProp, bVisible );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "WorksheetBuffer::insertSheet - cannot insert or rename worksheet" );
+ }
+ return aFinalName;
+}
+
+void WorksheetBuffer::insertSheet( const OoxSheetInfo& rSheetInfo )
+{
+ OSL_ENSURE( maExternalSheets.empty(), "WorksheetBuffer::insertSheet - external sheets exist already" );
+ sal_Int16 nSheet = static_cast< sal_Int16 >( maSheetInfos.size() );
+ maSheetInfos.push_back( rSheetInfo );
+ maSheetInfos.back().maFinalName = insertSheet( rSheetInfo.maName, nSheet, rSheetInfo.mnState == XML_visible );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx
new file mode 100644
index 000000000000..0fce487bb5c7
--- /dev/null
+++ b/oox/source/xls/worksheetfragment.cxx
@@ -0,0 +1,1068 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: worksheetfragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheetfragment.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/core/relations.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/autofiltercontext.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/condformatcontext.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/pivottablefragment.hxx"
+#include "oox/xls/querytablefragment.hxx"
+#include "oox/xls/sheetdatacontext.hxx"
+#include "oox/xls/tablefragment.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetsettings.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::xml::sax::XFastContextHandler;
+using ::oox::core::Relations;
+using ::oox::core::RelationsRef;
+using ::oox::core::RecordContextRef;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 OOBIN_BRK_MANUAL = 0x00000001;
+
+const sal_uInt16 BIFF_COLINFO_HIDDEN = 0x0001;
+const sal_uInt16 BIFF_COLINFO_COLLAPSED = 0x1000;
+
+const sal_uInt16 BIFF_DEFROW_CUSTOMHEIGHT = 0x0001;
+const sal_uInt16 BIFF_DEFROW_HIDDEN = 0x0002;
+const sal_uInt16 BIFF_DEFROW_THICKTOP = 0x0004;
+const sal_uInt16 BIFF_DEFROW_THICKBOTTOM = 0x0008;
+const sal_uInt16 BIFF2_DEFROW_DEFHEIGHT = 0x8000;
+const sal_uInt16 BIFF2_DEFROW_MASK = 0x7FFF;
+
+const sal_uInt32 BIFF_DATAVAL_STRINGLIST = 0x00000080;
+const sal_uInt32 BIFF_DATAVAL_ALLOWBLANK = 0x00000100;
+const sal_uInt32 BIFF_DATAVAL_NODROPDOWN = 0x00000200;
+const sal_uInt32 BIFF_DATAVAL_SHOWINPUT = 0x00040000;
+const sal_uInt32 BIFF_DATAVAL_SHOWERROR = 0x00080000;
+
+const sal_uInt32 BIFF_HYPERLINK_TARGET = 0x00000001; /// File name or URL.
+const sal_uInt32 BIFF_HYPERLINK_ABS = 0x00000002; /// Absolute path.
+const sal_uInt32 BIFF_HYPERLINK_DISPLAY = 0x00000014; /// Display string.
+const sal_uInt32 BIFF_HYPERLINK_LOC = 0x00000008; /// Target location.
+const sal_uInt32 BIFF_HYPERLINK_FRAME = 0x00000080; /// Target frame.
+const sal_uInt32 BIFF_HYPERLINK_UNC = 0x00000100; /// UNC path.
+
+} // namespace
+
+// ============================================================================
+
+OoxWorksheetFragment::OoxWorksheetFragment( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) :
+ OoxWorksheetFragmentBase( rHelper, rFragmentPath, xProgressBar, eSheetType, nSheet )
+{
+ // import data tables related to this worksheet
+ RelationsRef xTableRels = getRelations().getRelationsFromType( CREATE_RELATIONS_TYPE( "table" ) );
+ for( Relations::const_iterator aIt = xTableRels->begin(), aEnd = xTableRels->end(); aIt != aEnd; ++aIt )
+ importOoxFragment( new OoxTableFragment( *this, getFragmentPathFromTarget( aIt->second.maTarget ) ) );
+}
+
+// oox.xls.OoxContextHelper interface -----------------------------------------
+
+bool OoxWorksheetFragment::onCanCreateContext( sal_Int32 nElement ) const
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nElement == XLS_TOKEN( worksheet ));
+ case XLS_TOKEN( worksheet ):
+ return (nElement == XLS_TOKEN( sheetPr )) ||
+ (nElement == XLS_TOKEN( dimension )) ||
+ (nElement == XLS_TOKEN( sheetFormatPr )) ||
+ (nElement == XLS_TOKEN( sheetViews )) ||
+ (nElement == XLS_TOKEN( cols )) ||
+ (nElement == XLS_TOKEN( sheetData )) ||
+ (nElement == XLS_TOKEN( mergeCells )) ||
+ (nElement == XLS_TOKEN( hyperlinks )) ||
+ (nElement == XLS_TOKEN( autoFilter )) ||
+ (nElement == XLS_TOKEN( dataValidations )) ||
+ (nElement == XLS_TOKEN( conditionalFormatting )) ||
+ (nElement == XLS_TOKEN( pageMargins )) ||
+ (nElement == XLS_TOKEN( pageSetup )) ||
+ (nElement == XLS_TOKEN( headerFooter )) ||
+ (nElement == XLS_TOKEN( printOptions )) ||
+ (nElement == XLS_TOKEN( rowBreaks )) ||
+ (nElement == XLS_TOKEN( colBreaks )) ||
+ (nElement == XLS_TOKEN( sheetProtection )) ||
+ (nElement == XLS_TOKEN( phoneticPr ));
+ case XLS_TOKEN( sheetPr ):
+ return (nElement == XLS_TOKEN( outlinePr )) ||
+ (nElement == XLS_TOKEN( pageSetUpPr ));
+ case XLS_TOKEN( sheetViews ):
+ return (nElement == XLS_TOKEN( sheetView ));
+ case XLS_TOKEN( sheetView ):
+ return (nElement == XLS_TOKEN( pane )) ||
+ (nElement == XLS_TOKEN( selection ));
+ case XLS_TOKEN( cols ):
+ return (nElement == XLS_TOKEN( col ));
+ case XLS_TOKEN( mergeCells ):
+ return (nElement == XLS_TOKEN( mergeCell ));
+ case XLS_TOKEN( hyperlinks ):
+ return (nElement == XLS_TOKEN( hyperlink ));
+ case XLS_TOKEN( dataValidations ):
+ return (nElement == XLS_TOKEN( dataValidation ));
+ case XLS_TOKEN( dataValidation ):
+ return (nElement == XLS_TOKEN( formula1 )) ||
+ (nElement == XLS_TOKEN( formula2 ));
+ case XLS_TOKEN( headerFooter ):
+ return (nElement == XLS_TOKEN( firstHeader )) ||
+ (nElement == XLS_TOKEN( firstFooter )) ||
+ (nElement == XLS_TOKEN( oddHeader )) ||
+ (nElement == XLS_TOKEN( oddFooter )) ||
+ (nElement == XLS_TOKEN( evenHeader )) ||
+ (nElement == XLS_TOKEN( evenFooter ));
+ case XLS_TOKEN( rowBreaks ):
+ case XLS_TOKEN( colBreaks ):
+ return (nElement == XLS_TOKEN( brk ));
+ }
+ return false;
+}
+
+Reference< XFastContextHandler > OoxWorksheetFragment::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheetData ):
+ return new OoxSheetDataContext( *this );
+ case XLS_TOKEN( autoFilter ):
+ return new OoxAutoFilterContext( *this );
+ case XLS_TOKEN( conditionalFormatting ):
+ return new OoxCondFormatContext( *this );
+ }
+ return this;
+}
+
+void OoxWorksheetFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentContext() )
+ {
+ case XLS_TOKEN( dimension ): importDimension( rAttribs ); break;
+ case XLS_TOKEN( sheetFormatPr ): importSheetFormatPr( rAttribs ); break;
+ case XLS_TOKEN( sheetView ): getSheetViewSettings().importSheetView( rAttribs ); break;
+ case XLS_TOKEN( pane ): getSheetViewSettings().importPane( rAttribs ); break;
+ case XLS_TOKEN( selection ): getSheetViewSettings().importSelection( rAttribs ); break;
+ case XLS_TOKEN( outlinePr ): getWorksheetSettings().importOutlinePr( rAttribs ); break;
+ case XLS_TOKEN( sheetProtection ): getWorksheetSettings().importSheetProtection( rAttribs ); break;
+ case XLS_TOKEN( phoneticPr ): getWorksheetSettings().importPhoneticPr( rAttribs ); break;
+ case XLS_TOKEN( col ): importCol( rAttribs ); break;
+ case XLS_TOKEN( mergeCell ): importMergeCell( rAttribs ); break;
+ case XLS_TOKEN( hyperlink ): importHyperlink( rAttribs ); break;
+ case XLS_TOKEN( dataValidation ): importDataValidation( rAttribs ); break;
+ case XLS_TOKEN( pageMargins ): getPageSettings().importPageMargins( rAttribs ); break;
+ case XLS_TOKEN( pageSetup ): getPageSettings().importPageSetup( rAttribs ); break;
+ case XLS_TOKEN( printOptions ): getPageSettings().importPrintOptions( rAttribs ); break;
+ case XLS_TOKEN( headerFooter ): getPageSettings().importHeaderFooter( rAttribs ); break;
+ case XLS_TOKEN( pageSetUpPr ): importPageSetUpPr( rAttribs ); break;
+ case XLS_TOKEN( brk ): importBrk( rAttribs ); break;
+ }
+}
+
+void OoxWorksheetFragment::onEndElement( const OUString& rChars )
+{
+ sal_Int32 nCurrentContext = getCurrentContext();
+ switch( nCurrentContext )
+ {
+ case XLS_TOKEN( firstHeader ):
+ case XLS_TOKEN( firstFooter ):
+ case XLS_TOKEN( oddHeader ):
+ case XLS_TOKEN( oddFooter ):
+ case XLS_TOKEN( evenHeader ):
+ case XLS_TOKEN( evenFooter ):
+ getPageSettings().importHeaderFooterCharacters( rChars, nCurrentContext );
+ break;
+ case XLS_TOKEN( formula1 ):
+ if( mxValData.get() )
+ {
+ importDataValFormula( mxValData->maTokens1, rChars, mxValData->maRanges.getBaseAddress() );
+ // process string list of a list validation (convert to list of string tokens)
+ if( mxValData->mnType == XML_list )
+ getFormulaParser().convertStringToStringList( mxValData->maTokens1, ',', true );
+ }
+ break;
+ case XLS_TOKEN( formula2 ):
+ if( mxValData.get() )
+ importDataValFormula( mxValData->maTokens2, rChars, mxValData->maRanges.getBaseAddress() );
+ break;
+ case XLS_TOKEN( dataValidation ):
+ if( mxValData.get() )
+ setValidation( *mxValData );
+ mxValData.reset();
+ break;
+ }
+}
+
+bool OoxWorksheetFragment::onCanCreateRecordContext( sal_Int32 nRecId )
+{
+ switch( getCurrentContext() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nRecId == OOBIN_ID_WORKSHEET);
+ case OOBIN_ID_WORKSHEET:
+ return (nRecId == OOBIN_ID_SHEETPR) ||
+ (nRecId == OOBIN_ID_DIMENSION) ||
+ (nRecId == OOBIN_ID_SHEETFORMATPR) ||
+ (nRecId == OOBIN_ID_SHEETVIEWS) ||
+ (nRecId == OOBIN_ID_COLS) ||
+ (nRecId == OOBIN_ID_SHEETDATA) ||
+ (nRecId == OOBIN_ID_MERGECELLS) ||
+ (nRecId == OOBIN_ID_HYPERLINK) ||
+ (nRecId == OOBIN_ID_DATAVALIDATIONS) ||
+ (nRecId == OOBIN_ID_CONDFORMATTING) ||
+ (nRecId == OOBIN_ID_PAGEMARGINS) ||
+ (nRecId == OOBIN_ID_PAGESETUP) ||
+ (nRecId == OOBIN_ID_PRINTOPTIONS) ||
+ (nRecId == OOBIN_ID_HEADERFOOTER) ||
+ (nRecId == OOBIN_ID_ROWBREAKS) ||
+ (nRecId == OOBIN_ID_COLBREAKS) ||
+ (nRecId == OOBIN_ID_SHEETPROTECTION) ||
+ (nRecId == OOBIN_ID_PHONETICPR);
+ case OOBIN_ID_SHEETVIEWS:
+ return (nRecId == OOBIN_ID_SHEETVIEW);
+ case OOBIN_ID_SHEETVIEW:
+ return (nRecId == OOBIN_ID_PANE) ||
+ (nRecId == OOBIN_ID_SELECTION);
+ case OOBIN_ID_COLS:
+ return (nRecId == OOBIN_ID_COL);
+ case OOBIN_ID_MERGECELLS:
+ return (nRecId == OOBIN_ID_MERGECELL);
+ case OOBIN_ID_DATAVALIDATIONS:
+ return (nRecId == OOBIN_ID_DATAVALIDATION);
+ case OOBIN_ID_ROWBREAKS:
+ case OOBIN_ID_COLBREAKS:
+ return (nRecId == OOBIN_ID_BRK);
+ }
+ return false;
+}
+
+RecordContextRef OoxWorksheetFragment::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& )
+{
+ switch( nRecId )
+ {
+ case OOBIN_ID_SHEETDATA:
+ return new OoxSheetDataContext( *this );
+ case OOBIN_ID_CONDFORMATTING:
+ return new OoxCondFormatContext( *this );
+ }
+ return this;
+}
+
+void OoxWorksheetFragment::onStartRecord( RecordInputStream& rStrm )
+{
+ switch( getCurrentContext() )
+ {
+ case OOBIN_ID_SHEETPR: getWorksheetSettings().importSheetPr( rStrm ); break;
+ case OOBIN_ID_DIMENSION: importDimension( rStrm ); break;
+ case OOBIN_ID_SHEETPROTECTION: getWorksheetSettings().importSheetProtection( rStrm ); break;
+ case OOBIN_ID_PHONETICPR: getWorksheetSettings().importPhoneticPr( rStrm ); break;
+ case OOBIN_ID_SHEETFORMATPR: importSheetFormatPr( rStrm ); break;
+ case OOBIN_ID_SHEETVIEW: getSheetViewSettings().importSheetView( rStrm ); break;
+ case OOBIN_ID_PANE: getSheetViewSettings().importPane( rStrm ); break;
+ case OOBIN_ID_SELECTION: getSheetViewSettings().importSelection( rStrm ); break;
+ case OOBIN_ID_COL: importCol( rStrm ); break;
+ case OOBIN_ID_MERGECELL: importMergeCell( rStrm ); break;
+ case OOBIN_ID_HYPERLINK: importHyperlink( rStrm ); break;
+ case OOBIN_ID_DATAVALIDATION: importDataValidation( rStrm ); break;
+ case OOBIN_ID_PAGEMARGINS: getPageSettings().importPageMargins( rStrm ); break;
+ case OOBIN_ID_PAGESETUP: getPageSettings().importPageSetup( rStrm ); break;
+ case OOBIN_ID_PRINTOPTIONS: getPageSettings().importPrintOptions( rStrm ); break;
+ case OOBIN_ID_HEADERFOOTER: getPageSettings().importHeaderFooter( rStrm ); break;
+ case OOBIN_ID_BRK: importBrk( rStrm ); break;
+ }
+}
+
+// oox.xls.OoxFragmentHandler interface ---------------------------------------
+
+void OoxWorksheetFragment::initializeImport()
+{
+ // initial processing in base class WorksheetHelper
+ initializeWorksheetImport();
+
+ // import query table fragments related to this worksheet
+ RelationsRef xQueryRels = getRelations().getRelationsFromType( CREATE_RELATIONS_TYPE( "queryTable" ) );
+ for( Relations::const_iterator aIt = xQueryRels->begin(), aEnd = xQueryRels->end(); aIt != aEnd; ++aIt )
+ importOoxFragment( new OoxQueryTableFragment( *this, getFragmentPathFromTarget( aIt->second.maTarget ) ) );
+
+ // import pivot table fragments related to this worksheet
+ RelationsRef xPivotRels = getRelations().getRelationsFromType( CREATE_RELATIONS_TYPE( "pivotTable" ) );
+ for( Relations::const_iterator aIt = xPivotRels->begin(), aEnd = xPivotRels->end(); aIt != aEnd; ++aIt )
+ importOoxFragment( new OoxPivotTableFragment( *this, getFragmentPathFromTarget( aIt->second.maTarget ) ) );
+}
+
+void OoxWorksheetFragment::finalizeImport()
+{
+ // final processing in base class WorksheetHelper
+ finalizeWorksheetImport();
+}
+
+// private --------------------------------------------------------------------
+
+void OoxWorksheetFragment::importDimension( const AttributeList& rAttribs )
+{
+ CellRangeAddress aRange;
+ getAddressConverter().convertToCellRangeUnchecked( aRange, rAttribs.getString( XML_ref ), getSheetIndex() );
+ setDimension( aRange );
+}
+
+void OoxWorksheetFragment::importSheetFormatPr( const AttributeList& rAttribs )
+{
+ // default column settings
+ setBaseColumnWidth( rAttribs.getInteger( XML_baseColWidth, 8 ) );
+ setDefaultColumnWidth( rAttribs.getDouble( XML_defaultColWidth, 0.0 ) );
+ // default row settings
+ setDefaultRowSettings(
+ rAttribs.getDouble( XML_defaultRowHeight, 0.0 ),
+ rAttribs.getBool( XML_customHeight, false ),
+ rAttribs.getBool( XML_zeroHeight, false ),
+ rAttribs.getBool( XML_thickTop, false ),
+ rAttribs.getBool( XML_thickBottom, false ) );
+}
+
+void OoxWorksheetFragment::importCol( const AttributeList& rAttribs )
+{
+ OoxColumnData aData;
+ aData.mnFirstCol = rAttribs.getInteger( XML_min, -1 );
+ aData.mnLastCol = rAttribs.getInteger( XML_max, -1 );
+ aData.mfWidth = rAttribs.getDouble( XML_width, 0.0 );
+ aData.mnXfId = rAttribs.getInteger( XML_style, -1 );
+ aData.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
+ aData.mbHidden = rAttribs.getBool( XML_hidden, false );
+ aData.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
+ // set column properties in the current sheet
+ setColumnData( aData );
+}
+
+void OoxWorksheetFragment::importMergeCell( const AttributeList& rAttribs )
+{
+ CellRangeAddress aRange;
+ if( getAddressConverter().convertToCellRange( aRange, rAttribs.getString( XML_ref ), getSheetIndex(), true ) )
+ setMergedRange( aRange );
+}
+
+void OoxWorksheetFragment::importHyperlink( const AttributeList& rAttribs )
+{
+ OoxHyperlinkData aData;
+ if( getAddressConverter().convertToCellRange( aData.maRange, rAttribs.getString( XML_ref ), getSheetIndex(), true ) )
+ {
+ aData.maTarget = getRelations().getTargetFromRelId( rAttribs.getString( R_TOKEN( id ) ) );
+ aData.maLocation = rAttribs.getString( XML_location );
+ aData.maDisplay = rAttribs.getString( XML_display );
+ aData.maTooltip = rAttribs.getString( XML_tooltip );
+ setHyperlink( aData );
+ }
+}
+
+void OoxWorksheetFragment::importDataValidation( const AttributeList& rAttribs )
+{
+ mxValData.reset( new OoxValidationData );
+ getAddressConverter().convertToCellRangeList( mxValData->maRanges, rAttribs.getString( XML_sqref ), getSheetIndex(), true );
+ mxValData->maInputTitle = rAttribs.getString( XML_promptTitle );
+ mxValData->maInputMessage = rAttribs.getString( XML_prompt );
+ mxValData->maErrorTitle = rAttribs.getString( XML_errorTitle );
+ mxValData->maErrorMessage = rAttribs.getString( XML_error );
+ mxValData->mnType = rAttribs.getToken( XML_type, XML_none );
+ mxValData->mnOperator = rAttribs.getToken( XML_operator, XML_between );
+ mxValData->mnErrorStyle = rAttribs.getToken( XML_errorStyle, XML_stop );
+ mxValData->mbShowInputMsg = rAttribs.getBool( XML_showInputMessage, false );
+ mxValData->mbShowErrorMsg = rAttribs.getBool( XML_showErrorMessage, false );
+ /* The attribute showDropDown@dataValidation is in fact a "suppress
+ dropdown" flag, as it was in the BIFF format! ECMA specification
+ and attribute name are plain wrong! */
+ mxValData->mbNoDropDown = rAttribs.getBool( XML_showDropDown, false );
+ mxValData->mbAllowBlank = rAttribs.getBool( XML_allowBlank, false );
+}
+
+void OoxWorksheetFragment::importPageSetUpPr( const AttributeList& rAttribs )
+{
+ // for whatever reason, this flag is still stored separated from the page settings
+ getPageSettings().setFitToPagesMode( rAttribs.getBool( XML_fitToPage, false ) );
+}
+
+void OoxWorksheetFragment::importBrk( const AttributeList& rAttribs )
+{
+ OoxPageBreakData aData;
+ aData.mnColRow = rAttribs.getInteger( XML_id, 0 );
+ aData.mnMin = rAttribs.getInteger( XML_id, 0 );
+ aData.mnMax = rAttribs.getInteger( XML_id, 0 );
+ aData.mbManual = rAttribs.getBool( XML_man, false );
+ switch( getPreviousContext() )
+ {
+ case XLS_TOKEN( rowBreaks ): setPageBreak( aData, true ); break;
+ case XLS_TOKEN( colBreaks ): setPageBreak( aData, false ); break;
+ }
+}
+
+void OoxWorksheetFragment::importDataValFormula( ApiTokenSequence& orTokens,
+ const OUString& rFormula, const CellAddress& rBaseAddress )
+{
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( rBaseAddress );
+ getFormulaParser().importFormula( aContext, rFormula );
+ orTokens = aContext.getTokens();
+}
+
+void OoxWorksheetFragment::importDimension( RecordInputStream& rStrm )
+{
+ BinRange aBinRange;
+ aBinRange.read( rStrm );
+ CellRangeAddress aRange;
+ getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() );
+ setDimension( aRange );
+}
+
+void OoxWorksheetFragment::importSheetFormatPr( RecordInputStream& rStrm )
+{
+ sal_Int32 nDefaultWidth;
+ sal_uInt16 nBaseWidth, nDefaultHeight, nFlags;
+ rStrm >> nDefaultWidth >> nBaseWidth >> nDefaultHeight >> nFlags;
+
+ // base column with
+ setBaseColumnWidth( nBaseWidth );
+ // default width is stored as 1/256th of a character in OOBIN, convert to entire character
+ setDefaultColumnWidth( static_cast< double >( nDefaultWidth ) / 256.0 );
+ // row height is in twips in OOBIN, convert to points; equal flags in BIFF and OOBIN
+ setDefaultRowSettings(
+ nDefaultHeight / 20.0,
+ getFlag( nFlags, BIFF_DEFROW_CUSTOMHEIGHT ),
+ getFlag( nFlags, BIFF_DEFROW_HIDDEN ),
+ getFlag( nFlags, BIFF_DEFROW_THICKTOP ),
+ getFlag( nFlags, BIFF_DEFROW_THICKBOTTOM ) );
+}
+
+void OoxWorksheetFragment::importCol( RecordInputStream& rStrm )
+{
+ OoxColumnData aData;
+
+ sal_uInt16 nWidth, nFlags;
+ rStrm >> aData.mnFirstCol >> aData.mnLastCol >> nWidth;
+ rStrm.skip( 2 );
+ rStrm >> aData.mnXfId >> nFlags;
+
+ // column indexes are 0-based in OOBIN, but OoxColumnData expects 1-based
+ ++aData.mnFirstCol;
+ ++aData.mnLastCol;
+ // width is stored as 1/256th of a character in OOBIN, convert to entire character
+ aData.mfWidth = static_cast< double >( nWidth ) / 256.0;
+ // equal flags in BIFF and OOBIN
+ aData.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 );
+ aData.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN );
+ aData.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED );
+ // set column properties in the current sheet
+ setColumnData( aData );
+}
+
+void OoxWorksheetFragment::importMergeCell( RecordInputStream& rStrm )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ CellRangeAddress aRange;
+ if( getAddressConverter().convertToCellRange( aRange, aBinRange, getSheetIndex(), true ) )
+ setMergedRange( aRange );
+}
+
+void OoxWorksheetFragment::importHyperlink( RecordInputStream& rStrm )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ OoxHyperlinkData aData;
+ if( getAddressConverter().convertToCellRange( aData.maRange, aBinRange, getSheetIndex(), true ) )
+ {
+ aData.maTarget = getRelations().getTargetFromRelId( rStrm.readString() );
+ rStrm >> aData.maLocation >> aData.maTooltip >> aData.maDisplay;
+ setHyperlink( aData );
+ }
+}
+
+void OoxWorksheetFragment::importDataValidation( RecordInputStream& rStrm )
+{
+ OoxValidationData aData;
+
+ sal_uInt32 nFlags;
+ BinRangeList aRanges;
+ rStrm >> nFlags >> aRanges >> aData.maErrorTitle >> aData.maErrorMessage >> aData.maInputTitle >> aData.maInputMessage;
+
+ // equal flags in BIFF and OOBIN
+ aData.setBinType( extractValue< sal_uInt8 >( nFlags, 0, 4 ) );
+ aData.setBinOperator( extractValue< sal_uInt8 >( nFlags, 20, 4 ) );
+ aData.setBinErrorStyle( extractValue< sal_uInt8 >( nFlags, 4, 3 ) );
+ aData.mbAllowBlank = getFlag( nFlags, BIFF_DATAVAL_ALLOWBLANK );
+ aData.mbNoDropDown = getFlag( nFlags, BIFF_DATAVAL_NODROPDOWN );
+ aData.mbShowInputMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWINPUT );
+ aData.mbShowErrorMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWERROR );
+
+ // cell range list
+ getAddressConverter().convertToCellRangeList( aData.maRanges, aRanges, getSheetIndex(), true );
+
+ // condition formula(s)
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( aData.maRanges.getBaseAddress() );
+ getFormulaParser().importFormula( aContext, rStrm );
+ aData.maTokens1 = aContext.getTokens();
+ getFormulaParser().importFormula( aContext, rStrm );
+ aData.maTokens2 = aContext.getTokens();
+ // process string list of a list validation (convert to list of string tokens)
+ if( (aData.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) )
+ getFormulaParser().convertStringToStringList( aData.maTokens1, ',', true );
+
+ // set validation data
+ setValidation( aData );
+}
+
+void OoxWorksheetFragment::importBrk( RecordInputStream& rStrm )
+{
+ OoxPageBreakData aData;
+ sal_uInt32 nFlags;
+ rStrm >> aData.mnColRow >> aData.mnMin >> aData.mnMax >> nFlags;
+ aData.mbManual = getFlag( nFlags, OOBIN_BRK_MANUAL );
+ switch( getPreviousContext() )
+ {
+ case OOBIN_ID_ROWBREAKS: setPageBreak( aData, true ); break;
+ case OOBIN_ID_COLBREAKS: setPageBreak( aData, false ); break;
+ }
+}
+
+// ============================================================================
+
+BiffWorksheetFragment::BiffWorksheetFragment( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) :
+ BiffWorksheetFragmentBase( rHelper, xProgressBar, eSheetType, nSheet )
+{
+}
+
+bool BiffWorksheetFragment::importFragment( BiffInputStream& rStrm )
+{
+ // initial processing in base class WorksheetHelper
+ initializeWorksheetImport();
+
+ // create a SheetDataContext object that implements cell import
+ BiffSheetDataContext aSheetData( *this );
+
+ WorkbookSettings& rWorkbookSett = getWorkbookSettings();
+ WorksheetSettings& rWorksheetSett = getWorksheetSettings();
+ SheetViewSettings& rSheetViewSett = getSheetViewSettings();
+ CondFormatBuffer& rCondFormats = getCondFormats();
+ PageSettings& rPageSett = getPageSettings();
+
+ // process all record in this sheet fragment
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ {
+ sal_uInt16 nRecId = rStrm.getRecId();
+
+ if( isBofRecord( nRecId ) )
+ {
+ // skip unknown embedded fragments (BOF/EOF blocks)
+ skipFragment( rStrm );
+ }
+ else
+ {
+ // cache core stream position to detect if record is already processed
+ sal_Int64 nStrmPos = rStrm.getCoreStreamPos();
+
+ switch( nRecId )
+ {
+ // records in all BIFF versions
+ case BIFF_ID_BOTTOMMARGIN: rPageSett.importBottomMargin( rStrm ); break;
+ case BIFF_ID_CALCCOUNT: rWorkbookSett.importCalcCount( rStrm ); break;
+ case BIFF_ID_CALCMODE: rWorkbookSett.importCalcMode( rStrm ); break;
+ case BIFF_ID_DEFCOLWIDTH: importDefColWidth( rStrm ); break;
+ case BIFF_ID_DELTA: rWorkbookSett.importDelta( rStrm ); break;
+ case BIFF2_ID_DIMENSION: importDimension( rStrm ); break;
+ case BIFF3_ID_DIMENSION: importDimension( rStrm ); break;
+ case BIFF_ID_FOOTER: rPageSett.importFooter( rStrm ); break;
+ case BIFF_ID_HEADER: rPageSett.importHeader( rStrm ); break;
+ case BIFF_ID_HORPAGEBREAKS: importPageBreaks( rStrm, true ); break;
+ case BIFF_ID_ITERATION: rWorkbookSett.importIteration( rStrm ); break;
+ case BIFF_ID_LEFTMARGIN: rPageSett.importLeftMargin( rStrm ); break;
+ case BIFF_ID_PANE: rSheetViewSett.importPane( rStrm ); break;
+ case BIFF_ID_PASSWORD: rWorksheetSett.importPassword( rStrm ); break;
+ case BIFF_ID_PRINTGRIDLINES: rPageSett.importPrintGridLines( rStrm ); break;
+ case BIFF_ID_PRINTHEADERS: rPageSett.importPrintHeaders( rStrm ); break;
+ case BIFF_ID_PROTECT: rWorksheetSett.importProtect( rStrm ); break;
+ case BIFF_ID_REFMODE: rWorkbookSett.importRefMode( rStrm ); break;
+ case BIFF_ID_RIGHTMARGIN: rPageSett.importRightMargin( rStrm ); break;
+ case BIFF_ID_SELECTION: rSheetViewSett.importSelection( rStrm ); break;
+ case BIFF_ID_TOPMARGIN: rPageSett.importTopMargin( rStrm ); break;
+ case BIFF_ID_VERPAGEBREAKS: importPageBreaks( rStrm, false ); break;
+
+ // BIFF specific records
+ default: switch( getBiff() )
+ {
+ case BIFF2: switch( nRecId )
+ {
+ case BIFF_ID_COLUMNDEFAULT: importColumnDefault( rStrm ); break;
+ case BIFF_ID_COLWIDTH: importColWidth( rStrm ); break;
+ case BIFF2_ID_DEFROWHEIGHT: importDefRowHeight( rStrm ); break;
+ case BIFF2_ID_WINDOW2: rSheetViewSett.importWindow2( rStrm ); break;
+ }
+ break;
+
+ case BIFF3: switch( nRecId )
+ {
+ case BIFF_ID_COLINFO: importColInfo( rStrm ); break;
+ case BIFF_ID_DEFCOLWIDTH: importDefColWidth( rStrm ); break;
+ case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight( rStrm ); break;
+ case BIFF_ID_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( rStrm ); break;
+ case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( rStrm ); break;
+ case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( rStrm ); break;
+ case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( rStrm ); break;
+ case BIFF_ID_VCENTER: rPageSett.importVerCenter( rStrm ); break;
+ case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( rStrm ); break;
+
+ }
+ break;
+
+ case BIFF4: switch( nRecId )
+ {
+ case BIFF_ID_COLINFO: importColInfo( rStrm ); break;
+ case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight( rStrm ); break;
+ case BIFF_ID_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( rStrm ); break;
+ case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( rStrm ); break;
+ case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( rStrm ); break;
+ case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( rStrm ); break;
+ case BIFF_ID_STANDARDWIDTH: importStandardWidth( rStrm ); break;
+ case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( rStrm ); break;
+ case BIFF_ID_VCENTER: rPageSett.importVerCenter( rStrm ); break;
+ case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( rStrm ); break;
+ }
+ break;
+
+ case BIFF5: switch( nRecId )
+ {
+ case BIFF_ID_COLINFO: importColInfo( rStrm ); break;
+ case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight( rStrm ); break;
+ case BIFF_ID_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_MERGEDCELLS: importMergedCells( rStrm ); break; // #i62300# also in BIFF5
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( rStrm ); break;
+ case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( rStrm ); break;
+ case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( rStrm ); break;
+ case BIFF_ID_SCENPROTECT: rWorksheetSett.importScenProtect( rStrm ); break;
+ case BIFF_ID_SCL: rSheetViewSett.importScl( rStrm ); break;
+ case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( rStrm ); break;
+ case BIFF_ID_STANDARDWIDTH: importStandardWidth( rStrm ); break;
+ case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( rStrm ); break;
+ case BIFF_ID_VCENTER: rPageSett.importVerCenter( rStrm ); break;
+ case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( rStrm ); break;
+ }
+ break;
+
+ case BIFF8: switch( nRecId )
+ {
+ case BIFF_ID_CFHEADER: rCondFormats.importCfHeader( rStrm ); break;
+ case BIFF_ID_COLINFO: importColInfo( rStrm ); break;
+ case BIFF_ID_DATAVALIDATION: importDataValidation( rStrm ); break;
+ case BIFF_ID_DATAVALIDATIONS: importDataValidations( rStrm ); break;
+ case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight( rStrm ); break;
+ case BIFF_ID_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_HYPERLINK: importHyperlink( rStrm ); break;
+ case BIFF_ID_LABELRANGES: importLabelRanges( rStrm ); break;
+ case BIFF_ID_MERGEDCELLS: importMergedCells( rStrm ); break;
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( rStrm ); break;
+ case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( rStrm ); break;
+ case BIFF_ID_SCENPROTECT: rWorksheetSett.importScenProtect( rStrm ); break;
+ case BIFF_ID_SCL: rSheetViewSett.importScl( rStrm ); break;
+ case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( rStrm ); break;
+ case BIFF_ID_SHEETPROTECTION: rWorksheetSett.importSheetProtection( rStrm ); break;
+ case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( rStrm ); break;
+ case BIFF_ID_PHONETICPR: rWorksheetSett.importPhoneticPr( rStrm ); break;
+ case BIFF_ID_STANDARDWIDTH: importStandardWidth( rStrm ); break;
+ case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( rStrm ); break;
+ case BIFF_ID_VCENTER: rPageSett.importVerCenter( rStrm ); break;
+ case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( rStrm ); break;
+ }
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+ }
+
+ // record not processed, try cell records
+ if( rStrm.getCoreStreamPos() == nStrmPos )
+ aSheetData.importRecord( rStrm );
+ }
+ }
+
+ // final processing in base class WorksheetHelper
+ finalizeWorksheetImport();
+ return rStrm.getRecId() == BIFF_ID_EOF;
+}
+
+// private --------------------------------------------------------------------
+
+void BiffWorksheetFragment::importColInfo( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFirstCol, nLastCol, nWidth, nXfId, nFlags;
+ rStrm >> nFirstCol >> nLastCol >> nWidth >> nXfId >> nFlags;
+
+ OoxColumnData aData;
+ // column indexes are 0-based in BIFF, but OoxColumnData expects 1-based
+ aData.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1;
+ aData.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1;
+ // width is stored as 1/256th of a character in BIFF, convert to entire character
+ aData.mfWidth = static_cast< double >( nWidth ) / 256.0;
+ aData.mnXfId = nXfId;
+ aData.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 );
+ aData.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN );
+ aData.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED );
+ // set column properties in the current sheet
+ setColumnData( aData );
+}
+
+void BiffWorksheetFragment::importColumnDefault( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFirstCol, nLastCol, nXfId;
+ rStrm >> nFirstCol >> nLastCol >> nXfId;
+ convertColumnFormat( nFirstCol, nLastCol, nXfId );
+}
+
+void BiffWorksheetFragment::importColWidth( BiffInputStream& rStrm )
+{
+ sal_uInt8 nFirstCol, nLastCol;
+ sal_uInt16 nWidth;
+ rStrm >> nFirstCol >> nLastCol >> nWidth;
+
+ OoxColumnData aData;
+ // column indexes are 0-based in BIFF, but OoxColumnData expects 1-based
+ aData.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1;
+ aData.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1;
+ // width is stored as 1/256th of a character in BIFF, convert to entire character
+ aData.mfWidth = static_cast< double >( nWidth ) / 256.0;
+ // set column properties in the current sheet
+ setColumnData( aData );
+}
+
+void BiffWorksheetFragment::importDefColWidth( BiffInputStream& rStrm )
+{
+ /* Stored as entire number of characters without padding pixels, which
+ will be added in setBaseColumnWidth(). Call has no effect, if a
+ width has already been set from the STANDARDWIDTH record. */
+ setBaseColumnWidth( rStrm.readuInt16() );
+}
+
+void BiffWorksheetFragment::importDefRowHeight( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags = BIFF_DEFROW_CUSTOMHEIGHT, nHeight;
+ if( getBiff() != BIFF2 )
+ rStrm >> nFlags;
+ rStrm >> nHeight;
+ if( getBiff() == BIFF2 )
+ nHeight &= BIFF2_DEFROW_MASK;
+ // row height is in twips in BIFF, convert to points
+ setDefaultRowSettings(
+ nHeight / 20.0,
+ getFlag( nFlags, BIFF_DEFROW_CUSTOMHEIGHT ),
+ getFlag( nFlags, BIFF_DEFROW_HIDDEN ),
+ getFlag( nFlags, BIFF_DEFROW_THICKTOP ),
+ getFlag( nFlags, BIFF_DEFROW_THICKBOTTOM ) );
+}
+
+void BiffWorksheetFragment::importDataValidations( BiffInputStream& rStrm )
+{
+ sal_Int32 nObjId;
+ rStrm.skip( 10 );
+ rStrm >> nObjId;
+ //! TODO: invalidate object id in drawing object manager
+}
+
+void BiffWorksheetFragment::importDataValidation( BiffInputStream& rStrm )
+{
+ OoxValidationData aData;
+
+ // flags
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+ aData.setBinType( extractValue< sal_uInt8 >( nFlags, 0, 4 ) );
+ aData.setBinOperator( extractValue< sal_uInt8 >( nFlags, 20, 4 ) );
+ aData.setBinErrorStyle( extractValue< sal_uInt8 >( nFlags, 4, 3 ) );
+ aData.mbAllowBlank = getFlag( nFlags, BIFF_DATAVAL_ALLOWBLANK );
+ aData.mbNoDropDown = getFlag( nFlags, BIFF_DATAVAL_NODROPDOWN );
+ aData.mbShowInputMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWINPUT );
+ aData.mbShowErrorMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWERROR );
+
+ /* Message strings. Empty strings are single NUL characters (string length
+ is 1). Do not let the stream replace them with '?' characters. */
+ rStrm.setNulSubstChar( '\0' );
+ aData.maInputTitle = rStrm.readUniString();
+ aData.maErrorTitle = rStrm.readUniString();
+ aData.maInputMessage = rStrm.readUniString();
+ aData.maErrorMessage = rStrm.readUniString();
+
+ /* Condition formula(s). String list is single tStr token with NUL
+ separators, replace them with LF characters. */
+ rStrm.setNulSubstChar( '\n' );
+ readDataValFormula( aData.maTokens1, rStrm );
+ readDataValFormula( aData.maTokens2, rStrm );
+ rStrm.setNulSubstChar(); // back to default
+ // process string list of a list validation (convert to list of string tokens)
+ if( (aData.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) )
+ getFormulaParser().convertStringToStringList( aData.maTokens1, '\n', true );
+
+ // cell range list
+ BinRangeList aRanges;
+ rStrm >> aRanges;
+ getAddressConverter().convertToCellRangeList( aData.maRanges, aRanges, getSheetIndex(), true );
+
+ // set validation data
+ setValidation( aData );
+}
+
+void BiffWorksheetFragment::importDimension( BiffInputStream& rStrm )
+{
+ BinRange aBinRange;
+ aBinRange.read( rStrm, true, (rStrm.getRecId() == BIFF3_ID_DIMENSION) && (getBiff() == BIFF8) );
+ // first unused row/column index in BIFF, not last used
+ if( aBinRange.maFirst.mnCol < aBinRange.maLast.mnCol ) --aBinRange.maLast.mnCol;
+ if( aBinRange.maFirst.mnRow < aBinRange.maLast.mnRow ) --aBinRange.maLast.mnRow;
+ // set dimension
+ CellRangeAddress aRange;
+ getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() );
+ setDimension( aRange );
+}
+
+void BiffWorksheetFragment::importHyperlink( BiffInputStream& rStrm )
+{
+ OoxHyperlinkData aData;
+
+ // read cell range for the hyperlink
+ BinRange aBiffRange;
+ rStrm >> aBiffRange;
+ // #i80006# Excel silently ignores invalid hi-byte of column index (TODO: everywhere?)
+ aBiffRange.maFirst.mnCol &= 0xFF;
+ aBiffRange.maLast.mnCol &= 0xFF;
+ if( !getAddressConverter().convertToCellRange( aData.maRange, aBiffRange, getSheetIndex(), true ) )
+ return;
+
+ BiffGuid aGuid;
+ sal_uInt32 nId, nFlags;
+ rStrm >> aGuid >> nId >> nFlags;
+
+ OSL_ENSURE( aGuid == BiffHelper::maGuidStdHlink, "BiffWorksheetFragment::importHyperlink - unexpected header GUID" );
+ OSL_ENSURE( nId == 2, "BiffWorksheetFragment::importHyperlink - unexpected header identifier" );
+ if( !(aGuid == BiffHelper::maGuidStdHlink) )
+ return;
+
+ // display string
+ if( getFlag( nFlags, BIFF_HYPERLINK_DISPLAY ) )
+ aData.maDisplay = readHyperlinkString( rStrm, true );
+ // target frame (ignore) !TODO: DISPLAY/FRAME - right order? (never seen them together)
+ if( getFlag( nFlags, BIFF_HYPERLINK_FRAME ) )
+ skipHyperlinkString( rStrm, true );
+
+ // target
+ if( getFlag( nFlags, BIFF_HYPERLINK_TARGET ) )
+ {
+ if( getFlag( nFlags, BIFF_HYPERLINK_UNC ) )
+ {
+ // UNC path
+ OSL_ENSURE( getFlag( nFlags, BIFF_HYPERLINK_ABS ), "BiffWorksheetFragment::importHyperlink - UNC link not absolute" );
+ aData.maTarget = readHyperlinkString( rStrm, true );
+ }
+ else
+ {
+ rStrm >> aGuid;
+ if( aGuid == BiffHelper::maGuidFileMoniker )
+ {
+ // file name, maybe relative and with directory up-count
+ sal_Int16 nUpLevels;
+ rStrm >> nUpLevels;
+ OSL_ENSURE( (nUpLevels == 0) || !getFlag( nFlags, BIFF_HYPERLINK_ABS ), "BiffWorksheetFragment::importHyperlink - absolute filename with upcount" );
+ OUString aShortName = readHyperlinkString( rStrm, false );
+ if( rStrm.skip( 24 ).readInt32() > 0 )
+ {
+ sal_Int32 nStrLen = rStrm.readInt32() / 2; // byte count to char count
+ rStrm.skip( 2 );
+ aData.maTarget = readHyperlinkString( rStrm, nStrLen, true );
+ }
+ if( aData.maTarget.getLength() == 0 )
+ aData.maTarget = aShortName;
+ if( !getFlag( nFlags, BIFF_HYPERLINK_ABS ) )
+ for( sal_uInt16 nLevel = 0; nLevel < nUpLevels; ++nLevel )
+ aData.maTarget = CREATE_OUSTRING( "..\\" ) + aData.maTarget;
+ }
+ else if( aGuid == BiffHelper::maGuidUrlMoniker )
+ {
+ // URL, maybe relative and with leading '../'
+ sal_Int32 nStrLen = rStrm.readInt32() / 2; // byte count to char count
+ aData.maTarget = readHyperlinkString( rStrm, nStrLen, true );
+ }
+ else
+ {
+ OSL_ENSURE( false, "BiffWorksheetFragment::importHyperlink - unknown content GUID" );
+ return;
+ }
+ }
+ }
+
+ // target location
+ if( getFlag( nFlags, BIFF_HYPERLINK_LOC ) )
+ aData.maLocation = readHyperlinkString( rStrm, true );
+
+ OSL_ENSURE( rStrm.getRecLeft() == 0, "BiffWorksheetFragment::importHyperlink - unknown record data" );
+
+ // try to read the SCREENTIP record
+ if( (rStrm.getNextRecId() == BIFF_ID_SCREENTIP) && rStrm.startNextRecord() )
+ {
+ rStrm.skip( 2 ); // repeated record id
+ // the cell range, again
+ rStrm >> aBiffRange;
+ CellRangeAddress aRange;
+ if( getAddressConverter().convertToCellRange( aRange, aBiffRange, getSheetIndex(), true ) &&
+ (aRange.StartColumn == aData.maRange.StartColumn) &&
+ (aRange.StartRow == aData.maRange.StartRow) &&
+ (aRange.EndColumn == aData.maRange.EndColumn) &&
+ (aRange.EndRow == aData.maRange.EndRow) )
+ {
+ /* This time, we have no string length, no flag field, and a
+ null-terminated 16-bit character array. */
+ aData.maTooltip = rStrm.readUnicodeArray( static_cast< sal_uInt16 >( rStrm.getRecLeft() / 2 ) );
+ }
+ }
+
+ // store the hyperlink settings
+ setHyperlink( aData );
+}
+
+void BiffWorksheetFragment::importLabelRanges( BiffInputStream& rStrm )
+{
+ BinRangeList aBiffRowRanges, aBiffColRanges;
+ rStrm >> aBiffRowRanges >> aBiffColRanges;
+ ApiCellRangeList aColRanges, aRowRanges;
+ getAddressConverter().convertToCellRangeList( aColRanges, aBiffColRanges, getSheetIndex(), true );
+ getAddressConverter().convertToCellRangeList( aRowRanges, aBiffRowRanges, getSheetIndex(), true );
+ setLabelRanges( aColRanges, aRowRanges );
+}
+
+void BiffWorksheetFragment::importMergedCells( BiffInputStream& rStrm )
+{
+ BinRangeList aBiffRanges;
+ rStrm >> aBiffRanges;
+ ApiCellRangeList aRanges;
+ getAddressConverter().convertToCellRangeList( aRanges, aBiffRanges, getSheetIndex(), true );
+ for( ApiCellRangeList::const_iterator aIt = aRanges.begin(), aEnd = aRanges.end(); aIt != aEnd; ++aIt )
+ setMergedRange( *aIt );
+}
+
+void BiffWorksheetFragment::importPageBreaks( BiffInputStream& rStrm, bool bRowBreak )
+{
+ OoxPageBreakData aData;
+ aData.mbManual = true; // only manual breaks stored in BIFF
+ bool bBiff8 = getBiff() == BIFF8; // skip start/end columns or rows in BIFF8
+
+ sal_uInt16 nCount;
+ rStrm >> nCount;
+ for( sal_uInt16 nIndex = 0; rStrm.isValid() && (nIndex < nCount); ++nIndex )
+ {
+ aData.mnColRow = rStrm.readuInt16();
+ setPageBreak( aData, bRowBreak );
+ if( bBiff8 )
+ rStrm.skip( 4 );
+ }
+}
+
+void BiffWorksheetFragment::importStandardWidth( BiffInputStream& rStrm )
+{
+ sal_uInt16 nWidth;
+ rStrm >> nWidth;
+ // width is stored as 1/256th of a character in BIFF, convert to entire character
+ double fWidth = static_cast< double >( nWidth ) / 256.0;
+ // set as default width, will override the width from DEFCOLWIDTH record
+ setDefaultColumnWidth( fWidth );
+}
+
+void BiffWorksheetFragment::readDataValFormula( ApiTokenSequence& orTokens, BiffInputStream& rStrm )
+{
+ sal_uInt16 nFmlaSize = rStrm.readuInt16();
+ rStrm.skip( 2 );
+ TokensFormulaContext aContext( true, false );
+ getFormulaParser().importFormula( aContext, rStrm, &nFmlaSize );
+ orTokens = aContext.getTokens();
+}
+
+OUString BiffWorksheetFragment::readHyperlinkString( BiffInputStream& rStrm, sal_Int32 nChars, bool bUnicode )
+{
+ OUString aRet;
+ if( nChars > 0 )
+ {
+ sal_uInt16 nReadChars = getLimitedValue< sal_uInt16, sal_Int32 >( nChars, 0, SAL_MAX_UINT16 );
+ aRet = bUnicode ?
+ rStrm.readUnicodeArray( nReadChars ) :
+ rStrm.readCharArray( nReadChars, getTextEncoding() );
+ // skip remaining chars
+ sal_uInt32 nSkip = static_cast< sal_uInt32 >( nChars - nReadChars );
+ rStrm.skip( bUnicode ? (nSkip * 2) : nSkip );
+ }
+ return aRet;
+}
+
+OUString BiffWorksheetFragment::readHyperlinkString( BiffInputStream& rStrm, bool bUnicode )
+{
+ return readHyperlinkString( rStrm, rStrm.readInt32(), bUnicode );
+}
+
+void BiffWorksheetFragment::skipHyperlinkString( BiffInputStream& rStrm, sal_Int32 nChars, bool bUnicode )
+{
+ if( nChars > 0 )
+ rStrm.skip( static_cast< sal_uInt32 >( bUnicode ? (nChars * 2) : nChars ) );
+}
+
+void BiffWorksheetFragment::skipHyperlinkString( BiffInputStream& rStrm, bool bUnicode )
+{
+ skipHyperlinkString( rStrm, rStrm.readInt32(), bUnicode );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx
new file mode 100644
index 000000000000..e6fdbd88d85a
--- /dev/null
+++ b/oox/source/xls/worksheethelper.cxx
@@ -0,0 +1,1652 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: worksheethelper.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheethelper.hxx"
+#include <utility>
+#include <list>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include <com/sun/star/sheet/XSheetOutline.hpp>
+#include <com/sun/star/sheet/XMultipleOperation.hpp>
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/condformatbuffer.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/ooxtokens.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/sharedformulabuffer.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+#include "oox/xls/validationpropertyhelper.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+#include "oox/xls/worksheetsettings.hxx"
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+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 ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::util::XMergeable;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::table::BorderLine;
+using ::com::sun::star::table::XColumnRowRange;
+using ::com::sun::star::table::XTableColumns;
+using ::com::sun::star::table::XTableRows;
+using ::com::sun::star::table::XCell;
+using ::com::sun::star::table::XCellRange;
+using ::com::sun::star::sheet::XSpreadsheet;
+using ::com::sun::star::sheet::XSheetCellRanges;
+using ::com::sun::star::sheet::XSheetCellRangeContainer;
+using ::com::sun::star::sheet::XCellAddressable;
+using ::com::sun::star::sheet::XCellRangeAddressable;
+using ::com::sun::star::sheet::XFormulaTokens;
+using ::com::sun::star::sheet::XSheetOutline;
+using ::com::sun::star::sheet::XMultipleOperation;
+using ::com::sun::star::sheet::XLabelRanges;
+using ::com::sun::star::text::XText;
+using ::com::sun::star::text::XTextContent;
+using ::com::sun::star::text::XTextRange;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+void lclUpdateProgressBar( ISegmentProgressBarRef xProgressBar, const CellRangeAddress& rDimension, sal_Int32 nRow )
+{
+ if( xProgressBar.get() && (rDimension.StartRow <= nRow) && (nRow <= rDimension.EndRow) )
+ {
+ double fPosition = static_cast< double >( nRow - rDimension.StartRow + 1 ) / (rDimension.EndRow - rDimension.StartRow + 1);
+ if( xProgressBar->getPosition() < fPosition )
+ xProgressBar->setPosition( fPosition );
+ }
+}
+
+} // namespace
+
+// ============================================================================
+// ============================================================================
+
+void OoxCellData::reset()
+{
+ mxCell.clear();
+ maValueStr = maFormulaRef = OUString();
+ mnCellType = mnFormulaType = XML_TOKEN_INVALID;
+ mnSharedId = mnXfId = mnNumFmtId = -1;
+ mbHasValueStr = mbShowPhonetic = false;
+}
+
+// ----------------------------------------------------------------------------
+
+OoxDataTableData::OoxDataTableData() :
+ mb2dTable( false ),
+ mbRowTable( false ),
+ mbRef1Deleted( false ),
+ mbRef2Deleted( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OoxColumnData::OoxColumnData() :
+ mnFirstCol( -1 ),
+ mnLastCol( -1 ),
+ mfWidth( 0.0 ),
+ mnXfId( -1 ),
+ mnLevel( 0 ),
+ mbHidden( false ),
+ mbCollapsed( false )
+{
+}
+
+bool OoxColumnData::tryExpand( const OoxColumnData& rNewData )
+{
+ bool bExpandable =
+ (mnFirstCol <= rNewData.mnFirstCol) &&
+ (rNewData.mnFirstCol <= mnLastCol + 1) &&
+ (mfWidth == rNewData.mfWidth) &&
+ // ignore mnXfId, cell formatting is always set directly
+ (mnLevel == rNewData.mnLevel) &&
+ (mbHidden == rNewData.mbHidden) &&
+ (mbCollapsed == rNewData.mbCollapsed);
+ if( bExpandable )
+ mnLastCol = rNewData.mnLastCol;
+ return bExpandable;
+}
+
+// ----------------------------------------------------------------------------
+
+OoxRowData::OoxRowData() :
+ mnFirstRow( -1 ),
+ mnLastRow( -1 ),
+ mfHeight( 0.0 ),
+ mnXfId( -1 ),
+ mnLevel( 0 ),
+ mbCustomHeight( false ),
+ mbCustomFormat( false ),
+ mbShowPhonetic( false ),
+ mbHidden( false ),
+ mbCollapsed( false ),
+ mbThickTop( false ),
+ mbThickBottom( false )
+{
+}
+
+bool OoxRowData::tryExpand( const OoxRowData& rNewData )
+{
+ bool bExpandable =
+ (mnFirstRow <= rNewData.mnFirstRow) &&
+ (rNewData.mnFirstRow <= mnLastRow + 1) &&
+ (mfHeight == rNewData.mfHeight) &&
+ // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly
+ (mnLevel == rNewData.mnLevel) &&
+ (mbCustomHeight == rNewData.mbCustomHeight) &&
+ (mbHidden == rNewData.mbHidden) &&
+ (mbCollapsed == rNewData.mbCollapsed);
+ if( bExpandable )
+ mnLastRow = rNewData.mnLastRow;
+ return bExpandable;
+}
+
+// ----------------------------------------------------------------------------
+
+OoxPageBreakData::OoxPageBreakData() :
+ mnColRow( 0 ),
+ mbManual( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OoxHyperlinkData::OoxHyperlinkData()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OoxValidationData::OoxValidationData() :
+ mnType( XML_none ),
+ mnOperator( XML_between ),
+ mnErrorStyle( XML_stop ),
+ mbShowInputMsg( false ),
+ mbShowErrorMsg( false ),
+ mbNoDropDown( false ),
+ mbAllowBlank( false )
+{
+}
+
+void OoxValidationData::setBinType( sal_uInt8 nType )
+{
+ static const sal_Int32 spnTypeIds[] = {
+ XML_none, XML_whole, XML_decimal, XML_list, XML_date, XML_time, XML_textLength, XML_custom };
+ mnType = STATIC_ARRAY_SELECT( spnTypeIds, nType, XML_none );
+}
+
+void OoxValidationData::setBinOperator( sal_uInt8 nOperator )
+{
+ static const sal_Int32 spnOperators[] = {
+ XML_between, XML_notBetween, XML_equal, XML_notEqual,
+ XML_greaterThan, XML_lessThan, XML_greaterThanOrEqual, XML_lessThanOrEqual };
+ mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
+}
+
+void OoxValidationData::setBinErrorStyle( sal_uInt8 nErrorStyle )
+{
+ static const sal_Int32 spnErrorStyles[] = { XML_stop, XML_warning, XML_information };
+ mnErrorStyle = STATIC_ARRAY_SELECT( spnErrorStyles, nErrorStyle, XML_stop );
+}
+
+// ============================================================================
+// ============================================================================
+
+class WorksheetData : public WorkbookHelper
+{
+public:
+ explicit WorksheetData(
+ const WorkbookHelper& rHelper,
+ ISegmentProgressBarRef xProgressBar,
+ WorksheetType eSheetType,
+ sal_Int32 nSheet );
+
+ /** Returns true, if this helper refers to an existing Calc sheet. */
+ inline bool isValidSheet() const { return mxSheet.is(); }
+
+ /** Returns a cell formula simulating an empty string result. */
+ inline const OUString& getEmptyStringFormula() const { return maEmptyStrFormula; }
+ /** Returns a cell formula simulating the passed boolean value. */
+ const OUString& getBooleanFormula( bool bValue ) const;
+
+ /** Returns the type of this sheet. */
+ inline WorksheetType getSheetType() const { return meSheetType; }
+ /** Returns the index of the current sheet. */
+ inline sal_Int16 getSheetIndex() const { return mnSheet; }
+ /** Returns the XSpreadsheet interface of the current sheet. */
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >&
+ getXSpreadsheet() const { return mxSheet; }
+
+ /** Returns the XCell interface for the passed cell address. */
+ Reference< XCell > getCell( const CellAddress& rAddress ) const;
+ /** Returns the XCellRange interface for the passed cell range address. */
+ Reference< XCellRange > getCellRange( const CellRangeAddress& rRange ) const;
+ /** Returns the XSheetCellRanges interface for the passed cell range addresses. */
+ Reference< XSheetCellRanges > getCellRangeList( const ApiCellRangeList& rRanges ) const;
+
+ /** Returns the XCellRange interface for a column. */
+ Reference< XCellRange > getColumn( sal_Int32 nCol ) const;
+ /** Returns the XCellRange interface for a row. */
+ Reference< XCellRange > getRow( sal_Int32 nRow ) const;
+
+ /** Returns the XTableColumns interface for a range of columns. */
+ Reference< XTableColumns > getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const;
+ /** Returns the XTableRows interface for a range of rows. */
+ Reference< XTableRows > getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const;
+
+ /** Returns the worksheet settings object. */
+ inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; }
+ /** Returns the buffer containing all shared formulas in this sheet. */
+ inline SharedFormulaBuffer& getSharedFormulas() { return maSharedFmlas; }
+ /** Returns the conditional formattings in this sheet. */
+ inline CondFormatBuffer& getCondFormats() { return maCondFormats; }
+ /** Returns the page/print settings for this sheet. */
+ inline PageSettings& getPageSettings() { return maPageSett; }
+ /** Returns the view settings for this sheet. */
+ inline SheetViewSettings& getSheetViewSettings() { return maSheetViewSett; }
+
+ /** Sets the dimension (used area) of the sheet. */
+ void setDimension( const CellRangeAddress& rRange );
+ /** Stores the cell format at the passed address. */
+ void setCellFormat( const OoxCellData& rCellData );
+ /** Merges the cells in the passed cell range. */
+ void setMergedRange( const CellRangeAddress& rRange );
+ /** Sets a column or row page break described in the passed struct. */
+ void setPageBreak( const OoxPageBreakData& rData, bool bRowBreak );
+ /** Inserts the hyperlink URL into the spreadsheet. */
+ void setHyperlink( const OoxHyperlinkData& rHyperlink );
+ /** Inserts the data validation settings into the spreadsheet. */
+ void setValidation( const OoxValidationData& rValData );
+
+ /** Sets base width for all columns (without padding pixels). This value
+ is only used, if base width has not been set with setDefaultColumnWidth(). */
+ void setBaseColumnWidth( sal_Int32 nWidth );
+ /** Sets default width for all columns. This function overrides the base
+ width set with the setBaseColumnWidth() function. */
+ void setDefaultColumnWidth( double fWidth );
+ /** Sets column settings for a specific column range.
+ @descr Column default formatting is converted directly, other settings
+ are cached and converted in the finalizeImport() call. */
+ void setColumnData( const OoxColumnData& rData );
+
+ /** Sets default height and hidden state for all unused rows in the sheet. */
+ void setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom );
+ /** Sets row settings for a specific row.
+ @descr Row default formatting is converted directly, other settings
+ are cached and converted in the finalizeImport() call. */
+ void setRowData( const OoxRowData& rData );
+
+ /** Converts column default cell formatting. */
+ void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId );
+ /** Converts row default cell formatting. */
+ void convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId );
+
+ /** Initial conversion before importing the worksheet. */
+ void initializeWorksheetImport();
+ /** Final conversion after importing the worksheet. */
+ void finalizeWorksheetImport();
+
+private:
+ typedef ::std::vector< sal_Int32 > OutlineLevelVec;
+ typedef ::std::map< sal_Int32, OoxColumnData > OoxColumnDataMap;
+ typedef ::std::map< sal_Int32, OoxRowData > OoxRowDataMap;
+ typedef ::std::list< OoxHyperlinkData > OoxHyperlinkList;
+ typedef ::std::list< OoxValidationData > OoxValidationList;
+
+ struct XfIdRange
+ {
+ CellRangeAddress maRange; /// The formatted cell range.
+ sal_Int32 mnXfId; /// XF identifier for the range.
+ sal_Int32 mnNumFmtId; /// Number format id overriding the XF.
+
+ void set( const OoxCellData& rCellData );
+ bool tryExpand( const OoxCellData& rCellData );
+ bool tryMerge( const XfIdRange& rXfIdRange );
+ };
+
+ struct MergedRange
+ {
+ CellRangeAddress maRange; /// The formatted cell range.
+ sal_Int32 mnHorAlign; /// Horizontal alignment in the range.
+
+ explicit MergedRange( const CellRangeAddress& rAddress );
+ explicit MergedRange( const CellAddress& rAddress, sal_Int32 nHorAlign );
+ bool tryExpand( const CellAddress& rAddress, sal_Int32 nHorAlign );
+ };
+
+ typedef ::std::pair< sal_Int32, sal_Int32 > RowColKey;
+ typedef ::std::map< RowColKey, XfIdRange > XfIdRangeMap;
+ typedef ::std::list< MergedRange > MergedRangeList;
+
+ /** Writes all cell formatting attributes to the passed cell range. */
+ void writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const;
+ /** Tries to merge the ranges last inserted in maXfIdRanges with existing ranges. */
+ void mergeXfIdRanges();
+ /** Finalizes the remaining ranges in maXfIdRanges. */
+ void finalizeXfIdRanges();
+
+ /** Inserts all imported hyperlinks into their cell ranges. */
+ void finalizeHyperlinkRanges() const;
+ /** Inserts a hyperlinks into the specified cell. */
+ void finalizeHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const;
+
+ /** Inserts all imported data validations into their cell ranges. */
+ void finalizeValidationRanges() const;
+
+ /** Merges all cached merged ranges and updates right/bottom cell borders. */
+ void finalizeMergedRanges() const;
+ /** Merges the passed merged range and updates right/bottom cell borders. */
+ void finalizeMergedRange( const CellRangeAddress& rRange ) const;
+
+ /** Converts column properties for all columns in the sheet. */
+ void convertColumns();
+ /** Converts column properties. */
+ void convertColumns( OutlineLevelVec& orColLevels, sal_Int32 nFirstCol, sal_Int32 nLastCol, const OoxColumnData& rData );
+
+ /** Converts row properties for all rows in the sheet. */
+ void convertRows();
+ /** Converts row properties. */
+ void convertRows( OutlineLevelVec& orRowLevels, sal_Int32 nFirstRow, sal_Int32 nLastRow, const OoxRowData& rData, double fDefHeight = -1.0 );
+
+ /** Converts outline grouping for the passed column or row. */
+ void convertOutlines( OutlineLevelVec& orLevels, sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows );
+ /** Groups columns or rows for the given range. */
+ void groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapsed, bool bRows );
+
+private:
+ const OUString maEmptyStrFormula; /// Replacement formula for empty string result.
+ const OUString maTrueFormula; /// Replacement formula for TRUE boolean cells.
+ const OUString maFalseFormula; /// Replacement formula for FALSE boolean cells.
+ const OUString maSheetCellRanges; /// Service name for a SheetCellRanges object.
+ const OUString maRightBorderProp; /// Property name of the right border of a cell.
+ const OUString maBottomBorderProp; /// Property name of the bottom border of a cell.
+ const OUString maWidthProp; /// Property name for column width.
+ const OUString maHeightProp; /// Property name for row height.
+ const OUString maVisibleProp; /// Property name for column/row visibility.
+ const OUString maPageBreakProp; /// Property name of a page break.
+ const OUString maUrlTextField; /// Service name for a URL text field.
+ const OUString maUrlProp; /// Property name for the URL string in a URL text field.
+ const OUString maReprProp; /// Property name for the URL representation in a URL text field.
+ const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter.
+ CellRangeAddress maDimension; /// Dimension (used) area of the sheet.
+ OoxColumnData maDefColData; /// Default column formatting.
+ OoxColumnDataMap maColDatas; /// Column data sorted by first column index.
+ OoxRowData maDefRowData; /// Default row formatting.
+ OoxRowDataMap maRowDatas; /// Row data sorted by row index.
+ OoxHyperlinkList maHyperlinks; /// Cell ranges containing hyperlinks.
+ OoxValidationList maValidations; /// Cell ranges containing data validation settings.
+ XfIdRangeMap maXfIdRanges; /// Collected XF identifiers for cell ranges.
+ MergedRangeList maMergedRanges; /// Merged cell ranges.
+ MergedRangeList maCenterFillRanges; /// Merged cell ranges from 'center across' or 'fill' alignment.
+ WorksheetSettings maSheetSett; /// Global settings for this sheet.
+ SharedFormulaBuffer maSharedFmlas; /// Buffer for shared formulas in this sheet.
+ CondFormatBuffer maCondFormats; /// Buffer for conditional formattings.
+ PageSettings maPageSett; /// Page/print settings for this sheet.
+ SheetViewSettings maSheetViewSett; /// View settings for this sheet.
+ ISegmentProgressBarRef mxProgressBar; /// Sheet progress bar.
+ ISegmentProgressBarRef mxRowProgress; /// Progress bar for row/cell processing.
+ ISegmentProgressBarRef mxFinalProgress; /// Progress bar for finalization.
+ const WorksheetType meSheetType; /// Type of thes sheet.
+ Reference< XSpreadsheet > mxSheet; /// Reference to the current sheet.
+ sal_Int16 mnSheet; /// Index of the current sheet.
+ bool mbHasDefWidth; /// True = default column width is set from defaultColWidth attribute.
+};
+
+// ----------------------------------------------------------------------------
+
+WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) :
+ WorkbookHelper( rHelper ),
+ maEmptyStrFormula( CREATE_OUSTRING( "=\"\"" ) ),
+ maTrueFormula( CREATE_OUSTRING( "=TRUE()" ) ),
+ maFalseFormula( CREATE_OUSTRING( "=FALSE()" ) ),
+ maSheetCellRanges( CREATE_OUSTRING( "com.sun.star.sheet.SheetCellRanges" ) ),
+ maRightBorderProp( CREATE_OUSTRING( "RightBorder" ) ),
+ maBottomBorderProp( CREATE_OUSTRING( "BottomBorder" ) ),
+ maWidthProp( CREATE_OUSTRING( "Width" ) ),
+ maHeightProp( CREATE_OUSTRING( "Height" ) ),
+ maVisibleProp( CREATE_OUSTRING( "IsVisible" ) ),
+ maPageBreakProp( CREATE_OUSTRING( "IsStartOfNewPage" ) ),
+ maUrlTextField( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ),
+ maUrlProp( CREATE_OUSTRING( "URL" ) ),
+ maReprProp( CREATE_OUSTRING( "Representation" ) ),
+ mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ),
+ maSheetSett( WorksheetHelper( *this ) ),
+ maSharedFmlas( WorksheetHelper( *this ) ),
+ maCondFormats( WorksheetHelper( *this ) ),
+ maPageSett( WorksheetHelper( *this ) ),
+ maSheetViewSett( WorksheetHelper( *this ) ),
+ mxProgressBar( xProgressBar ),
+ meSheetType( eSheetType ),
+ mnSheet( static_cast< sal_Int16 >( nSheet ) ),
+ mbHasDefWidth( false )
+{
+ OSL_ENSURE( nSheet <= SAL_MAX_INT16, "WorksheetData::WorksheetData - invalid sheet index" );
+ mxSheet = getSheet( nSheet );
+ if( !mxSheet.is() )
+ mnSheet = -1;
+
+ maDimension.Sheet = mnSheet;
+
+ // default column settings (width and hidden state may be updated later)
+ maDefColData.mfWidth = 8.5;
+ maDefColData.mnXfId = -1;
+ maDefColData.mnLevel = 0;
+ maDefColData.mbHidden = false;
+ maDefColData.mbCollapsed = false;
+
+ // default row settings (height and hidden state may be updated later)
+ maDefRowData.mfHeight = 0.0;
+ maDefRowData.mnXfId = -1;
+ maDefRowData.mnLevel = 0;
+ maDefRowData.mbCustomHeight = false;
+ maDefRowData.mbCustomFormat = false;
+ maDefRowData.mbShowPhonetic = false;
+ maDefRowData.mbHidden = false;
+ maDefRowData.mbCollapsed = false;
+
+ if( mxProgressBar.get() )
+ {
+ mxRowProgress = mxProgressBar->createSegment( 0.5 );
+ mxFinalProgress = mxProgressBar->createSegment( 0.5 );
+ }
+}
+
+const OUString& WorksheetData::getBooleanFormula( bool bValue ) const
+{
+ return bValue ? maTrueFormula : maFalseFormula;
+}
+
+Reference< XCell > WorksheetData::getCell( const CellAddress& rAddress ) const
+{
+ Reference< XCell > xCell;
+ if( mxSheet.is() ) try
+ {
+ xCell = mxSheet->getCellByPosition( rAddress.Column, rAddress.Row );
+ }
+ catch( Exception& )
+ {
+ }
+ return xCell;
+}
+
+Reference< XCellRange > WorksheetData::getCellRange( const CellRangeAddress& rRange ) const
+{
+ Reference< XCellRange > xRange;
+ if( mxSheet.is() ) try
+ {
+ xRange = mxSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
+ }
+ catch( Exception& )
+ {
+ }
+ return xRange;
+}
+
+Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRangeList& rRanges ) const
+{
+ Reference< XSheetCellRanges > xRanges;
+ if( mxSheet.is() && !rRanges.empty() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW );
+ xRanges.set( xFactory->createInstance( maSheetCellRanges ), UNO_QUERY_THROW );
+ Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW );
+ xRangeCont->addRangeAddresses( ContainerHelper::vectorToSequence( rRanges ), sal_False );
+ }
+ catch( Exception& )
+ {
+ }
+ return xRanges;
+}
+
+Reference< XCellRange > WorksheetData::getColumn( sal_Int32 nCol ) const
+{
+ Reference< XCellRange > xColumn;
+ try
+ {
+ Reference< XColumnRowRange > xColRowRange( mxSheet, UNO_QUERY_THROW );
+ Reference< XTableColumns > xColumns = xColRowRange->getColumns();
+ if( xColumns.is() )
+ xColumn.set( xColumns->getByIndex( nCol ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xColumn;
+}
+
+Reference< XCellRange > WorksheetData::getRow( sal_Int32 nRow ) const
+{
+ Reference< XCellRange > xRow;
+ try
+ {
+ Reference< XColumnRowRange > xColRowRange( mxSheet, UNO_QUERY_THROW );
+ Reference< XTableRows > xRows = xColRowRange->getRows();
+ xRow.set( xRows->getByIndex( nRow ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xRow;
+}
+
+Reference< XTableColumns > WorksheetData::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const
+{
+ Reference< XTableColumns > xColumns;
+ nLastCol = ::std::min( nLastCol, mrMaxApiPos.Column );
+ if( (0 <= nFirstCol) && (nFirstCol <= nLastCol) )
+ {
+ Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( mnSheet, nFirstCol, 0, nLastCol, 0 ) ), UNO_QUERY );
+ if( xRange.is() )
+ xColumns = xRange->getColumns();
+ }
+ return xColumns;
+}
+
+Reference< XTableRows > WorksheetData::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const
+{
+ Reference< XTableRows > xRows;
+ nLastRow = ::std::min( nLastRow, mrMaxApiPos.Row );
+ if( (0 <= nFirstRow) && (nFirstRow <= nLastRow) )
+ {
+ Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( mnSheet, 0, nFirstRow, 0, nLastRow ) ), UNO_QUERY );
+ if( xRange.is() )
+ xRows = xRange->getRows();
+ }
+ return xRows;
+}
+
+void WorksheetData::setDimension( const CellRangeAddress& rRange )
+{
+ maDimension = rRange;
+}
+
+void WorksheetData::setCellFormat( const OoxCellData& rCellData )
+{
+ if( rCellData.mxCell.is() && (rCellData.mnXfId >= 0) || (rCellData.mnNumFmtId >= 0) )
+ {
+ // try to merge existing ranges and to write some formatting properties
+ if( !maXfIdRanges.empty() )
+ {
+ // get row index of last inserted cell
+ sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow;
+ // row changed - try to merge ranges of last row with existing ranges
+ if( rCellData.maAddress.Row != nLastRow )
+ {
+ mergeXfIdRanges();
+ // write format properties of all ranges above last row and remove them
+ XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end();
+ while( aIt != aEnd )
+ {
+ if( aIt->second.maRange.EndRow < nLastRow )
+ {
+ writeXfIdRangeProperties( aIt->second );
+ maXfIdRanges.erase( aIt++ );
+ }
+ else
+ ++aIt;
+ }
+ }
+ }
+
+ // try to expand last existing range, or create new range entry
+ if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rCellData ) )
+ maXfIdRanges[ RowColKey( rCellData.maAddress.Row, rCellData.maAddress.Column ) ].set( rCellData );
+
+ // update merged ranges for 'center across selection' and 'fill'
+ if( const Xf* pXf = getStyles().getCellXf( rCellData.mnXfId ).get() )
+ {
+ sal_Int32 nHorAlign = pXf->getAlignment().getOoxData().mnHorAlign;
+ if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) )
+ {
+ /* start new merged range, if cell is not empty (#108781#),
+ or try to expand last range with empty cell */
+ if( rCellData.mnCellType != XML_TOKEN_INVALID )
+ maCenterFillRanges.push_back( MergedRange( rCellData.maAddress, nHorAlign ) );
+ else if( !maCenterFillRanges.empty() )
+ maCenterFillRanges.rbegin()->tryExpand( rCellData.maAddress, nHorAlign );
+ }
+ }
+ }
+}
+
+void WorksheetData::setMergedRange( const CellRangeAddress& rRange )
+{
+ maMergedRanges.push_back( MergedRange( rRange ) );
+}
+
+void WorksheetData::setPageBreak( const OoxPageBreakData& rData, bool bRowBreak )
+{
+ if( rData.mbManual && (rData.mnColRow > 0) )
+ {
+ PropertySet aPropSet( bRowBreak ? getRow( rData.mnColRow ) : getColumn( rData.mnColRow ) );
+ aPropSet.setProperty( maPageBreakProp, true );
+ }
+}
+
+void WorksheetData::setHyperlink( const OoxHyperlinkData& rHyperlink )
+{
+ maHyperlinks.push_back( rHyperlink );
+}
+
+void WorksheetData::setValidation( const OoxValidationData& rValData )
+{
+ maValidations.push_back( rValData );
+}
+
+void WorksheetData::setBaseColumnWidth( sal_Int32 nWidth )
+{
+ // do not modify width, if setDefaultColumnWidth() has been used
+ if( !mbHasDefWidth && (nWidth > 0) )
+ {
+ /* #i3006# add 5 pixels padding to the width, assuming 1 pixel =
+ 1/96 inch. => 5/96 inch == 1.32 mm. */
+ const UnitConverter& rUnitConv = getUnitConverter();
+ maDefColData.mfWidth = rUnitConv.calcDigitsFromMm100( rUnitConv.calcMm100FromDigits( nWidth ) + 132 );
+ }
+}
+
+void WorksheetData::setDefaultColumnWidth( double fWidth )
+{
+ // overrides a width set with setBaseColumnWidth()
+ if( fWidth > 0.0 )
+ {
+ maDefColData.mfWidth = fWidth;
+ mbHasDefWidth = true;
+ }
+}
+
+void WorksheetData::setColumnData( const OoxColumnData& rData )
+{
+ // convert 1-based OOX column indexes to 0-based API column indexes
+ sal_Int32 nFirstCol = rData.mnFirstCol - 1;
+ sal_Int32 nLastCol = rData.mnLastCol - 1;
+ if( (0 <= nFirstCol) && (nFirstCol <= mrMaxApiPos.Column) )
+ {
+ // set column formatting directly, nLastCol is checked inside the function
+ convertColumnFormat( nFirstCol, nLastCol, rData.mnXfId );
+ // expand last entry or add new entry
+ if( maColDatas.empty() || !maColDatas.rbegin()->second.tryExpand( rData ) )
+ maColDatas[ nFirstCol ] = rData;
+ }
+}
+
+void WorksheetData::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
+{
+ maDefRowData.mfHeight = fHeight;
+ maDefRowData.mbCustomHeight = bCustomHeight;
+ maDefRowData.mbHidden = bHidden;
+ maDefRowData.mbThickTop = bThickTop;
+ maDefRowData.mbThickBottom = bThickBottom;
+}
+
+void WorksheetData::setRowData( const OoxRowData& rData )
+{
+ // convert 1-based OOX row indexes to 0-based API row indexes
+ sal_Int32 nFirstRow = rData.mnFirstRow - 1;
+ sal_Int32 nLastRow = rData.mnLastRow - 1;
+ if( (0 <= nFirstRow) && (nFirstRow <= mrMaxApiPos.Row) )
+ {
+ // set row formatting directly
+ if( rData.mbCustomFormat )
+ convertRowFormat( nFirstRow, nLastRow, rData.mnXfId );
+ // expand last entry or add new entry
+ if( maRowDatas.empty() || !maRowDatas.rbegin()->second.tryExpand( rData ) )
+ maRowDatas[ nFirstRow ] = rData;
+ }
+ lclUpdateProgressBar( mxRowProgress, maDimension, nLastRow );
+}
+
+void WorksheetData::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId )
+{
+ CellRangeAddress aRange( mnSheet, nFirstCol, 0, nLastCol, mrMaxApiPos.Row );
+ if( getAddressConverter().validateCellRange( aRange, false ) )
+ {
+ PropertySet aPropSet( getCellRange( aRange ) );
+ getStyles().writeCellXfToPropertySet( aPropSet, nXfId );
+ }
+}
+
+void WorksheetData::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId )
+{
+ CellRangeAddress aRange( mnSheet, 0, nFirstRow, mrMaxApiPos.Column, nLastRow );
+ if( getAddressConverter().validateCellRange( aRange, false ) )
+ {
+ PropertySet aPropSet( getCellRange( aRange ) );
+ getStyles().writeCellXfToPropertySet( aPropSet, nXfId );
+ }
+}
+
+void WorksheetData::initializeWorksheetImport()
+{
+#if OOX_XLS_USE_DEFAULT_STYLE
+#else
+ // set default cell style for unused cells
+ PropertySet aPropSet( mxSheet );
+ aPropSet.setProperty( CREATE_OUSTRING( "CellStyle" ), getStyles().getDefaultStyleName() );
+#endif
+}
+
+void WorksheetData::finalizeWorksheetImport()
+{
+ finalizeXfIdRanges();
+ finalizeHyperlinkRanges();
+ finalizeValidationRanges();
+ finalizeMergedRanges();
+ maCondFormats.finalizeImport();
+ maPageSett.finalizeImport();
+ maSheetViewSett.finalizeImport();
+ convertColumns();
+ convertRows();
+}
+
+// private --------------------------------------------------------------------
+
+void WorksheetData::XfIdRange::set( const OoxCellData& rCellData )
+{
+ maRange.Sheet = rCellData.maAddress.Sheet;
+ maRange.StartColumn = maRange.EndColumn = rCellData.maAddress.Column;
+ maRange.StartRow = maRange.EndRow = rCellData.maAddress.Row;
+ mnXfId = rCellData.mnXfId;
+ mnNumFmtId = rCellData.mnNumFmtId;
+}
+
+bool WorksheetData::XfIdRange::tryExpand( const OoxCellData& rCellData )
+{
+ if( (mnXfId == rCellData.mnXfId) && (mnNumFmtId == rCellData.mnNumFmtId) &&
+ (maRange.StartRow == rCellData.maAddress.Row) &&
+ (maRange.EndRow == rCellData.maAddress.Row) &&
+ (maRange.EndColumn + 1 == rCellData.maAddress.Column) )
+ {
+ ++maRange.EndColumn;
+ return true;
+ }
+ return false;
+}
+
+bool WorksheetData::XfIdRange::tryMerge( const XfIdRange& rXfIdRange )
+{
+ if( (mnXfId == rXfIdRange.mnXfId) &&
+ (mnNumFmtId == rXfIdRange.mnNumFmtId) &&
+ (maRange.EndRow + 1 == rXfIdRange.maRange.StartRow) &&
+ (maRange.StartColumn == rXfIdRange.maRange.StartColumn) &&
+ (maRange.EndColumn == rXfIdRange.maRange.EndColumn) )
+ {
+ maRange.EndRow = rXfIdRange.maRange.EndRow;
+ return true;
+ }
+ return false;
+}
+
+
+WorksheetData::MergedRange::MergedRange( const CellRangeAddress& rRange ) :
+ maRange( rRange ),
+ mnHorAlign( XML_TOKEN_INVALID )
+{
+}
+
+WorksheetData::MergedRange::MergedRange( const CellAddress& rAddress, sal_Int32 nHorAlign ) :
+ maRange( rAddress.Sheet, rAddress.Column, rAddress.Row, rAddress.Column, rAddress.Row ),
+ mnHorAlign( nHorAlign )
+{
+}
+
+bool WorksheetData::MergedRange::tryExpand( const CellAddress& rAddress, sal_Int32 nHorAlign )
+{
+ if( (mnHorAlign == nHorAlign) && (maRange.StartRow == rAddress.Row) &&
+ (maRange.EndRow == rAddress.Row) && (maRange.EndColumn + 1 == rAddress.Column) )
+ {
+ ++maRange.EndColumn;
+ return true;
+ }
+ return false;
+}
+
+void WorksheetData::writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const
+{
+ StylesBuffer& rStyles = getStyles();
+ PropertySet aPropSet( getCellRange( rXfIdRange.maRange ) );
+ if( rXfIdRange.mnXfId >= 0 )
+ rStyles.writeCellXfToPropertySet( aPropSet, rXfIdRange.mnXfId );
+ if( rXfIdRange.mnNumFmtId >= 0 )
+ rStyles.writeNumFmtToPropertySet( aPropSet, rXfIdRange.mnNumFmtId );
+}
+
+void WorksheetData::mergeXfIdRanges()
+{
+ if( !maXfIdRanges.empty() )
+ {
+ // get row index of last range
+ sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow;
+ // process all ranges located in the same row of the last range
+ XfIdRangeMap::iterator aMergeIt = maXfIdRanges.end();
+ while( (aMergeIt != maXfIdRanges.begin()) && ((--aMergeIt)->second.maRange.StartRow == nLastRow) )
+ {
+ const XfIdRange& rMergeXfIdRange = aMergeIt->second;
+ // try to find a range that can be merged with rMergeRange
+ bool bFound = false;
+ for( XfIdRangeMap::iterator aIt = maXfIdRanges.begin(); !bFound && (aIt != aMergeIt); ++aIt )
+ if( (bFound = aIt->second.tryMerge( rMergeXfIdRange )) == true )
+ maXfIdRanges.erase( aMergeIt++ );
+ }
+ }
+}
+
+void WorksheetData::finalizeXfIdRanges()
+{
+ // try to merge remaining inserted ranges
+ mergeXfIdRanges();
+ // write all formatting
+ sal_Int32 nLastRow = -1;
+ for( XfIdRangeMap::const_iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); aIt != aEnd; ++aIt )
+ {
+ writeXfIdRangeProperties( aIt->second );
+ if( aIt->first.first > nLastRow )
+ lclUpdateProgressBar( mxFinalProgress, maDimension, nLastRow = aIt->first.first );
+ }
+}
+
+void WorksheetData::finalizeHyperlinkRanges() const
+{
+ for( OoxHyperlinkList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt )
+ {
+ OUStringBuffer aUrlBuffer( getBaseFilter().getAbsoluteUrl( aIt->maTarget ) );
+ if( aIt->maLocation.getLength() > 0 )
+ aUrlBuffer.append( sal_Unicode( '#' ) ).append( aIt->maLocation );
+ OUString aUrl = aUrlBuffer.makeStringAndClear();
+ 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 renamed sheets
+ 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 aFinalName = getWorksheets().getFinalSheetName( aSheetName );
+ if( aFinalName.getLength() > 0 )
+ aUrl = aUrl.replaceAt( nNamePos, nNameLen, aFinalName );
+ }
+ }
+
+ // 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 );
+ }
+ }
+}
+
+void WorksheetData::finalizeHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const
+{
+ Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY );
+ Reference< XCell > xCell = getCell( rAddress );
+ Reference< XText > xText( xCell, UNO_QUERY );
+ // hyperlinks only supported in text cells
+ if( xFactory.is() && xCell.is() && (xCell->getType() == ::com::sun::star::table::CellContentType_TEXT) && xText.is() )
+ {
+ // create a URL field object and set its properties
+ Reference< XTextContent > xUrlField( xFactory->createInstance( maUrlTextField ), UNO_QUERY );
+ OSL_ENSURE( xUrlField.is(), "WorksheetData::finalizeHyperlink - cannot create text field" );
+ if( xUrlField.is() )
+ {
+ // properties of the URL field
+ PropertySet aPropSet( xUrlField );
+ aPropSet.setProperty( maUrlProp, rUrl );
+ aPropSet.setProperty( maReprProp, xText->getString() );
+ try
+ {
+ // insert the field into the cell
+ xText->setString( OUString() );
+ Reference< XTextRange > xRange( xText->createTextCursor(), UNO_QUERY_THROW );
+ xText->insertTextContent( xRange, xUrlField, sal_False );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( false, "WorksheetData::finalizeHyperlink - cannot insert text field" );
+ }
+ }
+ }
+}
+
+void WorksheetData::finalizeValidationRanges() const
+{
+ ValidationPropertyHelper& rPropHelper = getValidationPropertyHelper();
+ for( OoxValidationList::const_iterator aIt = maValidations.begin(), aEnd = maValidations.end(); aIt != aEnd; ++aIt )
+ {
+ PropertySet aPropSet( getCellRangeList( aIt->maRanges ) );
+ rPropHelper.writeValidationProperties( aPropSet, *aIt );
+ }
+}
+
+void WorksheetData::finalizeMergedRanges() const
+{
+ MergedRangeList::const_iterator aIt, aEnd;
+ for( aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt )
+ finalizeMergedRange( aIt->maRange );
+ for( aIt = maCenterFillRanges.begin(), aEnd = maCenterFillRanges.end(); aIt != aEnd; ++aIt )
+ finalizeMergedRange( aIt->maRange );
+}
+
+void WorksheetData::finalizeMergedRange( const CellRangeAddress& rRange ) const
+{
+ bool bMultiCol = rRange.StartColumn < rRange.EndColumn;
+ bool bMultiRow = rRange.StartRow < rRange.EndRow;
+
+ if( bMultiCol || bMultiRow ) try
+ {
+ // merge the cell range
+ Reference< XMergeable > xMerge( getCellRange( rRange ), UNO_QUERY_THROW );
+ xMerge->merge( sal_True );
+
+ // if merging this range worked (no overlapping merged ranges), update cell borders
+ PropertySet aTopLeft( getCell( CellAddress( mnSheet, rRange.StartColumn, rRange.StartRow ) ) );
+
+ // copy right border of top-right cell to right border of top-left cell
+ if( bMultiCol )
+ {
+ PropertySet aTopRight( getCell( CellAddress( mnSheet, rRange.EndColumn, rRange.StartRow ) ) );
+ BorderLine aLine;
+ if( aTopRight.getProperty( aLine, maRightBorderProp ) )
+ aTopLeft.setProperty( maRightBorderProp, aLine );
+ }
+
+ // copy bottom border of bottom-left cell to bottom border of top-left cell
+ if( bMultiRow )
+ {
+ PropertySet aBottomLeft( getCell( CellAddress( mnSheet, rRange.StartColumn, rRange.EndRow ) ) );
+ BorderLine aLine;
+ if( aBottomLeft.getProperty( aLine, maBottomBorderProp ) )
+ aTopLeft.setProperty( maBottomBorderProp, aLine );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void WorksheetData::convertColumns()
+{
+ sal_Int32 nNextCol = 0;
+ sal_Int32 nMaxCol = mrMaxApiPos.Column;
+ // stores first grouped column index for each level
+ OutlineLevelVec aColLevels;
+
+ for( OoxColumnDataMap::const_iterator aIt = maColDatas.begin(), aEnd = maColDatas.end(); aIt != aEnd; ++aIt )
+ {
+ // convert 1-based OOX column indexes to 0-based API column indexes
+ sal_Int32 nFirstCol = ::std::max( aIt->second.mnFirstCol - 1, nNextCol );
+ sal_Int32 nLastCol = ::std::min( aIt->second.mnLastCol - 1, nMaxCol );
+
+ // process gap between two column datas, use default column data
+ if( nNextCol < nFirstCol )
+ convertColumns( aColLevels, nNextCol, nFirstCol - 1, maDefColData );
+ // process the column data
+ convertColumns( aColLevels, nFirstCol, nLastCol, aIt->second );
+
+ // cache next column to be processed
+ nNextCol = nLastCol + 1;
+ }
+
+ // remaining default columns to end of sheet
+ convertColumns( aColLevels, nNextCol, nMaxCol, maDefColData );
+ // close remaining column outlines spanning to end of sheet
+ convertOutlines( aColLevels, nMaxCol + 1, 0, false, false );
+}
+
+void WorksheetData::convertColumns( OutlineLevelVec& orColLevels,
+ sal_Int32 nFirstCol, sal_Int32 nLastCol, const OoxColumnData& rData )
+{
+ Reference< XTableColumns > xColumns = getColumns( nFirstCol, nLastCol );
+ if( xColumns.is() )
+ {
+ PropertySet aPropSet( xColumns );
+ // column width: convert 'number of characters' to column width in 1/100 mm
+ sal_Int32 nWidth = getUnitConverter().calcMm100FromDigits( rData.mfWidth );
+ if( nWidth > 0 )
+ aPropSet.setProperty( maWidthProp, nWidth );
+ // hidden columns: TODO: #108683# hide columns later?
+ if( rData.mbHidden )
+ aPropSet.setProperty( maVisibleProp, false );
+ }
+ // outline settings for this column range
+ convertOutlines( orColLevels, nFirstCol, rData.mnLevel, rData.mbCollapsed, false );
+}
+
+void WorksheetData::convertRows()
+{
+ sal_Int32 nNextRow = 0;
+ sal_Int32 nMaxRow = mrMaxApiPos.Row;
+ // stores first grouped row index for each level
+ OutlineLevelVec aRowLevels;
+
+ for( OoxRowDataMap::const_iterator aIt = maRowDatas.begin(), aEnd = maRowDatas.end(); aIt != aEnd; ++aIt )
+ {
+ // convert 1-based OOX row indexes to 0-based API row indexes
+ sal_Int32 nFirstRow = ::std::max( aIt->second.mnFirstRow - 1, nNextRow );
+ sal_Int32 nLastRow = ::std::min( aIt->second.mnLastRow - 1, nMaxRow );
+
+ // process gap between two row datas, use default row data
+ if( nNextRow < nFirstRow )
+ convertRows( aRowLevels, nNextRow, nFirstRow - 1, maDefRowData );
+ // process the row data
+ convertRows( aRowLevels, nFirstRow, nLastRow, aIt->second, maDefRowData.mfHeight );
+
+ // cache next row to be processed
+ nNextRow = nLastRow + 1;
+ }
+
+ // remaining default rows to end of sheet
+ convertRows( aRowLevels, nNextRow, nMaxRow, maDefRowData );
+ // close remaining row outlines spanning to end of sheet
+ convertOutlines( aRowLevels, nMaxRow + 1, 0, false, true );
+}
+
+void WorksheetData::convertRows( OutlineLevelVec& orRowLevels,
+ sal_Int32 nFirstRow, sal_Int32 nLastRow, const OoxRowData& rData, double fDefHeight )
+{
+ Reference< XTableRows > xRows = getRows( nFirstRow, nLastRow );
+ if( xRows.is() )
+ {
+ PropertySet aPropSet( xRows );
+ /* Row height:
+ - convert points to row height in 1/100 mm
+ - ignore rData.mbCustomHeight, Excel does not set optimal height
+ correctly, if a merged cell contains multi-line text.
+ */
+ double fHeight = (rData.mfHeight >= 0.0) ? rData.mfHeight : fDefHeight;
+ sal_Int32 nHeight = getUnitConverter().calcMm100FromPoints( fHeight );
+ if( nHeight > 0 )
+ aPropSet.setProperty( maHeightProp, nHeight );
+ // hidden rows: TODO: #108683# hide rows later?
+ if( rData.mbHidden )
+ aPropSet.setProperty( maVisibleProp, false );
+ }
+ // outline settings for this row range
+ convertOutlines( orRowLevels, nFirstRow, rData.mnLevel, rData.mbCollapsed, true );
+}
+
+void WorksheetData::convertOutlines( OutlineLevelVec& orLevels,
+ sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows )
+{
+ /* It is ensured from caller functions, that this function is called
+ without any gaps between the processed column or row ranges. */
+
+ OSL_ENSURE( nLevel >= 0, "WorksheetData::convertOutlines - negative outline level" );
+ nLevel = ::std::max< sal_Int32 >( nLevel, 0 );
+
+ sal_Int32 nSize = orLevels.size();
+ if( nSize < nLevel )
+ {
+ // Outline level increased. Push the begin column position.
+ for( sal_Int32 nIndex = nSize; nIndex < nLevel; ++nIndex )
+ orLevels.push_back( nColRow );
+ }
+ else if( nLevel < nSize )
+ {
+ // Outline level decreased. Pop them all out.
+ for( sal_Int32 nIndex = nLevel; nIndex < nSize; ++nIndex )
+ {
+ sal_Int32 nFirstInLevel = orLevels.back();
+ orLevels.pop_back();
+ groupColumnsOrRows( nFirstInLevel, nColRow - 1, bCollapsed, bRows );
+ bCollapsed = false; // collapse only once
+ }
+ }
+}
+
+void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows )
+{
+ try
+ {
+ Reference< XSheetOutline > xOutline( mxSheet, UNO_QUERY_THROW );
+ if( bRows )
+ {
+ CellRangeAddress aRange( mnSheet, 0, nFirstColRow, 0, nLastColRow );
+ xOutline->group( aRange, ::com::sun::star::table::TableOrientation_ROWS );
+ if( bCollapse )
+ xOutline->hideDetail( aRange );
+ }
+ else
+ {
+ CellRangeAddress aRange( mnSheet, nFirstColRow, 0, nLastColRow, 0 );
+ xOutline->group( aRange, ::com::sun::star::table::TableOrientation_COLUMNS );
+ if( bCollapse )
+ xOutline->hideDetail( aRange );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+WorksheetHelper::WorksheetHelper( WorksheetData& rSheetData ) :
+ WorkbookHelper( rSheetData ),
+ mrSheetData( rSheetData )
+{
+}
+
+WorksheetType WorksheetHelper::getSheetType() const
+{
+ return mrSheetData.getSheetType();
+}
+
+sal_Int16 WorksheetHelper::getSheetIndex() const
+{
+ return mrSheetData.getSheetIndex();
+}
+
+const Reference< XSpreadsheet >& WorksheetHelper::getXSpreadsheet() const
+{
+ return mrSheetData.getXSpreadsheet();
+}
+
+Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const
+{
+ return mrSheetData.getCell( rAddress );
+}
+
+Reference< XCell > WorksheetHelper::getCell( const OUString& rAddressStr, CellAddress* opAddress ) const
+{
+ CellAddress aAddress;
+ if( getAddressConverter().convertToCellAddress( aAddress, rAddressStr, mrSheetData.getSheetIndex(), true ) )
+ {
+ if( opAddress ) *opAddress = aAddress;
+ return mrSheetData.getCell( aAddress );
+ }
+ return Reference< XCell >();
+}
+
+Reference< XCell > WorksheetHelper::getCell( const BinAddress& rBinAddress, CellAddress* opAddress ) const
+{
+ CellAddress aAddress;
+ if( getAddressConverter().convertToCellAddress( aAddress, rBinAddress, mrSheetData.getSheetIndex(), true ) )
+ {
+ if( opAddress ) *opAddress = aAddress;
+ return mrSheetData.getCell( aAddress );
+ }
+ return Reference< XCell >();
+}
+
+Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const
+{
+ return mrSheetData.getCellRange( rRange );
+}
+
+Reference< XCellRange > WorksheetHelper::getCellRange( const OUString& rRangeStr, CellRangeAddress* opRange ) const
+{
+ CellRangeAddress aRange;
+ if( getAddressConverter().convertToCellRange( aRange, rRangeStr, mrSheetData.getSheetIndex(), true ) )
+ {
+ if( opRange ) *opRange = aRange;
+ return mrSheetData.getCellRange( aRange );
+ }
+ return Reference< XCellRange >();
+}
+
+Reference< XCellRange > WorksheetHelper::getCellRange( const BinRange& rBinRange, CellRangeAddress* opRange ) const
+{
+ CellRangeAddress aRange;
+ if( getAddressConverter().convertToCellRange( aRange, rBinRange, mrSheetData.getSheetIndex(), true ) )
+ {
+ if( opRange ) *opRange = aRange;
+ return mrSheetData.getCellRange( aRange );
+ }
+ return Reference< XCellRange >();
+}
+
+Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( const ApiCellRangeList& rRanges ) const
+{
+ return mrSheetData.getCellRangeList( rRanges );
+}
+
+Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList(
+ const OUString& rRangesStr, ApiCellRangeList* opRanges ) const
+{
+ ApiCellRangeList aRanges;
+ getAddressConverter().convertToCellRangeList( aRanges, rRangesStr, mrSheetData.getSheetIndex(), true );
+ if( opRanges ) *opRanges = aRanges;
+ return mrSheetData.getCellRangeList( aRanges );
+}
+
+Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList(
+ const BinRangeList& rBinRanges, ApiCellRangeList* opRanges ) const
+{
+ ApiCellRangeList aRanges;
+ getAddressConverter().convertToCellRangeList( aRanges, rBinRanges, mrSheetData.getSheetIndex(), true );
+ if( opRanges ) *opRanges = aRanges;
+ return mrSheetData.getCellRangeList( aRanges );
+}
+
+CellAddress WorksheetHelper::getCellAddress( const Reference< XCell >& rxCell )
+{
+ CellAddress aAddress;
+ Reference< XCellAddressable > xAddressable( rxCell, UNO_QUERY );
+ OSL_ENSURE( xAddressable.is(), "WorksheetHelper::getCellAddress - cell reference not addressable" );
+ if( xAddressable.is() )
+ aAddress = xAddressable->getCellAddress();
+ return aAddress;
+}
+
+CellRangeAddress WorksheetHelper::getRangeAddress( const Reference< XCellRange >& rxRange )
+{
+ CellRangeAddress aRange;
+ Reference< XCellRangeAddressable > xAddressable( rxRange, UNO_QUERY );
+ OSL_ENSURE( xAddressable.is(), "WorksheetHelper::getRangeAddress - cell range reference not addressable" );
+ if( xAddressable.is() )
+ aRange = xAddressable->getRangeAddress();
+ return aRange;
+}
+
+Reference< XCellRange > WorksheetHelper::getColumn( sal_Int32 nCol ) const
+{
+ return mrSheetData.getColumn( nCol );
+}
+
+Reference< XCellRange > WorksheetHelper::getRow( sal_Int32 nRow ) const
+{
+ return mrSheetData.getRow( nRow );
+}
+
+Reference< XTableColumns > WorksheetHelper::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const
+{
+ return mrSheetData.getColumns( nFirstCol, nLastCol );
+}
+
+Reference< XTableRows > WorksheetHelper::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const
+{
+ return mrSheetData.getRows( nFirstRow, nLastRow );
+}
+
+WorksheetSettings& WorksheetHelper::getWorksheetSettings() const
+{
+ return mrSheetData.getWorksheetSettings();
+}
+
+SharedFormulaBuffer& WorksheetHelper::getSharedFormulas() const
+{
+ return mrSheetData.getSharedFormulas();
+}
+
+CondFormatBuffer& WorksheetHelper::getCondFormats() const
+{
+ return mrSheetData.getCondFormats();
+}
+
+PageSettings& WorksheetHelper::getPageSettings() const
+{
+ return mrSheetData.getPageSettings();
+}
+
+SheetViewSettings& WorksheetHelper::getSheetViewSettings() const
+{
+ return mrSheetData.getSheetViewSettings();
+}
+
+void WorksheetHelper::setEmptyStringCell( const Reference< XCell >& rxCell ) const
+{
+ OSL_ENSURE( rxCell.is(), "WorksheetHelper::setEmptyStringCell - missing cell interface" );
+ rxCell->setFormula( mrSheetData.getEmptyStringFormula() );
+}
+
+void WorksheetHelper::setStringCell( const Reference< XCell >& rxCell, const OUString& rText, bool bEmptyStringAsFormula ) const
+{
+ if( bEmptyStringAsFormula && (rText.getLength() == 0) )
+ {
+ setEmptyStringCell( rxCell );
+ }
+ else
+ {
+ OSL_ENSURE( rxCell.is(), "WorksheetHelper::setStringCell - missing cell interface" );
+ Reference< XText > xText( rxCell, UNO_QUERY );
+ if( xText.is() )
+ xText->setString( rText );
+ }
+}
+
+void WorksheetHelper::setSharedStringCell( const Reference< XCell >& rxCell, sal_Int32 nStringId, sal_Int32 nXfId ) const
+{
+ OSL_ENSURE( rxCell.is(), "WorksheetHelper::setSharedStringCell - missing cell interface" );
+ getSharedStrings().convertString( Reference< XText >( rxCell, UNO_QUERY ), nStringId, nXfId );
+}
+
+void WorksheetHelper::setBooleanCell( const Reference< XCell >& rxCell, bool bValue ) const
+{
+ OSL_ENSURE( rxCell.is(), "WorksheetHelper::setBooleanCell - missing cell interface" );
+ rxCell->setFormula( mrSheetData.getBooleanFormula( bValue ) );
+}
+
+void WorksheetHelper::setErrorCell( const Reference< XCell >& rxCell, const OUString& rErrorCode ) const
+{
+ setErrorCell( rxCell, getUnitConverter().calcBiffErrorCode( rErrorCode ) );
+}
+
+void WorksheetHelper::setErrorCell( const Reference< XCell >& rxCell, sal_uInt8 nErrorCode ) const
+{
+ Reference< XFormulaTokens > xTokens( rxCell, UNO_QUERY );
+ OSL_ENSURE( xTokens.is(), "WorksheetHelper::setErrorCell - missing cell interface" );
+ if( xTokens.is() )
+ {
+ SimpleFormulaContext aContext( xTokens, false, false );
+ getFormulaParser().convertErrorToFormula( aContext, nErrorCode );
+ }
+}
+
+void WorksheetHelper::setOoxCell( OoxCellData& orCellData, bool bEmptyStringAsFormula ) const
+{
+ OSL_ENSURE( orCellData.mxCell.is(), "WorksheetHelper::setCell - missing cell interface" );
+ if( orCellData.mbHasValueStr ) switch( orCellData.mnCellType )
+ {
+ case XML_b:
+ setBooleanCell( orCellData.mxCell, orCellData.maValueStr.toDouble() != 0.0 );
+ // #108770# set 'Standard' number format for all Boolean cells
+ orCellData.mnNumFmtId = 0;
+ break;
+ case XML_n:
+ orCellData.mxCell->setValue( orCellData.maValueStr.toDouble() );
+ break;
+ case XML_e:
+ setErrorCell( orCellData.mxCell, orCellData.maValueStr );
+ break;
+ case XML_str:
+ setStringCell( orCellData.mxCell, orCellData.maValueStr, bEmptyStringAsFormula );
+ break;
+ case XML_s:
+ setSharedStringCell( orCellData.mxCell, orCellData.maValueStr.toInt32(), orCellData.mnXfId );
+ break;
+ }
+}
+
+void WorksheetHelper::setDimension( const CellRangeAddress& rRange )
+{
+ mrSheetData.setDimension( rRange );
+}
+
+void WorksheetHelper::setCellFormat( const OoxCellData& rCellData )
+{
+ mrSheetData.setCellFormat( rCellData );
+}
+
+void WorksheetHelper::setMergedRange( const CellRangeAddress& rRange )
+{
+ mrSheetData.setMergedRange( rRange );
+}
+
+void WorksheetHelper::setPageBreak( const OoxPageBreakData& rData, bool bRowBreak )
+{
+ mrSheetData.setPageBreak( rData, bRowBreak );
+}
+
+void WorksheetHelper::setHyperlink( const OoxHyperlinkData& rHyperlink )
+{
+ mrSheetData.setHyperlink( rHyperlink );
+}
+
+void WorksheetHelper::setValidation( const OoxValidationData& rValData )
+{
+ mrSheetData.setValidation( rValData );
+}
+
+void WorksheetHelper::setTableOperation( const CellRangeAddress& rRange, const OoxDataTableData& rTableData ) const
+{
+ OSL_ENSURE( getAddressConverter().checkCellRange( rRange, false ), "WorksheetHelper::setTableOperation - invalid range" );
+ bool bOk = false;
+ if( !rTableData.mbRef1Deleted && (rTableData.maRef1.getLength() > 0) && (rRange.StartColumn > 0) && (rRange.StartRow > 0) )
+ {
+ CellRangeAddress aOpRange = rRange;
+ CellAddress aRef1, aRef2;
+ if( getAddressConverter().convertToCellAddress( aRef1, rTableData.maRef1, mrSheetData.getSheetIndex(), true ) ) try
+ {
+ if( rTableData.mb2dTable )
+ {
+ if( !rTableData.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rTableData.maRef2, mrSheetData.getSheetIndex(), true ) )
+ {
+ // API call expects input values inside operation range
+ --aOpRange.StartColumn;
+ --aOpRange.StartRow;
+ // formula range is top-left cell of operation range
+ CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow );
+ // set multiple operation
+ Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW );
+ xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_BOTH, aRef2, aRef1 );
+ bOk = true;
+ }
+ }
+ else if( rTableData.mbRowTable )
+ {
+ // formula range is column to the left of operation range
+ CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow );
+ // API call expects input values (top row) inside operation range
+ --aOpRange.StartRow;
+ // set multiple operation
+ Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW );
+ xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_ROW, aRef1, aRef1 );
+ bOk = true;
+ }
+ else
+ {
+ // formula range is row above operation range
+ CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 );
+ // API call expects input values (left column) inside operation range
+ --aOpRange.StartColumn;
+ // set multiple operation
+ Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW );
+ xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_COLUMN, aRef1, aRef1 );
+ bOk = true;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ // on error: fill cell range with error codes
+ if( !bOk )
+ {
+ for( CellAddress aPos( mrSheetData.getSheetIndex(), rRange.StartColumn, rRange.StartRow ); aPos.Row <= rRange.EndRow; ++aPos.Row )
+ for( aPos.Column = rRange.StartColumn; aPos.Column <= rRange.EndColumn; ++aPos.Column )
+ setErrorCell( mrSheetData.getCell( aPos ), BIFF_ERR_REF );
+ }
+}
+
+void WorksheetHelper::setLabelRanges( const ApiCellRangeList& rColRanges, const ApiCellRangeList& rRowRanges )
+{
+ const CellAddress& rMaxPos = getAddressConverter().getMaxApiAddress();
+ Reference< XLabelRanges > xLabelRanges;
+ PropertySet aPropSet( getXSpreadsheet() );
+
+ if( !rColRanges.empty() && aPropSet.getProperty( xLabelRanges, CREATE_OUSTRING( "ColumnLabelRanges" ) ) && xLabelRanges.is() )
+ {
+ for( ApiCellRangeList::const_iterator aIt = rColRanges.begin(), aEnd = rColRanges.end(); aIt != aEnd; ++aIt )
+ {
+ CellRangeAddress aDataRange = *aIt;
+ if( aDataRange.EndRow < rMaxPos.Row )
+ {
+ aDataRange.StartRow = aDataRange.EndRow + 1;
+ aDataRange.EndRow = rMaxPos.Row;
+ }
+ else if( aDataRange.StartRow > 0 )
+ {
+ aDataRange.EndRow = aDataRange.StartRow - 1;
+ aDataRange.StartRow = 0;
+ }
+ xLabelRanges->addNew( *aIt, aDataRange );
+ }
+ }
+
+ if( !rRowRanges.empty() && aPropSet.getProperty( xLabelRanges, CREATE_OUSTRING( "RowLabelRanges" ) ) && xLabelRanges.is() )
+ {
+ for( ApiCellRangeList::const_iterator aIt = rRowRanges.begin(), aEnd = rRowRanges.end(); aIt != aEnd; ++aIt )
+ {
+ CellRangeAddress aDataRange = *aIt;
+ if( aDataRange.EndColumn < rMaxPos.Column )
+ {
+ aDataRange.StartColumn = aDataRange.EndColumn + 1;
+ aDataRange.EndColumn = rMaxPos.Column;
+ }
+ else if( aDataRange.StartColumn > 0 )
+ {
+ aDataRange.EndColumn = aDataRange.StartColumn - 1;
+ aDataRange.StartColumn = 0;
+ }
+ xLabelRanges->addNew( *aIt, aDataRange );
+ }
+ }
+}
+
+void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth )
+{
+ mrSheetData.setBaseColumnWidth( nWidth );
+}
+
+void WorksheetHelper::setDefaultColumnWidth( double fWidth )
+{
+ mrSheetData.setDefaultColumnWidth( fWidth );
+}
+
+void WorksheetHelper::setColumnData( const OoxColumnData& rData )
+{
+ mrSheetData.setColumnData( rData );
+}
+
+void WorksheetHelper::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
+{
+ mrSheetData.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom );
+}
+
+void WorksheetHelper::setRowData( const OoxRowData& rData )
+{
+ mrSheetData.setRowData( rData );
+}
+
+void WorksheetHelper::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId )
+{
+ mrSheetData.convertColumnFormat( nFirstCol, nLastCol, nXfId );
+}
+
+void WorksheetHelper::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId )
+{
+ mrSheetData.convertRowFormat( nFirstRow, nLastRow, nXfId );
+}
+
+void WorksheetHelper::initializeWorksheetImport()
+{
+ mrSheetData.initializeWorksheetImport();
+}
+
+void WorksheetHelper::finalizeWorksheetImport()
+{
+ mrSheetData.finalizeWorksheetImport();
+}
+
+// ============================================================================
+
+namespace prv {
+
+WorksheetDataOwner::WorksheetDataOwner( WorksheetDataRef xSheetData ) :
+ mxSheetData( xSheetData )
+{
+}
+
+WorksheetDataOwner::~WorksheetDataOwner()
+{
+}
+
+} // namespace prv
+
+// ----------------------------------------------------------------------------
+
+WorksheetHelperRoot::WorksheetHelperRoot( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) :
+ prv::WorksheetDataOwner( prv::WorksheetDataRef( new WorksheetData( rHelper, xProgressBar, eSheetType, nSheet ) ) ),
+ WorksheetHelper( *mxSheetData )
+{
+}
+
+WorksheetHelperRoot::WorksheetHelperRoot( const WorksheetHelper& rHelper ) :
+ prv::WorksheetDataOwner( prv::WorksheetDataRef() ),
+ WorksheetHelper( rHelper )
+{
+}
+
+WorksheetHelperRoot::WorksheetHelperRoot( const WorksheetHelperRoot& rHelper ) :
+ prv::WorksheetDataOwner( rHelper.mxSheetData ),
+ WorksheetHelper( rHelper )
+{
+}
+
+bool WorksheetHelperRoot::isValidSheet() const
+{
+ return mxSheetData->isValidSheet();
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
diff --git a/oox/source/xls/worksheetsettings.cxx b/oox/source/xls/worksheetsettings.cxx
new file mode 100644
index 000000000000..d827fc1ff70d
--- /dev/null
+++ b/oox/source/xls/worksheetsettings.cxx
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: worksheetsettings.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: rt $ $Date: 2008-01-17 08:06:10 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheetsettings.hxx"
+#include <com/sun/star/util/XProtectable.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::util::XProtectable;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 BIFF_SHEETPR_APPLYSTYLES = 0x0020;
+const sal_uInt16 BIFF_SHEETPR_SYMBOLSBELOW = 0x0040;
+const sal_uInt16 BIFF_SHEETPR_SYMBOLSRIGHT = 0x0080;
+const sal_uInt16 BIFF_SHEETPR_FITTOPAGES = 0x0100;
+const sal_uInt16 BIFF_SHEETPR_SKIPEXT = 0x0200; /// BIFF3-BIFF4
+
+const sal_uInt16 BIFF_SHEETPROT_OBJECTS = 0x0001;
+const sal_uInt16 BIFF_SHEETPROT_SCENARIOS = 0x0002;
+const sal_uInt16 BIFF_SHEETPROT_FORMAT_CELLS = 0x0004;
+const sal_uInt16 BIFF_SHEETPROT_FORMAT_COLUMNS = 0x0008;
+const sal_uInt16 BIFF_SHEETPROT_FORMAT_ROWS = 0x0010;
+const sal_uInt16 BIFF_SHEETPROT_INSERT_COLUMNS = 0x0020;
+const sal_uInt16 BIFF_SHEETPROT_INSERT_ROWS = 0x0040;
+const sal_uInt16 BIFF_SHEETPROT_INSERT_HLINKS = 0x0080;
+const sal_uInt16 BIFF_SHEETPROT_DELETE_COLUMNS = 0x0100;
+const sal_uInt16 BIFF_SHEETPROT_DELETE_ROWS = 0x0200;
+const sal_uInt16 BIFF_SHEETPROT_SELECT_LOCKED = 0x0400;
+const sal_uInt16 BIFF_SHEETPROT_SORT = 0x0800;
+const sal_uInt16 BIFF_SHEETPROT_AUTOFILTER = 0x1000;
+const sal_uInt16 BIFF_SHEETPROT_PIVOTTABLES = 0x2000;
+const sal_uInt16 BIFF_SHEETPROT_SELECT_UNLOCKED = 0x4000;
+
+} // namespace
+
+// ============================================================================
+
+OoxOutlinePrData::OoxOutlinePrData() :
+ mbApplyStyles( false ),
+ mbSummaryBelow( true ),
+ mbSummaryRight( true )
+{
+}
+
+// ============================================================================
+
+OoxSheetProtectionData::OoxSheetProtectionData() :
+ mnPasswordHash( 0 ),
+ mbSheet( false ),
+ mbObjects( false ),
+ mbScenarios( false ),
+ mbFormatCells( true ),
+ mbFormatColumns( true ),
+ mbFormatRows( true ),
+ mbInsertColumns( true ),
+ mbInsertRows( true ),
+ mbInsertHyperlinks( true ),
+ mbDeleteColumns( true ),
+ mbDeleteRows( true ),
+ mbSelectLocked( false ),
+ mbSort( true ),
+ mbAutoFilter( true ),
+ mbPivotTables( true ),
+ mbSelectUnlocked( false )
+{
+}
+
+// ============================================================================
+
+WorksheetSettings::WorksheetSettings( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper ),
+ maPhoneticSett( rHelper )
+{
+}
+
+void WorksheetSettings::importOutlinePr( const AttributeList& rAttribs )
+{
+ maOoxOutlineData.mbApplyStyles = rAttribs.getBool( XML_applyStyles, false );
+ maOoxOutlineData.mbSummaryBelow = rAttribs.getBool( XML_summaryBelow, true );
+ maOoxOutlineData.mbSummaryRight = rAttribs.getBool( XML_summaryRight, true );
+}
+
+void WorksheetSettings::importSheetProtection( const AttributeList& rAttribs )
+{
+ sal_Int32 nHash = rAttribs.getHex( XML_password, 0 );
+ OSL_ENSURE( (0 <= nHash) && (nHash <= SAL_MAX_UINT16), "WorksheetSettings::importSheetProtection - invalid password hash" );
+ maOoxProtData.mnPasswordHash = static_cast< sal_uInt16 >( nHash );
+ maOoxProtData.mbSheet = rAttribs.getBool( XML_sheet, false );
+ maOoxProtData.mbObjects = rAttribs.getBool( XML_objects, false );
+ maOoxProtData.mbScenarios = rAttribs.getBool( XML_scenarios, false );
+ maOoxProtData.mbFormatCells = rAttribs.getBool( XML_formatCells, true );
+ maOoxProtData.mbFormatColumns = rAttribs.getBool( XML_formatColumns, true );
+ maOoxProtData.mbFormatRows = rAttribs.getBool( XML_formatRows, true );
+ maOoxProtData.mbInsertColumns = rAttribs.getBool( XML_insertColumns, true );
+ maOoxProtData.mbInsertRows = rAttribs.getBool( XML_insertRows, true );
+ maOoxProtData.mbInsertHyperlinks = rAttribs.getBool( XML_insertHyperlinks, true );
+ maOoxProtData.mbDeleteColumns = rAttribs.getBool( XML_deleteColumns, true );
+ maOoxProtData.mbDeleteRows = rAttribs.getBool( XML_deleteRows, true );
+ maOoxProtData.mbSelectLocked = rAttribs.getBool( XML_selectLockedCells, false );
+ maOoxProtData.mbSort = rAttribs.getBool( XML_sort, true );
+ maOoxProtData.mbAutoFilter = rAttribs.getBool( XML_autoFilter, true );
+ maOoxProtData.mbPivotTables = rAttribs.getBool( XML_pivotTables, true );
+ maOoxProtData.mbSelectUnlocked = rAttribs.getBool( XML_selectUnlockedCells, false );
+}
+
+void WorksheetSettings::importPhoneticPr( const AttributeList& rAttribs )
+{
+ maPhoneticSett.importPhoneticPr( rAttribs );
+}
+
+void WorksheetSettings::importSheetPr( RecordInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ // outline settings, equal flags in BIFF and OOBIN
+ maOoxOutlineData.mbApplyStyles = getFlag( nFlags, BIFF_SHEETPR_APPLYSTYLES );
+ maOoxOutlineData.mbSummaryRight = getFlag( nFlags, BIFF_SHEETPR_SYMBOLSRIGHT );
+ maOoxOutlineData.mbSummaryBelow = getFlag( nFlags, BIFF_SHEETPR_SYMBOLSBELOW );
+ /* Fit printout to width/height - for whatever reason, this flag is still
+ stored separated from the page settings */
+ getPageSettings().setFitToPagesMode( getFlag( nFlags, BIFF_SHEETPR_FITTOPAGES ) );
+}
+
+void WorksheetSettings::importSheetProtection( RecordInputStream& rStrm )
+{
+ rStrm >> maOoxProtData.mnPasswordHash;
+ // no flags field for all these boolean flags?!?
+ maOoxProtData.mbSheet = rStrm.readInt32() != 0;
+ maOoxProtData.mbObjects = rStrm.readInt32() != 0;
+ maOoxProtData.mbScenarios = rStrm.readInt32() != 0;
+ maOoxProtData.mbFormatCells = rStrm.readInt32() != 0;
+ maOoxProtData.mbFormatColumns = rStrm.readInt32() != 0;
+ maOoxProtData.mbFormatRows = rStrm.readInt32() != 0;
+ maOoxProtData.mbInsertColumns = rStrm.readInt32() != 0;
+ maOoxProtData.mbInsertRows = rStrm.readInt32() != 0;
+ maOoxProtData.mbInsertHyperlinks = rStrm.readInt32() != 0;
+ maOoxProtData.mbDeleteColumns = rStrm.readInt32() != 0;
+ maOoxProtData.mbDeleteRows = rStrm.readInt32() != 0;
+ maOoxProtData.mbSelectLocked = rStrm.readInt32() != 0;
+ maOoxProtData.mbSort = rStrm.readInt32() != 0;
+ maOoxProtData.mbAutoFilter = rStrm.readInt32() != 0;
+ maOoxProtData.mbPivotTables = rStrm.readInt32() != 0;
+ maOoxProtData.mbSelectUnlocked = rStrm.readInt32() != 0;
+}
+
+void WorksheetSettings::importPhoneticPr( RecordInputStream& rStrm )
+{
+ maPhoneticSett.importPhoneticPr( rStrm );
+}
+
+void WorksheetSettings::importSheetPr( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ // outline settings
+ maOoxOutlineData.mbApplyStyles = getFlag( nFlags, BIFF_SHEETPR_APPLYSTYLES );
+ maOoxOutlineData.mbSummaryRight = getFlag( nFlags, BIFF_SHEETPR_SYMBOLSRIGHT );
+ maOoxOutlineData.mbSummaryBelow = getFlag( nFlags, BIFF_SHEETPR_SYMBOLSBELOW );
+ // fit printout to width/height
+ getPageSettings().setFitToPagesMode( getFlag( nFlags, BIFF_SHEETPR_FITTOPAGES ) );
+ // save external linked values, in BIFF5-BIFF8 moved to BOOKBOOK record
+ if( getBiff() <= BIFF4 )
+ getWorkbookSettings().setSaveExtLinkValues( !getFlag( nFlags, BIFF_SHEETPR_SKIPEXT ) );
+}
+
+void WorksheetSettings::importProtect( BiffInputStream& rStrm )
+{
+ maOoxProtData.mbSheet = rStrm.readuInt16() != 0;
+}
+
+void WorksheetSettings::importObjectProtect( BiffInputStream& rStrm )
+{
+ maOoxProtData.mbObjects = rStrm.readuInt16() != 0;
+}
+
+void WorksheetSettings::importScenProtect( BiffInputStream& rStrm )
+{
+ maOoxProtData.mbScenarios = rStrm.readuInt16() != 0;
+}
+
+void WorksheetSettings::importPassword( BiffInputStream& rStrm )
+{
+ rStrm >> maOoxProtData.mnPasswordHash;
+}
+
+void WorksheetSettings::importSheetProtection( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags = rStrm.skip( 19 ).readuInt16();
+ // set flag means protection is disabled
+ maOoxProtData.mbObjects = !getFlag( nFlags, BIFF_SHEETPROT_OBJECTS );
+ maOoxProtData.mbScenarios = !getFlag( nFlags, BIFF_SHEETPROT_SCENARIOS );
+ maOoxProtData.mbFormatCells = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_CELLS );
+ maOoxProtData.mbFormatColumns = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_COLUMNS );
+ maOoxProtData.mbFormatRows = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_ROWS );
+ maOoxProtData.mbInsertColumns = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_COLUMNS );
+ maOoxProtData.mbInsertRows = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_ROWS );
+ maOoxProtData.mbInsertHyperlinks = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_HLINKS );
+ maOoxProtData.mbDeleteColumns = !getFlag( nFlags, BIFF_SHEETPROT_DELETE_COLUMNS );
+ maOoxProtData.mbDeleteRows = !getFlag( nFlags, BIFF_SHEETPROT_DELETE_ROWS );
+ maOoxProtData.mbSelectLocked = !getFlag( nFlags, BIFF_SHEETPROT_SELECT_LOCKED );
+ maOoxProtData.mbSort = !getFlag( nFlags, BIFF_SHEETPROT_SORT );
+ maOoxProtData.mbAutoFilter = !getFlag( nFlags, BIFF_SHEETPROT_AUTOFILTER );
+ maOoxProtData.mbPivotTables = !getFlag( nFlags, BIFF_SHEETPROT_PIVOTTABLES );
+ maOoxProtData.mbSelectUnlocked = !getFlag( nFlags, BIFF_SHEETPROT_SELECT_UNLOCKED );
+}
+
+void WorksheetSettings::importPhoneticPr( BiffInputStream& rStrm )
+{
+ maPhoneticSett.importPhoneticPr( rStrm );
+}
+
+void WorksheetSettings::finalizeImport()
+{
+ if( maOoxProtData.mbSheet )
+ {
+ Reference< XProtectable > xProtectable( getXSpreadsheet(), UNO_QUERY );
+ if( xProtectable.is() )
+ xProtectable->protect( OUString() );
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+