summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
Diffstat (limited to 'oox')
-rw-r--r--oox/inc/oox/core/binarycodec.hxx321
-rw-r--r--oox/inc/oox/core/binaryfilterbase.hxx62
-rw-r--r--oox/inc/oox/core/contexthandler.hxx118
-rw-r--r--oox/inc/oox/core/contexthandler2.hxx274
-rwxr-xr-xoox/inc/oox/core/fastparser.hxx93
-rw-r--r--oox/inc/oox/core/fasttokenhandler.hxx73
-rw-r--r--oox/inc/oox/core/filterbase.hxx310
-rw-r--r--oox/inc/oox/core/filterdetect.hxx167
-rw-r--r--oox/inc/oox/core/fragmenthandler.hxx136
-rw-r--r--oox/inc/oox/core/fragmenthandler2.hxx113
-rw-r--r--oox/inc/oox/core/recordparser.hxx96
-rwxr-xr-xoox/inc/oox/core/relations.hxx108
-rw-r--r--oox/inc/oox/core/relationshandler.hxx60
-rw-r--r--oox/inc/oox/core/xmlfilterbase.hxx229
-rw-r--r--oox/inc/oox/dllapi.h39
-rw-r--r--oox/inc/oox/drawingml/chart/axiscontext.hxx126
-rw-r--r--oox/inc/oox/drawingml/chart/axisconverter.hxx70
-rw-r--r--oox/inc/oox/drawingml/chart/axismodel.hxx111
-rw-r--r--oox/inc/oox/drawingml/chart/chartcontextbase.hxx101
-rw-r--r--oox/inc/oox/drawingml/chart/chartconverter.hxx110
-rw-r--r--oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx122
-rw-r--r--oox/inc/oox/drawingml/chart/chartspaceconverter.hxx63
-rw-r--r--oox/inc/oox/drawingml/chart/chartspacefragment.hxx61
-rw-r--r--oox/inc/oox/drawingml/chart/chartspacemodel.hxx78
-rw-r--r--oox/inc/oox/drawingml/chart/converterbase.hxx158
-rw-r--r--oox/inc/oox/drawingml/chart/datasourcecontext.hxx100
-rw-r--r--oox/inc/oox/drawingml/chart/datasourceconverter.hxx77
-rw-r--r--oox/inc/oox/drawingml/chart/datasourcemodel.hxx71
-rw-r--r--oox/inc/oox/drawingml/chart/modelbase.hxx140
-rw-r--r--oox/inc/oox/drawingml/chart/objectformatter.hxx171
-rw-r--r--oox/inc/oox/drawingml/chart/plotareacontext.hxx89
-rw-r--r--oox/inc/oox/drawingml/chart/plotareaconverter.hxx109
-rw-r--r--oox/inc/oox/drawingml/chart/plotareamodel.hxx93
-rw-r--r--oox/inc/oox/drawingml/chart/seriescontext.hxx272
-rw-r--r--oox/inc/oox/drawingml/chart/seriesconverter.hxx173
-rw-r--r--oox/inc/oox/drawingml/chart/seriesmodel.hxx243
-rw-r--r--oox/inc/oox/drawingml/chart/titlecontext.hxx89
-rw-r--r--oox/inc/oox/drawingml/chart/titleconverter.hxx112
-rw-r--r--oox/inc/oox/drawingml/chart/titlemodel.hxx95
-rw-r--r--oox/inc/oox/drawingml/chart/typegroupcontext.hxx170
-rw-r--r--oox/inc/oox/drawingml/chart/typegroupconverter.hxx204
-rw-r--r--oox/inc/oox/drawingml/chart/typegroupmodel.hxx102
-rw-r--r--oox/inc/oox/drawingml/clrscheme.hxx67
-rw-r--r--oox/inc/oox/drawingml/clrschemecontext.hxx68
-rw-r--r--oox/inc/oox/drawingml/color.hxx150
-rw-r--r--oox/inc/oox/drawingml/colorchoicecontext.hxx87
-rw-r--r--oox/inc/oox/drawingml/connectorshapecontext.hxx46
-rw-r--r--oox/inc/oox/drawingml/customshapegeometry.hxx77
-rw-r--r--oox/inc/oox/drawingml/customshapeproperties.hxx159
-rw-r--r--oox/inc/oox/drawingml/diagram/datamodelcontext.hxx54
-rw-r--r--oox/inc/oox/drawingml/diagram/diagram.hxx256
-rw-r--r--oox/inc/oox/drawingml/diagram/diagramfragmenthandler.hxx100
-rw-r--r--oox/inc/oox/drawingml/diagram/diagramlayoutatoms.hxx209
-rw-r--r--oox/inc/oox/drawingml/drawingmltypes.hxx188
-rw-r--r--oox/inc/oox/drawingml/embeddedwavaudiofile.hxx57
-rw-r--r--oox/inc/oox/drawingml/fillproperties.hxx206
-rw-r--r--oox/inc/oox/drawingml/fillpropertiesgroupcontext.hxx215
-rw-r--r--oox/inc/oox/drawingml/graphicshapecontext.hxx116
-rw-r--r--oox/inc/oox/drawingml/guidcontext.hxx49
-rw-r--r--oox/inc/oox/drawingml/lineproperties.hxx127
-rw-r--r--oox/inc/oox/drawingml/linepropertiescontext.hxx57
-rw-r--r--oox/inc/oox/drawingml/objectdefaultcontext.hxx49
-rw-r--r--oox/inc/oox/drawingml/shape.hxx229
-rw-r--r--oox/inc/oox/drawingml/shapecontext.hxx58
-rw-r--r--oox/inc/oox/drawingml/shapegroupcontext.hxx51
-rw-r--r--oox/inc/oox/drawingml/shapepropertiescontext.hxx49
-rw-r--r--oox/inc/oox/drawingml/shapestylecontext.hxx51
-rw-r--r--oox/inc/oox/drawingml/spdefcontext.hxx48
-rw-r--r--oox/inc/oox/drawingml/table/tablebackgroundstylecontext.hxx53
-rw-r--r--oox/inc/oox/drawingml/table/tablecell.hxx121
-rw-r--r--oox/inc/oox/drawingml/table/tablecellcontext.hxx54
-rw-r--r--oox/inc/oox/drawingml/table/tablecontext.hxx54
-rw-r--r--oox/inc/oox/drawingml/table/tablepartstylecontext.hxx53
-rw-r--r--oox/inc/oox/drawingml/table/tableproperties.hxx87
-rw-r--r--oox/inc/oox/drawingml/table/tablerow.hxx55
-rw-r--r--oox/inc/oox/drawingml/table/tablerowcontext.hxx55
-rw-r--r--oox/inc/oox/drawingml/table/tablestyle.hxx91
-rw-r--r--oox/inc/oox/drawingml/table/tablestylecellstylecontext.hxx54
-rw-r--r--oox/inc/oox/drawingml/table/tablestylecontext.hxx55
-rw-r--r--oox/inc/oox/drawingml/table/tablestylelist.hxx60
-rw-r--r--oox/inc/oox/drawingml/table/tablestylelistfragmenthandler.hxx63
-rw-r--r--oox/inc/oox/drawingml/table/tablestylepart.hxx79
-rw-r--r--oox/inc/oox/drawingml/table/tablestyletextstylecontext.hxx55
-rw-r--r--oox/inc/oox/drawingml/textbody.hxx76
-rw-r--r--oox/inc/oox/drawingml/textbodycontext.hxx69
-rw-r--r--oox/inc/oox/drawingml/textbodyproperties.hxx56
-rw-r--r--oox/inc/oox/drawingml/textbodypropertiescontext.hxx53
-rw-r--r--oox/inc/oox/drawingml/textcharacterproperties.hxx89
-rw-r--r--oox/inc/oox/drawingml/textcharacterpropertiescontext.hxx54
-rw-r--r--oox/inc/oox/drawingml/textfield.hxx68
-rw-r--r--oox/inc/oox/drawingml/textfieldcontext.hxx58
-rw-r--r--oox/inc/oox/drawingml/textfont.hxx80
-rw-r--r--oox/inc/oox/drawingml/textliststyle.hxx63
-rw-r--r--oox/inc/oox/drawingml/textliststylecontext.hxx51
-rw-r--r--oox/inc/oox/drawingml/textparagraph.hxx79
-rw-r--r--oox/inc/oox/drawingml/textparagraphproperties.hxx129
-rw-r--r--oox/inc/oox/drawingml/textparagraphpropertiescontext.hxx64
-rw-r--r--oox/inc/oox/drawingml/textrun.hxx68
-rw-r--r--oox/inc/oox/drawingml/textspacing.hxx81
-rw-r--r--oox/inc/oox/drawingml/theme.hxx115
-rw-r--r--oox/inc/oox/drawingml/themeelementscontext.hxx58
-rw-r--r--oox/inc/oox/drawingml/themefragmenthandler.hxx61
-rw-r--r--oox/inc/oox/drawingml/transform2dcontext.hxx58
-rw-r--r--oox/inc/oox/dump/biffdumper.hxx574
-rw-r--r--oox/inc/oox/dump/dffdumper.hxx82
-rw-r--r--oox/inc/oox/dump/dumperbase.hxx1979
-rw-r--r--oox/inc/oox/dump/oledumper.hxx939
-rw-r--r--oox/inc/oox/dump/pptxdumper.hxx78
-rw-r--r--oox/inc/oox/dump/xlsbdumper.hxx258
-rw-r--r--oox/inc/oox/export/drawingml.hxx115
-rw-r--r--oox/inc/oox/export/shapes.hxx162
-rw-r--r--oox/inc/oox/export/utils.hxx70
-rw-r--r--oox/inc/oox/export/vmlexport.hxx115
-rw-r--r--oox/inc/oox/helper/attributelist.hxx195
-rw-r--r--oox/inc/oox/helper/binaryinputstream.hxx290
-rw-r--r--oox/inc/oox/helper/binaryoutputstream.hxx160
-rw-r--r--oox/inc/oox/helper/binarystreambase.hxx146
-rw-r--r--oox/inc/oox/helper/containerhelper.hxx399
-rw-r--r--oox/inc/oox/helper/graphichelper.hxx177
-rw-r--r--oox/inc/oox/helper/helper.hxx324
-rw-r--r--oox/inc/oox/helper/modelobjecthelper.hxx129
-rw-r--r--oox/inc/oox/helper/progressbar.hxx144
-rw-r--r--oox/inc/oox/helper/propertymap.hxx101
-rw-r--r--oox/inc/oox/helper/propertyset.hxx166
-rwxr-xr-xoox/inc/oox/helper/refmap.hxx181
-rwxr-xr-xoox/inc/oox/helper/refvector.hxx201
-rw-r--r--oox/inc/oox/helper/storagebase.hxx197
-rw-r--r--oox/inc/oox/helper/textinputstream.hxx57
-rw-r--r--oox/inc/oox/helper/zipstorage.hxx95
-rw-r--r--oox/inc/oox/ole/axbinaryreader.hxx298
-rw-r--r--oox/inc/oox/ole/axcontrol.hxx955
-rw-r--r--oox/inc/oox/ole/axcontrolfragment.hxx80
-rw-r--r--oox/inc/oox/ole/olehelper.hxx146
-rw-r--r--oox/inc/oox/ole/oleobjecthelper.hxx85
-rw-r--r--oox/inc/oox/ole/olestorage.hxx116
-rw-r--r--oox/inc/oox/ole/vbacontrol.hxx219
-rw-r--r--oox/inc/oox/ole/vbahelper.hxx111
-rw-r--r--oox/inc/oox/ole/vbainputstream.hxx71
-rw-r--r--oox/inc/oox/ole/vbamodule.hxx111
-rw-r--r--oox/inc/oox/ole/vbaproject.hxx209
-rwxr-xr-xoox/inc/oox/ole/vbaprojectfilter.hxx76
-rw-r--r--oox/inc/oox/ppt/animationspersist.hxx132
-rw-r--r--oox/inc/oox/ppt/backgroundproperties.hxx50
-rw-r--r--oox/inc/oox/ppt/headerfooter.hxx51
-rw-r--r--oox/inc/oox/ppt/layoutfragmenthandler.hxx49
-rw-r--r--oox/inc/oox/ppt/pptimport.hxx90
-rw-r--r--oox/inc/oox/ppt/pptshape.hxx72
-rw-r--r--oox/inc/oox/ppt/pptshapecontext.hxx46
-rw-r--r--oox/inc/oox/ppt/pptshapegroupcontext.hxx58
-rw-r--r--oox/inc/oox/ppt/pptshapepropertiescontext.hxx46
-rw-r--r--oox/inc/oox/ppt/presentationfragmenthandler.hxx72
-rw-r--r--oox/inc/oox/ppt/slidefragmenthandler.hxx62
-rw-r--r--oox/inc/oox/ppt/slidemastertextstylescontext.hxx51
-rw-r--r--oox/inc/oox/ppt/slidepersist.hxx154
-rw-r--r--oox/inc/oox/ppt/slidetimingcontext.hxx57
-rw-r--r--oox/inc/oox/ppt/slidetransition.hxx75
-rw-r--r--oox/inc/oox/ppt/slidetransitioncontext.hxx60
-rw-r--r--oox/inc/oox/ppt/soundactioncontext.hxx61
-rw-r--r--oox/inc/oox/ppt/timenode.hxx134
-rw-r--r--oox/inc/oox/ppt/timenodelistcontext.hxx74
-rwxr-xr-xoox/inc/oox/token/namespacemap.hxx49
-rw-r--r--oox/inc/oox/token/propertynames.hxx49
-rw-r--r--oox/inc/oox/token/tokenmap.hxx80
-rw-r--r--oox/inc/oox/vml/vmldrawing.hxx216
-rw-r--r--oox/inc/oox/vml/vmldrawingfragment.hxx65
-rw-r--r--oox/inc/oox/vml/vmlformatting.hxx219
-rw-r--r--oox/inc/oox/vml/vmlinputstream.hxx68
-rw-r--r--oox/inc/oox/vml/vmlshape.hxx377
-rw-r--r--oox/inc/oox/vml/vmlshapecontainer.hxx142
-rw-r--r--oox/inc/oox/vml/vmlshapecontext.hxx167
-rwxr-xr-xoox/inc/oox/vml/vmltextbox.hxx95
-rwxr-xr-xoox/inc/oox/vml/vmltextboxcontext.hxx82
-rw-r--r--oox/inc/oox/xls/addressconverter.hxx691
-rwxr-xr-xoox/inc/oox/xls/autofilterbuffer.hxx279
-rw-r--r--oox/inc/oox/xls/autofiltercontext.hxx114
-rw-r--r--oox/inc/oox/xls/biffcodec.hxx187
-rw-r--r--oox/inc/oox/xls/biffdetector.hxx97
-rw-r--r--oox/inc/oox/xls/biffhelper.hxx668
-rw-r--r--oox/inc/oox/xls/biffinputstream.hxx446
-rw-r--r--oox/inc/oox/xls/biffoutputstream.hxx164
-rw-r--r--oox/inc/oox/xls/chartsheetfragment.hxx83
-rw-r--r--oox/inc/oox/xls/commentsbuffer.hxx101
-rw-r--r--oox/inc/oox/xls/commentsfragment.hxx70
-rw-r--r--oox/inc/oox/xls/condformatbuffer.hxx193
-rw-r--r--oox/inc/oox/xls/condformatcontext.hxx62
-rwxr-xr-xoox/inc/oox/xls/connectionsbuffer.hxx186
-rw-r--r--oox/inc/oox/xls/connectionsfragment.hxx78
-rw-r--r--oox/inc/oox/xls/defnamesbuffer.hxx233
-rw-r--r--oox/inc/oox/xls/drawingfragment.hxx326
-rw-r--r--oox/inc/oox/xls/excelchartconverter.hxx61
-rw-r--r--oox/inc/oox/xls/excelfilter.hxx119
-rw-r--r--oox/inc/oox/xls/excelhandlers.hxx307
-rwxr-xr-xoox/inc/oox/xls/excelvbaproject.hxx65
-rw-r--r--oox/inc/oox/xls/externallinkbuffer.hxx404
-rw-r--r--oox/inc/oox/xls/externallinkfragment.hxx161
-rw-r--r--oox/inc/oox/xls/formulabase.hxx924
-rw-r--r--oox/inc/oox/xls/formulaparser.hxx172
-rw-r--r--oox/inc/oox/xls/numberformatsbuffer.hxx138
-rw-r--r--oox/inc/oox/xls/ooxformulaparser.hxx111
-rw-r--r--oox/inc/oox/xls/pagesettings.hxx219
-rw-r--r--oox/inc/oox/xls/pivotcachebuffer.hxx510
-rw-r--r--oox/inc/oox/xls/pivotcachefragment.hxx155
-rw-r--r--oox/inc/oox/xls/pivottablebuffer.hxx448
-rw-r--r--oox/inc/oox/xls/pivottablefragment.hxx117
-rw-r--r--oox/inc/oox/xls/querytablebuffer.hxx109
-rw-r--r--oox/inc/oox/xls/querytablefragment.hxx76
-rw-r--r--oox/inc/oox/xls/richstring.hxx294
-rw-r--r--oox/inc/oox/xls/richstringcontext.hxx71
-rw-r--r--oox/inc/oox/xls/scenariobuffer.hxx155
-rw-r--r--oox/inc/oox/xls/scenariocontext.hxx80
-rw-r--r--oox/inc/oox/xls/sharedformulabuffer.hxx111
-rw-r--r--oox/inc/oox/xls/sharedstringsbuffer.hxx68
-rw-r--r--oox/inc/oox/xls/sharedstringsfragment.hxx58
-rw-r--r--oox/inc/oox/xls/sheetdatacontext.hxx172
-rw-r--r--oox/inc/oox/xls/stylesbuffer.hxx1098
-rw-r--r--oox/inc/oox/xls/stylesfragment.hxx155
-rw-r--r--oox/inc/oox/xls/tablebuffer.hxx139
-rw-r--r--oox/inc/oox/xls/tablefragment.hxx62
-rw-r--r--oox/inc/oox/xls/themebuffer.hxx63
-rw-r--r--oox/inc/oox/xls/unitconverter.hxx123
-rw-r--r--oox/inc/oox/xls/viewsettings.hxx232
-rw-r--r--oox/inc/oox/xls/workbookfragment.hxx98
-rw-r--r--oox/inc/oox/xls/workbookhelper.hxx325
-rw-r--r--oox/inc/oox/xls/workbooksettings.hxx164
-rw-r--r--oox/inc/oox/xls/worksheetbuffer.hxx133
-rw-r--r--oox/inc/oox/xls/worksheetfragment.hxx193
-rw-r--r--oox/inc/oox/xls/worksheethelper.hxx475
-rw-r--r--oox/inc/oox/xls/worksheetsettings.hxx144
-rw-r--r--oox/prj/build.lst18
-rw-r--r--oox/prj/d.lst46
-rw-r--r--oox/source/core/binarycodec.cxx427
-rw-r--r--oox/source/core/binaryfilterbase.cxx69
-rw-r--r--oox/source/core/contexthandler.cxx152
-rw-r--r--oox/source/core/contexthandler2.cxx268
-rwxr-xr-xoox/source/core/fastparser.cxx136
-rw-r--r--oox/source/core/fasttokenhandler.cxx119
-rw-r--r--oox/source/core/filterbase.cxx583
-rw-r--r--oox/source/core/filterdetect.cxx681
-rw-r--r--oox/source/core/fragmenthandler.cxx141
-rw-r--r--oox/source/core/fragmenthandler2.cxx150
-rw-r--r--oox/source/core/makefile.mk66
-rw-r--r--oox/source/core/recordparser.cxx350
-rw-r--r--oox/source/core/relations.cxx148
-rw-r--r--oox/source/core/relationshandler.cxx110
-rw-r--r--oox/source/core/services.cxx97
-rw-r--r--oox/source/core/xmlfilterbase.cxx510
-rw-r--r--oox/source/docprop/docprophandler.cxx691
-rw-r--r--oox/source/docprop/docprophandler.hxx102
-rw-r--r--oox/source/docprop/makefile.mk49
-rw-r--r--oox/source/docprop/ooxmldocpropimport.cxx189
-rw-r--r--oox/source/docprop/ooxmldocpropimport.hxx71
-rw-r--r--oox/source/drawingml/chart/axiscontext.cxx320
-rw-r--r--oox/source/drawingml/chart/axisconverter.cxx365
-rw-r--r--oox/source/drawingml/chart/axismodel.cxx79
-rw-r--r--oox/source/drawingml/chart/chartcontextbase.cxx122
-rw-r--r--oox/source/drawingml/chart/chartconverter.cxx93
-rw-r--r--oox/source/drawingml/chart/chartdrawingfragment.cxx232
-rw-r--r--oox/source/drawingml/chart/chartspaceconverter.cxx229
-rw-r--r--oox/source/drawingml/chart/chartspacefragment.cxx132
-rw-r--r--oox/source/drawingml/chart/chartspacemodel.cxx54
-rw-r--r--oox/source/drawingml/chart/converterbase.cxx439
-rw-r--r--oox/source/drawingml/chart/datasourcecontext.cxx233
-rw-r--r--oox/source/drawingml/chart/datasourceconverter.cxx94
-rw-r--r--oox/source/drawingml/chart/datasourcemodel.cxx59
-rw-r--r--oox/source/drawingml/chart/makefile.mk74
-rw-r--r--oox/source/drawingml/chart/modelbase.cxx78
-rw-r--r--oox/source/drawingml/chart/objectformatter.cxx1208
-rw-r--r--oox/source/drawingml/chart/plotareacontext.cxx187
-rw-r--r--oox/source/drawingml/chart/plotareaconverter.cxx452
-rw-r--r--oox/source/drawingml/chart/plotareamodel.cxx72
-rw-r--r--oox/source/drawingml/chart/seriescontext.cxx754
-rw-r--r--oox/source/drawingml/chart/seriesconverter.cxx619
-rw-r--r--oox/source/drawingml/chart/seriesmodel.cxx156
-rw-r--r--oox/source/drawingml/chart/titlecontext.cxx159
-rw-r--r--oox/source/drawingml/chart/titleconverter.cxx259
-rw-r--r--oox/source/drawingml/chart/titlemodel.cxx71
-rw-r--r--oox/source/drawingml/chart/typegroupcontext.cxx404
-rw-r--r--oox/source/drawingml/chart/typegroupconverter.cxx566
-rw-r--r--oox/source/drawingml/chart/typegroupmodel.cxx82
-rw-r--r--oox/source/drawingml/clrscheme.cxx82
-rw-r--r--oox/source/drawingml/clrschemecontext.cxx105
-rw-r--r--oox/source/drawingml/color.cxx670
-rw-r--r--oox/source/drawingml/colorchoicecontext.cxx160
-rw-r--r--oox/source/drawingml/connectorshapecontext.cxx79
-rw-r--r--oox/source/drawingml/customshapegeometry.cxx2065
-rw-r--r--oox/source/drawingml/customshapeproperties.cxx268
-rw-r--r--oox/source/drawingml/diagram/datamodelcontext.cxx334
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx297
-rw-r--r--oox/source/drawingml/diagram/diagramdefinitioncontext.cxx115
-rw-r--r--oox/source/drawingml/diagram/diagramdefinitioncontext.hxx51
-rw-r--r--oox/source/drawingml/diagram/diagramfragmenthandler.cxx222
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx141
-rw-r--r--oox/source/drawingml/diagram/layoutnodecontext.cxx356
-rw-r--r--oox/source/drawingml/diagram/layoutnodecontext.hxx52
-rw-r--r--oox/source/drawingml/diagram/makefile.mk53
-rw-r--r--oox/source/drawingml/drawingmltypes.cxx295
-rw-r--r--oox/source/drawingml/embeddedwavaudiofile.cxx53
-rw-r--r--oox/source/drawingml/fillproperties.cxx489
-rw-r--r--oox/source/drawingml/fillpropertiesgroupcontext.cxx308
-rw-r--r--oox/source/drawingml/graphicshapecontext.cxx317
-rw-r--r--oox/source/drawingml/guidcontext.cxx47
-rw-r--r--oox/source/drawingml/hyperlinkcontext.cxx176
-rw-r--r--oox/source/drawingml/hyperlinkcontext.hxx58
-rw-r--r--oox/source/drawingml/lineproperties.cxx477
-rw-r--r--oox/source/drawingml/linepropertiescontext.cxx106
-rw-r--r--oox/source/drawingml/makefile.mk91
-rw-r--r--oox/source/drawingml/objectdefaultcontext.cxx59
-rw-r--r--oox/source/drawingml/shape.cxx624
-rw-r--r--oox/source/drawingml/shapecontext.cxx127
-rw-r--r--oox/source/drawingml/shapegroupcontext.cxx119
-rw-r--r--oox/source/drawingml/shapepropertiescontext.cxx119
-rw-r--r--oox/source/drawingml/shapestylecontext.cxx86
-rw-r--r--oox/source/drawingml/spdefcontext.cxx76
-rw-r--r--oox/source/drawingml/table/makefile.mk62
-rw-r--r--oox/source/drawingml/table/tablebackgroundstylecontext.cxx91
-rw-r--r--oox/source/drawingml/table/tablecell.cxx363
-rw-r--r--oox/source/drawingml/table/tablecellcontext.cxx126
-rw-r--r--oox/source/drawingml/table/tablecontext.cxx107
-rw-r--r--oox/source/drawingml/table/tablepartstylecontext.cxx76
-rw-r--r--oox/source/drawingml/table/tableproperties.cxx178
-rw-r--r--oox/source/drawingml/table/tablerow.cxx53
-rw-r--r--oox/source/drawingml/table/tablerowcontext.cxx78
-rw-r--r--oox/source/drawingml/table/tablestyle.cxx40
-rw-r--r--oox/source/drawingml/table/tablestylecellstylecontext.cxx125
-rw-r--r--oox/source/drawingml/table/tablestylecontext.cxx116
-rw-r--r--oox/source/drawingml/table/tablestylelist.cxx41
-rw-r--r--oox/source/drawingml/table/tablestylelistfragmenthandler.cxx84
-rw-r--r--oox/source/drawingml/table/tablestylepart.cxx47
-rw-r--r--oox/source/drawingml/table/tablestyletextstylecontext.cxx108
-rw-r--r--oox/source/drawingml/textbody.cxx72
-rw-r--r--oox/source/drawingml/textbodycontext.cxx212
-rw-r--r--oox/source/drawingml/textbodyproperties.cxx54
-rw-r--r--oox/source/drawingml/textbodypropertiescontext.cxx187
-rw-r--r--oox/source/drawingml/textcharacterproperties.cxx169
-rw-r--r--oox/source/drawingml/textcharacterpropertiescontext.cxx177
-rw-r--r--oox/source/drawingml/textfield.cxx195
-rw-r--r--oox/source/drawingml/textfieldcontext.cxx89
-rw-r--r--oox/source/drawingml/textfont.cxx103
-rw-r--r--oox/source/drawingml/textliststyle.cxx68
-rw-r--r--oox/source/drawingml/textliststylecontext.cxx110
-rw-r--r--oox/source/drawingml/textparagraph.cxx130
-rw-r--r--oox/source/drawingml/textparagraphproperties.cxx423
-rw-r--r--oox/source/drawingml/textparagraphpropertiescontext.cxx283
-rw-r--r--oox/source/drawingml/textrun.cxx168
-rw-r--r--oox/source/drawingml/textspacingcontext.cxx75
-rw-r--r--oox/source/drawingml/textspacingcontext.hxx57
-rw-r--r--oox/source/drawingml/texttabstoplistcontext.cxx95
-rw-r--r--oox/source/drawingml/texttabstoplistcontext.hxx58
-rw-r--r--oox/source/drawingml/theme.cxx108
-rw-r--r--oox/source/drawingml/themeelementscontext.cxx241
-rw-r--r--oox/source/drawingml/themefragmenthandler.cxx87
-rw-r--r--oox/source/drawingml/transform2dcontext.cxx80
-rw-r--r--oox/source/dump/biffdumper.cxx4554
-rw-r--r--oox/source/dump/biffdumper.ini2378
-rw-r--r--oox/source/dump/dffdumper.cxx324
-rw-r--r--oox/source/dump/dffdumper.ini650
-rw-r--r--oox/source/dump/dumperbase.cxx3217
-rw-r--r--oox/source/dump/dumperbase.ini395
-rw-r--r--oox/source/dump/makefile.mk53
-rw-r--r--oox/source/dump/oledumper.cxx2364
-rw-r--r--oox/source/dump/oledumper.ini887
-rw-r--r--oox/source/dump/pptxdumper.cxx150
-rw-r--r--oox/source/dump/pptxdumper.ini18
-rw-r--r--oox/source/dump/xlsbdumper.cxx2340
-rw-r--r--oox/source/dump/xlsbdumper.ini1186
-rw-r--r--oox/source/export/README2
-rw-r--r--oox/source/export/drawingml.cxx1393
-rw-r--r--oox/source/export/makefile.mk27
-rw-r--r--oox/source/export/preset-definitions-to-shape-types.pl1242
-rw-r--r--oox/source/export/presetShapeDefinitions.xml19915
-rw-r--r--oox/source/export/presetTextWarpDefinitions.xml1885
-rw-r--r--oox/source/export/shapes.cxx994
-rw-r--r--oox/source/export/vmlexport.cxx837
-rw-r--r--oox/source/helper/attributelist.cxx325
-rw-r--r--oox/source/helper/binaryinputstream.cxx337
-rw-r--r--oox/source/helper/binaryoutputstream.cxx141
-rw-r--r--oox/source/helper/binarystreambase.cxx162
-rw-r--r--oox/source/helper/containerhelper.cxx163
-rwxr-xr-xoox/source/helper/graphichelper.cxx366
-rw-r--r--oox/source/helper/makefile.mk60
-rw-r--r--oox/source/helper/modelobjecthelper.cxx152
-rw-r--r--oox/source/helper/progressbar.cxx186
-rw-r--r--oox/source/helper/propertymap.cxx221
-rw-r--r--oox/source/helper/propertyset.cxx177
-rw-r--r--oox/source/helper/storagebase.cxx273
-rw-r--r--oox/source/helper/textinputstream.cxx130
-rw-r--r--oox/source/helper/zipstorage.cxx209
-rw-r--r--oox/source/ole/axbinaryreader.cxx348
-rw-r--r--oox/source/ole/axcontrol.cxx1865
-rw-r--r--oox/source/ole/axcontrolfragment.cxx160
-rw-r--r--oox/source/ole/makefile.mk60
-rw-r--r--oox/source/ole/olehelper.cxx313
-rw-r--r--oox/source/ole/oleobjecthelper.cxx138
-rw-r--r--oox/source/ole/olestorage.cxx413
-rw-r--r--oox/source/ole/vbacontrol.cxx850
-rw-r--r--oox/source/ole/vbahelper.cxx88
-rw-r--r--oox/source/ole/vbainputstream.cxx187
-rw-r--r--oox/source/ole/vbamodule.cxx264
-rw-r--r--oox/source/ole/vbaproject.cxx548
-rwxr-xr-xoox/source/ole/vbaprojectfilter.cxx106
-rw-r--r--oox/source/ppt/animationspersist.cxx198
-rw-r--r--oox/source/ppt/animationtypes.cxx72
-rw-r--r--oox/source/ppt/animationtypes.hxx47
-rw-r--r--oox/source/ppt/animvariantcontext.cxx122
-rw-r--r--oox/source/ppt/animvariantcontext.hxx60
-rw-r--r--oox/source/ppt/backgroundproperties.cxx63
-rw-r--r--oox/source/ppt/buildlistcontext.cxx112
-rw-r--r--oox/source/ppt/buildlistcontext.hxx64
-rw-r--r--oox/source/ppt/commonbehaviorcontext.cxx178
-rw-r--r--oox/source/ppt/commonbehaviorcontext.hxx82
-rw-r--r--oox/source/ppt/commontimenodecontext.cxx708
-rw-r--r--oox/source/ppt/commontimenodecontext.hxx62
-rw-r--r--oox/source/ppt/conditioncontext.cxx212
-rw-r--r--oox/source/ppt/conditioncontext.hxx84
-rw-r--r--oox/source/ppt/customshowlistcontext.cxx118
-rw-r--r--oox/source/ppt/customshowlistcontext.hxx63
-rw-r--r--oox/source/ppt/headerfootercontext.cxx64
-rw-r--r--oox/source/ppt/headerfootercontext.hxx50
-rw-r--r--oox/source/ppt/layoutfragmenthandler.cxx86
-rw-r--r--oox/source/ppt/makefile.mk76
-rw-r--r--oox/source/ppt/pptfilterhelpers.cxx140
-rw-r--r--oox/source/ppt/pptfilterhelpers.hxx104
-rw-r--r--oox/source/ppt/pptimport.cxx195
-rw-r--r--oox/source/ppt/pptshape.cxx279
-rw-r--r--oox/source/ppt/pptshapecontext.cxx216
-rw-r--r--oox/source/ppt/pptshapegroupcontext.cxx121
-rw-r--r--oox/source/ppt/pptshapepropertiescontext.cxx83
-rw-r--r--oox/source/ppt/presentationfragmenthandler.cxx390
-rw-r--r--oox/source/ppt/slidefragmenthandler.cxx205
-rw-r--r--oox/source/ppt/slidemastertextstylescontext.cxx88
-rw-r--r--oox/source/ppt/slidepersist.cxx317
-rw-r--r--oox/source/ppt/slidetimingcontext.cxx101
-rw-r--r--oox/source/ppt/slidetransition.cxx418
-rw-r--r--oox/source/ppt/slidetransitioncontext.cxx200
-rw-r--r--oox/source/ppt/soundactioncontext.cxx134
-rw-r--r--oox/source/ppt/timeanimvaluecontext.cxx98
-rw-r--r--oox/source/ppt/timeanimvaluecontext.hxx64
-rw-r--r--oox/source/ppt/timenode.cxx630
-rw-r--r--oox/source/ppt/timenodelistcontext.cxx1163
-rw-r--r--oox/source/ppt/timetargetelementcontext.cxx174
-rw-r--r--oox/source/ppt/timetargetelementcontext.hxx53
-rw-r--r--oox/source/shape/ShapeContextHandler.cxx352
-rw-r--r--oox/source/shape/ShapeContextHandler.hxx175
-rw-r--r--oox/source/shape/ShapeFilterBase.cxx78
-rw-r--r--oox/source/shape/ShapeFilterBase.hxx80
-rw-r--r--oox/source/shape/makefile.mk49
-rw-r--r--oox/source/token/makefile.mk78
-rwxr-xr-xoox/source/token/namespacemap.cxx49
-rwxr-xr-xoox/source/token/namespaces.hxx.head36
-rwxr-xr-xoox/source/token/namespaces.hxx.tail35
-rw-r--r--oox/source/token/namespaces.pl79
-rw-r--r--oox/source/token/namespaces.txt52
-rw-r--r--oox/source/token/parsexsd.pl75
-rwxr-xr-xoox/source/token/properties.hxx.head36
-rwxr-xr-xoox/source/token/properties.hxx.tail6
-rw-r--r--oox/source/token/properties.pl67
-rw-r--r--oox/source/token/properties.txt485
-rw-r--r--oox/source/token/propertynames.cxx51
-rw-r--r--oox/source/token/tokenmap.cxx119
-rwxr-xr-xoox/source/token/tokens.hxx.head36
-rwxr-xr-xoox/source/token/tokens.hxx.tail8
-rw-r--r--oox/source/token/tokens.pl80
-rw-r--r--oox/source/token/tokens.txt5680
-rw-r--r--oox/source/vml/makefile.mk56
-rw-r--r--oox/source/vml/vmldrawing.cxx281
-rw-r--r--oox/source/vml/vmldrawingfragment.cxx94
-rw-r--r--oox/source/vml/vmlformatting.cxx587
-rw-r--r--oox/source/vml/vmlinputstream.cxx325
-rw-r--r--oox/source/vml/vmlshape.cxx570
-rw-r--r--oox/source/vml/vmlshapecontainer.cxx136
-rw-r--r--oox/source/vml/vmlshapecontext.cxx406
-rwxr-xr-xoox/source/vml/vmltextbox.cxx81
-rwxr-xr-xoox/source/vml/vmltextboxcontext.cxx146
-rw-r--r--oox/source/xls/addressconverter.cxx783
-rwxr-xr-xoox/source/xls/autofilterbuffer.cxx853
-rw-r--r--oox/source/xls/autofiltercontext.cxx183
-rw-r--r--oox/source/xls/biffcodec.cxx379
-rw-r--r--oox/source/xls/biffdetector.cxx231
-rw-r--r--oox/source/xls/biffhelper.cxx338
-rw-r--r--oox/source/xls/biffinputstream.cxx633
-rw-r--r--oox/source/xls/biffoutputstream.cxx207
-rw-r--r--oox/source/xls/chartsheetfragment.cxx291
-rw-r--r--oox/source/xls/commentsbuffer.cxx151
-rw-r--r--oox/source/xls/commentsfragment.cxx146
-rw-r--r--oox/source/xls/condformatbuffer.cxx774
-rw-r--r--oox/source/xls/condformatcontext.cxx102
-rwxr-xr-xoox/source/xls/connectionsbuffer.cxx501
-rw-r--r--oox/source/xls/connectionsfragment.cxx179
-rw-r--r--oox/source/xls/defnamesbuffer.cxx706
-rw-r--r--oox/source/xls/drawingfragment.cxx1099
-rw-r--r--oox/source/xls/excelchartconverter.cxx124
-rw-r--r--oox/source/xls/excelfilter.cxx314
-rw-r--r--oox/source/xls/excelhandlers.cxx239
-rwxr-xr-xoox/source/xls/excelvbaproject.cxx147
-rw-r--r--oox/source/xls/externallinkbuffer.cxx1141
-rw-r--r--oox/source/xls/externallinkfragment.cxx548
-rwxr-xr-xoox/source/xls/formulabase.cxx1739
-rw-r--r--oox/source/xls/formulaparser.cxx2917
-rw-r--r--oox/source/xls/makefile.mk103
-rw-r--r--oox/source/xls/numberformatsbuffer.cxx2116
-rw-r--r--oox/source/xls/ooxformulaparser.cxx221
-rw-r--r--oox/source/xls/pagesettings.cxx1250
-rw-r--r--oox/source/xls/pivotcachebuffer.cxx1543
-rw-r--r--oox/source/xls/pivotcachefragment.cxx466
-rw-r--r--oox/source/xls/pivottablebuffer.cxx1567
-rw-r--r--oox/source/xls/pivottablefragment.cxx319
-rw-r--r--oox/source/xls/querytablebuffer.cxx390
-rw-r--r--oox/source/xls/querytablefragment.cxx106
-rw-r--r--oox/source/xls/richstring.cxx614
-rw-r--r--oox/source/xls/richstringcontext.cxx105
-rw-r--r--oox/source/xls/scenariobuffer.cxx299
-rw-r--r--oox/source/xls/scenariocontext.cxx126
-rw-r--r--oox/source/xls/sharedformulabuffer.cxx212
-rw-r--r--oox/source/xls/sharedstringsbuffer.cxx86
-rw-r--r--oox/source/xls/sharedstringsfragment.cxx102
-rw-r--r--oox/source/xls/sheetdatacontext.cxx982
-rw-r--r--oox/source/xls/stylesbuffer.cxx3471
-rw-r--r--oox/source/xls/stylesfragment.cxx329
-rw-r--r--oox/source/xls/tablebuffer.cxx164
-rw-r--r--oox/source/xls/tablefragment.cxx106
-rw-r--r--oox/source/xls/themebuffer.cxx123
-rw-r--r--oox/source/xls/unitconverter.cxx259
-rw-r--r--oox/source/xls/viewsettings.cxx823
-rw-r--r--oox/source/xls/workbookfragment.cxx727
-rw-r--r--oox/source/xls/workbookhelper.cxx947
-rw-r--r--oox/source/xls/workbooksettings.cxx366
-rw-r--r--oox/source/xls/worksheetbuffer.cxx258
-rw-r--r--oox/source/xls/worksheetfragment.cxx1230
-rw-r--r--oox/source/xls/worksheethelper.cxx2291
-rw-r--r--oox/source/xls/worksheetsettings.cxx348
-rw-r--r--oox/util/makefile.mk104
-rw-r--r--oox/util/makefile.pmk30
-rw-r--r--oox/util/oox.component67
-rw-r--r--oox/workben/ooxml-export-notes.txt220
534 files changed, 170760 insertions, 0 deletions
diff --git a/oox/inc/oox/core/binarycodec.hxx b/oox/inc/oox/core/binarycodec.hxx
new file mode 100644
index 000000000000..ced63250f3e1
--- /dev/null
+++ b/oox/inc/oox/core/binarycodec.hxx
@@ -0,0 +1,321 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_BINARYCODEC_HXX
+#define OOX_CORE_BINARYCODEC_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include <rtl/cipher.h>
+#include <rtl/digest.h>
+
+namespace oox { class AttributeList; }
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+class CodecHelper
+{
+public:
+ /** Returns the password hash if it is in the required 16-bit limit. */
+ static sal_uInt16 getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement );
+
+private:
+ CodecHelper();
+ ~CodecHelper();
+};
+
+// ============================================================================
+
+/** Encodes and decodes data from/to protected MS Office documents.
+
+ Implements a simple XOR encoding/decoding algorithm used in MS Office
+ versions up to MSO 95.
+ */
+class BinaryCodec_XOR
+{
+public:
+ /** Enumerates codec types supported by this XOR codec implementation. */
+ enum CodecType
+ {
+ CODEC_WORD, /// MS Word XOR codec.
+ CODEC_EXCEL /// MS Excel XOR codec.
+ };
+
+public:
+ /** Default constructor.
+
+ Two-step construction in conjunction with the initKey() and verifyKey()
+ functions allows to try to initialize with different passwords (e.g.
+ built-in default password used for Excel workbook protection).
+ */
+ explicit BinaryCodec_XOR( CodecType eCodecType );
+
+ ~BinaryCodec_XOR();
+
+ /** Initializes the algorithm with the specified password.
+
+ @param pnPassData
+ Character array containing the password. Must be zero terminated,
+ which results in a maximum length of 15 characters.
+ */
+ void initKey( const sal_uInt8 pnPassData[ 16 ] );
+
+ /** Initializes the algorithm with the encryption data.
+
+ @param aData
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ bool initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
+
+ /** Retrieves the encryption data
+
+ @return
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();
+
+ /** Verifies the validity of the password using the passed key and hash.
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+
+ @param nKey
+ Password key value read from the file.
+ @param nHash
+ Password hash value read from the file.
+
+ @return
+ True = test was successful.
+ */
+ bool verifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const;
+
+ /** Reinitializes the codec to start a new memory block.
+
+ Resets the internal key offset to 0.
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+ */
+ void startBlock();
+
+ /** Decodes a block of memory.
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+
+ @param pnDestData
+ Destination buffer. Will contain the decrypted data afterwards.
+ @param pnSrcData
+ Encrypted data block.
+ @param nBytes
+ Size of the passed data blocks. pnDestData and pnSrcData must be of
+ this size.
+
+ @return
+ True = decoding was successful (no error occured).
+ */
+ bool decode(
+ sal_uInt8* pnDestData,
+ const sal_uInt8* pnSrcData,
+ sal_Int32 nBytes );
+
+ /** Lets the cipher skip a specific amount of bytes.
+
+ This function sets the cipher to the same state as if the specified
+ amount of data has been decoded with one or more calls of decode().
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+
+ @param nBytes
+ Number of bytes to be skipped (cipher "seeks" forward).
+
+ @return
+ True = skip was successful (no error occured).
+ */
+ bool skip( sal_Int32 nBytes );
+
+private:
+ CodecType meCodecType; /// Codec type.
+ sal_uInt8 mpnKey[ 16 ]; /// Encryption key.
+ sal_Int32 mnOffset; /// Key offset.
+ sal_uInt16 mnBaseKey; /// Base key from password.
+ sal_uInt16 mnHash; /// Hash value from password.
+};
+
+// ============================================================================
+
+/** Encodes and decodes data from protected MSO 97+ documents.
+
+ This is a wrapper class around low level cryptographic functions from RTL.
+ Implementation is based on the wvDecrypt package by Caolan McNamara:
+ http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
+ */
+class BinaryCodec_RCF
+{
+public:
+ /** Default constructor.
+
+ Two-step construction in conjunction with the initKey() and verifyKey()
+ functions allows to try to initialize with different passwords (e.g.
+ built-in default password used for Excel workbook protection).
+ */
+ explicit BinaryCodec_RCF();
+
+ ~BinaryCodec_RCF();
+
+ /** Initializes the algorithm with the encryption data.
+
+ @param aData
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ bool initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
+
+ /** Retrieves the encryption data
+
+ @return
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();
+
+ /** Initializes the algorithm with the specified password and document ID.
+
+ @param pnPassData
+ Unicode character array containing the password. Must be zero
+ terminated, which results in a maximum length of 15 characters.
+ @param pnSalt
+ Random salt data block read from or written to the file.
+ */
+ void initKey(
+ const sal_uInt16 pnPassData[ 16 ],
+ const sal_uInt8 pnSalt[ 16 ] );
+
+ /** Verifies the validity of the password using the passed salt data.
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+
+ @param pnVerifier
+ Verifier block read from the file.
+ @param pnVerifierHash
+ Verifier hash read from the file.
+
+ @return
+ True = test was successful.
+ */
+ bool verifyKey(
+ const sal_uInt8 pnVerifier[ 16 ],
+ const sal_uInt8 pnVerifierHash[ 16 ] );
+
+ /** Rekeys the codec using the specified counter.
+
+ After reading a specific amount of data the cipher algorithm needs to
+ be rekeyed using a counter that counts the data blocks.
+
+ The block size is for example 512 bytes for MS Word files and 1024
+ bytes for MS Excel files.
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+
+ @param nCounter
+ Block counter used to rekey the cipher.
+ */
+ bool startBlock( sal_Int32 nCounter );
+
+ /** Decodes a block of memory.
+
+ @see rtl_cipher_decode()
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+
+ @param pnDestData
+ Destination buffer. Will contain the decrypted data afterwards.
+ @param pnSrcData
+ Encrypted data block.
+ @param nBytes
+ Size of the passed data blocks. pnDestData and pnSrcData must be of
+ this size.
+
+ @return
+ True = decoding was successful (no error occured).
+ */
+ bool decode(
+ sal_uInt8* pnDestData,
+ const sal_uInt8* pnSrcData,
+ sal_Int32 nBytes );
+
+ /** Lets the cipher skip a specific amount of bytes.
+
+ This function sets the cipher to the same state as if the specified
+ amount of data has been decoded with one or more calls of decode().
+
+ @precond
+ The codec must be initialized with the initKey() function before
+ this function can be used.
+
+ @param nBytes
+ Number of bytes to be skipped (cipher "seeks" forward).
+
+ @return
+ True = skip was successful (no error occured).
+ */
+ bool skip( sal_Int32 nBytes );
+
+private:
+ void InitKeyImpl(
+ const sal_uInt8 pKeyData[64],
+ const sal_uInt8 pUnique[16] );
+
+ rtlCipher mhCipher;
+ rtlDigest mhDigest;
+ sal_uInt8 mpnDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
+ sal_uInt8 mpnUnique[16];
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/binaryfilterbase.hxx b/oox/inc/oox/core/binaryfilterbase.hxx
new file mode 100644
index 000000000000..4cd9cd1db62f
--- /dev/null
+++ b/oox/inc/oox/core/binaryfilterbase.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_BINARYFILTERBASE_HXX
+#define OOX_CORE_BINARYFILTERBASE_HXX
+
+#include <rtl/ref.hxx>
+#include "oox/core/filterbase.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+class BinaryFilterBase : public FilterBase
+{
+public:
+ explicit BinaryFilterBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ~BinaryFilterBase();
+
+private:
+ virtual StorageRef implCreateStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const;
+ virtual StorageRef implCreateStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const;
+};
+
+typedef ::rtl::Reference< BinaryFilterBase > BinaryFilterRef;
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/contexthandler.hxx b/oox/inc/oox/core/contexthandler.hxx
new file mode 100644
index 000000000000..b1f24d051c70
--- /dev/null
+++ b/oox/inc/oox/core/contexthandler.hxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_CONTEXTHANDLER_HXX
+#define OOX_CORE_CONTEXTHANDLER_HXX
+
+#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
+#include <boost/shared_ptr.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ref.hxx>
+#include "oox/token/namespaces.hxx"
+#include "oox/token/tokens.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace xml { namespace sax { class XLocator; } }
+} } }
+
+namespace oox { class SequenceInputStream; }
+
+namespace oox {
+namespace core {
+
+class XmlFilterBase;
+class FragmentHandler;
+struct Relation;
+class Relations;
+
+// ============================================================================
+
+class ContextHandler;
+typedef ::rtl::Reference< ContextHandler > ContextHandlerRef;
+
+struct FragmentBaseData;
+typedef ::boost::shared_ptr< FragmentBaseData > FragmentBaseDataRef;
+
+typedef ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastContextHandler > ContextHandlerImplBase;
+
+class ContextHandler : public ContextHandlerImplBase
+{
+public:
+ explicit ContextHandler( ContextHandler& rParent );
+ virtual ~ContextHandler();
+
+ /** Returns the filter instance. */
+ XmlFilterBase& getFilter() const;
+ /** Returns the relations of the current fragment. */
+ const Relations& getRelations() const;
+ /** Returns the full path of the current fragment. */
+ const ::rtl::OUString& getFragmentPath() const;
+
+ /** Returns the full fragment path for the target of the passed relation. */
+ ::rtl::OUString getFragmentPathFromRelation( const Relation& rRelation ) const;
+ /** Returns the full fragment path for the passed relation identifier. */
+ ::rtl::OUString getFragmentPathFromRelId( const ::rtl::OUString& rRelId ) const;
+ /** Returns the full fragment path for the first relation of the passed type. */
+ ::rtl::OUString getFragmentPathFromFirstType( const ::rtl::OUString& rType ) const;
+
+ // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
+
+ virtual void SAL_CALL startFastElement( ::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);
+ virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) 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);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ // record context interface -----------------------------------------------
+
+ virtual ContextHandlerRef createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void startRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void endRecord( sal_Int32 nRecId );
+
+protected:
+ /** Helper constructor for the FragmentHandler. */
+ explicit ContextHandler( const FragmentBaseDataRef& rxBaseData );
+
+ void implSetLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& rxLocator );
+
+private:
+ ContextHandler& operator=( const ContextHandler& );
+
+private:
+ FragmentBaseDataRef mxBaseData; /// Base data of the fragment.
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/contexthandler2.hxx b/oox/inc/oox/core/contexthandler2.hxx
new file mode 100644
index 000000000000..0c9ac794e94b
--- /dev/null
+++ b/oox/inc/oox/core/contexthandler2.hxx
@@ -0,0 +1,274 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_CONTEXTHANDLER2_HXX
+#define OOX_CORE_CONTEXTHANDLER2_HXX
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+const sal_Int32 XML_ROOT_CONTEXT = SAL_MAX_INT32;
+
+// ============================================================================
+
+struct ElementInfo;
+
+/** Helper class that provides a context stack.
+
+ Fragment handlers and context handlers derived from this helper class will
+ track the identifiers of the visited elements in a stack. The idea is to
+ use the same instance of a fragment handler or context handler to process
+ several nested elements in an XML stream. For that, the abstract function
+ onCreateContext() has to return 'this' for the passed element.
+
+ Derived classes have to implement the createFastChildContext(),
+ startFastElement(), characters(), and endFastElement() functions from the
+ com.sun.star.xml.sax.XFastContextHandler interface by simply forwarding
+ them to the respective implCreateChildContext(), implStartElement(),
+ implCharacters(), and implEndElement() functions of this helper. This is
+ implemented already in the classes ContextHandler2 and FragmentHandler2.
+ The new abstract functions have to be implemented according to the elements
+ to be processed.
+
+ Similarly, for binary import, derived classes have to forward the
+ createRecordContext(), startRecord(), and endRecord() functions from the
+ ContextHandler class to the implCreateRecordContext(), implStartRecord(),
+ and implEndRecord() functions of this helper. Again, this is implemented
+ already in the classes ContextHandler2 and FragmentHandler2.
+ */
+class ContextHandler2Helper
+{
+public:
+ explicit ContextHandler2Helper( bool bEnableTrimSpace );
+ explicit ContextHandler2Helper( const ContextHandler2Helper& rParent );
+ virtual ~ContextHandler2Helper();
+
+ // allow instances to be stored in ::rtl::Reference
+ virtual void SAL_CALL acquire() throw() = 0;
+ virtual void SAL_CALL release() throw() = 0;
+
+ // interface --------------------------------------------------------------
+
+ /** Will be called to create a context handler for the passed element.
+
+ Usually 'this' can be returned to improve performance by reusing the
+ same instance to process several elements. Used by OOXML import only.
+ */
+ virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) = 0;
+
+ /** Will be called when a new element has been started.
+
+ This function is called at the context handler returned from
+ onCreateContext(), or, for root elements of an XML stream, at the
+ fragment handler itself.
+
+ The current element identifier can be accessed with getCurrentElement()
+ or isCurrentElement(). Used by OOXML import only.
+ */
+ virtual void onStartElement( const AttributeList& rAttribs ) = 0;
+
+ /** Will be called before a new child element starts, or if the current
+ element is about to be left.
+
+ This helper function collects all text fragments received by the
+ characters() function (such as encoded characters which are passed in
+ separate calls to the characters() function), and passes the
+ concatenated and trimmed string.
+
+ The current element identifier can be accessed with getCurrentElement()
+ or isCurrentElement(). Used by OOXML import only.
+ */
+ virtual void onCharacters( const ::rtl::OUString& rChars ) = 0;
+
+ /** Will be called when the current element is about to be left.
+
+ The current element identifier can be accessed with getCurrentElement()
+ or isCurrentElement(). Used by OOXML import only.
+ */
+ virtual void onEndElement() = 0;
+
+ /** Will be called to create a context handler for the passed record.
+
+ Usually 'this' can be returned to improve performance by reusing the
+ same instance to process several records. Used by BIFF import only.
+ */
+ virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) = 0;
+
+ /** Will be called when a new record block in a binary stream has been
+ started.
+
+ The current record identifier can be accessed with getCurrentElement()
+ or isCurrentElement(). Used by BIFF import only.
+ */
+ virtual void onStartRecord( SequenceInputStream& rStrm ) = 0;
+
+ /** Will be called when the current record block is about to be left.
+
+ The current record identifier can be accessed with getCurrentElement()
+ or isCurrentElement(). Used by BIFF import only.
+ */
+ virtual void onEndRecord() = 0;
+
+ // helpers ----------------------------------------------------------------
+
+ /** Returns the identifier of the currently processed element. */
+ sal_Int32 getCurrentElement() const;
+
+ /** Returns true, if nElement contains the identifier of the currently
+ processed element. */
+ inline bool isCurrentElement( sal_Int32 nElement ) const
+ { return getCurrentElement() == nElement; }
+
+ /** Returns true, if either nElement1 or nElement2 contain the identifier
+ of the currently processed element. */
+ inline bool isCurrentElement( sal_Int32 nElement1, sal_Int32 nElement2 ) const
+ { return isCurrentElement( nElement1 ) || isCurrentElement( nElement2 ); }
+
+ /** Returns the identifier of the specified parent element. */
+ sal_Int32 getParentElement( sal_Int32 nCountBack = 1 ) const;
+
+ /** Returns true, if nElement contains the identifier of the specified
+ parent element. */
+ inline sal_Int32 isParentElement( sal_Int32 nElement, sal_Int32 nCountBack = 1 ) const
+ { return getParentElement( nCountBack ) == nElement; }
+
+ /** Returns true, if the element currently processed is the root element of
+ the context or fragment handler. */
+ bool isRootElement() const;
+
+ // implementation ---------------------------------------------------------
+
+protected:
+ /** Must be called from createFastChildContext() in derived classes. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler >
+ implCreateChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs );
+
+ /** Must be called from startFastElement() in derived classes. */
+ void implStartElement(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs );
+
+ /** Must be called from characters() in derived classes. */
+ void implCharacters( const ::rtl::OUString& rChars );
+
+ /** Must be called from endFastElement() in derived classes. */
+ void implEndElement( sal_Int32 nElement );
+
+ /** Must be called from createRecordContext() in derived classes. */
+ ContextHandlerRef implCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ /** Must be called from startRecord() in derived classes. */
+ void implStartRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ /** Must be called from endRecord() in derived classes. */
+ void implEndRecord( sal_Int32 nRecId );
+
+private:
+ ContextHandler2Helper& operator=( const ContextHandler2Helper& );
+
+ ElementInfo& pushElementInfo( sal_Int32 nElement );
+ void popElementInfo();
+ void processCollectedChars();
+
+private:
+ typedef ::std::vector< ElementInfo > ContextStack;
+ typedef ::boost::shared_ptr< ContextStack > ContextStackRef;
+
+ ContextStackRef mxContextStack; /// Stack of all processed elements.
+ size_t mnRootStackSize; /// Stack size on construction time.
+ bool mbEnableTrimSpace; /// True = trim whitespace in characters().
+};
+
+// ============================================================================
+
+class ContextHandler2 : public ContextHandler, public ContextHandler2Helper
+{
+public:
+ explicit ContextHandler2( ContextHandler2Helper& rParent );
+ virtual ~ContextHandler2();
+
+ // resolve ambiguity from base classes
+ virtual void SAL_CALL acquire() throw() { ContextHandler::acquire(); }
+ virtual void SAL_CALL release() throw() { ContextHandler::release(); }
+
+ // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL characters( const ::rtl::OUString& rChars )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL endFastElement( sal_Int32 nElement )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // oox.core.ContextHandler interface --------------------------------------
+
+ virtual ContextHandlerRef createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void startRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void endRecord( sal_Int32 nRecId );
+
+ // oox.core.ContextHandler2Helper interface -------------------------------
+
+ virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+ virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+ virtual void onEndRecord();
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/fastparser.hxx b/oox/inc/oox/core/fastparser.hxx
new file mode 100755
index 000000000000..967c42474dcc
--- /dev/null
+++ b/oox/inc/oox/core/fastparser.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_FASTPARSER_HXX
+#define OOX_CORE_FASTPARSER_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
+
+namespace oox {
+ struct NamespaceMap;
+ class StorageBase;
+}
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+/** Wrapper for a fast SAX parser that works on automatically generated OOXML
+ token and namespace identifiers.
+ */
+class FastParser
+{
+public:
+ explicit FastParser(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ~FastParser();
+
+ /** Registers an OOXML namespace at the parser. */
+ void registerNamespace( sal_Int32 nNamespaceId )
+ throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
+
+ /** Sets the passed document handler that will receive the SAX parser events. */
+ void setDocumentHandler(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler >& rxDocHandler )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ /** Parses the passed SAX input source.
+ @param bCloseStream True = closes the stream in the input source after parsing. */
+ void parseStream( const ::com::sun::star::xml::sax::InputSource& rInputSource, bool bCloseStream = false )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
+
+ /** Parses the passed input stream.
+ @param bCloseStream True = closes the passed stream after parsing. */
+ void parseStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream,
+ const ::rtl::OUString& rStreamName, bool bCloseStream = false )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
+
+ /** Parses a stream from the passed storage with the specified name.
+ @param bCloseStream True = closes the stream after parsing. */
+ void parseStream( StorageBase& rStorage, const ::rtl::OUString& rStreamName, bool bCloseStream = false )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastParser >
+ mxParser;
+ const NamespaceMap& mrNamespaceMap;
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/fasttokenhandler.hxx b/oox/inc/oox/core/fasttokenhandler.hxx
new file mode 100644
index 000000000000..a6c73de9842b
--- /dev/null
+++ b/oox/inc/oox/core/fasttokenhandler.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_FASTTOKENHANDLER_HXX
+#define OOX_CORE_FASTTOKENHANDLER_HXX
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+namespace oox { class TokenMap; }
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+typedef ::cppu::WeakImplHelper2< ::com::sun::star::lang::XServiceInfo, ::com::sun::star::xml::sax::XFastTokenHandler > FastTokenHandlerBase;
+
+/** Wrapper implementing the com.sun.star.xml.sax.XFastTokenHandler API interface
+ that provides access to the tokens generated from the internal token name list.
+ */
+class FastTokenHandler : public FastTokenHandlerBase
+{
+public:
+ explicit FastTokenHandler();
+ virtual ~FastTokenHandler();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException);
+
+ // XFastTokenHandler
+ virtual sal_Int32 SAL_CALL getToken( const ::rtl::OUString& rIdentifier ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getIdentifier( sal_Int32 nToken ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getUTF8Identifier( sal_Int32 nToken ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getTokenFromUTF8( const ::com::sun::star::uno::Sequence< sal_Int8 >& Identifier ) throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ const TokenMap& mrTokenMap; /// Reference to global token map singleton.
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx
new file mode 100644
index 000000000000..80dc233491d4
--- /dev/null
+++ b/oox/inc/oox/core/filterbase.hxx
@@ -0,0 +1,310 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_FILTERBASE_HXX
+#define OOX_CORE_FILTERBASE_HXX
+
+#include <memory>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/implbase5.hxx>
+#include "oox/helper/binarystreambase.hxx"
+#include "oox/helper/storagebase.hxx"
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct DeviceInfo; }
+ namespace frame { class XFrame; }
+ namespace frame { class XModel; }
+ namespace graphic { class XGraphic; }
+ namespace io { class XInputStream; }
+ namespace io { class XOutputStream; }
+ namespace io { class XStream; }
+ namespace lang { class XMultiComponentFactory; }
+ namespace lang { class XMultiServiceFactory; }
+ namespace task { class XInteractionHandler; }
+ namespace task { class XStatusIndicator; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace comphelper {
+ class IDocPasswordVerifier;
+ class MediaDescriptor;
+}
+
+namespace oox {
+ class GraphicHelper;
+ class ModelObjectHelper;
+}
+
+namespace oox { namespace ole {
+ class OleObjectHelper;
+ class VbaProject;
+} }
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+struct FilterBaseImpl;
+
+typedef ::cppu::WeakImplHelper5<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::document::XImporter,
+ ::com::sun::star::document::XExporter,
+ ::com::sun::star::document::XFilter >
+ FilterBaseBase;
+
+class OOX_DLLPUBLIC FilterBase : public FilterBaseBase, public ::cppu::BaseMutex
+{
+public:
+ explicit FilterBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ~FilterBase();
+
+ /** Returns true, if filter is an import filter. */
+ bool isImportFilter() const;
+ /** Returns true, if filter is an export filter. */
+ bool isExportFilter() const;
+
+ /** Derived classes implement import of the entire document. */
+ virtual bool importDocument() = 0;
+
+ /** Derived classes implement export of the entire document. */
+ virtual bool exportDocument() = 0;
+
+ // ------------------------------------------------------------------------
+
+ /** Returns the specified argument passed through the XInitialization interface. */
+ ::com::sun::star::uno::Any getArgument( const ::rtl::OUString& rArgName ) const;
+
+ /** Returns the component context passed in the filter constructor (always existing). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&
+ getComponentContext() const;
+
+ /** Returns the component service factory (always existing). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiComponentFactory >&
+ getComponentFactory() const;
+
+ /** Returns the multi service factory of the component (always existing). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ getServiceFactory() const;
+
+ /** Returns the document model (always existing). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >&
+ getModel() const;
+
+ /** Returns the service factory provided by the document model (always existing). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ getModelFactory() const;
+
+ /** Returns the frame that will contain the document model (may be null). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >&
+ getTargetFrame() const;
+
+ /** Returns the status indicator (may be null). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator >&
+ getStatusIndicator() const;
+
+ /** Returns the status interaction handler (may be null). */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >&
+ getInteractionHandler() const;
+
+ /** Returns the media descriptor. */
+ ::comphelper::MediaDescriptor& getMediaDescriptor() const;
+
+ /** Returns the URL of the imported or exported file. */
+ const ::rtl::OUString& getFileUrl() const;
+
+ /** Returns an absolute URL for the passed relative or absolute URL. */
+ ::rtl::OUString getAbsoluteUrl( const ::rtl::OUString& rUrl ) const;
+
+ /** Returns the base storage of the imported/exported file. */
+ StorageRef getStorage() const;
+
+ /** Opens and returns the specified sub storage from the base storage.
+
+ @param rStorageName
+ The name of the embedded storage. The name may contain slashes to
+ open storages from embedded substorages.
+ @param bCreateMissing
+ True = create missing sub storages (for export filters).
+ */
+ StorageRef openSubStorage(
+ const ::rtl::OUString& rStorageName,
+ bool bCreateMissing ) const;
+
+ /** Opens and returns the specified input stream from the base storage.
+
+ @param rStreamName
+ The name of the embedded storage stream. The name may contain
+ slashes to open streams from embedded substorages. If base stream
+ access has been enabled in the storage, the base stream can be
+ accessed by passing an empty string as stream name.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ openInputStream( const ::rtl::OUString& rStreamName ) const;
+
+ /** Opens and returns the specified output stream from the base storage.
+
+ @param rStreamName
+ The name of the embedded storage stream. The name may contain
+ slashes to open streams from embedded substorages. If base stream
+ access has been enabled in the storage, the base stream can be
+ accessed by passing an empty string as stream name.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ openOutputStream( const ::rtl::OUString& rStreamName ) const;
+
+ /** Commits changes to base storage (and substorages) */
+ void commitStorage() const;
+
+ // helpers ----------------------------------------------------------------
+
+ /** Returns a helper for the handling of graphics and graphic objects. */
+ GraphicHelper& getGraphicHelper() const;
+
+ /** Returns a helper with containers for various named drawing objects for
+ the imported document. */
+ ModelObjectHelper& getModelObjectHelper() const;
+
+ /** Returns a helper for the handling of OLE obejcts. */
+ ::oox::ole::OleObjectHelper& getOleObjectHelper() const;
+
+ /** Returns the VBA project manager. */
+ ::oox::ole::VbaProject& getVbaProject() const;
+
+ /** Requests the encryption data from the media descriptor or from the user. On
+ success, the encryption data will be inserted into the media descriptor. */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >
+ requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const;
+
+ /** Imports the raw binary data from the specified stream.
+ @return True, if the data could be imported from the stream. */
+ bool importBinaryData( StreamDataSequence& orDataSeq, const ::rtl::OUString& rStreamName );
+
+ // com.sun.star.lang.XServiceInfo interface -------------------------------
+
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& rServiceName )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.lang.XInitialization interface ----------------------------
+
+ /** Receives user defined arguments.
+
+ @param rArgs
+ the sequence of arguments passed to the filter. The implementation
+ expects one or two arguments. The first argument shall be the
+ com.sun.star.lang.XMultiServiceFactory interface of the global
+ service factory. The optional second argument may contain a
+ sequence of com.sun.star.beans.NamedValue objects. The different
+ filter implemetations may support different arguments.
+ */
+ virtual void SAL_CALL initialize(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rArgs )
+ throw( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.document.XImporter interface ------------------------------
+
+ virtual void SAL_CALL setTargetDocument(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& rxDocument )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.document.XExporter interface ------------------------------
+
+ virtual void SAL_CALL setSourceDocument(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& rxDocument )
+ throw( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.document.XFilter interface --------------------------------
+
+ virtual sal_Bool SAL_CALL filter(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL cancel()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // ------------------------------------------------------------------------
+protected:
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ implGetInputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >
+ implGetOutputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+
+private:
+ void setMediaDescriptor(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq );
+
+ /** Derived classes may create a specialized graphic helper, e.g. for
+ resolving palette colors. */
+ virtual GraphicHelper* implCreateGraphicHelper() const;
+
+ /** Derived classes create a VBA project manager object. */
+ virtual ::oox::ole::VbaProject* implCreateVbaProject() const = 0;
+
+ virtual ::rtl::OUString implGetImplementationName() const = 0;
+
+ virtual StorageRef implCreateStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const = 0;
+ virtual StorageRef implCreateStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const = 0;
+
+private:
+ ::std::auto_ptr< FilterBaseImpl > mxImpl;
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/filterdetect.hxx b/oox/inc/oox/core/filterdetect.hxx
new file mode 100644
index 000000000000..7eb283f5056b
--- /dev/null
+++ b/oox/inc/oox/core/filterdetect.hxx
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_FILTERDETECT_HXX
+#define OOX_CORE_FILTERDETECT_HXX
+
+#include <vector>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XInputStream; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace comphelper { class MediaDescriptor; }
+
+namespace oox { class AttributeList; }
+
+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< ::com::sun::star::xml::sax::XFastDocumentHandler >
+{
+public:
+ explicit FilterDetectDocHandler( ::rtl::OUString& rFilter );
+ virtual ~FilterDetectDocHandler();
+
+ // XFastDocumentHandler
+ virtual void SAL_CALL startDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ // XFastContextHandler
+ virtual void SAL_CALL startFastElement( sal_Int32 nElement, 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);
+ virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL endFastElement( sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< 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);
+ virtual ::com::sun::star::uno::Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ void parseRelationship( const AttributeList& rAttribs );
+
+ ::rtl::OUString getFilterNameFromContentType( const ::rtl::OUString& rContentType ) const;
+ void parseContentTypesDefault( const AttributeList& rAttribs );
+ void parseContentTypesOverride( const AttributeList& rAttribs );
+
+private:
+ typedef ::std::vector< sal_Int32 > ContextVector;
+
+ ::rtl::OUString& mrFilterName;
+ ContextVector maContextStack;
+ ::rtl::OUString maTargetPath;
+};
+
+// ============================================================================
+
+class OOX_DLLPUBLIC FilterDetect : public ::cppu::WeakImplHelper2< ::com::sun::star::document::XExtendedFilterDetection, ::com::sun::star::lang::XServiceInfo >
+{
+public:
+ explicit FilterDetect( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ~FilterDetect();
+
+ /** Tries to extract an unencrypted ZIP package from the passed media
+ descriptor.
+
+ First, this function checks if the input stream provided by the media
+ descriptor property 'InputStream' contains a ZIP package. If yes, this
+ stream is returned.
+
+ Second, this function checks if the 'ComponentData' property exists and
+ contains a sequence of com.sun.star.beans.NamedValue. If yes, a named
+ value is searched with the name 'DecryptedPackage' and a value of type
+ com.sun.star.io.XStream. If the input stream provided by this XStream
+ contains a ZIP package, this input stream is returned.
+
+ Third, this function checks if the input stream of the media descriptor
+ contains an OLE package. If yes, it checks the existence of the streams
+ 'EncryptionInfo' and 'EncyptedPackage' and tries to decrypt the package
+ into a temporary file. This may include requesting a password from the
+ media descriptor property 'Password' or from the user, using the
+ interaction handler provided by the descriptor. On success, and if the
+ decrypted package is a ZIP package, the XStream of the temporary file
+ is stored in the property 'ComponentData' of the media descriptor and
+ its input stream is returned.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ extractUnencryptedPackage( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+
+ // com.sun.star.lang.XServiceInfo interface -------------------------------
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.document.XExtendedFilterDetection interface ---------------
+
+ /** Detects MS Office 2007 file types and supports package decryption.
+
+ The following file types are detected:
+ - MS Word 2007 XML Document (*.docx, *.docm)
+ - MS Word 2007 XML Template (*.dotx, *.dotm)
+ - MS Excel 2007 XML Document (*.xlsx, *.xlsm)
+ - MS Excel 2007 BIFF12 Document (*.xlsb)
+ - MS Excel 2007 XML Template (*.xltx, *.xltm)
+ - MS Powerpoint 2007 XML Document (*.pptx, *.pptm)
+ - MS Powerpoint 2007 XML Template (*.potx, *.potm)
+
+ If the package is encrypted, the detection tries to decrypt it into a
+ temporary file. The user may be asked for a password. The XStream
+ interface of the temporary file will be stored in the 'ComponentData'
+ property of the passed media descriptor.
+ */
+ virtual ::rtl::OUString SAL_CALL
+ detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxContext;
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/fragmenthandler.hxx b/oox/inc/oox/core/fragmenthandler.hxx
new file mode 100644
index 000000000000..ba3164a74da8
--- /dev/null
+++ b/oox/inc/oox/core/fragmenthandler.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_FRAGMENTHANDLER_HXX
+#define OOX_CORE_FRAGMENTHANDLER_HXX
+
+#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include "oox/core/contexthandler.hxx"
+#include "oox/core/relations.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XInputStream; }
+} } }
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+/** Base data of a fragment.
+
+ This data is stored in a separate struct to make it accessible in every
+ child context handler of the fragment.
+ */
+struct FragmentBaseData
+{
+ XmlFilterBase& mrFilter;
+ const ::rtl::OUString maFragmentPath;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >
+ mxLocator;
+ RelationsRef mxRelations;
+
+ explicit FragmentBaseData(
+ XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ RelationsRef xRelations );
+};
+
+// ============================================================================
+
+/** Describes record identifiers used to create contexts in a binary stream.
+
+ If a record is used to start a new context, usually the record identifier
+ increased by 1 is used to mark the end of this context, e.g. the Excel
+ record SHEETDATA == 0x0091 starts the <sheetData> context, and the record
+ SHEETDATA_END == 0x0092 ends this context. But some records are used to
+ start a new context, though there is no identifier to end this context,
+ e.g. the ROW or EXTROW records. These record identifiers can be marked by
+ setting the mnEndRecId member of this struct to -1.
+ */
+struct RecordInfo
+{
+ sal_Int32 mnStartRecId; /// Record identifier for context start.
+ sal_Int32 mnEndRecId; /// Record identifier for context end, -1 = no record.
+};
+
+// ============================================================================
+
+typedef ::cppu::ImplInheritanceHelper1< ContextHandler, ::com::sun::star::xml::sax::XFastDocumentHandler > FragmentHandlerImplBase;
+
+class FragmentHandler : public FragmentHandlerImplBase
+{
+public:
+ explicit FragmentHandler( XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath );
+ virtual ~FragmentHandler();
+
+ /** Returns the com.sun.star.xml.sax.XFastContextHandler interface of this context. */
+ inline ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler >
+ getFastContextHandler() { return static_cast< ContextHandler* >( this ); }
+
+ // com.sun.star.xml.sax.XFastDocumentHandler interface --------------------
+
+ virtual void SAL_CALL startDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& rxLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
+
+ virtual void SAL_CALL startFastElement( ::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);
+ virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) 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);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ // XML stream handling ----------------------------------------------------
+
+ /** Opens the fragment stream referred by the own fragment path. Derived
+ classes may provide specilized stream implementations. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ openFragmentStream() const;
+
+ // binary records ---------------------------------------------------------
+
+ virtual const RecordInfo* getRecordInfos() const;
+
+protected:
+ explicit FragmentHandler( XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, RelationsRef xRelations );
+};
+
+typedef ::rtl::Reference< FragmentHandler > FragmentHandlerRef;
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/fragmenthandler2.hxx b/oox/inc/oox/core/fragmenthandler2.hxx
new file mode 100644
index 000000000000..51408005ecdd
--- /dev/null
+++ b/oox/inc/oox/core/fragmenthandler2.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_FRAGMENTHANDLER2_HXX
+#define OOX_CORE_FRAGMENTHANDLER2_HXX
+
+#include "oox/core/contexthandler2.hxx"
+#include "oox/core/fragmenthandler.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+class FragmentHandler2 : public FragmentHandler, public ContextHandler2Helper
+{
+public:
+ explicit FragmentHandler2(
+ XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ bool bEnableTrimSpace = true );
+ virtual ~FragmentHandler2();
+
+ // resolve ambiguity from base classes
+ virtual void SAL_CALL acquire() throw() { FragmentHandler::acquire(); }
+ virtual void SAL_CALL release() throw() { FragmentHandler::release(); }
+
+ // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL characters( const ::rtl::OUString& rChars )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL endFastElement( sal_Int32 nElement )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.xml.sax.XFastDocumentHandler interface --------------------
+
+ virtual void SAL_CALL startDocument()
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL endDocument()
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // oox.core.ContextHandler interface --------------------------------------
+
+ virtual ContextHandlerRef createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void startRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void endRecord( sal_Int32 nRecId );
+
+ // oox.core.ContextHandler2Helper interface -------------------------------
+
+ virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+ virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+ virtual void onEndRecord();
+
+ // oox.core.FragmentHandler2 interface ------------------------------------
+
+ virtual void initializeImport();
+ virtual void finalizeImport();
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/recordparser.hxx b/oox/inc/oox/core/recordparser.hxx
new file mode 100644
index 000000000000..4600be3ff832
--- /dev/null
+++ b/oox/inc/oox/core/recordparser.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_RECORDPARSER_HXX
+#define OOX_CORE_RECORDPARSER_HXX
+
+#include <map>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#include <rtl/ref.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+
+namespace oox {
+namespace core {
+
+class FragmentHandler;
+struct RecordInfo;
+
+namespace prv { class Locator; }
+namespace prv { class ContextStack; }
+
+// ============================================================================
+
+struct RecordInputSource
+{
+ BinaryInputStreamRef mxInStream;
+ ::rtl::OUString maPublicId;
+ ::rtl::OUString maSystemId;
+};
+
+// ============================================================================
+
+class RecordParser
+{
+public:
+ explicit RecordParser();
+ virtual ~RecordParser();
+
+ void setFragmentHandler( const ::rtl::Reference< FragmentHandler >& rxHandler );
+
+ void parseStream( const RecordInputSource& rInputSource )
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException );
+
+ inline const RecordInputSource& getInputSource() const { return maSource; }
+
+private:
+ /** Returns a RecordInfo struct that contains the passed record identifier
+ as context start identifier. */
+ const RecordInfo* getStartRecordInfo( sal_Int32 nRecId ) const;
+ /** Returns a RecordInfo struct that contains the passed record identifier
+ as context end identifier. */
+ const RecordInfo* getEndRecordInfo( sal_Int32 nRecId ) const;
+
+private:
+ typedef ::std::map< sal_Int32, RecordInfo > RecordInfoMap;
+
+ RecordInputSource maSource;
+ ::rtl::Reference< FragmentHandler > mxHandler;
+ ::rtl::Reference< prv::Locator > mxLocator;
+ ::std::auto_ptr< prv::ContextStack > mxStack;
+ RecordInfoMap maStartMap;
+ RecordInfoMap maEndMap;
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/core/relations.hxx b/oox/inc/oox/core/relations.hxx
new file mode 100755
index 000000000000..285c4ed947e4
--- /dev/null
+++ b/oox/inc/oox/core/relations.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_RELATIONS
+#define OOX_CORE_RELATIONS
+
+#include <map>
+#include <boost/shared_ptr.hpp>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+/** Expands to an OUString containing an 'officeDocument' relation type created
+ from the passed literal(!) ASCII(!) character array. */
+#define CREATE_OFFICEDOC_RELATION_TYPE( ascii ) \
+ CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/" ascii )
+
+/** Expands to an OUString containing a 'package' relation type created from
+ the passed literal(!) ASCII(!) character array. */
+#define CREATE_PACKAGE_RELATION_TYPE( ascii ) \
+ CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships/" ascii )
+
+/** Expands to an OUString containing an MS Office specific relation type
+ created from the passed literal(!) ASCII(!) character array. */
+#define CREATE_MSOFFICE_RELATION_TYPE( ascii ) \
+ CREATE_OUSTRING( "http://schemas.microsoft.com/office/2006/relationships/" ascii )
+
+// ============================================================================
+
+struct Relation
+{
+ ::rtl::OUString maId;
+ ::rtl::OUString maType;
+ ::rtl::OUString maTarget;
+ bool mbExternal;
+
+ inline explicit Relation() : mbExternal( false ) {}
+};
+
+// ============================================================================
+
+class Relations;
+typedef ::boost::shared_ptr< Relations > RelationsRef;
+
+class Relations : public ::std::map< ::rtl::OUString, Relation >
+{
+public:
+ explicit Relations( const ::rtl::OUString& rFragmentPath );
+
+ /** Returns the path of the fragment this relations collection is related to. */
+ inline const ::rtl::OUString& getFragmentPath() const { return maFragmentPath; }
+
+ /** Returns the relation with the passed relation identifier. */
+ const Relation* getRelationFromRelId( const ::rtl::OUString& rId ) const;
+ /** Returns the first relation with the passed type. */
+ const Relation* getRelationFromFirstType( const ::rtl::OUString& rType ) const;
+ /** Finds all relations associated with the passed type. */
+ RelationsRef getRelationsFromType( const ::rtl::OUString& rType ) const;
+
+ /** Returns the external target of the relation with the passed relation identifier. */
+ ::rtl::OUString getExternalTargetFromRelId( const ::rtl::OUString& rRelId ) const;
+ /** Returns the external target of the first relation with the passed type. */
+ ::rtl::OUString getExternalTargetFromFirstType( const ::rtl::OUString& rType ) const;
+
+ /** Returns the full fragment path for the target of the passed relation. */
+ ::rtl::OUString getFragmentPathFromRelation( const Relation& rRelation ) const;
+ /** Returns the full fragment path for the passed relation identifier. */
+ ::rtl::OUString getFragmentPathFromRelId( const ::rtl::OUString& rRelId ) const;
+ /** Returns the full fragment path for the first relation of the passed type. */
+ ::rtl::OUString getFragmentPathFromFirstType( const ::rtl::OUString& rType ) const;
+
+private:
+ ::rtl::OUString maFragmentPath;
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif // OOX_CORE_RELATIONS
diff --git a/oox/inc/oox/core/relationshandler.hxx b/oox/inc/oox/core/relationshandler.hxx
new file mode 100644
index 000000000000..b2da8d59c39f
--- /dev/null
+++ b/oox/inc/oox/core/relationshandler.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_RELATIONSHANDLER
+#define OOX_CORE_RELATIONSHANDLER
+
+#include "oox/core/fragmenthandler.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+class RelationsFragment : public FragmentHandler
+{
+public:
+ explicit RelationsFragment(
+ XmlFilterBase& rFilter,
+ RelationsRef xRelations );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ RelationsRef mxRelations;
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif // OOX_CORE_RELATIONSHANDLER
diff --git a/oox/inc/oox/core/xmlfilterbase.hxx b/oox/inc/oox/core/xmlfilterbase.hxx
new file mode 100644
index 000000000000..11d2d488c8b6
--- /dev/null
+++ b/oox/inc/oox/core/xmlfilterbase.hxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_XMLFILTERBASE_HXX
+#define OOX_CORE_XMLFILTERBASE_HXX
+
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <rtl/ref.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/core/relations.hxx"
+#include "oox/drawingml/table/tablestylelist.hxx"
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameContainer; }
+ namespace document { class XDocumentProperties; }
+ namespace xml { namespace sax { class XLocator; } }
+ namespace xml { namespace sax { class XFastDocumentHandler; } }
+} } }
+
+namespace oox {
+ namespace drawingml { class Theme; }
+ namespace drawingml { namespace chart { class ChartConverter; } }
+ namespace vml { class Drawing; }
+}
+
+namespace sax_fastparser {
+ class FastSerializerHelper;
+
+ typedef boost::shared_ptr< FastSerializerHelper > FSHelperPtr;
+}
+
+namespace oox {
+namespace core {
+
+class FragmentHandler;
+
+// ============================================================================
+
+struct TextField {
+ com::sun::star::uno::Reference< com::sun::star::text::XText > xText;
+ com::sun::star::uno::Reference< com::sun::star::text::XTextCursor > xTextCursor;
+ com::sun::star::uno::Reference< com::sun::star::text::XTextField > xTextField;
+};
+typedef std::vector< TextField > TextFieldStack;
+
+// ============================================================================
+
+struct XmlFilterBaseImpl;
+
+class OOX_DLLPUBLIC XmlFilterBase : public FilterBase
+{
+public:
+ explicit XmlFilterBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ~XmlFilterBase();
+
+ /** Has to be implemented by each filter, returns the current theme. */
+ virtual const ::oox::drawingml::Theme*
+ getCurrentTheme() const = 0;
+
+ /** Has to be implemented by each filter to return the collection of VML shapes. */
+ virtual ::oox::vml::Drawing* getVmlDrawing() = 0;
+
+ /** Has to be implemented by each filter, returns a filter-specific chart
+ converter object, that should be global per imported document. */
+ virtual ::oox::drawingml::chart::ChartConverter& getChartConverter() = 0;
+
+ /** Has to be implemented by each filter to return the table style list. */
+ virtual const ::oox::drawingml::table::TableStyleListPtr getTableStyles() = 0;
+
+ // ------------------------------------------------------------------------
+
+ /** Returns the fragment path from the first relation of the passed type,
+ used for fragments referred by the root relations. */
+ ::rtl::OUString getFragmentPathFromFirstType( const ::rtl::OUString& rType );
+
+ /** Imports a fragment using the passed fragment handler, which contains
+ the full path to the fragment stream.
+
+ @return True, if the fragment could be imported.
+ */
+ bool importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler );
+
+ /** Imports the relations fragment associated with the specified fragment.
+
+ @return The relations collection of the specified fragment.
+ */
+ RelationsRef importRelations( const ::rtl::OUString& rFragmentPath );
+
+ /** Adds new relation.
+
+ @param rType
+ Relation type.
+
+ @param rTarget
+ Relation target.
+
+ @return Added relation Id.
+ */
+ ::rtl::OUString addRelation( const ::rtl::OUString& rType, const ::rtl::OUString& rTarget, bool bExternal = false );
+
+ /** Adds new relation to part's relations.
+
+ @param rPartName
+ Part name the relations are related to. The relations will be stored in <rPartName::path>/_rels/<rPartName::name>.rels.
+
+ @param rType
+ Relation type.
+
+ @param rTarget
+ Relation target.
+
+ @return Added relation Id.
+ */
+ ::rtl::OUString addRelation( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutputStream, const ::rtl::OUString& rType, const ::rtl::OUString& rTarget, bool bExternal = false );
+
+ /** Returns a stack of used textfields, used by the pptx importer to replace links to slidepages with rhe real page name */
+ TextFieldStack& getTextFieldStack() const;
+
+ /** Opens and returns the specified output stream from the base storage with specified media type.
+
+ @param rStreamName
+ The name of the embedded storage stream. The name may contain
+ slashes to open streams from embedded substorages. If base stream
+ access has been enabled in the storage, the base stream can be
+ accessed by passing an empty string as stream name.
+
+ @param rMediaType
+ The media type string, used in [Content_Types].xml stream in base
+ storage.
+
+ @return The opened output stream.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ openFragmentStream(
+ const ::rtl::OUString& rStreamName,
+ const ::rtl::OUString& rMediaType );
+
+ /** Opens specified output stream from the base storage with specified
+ media type and returns new fast serializer for that stream.
+
+ @param rStreamName
+ The name of the embedded storage stream. The name may contain
+ slashes to open streams from embedded substorages. If base stream
+ access has been enabled in the storage, the base stream can be
+ accessed by passing an empty string as stream name.
+
+ @param rMediaType
+ The media type string, used in [Content_Types].xml stream in base
+ storage.
+
+ @return newly created serializer helper.
+ */
+ ::sax_fastparser::FSHelperPtr
+ openFragmentStreamWithSerializer(
+ const ::rtl::OUString& rStreamName,
+ const ::rtl::OUString& rMediaType );
+
+ /** Returns new unique ID for exported document.
+
+ @return newly created ID.
+ */
+ inline sal_Int32 GetUniqueId() { return mnMaxDocId++; }
+ inline ::rtl::OString GetUniqueIdOString() { return ::rtl::OString::valueOf( mnMaxDocId++ ); }
+ inline ::rtl::OUString GetUniqueIdOUString() { return ::rtl::OUString::valueOf( mnMaxDocId++ ); }
+
+ /** Write the document properties into into the current OPC package.
+
+ @param xProperties The document properties to export.
+
+ @return *this
+ */
+ XmlFilterBase& exportDocumentProperties( ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties > xProperties );
+
+protected:
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ implGetInputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+
+private:
+ virtual StorageRef implCreateStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const;
+ virtual StorageRef implCreateStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const;
+
+private:
+ ::std::auto_ptr< XmlFilterBaseImpl > mxImpl;
+ sal_Int32 mnRelId;
+ sal_Int32 mnMaxDocId;
+};
+
+typedef ::rtl::Reference< XmlFilterBase > XmlFilterRef;
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/dllapi.h b/oox/inc/oox/dllapi.h
new file mode 100644
index 000000000000..035f11fcf426
--- /dev/null
+++ b/oox/inc/oox/dllapi.h
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_OOX_DLLAPI_H
+#define INCLUDED_OOX_DLLAPI_H
+
+#include "sal/types.h"
+
+#if defined OOX_DLLIMPLEMENTATION
+#define OOX_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define OOX_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/axiscontext.hxx b/oox/inc/oox/drawingml/chart/axiscontext.hxx
new file mode 100644
index 000000000000..13c550e881d4
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/axiscontext.hxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_AXISCONTEXT_HXX
+#define OOX_DRAWINGML_CHART_AXISCONTEXT_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct AxisDispUnitsModel;
+
+/** Handler for a value axis display units context (c:dispUnits element).
+ */
+class AxisDispUnitsContext : public ContextBase< AxisDispUnitsModel >
+{
+public:
+ explicit AxisDispUnitsContext( ::oox::core::ContextHandler2Helper& rParent, AxisDispUnitsModel& rModel );
+ virtual ~AxisDispUnitsContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct AxisModel;
+
+/** Base class for axis context handlers (c:catAx, c:dateAx, c:serAx, c:valAx
+ elements).
+ */
+class AxisContextBase : public ContextBase< AxisModel >
+{
+public:
+ explicit AxisContextBase( ::oox::core::ContextHandler2Helper& rParent, AxisModel& rModel );
+ virtual ~AxisContextBase();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a category axis context (c:catAx element).
+ */
+class CatAxisContext : public AxisContextBase
+{
+public:
+ explicit CatAxisContext( ::oox::core::ContextHandler2Helper& rParent, AxisModel& rModel );
+ virtual ~CatAxisContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a date axis context (c:dateAx element).
+ */
+class DateAxisContext : public AxisContextBase
+{
+public:
+ explicit DateAxisContext( ::oox::core::ContextHandler2Helper& rParent, AxisModel& rModel );
+ virtual ~DateAxisContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a series axis context (c:serAx element).
+ */
+class SerAxisContext : public AxisContextBase
+{
+public:
+ explicit SerAxisContext( ::oox::core::ContextHandler2Helper& rParent, AxisModel& rModel );
+ virtual ~SerAxisContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a value axis context (c:valAx element).
+ */
+class ValAxisContext : public AxisContextBase
+{
+public:
+ explicit ValAxisContext( ::oox::core::ContextHandler2Helper& rParent, AxisModel& rModel );
+ virtual ~ValAxisContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/axisconverter.hxx b/oox/inc/oox/drawingml/chart/axisconverter.hxx
new file mode 100644
index 000000000000..9e083f69d253
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/axisconverter.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_AXISCONVERTER_HXX
+#define OOX_DRAWINGML_CHART_AXISCONVERTER_HXX
+
+#include "oox/drawingml/chart/converterbase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace chart2 { class XAxis; }
+ namespace chart2 { class XCoordinateSystem; }
+} } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct AxisModel;
+class TypeGroupConverter;
+
+class AxisConverter : public ConverterBase< AxisModel >
+{
+public:
+ explicit AxisConverter(
+ const ConverterRoot& rParent,
+ AxisModel& rModel );
+ virtual ~AxisConverter();
+
+ /** Creates a chart2 axis and inserts it into the passed coordinate system. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem >& rxCoordSystem,
+ TypeGroupConverter& rTypeGroup,
+ const AxisModel* pCrossingAxis,
+ sal_Int32 nAxesSetIdx,
+ sal_Int32 nAxisIdx );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/axismodel.hxx b/oox/inc/oox/drawingml/chart/axismodel.hxx
new file mode 100644
index 000000000000..0ce24d6ff515
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/axismodel.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_AXISMODEL_HXX
+#define OOX_DRAWINGML_CHART_AXISMODEL_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/chart/titlemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct AxisDispUnitsModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+ typedef ModelRef< LayoutModel > LayoutRef;
+ typedef ModelRef< TextModel > TextRef;
+
+ ShapeRef mxShapeProp; /// Label frame formatting.
+ TextBodyRef mxTextProp; /// Label text formatting.
+ LayoutRef mxLayout; /// Layout/position of the axis units label.
+ TextRef mxText; /// Text source of the axis units label.
+ double mfCustomUnit; /// Custom unit size on value axis.
+ sal_Int32 mnBuiltInUnit; /// Built-in unit on value axis.
+
+ explicit AxisDispUnitsModel();
+ ~AxisDispUnitsModel();
+};
+
+// ============================================================================
+
+struct AxisModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+ typedef ModelRef< TitleModel > TitleRef;
+ typedef ModelRef< AxisDispUnitsModel > AxisDispUnitsRef;
+
+ ShapeRef mxShapeProp; /// Axis line formatting.
+ TextBodyRef mxTextProp; /// Axis label text formatting.
+ TitleRef mxTitle; /// Axis title.
+ AxisDispUnitsRef mxDispUnits; /// Axis units label.
+ ShapeRef mxMajorGridLines; /// Major grid lines formatting.
+ ShapeRef mxMinorGridLines; /// Minor grid lines formatting.
+ NumberFormat maNumberFormat; /// Number format for axis tick labels.
+ OptValue< double > mofCrossesAt; /// Position on this axis where another axis crosses.
+ OptValue< double > mofMajorUnit; /// Unit for major tick marks on date/value axis.
+ OptValue< double > mofMinorUnit; /// Unit for minor tick marks on date/value axis.
+ OptValue< double > mofLogBase; /// Logarithmic base for logarithmic axes.
+ OptValue< double > mofMax; /// Maximum axis value.
+ OptValue< double > mofMin; /// Minimum axis value.
+ OptValue< sal_Int32 > monBaseTimeUnit; /// Base time unit shown on a date axis.
+ sal_Int32 mnAxisId; /// Unique axis identifier.
+ sal_Int32 mnAxisPos; /// Position of the axis (top/bottom/left/right).
+ sal_Int32 mnCrossAxisId; /// Identifier of a crossing axis.
+ sal_Int32 mnCrossBetween; /// This value axis crosses between or inside category.
+ sal_Int32 mnCrossMode; /// Mode this axis crosses another axis (min, max, auto).
+ sal_Int32 mnLabelAlign; /// Tick mark label alignment.
+ sal_Int32 mnLabelOffset; /// Tick mark label distance from axis.
+ sal_Int32 mnMajorTickMark; /// Major tick mark style.
+ sal_Int32 mnMajorTimeUnit; /// Time unit for major tick marks on date axis.
+ sal_Int32 mnMinorTickMark; /// Mainor tick mark style.
+ sal_Int32 mnMinorTimeUnit; /// Time unit for minor tick marks on date axis.
+ sal_Int32 mnOrientation; /// Axis orientation (value order min to max, or max to min).
+ sal_Int32 mnTickLabelPos; /// Position of tick mark labels relative to the axis.
+ sal_Int32 mnTickLabelSkip; /// Number of tick mark labels to skip.
+ sal_Int32 mnTickMarkSkip; /// Number of tick marks to skip.
+ sal_Int32 mnTypeId; /// Type identifier of this axis.
+ bool mbAuto; /// True = automatic selection of text/date axis type.
+ bool mbDeleted; /// True = axis has been deleted manually.
+ bool mbNoMultiLevel; /// True = no multi-level categories supported.
+
+ explicit AxisModel( sal_Int32 nTypeId );
+ ~AxisModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/chartcontextbase.hxx b/oox/inc/oox/drawingml/chart/chartcontextbase.hxx
new file mode 100644
index 000000000000..76ddeafddb80
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/chartcontextbase.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_CHARTCONTEXTBASE_HXX
+#define OOX_DRAWINGML_CHART_CHARTCONTEXTBASE_HXX
+
+#include "oox/core/fragmenthandler2.hxx"
+
+namespace oox { namespace drawingml { class Shape; } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+template< typename ModelType >
+class ContextBase : public ::oox::core::ContextHandler2
+{
+public:
+ inline explicit ContextBase( ::oox::core::ContextHandler2Helper& rParent, ModelType& rModel ) :
+ ::oox::core::ContextHandler2( rParent ), mrModel( rModel ) {}
+ virtual ~ContextBase() {}
+
+protected:
+ ModelType& mrModel;
+};
+
+// ============================================================================
+
+template< typename ModelType >
+class FragmentBase : public ::oox::core::FragmentHandler2
+{
+public:
+ explicit FragmentBase( ::oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, ModelType& rModel ) :
+ ::oox::core::FragmentHandler2( rFilter, rFragmentPath, false ), mrModel( rModel ) {}
+ virtual ~FragmentBase() {}
+
+protected:
+ ModelType& mrModel;
+};
+
+// ============================================================================
+
+/** Help class for all contexts that have only the c:spPr child element.
+ */
+class ShapePrWrapperContext : public ContextBase< Shape >
+{
+public:
+ explicit ShapePrWrapperContext( ::oox::core::ContextHandler2Helper& rParent, Shape& rModel );
+ virtual ~ShapePrWrapperContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct LayoutModel;
+
+/** Handler for a chart layout context (c:layout element).
+ */
+class LayoutContext : public ContextBase< LayoutModel >
+{
+public:
+ explicit LayoutContext( ::oox::core::ContextHandler2Helper& rParent, LayoutModel& rModel );
+ virtual ~LayoutContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/chartconverter.hxx b/oox/inc/oox/drawingml/chart/chartconverter.hxx
new file mode 100644
index 000000000000..de8572ab168b
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/chartconverter.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_CHARTCONVERTER_HXX
+#define OOX_DRAWINGML_CHART_CHARTCONVERTER_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <oox/dllapi.h>
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Point; }
+ namespace awt { struct Size; }
+ namespace drawing { class XShapes; }
+ namespace chart2 { class XChartDocument; }
+ namespace chart2 { namespace data { class XDataProvider; } }
+ namespace chart2 { namespace data { class XDataSequence; } }
+} } }
+
+namespace oox { namespace core { class XmlFilterBase; } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+struct ChartSpaceModel;
+struct DataSequenceModel;
+
+// ============================================================================
+
+class OOX_DLLPUBLIC ChartConverter
+{
+public:
+ explicit ChartConverter();
+ virtual ~ChartConverter();
+
+ /** Converts the passed OOXML chart model to the passed chart2 document.
+
+ @param rChartModel The filled MSOOXML chart model structure.
+
+ @param rxChartDoc The UNO chart document model to be initialized.
+
+ @param rxExternalPage If null, all embedded shapes will be inserted
+ into the internal drawing page of the chart document. If not null,
+ all embedded shapes will be inserted into this shapes collection.
+
+ @param rChartPos The position of the chart shape in its drawing page,
+ in 1/100 mm. Will be used only, if parameter rxExternalPage is not
+ null, for correct positioning of the embedded shapes in the
+ external drawing page.
+
+ @param rChartSize The size of the chart shape in 1/100 mm. Needed for
+ calculation of position and size of the chart elements (diagram,
+ titles, legend, etc.) and embedded shapes.
+ */
+ void convertFromModel(
+ ::oox::core::XmlFilterBase& rFilter,
+ ChartSpaceModel& rChartModel,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxExternalPage,
+ const ::com::sun::star::awt::Point& rChartPos,
+ const ::com::sun::star::awt::Size& rChartSize );
+
+ /** Creates an internal data provider. Derived classes may override this
+ function to create an external data provider. */
+ virtual void createDataProvider(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc );
+
+ /** Creates a data sequence from a formula. Dummy implementation. Derived
+ classes have to override this function to actually parse the formula. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >
+ createDataSequence(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >& rxDataProvider,
+ const DataSequenceModel& rDataSeq );
+
+private:
+ ChartConverter( const ChartConverter& );
+ ChartConverter& operator=( const ChartConverter& );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx b/oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx
new file mode 100644
index 000000000000..3ff545cda295
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_CHARTDRAWINGFRAGMENT_HXX
+#define OOX_DRAWINGML_CHART_CHARTDRAWINGFRAGMENT_HXX
+
+#include "oox/core/fragmenthandler2.hxx"
+#include "oox/drawingml/shape.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+/** Relative shape position in a chart object. */
+struct AnchorPosModel
+{
+ double mfX; /// X coordinate relative to chart object (0.0 to 1.0).
+ double mfY; /// Y coordinate relative to chart object (0.0 to 1.0).
+
+ inline explicit AnchorPosModel() : mfX( -1.0 ), mfY( -1.0 ) {}
+ inline bool isValid() const { return (0.0 <= mfX) && (mfX <= 1.0) && (0.0 <= mfY) && (mfY <= 1.0); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Absolute shape size in a chart object (in EMUs). */
+struct AnchorSizeModel : public EmuSize
+{
+ inline explicit AnchorSizeModel() : EmuSize( -1, -1 ) {}
+ inline bool isValid() const { return (Width >= 0) && (Height >= 0); }
+};
+
+// ============================================================================
+
+/** Contains the position of a shape in the chart object. Supports different
+ shape anchor modes (absolute, relative).
+ */
+class ShapeAnchor
+{
+public:
+ explicit ShapeAnchor( bool bRelSize );
+
+ /** Imports the absolute anchor size from the cdr:ext element. */
+ void importExt( const AttributeList& rAttribs );
+ /** Sets an the relative anchor position from the cdr:from or cdr:to element. */
+ void setPos( sal_Int32 nElement, sal_Int32 nParentContext, const ::rtl::OUString& rValue );
+
+ /** Calculates the resulting shape anchor in EMUs. */
+ ::com::sun::star::awt::Rectangle
+ calcEmuLocation( const EmuRectangle& rEmuChartRect ) const;
+
+private:
+ AnchorPosModel maFrom; /// Top-left position relative to chart object.
+ AnchorPosModel maTo; /// Bottom-right position relative to chart object.
+ AnchorSizeModel maSize; /// Shape size, if anchor has absolute size.
+ bool mbRelSize; /// True = relative size, false = absolute size.
+};
+
+typedef ::boost::shared_ptr< ShapeAnchor > ShapeAnchorRef;
+
+// ============================================================================
+
+/** Handler for a chart drawing fragment (c:userShapes root element).
+ */
+class ChartDrawingFragment : public ::oox::core::FragmentHandler2
+{
+public:
+ explicit ChartDrawingFragment(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxDrawPage,
+ const ::com::sun::star::awt::Size& rChartSize,
+ const ::com::sun::star::awt::Point& rShapesOffset,
+ bool bOleSupport );
+ virtual ~ChartDrawingFragment();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
+ mxDrawPage; /// Drawing page of this sheet.
+ ::oox::drawingml::ShapePtr mxShape; /// Current top-level shape.
+ ShapeAnchorRef mxAnchor; /// Current anchor of top-level shape.
+ EmuRectangle maEmuChartRect; /// Position and size of the chart object for embedded shapes (in EMUs).
+ bool mbOleSupport; /// True = allow to insert OLE objects into the drawing page.
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/chartspaceconverter.hxx b/oox/inc/oox/drawingml/chart/chartspaceconverter.hxx
new file mode 100644
index 000000000000..91e622552aa7
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/chartspaceconverter.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_CHARTSPACECONVERTER_HXX
+#define OOX_DRAWINGML_CHART_CHARTSPACECONVERTER_HXX
+
+#include "oox/drawingml/chart/converterbase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace drawing { class XShapes; }
+} } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct ChartSpaceModel;
+
+class ChartSpaceConverter : public ConverterBase< ChartSpaceModel >
+{
+public:
+ explicit ChartSpaceConverter( const ConverterRoot& rParent, ChartSpaceModel& rModel );
+ virtual ~ChartSpaceConverter();
+
+ /** Converts the contained OOXML chart model to a chart2 document. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxExternalPage,
+ const ::com::sun::star::awt::Point& rChartPos );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/chartspacefragment.hxx b/oox/inc/oox/drawingml/chart/chartspacefragment.hxx
new file mode 100644
index 000000000000..e51c1c1fcc1b
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/chartspacefragment.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_CHARTSPACEFRAGMENT_HXX
+#define OOX_DRAWINGML_CHART_CHARTSPACEFRAGMENT_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct ChartSpaceModel;
+
+/** Handler for a chart fragment (c:chartSpace root element).
+ */
+class ChartSpaceFragment : public FragmentBase< ChartSpaceModel >
+{
+public:
+ explicit ChartSpaceFragment(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ ChartSpaceModel& rModel );
+ virtual ~ChartSpaceFragment();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/chartspacemodel.hxx b/oox/inc/oox/drawingml/chart/chartspacemodel.hxx
new file mode 100644
index 000000000000..79390c8b8022
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/chartspacemodel.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_CHARTSPACEMODEL_HXX
+#define OOX_DRAWINGML_CHART_CHARTSPACEMODEL_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/chart/plotareamodel.hxx"
+#include "oox/drawingml/chart/titlemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct ChartSpaceModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+ typedef ModelRef< PlotAreaModel > PlotAreaRef;
+ typedef ModelRef< WallFloorModel > WallFloorRef;
+ typedef ModelRef< View3DModel > View3DRef;
+ typedef ModelRef< TitleModel > TitleRef;
+ typedef ModelRef< LegendModel > LegendRef;
+
+ ShapeRef mxShapeProp; /// Chart frame formatting.
+ TextBodyRef mxTextProp; /// Global chart text formatting.
+ PlotAreaRef mxPlotArea; /// Plot area of the chart.
+ WallFloorRef mxFloor; /// Floor formatting in 3D charts.
+ WallFloorRef mxBackWall; /// Back wall formatting in 3D charts.
+ WallFloorRef mxSideWall; /// Side wall formatting in 3D charts.
+ View3DRef mxView3D; /// 3D settings.
+ TitleRef mxTitle; /// Chart main title.
+ LegendRef mxLegend; /// Chart legend.
+ ::rtl::OUString maDrawingPath; /// Path to drawing fragment with embedded shapes.
+ sal_Int32 mnDispBlanksAs; /// Mode how to display blank values.
+ sal_Int32 mnStyle; /// Index to default formatting.
+ bool mbAutoTitleDel; /// True = automatic title deleted manually.
+ bool mbPlotVisOnly; /// True = plot visible cells in a sheet only.
+ bool mbShowLabelsOverMax;/// True = show labels over chart maximum.
+ bool mbPivotChart; /// True = pivot chart.
+
+ explicit ChartSpaceModel();
+ ~ChartSpaceModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/converterbase.hxx b/oox/inc/oox/drawingml/chart/converterbase.hxx
new file mode 100644
index 000000000000..12c6c2294b32
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/converterbase.hxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_CONVERTERBASE_HXX
+#define OOX_DRAWINGML_CHART_CONVERTERBASE_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+#include "oox/drawingml/chart/objectformatter.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Rectangle; }
+ namespace awt { struct Size; }
+ namespace lang { class XMultiServiceFactory; }
+ namespace chart2 { class XChartDocument; }
+ namespace chart2 { class XTitle; }
+ namespace drawing { class XShape; }
+} } }
+
+namespace oox { namespace core {
+ class XmlFilterBase;
+} }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+class ChartConverter;
+struct ChartSpaceModel;
+struct ConverterData;
+
+// ============================================================================
+
+const sal_Int32 API_PRIM_AXESSET = 0;
+const sal_Int32 API_SECN_AXESSET = 1;
+
+const sal_Int32 API_X_AXIS = 0;
+const sal_Int32 API_Y_AXIS = 1;
+const sal_Int32 API_Z_AXIS = 2;
+
+// ============================================================================
+
+class ConverterRoot
+{
+public:
+ explicit ConverterRoot(
+ ::oox::core::XmlFilterBase& rFilter,
+ ChartConverter& rChartConverter,
+ const ChartSpaceModel& rChartModel,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc,
+ const ::com::sun::star::awt::Size& rChartSize );
+ virtual ~ConverterRoot();
+
+ /** Creates an instance for the passed service name, using the process service factory. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ createInstance( const ::rtl::OUString& rServiceName ) const;
+
+protected:
+ /** Returns the filter object of the imported/exported document. */
+ ::oox::core::XmlFilterBase& getFilter() const;
+ /** Returns the chart converter. */
+ ChartConverter& getChartConverter() const;
+ /** Returns the API chart document model. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >
+ getChartDocument() const;
+ /** Returns the position and size of the chart shape in 1/100 mm. */
+ const ::com::sun::star::awt::Size& getChartSize() const;
+ /** Returns the object formatter. */
+ ObjectFormatter& getFormatter() const;
+
+ /** Registers a title object and its layout data, needed for conversion of
+ the title position using the old Chart1 API. */
+ void registerTitleLayout(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitle >& rxTitle,
+ const ModelRef< LayoutModel >& rxLayout, ObjectType eObjType,
+ sal_Int32 nMainIdx = -1, sal_Int32 nSubIdx = -1 );
+ /** Converts the positions of the main title and all axis titles. */
+ void convertTitlePositions();
+
+private:
+ ::boost::shared_ptr< ConverterData > mxData;
+};
+
+// ============================================================================
+
+/** Base class of all converter classes. Holds a reference to a model structure
+ of the specified type.
+ */
+template< typename ModelType >
+class ConverterBase : public ConverterRoot
+{
+public:
+ inline const ModelType& getModel() const { return mrModel; }
+
+protected:
+ inline explicit ConverterBase( const ConverterRoot& rParent, ModelType& rModel ) :
+ ConverterRoot( rParent ), mrModel( rModel ) {}
+ virtual ~ConverterBase() {}
+
+protected:
+ ModelType& mrModel;
+};
+
+// ============================================================================
+
+/** A layout converter calculates positions and sizes for various chart objects.
+ */
+class LayoutConverter : public ConverterBase< LayoutModel >
+{
+public:
+ explicit LayoutConverter( const ConverterRoot& rParent, LayoutModel& rModel );
+ virtual ~LayoutConverter();
+
+ /** Tries to calculate the absolute position and size from the contained
+ OOXML layout model. Returns true, if returned rectangle is valid. */
+ bool calcAbsRectangle( ::com::sun::star::awt::Rectangle& orRect ) const;
+
+ /** Tries to set the position and size from the contained OOXML layout model.
+ Returns true, if a manual position and size could be calculated. */
+ bool convertFromModel( PropertySet& rPropSet );
+
+ /** Tries to set the position from the contained OOXML layout model.
+ Returns true, if a manual position could be calculated. */
+ bool convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ double fRotationAngle );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/datasourcecontext.hxx b/oox/inc/oox/drawingml/chart/datasourcecontext.hxx
new file mode 100644
index 000000000000..1cffa32e382a
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/datasourcecontext.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_DATASOURCECONTEXT_HXX
+#define OOX_DRAWINGML_CHART_DATASOURCECONTEXT_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct DataSequenceModel;
+
+typedef ContextBase< DataSequenceModel > DataSequenceContextBase;
+
+// ============================================================================
+
+/** Handler for a double sequence context (c:numLit, c:numRef elements).
+ */
+class DoubleSequenceContext : public DataSequenceContextBase
+{
+public:
+ explicit DoubleSequenceContext( ::oox::core::ContextHandler2Helper& rParent, DataSequenceModel& rModel );
+ virtual ~DoubleSequenceContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+private:
+ sal_Int32 mnPtIndex; /// Current data point index.
+};
+
+// ============================================================================
+
+/** Handler for a string sequence context (c:multiLvlStrRef, c:strLit,
+ c:strRef elements).
+ */
+class StringSequenceContext : public DataSequenceContextBase
+{
+public:
+ explicit StringSequenceContext( ::oox::core::ContextHandler2Helper& rParent, DataSequenceModel& rModel );
+ virtual ~StringSequenceContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+private:
+ sal_Int32 mnPtIndex; /// Current data point index.
+};
+
+// ============================================================================
+
+struct DataSourceModel;
+
+/** Handler for a data source context (c:bubbleSize, c:cat, c:minus, c:plus,
+ c:val, c:xVal, c:yVal elements).
+ */
+class DataSourceContext : public ContextBase< DataSourceModel >
+{
+public:
+ explicit DataSourceContext( ::oox::core::ContextHandler2Helper& rParent, DataSourceModel& rModel );
+ virtual ~DataSourceContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/datasourceconverter.hxx b/oox/inc/oox/drawingml/chart/datasourceconverter.hxx
new file mode 100644
index 000000000000..9d16f4e85882
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/datasourceconverter.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_DATASOURCECONVERTER_HXX
+#define OOX_DRAWINGML_CHART_DATASOURCECONVERTER_HXX
+
+#include "oox/drawingml/chart/converterbase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace chart2 { namespace data { class XDataSequence; } }
+} } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct DataSequenceModel;
+
+class DataSequenceConverter : public ConverterBase< DataSequenceModel >
+{
+public:
+ explicit DataSequenceConverter( const ConverterRoot& rParent, DataSequenceModel& rModel );
+ virtual ~DataSequenceConverter();
+
+ /** Creates a data sequence object from the contained formula link. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >
+ createDataSequence( const ::rtl::OUString& rRole );
+};
+
+// ============================================================================
+
+struct DataSourceModel;
+
+class DataSourceConverter : public ConverterBase< DataSourceModel >
+{
+public:
+ explicit DataSourceConverter( const ConverterRoot& rParent, DataSourceModel& rModel );
+ virtual ~DataSourceConverter();
+
+ /** Creates a data sequence object from the contained series data. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >
+ createDataSequence( const ::rtl::OUString& rRole );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/datasourcemodel.hxx b/oox/inc/oox/drawingml/chart/datasourcemodel.hxx
new file mode 100644
index 000000000000..04e79b831049
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/datasourcemodel.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_DATASOURCEMODEL_HXX
+#define OOX_DRAWINGML_CHART_DATASOURCEMODEL_HXX
+
+#include <com/sun/star/uno/Any.hxx>
+#include "oox/drawingml/chart/modelbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct DataSequenceModel
+{
+ typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > AnyMap;
+
+ AnyMap maData; /// Map of values, indexed by point identifier.
+ ::rtl::OUString maFormula; /// Formula reference, e.g. into a spreadsheet.
+ ::rtl::OUString maFormatCode; /// Number format for double values.
+ sal_Int32 mnPointCount; /// Number of points in this series source.
+
+ explicit DataSequenceModel();
+ ~DataSequenceModel();
+};
+
+// ============================================================================
+
+struct DataSourceModel
+{
+ typedef ModelRef< DataSequenceModel > DataSequenceRef;
+
+ DataSequenceRef mxDataSeq; /// The data sequence or formula link of this source.
+
+ explicit DataSourceModel();
+ ~DataSourceModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/modelbase.hxx b/oox/inc/oox/drawingml/chart/modelbase.hxx
new file mode 100644
index 000000000000..278a8af9fed3
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/modelbase.hxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_MODELBASE_HXX
+#define OOX_DRAWINGML_CHART_MODELBASE_HXX
+
+#include "oox/helper/helper.hxx"
+#include "oox/helper/refmap.hxx"
+#include "oox/helper/refvector.hxx"
+
+namespace oox { class AttributeList; }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+template< typename ModelType >
+class ModelRef : public ::boost::shared_ptr< ModelType >
+{
+public:
+ inline explicit ModelRef() {}
+ inline ModelRef( const ::boost::shared_ptr< ModelType >& rxModel ) : ::boost::shared_ptr< ModelType >( rxModel ) {}
+ inline ~ModelRef() {}
+
+ inline bool is() const { return this->get() != 0; }
+
+ inline ModelType& create() { reset( new ModelType ); return **this; }
+ template< typename Param1Type >
+ inline ModelType& create( const Param1Type& rParam1 ) { reset( new ModelType( rParam1 ) ); return **this; }
+
+ inline ModelType& getOrCreate() { if( !*this ) reset( new ModelType ); return **this; }
+ template< typename Param1Type >
+ inline ModelType& getOrCreate( const Param1Type& rParam1 ) { if( !*this ) reset( new ModelType( rParam1 ) ); return **this; }
+};
+
+// ============================================================================
+
+template< typename ModelType >
+class ModelVector : public RefVector< ModelType >
+{
+public:
+ typedef typename RefVector< ModelType >::value_type value_type;
+ typedef typename RefVector< ModelType >::size_type size_type;
+
+ inline explicit ModelVector() {}
+ inline ~ModelVector() {}
+
+ inline ModelType& create() { return append( new ModelType ); }
+ template< typename Param1Type >
+ inline ModelType& create( const Param1Type& rParam1 ) { return append( new ModelType( rParam1 ) ); }
+
+private:
+ inline ModelType& append( ModelType* pModel ) { this->push_back( value_type( pModel ) ); return *pModel; }
+};
+
+// ============================================================================
+
+template< typename KeyType, typename ModelType >
+class ModelMap : public RefMap< KeyType, ModelType >
+{
+public:
+ typedef typename RefMap< KeyType, ModelType >::key_type key_type;
+ typedef typename RefMap< KeyType, ModelType >::mapped_type mapped_type;
+ typedef typename RefMap< KeyType, ModelType >::value_type value_type;
+
+ inline explicit ModelMap() {}
+ inline ~ModelMap() {}
+
+ inline ModelType& create( KeyType eKey ) { return insert( eKey, new ModelType ); }
+ template< typename Param1Type >
+ inline ModelType& create( KeyType eKey, const Param1Type& rParam1 ) { return insert( eKey, new ModelType( rParam1 ) ); }
+
+private:
+ inline ModelType& insert( KeyType eKey, ModelType* pModel ) { (*this)[ eKey ].reset( pModel ); return *pModel; }
+};
+
+// ============================================================================
+
+struct NumberFormat
+{
+ ::rtl::OUString maFormatCode; /// Number format code.
+ bool mbSourceLinked; /// True = number format linked to source data.
+
+ explicit NumberFormat();
+
+ void setAttributes( const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct LayoutModel
+{
+ double mfX; /// Left position of this object.
+ double mfY; /// Top position of this object.
+ double mfW; /// Width of this object.
+ double mfH; /// Height of this object.
+ sal_Int32 mnXMode; /// Mode for left position.
+ sal_Int32 mnYMode; /// Mode for top position.
+ sal_Int32 mnWMode; /// Mode for width.
+ sal_Int32 mnHMode; /// Mode for height.
+ sal_Int32 mnTarget; /// Layout target for plot area.
+ bool mbAutoLayout; /// True = automatic positioning.
+
+ explicit LayoutModel();
+ ~LayoutModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/objectformatter.hxx b/oox/inc/oox/drawingml/chart/objectformatter.hxx
new file mode 100644
index 000000000000..c35cd66f65e1
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/objectformatter.hxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_OBJECTFORMATTER_HXX
+#define OOX_DRAWINGML_CHART_OBJECTFORMATTER_HXX
+
+#include "oox/helper/propertyset.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/chart/modelbase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace chart2 { class XChartDocument; }
+} } }
+
+namespace oox { namespace core { class XmlFilterBase; } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+/** Enumerates different object types for specific automatic formatting behaviour. */
+enum ObjectType
+{
+ OBJECTTYPE_CHARTSPACE, /// Chart background.
+ OBJECTTYPE_CHARTTITLE, /// Chart title.
+ OBJECTTYPE_LEGEND, /// Legend.
+ OBJECTTYPE_PLOTAREA2D, /// Plot area containing axes and data series in 2D charts.
+ OBJECTTYPE_PLOTAREA3D, /// Plot area containing axes and data series in 3D charts.
+ OBJECTTYPE_WALL, /// Background and side wall in 3D charts.
+ OBJECTTYPE_FLOOR, /// Floor in 3D charts.
+ OBJECTTYPE_AXIS, /// Axis line, labels, tick marks.
+ OBJECTTYPE_AXISTITLE, /// Axis title.
+ OBJECTTYPE_AXISUNIT, /// Axis unit label.
+ OBJECTTYPE_MAJORGRIDLINE, /// Axis major grid line.
+ OBJECTTYPE_MINORGRIDLINE, /// Axis minor grid line.
+ OBJECTTYPE_LINEARSERIES2D, /// Linear series in 2D line/radarline/scatter charts.
+ OBJECTTYPE_FILLEDSERIES2D, /// Filled series in 2D bar/area/radararea/bubble/pie/surface charts.
+ OBJECTTYPE_FILLEDSERIES3D, /// Filled series in 3D charts.
+ OBJECTTYPE_DATALABEL, /// Labels for data points.
+ OBJECTTYPE_TRENDLINE, /// Data series trend line.
+ OBJECTTYPE_TRENDLINELABEL, /// Trend line label.
+ OBJECTTYPE_ERRORBAR, /// Data series error indicator line.
+ OBJECTTYPE_SERLINE, /// Data point connector lines.
+ OBJECTTYPE_LEADERLINE, /// Leader lines between pie slice and data label.
+ OBJECTTYPE_DROPLINE, /// Drop lines between data points and X axis.
+ OBJECTTYPE_HILOLINE, /// High/low lines in line/stock charts.
+ OBJECTTYPE_UPBAR, /// Up-bar in line/stock charts.
+ OBJECTTYPE_DOWNBAR, /// Down-bar in line/stock charts.
+ OBJECTTYPE_DATATABLE /// Data table.
+};
+
+// ============================================================================
+
+struct ChartSpaceModel;
+struct ObjectFormatterData;
+struct PictureOptionsModel;
+
+class ObjectFormatter
+{
+public:
+ explicit ObjectFormatter(
+ const ::oox::core::XmlFilterBase& rFilter,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc,
+ const ChartSpaceModel& rChartSpace );
+ ~ObjectFormatter();
+
+ /** Sets the maximum series index used for color cycling/fading. */
+ void setMaxSeriesIndex( sal_Int32 nMaxSeriesIdx );
+ /** Returns the current maximum series index used for color cycling/fading. */
+ sal_Int32 getMaxSeriesIndex() const;
+
+ /** Sets frame formatting properties to the passed property set. */
+ void convertFrameFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ ObjectType eObjType,
+ sal_Int32 nSeriesIdx = -1 );
+
+ /** Sets frame formatting properties to the passed property set. */
+ void convertFrameFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ const PictureOptionsModel& rPicOptions,
+ ObjectType eObjType,
+ sal_Int32 nSeriesIdx = -1 );
+
+ /** Sets text formatting properties to the passed property set. */
+ void convertTextFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< TextBody >& rxTextProp,
+ ObjectType eObjType );
+
+ /** Sets frame/text formatting properties to the passed property set. */
+ void convertFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ const ModelRef< TextBody >& rxTextProp,
+ ObjectType eObjType );
+
+ /** Sets text formatting properties to the passed property set. */
+ void convertTextFormatting(
+ PropertySet& rPropSet,
+ const TextCharacterProperties& rTextProps,
+ ObjectType eObjType );
+
+ /** Sets text rotation properties to the passed property set. */
+ void convertTextRotation(
+ PropertySet& rPropSet,
+ const ModelRef< TextBody >& rxTextProp,
+ bool bSupportsStacked );
+
+ /** Sets number format properties to the passed property set. */
+ void convertNumberFormat(
+ PropertySet& rPropSet,
+ const NumberFormat& rNumberFormat,
+ bool bPercentFormat = false );
+
+ /** Sets automatic line properties to the passed property set. */
+ void convertAutomaticLine(
+ PropertySet& rPropSet,
+ ObjectType eObjType,
+ sal_Int32 nSeriesIdx = -1 );
+
+ /** Sets automatic fill properties to the passed property set. */
+ void convertAutomaticFill(
+ PropertySet& rPropSet,
+ ObjectType eObjType,
+ sal_Int32 nSeriesIdx = -1 );
+
+ /** Returns true, if the passed shape properties have automatic line mode. */
+ static bool isAutomaticLine( const ModelRef< Shape >& rxShapeProp );
+ /** Returns true, if the passed shape properties have automatic fill mode. */
+ static bool isAutomaticFill( const ModelRef< Shape >& rxShapeProp );
+
+private:
+ ::boost::shared_ptr< ObjectFormatterData > mxData;
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/plotareacontext.hxx b/oox/inc/oox/drawingml/chart/plotareacontext.hxx
new file mode 100644
index 000000000000..5d3358c1147c
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/plotareacontext.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_PLOTAREACONTEXT_HXX
+#define OOX_DRAWINGML_CHART_PLOTAREACONTEXT_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct View3DModel;
+
+/** Handler for a chart plot area context (c:plotArea element).
+ */
+class View3DContext : public ContextBase< View3DModel >
+{
+public:
+ explicit View3DContext( ::oox::core::ContextHandler2Helper& rParent, View3DModel& rModel );
+ virtual ~View3DContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct WallFloorModel;
+
+/** Handler for a chart wall/floor context (c:backWall, c:floor, c:sideWall
+ elements).
+ */
+class WallFloorContext : public ContextBase< WallFloorModel >
+{
+public:
+ explicit WallFloorContext( ::oox::core::ContextHandler2Helper& rParent, WallFloorModel& rModel );
+ virtual ~WallFloorContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct PlotAreaModel;
+
+/** Handler for a chart plot area context (c:plotArea element).
+ */
+class PlotAreaContext : public ContextBase< PlotAreaModel >
+{
+public:
+ explicit PlotAreaContext( ::oox::core::ContextHandler2Helper& rParent, PlotAreaModel& rModel );
+ virtual ~PlotAreaContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/plotareaconverter.hxx b/oox/inc/oox/drawingml/chart/plotareaconverter.hxx
new file mode 100644
index 000000000000..9089c0180024
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/plotareaconverter.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_PLOTAREACONVERTER_HXX
+#define OOX_DRAWINGML_CHART_PLOTAREACONVERTER_HXX
+
+#include "oox/drawingml/chart/converterbase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace chart2 { class XDiagram; }
+} } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct View3DModel;
+class TypeGroupConverter;
+
+class View3DConverter : public ConverterBase< View3DModel >
+{
+public:
+ explicit View3DConverter( const ConverterRoot& rParent, View3DModel& rModel );
+ virtual ~View3DConverter();
+
+ /** Converts the OOXML plot area model to a chart2 diagram. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& rxDiagram,
+ TypeGroupConverter& rTypeGroup );
+};
+
+// ============================================================================
+
+struct WallFloorModel;
+
+class WallFloorConverter : public ConverterBase< WallFloorModel >
+{
+public:
+ explicit WallFloorConverter( const ConverterRoot& rParent, WallFloorModel& rModel );
+ virtual ~WallFloorConverter();
+
+ /** Converts the OOXML wall/floor model to a chart2 diagram. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& rxDiagram,
+ ObjectType eObjType );
+};
+
+// ============================================================================
+
+struct PlotAreaModel;
+
+class PlotAreaConverter : public ConverterBase< PlotAreaModel >
+{
+public:
+ explicit PlotAreaConverter( const ConverterRoot& rParent, PlotAreaModel& rModel );
+ virtual ~PlotAreaConverter();
+
+ /** Converts the OOXML plot area model to a chart2 diagram. */
+ void convertFromModel( View3DModel& rView3DModel );
+ /** Converts the manual plot area position and size, if set. */
+ void convertPositionFromModel();
+
+ /** Returns the automatic chart title if the chart contains only one series. */
+ inline const ::rtl::OUString& getAutomaticTitle() const { return maAutoTitle; }
+ /** Returns true, if the chart is three-dimensional. */
+ inline bool is3dChart() const { return mb3dChart; }
+ /** Returns true, if chart type supports wall and floor format in 3D mode. */
+ inline bool isWall3dChart() const { return mbWall3dChart; }
+
+private:
+ ::rtl::OUString maAutoTitle;
+ bool mb3dChart;
+ bool mbWall3dChart;
+ bool mbPieChart;
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/plotareamodel.hxx b/oox/inc/oox/drawingml/chart/plotareamodel.hxx
new file mode 100644
index 000000000000..ef29a72f4b09
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/plotareamodel.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_PLOTAREAMODEL_HXX
+#define OOX_DRAWINGML_CHART_PLOTAREAMODEL_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/chart/axismodel.hxx"
+#include "oox/drawingml/chart/seriesmodel.hxx"
+#include "oox/drawingml/chart/typegroupmodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct View3DModel
+{
+ OptValue< sal_Int32 > monHeightPercent; /// Height of the 3D view, relative to chart width.
+ OptValue< sal_Int32 > monRotationX; /// Horizontal rotation in degrees.
+ OptValue< sal_Int32 > monRotationY; /// Vertical rotation in degrees.
+ sal_Int32 mnDepthPercent; /// Depth of the 3D view, relative to chart width.
+ sal_Int32 mnPerspective; /// Eye distance to the 3D objects.
+ bool mbRightAngled; /// True = right-angled axes in 3D view.
+
+ explicit View3DModel();
+ ~View3DModel();
+};
+
+// ============================================================================
+
+struct WallFloorModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< PictureOptionsModel > PictureOptionsRef;
+
+ ShapeRef mxShapeProp; /// Wall/floor frame formatting.
+ PictureOptionsRef mxPicOptions; /// Fill bitmap settings.
+
+ explicit WallFloorModel();
+ ~WallFloorModel();
+};
+
+// ============================================================================
+
+struct PlotAreaModel
+{
+ typedef ModelVector< TypeGroupModel > TypeGroupVector;
+ typedef ModelVector< AxisModel > AxisVector;
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< LayoutModel > LayoutRef;
+
+ TypeGroupVector maTypeGroups; /// All chart type groups contained in the chart.
+ AxisVector maAxes; /// All axes contained in the chart.
+ ShapeRef mxShapeProp; /// Plot area frame formatting.
+ LayoutRef mxLayout; /// Layout/position of the plot area.
+
+ explicit PlotAreaModel();
+ ~PlotAreaModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/seriescontext.hxx b/oox/inc/oox/drawingml/chart/seriescontext.hxx
new file mode 100644
index 000000000000..ef50bc94866c
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/seriescontext.hxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_SERIESCONTEXT_HXX
+#define OOX_DRAWINGML_CHART_SERIESCONTEXT_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct DataLabelModel;
+
+/** Handler for a chart data point label context (c:dLbl element).
+ */
+class DataLabelContext : public ContextBase< DataLabelModel >
+{
+public:
+ explicit DataLabelContext( ::oox::core::ContextHandler2Helper& rParent, DataLabelModel& rModel );
+ virtual ~DataLabelContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+};
+
+// ============================================================================
+
+struct DataLabelsModel;
+
+/** Handler for a chart data point label context (c:dLbl element).
+ */
+class DataLabelsContext : public ContextBase< DataLabelsModel >
+{
+public:
+ explicit DataLabelsContext( ::oox::core::ContextHandler2Helper& rParent, DataLabelsModel& rModel );
+ virtual ~DataLabelsContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+};
+
+// ============================================================================
+
+struct PictureOptionsModel;
+
+/** Handler for fill bitmap settings (c:pictureOptions element).
+ */
+class PictureOptionsContext : public ContextBase< PictureOptionsModel >
+{
+public:
+ explicit PictureOptionsContext( ::oox::core::ContextHandler2Helper& rParent, PictureOptionsModel& rModel );
+ virtual ~PictureOptionsContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct ErrorBarModel;
+
+/** Handler for a series error bar context (c:errBars element).
+ */
+class ErrorBarContext : public ContextBase< ErrorBarModel >
+{
+public:
+ explicit ErrorBarContext( ::oox::core::ContextHandler2Helper& rParent, ErrorBarModel& rModel );
+ virtual ~ErrorBarContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct TrendlineLabelModel;
+
+/** Handler for a series trendline label context (c:trendlineLbl element).
+ */
+class TrendlineLabelContext : public ContextBase< TrendlineLabelModel >
+{
+public:
+ explicit TrendlineLabelContext( ::oox::core::ContextHandler2Helper& rParent, TrendlineLabelModel& rModel );
+ virtual ~TrendlineLabelContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct TrendlineModel;
+
+/** Handler for a series trendline context (c:trendline element).
+ */
+class TrendlineContext : public ContextBase< TrendlineModel >
+{
+public:
+ explicit TrendlineContext( ::oox::core::ContextHandler2Helper& rParent, TrendlineModel& rModel );
+ virtual ~TrendlineContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+};
+
+// ============================================================================
+
+struct DataPointModel;
+
+/** Handler for a chart data point context (c:dPt element).
+ */
+class DataPointContext : public ContextBase< DataPointModel >
+{
+public:
+ explicit DataPointContext( ::oox::core::ContextHandler2Helper& rParent, DataPointModel& rModel );
+ virtual ~DataPointContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct SeriesModel;
+
+/** Handler base class for chart data series contexts (c:ser element).
+ */
+class SeriesContextBase : public ContextBase< SeriesModel >
+{
+public:
+ explicit SeriesContextBase( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~SeriesContextBase();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for area chart types (c:ser element).
+ */
+class AreaSeriesContext : public SeriesContextBase
+{
+public:
+ explicit AreaSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~AreaSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for bar chart types (c:ser element).
+ */
+class BarSeriesContext : public SeriesContextBase
+{
+public:
+ explicit BarSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~BarSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for bubble chart types (c:ser element).
+ */
+class BubbleSeriesContext : public SeriesContextBase
+{
+public:
+ explicit BubbleSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~BubbleSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for line and stock chart types (c:ser
+ element).
+ */
+class LineSeriesContext : public SeriesContextBase
+{
+public:
+ explicit LineSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~LineSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for pie and doughnut chart types (c:ser
+ element).
+ */
+class PieSeriesContext : public SeriesContextBase
+{
+public:
+ explicit PieSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~PieSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for radar chart types (c:ser element).
+ */
+class RadarSeriesContext : public SeriesContextBase
+{
+public:
+ explicit RadarSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~RadarSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for scatter chart types (c:ser element).
+ */
+class ScatterSeriesContext : public SeriesContextBase
+{
+public:
+ explicit ScatterSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~ScatterSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for a data series context for scatter chart types (c:ser element).
+ */
+class SurfaceSeriesContext : public SeriesContextBase
+{
+public:
+ explicit SurfaceSeriesContext( ::oox::core::ContextHandler2Helper& rParent, SeriesModel& rModel );
+ virtual ~SurfaceSeriesContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/seriesconverter.hxx b/oox/inc/oox/drawingml/chart/seriesconverter.hxx
new file mode 100644
index 000000000000..6874298487d4
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/seriesconverter.hxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_SERIESCONVERTER_HXX
+#define OOX_DRAWINGML_CHART_SERIESCONVERTER_HXX
+
+#include "oox/drawingml/chart/converterbase.hxx"
+#include "oox/drawingml/chart/seriesmodel.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace chart2 { class XDataSeries; }
+ namespace chart2 { namespace data { class XLabeledDataSequence; } }
+} } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+class TypeGroupConverter;
+
+// #i66858# enable this when Chart2 supports smoothed lines per data series
+#define OOX_CHART_SMOOTHED_PER_SERIES 0
+
+// ============================================================================
+
+class DataLabelConverter : public ConverterBase< DataLabelModel >
+{
+public:
+ explicit DataLabelConverter( const ConverterRoot& rParent, DataLabelModel& rModel );
+ virtual ~DataLabelConverter();
+
+ /** Converts OOXML data label settings for the passed data point. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& rxDataSeries,
+ const TypeGroupConverter& rTypeGroup );
+
+ /** Conversion helper for data series and data points. */
+ static void convertLabelFormatting(
+ PropertySet& rPropSet,
+ ObjectFormatter& rFormatter,
+ const DataLabelModelBase& rDataLabel,
+ const TypeGroupConverter& rTypeGroup,
+ bool bDataSeriesLabel );
+};
+
+// ============================================================================
+
+class DataLabelsConverter : public ConverterBase< DataLabelsModel >
+{
+public:
+ explicit DataLabelsConverter( const ConverterRoot& rParent, DataLabelsModel& rModel );
+ virtual ~DataLabelsConverter();
+
+ /** Converts OOXML data label settings for the passed data series. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& rxDataSeries,
+ const TypeGroupConverter& rTypeGroup );
+};
+
+// ============================================================================
+
+class ErrorBarConverter : public ConverterBase< ErrorBarModel >
+{
+public:
+ explicit ErrorBarConverter( const ConverterRoot& rParent, ErrorBarModel& rModel );
+ virtual ~ErrorBarConverter();
+
+ /** Converts an OOXML errorbar and inserts it into the passed data series. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& rxDataSeries );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >
+ createLabeledDataSequence( ErrorBarModel::SourceType eSourceType );
+};
+
+// ============================================================================
+
+class TrendlineLabelConverter : public ConverterBase< TrendlineLabelModel >
+{
+public:
+ explicit TrendlineLabelConverter( const ConverterRoot& rParent, TrendlineLabelModel& rModel );
+ virtual ~TrendlineLabelConverter();
+
+ /** Converts the OOXML trendline label. */
+ void convertFromModel( PropertySet& rPropSet );
+};
+
+// ============================================================================
+
+class TrendlineConverter : public ConverterBase< TrendlineModel >
+{
+public:
+ explicit TrendlineConverter( const ConverterRoot& rParent, TrendlineModel& rModel );
+ virtual ~TrendlineConverter();
+
+ /** Converts an OOXML trendline and inserts it into the passed data series. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& rxDataSeries );
+};
+
+// ============================================================================
+
+class DataPointConverter : public ConverterBase< DataPointModel >
+{
+public:
+ explicit DataPointConverter( const ConverterRoot& rParent, DataPointModel& rModel );
+ virtual ~DataPointConverter();
+
+ /** Converts settings for a data point in the passed series. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& rxDataSeries,
+ const TypeGroupConverter& rTypeGroup,
+ const SeriesModel& rSeries );
+};
+
+// ============================================================================
+
+class SeriesConverter : public ConverterBase< SeriesModel >
+{
+public:
+ explicit SeriesConverter( const ConverterRoot& rParent, SeriesModel& rModel );
+ virtual ~SeriesConverter();
+
+ /** Creates a labeled data sequence object from category data link. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >
+ createCategorySequence( const ::rtl::OUString& rRole );
+ /** Creates a labeled data sequence object from value data link. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >
+ createValueSequence( const ::rtl::OUString& rRole );
+ /** Creates a data series object with initialized source links. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >
+ createDataSeries( const TypeGroupConverter& rTypeGroup, bool bVaryColorsByPoint );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >
+ createLabeledDataSequence(
+ SeriesModel::SourceType eSourceType,
+ const ::rtl::OUString& rRole,
+ bool bUseTextLabel );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/seriesmodel.hxx b/oox/inc/oox/drawingml/chart/seriesmodel.hxx
new file mode 100644
index 000000000000..d4b9ab3c9715
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/seriesmodel.hxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_SERIESMODEL_HXX
+#define OOX_DRAWINGML_CHART_SERIESMODEL_HXX
+
+#include "oox/drawingml/chart/datasourcemodel.hxx"
+#include "oox/drawingml/chart/titlemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct DataLabelModelBase
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+
+ ShapeRef mxShapeProp; /// Data label frame formatting.
+ TextBodyRef mxTextProp; /// Data label text formatting.
+ NumberFormat maNumberFormat; /// Number format for numeric data labels.
+ OptValue< ::rtl::OUString > moaSeparator;/// Separator between label components.
+ OptValue< sal_Int32 > monLabelPos; /// Data label position.
+ OptValue< bool > mobShowBubbleSize; /// True = show size of bubbles in bubble charts.
+ OptValue< bool > mobShowCatName; /// True = show category name of data points.
+ OptValue< bool > mobShowLegendKey; /// True = show legend key of data series.
+ OptValue< bool > mobShowPercent; /// True = show percentual value in pie/doughnut charts.
+ OptValue< bool > mobShowSerName; /// True = show series name.
+ OptValue< bool > mobShowVal; /// True = show data point value.
+ bool mbDeleted; /// True = data label(s) deleted.
+
+ explicit DataLabelModelBase();
+ ~DataLabelModelBase();
+};
+
+// ============================================================================
+
+struct DataLabelModel : public DataLabelModelBase
+{
+ typedef ModelRef< LayoutModel > LayoutRef;
+ typedef ModelRef< TextModel > TextRef;
+
+ LayoutRef mxLayout; /// Layout/position of the data point label frame.
+ TextRef mxText; /// Manual or linked text for this data point label.
+ sal_Int32 mnIndex; /// Data point index for this data label.
+
+ explicit DataLabelModel();
+ ~DataLabelModel();
+};
+
+// ============================================================================
+
+struct DataLabelsModel : public DataLabelModelBase
+{
+ typedef ModelVector< DataLabelModel > DataLabelVector;
+ typedef ModelRef< Shape > ShapeRef;
+
+ DataLabelVector maPointLabels; /// Settings for individual data point labels.
+ ShapeRef mxLeaderLines; /// Formatting of connector lines between data points and labels.
+ bool mbShowLeaderLines; /// True = show connector lines between data points and labels.
+
+ explicit DataLabelsModel();
+ ~DataLabelsModel();
+};
+
+// ============================================================================
+
+struct PictureOptionsModel
+{
+ double mfStackUnit; /// Bitmap stacking unit.
+ sal_Int32 mnPictureFormat; /// Bitmap mode (stretch/tile).
+ bool mbApplyToFront; /// True = draw picture at front/back side of 3D data points.
+ bool mbApplyToSides; /// True = draw picture at left/right side of 3D data points.
+ bool mbApplyToEnd; /// True = draw picture at top/bottom side of 3D data points.
+
+ explicit PictureOptionsModel();
+ ~PictureOptionsModel();
+};
+
+// ============================================================================
+
+struct ErrorBarModel
+{
+ enum SourceType
+ {
+ PLUS, /// Plus error bar values.
+ MINUS /// Minus error bar values.
+ };
+
+ typedef ModelMap< SourceType, DataSourceModel > DataSourceMap;
+ typedef ModelRef< Shape > ShapeRef;
+
+ DataSourceMap maSources; /// Source ranges for manual error bar values.
+ ShapeRef mxShapeProp; /// Error line formatting.
+ double mfValue; /// Fixed value for several error bar types.
+ sal_Int32 mnDirection; /// Direction of the error bars (x/y).
+ sal_Int32 mnTypeId; /// Type of the error bars (plus/minus/both).
+ sal_Int32 mnValueType; /// Type of the values.
+ bool mbNoEndCap; /// True = no end cap at error bar lines.
+
+ explicit ErrorBarModel();
+ ~ErrorBarModel();
+};
+
+// ============================================================================
+
+struct TrendlineLabelModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+ typedef ModelRef< LayoutModel > LayoutRef;
+ typedef ModelRef< TextModel > TextRef;
+
+ ShapeRef mxShapeProp; /// Label frame formatting.
+ TextBodyRef mxTextProp; /// Label text formatting.
+ LayoutRef mxLayout; /// Layout/position of the frame.
+ TextRef mxText; /// Text source of the label.
+ NumberFormat maNumberFormat; /// Number format for coefficients.
+
+ explicit TrendlineLabelModel();
+ ~TrendlineLabelModel();
+};
+
+// ============================================================================
+
+struct TrendlineModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TrendlineLabelModel > TrendlineLabelRef;
+
+ ShapeRef mxShapeProp; /// Trendline formatting.
+ TrendlineLabelRef mxLabel; /// Trendline label text object.
+ ::rtl::OUString maName; /// User-defined name of the trendline.
+ OptValue< double > mfBackward; /// Size of trendline before first data point.
+ OptValue< double > mfForward; /// Size of trendline behind last data point.
+ OptValue< double > mfIntercept; /// Crossing point with Y axis.
+ sal_Int32 mnOrder; /// Polynomial order in range [2, 6].
+ sal_Int32 mnPeriod; /// Moving average period in range [2, 255].
+ sal_Int32 mnTypeId; /// Type of the trendline.
+ bool mbDispEquation; /// True = show equation of the trendline.
+ bool mbDispRSquared; /// True = show R-squared of the trendline.
+
+ explicit TrendlineModel();
+ ~TrendlineModel();
+};
+
+// ============================================================================
+
+struct DataPointModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< PictureOptionsModel > PictureOptionsRef;
+
+ ShapeRef mxShapeProp; /// Data point formatting.
+ PictureOptionsRef mxPicOptions; /// Fill bitmap settings.
+ ShapeRef mxMarkerProp; /// Data point marker formatting.
+ OptValue< sal_Int32 > monExplosion; /// Pie slice moved from pie center.
+ OptValue< sal_Int32 > monMarkerSize; /// Size of the series line marker (2...72).
+ OptValue< sal_Int32 > monMarkerSymbol; /// Series line marker symbol.
+ OptValue< bool > mobBubble3d; /// True = show bubbles with 3D shade.
+ sal_Int32 mnIndex; /// Unique data point index.
+ bool mbInvertNeg; /// True = invert negative data points (not derived from series!).
+
+ explicit DataPointModel();
+ ~DataPointModel();
+};
+
+// ============================================================================
+
+struct SeriesModel
+{
+ enum SourceType
+ {
+ CATEGORIES, /// Data point categories.
+ VALUES, /// Data point values.
+ POINTS /// Data point size (e.g. bubble size in bubble charts).
+ };
+
+ typedef ModelMap< SourceType, DataSourceModel > DataSourceMap;
+ typedef ModelVector< ErrorBarModel > ErrorBarVector;
+ typedef ModelVector< TrendlineModel > TrendlineVector;
+ typedef ModelVector< DataPointModel > DataPointVector;
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< PictureOptionsModel > PictureOptionsRef;
+ typedef ModelRef< TextModel > TextRef;
+ typedef ModelRef< DataLabelsModel > DataLabelsRef;
+
+ DataSourceMap maSources; /// Series source ranges.
+ ErrorBarVector maErrorBars; /// All error bars of this series.
+ TrendlineVector maTrendlines; /// All trendlines of this series.
+ DataPointVector maPoints; /// Explicit formatted data points.
+ ShapeRef mxShapeProp; /// Series formatting.
+ PictureOptionsRef mxPicOptions; /// Fill bitmap settings.
+ ShapeRef mxMarkerProp; /// Data point marker formatting.
+ TextRef mxText; /// Series title source.
+ DataLabelsRef mxLabels; /// Data point label settings for all points.
+ OptValue< sal_Int32 > monShape; /// 3D bar shape type.
+ sal_Int32 mnExplosion; /// Pie slice moved from pie center.
+ sal_Int32 mnIndex; /// Series index used for automatic formatting.
+ sal_Int32 mnMarkerSize; /// Size of the series line marker (2...72).
+ sal_Int32 mnMarkerSymbol; /// Series line marker symbol.
+ sal_Int32 mnOrder; /// Series order.
+ bool mbBubble3d; /// True = show bubbles with 3D shade.
+ bool mbInvertNeg; /// True = invert negative data points.
+ bool mbSmooth; /// True = smooth series line.
+
+ explicit SeriesModel();
+ ~SeriesModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/titlecontext.hxx b/oox/inc/oox/drawingml/chart/titlecontext.hxx
new file mode 100644
index 000000000000..45969bf150c2
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/titlecontext.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_TITLECONTEXT_HXX
+#define OOX_DRAWINGML_CHART_TITLECONTEXT_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct TextModel;
+
+/** Handler for a chart text context (c:tx element).
+ */
+class TextContext : public ContextBase< TextModel >
+{
+public:
+ explicit TextContext( ::oox::core::ContextHandler2Helper& rParent, TextModel& rModel );
+ virtual ~TextContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+};
+
+// ============================================================================
+
+struct TitleModel;
+
+/** Handler for a chart title context (c:title element).
+ */
+class TitleContext : public ContextBase< TitleModel >
+{
+public:
+ explicit TitleContext( ::oox::core::ContextHandler2Helper& rParent, TitleModel& rModel );
+ virtual ~TitleContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct LegendModel;
+
+/** Handler for a chart legend context (c:legend element).
+ */
+class LegendContext : public ContextBase< LegendModel >
+{
+public:
+ explicit LegendContext( ::oox::core::ContextHandler2Helper& rParent, LegendModel& rModel );
+ virtual ~LegendContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/titleconverter.hxx b/oox/inc/oox/drawingml/chart/titleconverter.hxx
new file mode 100644
index 000000000000..2a452ae6c96b
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/titleconverter.hxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_TITLECONVERTER_HXX
+#define OOX_DRAWINGML_CHART_TITLECONVERTER_HXX
+
+#include "oox/drawingml/chart/converterbase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace chart2 { class XDiagram; }
+ namespace chart2 { class XFormattedString; }
+ namespace chart2 { class XTitled; }
+ namespace chart2 { namespace data { class XDataSequence; } }
+} } }
+
+namespace oox { namespace drawingml { struct TextCharacterProperties; } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct TextModel;
+
+class TextConverter : public ConverterBase< TextModel >
+{
+public:
+ explicit TextConverter( const ConverterRoot& rParent, TextModel& rModel );
+ virtual ~TextConverter();
+
+ /** Creates a data sequence object from the contained text data. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >
+ createDataSequence( const ::rtl::OUString& rRole );
+ /** Creates a sequence of formatted string objects. */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString > >
+ createStringSequence(
+ const ::rtl::OUString& rDefaultText,
+ const ModelRef< TextBody >& rxTextProp,
+ ObjectType eObjType );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString >
+ appendFormattedString(
+ ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString > >& orStringVec,
+ const ::rtl::OUString& rString,
+ bool bAddNewLine ) const;
+};
+
+// ============================================================================
+
+struct TitleModel;
+
+class TitleConverter : public ConverterBase< TitleModel >
+{
+public:
+ explicit TitleConverter( const ConverterRoot& rParent, TitleModel& rModel );
+ virtual ~TitleConverter();
+
+ /** Creates a title text object and attaches it at the passed interface. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitled >& rxTitled,
+ const ::rtl::OUString& rAutoTitle, ObjectType eObjType,
+ sal_Int32 nMainIdx = -1, sal_Int32 nSubIdx = -1 );
+};
+
+// ============================================================================
+
+struct LegendModel;
+
+class LegendConverter : public ConverterBase< LegendModel >
+{
+public:
+ explicit LegendConverter( const ConverterRoot& rParent, LegendModel& rModel );
+ virtual ~LegendConverter();
+
+ /** Creates a legend object and attaches it at the passed diagram. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& rxDiagram );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/titlemodel.hxx b/oox/inc/oox/drawingml/chart/titlemodel.hxx
new file mode 100644
index 000000000000..fc47d684c6dc
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/titlemodel.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_TITLEMODEL_HXX
+#define OOX_DRAWINGML_CHART_TITLEMODEL_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/chart/datasourcemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct TextModel
+{
+ typedef ModelRef< DataSequenceModel > DataSequenceRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+
+ DataSequenceRef mxDataSeq; /// The string data or formula link of this text.
+ TextBodyRef mxTextBody; /// Rich-formatted literal text (for title objects only).
+
+ explicit TextModel();
+ ~TextModel();
+};
+
+// ============================================================================
+
+struct TitleModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+ typedef ModelRef< LayoutModel > LayoutRef;
+ typedef ModelRef< TextModel > TextRef;
+
+ ShapeRef mxShapeProp; /// Title shape formatting.
+ TextBodyRef mxTextProp; /// Title text formatting.
+ LayoutRef mxLayout; /// Layout/position of the frame.
+ TextRef mxText; /// Text source of the title.
+ bool mbOverlay; /// True = title may overlay other objects.
+
+ explicit TitleModel();
+ ~TitleModel();
+};
+
+// ============================================================================
+
+struct LegendModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+ typedef ModelRef< TextBody > TextBodyRef;
+ typedef ModelRef< LayoutModel > LayoutRef;
+
+ ShapeRef mxShapeProp; /// Legend shape formatting.
+ TextBodyRef mxTextProp; /// Legend text formatting.
+ LayoutRef mxLayout; /// Layout/position of the legend.
+ sal_Int32 mnPosition; /// Legend position.
+ bool mbOverlay; /// True = legend may overlay other objects.
+
+ explicit LegendModel();
+ ~LegendModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/typegroupcontext.hxx b/oox/inc/oox/drawingml/chart/typegroupcontext.hxx
new file mode 100644
index 000000000000..d58cb7e1c4f7
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/typegroupcontext.hxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_TYPEGROUPCONTEXT_HXX
+#define OOX_DRAWINGML_CHART_TYPEGROUPCONTEXT_HXX
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct UpDownBarsModel;
+
+/** Handler for an up/down bars context (c:upDownBars element).
+ */
+class UpDownBarsContext : public ContextBase< UpDownBarsModel >
+{
+public:
+ explicit UpDownBarsContext( ::oox::core::ContextHandler2Helper& rParent, UpDownBarsModel& rModel );
+ virtual ~UpDownBarsContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+struct TypeGroupModel;
+typedef ContextBase< TypeGroupModel > TypeGroupContextBase;
+
+// ============================================================================
+
+/** Handler for area type group contexts (c:area3DChart, c:areaChart elements).
+ */
+class AreaTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit AreaTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~AreaTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for bar type group contexts (c:bar3DChart, c:barChart elements).
+ */
+class BarTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit BarTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~BarTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for bubble type group context (c:bubbleChart element).
+ */
+class BubbleTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit BubbleTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~BubbleTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for line type group contexts (c:line3DChart, c:lineChart,
+ c:stockChart elements).
+ */
+class LineTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit LineTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~LineTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for pie type group contexts (c:doughnutChart, c:ofPieChart,
+ c:pie3DChart, c:pieChart elements).
+ */
+class PieTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit PieTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~PieTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for radar type group context (c:radarChart element).
+ */
+class RadarTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit RadarTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~RadarTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for scatter type group context (c:scatterChart element).
+ */
+class ScatterTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit ScatterTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~ScatterTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+/** Handler for surface type group contexts (c:surface3DChart, c:surfaceChart
+ elements).
+ */
+class SurfaceTypeGroupContext : public TypeGroupContextBase
+{
+public:
+ explicit SurfaceTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
+ virtual ~SurfaceTypeGroupContext();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/typegroupconverter.hxx b/oox/inc/oox/drawingml/chart/typegroupconverter.hxx
new file mode 100644
index 000000000000..58375a4c2b1f
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/typegroupconverter.hxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_TYPEGROUPCONVERTER_HXX
+#define OOX_DRAWINGML_CHART_TYPEGROUPCONVERTER_HXX
+
+#include "oox/drawingml/chart/converterbase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace chart2 { class XChartType; }
+ namespace chart2 { class XCoordinateSystem; }
+ namespace chart2 { class XDataSeries; }
+ namespace chart2 { class XDiagram; }
+ namespace chart2 { namespace data { class XLabeledDataSequence; } }
+} } }
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+/** Enumerates different chart types. */
+enum TypeId
+{
+ TYPEID_BAR, /// Vertical bar chart.
+ TYPEID_HORBAR, /// Horizontal bar chart.
+ TYPEID_LINE, /// Line chart.
+ TYPEID_AREA, /// Area chart.
+ TYPEID_STOCK, /// Stock chart.
+ TYPEID_RADARLINE, /// Linear radar chart.
+ TYPEID_RADARAREA, /// Filled radar chart.
+ TYPEID_PIE, /// Pie chart.
+ TYPEID_DOUGHNUT, /// Doughnut (ring) chart.
+ TYPEID_OFPIE, /// Pie-to-pie or pie-to-bar chart.
+ TYPEID_SCATTER, /// Scatter (XY) chart.
+ TYPEID_BUBBLE, /// Bubble chart.
+ TYPEID_SURFACE, /// Surface chart.
+ TYPEID_UNKNOWN /// Default for unknown chart types.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Enumerates different categories of similar chart types. */
+enum TypeCategory
+{
+ TYPECATEGORY_BAR, /// Bar charts (horizontal or vertical).
+ TYPECATEGORY_LINE, /// Line charts (line, area, stock charts).
+ TYPECATEGORY_RADAR, /// Radar charts (linear or filled).
+ TYPECATEGORY_PIE, /// Pie and donut charts.
+ TYPECATEGORY_SCATTER, /// Scatter and bubble charts.
+ TYPECATEGORY_SURFACE /// Surface charts.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Enumerates modes for varying point colors in a series. */
+enum VarPointMode
+{
+ VARPOINTMODE_NONE, /// No varied colors supported.
+ VARPOINTMODE_SINGLE, /// Only supported, if type group contains only one series.
+ VARPOINTMODE_MULTI /// Supported for multiple series in a chart type group.
+};
+
+// ============================================================================
+
+/** Contains info for a chart type related to the OpenOffice.org chart module. */
+struct TypeGroupInfo
+{
+ TypeId meTypeId; /// Unique chart type identifier.
+ TypeCategory meTypeCategory; /// Category this chart type belongs to.
+ const sal_Char* mpcServiceName; /// Service name of the type.
+ VarPointMode meVarPointMode; /// Mode for varying point colors.
+ sal_Int32 mnDefLabelPos; /// Default data label position (API constant).
+ bool mbCombinable2d; /// True = types can be combined in one axes set.
+ bool mbSupports3d; /// True = 3D type allowed, false = only 2D type.
+ bool mbPolarCoordSystem; /// True = polar, false = cartesian.
+ bool mbSeriesIsFrame2d; /// True = 2D type series with area formatting.
+ bool mbSingleSeriesVis; /// True = only first series visible (e.g. pie charts).
+ bool mbCategoryAxis; /// True = X axis contains categories.
+ bool mbSwappedAxesSet; /// True = X axis and Y axis are swapped.
+ bool mbSupportsStacking; /// True = data points can be stacked on each other.
+ bool mbReverseSeries; /// True = insert unstacked series in reverse order.
+ bool mbTicksBetweenCateg; /// True = X axis ticks between categories.
+ bool mbPictureOptions; /// True = bitmaps support options from c:pictureOptions.
+};
+
+// ============================================================================
+
+struct UpDownBarsModel;
+
+class UpDownBarsConverter : public ConverterBase< UpDownBarsModel >
+{
+public:
+ explicit UpDownBarsConverter( const ConverterRoot& rParent, UpDownBarsModel& rModel );
+ virtual ~UpDownBarsConverter();
+
+ /** Converts the OOXML up/down bars. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& rxChartType );
+};
+
+// ============================================================================
+
+struct TypeGroupModel;
+struct View3DModel;
+
+class TypeGroupConverter : public ConverterBase< TypeGroupModel >
+{
+public:
+ explicit TypeGroupConverter( const ConverterRoot& rParent, TypeGroupModel& rModel );
+ virtual ~TypeGroupConverter();
+
+ /** Returns the type info struct that describes this chart type group. */
+ inline const TypeGroupInfo& getTypeInfo() const { return maTypeInfo; }
+
+ /** Returns true, if the series in this chart type group are stacked on each other (no percentage). */
+ bool isStacked() const;
+ /** Returns true, if the series in this chart type group are stacked on each other as percentage. */
+ bool isPercent() const;
+ /** Returns true, if the chart is three-dimensional. */
+ bool is3dChart() const;
+ /** Returns true, if chart type supports wall and floor format in 3D mode. */
+ bool isWall3dChart() const;
+ /** Returns true, if the series in this chart type group are ordered on the Z axis. */
+ bool isDeep3dChart() const;
+
+ /** Returns true, if this chart type supports area formatting for its series. */
+ bool isSeriesFrameFormat() const;
+ /** Returns the object type for a series depending on the chart type. */
+ ObjectType getSeriesObjectType() const;
+
+ /** Returns true, if this chart type has to reverse its series order. */
+ bool isReverseSeries() const;
+ /** Returns series title, if the chart type group contains only one single series. */
+ ::rtl::OUString getSingleSeriesTitle() const;
+
+ /** Creates a coordinate system according to the contained chart type. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem >
+ createCoordinateSystem();
+ /** Creates a labeled data sequence object for axis categories. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >
+ createCategorySequence();
+
+ /** Converts the OOXML type group model into a chart2 coordinate system. */
+ void convertFromModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& rxDiagram,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem >& rxCoordSystem,
+ sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint );
+
+ /** Sets the passed OOXML marker style at the passed property set. */
+ void convertMarker( PropertySet& rPropSet, sal_Int32 nOoxSymbol, sal_Int32 nOoxSize ) const;
+ /** Sets the passed OOXML line smoothing at the passed property set. */
+ void convertLineSmooth( PropertySet& rPropSet, bool bOoxSmooth ) const;
+ /** Sets the passed OOXML bar 3D geometry at the passed property set. */
+ void convertBarGeometry( PropertySet& rPropSet, sal_Int32 nOoxShape ) const;
+ /** Sets the passed OOXML pie rotation at the passed property set. */
+ void convertPieRotation( PropertySet& rPropSet, sal_Int32 nOoxAngle ) const;
+ /** Sets the passed OOXML pie explosion at the passed property set. */
+ void convertPieExplosion( PropertySet& rPropSet, sal_Int32 nOoxExplosion ) const;
+
+private:
+ /** Inserts the passed series into the chart type. Adds additional properties to the series. */
+ void insertDataSeries(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& rxChartType,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& rxSeries,
+ sal_Int32 nAxesSetIdx );
+
+private:
+ TypeGroupInfo maTypeInfo; /// Extended type info for contained chart type model.
+ bool mb3dChart; /// True = type is a 3D chart type.
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/chart/typegroupmodel.hxx b/oox/inc/oox/drawingml/chart/typegroupmodel.hxx
new file mode 100644
index 000000000000..9af01210d585
--- /dev/null
+++ b/oox/inc/oox/drawingml/chart/typegroupmodel.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CHART_TYPEGROUPMODEL_HXX
+#define OOX_DRAWINGML_CHART_TYPEGROUPMODEL_HXX
+
+#include "oox/drawingml/chart/seriesmodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+struct UpDownBarsModel
+{
+ typedef ModelRef< Shape > ShapeRef;
+
+ ShapeRef mxDownBars; /// Formatting of down bars.
+ ShapeRef mxUpBars; /// Formatting of up bars.
+ sal_Int32 mnGapWidth; /// Space between up/down bars.
+
+ explicit UpDownBarsModel();
+ ~UpDownBarsModel();
+};
+
+// ============================================================================
+
+struct TypeGroupModel
+{
+ typedef ModelVector< SeriesModel > SeriesVector;
+ typedef ::std::vector< sal_Int32 > AxisIdVector;
+ typedef ModelRef< DataLabelsModel > DataLabelsRef;
+ typedef ModelRef< UpDownBarsModel > UpDownBarsRef;
+ typedef ModelRef< Shape > ShapeRef;
+
+ SeriesVector maSeries; /// Series attached to this chart type group.
+ AxisIdVector maAxisIds; /// List of axis identifiers used by this chart type.
+ DataLabelsRef mxLabels; /// Data point label settings for all series.
+ UpDownBarsRef mxUpDownBars; /// Up/down bars in stock charts.
+ ShapeRef mxSerLines; /// Connector lines in stacked bar charts.
+ ShapeRef mxDropLines; /// Drop lines connecting data points with X axis.
+ ShapeRef mxHiLowLines; /// High/low lines connecting lowest and highest data points.
+ double mfSplitPos; /// Threshold value in pie-to charts.
+ sal_Int32 mnBarDir; /// Bar direction in bar charts (vertical/horizontal).
+ sal_Int32 mnBubbleScale; /// Relative scaling of bubble size (percent).
+ sal_Int32 mnFirstAngle; /// Rotation angle of first slice in pie charts.
+ sal_Int32 mnGapDepth; /// Space between series in deep 3D charts.
+ sal_Int32 mnGapWidth; /// Space between bars in bar charts, or space in pie-to charts.
+ sal_Int32 mnGrouping; /// Series grouping mode.
+ sal_Int32 mnHoleSize; /// Hole size in doughnut charts.
+ sal_Int32 mnOfPieType; /// Pie-to-pie or pie-to-bar chart.
+ sal_Int32 mnOverlap; /// Bar overlap per category (2D bar charts only).
+ sal_Int32 mnRadarStyle; /// Type of radar chart (lines, markers, filled).
+ sal_Int32 mnScatterStyle; /// Type of scatter chart (lines, markers, smooth).
+ sal_Int32 mnSecondPieSize; /// relative size of second pie/bar in pie-to charts (percent).
+ sal_Int32 mnShape; /// 3D bar shape type.
+ sal_Int32 mnSizeRepresents; /// Bubble size represents area or width.
+ sal_Int32 mnSplitType; /// Split type in pie-to charts.
+ sal_Int32 mnTypeId; /// Chart type identifier.
+ bool mbBubble3d; /// True = show bubbles with 3D shade.
+ bool mbShowMarker; /// True = show point markers in line charts.
+ bool mbShowNegBubbles; /// True = show absolute value of negative bubbles.
+ bool mbSmooth; /// True = smooth lines in line charts.
+ bool mbVaryColors; /// True = different automatic colors for each point.
+ bool mbWireframe; /// True = wireframe surface chart, false = filled surface chart.
+
+ explicit TypeGroupModel( sal_Int32 nTypeId );
+ ~TypeGroupModel();
+};
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/drawingml/clrscheme.hxx b/oox/inc/oox/drawingml/clrscheme.hxx
new file mode 100644
index 000000000000..5f13f54b705d
--- /dev/null
+++ b/oox/inc/oox/drawingml/clrscheme.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CLRSCHEME_HXX
+#define OOX_DRAWINGML_CLRSCHEME_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include <vector>
+#include "oox/drawingml/color.hxx"
+
+namespace oox { namespace drawingml {
+
+class ClrMap
+{
+ std::map < sal_Int32, sal_Int32 > maClrMap;
+
+public:
+
+ sal_Bool getColorMap( sal_Int32& nClrToken );
+ void setColorMap( sal_Int32 nClrToken, sal_Int32 nMappedClrToken );
+};
+
+typedef boost::shared_ptr< ClrMap > ClrMapPtr;
+
+class ClrScheme
+{
+ std::map < sal_Int32, sal_Int32 > maClrScheme;
+
+public:
+
+ ClrScheme();
+ ~ClrScheme();
+
+ sal_Bool getColor( sal_Int32 nSchemeClrToken, sal_Int32& rColor ) const;
+ void setColor( sal_Int32 nSchemeClrToken, sal_Int32 nColor );
+};
+
+typedef boost::shared_ptr< ClrScheme > ClrSchemePtr;
+
+} }
+
+#endif // OOX_DRAWINGML_CLRSCHEME_HXX
diff --git a/oox/inc/oox/drawingml/clrschemecontext.hxx b/oox/inc/oox/drawingml/clrschemecontext.hxx
new file mode 100644
index 000000000000..2ecc588716e0
--- /dev/null
+++ b/oox/inc/oox/drawingml/clrschemecontext.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CLRSCHEMECONTEXT_HXX
+#define OOX_DRAWINGML_CLRSCHEMECONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/clrscheme.hxx"
+#include "oox/drawingml/color.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+
+namespace oox { namespace drawingml {
+
+class clrMapContext : public oox::core::ContextHandler
+{
+public:
+ clrMapContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, ClrMap& rClrMap );
+};
+
+class clrSchemeColorContext : private Color, public ColorContext
+{
+public:
+ clrSchemeColorContext( ::oox::core::ContextHandler& rParent, ClrScheme& rClrScheme, sal_Int32 nColorToken );
+ virtual ~clrSchemeColorContext();
+
+private:
+ ClrScheme& mrClrScheme;
+ sal_Int32 mnColorToken;
+};
+
+class clrSchemeContext : public oox::core::ContextHandler
+{
+public:
+ clrSchemeContext( ::oox::core::ContextHandler& rParent, ClrScheme& rClrScheme );
+ 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:
+ ClrScheme& mrClrScheme;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_CLRSCHEMECONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/color.hxx b/oox/inc/oox/drawingml/color.hxx
new file mode 100644
index 000000000000..51e9501205cf
--- /dev/null
+++ b/oox/inc/oox/drawingml/color.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_COLOR_HXX
+#define OOX_DRAWINGML_COLOR_HXX
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <sal/types.h>
+#include <rtl/instance.hxx>
+#include <rtl/ustring.hxx>
+#include "oox/helper/helper.hxx"
+
+namespace oox { class GraphicHelper; }
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+class Color
+{
+public:
+ Color();
+ ~Color();
+
+ /** Returns the RGB value for the passed DrawingML color token, or nDefaultRgb on error. */
+ static sal_Int32 getDmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb );
+ /** Returns the RGB value for the passed VML color token, or nDefaultRgb on error. */
+ static sal_Int32 getVmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb );
+
+ /** Sets the color to unused state. */
+ void setUnused();
+ /** Sets an RGB value (hexadecimal RRGGBB) from the a:srgbClr element. */
+ void setSrgbClr( sal_Int32 nRgb );
+ /** Sets the percentual RGB values from the a:scrgbClr element. */
+ void setScrgbClr( sal_Int32 nR, sal_Int32 nG, sal_Int32 nB );
+ /** Sets the HSL values from the a:hslClr element. */
+ void setHslClr( sal_Int32 nHue, sal_Int32 nSat, sal_Int32 nLum );
+ /** Sets a predefined color from the a:prstClr element. */
+ void setPrstClr( sal_Int32 nToken );
+ /** Sets a scheme color from the a:schemeClr element. */
+ void setSchemeClr( sal_Int32 nToken );
+ /** Sets a system color from the a:sysClr element. */
+ void setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb );
+ /** Sets a palette color index. */
+ void setPaletteClr( sal_Int32 nPaletteIdx );
+
+ /** Inserts the passed color transformation. */
+ void addTransformation( sal_Int32 nElement, sal_Int32 nValue = -1 );
+ /** Inserts Chart specific color tint (-1.0...0.0 = shade, 0.0...1.0 = tint). */
+ void addChartTintTransformation( double fTint );
+ /** Inserts Excel specific color tint (-1.0...0.0 = shade, 0.0...1.0 = tint). */
+ void addExcelTintTransformation( double fTint );
+ /** Removes all color transformations. */
+ void clearTransformations();
+ /** Removes transparence from the color. */
+ void clearTransparence();
+
+ /** Overwrites this color with the passed color, if it is used. */
+ inline void assignIfUsed( const Color& rColor ) { if( rColor.isUsed() ) *this = rColor; }
+
+ /** Returns true, if the color is initialized. */
+ bool isUsed() const { return meMode != COLOR_UNUSED; }
+ /** Returns true, if the color is a placeholder color in theme style lists. */
+ bool isPlaceHolder() const { return meMode == COLOR_PH; }
+ /** Returns the final RGB color value.
+ @param nPhClr Actual color for the phClr placeholder color used in theme style lists. */
+ sal_Int32 getColor( const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const;
+
+ /** Returns true, if the color has a transparence set. */
+ bool hasTransparence() const;
+ /** Returns the transparence of the color (0 = opaque, 100 = full transparent). */
+ sal_Int16 getTransparence() const;
+
+private:
+ /** Internal helper for getColor(). */
+ void setResolvedRgb( sal_Int32 nRgb ) const;
+
+ /** Converts the color components to RGB values. */
+ void toRgb() const;
+ /** Converts the color components to CRGB values (gamma corrected percentage). */
+ void toCrgb() const;
+ /** Converts the color components to HSL values. */
+ void toHsl() const;
+
+private:
+ enum ColorMode
+ {
+ COLOR_UNUSED, /// Color is not used, or undefined.
+ COLOR_RGB, /// Absolute RGB (r/g/b: 0...255).
+ COLOR_CRGB, /// Relative RGB (r/g/b: 0...100000).
+ COLOR_HSL, /// HSL (hue: 0...21600000, sat/lum: 0...100000).
+ COLOR_SCHEME, /// Color from scheme.
+ COLOR_PALETTE, /// Color from application defined palette.
+ COLOR_SYSTEM, /// Color from system palette.
+ COLOR_PH, /// Placeholder color in theme style lists.
+ COLOR_FINAL /// Finalized RGB color.
+ };
+
+ struct Transformation
+ {
+ sal_Int32 mnToken;
+ sal_Int32 mnValue;
+
+ explicit Transformation( sal_Int32 nToken, sal_Int32 nValue ) : mnToken( nToken ), mnValue( nValue ) {}
+ };
+ typedef ::std::vector< Transformation > TransformVec;
+
+ mutable ColorMode meMode; /// Current color mode.
+ mutable TransformVec maTransforms; /// Color transformations.
+ mutable sal_Int32 mnC1; /// Red, red%, hue, scheme token, palette index, system token, or final RGB.
+ mutable sal_Int32 mnC2; /// Green, green%, saturation, or system default RGB.
+ mutable sal_Int32 mnC3; /// Blue, blue%, or luminance.
+ sal_Int32 mnAlpha; /// Alpha value (color opacity).
+};
+
+typedef boost::shared_ptr< Color > ColorPtr;
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/colorchoicecontext.hxx b/oox/inc/oox/drawingml/colorchoicecontext.hxx
new file mode 100644
index 000000000000..8b42a2e74c15
--- /dev/null
+++ b/oox/inc/oox/drawingml/colorchoicecontext.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_COLORCHOICECONTEXT_HXX
+#define OOX_DRAWINGML_COLORCHOICECONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox {
+namespace drawingml {
+
+class Color;
+
+// ============================================================================
+
+/** Context handler for the different color value elements (a:scrgbClr,
+ a:srgbClr, a:hslClr, a:sysClr, a:schemeClr, a:prstClr). */
+class ColorValueContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit ColorValueContext( ::oox::core::ContextHandler& rParent, Color& rColor );
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ 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 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ Color& mrColor;
+};
+
+// ============================================================================
+
+/** Context handler for elements that *contain* a color value element
+ (a:scrgbClr, a:srgbClr, a:hslClr, a:sysClr, a:schemeClr, a:prstClr). */
+class ColorContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit ColorContext( ::oox::core::ContextHandler& rParent, Color& rColor );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ Color& mrColor;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/connectorshapecontext.hxx b/oox/inc/oox/drawingml/connectorshapecontext.hxx
new file mode 100644
index 000000000000..f20624c55efc
--- /dev/null
+++ b/oox/inc/oox/drawingml/connectorshapecontext.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CONNECTORSHAPECONTEXT_HXX
+#define OOX_DRAWINGML_CONNECTORSHAPECONTEXT_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/shapecontext.hxx"
+
+namespace oox { namespace drawingml {
+
+class ConnectorShapeContext : public ShapeContext
+{
+public:
+ ConnectorShapeContext( ::oox::core::ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pGroupShapePtr );
+ virtual ~ConnectorShapeContext();
+ 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);
+};
+
+} }
+
+#endif // OOX_DRAWINGML_CONNECTORSHAPECONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/customshapegeometry.hxx b/oox/inc/oox/drawingml/customshapegeometry.hxx
new file mode 100644
index 000000000000..4fec38cf09eb
--- /dev/null
+++ b/oox/inc/oox/drawingml/customshapegeometry.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CUSTOMSHAPEGEOMETRY_HXX
+#define OOX_DRAWINGML_CUSTOMSHAPEGEOMETRY_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/shape.hxx"
+
+namespace oox { namespace drawingml {
+
+
+// ---------------------------------------------------------------------
+// CT_CustomGeometry2D
+class CustomShapeGeometryContext : public ::oox::core::ContextHandler
+{
+public:
+ CustomShapeGeometryContext( ::oox::core::ContextHandler& rParent, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, 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);
+
+private:
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+// ---------------------------------------------------------------------
+// CT_PresetGeometry2D
+class PresetShapeGeometryContext : public ::oox::core::ContextHandler
+{
+public:
+ PresetShapeGeometryContext( ::oox::core::ContextHandler& rParent, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, 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);
+
+private:
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+// ---------------------------------------------------------------------
+// CT_PresetTextShape
+class PresetTextShapeContext : public ::oox::core::ContextHandler
+{
+public:
+ PresetTextShapeContext( ::oox::core::ContextHandler& rParent, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, 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);
+
+private:
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_CUSTOMSHAPEGEOMETRY_HXX
diff --git a/oox/inc/oox/drawingml/customshapeproperties.hxx b/oox/inc/oox/drawingml/customshapeproperties.hxx
new file mode 100644
index 000000000000..985507d22265
--- /dev/null
+++ b/oox/inc/oox/drawingml/customshapeproperties.hxx
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_CUSTOMSHAPEPROPERTIES_HXX
+#define OOX_DRAWINGML_CUSTOMSHAPEPROPERTIES_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <map>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/color.hxx"
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/token/tokens.hxx"
+
+namespace oox { namespace drawingml {
+
+class CustomShapeProperties;
+
+typedef boost::shared_ptr< CustomShapeProperties > CustomShapePropertiesPtr;
+
+struct CustomShapeGuide
+{
+ rtl::OUString maName;
+ rtl::OUString maFormula;
+};
+
+struct AdjustHandle
+{
+ sal_Bool polar;
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair
+ pos;
+
+ // depending to the type (polar or not):
+ OptValue< rtl::OUString > gdRef1; // gdRefX or gdRefR
+ OptValue< com::sun::star::drawing::EnhancedCustomShapeParameter >
+ min1; // minX or minR
+ OptValue< com::sun::star::drawing::EnhancedCustomShapeParameter >
+ max1; // maxX or maxR
+ OptValue< rtl::OUString > gdRef2; // gdRefY or gdRefAng
+ OptValue< com::sun::star::drawing::EnhancedCustomShapeParameter >
+ min2; // minX or minAng
+ OptValue< com::sun::star::drawing::EnhancedCustomShapeParameter >
+ max2; // maxY or maxAng
+
+ AdjustHandle( sal_Bool bPolar ) : polar( bPolar ) {};
+};
+
+struct ConnectionSite
+{
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair
+ pos;
+ com::sun::star::drawing::EnhancedCustomShapeParameter
+ ang;
+};
+
+struct GeomRect
+{
+ com::sun::star::drawing::EnhancedCustomShapeParameter l;
+ com::sun::star::drawing::EnhancedCustomShapeParameter t;
+ com::sun::star::drawing::EnhancedCustomShapeParameter r;
+ com::sun::star::drawing::EnhancedCustomShapeParameter b;
+};
+
+struct Path2D
+{
+ sal_Int64 w;
+ sal_Int64 h;
+ sal_Int32 fill;
+ sal_Bool stroke;
+ sal_Bool extrusionOk;
+ std::vector< com::sun::star::drawing::EnhancedCustomShapeParameterPair > parameter;
+
+ Path2D() : w( 0 ), h( 0 ), fill( XML_norm ), stroke( sal_True ), extrusionOk( sal_True ) {};
+};
+
+class CustomShapeProperties
+{
+public:
+
+ CustomShapeProperties();
+ virtual ~CustomShapeProperties();
+
+ void apply( const CustomShapePropertiesPtr& );
+ void pushToPropSet( const ::oox::core::FilterBase& rFilterBase,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > & xPropSet,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape > & xShape) const;
+
+ void setShapePresetType( const rtl::OUString& rShapePresetType ){ maShapePresetType = rShapePresetType; };
+
+ std::vector< CustomShapeGuide >& getAdjustmentGuideList(){ return maAdjustmentGuideList; };
+ std::vector< CustomShapeGuide >& getGuideList(){ return maGuideList; };
+ std::vector< AdjustHandle >& getAdjustHandleList(){ return maAdjustHandleList; };
+ std::vector< ConnectionSite >& getConnectionSiteList(){ return maConnectionSiteList; };
+ OptValue< GeomRect >& getTextRect(){ return maTextRect; };
+ std::vector< Path2D >& getPath2DList(){ return maPath2DList; };
+ std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& getSegments(){ return maSegments; };
+ void setMirroredX( sal_Bool bMirroredX ) { mbMirroredX = bMirroredX; };
+ void setMirroredY( sal_Bool bMirroredY ) { mbMirroredY = bMirroredY; };
+
+ double getValue( const std::vector< CustomShapeGuide >&, sal_uInt32 nIndex ) const;
+ static sal_Int32 SetCustomShapeGuideValue( std::vector< CustomShapeGuide >& rGuideList, const CustomShapeGuide& rGuide );
+ static sal_Int32 GetCustomShapeGuideValue( const std::vector< CustomShapeGuide >& rGuideList, const rtl::OUString& rFormulaName );
+
+private:
+
+ rtl::OUString maShapePresetType;
+ std::vector< CustomShapeGuide > maAdjustmentGuideList;
+ std::vector< CustomShapeGuide > maGuideList;
+ std::vector< AdjustHandle > maAdjustHandleList;
+ std::vector< ConnectionSite > maConnectionSiteList;
+ OptValue< GeomRect > maTextRect;
+ std::vector< Path2D > maPath2DList;
+
+ std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >
+ maSegments;
+ sal_Bool mbMirroredX;
+ sal_Bool mbMirroredY;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_CUSTOMSHAPEPROPERTIES_HXX
diff --git a/oox/inc/oox/drawingml/diagram/datamodelcontext.hxx b/oox/inc/oox/drawingml/diagram/datamodelcontext.hxx
new file mode 100644
index 000000000000..a09f7b100e2e
--- /dev/null
+++ b/oox/inc/oox/drawingml/diagram/datamodelcontext.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_SHAPECONTEXT_HXX
+#define OOX_DRAWINGML_SHAPECONTEXT_HXX
+
+#include <com/sun/star/drawing/XShapes.hpp>
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+
+namespace oox { namespace drawingml {
+
+// CT_DataModel
+class DataModelContext : public ::oox::core::ContextHandler
+{
+public:
+ DataModelContext( ::oox::core::ContextHandler& rParent, const DiagramDataPtr & pDataModelPtr );
+ virtual ~DataModelContext();
+
+ 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:
+ DiagramDataPtr mpDataModel;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_SHAPEGROUPCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/diagram/diagram.hxx b/oox/inc/oox/drawingml/diagram/diagram.hxx
new file mode 100644
index 000000000000..f9c74246e558
--- /dev/null
+++ b/oox/inc/oox/drawingml/diagram/diagram.hxx
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_DRAWINGML_DIAGRAM_HXX
+#define OOX_DRAWINGML_DIAGRAM_HXX
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/diagram/diagramlayoutatoms.hxx"
+
+namespace oox { namespace drawingml {
+
+namespace dgm {
+
+/** A Connection
+ */
+class Connection
+{
+public:
+ Connection()
+ : mnType( 0 )
+ , mnSourceOrder( 0 )
+ , mnDestOrder( 0 )
+ {
+ }
+
+ void dump();
+
+ sal_Int32 mnType;
+ ::rtl::OUString msModelId;
+ ::rtl::OUString msSourceId;
+ ::rtl::OUString msDestId;
+ ::rtl::OUString msParTransId;
+ ::rtl::OUString msPresId;
+ ::rtl::OUString msSibTransId;
+ sal_Int32 mnSourceOrder;
+ sal_Int32 mnDestOrder;
+
+};
+
+typedef boost::shared_ptr< Connection > ConnectionPtr;
+typedef std::vector< ConnectionPtr > Connections;
+
+class Point;
+
+typedef boost::shared_ptr< Point > PointPtr;
+typedef std::vector< PointPtr > Points;
+/** A point
+ */
+class Point
+{
+public:
+ Point();
+ ShapePtr & getShape( )
+ { return mpShape; }
+
+ void setCnxId( const ::rtl::OUString & sCnxId )
+ { msCnxId = sCnxId; }
+ void setModelId( const ::rtl::OUString & sModelId );
+ const ::rtl::OUString & getModelId() const
+ { return msModelId; }
+ void setType( const sal_Int32 nType )
+ { mnType = nType; }
+ sal_Int32 getType() const
+ { return mnType; }
+
+ void dump();
+private:
+ ShapePtr mpShape;
+ ::rtl::OUString msCnxId;
+ ::rtl::OUString msModelId;
+ sal_Int32 mnType;
+};
+
+
+class PointsTree;
+typedef boost::shared_ptr< PointsTree > PointsTreePtr;
+
+/** a points tree node */
+class PointsTree
+ : public boost::enable_shared_from_this< PointsTree >
+{
+public:
+ typedef std::vector< PointsTreePtr > Childrens;
+ PointsTree()
+ {};
+ PointsTree( const PointPtr & pPoint )
+ : mpNode( pPoint )
+ { }
+ bool addChild( const PointsTreePtr & pChild );
+ const PointPtr & getPoint() const
+ { return mpNode; }
+ PointsTreePtr getParent() const;
+ Childrens::const_iterator beginChild() const
+ { return maChildrens.begin(); }
+ Childrens::const_iterator endChild() const
+ { return maChildrens.end(); }
+private:
+ PointPtr mpNode;
+ boost::weak_ptr< PointsTree > mpParent;
+ Childrens maChildrens;
+};
+
+}
+
+////////////////////
+
+class DiagramData
+{
+public:
+
+ DiagramData();
+ FillPropertiesPtr & getFillProperties()
+ { return mpFillProperties; }
+ dgm::Connections & getConnections()
+ { return maConnections; }
+ dgm::Points & getPoints()
+ { return maPoints; }
+ void dump();
+private:
+ FillPropertiesPtr mpFillProperties;
+ dgm::Connections maConnections;
+ dgm::Points maPoints;
+};
+
+typedef boost::shared_ptr< DiagramData > DiagramDataPtr;
+
+
+
+////////////////////
+
+class DiagramLayout
+{
+public:
+ void setDefStyle( const ::rtl::OUString & sDefStyle )
+ { msDefStyle = sDefStyle; }
+ void setMinVer( const ::rtl::OUString & sMinVer )
+ { msMinVer = sMinVer; }
+ void setUniqueId( const ::rtl::OUString & sUniqueId )
+ { msUniqueId = sUniqueId; }
+ const ::rtl::OUString & getUniqueId()
+ { return msUniqueId; }
+ void setTitle( const ::rtl::OUString & sTitle )
+ { msTitle = sTitle; }
+ void setDesc( const ::rtl::OUString & sDesc )
+ { msDesc = sDesc; }
+
+ LayoutNodePtr & getNode()
+ { return mpNode; }
+ const LayoutNodePtr & getNode() const
+ { return mpNode; }
+ DiagramDataPtr & getSampData()
+ { return mpSampData; }
+ const DiagramDataPtr & getSampData() const
+ { return mpSampData; }
+ DiagramDataPtr & getStyleData()
+ { return mpStyleData; }
+ const DiagramDataPtr & getStyleData() const
+ { return mpStyleData; }
+
+ void layout( const dgm::PointsTreePtr & pTree, const com::sun::star::awt::Point & pt );
+private:
+ ::rtl::OUString msDefStyle;
+ ::rtl::OUString msMinVer;
+ ::rtl::OUString msUniqueId;
+
+ ::rtl::OUString msTitle;
+ ::rtl::OUString msDesc;
+ LayoutNodePtr mpNode;
+ DiagramDataPtr mpSampData;
+ DiagramDataPtr mpStyleData;
+ // TODO
+ // catLst
+ // clrData
+};
+
+typedef boost::shared_ptr< DiagramLayout > DiagramLayoutPtr;
+
+///////////////////////
+
+class DiagramQStyles
+{
+
+};
+
+typedef boost::shared_ptr< DiagramQStyles > DiagramQStylesPtr;
+
+///////////////////////
+
+class DiagramColors
+{
+
+};
+
+typedef boost::shared_ptr< DiagramColors > DiagramColorsPtr;
+
+///////////////////////
+
+class Diagram
+{
+public:
+ void setData( const DiagramDataPtr & );
+ void setLayout( const DiagramLayoutPtr & );
+ DiagramLayoutPtr getLayout() const
+ {
+ return mpLayout;
+ }
+ void setQStyles( const DiagramQStylesPtr & );
+ void setColors( const DiagramColorsPtr & );
+
+ void addTo( const ShapePtr & pShape );
+ ::rtl::OUString getLayoutId() const;
+private:
+ void build( );
+ DiagramDataPtr mpData;
+ DiagramLayoutPtr mpLayout;
+ DiagramQStylesPtr mpQStyles;
+ DiagramColorsPtr mpColors;
+ std::map< ::rtl::OUString, ShapePtr > maShapeMap;
+ dgm::PointsTreePtr mpRoot;
+};
+
+
+typedef boost::shared_ptr< Diagram > DiagramPtr;
+
+} }
+
+#endif
diff --git a/oox/inc/oox/drawingml/diagram/diagramfragmenthandler.hxx b/oox/inc/oox/drawingml/diagram/diagramfragmenthandler.hxx
new file mode 100644
index 000000000000..f9fd32dc71d6
--- /dev/null
+++ b/oox/inc/oox/drawingml/diagram/diagramfragmenthandler.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_DIAGRAMFRAGMENTHANDLER
+#define OOX_DRAWINGML_DIAGRAMFRAGMENTHANDLER
+
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+
+namespace oox { namespace drawingml {
+
+
+class DiagramDataFragmentHandler : public ::oox::core::FragmentHandler
+{
+public:
+ DiagramDataFragmentHandler( oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, const DiagramDataPtr pDataPtr ) throw();
+ virtual ~DiagramDataFragmentHandler() throw();
+
+ virtual void SAL_CALL endDocument() 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:
+
+ DiagramDataPtr mpDataPtr;
+};
+
+
+
+class DiagramLayoutFragmentHandler : public ::oox::core::FragmentHandler
+{
+public:
+ DiagramLayoutFragmentHandler( oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, const DiagramLayoutPtr pDataPtr ) throw();
+ virtual ~DiagramLayoutFragmentHandler() throw();
+
+ virtual void SAL_CALL endDocument() 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 mpDataPtr;
+};
+
+class DiagramQStylesFragmentHandler : public ::oox::core::FragmentHandler
+{
+public:
+ DiagramQStylesFragmentHandler( oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, const DiagramQStylesPtr pDataPtr ) throw();
+ virtual ~DiagramQStylesFragmentHandler() throw();
+
+ virtual void SAL_CALL endDocument() 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:
+
+ DiagramQStylesPtr mpDataPtr;
+};
+
+
+class DiagramColorsFragmentHandler : public ::oox::core::FragmentHandler
+{
+public:
+ DiagramColorsFragmentHandler( ::oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, const DiagramColorsPtr pDataPtr ) throw();
+ virtual ~DiagramColorsFragmentHandler() throw();
+
+ virtual void SAL_CALL endDocument() 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:
+
+ DiagramColorsPtr mpDataPtr;
+};
+
+} }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/diagram/diagramlayoutatoms.hxx b/oox/inc/oox/drawingml/diagram/diagramlayoutatoms.hxx
new file mode 100644
index 000000000000..7df2deddfa83
--- /dev/null
+++ b/oox/inc/oox/drawingml/diagram/diagramlayoutatoms.hxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+
+
+#ifndef OOX_DRAWINGML_DIAGRAMLAYOUTATOMS_HXX
+#define OOX_DRAWINGML_DIAGRAMLAYOUTATOMS_HXX
+
+#include <map>
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/array.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+
+#include "oox/drawingml/shape.hxx"
+
+
+namespace oox { namespace drawingml {
+
+
+// AG_IteratorAttributes
+class IteratorAttr
+{
+public:
+ IteratorAttr();
+
+ // not sure this belong here, but wth
+ void loadFromXAttr( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes );
+
+private:
+ sal_Int32 mnAxis;
+ sal_Int32 mnCnt;
+ sal_Bool mbHideLastTrans;
+ sal_Int32 mnPtType;
+ sal_Int32 mnSt;
+ sal_Int32 mnStep;
+};
+
+class ConditionAttr
+{
+public:
+ ConditionAttr();
+
+ // not sure this belong here, but wth
+ void loadFromXAttr( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes );
+
+private:
+ sal_Int32 mnFunc;
+ sal_Int32 mnArg;
+ sal_Int32 mnOp;
+ ::rtl::OUString msVal;
+};
+
+class LayoutAtom;
+
+typedef boost::shared_ptr< LayoutAtom > LayoutAtomPtr;
+
+/** abstract Atom for the layout */
+class LayoutAtom
+{
+public:
+ virtual ~LayoutAtom()
+ {}
+ // TODO change signature to the proper one
+ virtual void processAtom() = 0;
+ void setName( const ::rtl::OUString & sName )
+ { msName = sName; }
+ void addChild( const LayoutAtomPtr & pNode )
+ { mpChildNodes.push_back( pNode ); }
+
+ // dump for debug
+ virtual void dump(int level = 0);
+protected:
+ std::vector< LayoutAtomPtr > mpChildNodes;
+ ::rtl::OUString msName;
+};
+
+class AlgAtom
+ : public LayoutAtom
+{
+public:
+ virtual ~AlgAtom()
+ {}
+ typedef std::map< std::string, ::com::sun::star::uno::Any > ParamMap;
+
+ virtual void processAtom()
+ {}
+private:
+ ParamMap mParams;
+};
+
+
+class ForEachAtom
+ : public LayoutAtom
+{
+public:
+ virtual ~ForEachAtom()
+ {}
+
+ IteratorAttr & iterator()
+ { return maIter; }
+ virtual void processAtom();
+private:
+ IteratorAttr maIter;
+};
+
+typedef boost::shared_ptr< ForEachAtom > ForEachAtomPtr;
+
+
+class ConditionAtom
+ : public LayoutAtom
+{
+public:
+ ConditionAtom( bool bElse = false )
+ : LayoutAtom( )
+ , mbElse( bElse )
+ {}
+ virtual ~ConditionAtom()
+ {}
+ bool test();
+ virtual void processAtom()
+ {}
+ IteratorAttr & iterator()
+ { return maIter; }
+ ConditionAttr & cond()
+ { return maCond; }
+private:
+ bool mbElse;
+ IteratorAttr maIter;
+ ConditionAttr maCond;
+};
+
+typedef boost::shared_ptr< ConditionAtom > ConditionAtomPtr;
+
+
+/** "choose" statements. Atoms will be tested in order. */
+class ChooseAtom
+ : public LayoutAtom
+{
+public:
+ virtual ~ChooseAtom()
+ {}
+ virtual void processAtom();
+};
+
+class LayoutNode
+ : public LayoutAtom
+{
+public:
+ enum {
+ VAR_animLvl = 0,
+ VAR_animOne,
+ VAR_bulletEnabled,
+ VAR_chMax,
+ VAR_chPref,
+ VAR_dir,
+ VAR_hierBranch,
+ VAR_orgChart,
+ VAR_resizeHandles
+ };
+ // we know that the array is of fixed size
+ // the use of Any allow having empty values
+ typedef boost::array< ::com::sun::star::uno::Any, 9 > VarMap;
+
+ virtual ~LayoutNode()
+ {}
+ virtual void processAtom()
+ {}
+ VarMap & variables()
+ { return mVariables; }
+private:
+ VarMap mVariables;
+ std::vector< ShapePtr > mpShapes;
+};
+
+typedef boost::shared_ptr< LayoutNode > LayoutNodePtr;
+
+} }
+
+#endif
diff --git a/oox/inc/oox/drawingml/drawingmltypes.hxx b/oox/inc/oox/drawingml/drawingmltypes.hxx
new file mode 100644
index 000000000000..f8bb4c91b5d5
--- /dev/null
+++ b/oox/inc/oox/drawingml/drawingmltypes.hxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TYPES_HXX
+#define OOX_DRAWINGML_TYPES_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <com/sun/star/style/TabAlign.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/geometry/IntegerRectangle2D.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+const sal_Int32 PER_PERCENT = 1000;
+const sal_Int32 MAX_PERCENT = 100 * PER_PERCENT;
+
+const sal_Int32 PER_DEGREE = 60000;
+const sal_Int32 MAX_DEGREE = 360 * PER_DEGREE;
+
+// ============================================================================
+
+struct LineProperties;
+typedef ::boost::shared_ptr< LineProperties > LinePropertiesPtr;
+
+struct FillProperties;
+typedef ::boost::shared_ptr< FillProperties > FillPropertiesPtr;
+
+struct GraphicProperties;
+typedef ::boost::shared_ptr< GraphicProperties > GraphicPropertiesPtr;
+
+struct TextCharacterProperties;
+typedef ::boost::shared_ptr< TextCharacterProperties > TextCharacterPropertiesPtr;
+
+struct TextBodyProperties;
+typedef ::boost::shared_ptr< TextBodyProperties > TextBodyPropertiesPtr;
+
+class TextBody;
+typedef ::boost::shared_ptr< TextBody > TextBodyPtr;
+
+class Shape;
+typedef ::boost::shared_ptr< Shape > ShapePtr;
+
+class Theme;
+typedef ::boost::shared_ptr< Theme > ThemePtr;
+
+// ---------------------------------------------------------------------------
+
+namespace table {
+
+class TableProperties;
+typedef ::boost::shared_ptr< TableProperties > TablePropertiesPtr;
+
+} // namespace table
+
+// ============================================================================
+
+/** converts the attributes from an CT_Point2D into an awt Point with 1/100th mm */
+com::sun::star::awt::Point GetPoint2D( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes );
+
+/** 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 );
+
+
+/** converts the attributes from an CT_Size2D into an awt Size with 1/100th mm */
+com::sun::star::awt::Size GetSize2D( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes );
+
+/** 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 >& xAttributes );
+
+/** 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 );
+
+/** converts EMUs into 1/100th mmm */
+sal_Int32 GetCoordinate( sal_Int32 nValue );
+
+/** converts an emu string into 1/100th mmm */
+sal_Int32 GetCoordinate( const ::rtl::OUString& sValue );
+
+/** converts a ST_Percentage % string into 1/1000th of % */
+sal_Int32 GetPercent( const ::rtl::OUString& sValue );
+
+/** Converts a ST_PositiveFixedPercentage to a float. 1.0 == 100% */
+double GetPositiveFixedPercentage( const ::rtl::OUString& sValue );
+
+/** converts the ST_TextFontSize to point */
+float GetTextSize( const ::rtl::OUString& rValue );
+
+/** converts the ST_TextSpacingPoint to 1/100mm */
+sal_Int32 GetTextSpacingPoint( const ::rtl::OUString& sValue );
+sal_Int32 GetTextSpacingPoint( const sal_Int32 nValue );
+
+::com::sun::star::drawing::TextVerticalAdjust GetTextVerticalAdjust( sal_Int32 nToken );
+
+/** */
+::com::sun::star::style::TabAlign GetTabAlign( ::sal_Int32 aToken );
+
+float GetFontHeight( sal_Int32 nHeight );
+
+sal_Int16 GetFontUnderline( sal_Int32 nToken );
+
+sal_Int16 GetFontStrikeout( sal_Int32 nToken );
+
+sal_Int16 GetCaseMap( sal_Int32 nToken );
+
+/** converts a paragraph align to a ParaAdjust */
+sal_Int16 GetParaAdjust( sal_Int32 nAlign );
+
+// ============================================================================
+
+// CT_IndexRange
+struct IndexRange {
+ sal_Int32 start;
+ sal_Int32 end;
+};
+
+/** retrieve the content of CT_IndexRange */
+IndexRange GetIndexRange( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes );
+
+// ============================================================================
+
+struct EmuPoint
+{
+ sal_Int64 X;
+ sal_Int64 Y;
+
+ inline explicit EmuPoint() : X( 0 ), Y( 0 ) {}
+ inline explicit EmuPoint( sal_Int64 nX, sal_Int64 nY ) : X( nX ), Y( nY ) {}
+};
+
+// ============================================================================
+
+struct EmuSize
+{
+ sal_Int64 Width;
+ sal_Int64 Height;
+
+ inline explicit EmuSize() : Width( 0 ), Height( 0 ) {}
+ inline explicit EmuSize( sal_Int64 nWidth, sal_Int64 nHeight ) : Width( nWidth ), Height( nHeight ) {}
+};
+
+// ============================================================================
+
+struct EmuRectangle : public EmuPoint, public EmuSize
+{
+ inline explicit EmuRectangle() {}
+ inline explicit EmuRectangle( const EmuPoint& rPos, const EmuSize& rSize ) : EmuPoint( rPos ), EmuSize( rSize ) {}
+ inline explicit EmuRectangle( sal_Int64 nX, sal_Int64 nY, sal_Int64 nWidth, sal_Int64 nHeight ) : EmuPoint( nX, nY ), EmuSize( nWidth, nHeight ) {}
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/embeddedwavaudiofile.hxx b/oox/inc/oox/drawingml/embeddedwavaudiofile.hxx
new file mode 100644
index 000000000000..d724254b4263
--- /dev/null
+++ b/oox/inc/oox/drawingml/embeddedwavaudiofile.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_EMBEDDEDWAVAUDIOFILE_HXX
+#define OOX_DRAWINGML_EMBEDDEDWAVAUDIOFILE_HXX
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+
+#include "oox/core/fragmenthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+ struct EmbeddedWAVAudioFile
+ {
+ EmbeddedWAVAudioFile()
+ : mbBuiltIn(false)
+ {
+ }
+ bool mbBuiltIn;
+ ::rtl::OUString msName;
+ ::rtl::OUString msEmbed;
+ };
+
+ void getEmbeddedWAVAudioFile(
+ const ::oox::core::Relations& rRelations,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ EmbeddedWAVAudioFile & aAudio );
+
+} }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/fillproperties.hxx b/oox/inc/oox/drawingml/fillproperties.hxx
new file mode 100644
index 000000000000..d62651ebdc20
--- /dev/null
+++ b/oox/inc/oox/drawingml/fillproperties.hxx
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_FILLPROPERTIES_HXX
+#define OOX_DRAWINGML_FILLPROPERTIES_HXX
+
+#include <map>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/geometry/IntegerRectangle2D.hpp>
+#include "oox/drawingml/color.hxx"
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+ class GraphicHelper;
+ class ModelObjectHelper;
+ class PropertyMap;
+ class PropertySet;
+}
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+enum FillPropertyId
+{
+ FillStyleId,
+ FillColorId,
+ FillTransparenceId,
+ FillGradientId,
+ FillBitmapUrlId,
+ FillBitmapModeId,
+ FillBitmapSizeXId,
+ FillBitmapSizeYId,
+ FillBitmapOffsetXId,
+ FillBitmapOffsetYId,
+ FillBitmapRectanglePointId,
+ FillId_END
+};
+
+struct FillPropertyIds
+{
+ const sal_Int32* mpnPropertyIds;
+ bool mbNamedFillGradient;
+ bool mbNamedFillBitmap;
+
+ explicit FillPropertyIds(
+ const sal_Int32* pnPropertyIds,
+ bool bNamedFillGradient,
+ bool bNamedFillBitmap );
+
+ inline bool has( FillPropertyId ePropId ) const { return mpnPropertyIds[ ePropId ] >= 0; }
+ inline sal_Int32 operator[]( FillPropertyId ePropId ) const { return mpnPropertyIds[ ePropId ]; }
+};
+
+// ============================================================================
+
+struct GradientFillProperties
+{
+ typedef ::std::map< double, Color > GradientStopMap;
+
+ GradientStopMap maGradientStops; /// Gradient stops (colors/transparence).
+ OptValue< ::com::sun::star::geometry::IntegerRectangle2D > moFillToRect;
+ OptValue< ::com::sun::star::geometry::IntegerRectangle2D > moTileRect;
+ OptValue< sal_Int32 > moGradientPath; /// If set, gradient follows rectangle, circle, or shape.
+ OptValue< sal_Int32 > moShadeAngle; /// Rotation angle of linear gradients.
+ OptValue< sal_Int32 > moShadeFlip; /// Flip mode of gradient, if not stretched to shape.
+ OptValue< bool > moShadeScaled; /// True = scale gradient into shape.
+ OptValue< bool > moRotateWithShape; /// True = rotate gradient with shape.
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const GradientFillProperties& rSourceProps );
+};
+
+// ============================================================================
+
+struct PatternFillProperties
+{
+ Color maPattFgColor; /// Pattern foreground color.
+ Color maPattBgColor; /// Pattern background color.
+ OptValue< sal_Int32 > moPattPreset; /// Preset pattern type.
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const PatternFillProperties& rSourceProps );
+};
+
+// ============================================================================
+
+struct BlipFillProperties
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >
+ mxGraphic; /// The fill graphic.
+ OptValue< sal_Int32 > moBitmapMode; /// Bitmap tile or stretch.
+ OptValue< ::com::sun::star::geometry::IntegerRectangle2D >
+ moFillRect; /// Stretch fill offsets.
+ OptValue< ::com::sun::star::geometry::IntegerRectangle2D >
+ moClipRect;
+ OptValue< sal_Int32 > moTileOffsetX; /// Width of bitmap tiles (EMUs).
+ OptValue< sal_Int32 > moTileOffsetY; /// Height of bitmap tiles (EMUs).
+ OptValue< sal_Int32 > moTileScaleX; /// Horizontal scaling of bitmap tiles (1/1000 percent).
+ OptValue< sal_Int32 > moTileScaleY; /// Vertical scaling of bitmap tiles (1/1000 percent).
+ OptValue< sal_Int32 > moTileAlign; /// Anchor point inside bitmap.
+ OptValue< sal_Int32 > moTileFlip; /// Flip mode of bitmap tiles.
+ OptValue< bool > moRotateWithShape; /// True = rotate bitmap with shape.
+ // effects
+ OptValue< sal_Int32 > moColorEffect; /// XML token for a color effect.
+ OptValue< sal_Int32 > moBrightness; /// Brightness in the range [-100000,100000].
+ OptValue< sal_Int32 > moContrast; /// Contrast in the range [-100000,100000].
+ Color maColorChangeFrom; /// Start color of color transformation.
+ Color maColorChangeTo; /// Destination color of color transformation.
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const BlipFillProperties& rSourceProps );
+};
+
+// ============================================================================
+
+struct FillProperties
+{
+ OptValue< sal_Int32 > moFillType; /// Fill type (OOXML token).
+ Color maFillColor; /// Solid fill color and transparence.
+ GradientFillProperties maGradientProps; /// Properties for gradient fills.
+ PatternFillProperties maPatternProps; /// Properties for pattern fills.
+ BlipFillProperties maBlipProps; /// Properties for bitmap fills.
+
+ static FillPropertyIds DEFAULT_IDS; /// Default fill property identifiers for shape fill.
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const FillProperties& rSourceProps );
+
+ /** Tries to resolve current settings to a solid color, e.g. returns the
+ start color of a gradient. */
+ Color getBestSolidColor() const;
+
+ /** Writes the properties to the passed property map. */
+ void pushToPropMap(
+ PropertyMap& rPropMap,
+ ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper,
+ const FillPropertyIds& rPropIds = DEFAULT_IDS,
+ sal_Int32 nShapeRotation = 0,
+ sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const;
+
+ /** Writes the properties to the passed property set. */
+ void pushToPropSet(
+ PropertySet& rPropSet,
+ ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper,
+ const FillPropertyIds& rPropIds = DEFAULT_IDS,
+ sal_Int32 nShapeRotation = 0,
+ sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const;
+};
+
+// ============================================================================
+
+struct GraphicProperties
+{
+ BlipFillProperties maBlipProps; /// Properties for the graphic.
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const GraphicProperties& rSourceProps );
+
+ /** Writes the properties to the passed property map. */
+ void pushToPropMap(
+ PropertyMap& rPropMap,
+ const GraphicHelper& rGraphicHelper,
+ sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const;
+
+ /** Writes the properties to the passed property set. */
+ void pushToPropSet(
+ PropertySet& rPropSet,
+ const GraphicHelper& rGraphicHelper,
+ sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/fillpropertiesgroupcontext.hxx b/oox/inc/oox/drawingml/fillpropertiesgroupcontext.hxx
new file mode 100644
index 000000000000..86c790795f25
--- /dev/null
+++ b/oox/inc/oox/drawingml/fillpropertiesgroupcontext.hxx
@@ -0,0 +1,215 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_FILLPROPERTIESGROUPCONTEXT_HPP
+#define OOX_DRAWINGML_FILLPROPERTIESGROUPCONTEXT_HPP
+
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+/** Context handler that imports the a:solidFill element. */
+class SolidFillContext : public ColorContext
+{
+public:
+ explicit SolidFillContext(
+ ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ FillProperties& rFillProps );
+};
+
+// ============================================================================
+
+/** Context handler that imports the a:gradFill element. */
+class GradientFillContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit GradientFillContext(
+ ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ GradientFillProperties& rGradientProps );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+private:
+ GradientFillProperties& mrGradientProps;
+};
+
+// ============================================================================
+
+/** Context handler that imports the a:pattFill element. */
+class PatternFillContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit PatternFillContext(
+ ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ PatternFillProperties& rPatternProps );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+private:
+ PatternFillProperties& mrPatternProps;
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Context handler that imports the a:clrChange element containing the colors
+ of a bitmap color change transformation. */
+class ColorChangeContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit ColorChangeContext(
+ ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ BlipFillProperties& rBlipProps );
+ virtual ~ColorChangeContext();
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+private:
+ BlipFillProperties& mrBlipProps;
+ bool mbUseAlpha;
+};
+
+// ============================================================================
+
+/** Context handler that imports the a:blip element containing the fill bitmap
+ and bitmap color transformation settings. */
+class BlipContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit BlipContext(
+ ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ BlipFillProperties& rBlipProps );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+private:
+ BlipFillProperties& mrBlipProps;
+};
+
+// ============================================================================
+
+/** Context handler that imports the a:blipFill element. */
+class BlipFillContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit BlipFillContext(
+ ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ BlipFillProperties& rBlipProps );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+private:
+ BlipFillProperties& mrBlipProps;
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Context handler for elements that contain a fill property element
+ (a:noFill, a:solidFill, a:gradFill, a:pattFill, a:blipFill, a:grpFill). */
+class FillPropertiesContext : public ::oox::core::ContextHandler
+{
+public:
+ explicit FillPropertiesContext(
+ ::oox::core::ContextHandler& rParent,
+ FillProperties& rFillProps );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler >
+ createFillContext(
+ ::oox::core::ContextHandler& rParent,
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
+ FillProperties& rFillProps );
+
+protected:
+ FillProperties& mrFillProps;
+};
+
+// ============================================================================
+
+/** Context handler for elements that contain a fill property element
+ (a:noFill, a:solidFill, a:gradFill, a:pattFill, a:blipFill, a:grpFill).
+
+ This context handler takes a simple color instead of a fill properties
+ struct. The imported fill properties are converted automatically to the
+ best fitting solid color.
+ */
+class SimpleFillPropertiesContext : private FillProperties, public FillPropertiesContext
+{
+public:
+ explicit SimpleFillPropertiesContext(
+ ::oox::core::ContextHandler& rParent,
+ Color& rColor );
+ virtual ~SimpleFillPropertiesContext();
+
+protected:
+ Color& mrColor;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/graphicshapecontext.hxx b/oox/inc/oox/drawingml/graphicshapecontext.hxx
new file mode 100644
index 000000000000..5f27efdf15e7
--- /dev/null
+++ b/oox/inc/oox/drawingml/graphicshapecontext.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_GRAPHICSHAPECONTEXT_HXX
+#define OOX_DRAWINGML_GRAPHICSHAPECONTEXT_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/shapecontext.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+
+namespace oox { namespace vml { struct OleObjectInfo; } }
+
+namespace oox { namespace drawingml {
+
+class GraphicShapeContext : public ShapeContext
+{
+public:
+ GraphicShapeContext( ::oox::core::ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr );
+
+ 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);
+
+};
+
+// ====================================================================
+
+class GraphicalObjectFrameContext : public ShapeContext
+{
+public:
+ GraphicalObjectFrameContext( ::oox::core::ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr, bool bEmbedShapesInChart );
+
+ 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:
+ bool mbEmbedShapesInChart;
+};
+
+// ====================================================================
+
+class OleObjectGraphicDataContext : public ShapeContext
+{
+public:
+ OleObjectGraphicDataContext( ::oox::core::ContextHandler& rParent, ShapePtr pShapePtr );
+ ~OleObjectGraphicDataContext();
+ 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:
+ ::oox::vml::OleObjectInfo& mrOleObjectInfo;
+};
+
+// ====================================================================
+
+class DiagramGraphicDataContext
+ : public ShapeContext
+{
+public:
+ DiagramGraphicDataContext( ::oox::core::ContextHandler& rParent, ShapePtr pShapePtr );
+ virtual ~DiagramGraphicDataContext();
+ 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:
+ DiagramPtr loadDiagram();
+
+ ::rtl::OUString msDm;
+ ::rtl::OUString msLo;
+ ::rtl::OUString msQs;
+ ::rtl::OUString msCs;
+};
+
+// ====================================================================
+
+class ChartGraphicDataContext : public ShapeContext
+{
+public:
+ explicit ChartGraphicDataContext(
+ ::oox::core::ContextHandler& rParent,
+ const ShapePtr& rxShape, bool bEmbedShapes );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ ChartShapeInfo& mrChartShapeInfo;
+};
+
+// ====================================================================
+
+} }
+
+#endif // OOX_DRAWINGML_GRAPHICSHAPECONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/guidcontext.hxx b/oox/inc/oox/drawingml/guidcontext.hxx
new file mode 100644
index 000000000000..20dff63fc373
--- /dev/null
+++ b/oox/inc/oox/drawingml/guidcontext.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_GUIDCONTEXT_HXX
+#define OOX_DRAWINGML_GUIDCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+ class GuidContext : public ::oox::core::ContextHandler
+ {
+
+ public:
+ GuidContext( ::oox::core::ContextHandler& rParent, rtl::OUString& rGuidId );
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ private:
+
+ rtl::OUString& mrGuidId;
+ };
+
+} }
+
+#endif
diff --git a/oox/inc/oox/drawingml/lineproperties.hxx b/oox/inc/oox/drawingml/lineproperties.hxx
new file mode 100644
index 000000000000..0f034a89f65b
--- /dev/null
+++ b/oox/inc/oox/drawingml/lineproperties.hxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_LINEPROPERTIES_HXX
+#define OOX_DRAWINGML_LINEPROPERTIES_HXX
+
+#include "oox/drawingml/fillproperties.hxx"
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+enum LinePropertyId
+{
+ LineStyleId,
+ LineWidthId,
+ LineColorId,
+ LineTransparenceId,
+ LineDashId,
+ LineJointId,
+ LineStartId,
+ LineStartWidthId,
+ LineStartCenterId,
+ LineEndId,
+ LineEndWidthId,
+ LineEndCenterId,
+ LineId_END
+};
+
+struct LinePropertyIds
+{
+ const sal_Int32* mpnPropertyIds;
+ bool mbNamedLineDash;
+ bool mbNamedLineMarker;
+
+ explicit LinePropertyIds(
+ const sal_Int32* pnPropertyIds,
+ bool bNamedLineDash,
+ bool bNamedLineMarker );
+
+ inline bool has( LinePropertyId ePropId ) const { return mpnPropertyIds[ ePropId ] >= 0; }
+ inline sal_Int32 operator[]( LinePropertyId ePropId ) const { return mpnPropertyIds[ ePropId ]; }
+};
+
+// ============================================================================
+
+struct LineArrowProperties
+{
+ OptValue< sal_Int32 > moArrowType;
+ OptValue< sal_Int32 > moArrowWidth;
+ OptValue< sal_Int32 > moArrowLength;
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const LineArrowProperties& rSourceProps );
+};
+
+// ============================================================================
+
+struct LineProperties
+{
+ typedef ::std::pair< sal_Int32, sal_Int32 > DashStop;
+ typedef ::std::vector< DashStop > DashStopVector;
+
+ LineArrowProperties maStartArrow; /// Start line arrow style.
+ LineArrowProperties maEndArrow; /// End line arrow style.
+ FillProperties maLineFill; /// Line fill (solid, gradient, ...).
+ DashStopVector maCustomDash; /// User-defined line dash style.
+ OptValue< sal_Int32 > moLineWidth; /// Line width (EMUs).
+ OptValue< sal_Int32 > moPresetDash; /// Preset dash (OOXML token).
+ OptValue< sal_Int32 > moLineCompound; /// Line compound type (OOXML token).
+ OptValue< sal_Int32 > moLineCap; /// Line cap (OOXML token).
+ OptValue< sal_Int32 > moLineJoint; /// Line joint type (OOXML token).
+
+ static LinePropertyIds DEFAULT_IDS; /// Default line property identifiers.
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const LineProperties& rSourceProps );
+
+ /** Writes the properties to the passed property map. */
+ void pushToPropMap(
+ PropertyMap& rPropMap,
+ ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper,
+ const LinePropertyIds& rPropIds = DEFAULT_IDS,
+ sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const;
+
+ /** Writes the properties to the passed property map. */
+ void pushToPropSet(
+ PropertySet& rPropSet,
+ ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper,
+ const LinePropertyIds& rPropIds = DEFAULT_IDS,
+ sal_Int32 nPhClr = API_RGB_TRANSPARENT ) const;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/linepropertiescontext.hxx b/oox/inc/oox/drawingml/linepropertiescontext.hxx
new file mode 100644
index 000000000000..617e3fa67c93
--- /dev/null
+++ b/oox/inc/oox/drawingml/linepropertiescontext.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_LINEPROPERTIESCONTEXT_HXX
+#define OOX_DRAWINGML_LINEPROPERTIESCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+// ---------------------------------------------------------------------
+
+struct LineProperties;
+
+class LinePropertiesContext : public ::oox::core::ContextHandler
+{
+public:
+ LinePropertiesContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes,
+ LineProperties& rLineProperties ) throw();
+ ~LinePropertiesContext();
+
+ 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:
+ LineProperties& mrLineProperties;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_LINEPROPERTIESCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/objectdefaultcontext.hxx b/oox/inc/oox/drawingml/objectdefaultcontext.hxx
new file mode 100644
index 000000000000..b572637ec047
--- /dev/null
+++ b/oox/inc/oox/drawingml/objectdefaultcontext.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_OBJECTDEFAULTCONTEXT_HXX
+#define OOX_DRAWINGML_OBJECTDEFAULTCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class Theme;
+
+class objectDefaultContext : public oox::core::ContextHandler
+{
+public:
+ objectDefaultContext( ::oox::core::ContextHandler& rParent, Theme& rTheme );
+ 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:
+ Theme& mrTheme;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_OBJECTDEFAULTCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/shape.hxx b/oox/inc/oox/drawingml/shape.hxx
new file mode 100644
index 000000000000..2114f8d9cf02
--- /dev/null
+++ b/oox/inc/oox/drawingml/shape.hxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_SHAPE_HXX
+#define OOX_DRAWINGML_SHAPE_HXX
+
+#include "oox/helper/propertymap.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapeproperties.hxx"
+#include "oox/drawingml/textliststyle.hxx"
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <vector>
+#include <map>
+
+namespace oox { namespace vml {
+ struct OleObjectInfo;
+} }
+
+namespace oox { namespace drawingml {
+
+class CustomShapeProperties;
+typedef boost::shared_ptr< CustomShapeProperties > CustomShapePropertiesPtr;
+
+typedef ::std::map< ::rtl::OUString, ShapePtr > ShapeIdMap;
+
+struct ShapeStyleRef
+{
+ Color maPhClr;
+ sal_Int32 mnThemedIdx;
+};
+
+typedef ::std::map< sal_Int32, ShapeStyleRef > ShapeStyleRefMap;
+
+// ============================================================================
+
+/** Additional information for a chart embedded in a drawing shape. */
+struct ChartShapeInfo
+{
+ ::rtl::OUString maFragmentPath; /// Path to related XML stream, e.g. for charts.
+ bool mbEmbedShapes; /// True = load chart shapes into chart, false = load into parent drawpage.
+
+ inline explicit ChartShapeInfo( bool bEmbedShapes ) : mbEmbedShapes( bEmbedShapes ) {}
+};
+
+// ============================================================================
+
+class Shape
+ : public boost::enable_shared_from_this< Shape >
+{
+public:
+
+ explicit Shape( const sal_Char* pServiceType = 0 );
+ virtual ~Shape();
+
+ rtl::OUString& getServiceName(){ return msServiceName; }
+ void setServiceName( const sal_Char* pServiceName );
+
+ PropertyMap& getShapeProperties(){ return maShapeProperties; }
+
+ inline LineProperties& getLineProperties() { return *mpLinePropertiesPtr; }
+ inline const LineProperties& getLineProperties() const { return *mpLinePropertiesPtr; }
+
+ inline FillProperties& getFillProperties() { return *mpFillPropertiesPtr; }
+ inline const FillProperties& getFillProperties() const { return *mpFillPropertiesPtr; }
+
+ inline GraphicProperties& getGraphicProperties() { return *mpGraphicPropertiesPtr; }
+ inline const GraphicProperties& getGraphicProperties() const { return *mpGraphicPropertiesPtr; }
+
+ CustomShapePropertiesPtr getCustomShapeProperties(){ return mpCustomShapePropertiesPtr; }
+
+ table::TablePropertiesPtr getTableProperties();
+
+ void setPosition( com::sun::star::awt::Point nPosition ){ maPosition = nPosition; }
+ void setSize( com::sun::star::awt::Size aSize ){ maSize = aSize; }
+ void setRotation( sal_Int32 nRotation ) { mnRotation = nRotation; }
+ void setFlip( sal_Bool bFlipH, sal_Bool bFlipV ) { mbFlipH = bFlipH; mbFlipV = bFlipV; }
+ void addChild( const ShapePtr pChildPtr ) { maChildren.push_back( pChildPtr ); }
+ std::vector< ShapePtr >& getChildren() { return maChildren; }
+
+ void setName( const rtl::OUString& rName ) { msName = rName; }
+ ::rtl::OUString getName( ) { return msName; }
+ void setId( const rtl::OUString& rId ) { msId = rId; }
+ void setHidden( sal_Bool bHidden ) { mbHidden = bHidden; }
+ sal_Bool getHidden() const { return mbHidden; };
+ void setSubType( sal_Int32 nSubType ) { mnSubType = nSubType; }
+ sal_Int32 getSubType() const { return mnSubType; }
+ void setSubTypeIndex( sal_uInt32 nSubTypeIndex ) { mnSubTypeIndex = nSubTypeIndex; }
+ sal_Int32 getSubTypeIndex() const { return mnSubTypeIndex; }
+
+ // setDefaults has to be called if styles are imported (OfficeXML is not storing properties having the default value)
+ void setDefaults();
+
+ ::oox::vml::OleObjectInfo& setOleObjectType();
+ ChartShapeInfo& setChartType( bool bEmbedShapes );
+ void setDiagramType();
+ void setTableType();
+
+ void setTextBody(const TextBodyPtr & pTextBody);
+ TextBodyPtr getTextBody();
+ void setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle );
+ TextListStylePtr getMasterTextListStyle() const { return mpMasterTextListStyle; }
+
+ inline ShapeStyleRefMap& getShapeStyleRefs() { return maShapeStyleRefs; }
+ inline const ShapeStyleRefMap& getShapeStyleRefs() const { return maShapeStyleRefs; }
+ const ShapeStyleRef* getShapeStyleRef( sal_Int32 nRefType ) const;
+
+ // addShape is creating and inserting the corresponding XShape.
+ void addShape(
+ ::oox::core::XmlFilterBase& rFilterBase,
+ const Theme* pTheme,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle* pShapeRect = 0,
+ ShapeIdMap* pShapeMap = 0 );
+
+ void setXShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rXShape )
+ { mxShape = rXShape; };
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > &
+ getXShape() const { return mxShape; }
+
+ virtual void applyShapeReference( const Shape& rReferencedShape );
+
+protected:
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createAndInsert(
+ ::oox::core::XmlFilterBase& rFilterBase,
+ const ::rtl::OUString& rServiceName,
+ const Theme* pTheme,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle* pShapeRect,
+ sal_Bool bClearText );
+
+ void addChildren(
+ ::oox::core::XmlFilterBase& rFilterBase,
+ Shape& rMaster,
+ const Theme* pTheme,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rClientRect,
+ ShapeIdMap* pShapeMap );
+
+ virtual ::rtl::OUString finalizeServiceName(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rServiceName,
+ const ::com::sun::star::awt::Rectangle& rShapeRect );
+
+ virtual void finalizeXShape(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes );
+
+ std::vector< ShapePtr > maChildren; // only used for group shapes
+ TextBodyPtr mpTextBody;
+ LinePropertiesPtr mpLinePropertiesPtr;
+ FillPropertiesPtr mpFillPropertiesPtr;
+ GraphicPropertiesPtr mpGraphicPropertiesPtr;
+ CustomShapePropertiesPtr mpCustomShapePropertiesPtr;
+ table::TablePropertiesPtr mpTablePropertiesPtr;
+ PropertyMap maShapeProperties;
+ TextListStylePtr mpMasterTextListStyle;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxShape;
+
+ rtl::OUString msServiceName;
+ rtl::OUString msName;
+ rtl::OUString msId;
+ sal_Int32 mnSubType; // if this type is not zero, then the shape is a placeholder
+ sal_Int32 mnSubTypeIndex;
+
+ ShapeStyleRefMap maShapeStyleRefs;
+
+ com::sun::star::awt::Size maSize;
+ com::sun::star::awt::Point maPosition;
+
+private:
+ enum FrameType
+ {
+ FRAMETYPE_GENERIC, /// Generic shape, no special type.
+ FRAMETYPE_OLEOBJECT, /// OLE object embedded in a shape.
+ FRAMETYPE_CHART, /// Chart embedded in a shape.
+ FRAMETYPE_DIAGRAM, /// Complex diagram drawing shape.
+ FRAMETYPE_TABLE /// A table embedded in a shape.
+ };
+
+ typedef ::boost::shared_ptr< ::oox::vml::OleObjectInfo > OleObjectInfoRef;
+ typedef ::boost::shared_ptr< ChartShapeInfo > ChartShapeInfoRef;
+
+ FrameType meFrameType; /// Type for graphic frame shapes.
+ OleObjectInfoRef mxOleObjectInfo; /// Additional data for OLE objects.
+ ChartShapeInfoRef mxChartShapeInfo; /// Additional data for chart shapes.
+
+ sal_Int32 mnRotation;
+ sal_Bool mbFlipH;
+ sal_Bool mbFlipV;
+ sal_Bool mbHidden;
+};
+
+::rtl::OUString GetShapeType( sal_Int32 nType );
+
+// ============================================================================
+
+} }
+
+#endif // OOX_DRAWINGML_SHAPE_HXX
diff --git a/oox/inc/oox/drawingml/shapecontext.hxx b/oox/inc/oox/drawingml/shapecontext.hxx
new file mode 100644
index 000000000000..68ef45ac92cc
--- /dev/null
+++ b/oox/inc/oox/drawingml/shapecontext.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_SHAPECONTEXT_HXX
+#define OOX_DRAWINGML_SHAPECONTEXT_HXX
+
+#include <com/sun/star/drawing/XShapes.hpp>
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/shapepropertiescontext.hxx"
+
+namespace oox { namespace drawingml {
+
+class ShapeContext : public ::oox::core::ContextHandler
+{
+public:
+ ShapeContext( ::oox::core::ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr );
+ virtual ~ShapeContext();
+
+ 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);
+
+ ShapePtr getShape();
+
+protected:
+
+ ShapePtr mpMasterShapePtr;
+ ShapePtr mpShapePtr;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_SHAPEGROUPCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/shapegroupcontext.hxx b/oox/inc/oox/drawingml/shapegroupcontext.hxx
new file mode 100644
index 000000000000..681c527c0635
--- /dev/null
+++ b/oox/inc/oox/drawingml/shapegroupcontext.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_SHAPEGROUPCONTEXT_HXX
+#define OOX_DRAWINGML_SHAPEGROUPCONTEXT_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/shapecontext.hxx"
+
+namespace oox { namespace drawingml {
+
+class ShapeGroupContext : public ::oox::core::ContextHandler
+{
+public:
+ ShapeGroupContext( ::oox::core::ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pGroupShapePtr );
+ virtual ~ShapeGroupContext();
+ 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:
+
+ ShapePtr mpGroupShapePtr;
+ ShapePtr mpMasterShapePtr;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_SHAPEGROUPCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/shapepropertiescontext.hxx b/oox/inc/oox/drawingml/shapepropertiescontext.hxx
new file mode 100644
index 000000000000..8cb4a3276918
--- /dev/null
+++ b/oox/inc/oox/drawingml/shapepropertiescontext.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_SHAPEPROPERTIESCONTEXT_HXX
+#define OOX_DRAWINGML_SHAPEPROPERTIESCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/shape.hxx"
+
+namespace oox { namespace drawingml {
+
+class ShapePropertiesContext : public ::oox::core::ContextHandler
+{
+public:
+ ShapePropertiesContext( ::oox::core::ContextHandler& rParent, Shape& rShape );
+
+ 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:
+ Shape& mrShape;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_SHAPEPROPERTIESCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/shapestylecontext.hxx b/oox/inc/oox/drawingml/shapestylecontext.hxx
new file mode 100644
index 000000000000..71fc8b33b7c6
--- /dev/null
+++ b/oox/inc/oox/drawingml/shapestylecontext.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_SHAPESTYLECONTEXT_HXX
+#define OOX_DRAWINGML_SHAPESTYLECONTEXT_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class ShapeStyleContext : public ::oox::core::ContextHandler
+{
+public:
+ ShapeStyleContext( ::oox::core::ContextHandler& rParent, Shape& rShape );
+ ~ShapeStyleContext();
+
+ 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:
+ Shape& mrShape;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_SHAPESTYLECONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/spdefcontext.hxx b/oox/inc/oox/drawingml/spdefcontext.hxx
new file mode 100644
index 000000000000..dced46eaa700
--- /dev/null
+++ b/oox/inc/oox/drawingml/spdefcontext.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_SPDEFCONTEXT_HXX
+#define OOX_DRAWINGML_SPDEFCONTEXT_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class spDefContext : public oox::core::ContextHandler
+{
+public:
+ spDefContext( ::oox::core::ContextHandler& rParent, Shape& rDefaultObject );
+ 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:
+ Shape& mrDefaultObject;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_SPDEFCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/table/tablebackgroundstylecontext.hxx b/oox/inc/oox/drawingml/table/tablebackgroundstylecontext.hxx
new file mode 100644
index 000000000000..541fc2333234
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablebackgroundstylecontext.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLEBACKGROUNDSTYLECONTEXT
+#define OOX_DRAWINGML_TABLEBACKGROUNDSTYLECONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/table/tablestyle.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableBackgroundStyleContext : public ::oox::core::ContextHandler
+{
+public:
+ TableBackgroundStyleContext( ::oox::core::ContextHandler& rParent, TableStyle& rTableStyle );
+ ~TableBackgroundStyleContext();
+
+ 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:
+
+ TableStyle& mrTableStyle;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/table/tablecell.hxx b/oox/inc/oox/drawingml/table/tablecell.hxx
new file mode 100644
index 000000000000..cf70e1d155c0
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablecell.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TABLECELL_HXX
+#define OOX_DRAWINGML_TABLECELL_HXX
+
+#include "oox/helper/propertymap.hxx"
+#include "oox/drawingml/color.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/drawingml/textliststyle.hxx"
+#include <com/sun/star/table/XCell.hpp>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
+#include <vector>
+#include <map>
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableCellContext;
+class TableProperties;
+class TableStyle;
+
+class TableCell
+{
+ friend class TableCellContext;
+
+public:
+
+ TableCell();
+ ~TableCell();
+
+ sal_Int32 getRowSpan() const { return mnRowSpan; };
+ void setRowSpan( sal_Int32 nRowSpan ){ mnRowSpan = nRowSpan; };
+ sal_Int32 getGridSpan() const { return mnGridSpan; };
+ void setGridSpan( sal_Int32 nGridSpan ){ mnGridSpan = nGridSpan; };
+ sal_Bool gethMerge() const { return mbhMerge; };
+ void sethMerge( sal_Bool bhMerge ){ mbhMerge = bhMerge; };
+ sal_Bool getvMerge() const { return mbvMerge; };
+ void setvMerge( sal_Bool bvMerge ){ mbvMerge = bvMerge; };
+ sal_Int32 getLeftMargin() const { return mnMarL; };
+ void setLeftMargin( sal_Int32 nMargin ){ mnMarL = nMargin; };
+ sal_Int32 getRightMargin() const { return mnMarR; };
+ void setRightMargin( sal_Int32 nMargin ){ mnMarR = nMargin; };
+ sal_Int32 getTopMargin() const { return mnMarT; };
+ void setTopMargin( sal_Int32 nMargin ){ mnMarT = nMargin; };
+ sal_Int32 getBottomMargin() const { return mnMarB; };
+ void setBottomMargin( sal_Int32 nMargin ){ mnMarB = nMargin; };
+ sal_Int32 getVertToken() const { return mnVertToken; };
+ void setVertToken( sal_Int32 nToken ){ mnVertToken = nToken; };
+ sal_Int32 getAnchorToken() const { return mnAnchorToken; };
+ void setAnchorToken( sal_Int32 nToken ){ mnAnchorToken = nToken; };
+ sal_Bool getAnchorCtr() const { return mbAnchorCtr; };
+ void setAnchorCtr( sal_Bool bAnchorCtr ){ mbAnchorCtr = bAnchorCtr; };
+ sal_Int32 getHorzOverflowToken() const { return mnHorzOverflowToken; };
+ void setHorzOverflowToken( sal_Int32 nToken ){ mnHorzOverflowToken = nToken; };
+
+ void setTextBody( const oox::drawingml::TextBodyPtr& pTextBody ){ mpTextBody = pTextBody; };
+ oox::drawingml::TextBodyPtr getTextBody(){ return mpTextBody; };
+
+ void pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, ::oox::drawingml::TextListStylePtr pMasterTextListStyle,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::table::XCell >& rxCell, const TableProperties& rTableProperties,
+ const TableStyle& rTable, sal_Int32 nColumn, sal_Int32 nMaxColumn, sal_Int32 nRow, sal_Int32 nMaxRow );
+
+private:
+
+ oox::drawingml::TextBodyPtr mpTextBody;
+
+ oox::drawingml::LineProperties maLinePropertiesLeft;
+ oox::drawingml::LineProperties maLinePropertiesRight;
+ oox::drawingml::LineProperties maLinePropertiesTop;
+ oox::drawingml::LineProperties maLinePropertiesBottom;
+ oox::drawingml::LineProperties maLinePropertiesTopLeftToBottomRight;
+ oox::drawingml::LineProperties maLinePropertiesBottomLeftToTopRight;
+
+ oox::drawingml::FillProperties maFillProperties;
+
+ sal_Int32 mnRowSpan;
+ sal_Int32 mnGridSpan;
+ sal_Bool mbhMerge;
+ sal_Bool mbvMerge;
+
+ sal_Int32 mnMarL;
+ sal_Int32 mnMarR;
+ sal_Int32 mnMarT;
+ sal_Int32 mnMarB;
+ sal_Int32 mnVertToken;
+ sal_Int32 mnAnchorToken;
+ sal_Bool mbAnchorCtr;
+ sal_Int32 mnHorzOverflowToken;
+};
+
+} } }
+
+#endif // OOX_DRAWINGML_TABLECELL_HXX
diff --git a/oox/inc/oox/drawingml/table/tablecellcontext.hxx b/oox/inc/oox/drawingml/table/tablecellcontext.hxx
new file mode 100644
index 000000000000..02ab8d93ff76
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablecellcontext.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLECELLCONTEXT
+#define OOX_DRAWINGML_TABLECELLCONTEXT
+
+#include "oox/drawingml/shapecontext.hxx"
+#include "oox/drawingml/table/tablecell.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableCellContext : public ::oox::core::ContextHandler
+{
+public:
+ TableCellContext( ::oox::core::ContextHandler& rParent,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& xAttribs, TableCell& rTableCell );
+ ~TableCellContext();
+
+ 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:
+
+ TableCell& mrTableCell;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/table/tablecontext.hxx b/oox/inc/oox/drawingml/table/tablecontext.hxx
new file mode 100644
index 000000000000..727bf66b4185
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablecontext.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLECONTEXT
+#define OOX_DRAWINGML_TABLECONTEXT
+
+#include "oox/drawingml/shapecontext.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableProperties;
+
+class TableContext : public ShapeContext
+{
+public:
+ TableContext( ::oox::core::ContextHandler& rParent, ShapePtr pShapePtr );
+ ~TableContext();
+
+ 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:
+
+ TableProperties& mrTableProperties;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/table/tablepartstylecontext.hxx b/oox/inc/oox/drawingml/table/tablepartstylecontext.hxx
new file mode 100644
index 000000000000..902e1ad79f89
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablepartstylecontext.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLEPARTSTYLECONTEXT
+#define OOX_DRAWINGML_TABLEPARTSTYLECONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/table/tablestylepart.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TablePartStyleContext : public ::oox::core::ContextHandler
+{
+public:
+ TablePartStyleContext( ::oox::core::ContextHandler& rParent, TableStylePart& rTableStylePart );
+ ~TablePartStyleContext();
+
+ 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:
+
+ TableStylePart& mrTableStylePart;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/table/tableproperties.hxx b/oox/inc/oox/drawingml/table/tableproperties.hxx
new file mode 100644
index 000000000000..83793709da7c
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tableproperties.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TABLEPROPERTIES_HXX
+#define OOX_DRAWINGML_TABLEPROPERTIES_HXX
+
+#include "oox/drawingml/table/tablerow.hxx"
+#include "oox/drawingml/table/tablestyle.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/drawingml/color.hxx"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
+#include <vector>
+#include <map>
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableProperties
+{
+public:
+
+ TableProperties();
+ ~TableProperties();
+
+ std::vector< sal_Int32 >& getTableGrid() { return mvTableGrid; };
+ std::vector< TableRow >& getTableRows() { return mvTableRows; };
+
+ rtl::OUString& getStyleId(){ return maStyleId; };
+ boost::shared_ptr< TableStyle >& getTableStyle(){ return mpTableStyle; };
+ sal_Bool& isRtl(){ return mbRtl; };
+ sal_Bool& isFirstRow(){ return mbFirstRow; };
+ sal_Bool& isFirstCol(){ return mbFirstCol; };
+ sal_Bool& isLastRow(){ return mbLastRow; };
+ sal_Bool& isLastCol(){ return mbLastCol; };
+ sal_Bool& isBandRow(){ return mbBandRow; };
+ sal_Bool& isBandCol(){ return mbBandCol; };
+
+ void apply( const TablePropertiesPtr& );
+ void pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > & xPropSet, ::oox::drawingml::TextListStylePtr pMasterTextListStyle );
+
+private:
+
+ const TableStyle& getUsedTableStyle( const ::oox::core::XmlFilterBase& rFilterBase );
+
+ rtl::OUString maStyleId; // either StyleId is available
+ boost::shared_ptr< TableStyle > mpTableStyle; // or the complete TableStyle
+ std::vector< sal_Int32 > mvTableGrid;
+ std::vector< TableRow > mvTableRows;
+
+ sal_Bool mbRtl;
+ sal_Bool mbFirstRow;
+ sal_Bool mbFirstCol;
+ sal_Bool mbLastRow;
+ sal_Bool mbLastCol;
+ sal_Bool mbBandRow;
+ sal_Bool mbBandCol;
+};
+
+} } }
+
+#endif // OOX_DRAWINGML_TABLEPROPERTIES_HXX
diff --git a/oox/inc/oox/drawingml/table/tablerow.hxx b/oox/inc/oox/drawingml/table/tablerow.hxx
new file mode 100644
index 000000000000..4ef12f3002ea
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablerow.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TABLEROW_HXX
+#define OOX_DRAWINGML_TABLEROW_HXX
+
+#include "oox/drawingml/table/tablecell.hxx"
+#include <vector>
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableRow
+{
+public:
+
+ TableRow();
+ ~TableRow();
+
+ void setHeight( sal_Int32 nHeight ){ mnHeight = nHeight; };
+ sal_Int32 getHeight() const { return mnHeight; };
+ std::vector< TableCell >& getTableCells() { return mvTableCells; };
+
+private:
+
+ sal_Int32 mnHeight;
+ std::vector< TableCell > mvTableCells;
+};
+
+} } }
+
+#endif // OOX_DRAWINGML_TABLEROW_HXX
diff --git a/oox/inc/oox/drawingml/table/tablerowcontext.hxx b/oox/inc/oox/drawingml/table/tablerowcontext.hxx
new file mode 100644
index 000000000000..f6cd981ddaed
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablerowcontext.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLEROWCONTEXT
+#define OOX_DRAWINGML_TABLEROWCONTEXT
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableRow;
+
+class TableRowContext : public ::oox::core::ContextHandler
+{
+public:
+ TableRowContext( ::oox::core::ContextHandler& rParent,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& xAttribs, TableRow& rTableRow );
+ ~TableRowContext();
+
+ 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:
+
+ TableRow& mrTableRow;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/table/tablestyle.hxx b/oox/inc/oox/drawingml/table/tablestyle.hxx
new file mode 100644
index 000000000000..4fb71d6ad5e0
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablestyle.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TABLESTYLE_HXX
+#define OOX_DRAWINGML_TABLESTYLE_HXX
+
+#include "oox/drawingml/table/tablestylepart.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/shape.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableStyle
+{
+public:
+
+ TableStyle();
+ ~TableStyle();
+
+ rtl::OUString& getStyleId(){ return maStyleId; }
+ rtl::OUString& getStyleName() { return maStyleName; }
+
+ ::oox::drawingml::ShapeStyleRef& getBackgroundFillStyleRef(){ return maFillStyleRef; }
+
+ ::oox::drawingml::FillPropertiesPtr& getBackgroundFillProperties(){ return mpFillProperties; }
+
+ TableStylePart& getWholeTbl() { return maWholeTbl; }
+ TableStylePart& getBand1H() { return maBand1H; }
+ TableStylePart& getBand2H() { return maBand2H; }
+ TableStylePart& getBand1V() { return maBand1V; }
+ TableStylePart& getBand2V() { return maBand2V; }
+ TableStylePart& getLastCol() { return maLastCol; }
+ TableStylePart& getFirstCol() { return maFirstCol; }
+ TableStylePart& getLastRow() { return maLastRow; }
+ TableStylePart& getSeCell() { return maSeCell; }
+ TableStylePart& getSwCell() { return maSwCell; }
+ TableStylePart& getFirstRow() { return maFirstRow; }
+ TableStylePart& getNeCell() { return maNeCell; }
+ TableStylePart& getNwCell() { return maNwCell; }
+
+private:
+
+ rtl::OUString maStyleId;
+ rtl::OUString maStyleName;
+
+ ::oox::drawingml::ShapeStyleRef maFillStyleRef;
+
+ ::oox::drawingml::FillPropertiesPtr mpFillProperties;
+
+ TableStylePart maWholeTbl;
+ TableStylePart maBand1H;
+ TableStylePart maBand2H;
+ TableStylePart maBand1V;
+ TableStylePart maBand2V;
+ TableStylePart maLastCol;
+ TableStylePart maFirstCol;
+ TableStylePart maLastRow;
+ TableStylePart maSeCell;
+ TableStylePart maSwCell;
+ TableStylePart maFirstRow;
+ TableStylePart maNeCell;
+ TableStylePart maNwCell;
+};
+
+} } }
+
+#endif // OOX_DRAWINGML_TABLESTYLE_HXX
diff --git a/oox/inc/oox/drawingml/table/tablestylecellstylecontext.hxx b/oox/inc/oox/drawingml/table/tablestylecellstylecontext.hxx
new file mode 100644
index 000000000000..e63a7754845e
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablestylecellstylecontext.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLESTYLECELLSTYLECONTEXT
+#define OOX_DRAWINGML_TABLESTYLECELLSTYLECONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/table/tablestylepart.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableStyleCellStyleContext : public ::oox::core::ContextHandler
+{
+public:
+ TableStyleCellStyleContext( ::oox::core::ContextHandler& rParent, TableStylePart& rTableStylePart );
+ ~TableStyleCellStyleContext();
+
+ 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:
+
+ TableStylePart& mrTableStylePart;
+ sal_Int32 mnLineType;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/table/tablestylecontext.hxx b/oox/inc/oox/drawingml/table/tablestylecontext.hxx
new file mode 100644
index 000000000000..8e464b2b2744
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablestylecontext.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLESTYLECONTEXT
+#define OOX_DRAWINGML_TABLESTYLECONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/table/tablestyle.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableStyleContext : public ::oox::core::ContextHandler
+{
+public:
+ TableStyleContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs,
+ TableStyle& rTableStyle );
+ ~TableStyleContext();
+
+ 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:
+
+ TableStyle& mrTableStyle;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/table/tablestylelist.hxx b/oox/inc/oox/drawingml/table/tablestylelist.hxx
new file mode 100644
index 000000000000..ea82fcdc4b28
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablestylelist.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TABLESTYLELIST_HXX
+#define OOX_DRAWINGML_TABLESTYLELIST_HXX
+
+#include <rtl/ustring.hxx>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableStyle;
+
+class TableStyleList
+{
+public:
+
+ TableStyleList();
+ ~TableStyleList();
+
+ rtl::OUString& getDefaultStyleId() { return maDefaultStyleId; };
+ std::vector< TableStyle >& getTableStyles(){ return maTableStyles; };
+
+private:
+
+ rtl::OUString maDefaultStyleId;
+ std::vector< TableStyle > maTableStyles;
+
+};
+
+typedef boost::shared_ptr< TableStyleList > TableStyleListPtr;
+
+} } }
+
+#endif // OOX_DRAWINGML_TABLESTYLELIST_HXX
diff --git a/oox/inc/oox/drawingml/table/tablestylelistfragmenthandler.hxx b/oox/inc/oox/drawingml/table/tablestylelistfragmenthandler.hxx
new file mode 100644
index 000000000000..7142f395d041
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablestylelistfragmenthandler.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TABLESTYLELISTFRAGMENTHANDLER_HXX
+#define OOX_DRAWINGML_TABLESTYLELISTFRAGMENTHANDLER_HXX
+
+#include "oox/drawingml/table/tablestylelist.hxx"
+#include "oox/core/fragmenthandler2.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace table {
+
+// ============================================================================
+
+class TableStyleListFragmentHandler : public ::oox::core::FragmentHandler2
+{
+public:
+ explicit TableStyleListFragmentHandler(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ TableStyleList& rTableStyleList );
+ virtual ~TableStyleListFragmentHandler();
+
+ 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:
+
+ TableStyleList& mrTableStyleList;
+};
+
+// ============================================================================
+
+} // namespace table
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/table/tablestylepart.hxx b/oox/inc/oox/drawingml/table/tablestylepart.hxx
new file mode 100644
index 000000000000..aebdd0245516
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablestylepart.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TABLESTYLEPART_HXX
+#define OOX_DRAWINGML_TABLESTYLEPART_HXX
+
+#include <rtl/ustring.hxx>
+#include <boost/optional.hpp>
+#include "oox/drawingml/color.hxx"
+#include "oox/drawingml/textfont.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/shape.hxx"
+#include <map>
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableStylePart
+{
+public:
+
+ TableStylePart();
+ ~TableStylePart();
+
+ ::oox::drawingml::Color& getTextColor(){ return maTextColor; }
+ ::boost::optional< sal_Bool >& getTextBoldStyle(){ return maTextBoldStyle; }
+ ::boost::optional< sal_Bool >& getTextItalicStyle(){ return maTextItalicStyle; }
+ ::oox::drawingml::TextFont& getAsianFont(){ return maAsianFont; }
+ ::oox::drawingml::TextFont& getComplexFont(){ return maComplexFont; }
+ ::oox::drawingml::TextFont& getSymbolFont(){ return maSymbolFont; }
+ ::oox::drawingml::TextFont& getLatinFont(){ return maLatinFont; }
+
+ ::oox::drawingml::FillPropertiesPtr& getFillProperties(){ return mpFillProperties; }
+ std::map < sal_Int32, ::oox::drawingml::LinePropertiesPtr >& getLineBorders(){ return maLineBorders; }
+
+ ::oox::drawingml::ShapeStyleRefMap& getStyleRefs(){ return maStyleRefs; }
+
+private:
+
+ ::oox::drawingml::Color maTextColor;
+ ::boost::optional< sal_Bool > maTextBoldStyle;
+ ::boost::optional< sal_Bool > maTextItalicStyle;
+ ::oox::drawingml::TextFont maAsianFont;
+ ::oox::drawingml::TextFont maComplexFont;
+ ::oox::drawingml::TextFont maSymbolFont;
+ ::oox::drawingml::TextFont maLatinFont;
+
+ ::oox::drawingml::FillPropertiesPtr mpFillProperties;
+ std::map < sal_Int32, ::oox::drawingml::LinePropertiesPtr > maLineBorders;
+ ::oox::drawingml::ShapeStyleRefMap maStyleRefs;
+};
+
+} } }
+
+#endif // OOX_DRAWINGML_TABLESTYLEPART_HXX
diff --git a/oox/inc/oox/drawingml/table/tablestyletextstylecontext.hxx b/oox/inc/oox/drawingml/table/tablestyletextstylecontext.hxx
new file mode 100644
index 000000000000..cf66d93c8738
--- /dev/null
+++ b/oox/inc/oox/drawingml/table/tablestyletextstylecontext.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TABLESTYLETEXTSTYLECONTEXT
+#define OOX_DRAWINGML_TABLESTYLETEXTSTYLECONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/table/tablestylepart.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+class TableStyleTextStyleContext : public ::oox::core::ContextHandler
+{
+public:
+ TableStyleTextStyleContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs,
+ TableStylePart& rTableStylePart );
+ ~TableStyleTextStyleContext();
+
+ 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:
+
+ TableStylePart& mrTableStylePart;
+};
+
+} } }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/textbody.hxx b/oox/inc/oox/drawingml/textbody.hxx
new file mode 100644
index 000000000000..ce747c62bdbb
--- /dev/null
+++ b/oox/inc/oox/drawingml/textbody.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTBODY_HXX
+#define OOX_DRAWINGML_TEXTBODY_HXX
+
+#include "oox/drawingml/textbodyproperties.hxx"
+#include "oox/drawingml/textliststyle.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace text { class XText; }
+ namespace text { class XTextCursor; }
+} } }
+
+namespace oox { namespace core { class XmlFilterBase; } }
+
+namespace oox { namespace drawingml {
+
+class TextParagraph;
+typedef RefVector< TextParagraph > TextParagraphVector;
+
+class TextBody
+{
+public:
+ TextBody();
+ ~TextBody();
+
+ inline const TextParagraphVector& getParagraphs() const { return maParagraphs; }
+ TextParagraph& addParagraph();
+
+ inline const TextListStyle& getTextListStyle() const { return maTextListStyle; }
+ inline TextListStyle& getTextListStyle() { return maTextListStyle; }
+
+ inline const TextBodyProperties& getTextProperties() const { return maTextProperties; }
+ inline TextBodyProperties& getTextProperties() { return maTextProperties; }
+
+ /** insert the text body at the text cursor */
+ void insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XText > & xText,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XTextCursor > & xAt,
+ const TextCharacterProperties& rTextStyleProperties,
+ const TextListStylePtr& pMasterTextListStyle ) const;
+protected:
+ TextParagraphVector maParagraphs;
+ TextBodyProperties maTextProperties;
+ TextListStyle maTextListStyle;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTBODY_HXX
diff --git a/oox/inc/oox/drawingml/textbodycontext.hxx b/oox/inc/oox/drawingml/textbodycontext.hxx
new file mode 100644
index 000000000000..acb12bffdac7
--- /dev/null
+++ b/oox/inc/oox/drawingml/textbodycontext.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTBODYCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTBODYCONTEXT_HXX
+
+#include <com/sun/star/text/XText.hpp>
+
+#include "oox/drawingml/textbody.hxx"
+#include "oox/drawingml/textrun.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class TextBodyContext : public ::oox::core::ContextHandler
+{
+public:
+ TextBodyContext( ::oox::core::ContextHandler& rParent, TextBody& rTextBody );
+
+ 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:
+ TextBody& mrTextBody;
+ ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > mxText;
+};
+
+// CT_RegularTextRun
+class RegularTextRunContext : public ::oox::core::ContextHandler
+{
+public:
+ RegularTextRunContext( ::oox::core::ContextHandler& rParent, TextRunPtr pRunPtr );
+
+ 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);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ TextRunPtr mpRunPtr;
+ bool mbIsInText;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTBODYCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/textbodyproperties.hxx b/oox/inc/oox/drawingml/textbodyproperties.hxx
new file mode 100644
index 000000000000..6688eea7746c
--- /dev/null
+++ b/oox/inc/oox/drawingml/textbodyproperties.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTBODYPROPERTIES_HXX
+#define OOX_DRAWINGML_TEXTBODYPROPERTIES_HXX
+
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertymap.hxx"
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+struct TextBodyProperties
+{
+ PropertyMap maPropertyMap;
+ OptValue< sal_Int32 > moRotation;
+ OptValue< sal_Int32 > moVert;
+
+ explicit TextBodyProperties();
+
+ void pushToPropMap( PropertyMap& rPropMap ) const;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/textbodypropertiescontext.hxx b/oox/inc/oox/drawingml/textbodypropertiescontext.hxx
new file mode 100644
index 000000000000..ec51d6da2b2f
--- /dev/null
+++ b/oox/inc/oox/drawingml/textbodypropertiescontext.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTBODYPROPERTIESCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTBODYPROPERTIESCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+struct TextBodyProperties;
+
+class TextBodyPropertiesContext : public ::oox::core::ContextHandler
+{
+public:
+ TextBodyPropertiesContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes,
+ TextBodyProperties& rTextBodyProp );
+
+ 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:
+ TextBodyProperties& mrTextBodyProp;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTBODYPROPERTIESCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/textcharacterproperties.hxx b/oox/inc/oox/drawingml/textcharacterproperties.hxx
new file mode 100644
index 000000000000..6f4282471227
--- /dev/null
+++ b/oox/inc/oox/drawingml/textcharacterproperties.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTCHARACTERPROPERTIES_HXX
+#define OOX_DRAWINGML_TEXTCHARACTERPROPERTIES_HXX
+
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/drawingml/color.hxx"
+#include "oox/drawingml/textfont.hxx"
+
+namespace oox { class PropertySet; }
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+struct TextCharacterProperties
+{
+ PropertyMap maHyperlinkPropertyMap;
+ TextFont maLatinFont;
+ TextFont maAsianFont;
+ TextFont maComplexFont;
+ TextFont maSymbolFont;
+ Color maCharColor;
+ Color maUnderlineColor;
+ Color maHighlightColor;
+ OptValue< ::rtl::OUString > moLang;
+ OptValue< sal_Int32 > moHeight;
+ OptValue< sal_Int32 > moSpacing;
+ OptValue< sal_Int32 > moUnderline;
+ OptValue< sal_Int32 > moStrikeout;
+ OptValue< sal_Int32 > moCaseMap;
+ OptValue< bool > moBold;
+ OptValue< bool > moItalic;
+ OptValue< bool > moUnderlineLineFollowText;
+ OptValue< bool > moUnderlineFillFollowText;
+
+ /** Overwrites all members that are explicitly set in rSourceProps. */
+ void assignUsed( const TextCharacterProperties& rSourceProps );
+
+ /** Returns the current character size. If possible the masterstyle should
+ have been applied before, otherwise the character size can be zero and
+ the default value is returned. */
+ float getCharHeightPoints( float fDefault ) const;
+
+ /** Writes the properties to the passed property map. */
+ void pushToPropMap(
+ PropertyMap& rPropMap,
+ const ::oox::core::XmlFilterBase& rFilter ) const;
+
+ /** Writes the properties to the passed property set. */
+ void pushToPropSet(
+ PropertySet& rPropSet,
+ const ::oox::core::XmlFilterBase& rFilter ) const;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/textcharacterpropertiescontext.hxx b/oox/inc/oox/drawingml/textcharacterpropertiescontext.hxx
new file mode 100644
index 000000000000..0d45c7c19f2b
--- /dev/null
+++ b/oox/inc/oox/drawingml/textcharacterpropertiescontext.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTCHARACTERPROPERTIESCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTCHARACTERPROPERTIESCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+struct TextCharacterProperties;
+
+class TextCharacterPropertiesContext : public ::oox::core::ContextHandler
+{
+public:
+ TextCharacterPropertiesContext( ::oox::core::ContextHandler& rParent,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& rXAttributes,
+ TextCharacterProperties& rTextCharacterProperties );
+ virtual ~TextCharacterPropertiesContext();
+
+ 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:
+ TextCharacterProperties& mrTextCharacterProperties;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTCHARACTERPROPERTIESCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/textfield.hxx b/oox/inc/oox/drawingml/textfield.hxx
new file mode 100644
index 000000000000..a1a0ab49c141
--- /dev/null
+++ b/oox/inc/oox/drawingml/textfield.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTFIELD_HXX
+#define OOX_DRAWINGML_TEXTFIELD_HXX
+
+#include <boost/shared_ptr.hpp>
+
+#include "oox/drawingml/textrun.hxx"
+#include "oox/drawingml/textparagraphproperties.hxx"
+
+namespace oox { namespace drawingml {
+
+struct TextCharacterProperties;
+
+class TextField
+ : public TextRun
+{
+public:
+ TextField();
+
+ inline TextParagraphProperties& getTextParagraphProperties() { return maTextParagraphProperties; }
+ inline const TextParagraphProperties& getTextParagraphProperties() const { return maTextParagraphProperties; }
+
+ inline void setType( const ::rtl::OUString& sType ) { msType = sType; }
+ inline void setUuid( const ::rtl::OUString & sUuid ) { msUuid = sUuid; }
+
+ virtual void insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XText > & xText,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XTextCursor > &xAt,
+ const TextCharacterProperties& rTextCharacterStyle ) const;
+
+private:
+ TextParagraphProperties maTextParagraphProperties;
+ ::rtl::OUString msType;
+ ::rtl::OUString msUuid;
+};
+
+typedef boost::shared_ptr< TextField > TextFieldPtr;
+
+} }
+
+#endif
diff --git a/oox/inc/oox/drawingml/textfieldcontext.hxx b/oox/inc/oox/drawingml/textfieldcontext.hxx
new file mode 100644
index 000000000000..b81265c9e923
--- /dev/null
+++ b/oox/inc/oox/drawingml/textfieldcontext.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTFIELDCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTFIELDCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class TextField;
+
+class TextFieldContext
+ : public ::oox::core::ContextHandler
+{
+public:
+ TextFieldContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rXAttributes,
+ TextField& rTextField);
+ virtual void SAL_CALL endFastElement( sal_Int32 aElementToken ) 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 >& rXAttributes )
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ TextField& mrTextField;
+ bool mbIsInText;
+};
+
+} }
+
+
+#endif
diff --git a/oox/inc/oox/drawingml/textfont.hxx b/oox/inc/oox/drawingml/textfont.hxx
new file mode 100644
index 000000000000..b8fd1d6f653b
--- /dev/null
+++ b/oox/inc/oox/drawingml/textfont.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGNML_TEXTFONT_HXX
+#define OOX_DRAWINGNML_TEXTFONT_HXX
+
+#include <rtl/ustring.hxx>
+
+namespace oox { class AttributeList; }
+namespace oox { namespace core { class XmlFilterBase; } }
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+/** carries a CT_TextFont*/
+class TextFont
+{
+public:
+ explicit TextFont();
+
+ /** Sets attributes from the passed attribute list. */
+ void setAttributes( const AttributeList& rAttribs );
+
+ /** Overwrites this text font with the passed text font, if it is used. */
+ void assignIfUsed( const TextFont& rTextFont );
+
+ /** Returns the font name, pitch, and family; tries to resolve theme
+ placeholder names, e.g. '+mj-lt' for the major latin theme font. */
+ bool getFontData(
+ ::rtl::OUString& rFontName,
+ sal_Int16 rnFontPitch,
+ sal_Int16& rnFontFamily,
+ const ::oox::core::XmlFilterBase& rFilter ) const;
+
+private:
+ bool implGetFontData(
+ ::rtl::OUString& rFontName,
+ sal_Int16 rnFontPitch,
+ sal_Int16& rnFontFamily ) const;
+
+private:
+ ::rtl::OUString maTypeface;
+ ::rtl::OUString maPanose;
+ sal_Int32 mnPitch;
+ sal_Int32 mnCharset;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/textliststyle.hxx b/oox/inc/oox/drawingml/textliststyle.hxx
new file mode 100644
index 000000000000..cafcc951504b
--- /dev/null
+++ b/oox/inc/oox/drawingml/textliststyle.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTLISTSTYLE_HXX
+#define OOX_DRAWINGML_TEXTLISTSTYLE_HXX
+
+#include "oox/drawingml/textparagraphproperties.hxx"
+#include "oox/helper/refvector.hxx"
+
+namespace oox { namespace drawingml {
+
+typedef RefVector< TextParagraphProperties > TextParagraphPropertiesVector;
+
+class TextListStyle
+{
+public:
+
+ TextListStyle();
+ ~TextListStyle();
+
+ void apply( const TextListStyle& rTextListStyle );
+
+ inline const TextParagraphPropertiesVector& getListStyle() const { return maListStyle; };
+ inline TextParagraphPropertiesVector& getListStyle() { return maListStyle; };
+
+ inline const TextParagraphPropertiesVector& getAggregationListStyle() const { return maAggregationListStyle; };
+ inline TextParagraphPropertiesVector& getAggregationListStyle() { return maAggregationListStyle; };
+
+protected:
+
+ TextParagraphPropertiesVector maListStyle;
+ TextParagraphPropertiesVector maAggregationListStyle;
+};
+
+typedef boost::shared_ptr< TextListStyle > TextListStylePtr;
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTLISTSTYLE_HXX
diff --git a/oox/inc/oox/drawingml/textliststylecontext.hxx b/oox/inc/oox/drawingml/textliststylecontext.hxx
new file mode 100644
index 000000000000..225bb83bf67f
--- /dev/null
+++ b/oox/inc/oox/drawingml/textliststylecontext.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTLISTSTYLECONTEXT_HXX
+#define OOX_DRAWINGML_TEXTLISTSTYLECONTEXT_HXX
+
+#include "oox/drawingml/textliststyle.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class TextListStyleContext : public ::oox::core::ContextHandler
+{
+public:
+ TextListStyleContext( ::oox::core::ContextHandler& rParent, TextListStyle& rTextListStyle );
+ ~TextListStyleContext();
+
+ 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:
+ TextListStyle& mrTextListStyle;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTLISTSTYLECONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/textparagraph.hxx b/oox/inc/oox/drawingml/textparagraph.hxx
new file mode 100644
index 000000000000..c059edc73f43
--- /dev/null
+++ b/oox/inc/oox/drawingml/textparagraph.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTPARAGRAPH_HXX
+#define OOX_DRAWINGML_TEXTPARAGRAPH_HXX
+
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XText.hpp>
+
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/textrun.hxx"
+#include "oox/drawingml/textliststyle.hxx"
+#include "oox/drawingml/textparagraphproperties.hxx"
+
+namespace oox { namespace drawingml {
+
+typedef RefVector< TextRun > TextRunVector;
+
+class TextParagraph
+{
+public:
+ TextParagraph();
+ ~TextParagraph();
+
+ inline TextRunVector& getRuns() { return maRuns; }
+ inline const TextRunVector& getRuns() const { return maRuns; }
+ inline void addRun( const TextRunPtr & pRun ) { maRuns.push_back( pRun ); }
+
+ inline TextParagraphProperties& getProperties() { return maProperties; }
+ inline const TextParagraphProperties& getProperties() const { return maProperties; }
+
+ inline TextCharacterProperties& getEndProperties() { return maEndProperties; }
+ inline const TextCharacterProperties& getEndProperties() const { return maEndProperties; }
+
+ //inline void setProperties( TextParagraphPropertiesPtr pProps ) { mpProperties = pProps; }
+
+ void insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XText > & xText,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XTextCursor > &xAt,
+ const TextCharacterProperties& rTextStyleProperties,
+ const TextListStyle& rTextListStyle,
+ bool bFirst = false ) const;
+
+private:
+ TextParagraphProperties maProperties;
+ TextCharacterProperties maEndProperties;
+ TextRunVector maRuns;
+};
+
+typedef boost::shared_ptr< TextParagraph > TextParagraphPtr;
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTPARAGRAPH_HXX
diff --git a/oox/inc/oox/drawingml/textparagraphproperties.hxx b/oox/inc/oox/drawingml/textparagraphproperties.hxx
new file mode 100644
index 000000000000..ef80af2d1c11
--- /dev/null
+++ b/oox/inc/oox/drawingml/textparagraphproperties.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIES_HXX
+#define OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIES_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/textcharacterproperties.hxx"
+#include <com/sun/star/style/NumberingType.hpp>
+#include "oox/drawingml/textfont.hxx"
+#include "textspacing.hxx"
+#include <boost/optional.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace graphic { class XGraphic; }
+} } }
+
+namespace oox { namespace drawingml {
+
+class TextParagraphProperties;
+
+typedef boost::shared_ptr< TextParagraphProperties > TextParagraphPropertiesPtr;
+
+class BulletList
+{
+public:
+ BulletList( );
+ bool is() const;
+ void apply( const BulletList& );
+ void pushToPropMap( const ::oox::core::XmlFilterBase& rFilterBase, PropertyMap& rPropMap ) const;
+ void setBulletChar( const ::rtl::OUString & sChar );
+ void setStartAt( sal_Int32 nStartAt ){ mnStartAt <<= static_cast< sal_Int16 >( nStartAt ); }
+ void setType( sal_Int32 nType );
+ void setNone( );
+ void setSuffixParenBoth();
+ void setSuffixParenRight();
+ void setSuffixPeriod();
+ void setSuffixNone();
+ void setSuffixMinusRight();
+ void setBulletSize(sal_Int16 nSize);
+ void setFontSize(sal_Int16 nSize);
+ void setStyleName( const rtl::OUString& rStyleName ) { maStyleName <<= rStyleName; }
+ void setGraphic( ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rXGraphic );
+
+ ::oox::drawingml::ColorPtr maBulletColorPtr;
+ ::com::sun::star::uno::Any mbBulletColorFollowText;
+ ::com::sun::star::uno::Any mbBulletFontFollowText;
+ ::oox::drawingml::TextFont maBulletFont;
+ ::com::sun::star::uno::Any msBulletChar;
+ ::com::sun::star::uno::Any mnStartAt;
+ ::com::sun::star::uno::Any mnNumberingType;
+ ::com::sun::star::uno::Any msNumberingPrefix;
+ ::com::sun::star::uno::Any msNumberingSuffix;
+ ::com::sun::star::uno::Any mnSize;
+ ::com::sun::star::uno::Any mnFontSize;
+ ::com::sun::star::uno::Any maStyleName;
+ ::com::sun::star::uno::Any maGraphic;
+ boost::optional< float > maFollowFontSize;
+};
+
+class TextParagraphProperties
+{
+public:
+
+ TextParagraphProperties();
+ ~TextParagraphProperties();
+
+ void setLevel( sal_Int16 nLevel ) { mnLevel = nLevel; }
+ sal_Int16 getLevel( ) const { return mnLevel; }
+ PropertyMap& getTextParagraphPropertyMap() { return maTextParagraphPropertyMap; }
+ BulletList& getBulletList() { return maBulletList; }
+ TextCharacterProperties& getTextCharacterProperties() { return maTextCharacterProperties; }
+ const TextCharacterProperties& getTextCharacterProperties() const { return maTextCharacterProperties; }
+
+ TextSpacing& getParaTopMargin() { return maParaTopMargin; }
+ TextSpacing& getParaBottomMargin() { return maParaBottomMargin; }
+ boost::optional< sal_Int32 >& getParaLeftMargin(){ return moParaLeftMargin; }
+ boost::optional< sal_Int32 >& getFirstLineIndentation(){ return moFirstLineIndentation; }
+
+ void apply( const TextParagraphProperties& rSourceProps );
+ void pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > & xPropSet,
+ PropertyMap& rioBulletList, const BulletList* pMasterBuList, sal_Bool bApplyBulletList, float fFontSize ) const;
+
+ /** Returns the largest character size of this paragraph. If possible the
+ masterstyle should have been applied before, otherwise the character
+ size can be zero and the default value is returned. */
+ float getCharHeightPoints( float fDefault ) const;
+
+protected:
+
+ TextCharacterProperties maTextCharacterProperties;
+ PropertyMap maTextParagraphPropertyMap;
+ BulletList maBulletList;
+ TextSpacing maParaTopMargin;
+ TextSpacing maParaBottomMargin;
+ boost::optional< sal_Int32 > moParaLeftMargin;
+ boost::optional< sal_Int32 > moFirstLineIndentation;
+ sal_Int16 mnLevel;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIES_HXX
diff --git a/oox/inc/oox/drawingml/textparagraphpropertiescontext.hxx b/oox/inc/oox/drawingml/textparagraphpropertiescontext.hxx
new file mode 100644
index 000000000000..de369c622e69
--- /dev/null
+++ b/oox/inc/oox/drawingml/textparagraphpropertiescontext.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX
+
+#include <list>
+
+#include <com/sun/star/style/TabStop.hpp>
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/textparagraphproperties.hxx"
+#include "oox/drawingml/textspacing.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class TextParagraphPropertiesContext : public ::oox::core::ContextHandler
+{
+public:
+ TextParagraphPropertiesContext( ::oox::core::ContextHandler& rParent,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& rXAttributes,
+ TextParagraphProperties& rTextParagraphProperties );
+ ~TextParagraphPropertiesContext();
+
+ 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:
+ TextParagraphProperties& mrTextParagraphProperties;
+ TextSpacing maLineSpacing;
+ TextSpacing& mrSpaceBefore;
+ TextSpacing& mrSpaceAfter;
+ BulletList& mrBulletList;
+ ::std::list< ::com::sun::star::style::TabStop > maTabList;
+ ::boost::shared_ptr< BlipFillProperties > mxBlipProps;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX
diff --git a/oox/inc/oox/drawingml/textrun.hxx b/oox/inc/oox/drawingml/textrun.hxx
new file mode 100644
index 000000000000..2704b8e92621
--- /dev/null
+++ b/oox/inc/oox/drawingml/textrun.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTRUN_HXX
+#define OOX_DRAWINGML_TEXTRUN_HXX
+
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include "oox/drawingml/textcharacterproperties.hxx"
+
+namespace oox { namespace drawingml {
+
+class TextRun
+{
+public:
+ TextRun();
+ virtual ~TextRun();
+
+ inline ::rtl::OUString& getText() { return msText; }
+ inline const ::rtl::OUString& getText() const { return msText; }
+
+ inline TextCharacterProperties& getTextCharacterProperties() { return maTextCharacterProperties; }
+ inline const TextCharacterProperties& getTextCharacterProperties() const { return maTextCharacterProperties; }
+
+ inline void setLineBreak() { mbIsLineBreak = true; }
+
+ virtual void insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XText >& xText,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::text::XTextCursor >& xAt,
+ const TextCharacterProperties& rTextCharacterStyle ) const;
+
+private:
+ ::rtl::OUString msText;
+ TextCharacterProperties maTextCharacterProperties;
+ bool mbIsLineBreak;
+};
+
+typedef boost::shared_ptr< TextRun > TextRunPtr;
+
+} }
+
+#endif // OOX_DRAWINGML_TEXTRUN_HXX
diff --git a/oox/inc/oox/drawingml/textspacing.hxx b/oox/inc/oox/drawingml/textspacing.hxx
new file mode 100644
index 000000000000..80c172c125ee
--- /dev/null
+++ b/oox/inc/oox/drawingml/textspacing.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGNML__TEXTSPACING_HXX
+#define OOX_DRAWINGNML__TEXTSPACING_HXX
+
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/LineSpacingMode.hpp>
+
+namespace oox { namespace drawingml {
+
+
+ /** carries a CT_TextSpacing */
+ class TextSpacing
+ {
+ public:
+ enum {
+ POINTS = 0,
+ PERCENT
+ };
+ TextSpacing()
+ : nUnit( POINTS ), nValue( 0 ), bHasValue( sal_False )
+ {
+ }
+ TextSpacing( sal_Int32 nPoints ) : nUnit( POINTS ), nValue( nPoints ), bHasValue( sal_True ){};
+ ::com::sun::star::style::LineSpacing toLineSpacing() const
+ {
+ ::com::sun::star::style::LineSpacing aSpacing;
+ aSpacing.Mode = ( nUnit == PERCENT
+ ? ::com::sun::star::style::LineSpacingMode::PROP
+ : ::com::sun::star::style::LineSpacingMode::MINIMUM );
+ aSpacing.Height = static_cast< sal_Int16 >( nUnit == PERCENT ? nValue / 1000 : nValue );
+ return aSpacing;
+ }
+ sal_Int32 toMargin( float fFontSize ) const
+ {
+ if ( nUnit == PERCENT )
+ {
+ double fMargin = ( fFontSize * 2540 + 36 ) / 72;
+ fMargin *= nValue;
+ fMargin /= 100000;
+ return static_cast< sal_Int32 >( fMargin );
+ }
+ else
+ return nValue;
+ }
+ sal_Int32 nUnit;
+ sal_Int32 nValue;
+ sal_Bool bHasValue;
+ };
+
+} }
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/theme.hxx b/oox/inc/oox/drawingml/theme.hxx
new file mode 100644
index 000000000000..7f982a1eec71
--- /dev/null
+++ b/oox/inc/oox/drawingml/theme.hxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_THEME_HXX
+#define OOX_DRAWINGML_THEME_HXX
+
+#include "oox/drawingml/clrscheme.hxx"
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/textfont.hxx"
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+const sal_Int32 THEMED_STYLE_SUBTLE = 1;
+const sal_Int32 THEMED_STYLE_MODERATE = 2;
+const sal_Int32 THEMED_STYLE_INTENSE = 3;
+
+typedef RefVector< FillProperties > FillStyleList;
+typedef RefVector< LineProperties > LineStyleList;
+typedef RefVector< PropertyMap > EffectStyleList;
+typedef RefMap< sal_Int32, TextCharacterProperties > FontScheme;
+
+// ============================================================================
+
+class Theme
+{
+public:
+ explicit Theme();
+ ~Theme();
+
+ inline void setStyleName( const ::rtl::OUString& rStyleName ) { maStyleName = rStyleName; }
+ inline const ::rtl::OUString& getStyleName() const { return maStyleName; }
+
+ inline ClrScheme& getClrScheme() { return maClrScheme; }
+ inline const ClrScheme& getClrScheme() const { return maClrScheme; }
+
+ inline FillStyleList& getFillStyleList() { return maFillStyleList; }
+ inline const FillStyleList& getFillStyleList() const { return maFillStyleList; }
+ inline FillStyleList& getBgFillStyleList() { return maBgFillStyleList; }
+ inline const FillStyleList& getBgFillStyleList() const { return maBgFillStyleList; }
+ /** Returns the fill properties of the passed one-based themed style index. */
+ const FillProperties* getFillStyle( sal_Int32 nIndex ) const;
+
+ inline LineStyleList& getLineStyleList() { return maLineStyleList; }
+ inline const LineStyleList& getLineStyleList() const { return maLineStyleList; }
+ /** Returns the line properties of the passed one-based themed style index. */
+ const LineProperties* getLineStyle( sal_Int32 nIndex ) const;
+
+ inline EffectStyleList& getEffectStyleList() { return maEffectStyleList; }
+ inline const EffectStyleList& getEffectStyleList() const { return maEffectStyleList; }
+ /** Returns the effect properties of the passed one-based themed style index. */
+ const PropertyMap* getEffectStyle( sal_Int32 nIndex ) const;
+
+ inline FontScheme& getFontScheme() { return maFontScheme; }
+ inline const FontScheme& getFontScheme() const { return maFontScheme; }
+ /** Returns theme font properties by scheme type (major/minor). */
+ const TextCharacterProperties* getFontStyle( sal_Int32 nSchemeType ) const;
+ /** Returns theme font by placeholder name, e.g. the major latin theme font for the font name '+mj-lt'. */
+ const TextFont* resolveFont( const ::rtl::OUString& rName ) const;
+
+ inline Shape& getSpDef() { return maSpDef; }
+ inline const Shape& getSpDef() const { return maSpDef; }
+
+ inline Shape& getLnDef() { return maLnDef; }
+ inline const Shape& getLnDef() const { return maLnDef; }
+
+ inline Shape& getTxDef() { return maTxDef; }
+ inline const Shape& getTxDef() const { return maTxDef; }
+
+private:
+ ::rtl::OUString maStyleName;
+ ClrScheme maClrScheme;
+ FillStyleList maFillStyleList;
+ FillStyleList maBgFillStyleList;
+ LineStyleList maLineStyleList;
+ EffectStyleList maEffectStyleList;
+ FontScheme maFontScheme;
+ Shape maSpDef;
+ Shape maLnDef;
+ Shape maTxDef;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/themeelementscontext.hxx b/oox/inc/oox/drawingml/themeelementscontext.hxx
new file mode 100644
index 000000000000..1dfc76b6957d
--- /dev/null
+++ b/oox/inc/oox/drawingml/themeelementscontext.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_THEMEELEMENTSCONTEXT_HXX
+#define OOX_DRAWINGML_THEMEELEMENTSCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox {
+namespace drawingml {
+
+class Theme;
+
+// ============================================================================
+
+class ThemeElementsContext : public oox::core::ContextHandler
+{
+public:
+ ThemeElementsContext( ::oox::core::ContextHandler& rParent, Theme& rTheme );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement,
+ 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:
+ Theme& mrTheme;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/themefragmenthandler.hxx b/oox/inc/oox/drawingml/themefragmenthandler.hxx
new file mode 100644
index 000000000000..aeaaa5378bd8
--- /dev/null
+++ b/oox/inc/oox/drawingml/themefragmenthandler.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_THEMEFRAGMENTHANDLER_HXX
+#define OOX_DRAWINGML_THEMEFRAGMENTHANDLER_HXX
+
+#include "oox/core/fragmenthandler2.hxx"
+
+namespace oox {
+namespace drawingml {
+
+class Theme;
+
+// ============================================================================
+
+class ThemeFragmentHandler : public ::oox::core::FragmentHandler2
+{
+public:
+ explicit ThemeFragmentHandler(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ Theme& rTheme );
+ virtual ~ThemeFragmentHandler();
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ Theme& mrTheme;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/drawingml/transform2dcontext.hxx b/oox/inc/oox/drawingml/transform2dcontext.hxx
new file mode 100644
index 000000000000..022f1dbe47c2
--- /dev/null
+++ b/oox/inc/oox/drawingml/transform2dcontext.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TRANSFORM2DCONTEXT_HXX
+#define OOX_DRAWINGML_TRANSFORM2DCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+class Shape;
+
+/** context to import a CT_Transform2D */
+class Transform2DContext : public ::oox::core::ContextHandler
+{
+public:
+ Transform2DContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, Shape& rShape ) throw();
+ 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:
+ Shape& mrShape;
+};
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/dump/biffdumper.hxx b/oox/inc/oox/dump/biffdumper.hxx
new file mode 100644
index 000000000000..a3bdc4a87c73
--- /dev/null
+++ b/oox/inc/oox/dump/biffdumper.hxx
@@ -0,0 +1,574 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DUMP_BIFFDUMPER_HXX
+#define OOX_DUMP_BIFFDUMPER_HXX
+
+#include "oox/dump/dumperbase.hxx"
+#include "oox/dump/dffdumper.hxx"
+#include "oox/dump/oledumper.hxx"
+#include "oox/xls/richstring.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox { namespace xls {
+ class BiffInputStream;
+ class FontPortionModelList;
+ struct FunctionInfo;
+ class FunctionProvider;
+} }
+
+namespace oox {
+namespace dump {
+namespace biff {
+
+typedef ::boost::shared_ptr< ::oox::xls::BiffInputStream > BiffInputStreamRef;
+
+// ============================================================================
+// ============================================================================
+
+class BiffDffStreamObject : public DffStreamObject
+{
+public:
+ explicit BiffDffStreamObject(
+ const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm );
+
+protected:
+ virtual void implDumpClientAnchor();
+};
+
+// ============================================================================
+
+class BiffCtlsStreamObject : public InputObjectBase
+{
+public:
+ explicit BiffCtlsStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm );
+
+ void dumpControl( sal_uInt32 nStartPos, sal_uInt32 nLength );
+
+protected:
+ virtual void implDump();
+
+private:
+ sal_uInt32 mnStartPos;
+ sal_uInt32 mnLength;
+};
+
+// ============================================================================
+// ============================================================================
+
+class BiffConfig : public Config
+{
+public:
+ explicit BiffConfig( const Config& rParent, ::oox::xls::BiffType eBiff );
+
+protected:
+ virtual bool implIsValid() const;
+ virtual NameListRef implGetNameList( const ::rtl::OUString& rKey ) const;
+
+private:
+ ::oox::xls::BiffType meBiff;
+};
+
+// ============================================================================
+
+class BiffSharedData : public Base
+{
+public:
+ explicit BiffSharedData( ::oox::xls::BiffType eBiff );
+
+ void initializePerSheet();
+
+ inline ::oox::xls::BiffType getBiff() const { return meBiff; }
+
+ inline rtl_TextEncoding getTextEncoding() const { return meTextEnc; }
+ void setTextEncoding( rtl_TextEncoding eTextEnc );
+
+ sal_uInt16 getFontCount() const;
+ rtl_TextEncoding getFontEncoding( sal_uInt16 nFontId ) const;
+ void appendFontEncoding( rtl_TextEncoding eFontEnc );
+
+ sal_uInt16 getXfCount() const;
+ rtl_TextEncoding getXfEncoding( sal_uInt16 nXfId ) const;
+ void appendXfFontId( sal_uInt16 nFontId );
+
+protected:
+ virtual bool implIsValid() const;
+
+private:
+ typedef ::std::vector< rtl_TextEncoding > TextEncVec;
+ typedef ::std::vector< sal_uInt16 > FontIdVec;
+
+ TextEncVec maFontEncs;
+ FontIdVec maXfFontIds;
+ ::oox::xls::BiffType meBiff;
+ rtl_TextEncoding meTextEnc;
+};
+
+// ============================================================================
+
+class BiffObjectBase : public RecordObjectBase
+{
+public:
+ inline BiffSharedData& getBiffData() const { return *mxBiffData; }
+ inline ::oox::xls::BiffInputStream& getBiffStream() const { return *mxBiffStrm; }
+ inline ::oox::xls::BiffType getBiff() const { return mxBiffData->getBiff(); }
+
+protected:
+ inline explicit BiffObjectBase() {}
+ virtual ~BiffObjectBase();
+
+ using InputObjectBase::construct;
+ void construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, ::oox::xls::BiffType eBiff, const ::rtl::OUString& rSysFileName );
+ void construct( const BiffObjectBase& rParent );
+
+ virtual bool implIsValid() const;
+ virtual bool implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize );
+
+ inline sal_uInt16 getLastRecId() const { return mnLastRecId; }
+ ::rtl::OUString getErrorName( sal_uInt8 nErrCode ) const;
+
+ // ------------------------------------------------------------------------
+
+ sal_Int32 readCol( bool bCol16Bit );
+ sal_Int32 readRow( bool bRow32Bit );
+ void readAddress( Address& orAddress, bool bCol16Bit = true, bool bRow32Bit = false );
+ void readRange( Range& orRange, bool bCol16Bit = true, bool bRow32Bit = false );
+ void readRangeList( RangeList& orRanges, bool bCol16Bit = true, bool bRow32Bit = false );
+
+ // ------------------------------------------------------------------------
+
+ void writeBooleanItem( const String& rName, sal_uInt8 nBool );
+ void writeErrorCodeItem( const String& rName, sal_uInt8 nErrCode );
+
+ void writeFontPortions( const ::oox::xls::FontPortionModelList& rPortions );
+
+ template< typename Type >
+ void writeRectItem( const String& rName,
+ Type nLeft, Type nTop, Type nWidth, Type nHeight,
+ const NameListWrapper& rListWrp = NO_LIST,
+ FormatType eFmtType = FORMATTYPE_DEC );
+
+ // ------------------------------------------------------------------------
+
+ ::rtl::OUString dumpByteString(
+ const String& rName,
+ ::oox::xls::BiffStringFlags nFlags = ::oox::xls::BIFF_STR_DEFAULT,
+ rtl_TextEncoding eDefaultTextEnc = RTL_TEXTENCODING_DONTKNOW );
+ ::rtl::OUString dumpUniString(
+ const String& rName,
+ ::oox::xls::BiffStringFlags nFlags = ::oox::xls::BIFF_STR_DEFAULT );
+ ::rtl::OUString dumpString(
+ const String& rName,
+ ::oox::xls::BiffStringFlags nByteFlags = ::oox::xls::BIFF_STR_DEFAULT,
+ ::oox::xls::BiffStringFlags nUniFlags = ::oox::xls::BIFF_STR_DEFAULT,
+ rtl_TextEncoding eDefaultTextEnc = RTL_TEXTENCODING_DONTKNOW );
+
+ ::rtl::OUString dumpSegmentedUniString( const String& rName );
+ void dumpSegmentedUniStringArray( const String& rName );
+
+ sal_uInt8 dumpBoolean( const String& rName = EMPTY_STRING );
+ sal_uInt8 dumpErrorCode( const String& rName = EMPTY_STRING );
+
+ rtl_TextEncoding dumpCodePage( const String& rName = EMPTY_STRING );
+ void dumpFormulaResult( const String& rName = EMPTY_STRING );
+
+ sal_Int32 dumpColIndex( const String& rName = EMPTY_STRING, bool bCol16Bit = true );
+ sal_Int32 dumpRowIndex( const String& rName = EMPTY_STRING, bool bRow32Bit = false );
+ sal_Int32 dumpColRange( const String& rName = EMPTY_STRING, bool bCol16Bit = true );
+ sal_Int32 dumpRowRange( const String& rName = EMPTY_STRING, bool bRow32Bit = false );
+
+ Address dumpAddress( const String& rName = EMPTY_STRING, bool bCol16Bit = true, bool bRow32Bit = false );
+ Range dumpRange( const String& rName = EMPTY_STRING, bool bCol16Bit = true, bool bRow32Bit = false );
+ void dumpRangeList( const String& rName = EMPTY_STRING, bool bCol16Bit = true, bool bRow32Bit = false );
+
+ void dumpConstArrayHeader( sal_uInt32& rnCols, sal_uInt32& rnRows );
+ ::rtl::OUString dumpConstValue( sal_Unicode cStrQuote = OOX_DUMP_STRQUOTE );
+
+ template< typename Type >
+ void dumpRect( const String& rName,
+ const NameListWrapper& rListWrp = NO_LIST,
+ FormatType eFmtType = FORMATTYPE_DEC );
+ template< typename Type >
+ void dumpRectWithGaps( const String& rName, sal_Int32 nGap,
+ const NameListWrapper& rListWrp = NO_LIST,
+ FormatType eFmtType = FORMATTYPE_DEC );
+
+ sal_uInt16 dumpRepeatedRecId();
+ void dumpFrHeader( bool bWithFlags, bool bWithRange );
+
+ void dumpDffClientRect();
+ void dumpEmbeddedDff();
+ void dumpControl();
+
+private:
+ typedef ::boost::shared_ptr< BiffSharedData > BiffSharedDataRef;
+ typedef ::boost::shared_ptr< BiffDffStreamObject > BiffDffStreamObjRef;
+ typedef ::boost::shared_ptr< BiffCtlsStreamObject > BiffCtlsStrmObjRef;
+
+ BiffSharedDataRef mxBiffData;
+ BiffInputStreamRef mxBiffStrm;
+ BiffDffStreamObjRef mxDffObj;
+ BiffCtlsStrmObjRef mxCtlsObj;
+ NameListRef mxErrCodes;
+ NameListRef mxConstType;
+ NameListRef mxResultType;
+ sal_uInt16 mnLastRecId;
+ bool mbMergeContRec;
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void BiffObjectBase::writeRectItem( const String& rName,
+ Type nLeft, Type nTop, Type nWidth, Type nHeight,
+ const NameListWrapper& rListWrp, FormatType eFmtType )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( rName );
+ writeValueItem( "x-pos", nLeft, eFmtType, rListWrp );
+ writeValueItem( "y-pos", nTop, eFmtType, rListWrp );
+ writeValueItem( "x-size", nWidth, eFmtType, rListWrp );
+ writeValueItem( "y-size", nHeight, eFmtType, rListWrp );
+}
+
+template< typename Type >
+void BiffObjectBase::dumpRect( const String& rName,
+ const NameListWrapper& rListWrp, FormatType eFmtType )
+{
+ Type nLeft, nTop, nWidth, nHeight;
+ *mxBiffStrm >> nLeft >> nTop >> nWidth >> nHeight;
+ writeRectItem( rName, nLeft, nTop, nWidth, nHeight, rListWrp, eFmtType );
+}
+
+template< typename Type >
+void BiffObjectBase::dumpRectWithGaps( const String& rName, sal_Int32 nGap,
+ const NameListWrapper& rListWrp, FormatType eFmtType )
+{
+ Type nLeft, nTop, nWidth, nHeight;
+ *mxBiffStrm >> nLeft;
+ mxBiffStrm->skip( nGap );
+ *mxBiffStrm >> nTop;
+ mxBiffStrm->skip( nGap );
+ *mxBiffStrm >> nWidth;
+ mxBiffStrm->skip( nGap );
+ *mxBiffStrm >> nHeight;
+ mxBiffStrm->skip( nGap );
+ writeRectItem( rName, nLeft, nTop, nWidth, nHeight, rListWrp, eFmtType );
+}
+
+// ============================================================================
+// ============================================================================
+
+class FormulaObject : public BiffObjectBase
+{
+public:
+ explicit FormulaObject( const BiffObjectBase& rParent );
+ virtual ~FormulaObject();
+
+ sal_uInt16 readFormulaSize();
+ sal_uInt16 dumpFormulaSize( const String& rName = EMPTY_STRING );
+
+ void dumpCellFormula( const String& rName, sal_uInt16 nSize );
+ void dumpCellFormula( const String& rName = EMPTY_STRING );
+ void dumpNameFormula( const String& rName, sal_uInt16 nSize );
+ void dumpNameFormula( const String& rName = EMPTY_STRING );
+
+protected:
+ virtual void implDump();
+
+private:
+ void constructFmlaObj();
+
+ void dumpFormula( const String& rName, sal_uInt16 nSize, bool bNameMode );
+ void dumpFormula( const String& rName, bool bNameMode );
+
+ TokenAddress createTokenAddress( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelC, bool bRelR, bool bNameMode ) const;
+ ::rtl::OUString createRef( const ::rtl::OUString& rData ) const;
+ ::rtl::OUString createName( sal_uInt16 nNameIdx ) const;
+ ::rtl::OUString createPlaceHolder( size_t nIdx ) const;
+ ::rtl::OUString createPlaceHolder() const;
+
+ sal_uInt16 readFuncId();
+ ::rtl::OUString writeFuncIdItem( sal_uInt16 nFuncId, const ::oox::xls::FunctionInfo** oppFuncInfo = 0 );
+
+ sal_uInt16 dumpTokenCol( const String& rName, bool& rbRelC, bool& rbRelR );
+ sal_uInt16 dumpTokenRow( const String& rName, bool& rbRelC, bool& rbRelR );
+ TokenAddress dumpTokenAddress( bool bNameMode );
+ TokenRange dumpTokenRange( bool bNameMode );
+
+ sal_Int16 readTokenRefIdx();
+ ::rtl::OUString dumpTokenRefIdx();
+ ::rtl::OUString dumpTokenRefTabIdxs();
+
+ void dumpIntToken();
+ void dumpDoubleToken();
+ void dumpStringToken();
+ void dumpBoolToken();
+ void dumpErrorToken();
+ void dumpMissArgToken();
+
+ void dumpArrayToken( const ::rtl::OUString& rTokClass );
+ void dumpNameToken( const ::rtl::OUString& rTokClass );
+ void dumpNameXToken( const ::rtl::OUString& rTokClass );
+ void dumpRefToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpAreaToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpRefErrToken( const ::rtl::OUString& rTokClass, bool bArea );
+ void dumpRef3dToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpArea3dToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpRefErr3dToken( const ::rtl::OUString& rTokClass, bool bArea );
+ void dumpMemFuncToken( const ::rtl::OUString& rTokClass );
+ void dumpMemAreaToken( const ::rtl::OUString& rTokClass, bool bAddData );
+
+ void dumpExpToken( const String& rName );
+ void dumpUnaryOpToken( const String& rLOp, const String& rROp );
+ void dumpBinaryOpToken( const String& rOp );
+ void dumpFuncToken( const ::rtl::OUString& rTokClass );
+ void dumpFuncVarToken( const ::rtl::OUString& rTokClass );
+ void dumpCmdToken( const ::rtl::OUString& rTokClass );
+
+ void dumpSheetToken();
+ void dumpEndSheetToken();
+ bool dumpAttrToken();
+
+ bool dumpNlrToken();
+ void dumpNlrErrToken();
+ void dumpNlrColRowToken( const ::rtl::OUString& rTokClass, bool bAddData );
+ void dumpNlrRangeToken( const ::rtl::OUString& rTokClass, bool bAddData );
+ void dumpNlrRangeErrToken();
+
+ void dumpAddTokenData();
+ void dumpAddDataNlr( size_t nIdx );
+ void dumpAddDataArray( size_t nIdx );
+ void dumpAddDataMemArea( size_t nIdx );
+
+private:
+ enum AddDataType { ADDDATA_NLR, ADDDATA_ARRAY, ADDDATA_MEMAREA };
+
+ typedef ::boost::shared_ptr< FormulaStack > FormulaStackRef;
+ typedef ::boost::shared_ptr< ::oox::xls::FunctionProvider > FuncProvRef;
+ typedef ::std::vector< AddDataType > AddDataTypeVec;
+
+ NameListRef mxTokens;
+ NameListRef mxClasses;
+ NameListRef mxRelFlags;
+ NameListRef mxNlrTypes;
+ NameListRef mxAttrTypes;
+ NameListRef mxSpTypes;
+ sal_Int32 mnColCount;
+ sal_Int32 mnRowCount;
+
+ FormulaStackRef mxStack;
+ FuncProvRef mxFuncProv;
+ AddDataTypeVec maAddData;
+ ::rtl::OUString maRefPrefix;
+ ::rtl::OUString maName;
+ sal_uInt16 mnSize;
+ bool mbNameMode;
+};
+
+// ============================================================================
+// ============================================================================
+
+class RecordStreamObject : public BiffObjectBase
+{
+protected:
+ inline explicit RecordStreamObject() {}
+ virtual ~RecordStreamObject();
+
+ using BiffObjectBase::construct;
+ void construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, ::oox::xls::BiffType eBiff, const ::rtl::OUString& rSysFileName );
+
+ virtual bool implIsValid() const;
+
+ inline FormulaObject& getFormulaDumper() const { return *mxFmlaObj; }
+
+private:
+ typedef ::boost::shared_ptr< FormulaObject > FormulaObjectRef;
+ FormulaObjectRef mxFmlaObj;
+};
+
+// ============================================================================
+
+class WorkbookStreamObject : public RecordStreamObject
+{
+public:
+ explicit WorkbookStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+ virtual ~WorkbookStreamObject();
+
+protected:
+ virtual void implDumpRecordBody();
+
+private:
+ void initializePerSheet();
+
+ ::rtl::OUString createFontName( const ::rtl::OUString& rName, sal_uInt16 nHeight, bool bBold, bool bItalic ) const;
+
+ sal_uInt16 dumpPatternIdx( const String& rName = EMPTY_STRING, bool b16Bit = true );
+ sal_uInt16 dumpColorIdx( const String& rName = EMPTY_STRING, bool b16Bit = true );
+ sal_uInt16 dumpFontIdx( const String& rName = EMPTY_STRING, bool b16Bit = true );
+ sal_uInt16 dumpFormatIdx( const String& rName = EMPTY_STRING );
+ sal_uInt16 dumpXfIdx( const String& rName = EMPTY_STRING, bool bBiff2Style = false );
+
+ template< typename Type >
+ inline Type dumpExtColorType() { return dumpDec< Type >( "color-type", "EXTCOLOR-TYPE" ); }
+ void dumpExtColorValue( sal_uInt32 nColorType );
+ void dumpExtColor( const String& rName = EMPTY_STRING );
+ void dumpExtCfColor( const String& rName = EMPTY_STRING );
+ void dumpExtGradientHead();
+
+ sal_uInt8 dumpFilterColumnOperator( const String& rName );
+
+ ::rtl::OUString dumpPivotString( const String& rName, sal_uInt16 nStrLen );
+ ::rtl::OUString dumpPivotString( const String& rName );
+
+ sal_uInt16 dumpCellHeader( bool bBiff2Style = false );
+ void dumpBoolErr();
+
+ void dumpCfRuleProp();
+ void dumpXfExtProp();
+ void dumpDxfProp();
+ void dumpDxf12Prop();
+ void dumpCfRule12Param( sal_uInt16 nSubType );
+
+ void dumpFontRec();
+ void dumpFormatRec();
+ void dumpXfRec();
+
+ void dumpObjRec();
+ void dumpObjRecBiff3();
+ void dumpObjRecBiff4();
+ void dumpObjRecBiff5();
+ void dumpObjRecBiff8();
+
+ void dumpObjRecLineData();
+ void dumpObjRecFillData();
+ void dumpObjRecRectData();
+ void dumpObjRecTextDataBiff3( sal_uInt16& ornTextLen, sal_uInt16& ornFormatSize );
+ void dumpObjRecTextDataBiff5( sal_uInt16& ornTextLen, sal_uInt16& ornFormatSize, sal_uInt16& ornLinkSize );
+ void dumpObjRecSbsData();
+ void dumpObjRecGboData();
+ void dumpObjRecEdoData();
+ void dumpObjRecRboData();
+ void dumpObjRecCblsData();
+ void dumpObjRecLbsData();
+
+ void dumpObjRecPadding();
+ void dumpObjRecString( const String& rName, sal_uInt16 nTextLen, bool bRepeatLen );
+ void dumpObjRecTextFmt( sal_uInt16 nFormatSize );
+ void dumpObjRecFmlaRaw();
+ void dumpObjRecFmla( const String& rName, sal_uInt16 nFmlaSize );
+ void dumpObjRecPictFmla( sal_uInt16 nFmlaSize );
+
+ typedef ::std::pair< sal_uInt8, ::rtl::OUString > ChFrExtPropInfo;
+
+ void dumpChFrExtProps();
+ ChFrExtPropInfo dumpChFrExtPropHeader();
+
+private:
+ NameListRef mxColors;
+ NameListRef mxBorderStyles;
+ NameListRef mxFillPatterns;
+ NameListRef mxFontNames;
+ NameListRef mxFormats;
+ sal_uInt16 mnFormatIdx;
+ sal_uInt16 mnPTRowFields;
+ sal_uInt16 mnPTColFields;
+ sal_uInt16 mnPTRowColItemsIdx;
+ bool mbHasCodePage;
+ bool mbHasDff;
+};
+
+// ============================================================================
+
+class PivotCacheStreamObject : public RecordStreamObject
+{
+public:
+ explicit PivotCacheStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ ::oox::xls::BiffType eBiff,
+ const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual void implDumpRecordBody();
+};
+
+// ============================================================================
+// ============================================================================
+
+class RootStorageObject : public OleStorageObject
+{
+public:
+ explicit RootStorageObject( const DumperBase& rParent );
+
+protected:
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+
+ virtual void implDumpStorage(
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rSysPath );
+
+ virtual void implDumpBaseStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName );
+};
+
+// ============================================================================
+// ============================================================================
+
+class Dumper : public DumperBase
+{
+public:
+ explicit Dumper( const ::oox::core::FilterBase& rFilter );
+
+ explicit Dumper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
+ const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual void implDump();
+};
+
+// ============================================================================
+// ============================================================================
+
+} // namespace biff
+} // namespace dump
+} // namespace oox
+
+#endif
+#endif
+
diff --git a/oox/inc/oox/dump/dffdumper.hxx b/oox/inc/oox/dump/dffdumper.hxx
new file mode 100644
index 000000000000..f229c19eff8c
--- /dev/null
+++ b/oox/inc/oox/dump/dffdumper.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DUMP_DFFDUMPER_HXX
+#define OOX_DUMP_DFFDUMPER_HXX
+
+#include "oox/dump/dumperbase.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+
+class DffStreamObject : public SequenceRecordObjectBase
+{
+public:
+ inline sal_uInt16 getVer() const { return mnInstVer & 0x000F; }
+ inline sal_uInt16 getInst() const { return (mnInstVer & 0xFFF0) >> 4; }
+ inline bool isContainer() const { return getVer() == 15; }
+
+protected:
+ inline explicit DffStreamObject() {}
+
+ using SequenceRecordObjectBase::construct;
+ void construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+ void construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm );
+
+ virtual bool implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize );
+ virtual void implWriteExtHeader();
+ virtual void implDumpRecordBody();
+ virtual void implDumpClientAnchor();
+
+private:
+ void constructDffObj();
+
+ sal_uInt32 dumpDffSimpleColor( const String& rName );
+ sal_uInt32 dumpDffColor( const String& rName );
+
+ void dumpDffOpt();
+ sal_uInt16 dumpDffOptPropHeader();
+
+private:
+ ItemFormatMap maSimpleProps;
+ ItemFormatMap maComplexProps;
+ sal_uInt16 mnInstVer;
+ sal_Int32 mnRealSize;
+};
+
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
+#endif
+
diff --git a/oox/inc/oox/dump/dumperbase.hxx b/oox/inc/oox/dump/dumperbase.hxx
new file mode 100644
index 000000000000..d9acaa1f1011
--- /dev/null
+++ b/oox/inc/oox/dump/dumperbase.hxx
@@ -0,0 +1,1979 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DUMP_DUMPERBASE_HXX
+#define OOX_DUMP_DUMPERBASE_HXX
+
+#include <math.h>
+#include <vector>
+#include <stack>
+#include <set>
+#include <map>
+#include <boost/shared_ptr.hpp>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/helper.hxx"
+#include "oox/helper/storagebase.hxx"
+
+#define OOX_INCLUDE_DUMPER (OSL_DEBUG_LEVEL > 0)
+
+#if OOX_INCLUDE_DUMPER
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XInputStream; }
+ namespace io { class XTextInputStream; }
+ namespace io { class XOutputStream; }
+ namespace io { class XTextOutputStream; }
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace comphelper {
+ class IDocPasswordVerifier;
+}
+
+namespace oox {
+ class BinaryOutputStream;
+ class TextInputStream;
+}
+
+namespace oox { namespace core {
+ class FilterBase;
+} }
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+
+#define OOX_DUMP_UNUSED "unused"
+#define OOX_DUMP_UNKNOWN "?unknown"
+
+#define OOX_DUMP_ERRASCII( ascii ) "?err:" ascii
+#define OOX_DUMP_ERRSTRING( ascii ) CREATE_OUSTRING( OOX_DUMP_ERRASCII( ascii ) )
+
+#define OOX_DUMP_ERR_NOMAP OOX_DUMP_ERRSTRING( "no-map" )
+#define OOX_DUMP_ERR_NONAME OOX_DUMP_ERRSTRING( "no-name" )
+#define OOX_DUMP_ERR_STREAM OOX_DUMP_ERRSTRING( "stream-error" )
+
+#define OOX_DUMP_DUMPEXT CREATE_OUSTRING( ".dump" )
+
+const sal_Unicode OOX_DUMP_STRQUOTE = '\'';
+const sal_Unicode OOX_DUMP_FMLASTRQUOTE = '"';
+const sal_Unicode OOX_DUMP_ADDRABS = '$';
+const sal_Unicode OOX_DUMP_R1C1ROW = 'R';
+const sal_Unicode OOX_DUMP_R1C1COL = 'C';
+const sal_Unicode OOX_DUMP_R1C1OPEN = '[';
+const sal_Unicode OOX_DUMP_R1C1CLOSE = ']';
+const sal_Unicode OOX_DUMP_RANGESEP = ':';
+const sal_Unicode OOX_DUMP_BASECLASS = 'B';
+const sal_Unicode OOX_DUMP_FUNCSEP = ',';
+const sal_Unicode OOX_DUMP_LISTSEP = ',';
+const sal_Unicode OOX_DUMP_TABSEP = '!';
+const sal_Unicode OOX_DUMP_ARRAYSEP = ';';
+const sal_Unicode OOX_DUMP_EMPTYVALUE = '~';
+const sal_Unicode OOX_DUMP_CMDPROMPT = '?';
+const sal_Unicode OOX_DUMP_PLACEHOLDER = '\x01';
+
+typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > OUStringPair;
+typedef ::std::pair< sal_Int64, sal_Int64 > Int64Pair;
+
+typedef ::std::vector< ::rtl::OUString > OUStringVector;
+typedef ::std::vector< sal_Int64 > Int64Vector;
+
+// ============================================================================
+// ============================================================================
+
+/** Static helper functions for system file and stream access. */
+class InputOutputHelper
+{
+public:
+ // file names -------------------------------------------------------------
+
+ static ::rtl::OUString convertFileNameToUrl( const ::rtl::OUString& rFileName );
+ static sal_Int32 getFileNamePos( const ::rtl::OUString& rFileUrl );
+ static ::rtl::OUString getFileNameExtension( const ::rtl::OUString& rFileUrl );
+
+ // input streams ----------------------------------------------------------
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ getXInputStream( BinaryInputStream& rStrm );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ openInputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::rtl::OUString& rFileName );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextInputStream >
+ openTextInputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
+ const ::rtl::OUString& rEncoding );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextInputStream >
+ openTextInputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::rtl::OUString& rFileName,
+ const ::rtl::OUString& rEncoding );
+
+ // output streams ---------------------------------------------------------
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ openOutputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::rtl::OUString& rFileName );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >
+ openTextOutputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rxOutStrm,
+ const ::rtl::OUString& rEncoding );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >
+ openTextOutputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::rtl::OUString& rFileName,
+ const ::rtl::OUString& rEncoding );
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Specifiers for atomic data types. */
+enum DataType
+{
+ DATATYPE_VOID, /// No data type.
+ DATATYPE_INT8, /// Signed 8-bit integer.
+ DATATYPE_UINT8, /// Unsigned 8-bit integer.
+ DATATYPE_INT16, /// Signed 16-bit integer.
+ DATATYPE_UINT16, /// Unsigned 16-bit integer.
+ DATATYPE_INT32, /// Signed 32-bit integer.
+ DATATYPE_UINT32, /// Unsigned 32-bit integer.
+ DATATYPE_INT64, /// Signed 64-bit integer.
+ DATATYPE_UINT64, /// Unsigned 64-bit integer.
+ DATATYPE_FLOAT, /// Floating-point, single precision.
+ DATATYPE_DOUBLE /// Floating-point, double precision.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Specifiers for the output format of values. */
+enum FormatType
+{
+ FORMATTYPE_NONE, /// No numeric format (e.g. show name only).
+ FORMATTYPE_DEC, /// Decimal.
+ FORMATTYPE_HEX, /// Hexadecimal.
+ FORMATTYPE_SHORTHEX, /// Hexadecimal, as short as possible (no leading zeros).
+ FORMATTYPE_BIN, /// Binary.
+ FORMATTYPE_FIX, /// Fixed-point.
+ FORMATTYPE_BOOL /// Boolean ('true' or 'false').
+};
+
+// ----------------------------------------------------------------------------
+
+/** Describes the output format of a data item.
+
+ Data items are written in the following format:
+
+ <NAME>=<VALUE>=<NAME-FROM-LIST>
+
+ NAME is the name of the data item. The name is contained in the member
+ maItemName. If the name is empty, only the value is written (without a
+ leading equality sign).
+
+ VALUE is the numeric value of the data item. Its format is dependent on the
+ output format given in the member meFmtType. If the format type is
+ FORMATTYPE_NONE, no value is written.
+
+ NAME-FROM-LIST is a symbolic name for the current value of the data item.
+ Various types of name lists produce different names for values, which can
+ be used for enumerations or names for single bits in bitfields (see class
+ NameListBase and derived classes). The name of the list is given in the
+ member maListName. If it is empty, no name is written for the value.
+ */
+struct ItemFormat
+{
+ DataType meDataType; /// Data type of the item.
+ FormatType meFmtType; /// Output format for the value.
+ ::rtl::OUString maItemName; /// Name of the item.
+ ::rtl::OUString maListName; /// Name of a name list to be used for this item.
+
+ explicit ItemFormat();
+
+ void set( DataType eDataType, FormatType eFmtType, const ::rtl::OUString& rItemName );
+ void set( DataType eDataType, FormatType eFmtType, const ::rtl::OUString& rItemName, const ::rtl::OUString& rListName );
+
+ /** Initializes the struct from a vector of strings containing the item format.
+
+ The vector must contain at least 2 strings. The struct is filled from
+ the strings in the vector in the following order:
+ 1) Data type (one of: [u]int8, [u]int16, [u]int32, [u]int64, float, double).
+ 2) Format type (one of: dec, hex, shorthex, bin, fix, bool, unused, unknown).
+ 3) Item name (optional).
+ 4) Name list name (optional).
+
+ @return Iterator pointing to the first unhandled string.
+ */
+ OUStringVector::const_iterator parse( const OUStringVector& rFormatVec );
+
+ /** Initializes the struct from a string containing the item format.
+
+ The string must have the following format:
+ DATATYPE,FORMATTYPE[,ITEMNAME[,LISTNAME]]
+
+ DATATYPE is the data type of the item (see above for possible values).
+ FORMATTYPE is the format type of the item (see above for possible values).
+ ITEMNAME is the name of the item (optional).
+ LISTNAME is the name of a name list (optional).
+
+ @return List containing remaining unhandled format strings.
+ */
+ OUStringVector parse( const ::rtl::OUString& rFormatStr );
+};
+
+// ============================================================================
+// ============================================================================
+
+struct Address
+{
+ sal_Int32 mnCol;
+ sal_Int32 mnRow;
+ inline explicit Address() : mnCol( 0 ), mnRow( 0 ) {}
+ inline explicit Address( sal_Int32 nCol, sal_Int32 nRow ) : mnCol( nCol ), mnRow( nRow ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+struct Range
+{
+ Address maFirst;
+ Address maLast;
+ inline explicit Range() {}
+};
+
+// ----------------------------------------------------------------------------
+
+typedef ::std::vector< Range > RangeList;
+
+// ============================================================================
+
+struct TokenAddress : public Address
+{
+ bool mbRelCol;
+ bool mbRelRow;
+ inline explicit TokenAddress() : mbRelCol( false ), mbRelRow( false ) {}
+};
+
+// ----------------------------------------------------------------------------
+
+struct TokenRange
+{
+ TokenAddress maFirst;
+ TokenAddress maLast;
+ inline explicit TokenRange() {}
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Static helper functions for formatted output to strings. */
+class StringHelper
+{
+public:
+ // append string to string ------------------------------------------------
+
+ static void appendChar( ::rtl::OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount = 1 );
+ static void appendString( ::rtl::OUStringBuffer& rStr, const ::rtl::OUString& rData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+
+ // append decimal ---------------------------------------------------------
+
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_uInt8 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_Int8 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_uInt16 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_Int16 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_uInt32 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_Int32 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_uInt64 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, sal_Int64 nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+ static void appendDec( ::rtl::OUStringBuffer& rStr, double fData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' );
+
+ // append hexadecimal -----------------------------------------------------
+
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix = true );
+ static void appendHex( ::rtl::OUStringBuffer& rStr, double fData, bool bPrefix = true );
+
+ // append shortened hexadecimal -------------------------------------------
+
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix = true );
+ static void appendShortHex( ::rtl::OUStringBuffer& rStr, double fData, bool bPrefix = true );
+
+ // append binary ----------------------------------------------------------
+
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_uInt8 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_Int8 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_uInt16 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_Int16 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_uInt32 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_Int32 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_uInt64 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, sal_Int64 nData, bool bDots = true );
+ static void appendBin( ::rtl::OUStringBuffer& rStr, double fData, bool bDots = true );
+
+ // append fixed-point decimal ---------------------------------------------
+
+ template< typename Type >
+ static void appendFix( ::rtl::OUStringBuffer& rStr, Type nData, sal_Int32 nWidth = 0 );
+
+ // append formatted value -------------------------------------------------
+
+ static void appendBool( ::rtl::OUStringBuffer& rStr, bool bData );
+ template< typename Type >
+ static void appendValue( ::rtl::OUStringBuffer& rStr, Type nData, FormatType eFmtType );
+
+ // append columns, rows, addresses ----------------------------------------
+
+ static void appendAddrCol( ::rtl::OUStringBuffer& rStr, sal_Int32 nCol, bool bRel );
+ static void appendAddrRow( ::rtl::OUStringBuffer& rStr, sal_Int32 nRow, bool bRel );
+ static void appendAddrName( ::rtl::OUStringBuffer& rStr, sal_Unicode cPrefix, sal_Int32 nColRow, bool bRel );
+
+ static void appendAddress( ::rtl::OUStringBuffer& rStr, const Address& rPos );
+ static void appendRange( ::rtl::OUStringBuffer& rStr, const Range& rRange );
+ static void appendRangeList( ::rtl::OUStringBuffer& rStr, const RangeList& rRanges );
+
+ static void appendAddress( ::rtl::OUStringBuffer& rStr, const TokenAddress& rPos, bool bR1C1 );
+ static void appendRange( ::rtl::OUStringBuffer& rStr, const TokenRange& rRange, bool bR1C1 );
+
+ // encoded text output ----------------------------------------------------
+
+ static void appendCChar( ::rtl::OUStringBuffer& rStr, sal_Unicode cChar, bool bPrefix = true );
+ static void appendEncChar( ::rtl::OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount = 1, bool bPrefix = true );
+ static void appendEncString( ::rtl::OUStringBuffer& rStr, const ::rtl::OUString& rData, bool bPrefix = true );
+
+ // token list -------------------------------------------------------------
+
+ static void appendToken( ::rtl::OUStringBuffer& rStr, const ::rtl::OUString& rToken, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+ static void appendToken( ::rtl::OUStringBuffer& rStr, sal_Int64 nToken, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+ static void prependToken( ::rtl::OUStringBuffer& rStr, const ::rtl::OUString& rToken, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+ static void prependToken( ::rtl::OUStringBuffer& rStr, sal_Int64 nToken, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+
+ static void appendIndex( ::rtl::OUStringBuffer& rStr, const ::rtl::OUString& rIdx );
+ static void appendIndex( ::rtl::OUStringBuffer& rStr, sal_Int64 nIdx );
+ static void appendIndexedText( ::rtl::OUStringBuffer& rStr, const ::rtl::OUString& rData, const ::rtl::OUString& rIdx );
+ static void appendIndexedText( ::rtl::OUStringBuffer& rStr, const ::rtl::OUString& rData, sal_Int64 nIdx );
+
+ static ::rtl::OUString getToken( const ::rtl::OUString& rData, sal_Int32& rnPos, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+
+ /** Encloses the passed string with the passed characters. Uses cOpen, if cClose is NUL. */
+ static void enclose( ::rtl::OUStringBuffer& rStr, sal_Unicode cOpen, sal_Unicode cClose = '\0' );
+
+ // string conversion ------------------------------------------------------
+
+ static ::rtl::OUString trimSpaces( const ::rtl::OUString& rStr );
+ static ::rtl::OUString trimTrailingNul( const ::rtl::OUString& rStr );
+
+ static ::rtl::OString convertToUtf8( const ::rtl::OUString& rStr );
+ static DataType convertToDataType( const ::rtl::OUString& rStr );
+ static FormatType convertToFormatType( const ::rtl::OUString& rStr );
+
+ static bool convertFromDec( sal_Int64& ornData, const ::rtl::OUString& rData );
+ static bool convertFromHex( sal_Int64& ornData, const ::rtl::OUString& rData );
+
+ static bool convertStringToInt( sal_Int64& ornData, const ::rtl::OUString& rData );
+ static bool convertStringToDouble( double& orfData, const ::rtl::OUString& rData );
+ static bool convertStringToBool( const ::rtl::OUString& rData );
+
+ static OUStringPair convertStringToPair( const ::rtl::OUString& rString, sal_Unicode cSep = '=' );
+
+ // string to list conversion ----------------------------------------------
+
+ static void convertStringToStringList( OUStringVector& orVec, const ::rtl::OUString& rData, bool bIgnoreEmpty );
+ static void convertStringToIntList( Int64Vector& orVec, const ::rtl::OUString& rData, bool bIgnoreEmpty );
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void StringHelper::appendFix( ::rtl::OUStringBuffer& rStr, Type nData, sal_Int32 nWidth )
+{
+ appendDec( rStr, static_cast< double >( nData ) / pow( 2.0, 4.0 * sizeof( Type ) ), nWidth );
+}
+
+template< typename Type >
+void StringHelper::appendValue( ::rtl::OUStringBuffer& rStr, Type nData, FormatType eFmtType )
+{
+ switch( eFmtType )
+ {
+ case FORMATTYPE_DEC: appendDec( rStr, nData ); break;
+ case FORMATTYPE_HEX: appendHex( rStr, nData ); break;
+ case FORMATTYPE_SHORTHEX: appendShortHex( rStr, nData ); break;
+ case FORMATTYPE_BIN: appendBin( rStr, nData ); break;
+ case FORMATTYPE_FIX: appendFix( rStr, nData ); break;
+ case FORMATTYPE_BOOL: appendBool( rStr, nData ); break;
+ default:;
+ }
+}
+
+// ============================================================================
+
+class String : public ::rtl::OUString
+{
+public:
+ inline String() {}
+ inline /*implicit*/ String( const ::rtl::OUString& rStr ) : ::rtl::OUString( rStr ) {}
+ inline /*implicit*/ String( const sal_Char* pcStr ) : ::rtl::OUString( ::rtl::OUString::createFromAscii( pcStr ? pcStr : "" ) ) {}
+ inline /*implicit*/ String( sal_Unicode cChar ) : ::rtl::OUString( cChar ) {}
+
+ inline bool has() const { return getLength() > 0; }
+ inline ::rtl::OUString operator()( const sal_Char* pcDefault ) const { if( has() ) return *this; return String( pcDefault ); }
+};
+
+static const String EMPTY_STRING;
+
+// ============================================================================
+// ============================================================================
+
+/** Stack to create a human readable formula string from a UPN token array. */
+class FormulaStack
+{
+public:
+ explicit FormulaStack();
+
+ inline const ::rtl::OUString& getFormulaString() const { return getString( maFmlaStack ); }
+ inline const ::rtl::OUString& getClassesString() const { return getString( maClassStack ); }
+
+ void pushOperand( const String& rOp, const ::rtl::OUString& rTokClass );
+ void pushOperand( const String& rOp );
+ void pushUnaryOp( const String& rLOp, const String& rROp );
+ void pushBinaryOp( const String& rOp );
+ void pushFuncOp( const String& rFunc, const ::rtl::OUString& rTokClass, sal_uInt8 nParamCount );
+
+ inline void setError() { mbError = true; }
+ void replaceOnTop( const ::rtl::OUString& rOld, const ::rtl::OUString& rNew );
+
+private:
+ typedef ::std::stack< ::rtl::OUString > StringStack;
+
+ inline bool check( bool bCond ) { return (mbError |= !bCond) == false; }
+
+ const ::rtl::OUString& getString( const StringStack& rStack ) const;
+ void pushUnaryOp( StringStack& rStack, const ::rtl::OUString& rLOp, const ::rtl::OUString& rROp );
+ void pushBinaryOp( StringStack& rStack, const ::rtl::OUString& rOp );
+ void pushFuncOp( StringStack& rStack, const ::rtl::OUString& rOp, sal_uInt8 nParamCount );
+
+private:
+ StringStack maFmlaStack;
+ StringStack maClassStack;
+ bool mbError;
+};
+
+// ============================================================================
+// ============================================================================
+
+class Base;
+typedef ::boost::shared_ptr< Base > BaseRef;
+
+/** Base class for all dumper classes.
+
+ Derived classes implement the virtual function implIsValid(). It should
+ check all members the other functions rely on. If the function
+ implIsValid() returns true, all references and pointers can be used without
+ further checking.
+
+ Overview of all classes in this header file based on this Base class:
+
+ Base
+ |
+ +----> NameListBase
+ | |
+ | +----> ConstList ------> MultiList
+ | |
+ | +----> FlagsList ------> CombiList
+ | |
+ | +----> UnitConverter
+ |
+ +----> SharedConfigData
+ |
+ +----> Config
+ |
+ +----> Output
+ |
+ +----> StorageIterator
+ |
+ +----> ObjectBase
+ |
+ +----> StorageObjectBase
+ |
+ +----> OutputObjectBase
+ | |
+ | +----> InputObjectBase
+ | |
+ | +----> BinaryStreamObject
+ | |
+ | +----> TextStreamObject
+ | | |
+ | | +----> XmlStreamObject
+ | |
+ | +----> RecordObjectBase
+ | |
+ | +----> SequenceRecordObjectBase
+ |
+ +----> DumperBase
+ */
+class Base
+{
+public:
+ virtual ~Base();
+
+ inline bool isValid() const { return implIsValid(); }
+ inline static bool isValid( const BaseRef& rxBase ) { return rxBase.get() && rxBase->isValid(); }
+
+protected:
+ inline explicit Base() {}
+
+ virtual bool implIsValid() const = 0;
+};
+
+// ============================================================================
+// ============================================================================
+
+class ConfigItemBase
+{
+public:
+ virtual ~ConfigItemBase();
+ void readConfigBlock( TextInputStream& rStrm );
+
+protected:
+ inline explicit ConfigItemBase() {}
+
+ virtual void implProcessConfigItemStr(
+ TextInputStream& rStrm,
+ const ::rtl::OUString& rKey,
+ const ::rtl::OUString& rData );
+
+ virtual void implProcessConfigItemInt(
+ TextInputStream& rStrm,
+ sal_Int64 nKey,
+ const ::rtl::OUString& rData );
+
+ void readConfigBlockContents(
+ TextInputStream& rStrm );
+
+private:
+ enum LineType { LINETYPE_DATA, LINETYPE_END };
+
+ LineType readConfigLine(
+ TextInputStream& rStrm,
+ ::rtl::OUString& orKey,
+ ::rtl::OUString& orData ) const;
+
+ LineType readConfigLine(
+ TextInputStream& rStrm ) const;
+
+ void processConfigItem(
+ TextInputStream& rStrm,
+ const ::rtl::OUString& rKey,
+ const ::rtl::OUString& rData );
+};
+
+// ============================================================================
+
+class SharedConfigData;
+class Config;
+
+class NameListBase;
+typedef ::boost::shared_ptr< NameListBase > NameListRef;
+
+/** Base class of all classes providing names for specific values (name lists).
+
+ The idea is to provide a unique interfase for all different methods to
+ write specific names for any values. This can be enumerations (dedicated
+ names for a subset of values), or names for bits in bit fields. Classes
+ derived from this base class implement the specific behaviour for the
+ desired purpose.
+ */
+class NameListBase : public Base, public ConfigItemBase
+{
+public:
+ typedef ::std::map< sal_Int64, ::rtl::OUString > OUStringMap;
+ typedef OUStringMap::const_iterator const_iterator;
+
+public:
+ virtual ~NameListBase();
+
+ /** Sets a name for the specified key. */
+ void setName( sal_Int64 nKey, const String& rName );
+
+ /** Include all names of the passed list. */
+ void includeList( const NameListRef& rxList );
+
+ /** Returns true, if the map contains an entry for the passed key. */
+ template< typename Type >
+ inline bool hasName( Type nKey ) const
+ { return maMap.count( static_cast< sal_Int64 >( nKey ) ) != 0; }
+
+ /** Returns the name for the passed key. */
+ template< typename Type >
+ inline ::rtl::OUString getName( const Config& rCfg, Type nKey ) const
+ { return implGetName( rCfg, static_cast< sal_Int64 >( nKey ) ); }
+
+ /** Returns a display name for the passed double value. */
+ inline ::rtl::OUString getName( const Config& rCfg, double fValue ) const
+ { return implGetNameDbl( rCfg, fValue ); }
+
+ /** Returns a map iterator pointing to the first contained name. */
+ inline const_iterator begin() const { return maMap.begin(); }
+ /** Returns a map iterator pointing one past the last contained name. */
+ inline const_iterator end() const { return maMap.end(); }
+
+protected:
+ inline explicit NameListBase( const SharedConfigData& rCfgData ) : mrCfgData( rCfgData ) {}
+
+ virtual bool implIsValid() const;
+
+ virtual void implProcessConfigItemStr(
+ TextInputStream& rStrm,
+ const ::rtl::OUString& rKey,
+ const ::rtl::OUString& rData );
+
+ virtual void implProcessConfigItemInt(
+ TextInputStream& rStrm,
+ sal_Int64 nKey,
+ const ::rtl::OUString& rData );
+
+ /** Derived classes set the name for the passed key. */
+ virtual void implSetName( sal_Int64 nKey, const ::rtl::OUString& rName ) = 0;
+ /** Derived classes generate and return the name for the passed key. */
+ virtual ::rtl::OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const = 0;
+ /** Derived classes generate and return the name for the passed double value. */
+ virtual ::rtl::OUString implGetNameDbl( const Config& rCfg, double fValue ) const = 0;
+ /** Derived classes insert all names and other settings from the passed list. */
+ virtual void implIncludeList( const NameListBase& rList ) = 0;
+
+ /** Inserts the passed name into the internal map. */
+ void insertRawName( sal_Int64 nKey, const ::rtl::OUString& rName );
+ /** Returns the name for the passed key, or 0, if nothing found. */
+ const ::rtl::OUString* findRawName( sal_Int64 nKey ) const;
+
+private:
+ /** Includes name lists, given in a comma separated list of names of the lists. */
+ void include( const ::rtl::OUString& rListKeys );
+ /** Excludes names from the list, given in a comma separated list of their keys. */
+ void exclude( const ::rtl::OUString& rKeys );
+
+private:
+ OUStringMap maMap;
+ const SharedConfigData& mrCfgData;
+};
+
+// ============================================================================
+
+class ConstList : public NameListBase
+{
+public:
+ explicit ConstList( const SharedConfigData& rCfgData );
+
+ /** Sets a default name for unknown keys. */
+ inline void setDefaultName( const String& rDefName ) { maDefName = rDefName; }
+ /** Enables or disables automatic quotation of returned names. */
+ inline void setQuoteNames( bool bQuoteNames ) { mbQuoteNames = bQuoteNames; }
+
+protected:
+ virtual void implProcessConfigItemStr(
+ TextInputStream& rStrm,
+ const ::rtl::OUString& rKey,
+ const ::rtl::OUString& rData );
+
+ /** Sets the name for the passed key. */
+ virtual void implSetName( sal_Int64 nKey, const ::rtl::OUString& rName );
+ /** Returns the name for the passed key, or the default name, if key is not contained. */
+ virtual ::rtl::OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const;
+ /** Returns the name for the passed double value. */
+ virtual ::rtl::OUString implGetNameDbl( const Config& rCfg, double fValue ) const;
+ /** Inserts all names from the passed list. */
+ virtual void implIncludeList( const NameListBase& rList );
+
+private:
+ ::rtl::OUString maDefName;
+ bool mbQuoteNames;
+};
+
+// ============================================================================
+
+class MultiList : public ConstList
+{
+public:
+ explicit MultiList( const SharedConfigData& rCfgData );
+
+ void setNamesFromVec( sal_Int64 nStartKey, const OUStringVector& rNames );
+
+protected:
+ virtual void implProcessConfigItemStr(
+ TextInputStream& rStrm,
+ const ::rtl::OUString& rKey,
+ const ::rtl::OUString& rData );
+
+ virtual void implSetName( sal_Int64 nKey, const ::rtl::OUString& rName );
+
+private:
+ void insertNames( sal_Int64 nStartKey, const ::rtl::OUString& rData );
+
+private:
+ bool mbIgnoreEmpty;
+};
+
+// ============================================================================
+
+class FlagsList : public NameListBase
+{
+public:
+ explicit FlagsList( const SharedConfigData& rCfgData );
+
+ /** Returns the flags to be ignored on output. */
+ inline sal_Int64 getIgnoreFlags() const { return mnIgnore; }
+ /** Sets flags to be ignored on output. */
+ inline void setIgnoreFlags( sal_Int64 nIgnore ) { mnIgnore = nIgnore; }
+
+protected:
+ virtual void implProcessConfigItemStr(
+ TextInputStream& rStrm,
+ const ::rtl::OUString& rKey,
+ const ::rtl::OUString& rData );
+
+ /** Sets the name for the passed key. */
+ virtual void implSetName( sal_Int64 nKey, const ::rtl::OUString& rName );
+ /** Returns the name for the passed key. */
+ virtual ::rtl::OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const;
+ /** Returns the name for the passed double value. */
+ virtual ::rtl::OUString implGetNameDbl( const Config& rCfg, double fValue ) const;
+ /** Inserts all flags from the passed list. */
+ virtual void implIncludeList( const NameListBase& rList );
+
+private:
+ sal_Int64 mnIgnore;
+};
+
+// ============================================================================
+
+class CombiList : public FlagsList
+{
+public:
+ explicit CombiList( const SharedConfigData& rCfgData );
+
+protected:
+ /** Sets the name for the passed key. */
+ virtual void implSetName( sal_Int64 nKey, const ::rtl::OUString& rName );
+ /** Returns the name for the passed key. */
+ virtual ::rtl::OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const;
+ /** Inserts all flags from the passed list. */
+ virtual void implIncludeList( const NameListBase& rList );
+
+private:
+ struct ExtItemFormatKey
+ {
+ sal_Int64 mnKey;
+ Int64Pair maFilter;
+ inline explicit ExtItemFormatKey( sal_Int64 nKey ) : mnKey( nKey ), maFilter( 0, 0 ) {}
+ bool operator<( const ExtItemFormatKey& rRight ) const;
+
+ };
+ struct ExtItemFormat : public ItemFormat
+ {
+ bool mbShiftValue;
+ inline explicit ExtItemFormat() : mbShiftValue( true ) {}
+ };
+ typedef ::std::map< ExtItemFormatKey, ExtItemFormat > ExtItemFormatMap;
+ ExtItemFormatMap maFmtMap;
+};
+
+// ============================================================================
+
+class UnitConverter : public NameListBase
+{
+public:
+ explicit UnitConverter( const SharedConfigData& rCfgData );
+
+ inline void setUnitName( const String& rUnitName ) { maUnitName = rUnitName; }
+ inline void setFactor( double fFactor ) { mfFactor = fFactor; }
+
+protected:
+ /** Sets the name for the passed key. */
+ virtual void implSetName( sal_Int64 nKey, const ::rtl::OUString& rName );
+ /** Returns the converted value with appended unit name. */
+ virtual ::rtl::OUString implGetName( const Config& rCfg, sal_Int64 nKey ) const;
+ /** Returns the converted value with appended unit name. */
+ virtual ::rtl::OUString implGetNameDbl( const Config& rCfg, double fValue ) const;
+ /** Empty implementation. */
+ virtual void implIncludeList( const NameListBase& rList );
+
+private:
+ ::rtl::OUString maUnitName;
+ double mfFactor;
+};
+
+// ============================================================================
+
+class NameListWrapper
+{
+public:
+ inline NameListWrapper() {}
+ inline /*implicit*/ NameListWrapper( const ::rtl::OUString& rListName ) : maName( rListName ) {}
+ inline /*implicit*/ NameListWrapper( const sal_Char* pcListName ) : maName( pcListName ) {}
+ inline /*implicit*/ NameListWrapper( const NameListRef& rxList ) : mxList( rxList ) {}
+
+ inline bool isEmpty() const { return !mxList && !maName.has(); }
+ NameListRef getNameList( const Config& rCfg ) const;
+
+private:
+ String maName;
+ mutable NameListRef mxList;
+};
+
+static const NameListWrapper NO_LIST;
+
+// ============================================================================
+
+class ItemFormatMap : public ::std::map< sal_Int64, ItemFormat >
+{
+public:
+ inline explicit ItemFormatMap() {}
+ inline explicit ItemFormatMap( const NameListRef& rxNameList ) { insertFormats( rxNameList ); }
+
+ void insertFormats( const NameListRef& rxNameList );
+};
+
+// ============================================================================
+// ============================================================================
+
+class SharedConfigData : public Base, public ConfigItemBase
+{
+public:
+ explicit SharedConfigData(
+ const ::rtl::OUString& rFileName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const StorageRef& rxRootStrg,
+ const ::rtl::OUString& rSysFileName,
+ ::comphelper::MediaDescriptor& rMediaDesc );
+
+ virtual ~SharedConfigData();
+
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& getFactory() const { return mxFactory; }
+ inline const StorageRef& getRootStorage() const { return mxRootStrg; }
+ inline const ::rtl::OUString& getSysFileName() const { return maSysFileName; }
+
+ void setOption( const ::rtl::OUString& rKey, const ::rtl::OUString& rData );
+ const ::rtl::OUString* getOption( const ::rtl::OUString& rKey ) const;
+
+ template< typename ListType >
+ ::boost::shared_ptr< ListType > createNameList( const ::rtl::OUString& rListName );
+ void setNameList( const ::rtl::OUString& rListName, const NameListRef& rxList );
+ void eraseNameList( const ::rtl::OUString& rListName );
+ NameListRef getNameList( const ::rtl::OUString& rListName ) const;
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier );
+ inline bool isPasswordCancelled() const { return mbPwCancelled; }
+
+protected:
+ virtual bool implIsValid() const;
+ virtual void implProcessConfigItemStr(
+ TextInputStream& rStrm,
+ const ::rtl::OUString& rKey,
+ const ::rtl::OUString& rData );
+
+private:
+ bool readConfigFile( const ::rtl::OUString& rFileUrl );
+ template< typename ListType >
+ void readNameList( TextInputStream& rStrm, const ::rtl::OUString& rListName );
+ void createShortList( const ::rtl::OUString& rData );
+ void createUnitConverter( const ::rtl::OUString& rData );
+
+private:
+ typedef ::std::set< ::rtl::OUString > ConfigFileSet;
+ typedef ::std::map< ::rtl::OUString, ::rtl::OUString > ConfigDataMap;
+ typedef ::std::map< ::rtl::OUString, NameListRef > NameListMap;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxFactory;
+ StorageRef mxRootStrg;
+ ::rtl::OUString maSysFileName;
+ ::comphelper::MediaDescriptor& mrMediaDesc;
+ ConfigFileSet maConfigFiles;
+ ConfigDataMap maConfigData;
+ NameListMap maNameLists;
+ ::rtl::OUString maConfigPath;
+ bool mbLoaded;
+ bool mbPwCancelled;
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename ListType >
+::boost::shared_ptr< ListType > SharedConfigData::createNameList( const ::rtl::OUString& rListName )
+{
+ ::boost::shared_ptr< ListType > xList;
+ if( rListName.getLength() > 0 )
+ {
+ xList.reset( new ListType( *this ) );
+ setNameList( rListName, xList );
+ }
+ return xList;
+}
+
+template< typename ListType >
+void SharedConfigData::readNameList( TextInputStream& rStrm, const ::rtl::OUString& rListName )
+{
+ NameListRef xList = createNameList< ListType >( rListName );
+ if( xList.get() )
+ xList->readConfigBlock( rStrm );
+}
+
+// ============================================================================
+
+class Config : public Base
+{
+public:
+ explicit Config( const Config& rParent );
+ explicit Config(
+ const sal_Char* pcEnvVar,
+ const ::oox::core::FilterBase& rFilter );
+ explicit Config(
+ const sal_Char* pcEnvVar,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const StorageRef& rxRootStrg,
+ const ::rtl::OUString& rSysFileName,
+ ::comphelper::MediaDescriptor& rMediaDesc );
+
+ virtual ~Config();
+
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& getFactory() const { return mxCfgData->getFactory(); }
+ inline const StorageRef& getRootStorage() const { return mxCfgData->getRootStorage(); }
+ inline const ::rtl::OUString& getSysFileName() const { return mxCfgData->getSysFileName(); }
+
+ void setStringOption( const String& rKey, const String& rData );
+
+ const ::rtl::OUString& getStringOption( const String& rKey, const ::rtl::OUString& rDefault ) const;
+ bool getBoolOption( const String& rKey, bool bDefault ) const;
+ template< typename Type >
+ Type getIntOption( const String& rKey, Type nDefault ) const;
+
+ bool isDumperEnabled() const;
+ bool isImportEnabled() const;
+
+ template< typename ListType >
+ ::boost::shared_ptr< ListType > createNameList( const String& rListName );
+ void setNameList( const String& rListName, const NameListRef& rxList );
+ void eraseNameList( const String& rListName );
+ NameListRef getNameList( const String& rListName ) const;
+
+ /** Returns the name for the passed key from the passed name list. */
+ template< typename Type >
+ ::rtl::OUString getName( const NameListWrapper& rListWrp, Type nKey ) const;
+ /** Returns true, if the passed name list contains an entry for the passed key. */
+ template< typename Type >
+ bool hasName( const NameListWrapper& rListWrp, Type nKey ) const;
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier );
+ bool isPasswordCancelled() const;
+
+protected:
+ inline explicit Config() {}
+ void construct( const Config& rParent );
+ void construct(
+ const sal_Char* pcEnvVar,
+ const ::oox::core::FilterBase& rFilter );
+ void construct(
+ const sal_Char* pcEnvVar,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const StorageRef& rxRootStrg,
+ const ::rtl::OUString& rSysFileName,
+ ::comphelper::MediaDescriptor& rMediaDesc );
+
+ virtual bool implIsValid() const;
+ virtual const ::rtl::OUString* implGetOption( const ::rtl::OUString& rKey ) const;
+ virtual NameListRef implGetNameList( const ::rtl::OUString& rListName ) const;
+
+private:
+ typedef ::boost::shared_ptr< SharedConfigData > SharedConfigDataRef;
+ SharedConfigDataRef mxCfgData;
+};
+
+typedef ::boost::shared_ptr< Config > ConfigRef;
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+Type Config::getIntOption( const String& rKey, Type nDefault ) const
+{
+ sal_Int64 nRawData;
+ const ::rtl::OUString* pData = implGetOption( rKey );
+ return (pData && StringHelper::convertStringToInt( nRawData, *pData )) ?
+ static_cast< Type >( nRawData ) : nDefault;
+}
+
+template< typename ListType >
+::boost::shared_ptr< ListType > Config::createNameList( const String& rListName )
+{
+ return mxCfgData->createNameList< ListType >( rListName );
+}
+
+template< typename Type >
+::rtl::OUString Config::getName( const NameListWrapper& rListWrp, Type nKey ) const
+{
+ NameListRef xList = rListWrp.getNameList( *this );
+ return xList.get() ? xList->getName( *this, nKey ) : OOX_DUMP_ERR_NOMAP;
+}
+
+template< typename Type >
+bool Config::hasName( const NameListWrapper& rListWrp, Type nKey ) const
+{
+ NameListRef xList = rListWrp.getNameList( *this );
+ return xList.get() && xList->hasName( nKey );
+}
+
+// ============================================================================
+// ============================================================================
+
+class Output : public Base
+{
+public:
+ explicit Output(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >& rxStrm );
+
+ explicit Output(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::rtl::OUString& rFileName );
+
+ // ------------------------------------------------------------------------
+
+ void newLine();
+ void emptyLine( size_t nCount = 1 );
+ inline ::rtl::OUStringBuffer& getLine() { return maLine; }
+
+ void incIndent();
+ void decIndent();
+ void resetIndent();
+
+ void startTable( sal_Int32 nW1 );
+ void startTable( sal_Int32 nW1, sal_Int32 nW2 );
+ void startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3 );
+ void startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 );
+ void startTable( size_t nColCount, const sal_Int32* pnColWidths );
+ void tab();
+ void tab( size_t nCol );
+ void endTable();
+
+ void resetItemIndex( sal_Int64 nIdx = 0 );
+ void startItem( const String& rItemName );
+ void contItem();
+ void endItem();
+ inline const ::rtl::OUString& getLastItemValue() const { return maLastItem; }
+
+ void startMultiItems();
+ void endMultiItems();
+
+ // ------------------------------------------------------------------------
+
+ void writeChar( sal_Unicode cChar, sal_Int32 nCount = 1 );
+ void writeAscii( const sal_Char* pcStr );
+ void writeString( const ::rtl::OUString& rStr );
+ void writeArray( const sal_uInt8* pnData, sal_Size nSize, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+ void writeBool( bool bData );
+ void writeColorABGR( sal_Int32 nColor );
+ void writeDateTime( const ::com::sun::star::util::DateTime& rDateTime );
+ void writeColIndex( sal_Int32 nCol );
+ void writeRowIndex( sal_Int32 nRow );
+ void writeColRowRange( sal_Int32 nColRow1, sal_Int32 nColRow2 );
+ void writeColRange( sal_Int32 nCol1, sal_Int32 nCol2 );
+ void writeRowRange( sal_Int32 nRow1, sal_Int32 nRow2 );
+ void writeAddress( const Address& rPos );
+ void writeRange( const Range& rRange );
+ void writeRangeList( const RangeList& rRanges );
+
+ template< typename Type >
+ inline void writeDec( Type nData, sal_Int32 nWidth = 0, sal_Unicode cFill = ' ' )
+ { StringHelper::appendDec( maLine, nData, nWidth, cFill ); }
+ template< typename Type >
+ inline void writeHex( Type nData, bool bPrefix = true )
+ { StringHelper::appendHex( maLine, nData, bPrefix ); }
+ template< typename Type >
+ inline void writeShortHex( Type nData, bool bPrefix = true )
+ { StringHelper::appendShortHex( maLine, nData, bPrefix ); }
+ template< typename Type >
+ inline void writeBin( Type nData, bool bDots = true )
+ { StringHelper::appendBin( maLine, nData, bDots ); }
+ template< typename Type >
+ inline void writeFix( Type nData, sal_Int32 nWidth = 0 )
+ { StringHelper::appendFix( maLine, nData, nWidth ); }
+ template< typename Type >
+ inline void writeValue( Type nData, FormatType eFmtType )
+ { StringHelper::appendValue( maLine, nData, eFmtType ); }
+ template< typename Type >
+ inline void writeName( const Config& rCfg, Type nData, const NameListWrapper& rListWrp )
+ { writeString( rCfg.getName( rListWrp, nData ) ); }
+
+ // ------------------------------------------------------------------------
+protected:
+ void construct( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >& rxStrm );
+
+ virtual bool implIsValid() const;
+
+private:
+ void writeItemName( const String& rItemName );
+
+private:
+ typedef ::std::vector< sal_Int32 > StringLenVec;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream > mxStrm;
+ ::rtl::OUString maIndent;
+ ::rtl::OUStringBuffer maLine;
+ ::rtl::OUString maLastItem;
+ StringLenVec maColPos;
+ size_t mnCol;
+ size_t mnItemLevel;
+ size_t mnMultiLevel;
+ sal_Int64 mnItemIdx;
+ sal_Int32 mnLastItem;
+};
+
+typedef ::boost::shared_ptr< Output > OutputRef;
+
+// ============================================================================
+
+class IndentGuard
+{
+public:
+ inline explicit IndentGuard( const OutputRef& rxOut ) : mrOut( *rxOut ) { mrOut.incIndent(); }
+ inline ~IndentGuard() { mrOut.decIndent(); }
+private:
+ IndentGuard( const IndentGuard& );
+ IndentGuard& operator=( const IndentGuard& );
+private:
+ Output& mrOut;
+};
+
+// ----------------------------------------------------------------------------
+
+class TableGuard
+{
+public:
+ inline explicit TableGuard( const OutputRef& rxOut, sal_Int32 nW1 ) :
+ mrOut( *rxOut ) { mrOut.startTable( nW1 ); }
+ inline explicit TableGuard( const OutputRef& rxOut, sal_Int32 nW1, sal_Int32 nW2 ) :
+ mrOut( *rxOut ) { mrOut.startTable( nW1, nW2 ); }
+ inline explicit TableGuard( const OutputRef& rxOut, sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3 ) :
+ mrOut( *rxOut ) { mrOut.startTable( nW1, nW2, nW3 ); }
+ inline explicit TableGuard( const OutputRef& rxOut, sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 ) :
+ mrOut( *rxOut ) { mrOut.startTable( nW1, nW2, nW3, nW4 ); }
+ inline explicit TableGuard( const OutputRef& rxOut, size_t nColCount,
+ const sal_Int32* pnColWidths ) :
+ mrOut( *rxOut ) { mrOut.startTable( nColCount, pnColWidths ); }
+ inline ~TableGuard() { mrOut.endTable(); }
+ inline void tab() { mrOut.tab(); }
+ inline void tab( size_t nCol ) { mrOut.tab( nCol ); }
+private:
+ TableGuard( const TableGuard& );
+ TableGuard& operator=( const TableGuard& );
+private:
+ Output& mrOut;
+};
+
+// ----------------------------------------------------------------------------
+
+class ItemGuard
+{
+public:
+ inline explicit ItemGuard( const OutputRef& rxOut, const String& rName = EMPTY_STRING ) :
+ mrOut( *rxOut ) { mrOut.startItem( rName ); }
+ inline ~ItemGuard() { mrOut.endItem(); }
+ inline void cont() { mrOut.contItem(); }
+private:
+ ItemGuard( const ItemGuard& );
+ ItemGuard& operator=( const ItemGuard& );
+private:
+ Output& mrOut;
+};
+
+// ----------------------------------------------------------------------------
+
+class MultiItemsGuard
+{
+public:
+ inline explicit MultiItemsGuard( const OutputRef& rxOut ) : mrOut( *rxOut ) { mrOut.startMultiItems(); }
+ inline ~MultiItemsGuard() { mrOut.endMultiItems(); }
+private:
+ MultiItemsGuard( const MultiItemsGuard& );
+ MultiItemsGuard& operator=( const MultiItemsGuard& );
+private:
+ Output& mrOut;
+};
+
+// ============================================================================
+
+class StorageIterator : public Base
+{
+public:
+ explicit StorageIterator( const StorageRef& rxStrg );
+ virtual ~StorageIterator();
+
+ size_t getElementCount() const;
+
+ StorageIterator& operator++();
+
+ ::rtl::OUString getName() const;
+ bool isStream() const;
+ bool isStorage() const;
+
+private:
+ virtual bool implIsValid() const;
+
+private:
+ StorageRef mxStrg;
+ OUStringVector maNames;
+ OUStringVector::const_iterator maIt;
+};
+
+// ============================================================================
+// ============================================================================
+
+class ObjectBase : public Base
+{
+public:
+ virtual ~ObjectBase();
+
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
+ getFactory() const { return mxConfig->getFactory(); }
+
+ void dump();
+
+ // ------------------------------------------------------------------------
+protected:
+ inline explicit ObjectBase() {}
+
+ void construct( const ConfigRef& rxConfig );
+ void construct( const ObjectBase& rParent );
+
+ virtual bool implIsValid() const;
+ virtual void implDump();
+
+ // ------------------------------------------------------------------------
+
+ void reconstructConfig( const ConfigRef& rxConfig );
+
+ inline Config& cfg() const { return *mxConfig; }
+
+private:
+ ConfigRef mxConfig;
+};
+
+typedef ::boost::shared_ptr< ObjectBase > ObjectRef;
+
+// ============================================================================
+// ============================================================================
+
+class StorageObjectBase : public ObjectBase
+{
+protected:
+ inline explicit StorageObjectBase() {}
+
+protected:
+ using ObjectBase::construct;
+ void construct( const ObjectBase& rParent, const StorageRef& rxStrg, const ::rtl::OUString& rSysPath );
+ void construct( const ObjectBase& rParent );
+
+ virtual bool implIsValid() const;
+ virtual void implDump();
+
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+
+ virtual void implDumpStorage(
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rSysPath );
+
+ virtual void implDumpBaseStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName );
+
+ void addPreferredStream( const String& rStrmName );
+ void addPreferredStorage( const String& rStrgPath );
+
+private:
+ ::rtl::OUString getSysFileName(
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysOutPath );
+
+ void extractStream(
+ StorageBase& rStrg,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+ void extractStorage(
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rSysPath );
+
+ void extractItem(
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rItemName,
+ const ::rtl::OUString& rSysPath,
+ bool bIsStrg, bool bIsStrm );
+
+private:
+ struct PreferredItem
+ {
+ ::rtl::OUString maName;
+ bool mbStorage;
+
+ inline explicit PreferredItem( const ::rtl::OUString rName, bool bStorage ) :
+ maName( rName ), mbStorage( bStorage ) {}
+ };
+ typedef ::std::vector< PreferredItem > PreferredItemVector;
+
+ StorageRef mxStrg;
+ ::rtl::OUString maSysPath;
+ PreferredItemVector maPreferred;
+};
+
+typedef ::boost::shared_ptr< StorageObjectBase > StorageObjectRef;
+
+// ============================================================================
+// ============================================================================
+
+class OutputObjectBase : public ObjectBase
+{
+public:
+ virtual ~OutputObjectBase();
+
+ // ------------------------------------------------------------------------
+protected:
+ inline explicit OutputObjectBase() {}
+
+ using ObjectBase::construct;
+ void construct( const ObjectBase& rParent, const ::rtl::OUString& rSysFileName );
+ void construct( const ObjectBase& rParent, const OutputRef& rxOut );
+ void construct( const OutputObjectBase& rParent );
+
+ virtual bool implIsValid() const;
+
+ // ------------------------------------------------------------------------
+
+ void writeEmptyItem( const String& rName );
+ void writeInfoItem( const String& rName, const String& rData );
+ void writeCharItem( const String& rName, sal_Unicode cData );
+ void writeStringItem( const String& rName, const ::rtl::OUString& rData );
+ void writeArrayItem( const String& rName, const sal_uInt8* pnData, sal_Size nSize, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+ void writeBoolItem( const String& rName, bool bData );
+ double writeRkItem( const String& rName, sal_Int32 nRk );
+ void writeColorABGRItem( const String& rName, sal_Int32 nColor );
+ void writeDateTimeItem( const String& rName, const ::com::sun::star::util::DateTime& rDateTime );
+ void writeGuidItem( const String& rName, const ::rtl::OUString& rGuid );
+ void writeColIndexItem( const String& rName, sal_Int32 nCol );
+ void writeRowIndexItem( const String& rName, sal_Int32 nRow );
+ void writeColRangeItem( const String& rName, sal_Int32 nCol1, sal_Int32 nCol2 );
+ void writeRowRangeItem( const String& rName, sal_Int32 nRow1, sal_Int32 nRow2 );
+ void writeAddressItem( const String& rName, const Address& rPos );
+ void writeRangeItem( const String& rName, const Range& rRange );
+ void writeRangeListItem( const String& rName, const RangeList& rRanges );
+ void writeTokenAddressItem( const String& rName, const TokenAddress& rPos, bool bNameMode );
+ void writeTokenAddress3dItem( const String& rName, const ::rtl::OUString& rRef, const TokenAddress& rPos, bool bNameMode );
+ void writeTokenRangeItem( const String& rName, const TokenRange& rRange, bool bNameMode );
+ void writeTokenRange3dItem( const String& rName, const ::rtl::OUString& rRef, const TokenRange& rRange, bool bNameMode );
+
+ template< typename Type >
+ void addNameToItem( Type nData, const NameListWrapper& rListWrp );
+
+ template< typename Type >
+ void writeNameItem( const String& rName, Type nData, const NameListWrapper& rListWrp );
+ template< typename Type >
+ void writeDecItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ void writeHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ void writeShortHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ void writeBinItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ void writeFixItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ void writeDecBoolItem( const String& rName, Type nData, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ void writeValueItem( const String& rName, Type nData, FormatType eFmtType, const NameListWrapper& rListWrp = NO_LIST );
+
+ template< typename Type >
+ void writeValueItem( const ItemFormat& rItemFmt, Type nData );
+
+ template< typename Type >
+ void writeDecPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep = ',' );
+ template< typename Type >
+ void writeHexPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep = ',' );
+
+protected:
+ OutputRef mxOut;
+};
+
+typedef ::boost::shared_ptr< OutputObjectBase > OutputObjectRef;
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void OutputObjectBase::addNameToItem( Type nData, const NameListWrapper& rListWrp )
+{
+ if( !rListWrp.isEmpty() )
+ {
+ mxOut->contItem();
+ mxOut->writeName( cfg(), nData, rListWrp );
+ }
+}
+
+template< typename Type >
+void OutputObjectBase::writeNameItem( const String& rName, Type nData, const NameListWrapper& rListWrp )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeName( cfg(), nData, rListWrp );
+}
+
+template< typename Type >
+void OutputObjectBase::writeDecItem( const String& rName, Type nData, const NameListWrapper& rListWrp )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeDec( nData );
+ addNameToItem( nData, rListWrp );
+}
+
+template< typename Type >
+void OutputObjectBase::writeHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeHex( nData );
+ addNameToItem( nData, rListWrp );
+}
+
+template< typename Type >
+void OutputObjectBase::writeShortHexItem( const String& rName, Type nData, const NameListWrapper& rListWrp )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeShortHex( nData );
+ addNameToItem( nData, rListWrp );
+}
+
+template< typename Type >
+void OutputObjectBase::writeBinItem( const String& rName, Type nData, const NameListWrapper& rListWrp )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeBin( nData );
+ addNameToItem( nData, rListWrp );
+}
+
+template< typename Type >
+void OutputObjectBase::writeFixItem( const String& rName, Type nData, const NameListWrapper& rListWrp )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeFix( nData );
+ addNameToItem( nData, rListWrp );
+}
+
+template< typename Type >
+void OutputObjectBase::writeDecBoolItem( const String& rName, Type nData, const NameListWrapper& rListWrp )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeDec( nData );
+ aItem.cont();
+ mxOut->writeBool( nData != 0 );
+ addNameToItem( nData, rListWrp );
+}
+
+template< typename Type >
+void OutputObjectBase::writeValueItem( const String& rName, Type nData, FormatType eFmtType, const NameListWrapper& rListWrp )
+{
+ if( eFmtType == FORMATTYPE_BOOL )
+ writeDecBoolItem( rName, nData, rListWrp );
+ else
+ {
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeValue( nData, eFmtType );
+ addNameToItem( nData, rListWrp );
+ }
+}
+
+template< typename Type >
+void OutputObjectBase::writeValueItem( const ItemFormat& rItemFmt, Type nData )
+{
+ ::rtl::OString aNameUtf8 = StringHelper::convertToUtf8( rItemFmt.maItemName );
+ writeValueItem( aNameUtf8.getStr(), nData, rItemFmt.meFmtType, rItemFmt.maListName );
+}
+
+template< typename Type >
+void OutputObjectBase::writeDecPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeDec( nData1 );
+ mxOut->writeChar( cSep );
+ mxOut->writeDec( nData2 );
+}
+
+template< typename Type >
+void OutputObjectBase::writeHexPairItem( const String& rName, Type nData1, Type nData2, sal_Unicode cSep )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeHex( nData1 );
+ mxOut->writeChar( cSep );
+ mxOut->writeHex( nData2 );
+}
+
+// ============================================================================
+// ============================================================================
+
+class InputObjectBase : public OutputObjectBase
+{
+public:
+ virtual ~InputObjectBase();
+
+ // ------------------------------------------------------------------------
+protected:
+ inline explicit InputObjectBase() {}
+
+ using OutputObjectBase::construct;
+ void construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+ void construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OutputRef& rxOut );
+ void construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm );
+ void construct( const InputObjectBase& rParent );
+
+ virtual bool implIsValid() const;
+
+ // ------------------------------------------------------------------------
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ getXInputStream() const;
+
+ // ------------------------------------------------------------------------
+
+ void skipBlock( sal_Int64 nBytes, bool bShowSize = true );
+ void dumpRawBinary( sal_Int64 nBytes, bool bShowOffset = true, bool bStream = false );
+
+ void dumpBinary( const String& rName, sal_Int64 nBytes, bool bShowOffset = true );
+ void dumpRemaining( sal_Int64 nBytes );
+ void dumpRemainingTo( sal_Int64 nPos );
+ void dumpRemainingStream();
+
+ void dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep = OOX_DUMP_LISTSEP );
+ inline void dumpUnused( sal_Int32 nBytes ) { dumpArray( OOX_DUMP_UNUSED, nBytes ); }
+ inline void dumpUnknown( sal_Int32 nBytes ) { dumpArray( OOX_DUMP_UNKNOWN, nBytes ); }
+
+ sal_Unicode dumpChar( const String& rName, rtl_TextEncoding eTextEnc );
+ sal_Unicode dumpUnicode( const String& rName );
+
+ ::rtl::OUString dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul = false );
+ ::rtl::OUString dumpUnicodeArray( const String& rName, sal_Int32 nLen, bool bHideTrailingNul = false );
+
+ ::rtl::OUString dumpNullCharArray( const String& rName, rtl_TextEncoding eTextEnc );
+ ::rtl::OUString dumpNullUnicodeArray( const String& rName );
+
+ double dumpRk( const String& rName = EMPTY_STRING );
+ sal_Int32 dumpColorABGR( const String& rName = EMPTY_STRING );
+ ::com::sun::star::util::DateTime dumpFileTime( const String& rName = EMPTY_STRING );
+ ::rtl::OUString dumpGuid( const String& rName = EMPTY_STRING );
+
+ void dumpItem( const ItemFormat& rItemFmt );
+
+ template< typename Type >
+ Type dumpName( const String& rName, const NameListWrapper& rListWrp );
+ template< typename Type >
+ Type dumpDec( const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ Type dumpHex( const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ Type dumpBin( const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ Type dumpFix( const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ Type dumpBool( const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ Type dumpValue( const ItemFormat& rItemFmt );
+
+ template< typename Type1, typename Type2 >
+ Type1 dumpName( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type1, typename Type2 >
+ Type1 dumpDec( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type1, typename Type2 >
+ Type1 dumpHex( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type1, typename Type2 >
+ Type1 dumpBin( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type1, typename Type2 >
+ Type1 dumpFix( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type1, typename Type2 >
+ Type1 dumpBool( bool bType1, const String& rName, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type1, typename Type2 >
+ Type1 dumpValue( bool bType1, const ItemFormat& rItemFmt );
+
+ template< typename Type >
+ void dumpDecPair( const String& rName, sal_Unicode cSep = ',' );
+ template< typename Type >
+ void dumpHexPair( const String& rName, sal_Unicode cSep = ',' );
+
+protected:
+ BinaryInputStreamRef mxStrm;
+};
+
+typedef ::boost::shared_ptr< InputObjectBase > InputObjectRef;
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+Type InputObjectBase::dumpName( const String& rName, const NameListWrapper& rListWrp )
+{
+ Type nData;
+ *mxStrm >> nData;
+ writeNameItem( rName, nData, rListWrp );
+ return nData;
+}
+
+template< typename Type >
+Type InputObjectBase::dumpDec( const String& rName, const NameListWrapper& rListWrp )
+{
+ Type nData;
+ *mxStrm >> nData;
+ writeDecItem( rName, nData, rListWrp );
+ return nData;
+}
+
+template< typename Type >
+Type InputObjectBase::dumpHex( const String& rName, const NameListWrapper& rListWrp )
+{
+ Type nData;
+ *mxStrm >> nData;
+ writeHexItem( rName, nData, rListWrp );
+ return nData;
+}
+
+template< typename Type >
+Type InputObjectBase::dumpBin( const String& rName, const NameListWrapper& rListWrp )
+{
+ Type nData;
+ *mxStrm >> nData;
+ writeBinItem( rName, nData, rListWrp );
+ return nData;
+}
+
+template< typename Type >
+Type InputObjectBase::dumpFix( const String& rName, const NameListWrapper& rListWrp )
+{
+ Type nData;
+ *mxStrm >> nData;
+ writeFixItem( rName, nData, rListWrp );
+ return nData;
+}
+
+template< typename Type >
+Type InputObjectBase::dumpBool( const String& rName, const NameListWrapper& rListWrp )
+{
+ Type nData;
+ *mxStrm >> nData;
+ writeDecBoolItem( rName, nData, rListWrp );
+ return nData;
+}
+
+template< typename Type >
+Type InputObjectBase::dumpValue( const ItemFormat& rItemFmt )
+{
+ Type nData;
+ *mxStrm >> nData;
+ writeValueItem( rItemFmt, nData );
+ return nData;
+}
+
+template< typename Type1, typename Type2 >
+Type1 InputObjectBase::dumpName( bool bType1, const String& rName, const NameListWrapper& rListWrp )
+{
+ return bType1 ? dumpName< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpName< Type2 >( rName, rListWrp ) );
+}
+
+template< typename Type1, typename Type2 >
+Type1 InputObjectBase::dumpDec( bool bType1, const String& rName, const NameListWrapper& rListWrp )
+{
+ return bType1 ? dumpDec< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpDec< Type2 >( rName, rListWrp ) );
+}
+
+template< typename Type1, typename Type2 >
+Type1 InputObjectBase::dumpHex( bool bType1, const String& rName, const NameListWrapper& rListWrp )
+{
+ return bType1 ? dumpHex< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpHex< Type2 >( rName, rListWrp ) );
+}
+
+template< typename Type1, typename Type2 >
+Type1 InputObjectBase::dumpBin( bool bType1, const String& rName, const NameListWrapper& rListWrp )
+{
+ return bType1 ? dumpBin< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpBin< Type2 >( rName, rListWrp ) );
+}
+
+template< typename Type1, typename Type2 >
+Type1 InputObjectBase::dumpFix( bool bType1, const String& rName, const NameListWrapper& rListWrp )
+{
+ return bType1 ? dumpFix< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpFix< Type2 >( rName, rListWrp ) );
+}
+
+template< typename Type1, typename Type2 >
+Type1 InputObjectBase::dumpBool( bool bType1, const String& rName, const NameListWrapper& rListWrp )
+{
+ return bType1 ? dumpBool< Type1 >( rName, rListWrp ) : static_cast< Type1 >( dumpBool< Type2 >( rName, rListWrp ) );
+}
+
+template< typename Type1, typename Type2 >
+Type1 InputObjectBase::dumpValue( bool bType1, const ItemFormat& rItemFmt )
+{
+ return bType1 ? dumpValue< Type1 >( rItemFmt ) : static_cast< Type1 >( dumpValue< Type2 >( rItemFmt ) );
+}
+
+template< typename Type >
+void InputObjectBase::dumpDecPair( const String& rName, sal_Unicode cSep )
+{
+ Type nData1, nData2;
+ *mxStrm >> nData1 >> nData2;
+ writeDecPairItem( rName, nData1, nData2, cSep );
+}
+
+template< typename Type >
+void InputObjectBase::dumpHexPair( const String& rName, sal_Unicode cSep )
+{
+ Type nData1, nData2;
+ *mxStrm >> nData1 >> nData2;
+ writeHexPairItem( rName, nData1, nData2, cSep );
+}
+
+// ============================================================================
+// ============================================================================
+
+class BinaryStreamObject : public InputObjectBase
+{
+public:
+ explicit BinaryStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName );
+
+ explicit BinaryStreamObject(
+ const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm );
+
+protected:
+ void dumpBinaryStream( bool bShowOffset = true );
+
+ virtual void implDump();
+};
+
+// ============================================================================
+
+class TextStreamObject : public InputObjectBase
+{
+public:
+ explicit TextStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ rtl_TextEncoding eTextEnc,
+ const ::rtl::OUString& rSysFileName );
+
+ explicit TextStreamObject(
+ const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ rtl_TextEncoding eTextEnc );
+
+protected:
+ virtual bool implIsValid() const;
+ virtual void implDump();
+ virtual void implDumpLine( const ::rtl::OUString& rLine, sal_uInt32 nLine );
+
+private:
+ ::boost::shared_ptr< TextInputStream > mxTextStrm;
+};
+
+// ============================================================================
+
+class XmlStreamObject : public TextStreamObject
+{
+public:
+ explicit XmlStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual void implDump();
+ virtual void implDumpLine( const ::rtl::OUString& rLine, sal_uInt32 nLine );
+
+private:
+ ::rtl::OUString maIncompleteLine;
+};
+
+// ============================================================================
+// ============================================================================
+
+class RecordObjectBase : public InputObjectBase
+{
+protected:
+ inline explicit RecordObjectBase() {}
+
+ using InputObjectBase::construct;
+ void construct(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm,
+ const ::rtl::OUString& rSysFileName,
+ const BinaryInputStreamRef& rxRecStrm,
+ const String& rRecNames,
+ const String& rSimpleRecs = EMPTY_STRING );
+ void construct(
+ const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm,
+ const BinaryInputStreamRef& rxRecStrm,
+ const String& rRecNames,
+ const String& rSimpleRecs = EMPTY_STRING );
+
+ inline sal_Int64 getRecPos() const { return mnRecPos; }
+ inline sal_Int64 getRecId() const { return mnRecId; }
+ inline sal_Int64 getRecSize() const { return mnRecSize; }
+ inline NameListRef getRecNames() const { return maRecNames.getNameList( cfg() ); }
+
+ inline void setBinaryOnlyMode( bool bBinaryOnly ) { mbBinaryOnly = bBinaryOnly; }
+ inline bool isBinaryOnlyMode() const { return mbBinaryOnly; }
+
+ virtual bool implIsValid() const;
+ virtual void implDump();
+
+ virtual bool implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize ) = 0;
+ virtual void implWriteExtHeader();
+ virtual void implDumpRecordBody();
+
+private:
+ void constructRecObjBase(
+ const BinaryInputStreamRef& rxBaseStrm,
+ const String& rRecNames,
+ const String& rSimpleRecs );
+
+ void writeHeader();
+
+private:
+ BinaryInputStreamRef mxBaseStrm;
+ NameListWrapper maRecNames;
+ NameListWrapper maSimpleRecs;
+ sal_Int64 mnRecPos;
+ sal_Int64 mnRecId;
+ sal_Int64 mnRecSize;
+ bool mbShowRecPos;
+ bool mbBinaryOnly;
+};
+
+// ============================================================================
+
+class SequenceRecordObjectBase : public RecordObjectBase
+{
+protected:
+ inline explicit SequenceRecordObjectBase() : mxRecData( new StreamDataSequence ) {}
+
+ inline StreamDataSequence& getRecordDataSequence() { return *mxRecData; }
+
+ using RecordObjectBase::construct;
+ void construct(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm,
+ const ::rtl::OUString& rSysFileName,
+ const String& rRecNames,
+ const String& rSimpleRecs = EMPTY_STRING );
+ void construct(
+ const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm,
+ const String& rRecNames,
+ const String& rSimpleRecs = EMPTY_STRING );
+
+ virtual bool implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize );
+ virtual bool implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize ) = 0;
+
+private:
+ typedef ::boost::shared_ptr< StreamDataSequence > StreamDataSeqRef;
+ StreamDataSeqRef mxRecData;
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Base class for a file dumper. Derived classes implement the implDump()
+ function to add functionality.
+ */
+class DumperBase : public ObjectBase
+{
+public:
+ virtual ~DumperBase();
+
+ bool isImportEnabled() const;
+ bool isImportCancelled() const;
+
+protected:
+ inline explicit DumperBase() {}
+
+ using ObjectBase::construct;
+ void construct( const ConfigRef& rxConfig );
+};
+
+// ============================================================================
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#define OOX_DUMP_FILE( DumperClassName ) \
+do { \
+ DumperClassName aDumper( *this ); \
+ aDumper.dump(); \
+ bool bCancelled = aDumper.isImportCancelled(); \
+ if( !aDumper.isImportEnabled() || bCancelled ) \
+ return aDumper.isValid() && !bCancelled; \
+} while( false )
+
+#else // OOX_INCLUDE_DUMPER
+
+#define OOX_DUMP_FILE( DumperClassName ) (void)0
+
+#endif // OOX_INCLUDE_DUMPER
+#endif
+
diff --git a/oox/inc/oox/dump/oledumper.hxx b/oox/inc/oox/dump/oledumper.hxx
new file mode 100644
index 000000000000..8f706f4c40f1
--- /dev/null
+++ b/oox/inc/oox/dump/oledumper.hxx
@@ -0,0 +1,939 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DUMP_OLEDUMPER_HXX
+#define OOX_DUMP_OLEDUMPER_HXX
+
+#include "oox/helper/storagebase.hxx"
+#include "oox/dump/dumperbase.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace com { namespace sun { namespace star {
+ namespace io { class XInputStream; }
+} } }
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+// ============================================================================
+
+class OleInputObjectBase : public InputObjectBase
+{
+protected:
+ inline explicit OleInputObjectBase() {}
+
+ ::rtl::OUString dumpAnsiString32( const String& rName );
+ ::rtl::OUString dumpUniString32( const String& rName );
+
+ sal_Int32 dumpStdClipboardFormat( const String& rName = EMPTY_STRING );
+ ::rtl::OUString dumpAnsiString32OrStdClip( const String& rName );
+ ::rtl::OUString dumpUniString32OrStdClip( const String& rName );
+
+ void writeOleColorItem( const String& rName, sal_uInt32 nColor );
+ sal_uInt32 dumpOleColor( const String& rName );
+};
+
+// ============================================================================
+// ============================================================================
+
+class StdFontObject : public OleInputObjectBase
+{
+public:
+ explicit StdFontObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDump();
+};
+
+// ============================================================================
+
+class StdPicObject : public OleInputObjectBase
+{
+public:
+ explicit StdPicObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDump();
+};
+
+// ============================================================================
+
+class StdHlinkObject : public OleInputObjectBase
+{
+public:
+ explicit StdHlinkObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDump();
+
+private:
+ ::rtl::OUString dumpHyperlinkString( const String& rName, bool bUnicode );
+
+ bool dumpGuidAndMoniker();
+ void dumpUrlMoniker();
+ void dumpFileMoniker();
+ void dumpItemMoniker();
+ void dumpAntiMoniker();
+ void dumpCompositeMoniker();
+};
+
+// ============================================================================
+// ============================================================================
+
+class OleStreamObject : public OleInputObjectBase
+{
+public:
+ explicit OleStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+};
+
+// ============================================================================
+
+class OleCompObjObject : public OleStreamObject
+{
+public:
+ explicit OleCompObjObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual void implDump();
+};
+
+// ============================================================================
+// ============================================================================
+
+class OlePropertyStreamObject : public InputObjectBase
+{
+public:
+ explicit OlePropertyStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual void implDump();
+
+private:
+ void dumpSection( const ::rtl::OUString& rGuid, sal_uInt32 nStartPos );
+
+ void dumpProperty( sal_Int32 nPropId, sal_uInt32 nStartPos );
+ void dumpCodePageProperty( sal_uInt32 nStartPos );
+ void dumpDictionaryProperty( sal_uInt32 nStartPos );
+
+ sal_uInt16 dumpPropertyContents( sal_Int32 nPropId );
+ void dumpPropertyValue( sal_Int32 nPropId, sal_uInt16 nBaseType );
+ void dumpPropertyVector( sal_Int32 nPropId, sal_uInt16 nBaseType );
+ void dumpPropertyArray( sal_Int32 nPropId, sal_uInt16 nBaseType );
+
+ sal_uInt16 dumpPropertyType();
+ void dumpBlob( sal_Int32 nPropId, const String& rName );
+ ::rtl::OUString dumpString8( const String& rName );
+ ::rtl::OUString dumpCharArray8( const String& rName, sal_Int32 nLen );
+ ::rtl::OUString dumpString16( const String& rName );
+ ::rtl::OUString dumpCharArray16( const String& rName, sal_Int32 nLen );
+ bool dumpTypedProperty( const String& rName, sal_uInt16 nExpectedType );
+ void dumpHlinks( sal_Int32 nSize );
+
+ bool startElement( sal_uInt32 nStartPos );
+ void writeSectionHeader( const ::rtl::OUString& rGuid, sal_uInt32 nStartPos );
+ void writePropertyHeader( sal_Int32 nPropId, sal_uInt32 nStartPos );
+
+private:
+ NameListRef mxPropIds;
+ rtl_TextEncoding meTextEnc;
+ bool mbIsUnicode;
+};
+
+// ============================================================================
+
+class OleStorageObject : public StorageObjectBase
+{
+public:
+ explicit OleStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const ::rtl::OUString& rSysPath );
+
+protected:
+ inline explicit OleStorageObject() {}
+
+ using StorageObjectBase::construct;
+ void construct( const ObjectBase& rParent, const StorageRef& rxStrg, const ::rtl::OUString& rSysPath );
+ void construct( const ObjectBase& rParent );
+
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+};
+
+// ============================================================================
+// ============================================================================
+
+class ComCtlObjectBase : public OleInputObjectBase
+{
+protected:
+ explicit ComCtlObjectBase(
+ const InputObjectBase& rParent,
+ sal_uInt32 nDataId5, sal_uInt32 nDataId6, sal_uInt16 nVersion,
+ bool bCommonPart, bool bComplexPart );
+
+ virtual void implDump();
+ virtual void implDumpProperties() = 0;
+ virtual void implDumpCommonExtra( sal_Int64 nEndPos );
+ virtual void implDumpCommonTrailing();
+
+private:
+ bool dumpComCtlHeader( sal_uInt32 nExpId, sal_uInt16 nExpMajor = SAL_MAX_UINT16, sal_uInt16 nExpMinor = SAL_MAX_UINT16 );
+ bool dumpComCtlSize();
+ bool dumpComCtlData( sal_uInt32& ornCommonPartSize );
+ bool dumpComCtlCommon( sal_uInt32 nPartSize );
+ bool dumpComCtlComplex();
+
+protected:
+ sal_uInt32 mnDataId5;
+ sal_uInt32 mnDataId6;
+ sal_uInt16 mnVersion;
+ bool mbCommonPart;
+ bool mbComplexPart;
+};
+
+// ============================================================================
+
+class ComCtlScrollBarObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlScrollBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+};
+
+// ============================================================================
+
+class ComCtlProgressBarObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlProgressBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+};
+
+// ============================================================================
+
+class ComCtlSliderObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlSliderObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+};
+
+// ============================================================================
+
+class ComCtlUpDownObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlUpDownObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+};
+
+// ============================================================================
+
+class ComCtlImageListObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlImageListObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+ virtual void implDumpCommonExtra( sal_Int64 nEndPos );
+ virtual void implDumpCommonTrailing();
+};
+
+// ============================================================================
+
+class ComCtlTabStripObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlTabStripObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+ virtual void implDumpCommonExtra( sal_Int64 nEndPos );
+};
+
+// ============================================================================
+
+class ComCtlTreeViewObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlTreeViewObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+ virtual void implDumpCommonExtra( sal_Int64 nEndPos );
+
+private:
+ sal_uInt32 mnStringFlags;
+};
+
+// ============================================================================
+
+class ComCtlStatusBarObject : public ComCtlObjectBase
+{
+public:
+ explicit ComCtlStatusBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion );
+
+protected:
+ virtual void implDumpProperties();
+ virtual void implDumpCommonExtra( sal_Int64 nEndPos );
+ virtual void implDumpCommonTrailing();
+};
+
+// ============================================================================
+// ============================================================================
+
+class AxPropertyObjectBase : public OleInputObjectBase
+{
+protected:
+ inline explicit AxPropertyObjectBase() {}
+
+ using OleInputObjectBase::construct;
+ void construct(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName,
+ const String& rPropNameList,
+ bool b64BitPropFlags = false );
+ void construct(
+ const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const String& rPropNameList,
+ bool b64BitPropFlags = false );
+ void construct(
+ const InputObjectBase& rParent,
+ const String& rPropNameList,
+ bool b64BitPropFlags = false );
+
+ virtual bool implIsValid() const;
+ virtual void implDump();
+
+ virtual void implDumpShortProperties();
+ virtual void implDumpExtended();
+
+ bool ensureValid( bool bCondition = true );
+
+ template< typename Type >
+ void alignInput();
+
+ void setAlignAnchor();
+ bool startNextProperty();
+ ::rtl::OUString getPropertyName() const;
+
+ template< typename Type >
+ Type dumpDecProperty( Type nDefault, const NameListWrapper& rListWrp = NO_LIST );
+ template< typename Type >
+ Type dumpHexProperty( Type nDefault, const NameListWrapper& rListWrp = NO_LIST );
+
+ inline bool dumpBoolProperty() { return startNextProperty(); }
+ inline sal_Int32 dumpHmmProperty() { return dumpDecProperty< sal_Int32 >( 0, "CONV-HMM-TO-CM" ); }
+ inline sal_uInt8 dumpMousePtrProperty() { return dumpDecProperty< sal_uInt8 >( 0, "OLE-MOUSEPTR" ); }
+ template< typename Type >
+ inline Type dumpBorderStyleProperty( Type nDefault ) { return dumpDecProperty< Type >( nDefault, "AX-BORDERSTYLE" ); }
+ template< typename Type >
+ inline Type dumpSpecialEffectProperty( Type nDefault ) { return dumpDecProperty< Type >( nDefault, "AX-SPECIALEFFECT" ); }
+ inline sal_uInt32 dumpEnabledProperty() { return dumpDecProperty< sal_uInt32 >( 1, "AX-ENABLED" ); }
+ inline sal_Int32 dumpOrientationProperty() { return dumpDecProperty< sal_Int32 >( -1, "AX-ORIENTATION" ); }
+ inline sal_Int32 dumpDelayProperty() { return dumpDecProperty< sal_Int32 >( 50, "AX-CONV-MS" ); }
+ inline sal_uInt32 dumpImagePosProperty() { return dumpHexProperty< sal_uInt32 >( 0x00070001, "AX-IMAGEPOS" ); }
+ inline sal_uInt8 dumpImageSizeModeProperty() { return dumpDecProperty< sal_uInt8 >( 0, "AX-IMAGESIZEMODE" ); }
+ inline sal_uInt8 dumpImageAlignProperty() { return dumpDecProperty< sal_uInt8 >( 2, "AX-IMAGEALIGN" ); }
+
+ sal_uInt32 dumpFlagsProperty( sal_uInt32 nDefault, const sal_Char* pcNameList = "AX-FLAGS" );
+ sal_uInt32 dumpColorProperty( sal_uInt32 nDefault );
+ sal_Unicode dumpUnicodeProperty();
+ void dumpUnknownProperty();
+
+ void dumpPosProperty();
+ void dumpSizeProperty();
+ void dumpGuidProperty( ::rtl::OUString* pValue = 0 );
+ void dumpStringProperty( ::rtl::OUString* pValue = 0 );
+ void dumpStringArrayProperty();
+ void dumpStreamProperty();
+
+ void dumpEmbeddedFont();
+ void dumpToPosition( sal_Int64 nPos );
+
+private:
+ void constructAxPropObj( const String& rPropNameList, bool b64BitPropFlags );
+
+ void dumpVersion();
+ ::rtl::OUString dumpString( const String& rName, sal_uInt32 nSize, bool bArray );
+ void dumpShortProperties();
+ void dumpLargeProperties();
+
+private:
+ struct LargeProperty
+ {
+ enum LargePropertyType { PROPTYPE_POS, PROPTYPE_SIZE, PROPTYPE_GUID, PROPTYPE_STRING, PROPTYPE_STRINGARRAY };
+
+ LargePropertyType mePropType;
+ ::rtl::OUString maItemName;
+ sal_uInt32 mnDataSize;
+ ::rtl::OUString* mpItemValue;
+ inline explicit LargeProperty( LargePropertyType ePropType, const String& rItemName, sal_uInt32 nDataSize, ::rtl::OUString* pItemValue = 0 ) :
+ mePropType( ePropType ), maItemName( rItemName ), mnDataSize( nDataSize ), mpItemValue( pItemValue ) {}
+ };
+ typedef ::std::vector< LargeProperty > LargePropertyVector;
+
+ struct StreamProperty
+ {
+ ::rtl::OUString maItemName;
+ sal_uInt16 mnData;
+ inline explicit StreamProperty( const String& rItemName, sal_uInt16 nData ) :
+ maItemName( rItemName ), mnData( nData ) {}
+ };
+ typedef ::std::vector< StreamProperty > StreamPropertyVector;
+
+ LargePropertyVector maLargeProps;
+ StreamPropertyVector maStreamProps;
+ NameListRef mxPropNames;
+ sal_Int64 mnPropertiesStart;
+ sal_Int64 mnPropertiesEnd;
+ sal_Int64 mnPropFlags;
+ sal_Int64 mnCurrProp;
+ bool mb64BitPropFlags;
+ bool mbValid;
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void AxPropertyObjectBase::alignInput()
+{
+ mxStrm->skip( (sizeof( Type ) - ((mxStrm->tell() - mnPropertiesStart) % sizeof( Type ))) % sizeof( Type ) );
+}
+
+template< typename Type >
+Type AxPropertyObjectBase::dumpDecProperty( Type nDefault, const NameListWrapper& rListWrp )
+{
+ if( startNextProperty() )
+ {
+ alignInput< Type >();
+ return dumpDec< Type >( getPropertyName(), rListWrp );
+ }
+ return nDefault;
+}
+
+template< typename Type >
+Type AxPropertyObjectBase::dumpHexProperty( Type nDefault, const NameListWrapper& rListWrp )
+{
+ if( startNextProperty() )
+ {
+ alignInput< Type >();
+ return dumpHex< Type >( getPropertyName(), rListWrp );
+ }
+ return nDefault;
+}
+
+// ============================================================================
+
+class AxCFontNewObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxCFontNewObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+};
+
+// ============================================================================
+
+class AxColumnInfoObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxColumnInfoObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+};
+
+// ============================================================================
+
+class AxCommandButtonObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxCommandButtonObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+ virtual void implDumpExtended();
+};
+
+// ============================================================================
+
+class AxMorphControlObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxMorphControlObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+ virtual void implDumpExtended();
+
+private:
+ void dumpColumnInfos();
+
+private:
+ sal_uInt16 mnColInfoCount;
+ sal_uInt8 mnCtrlType;
+};
+
+// ============================================================================
+
+class AxLabelObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxLabelObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+ virtual void implDumpExtended();
+};
+
+// ============================================================================
+
+class AxImageObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxImageObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+};
+
+// ============================================================================
+
+class AxScrollBarObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxScrollBarObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+};
+
+// ============================================================================
+
+class AxSpinButtonObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxSpinButtonObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+};
+
+// ============================================================================
+
+class AxTabStripObject : public AxPropertyObjectBase
+{
+public:
+ explicit AxTabStripObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+ virtual void implDumpExtended();
+
+private:
+ sal_Int32 mnTabFlagCount;
+};
+
+// ============================================================================
+// ============================================================================
+
+class FormControlStreamObject : public OleInputObjectBase
+{
+public:
+ explicit FormControlStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName,
+ const ::rtl::OUString* pProgId = 0 );
+ explicit FormControlStreamObject(
+ const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString* pProgId = 0 );
+
+protected:
+ virtual void implDump();
+
+private:
+ void constructFormCtrlStrmObj( const ::rtl::OUString* pProgId );
+
+private:
+ ::rtl::OUString maProgId;
+ bool mbReadGuid;
+};
+
+// ============================================================================
+// ============================================================================
+
+struct VbaFormSiteInfo
+{
+ ::rtl::OUString maProgId;
+ sal_Int32 mnId;
+ sal_uInt32 mnLength;
+ bool mbInStream;
+
+ inline explicit VbaFormSiteInfo() : mnId( 0 ), mnLength( 0 ), mbInStream( false ) {}
+};
+
+typedef ::std::vector< VbaFormSiteInfo > VbaFormSiteInfoVector;
+
+// ============================================================================
+
+struct VbaFormSharedData
+{
+ OUStringVector maClassInfoProgIds;
+ VbaFormSiteInfoVector maSiteInfos;
+};
+
+// ============================================================================
+
+class VbaFormClassInfoObject : public AxPropertyObjectBase
+{
+public:
+ explicit VbaFormClassInfoObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData );
+
+protected:
+ virtual void implDumpShortProperties();
+
+private:
+ VbaFormSharedData& mrFormData;
+};
+
+// ============================================================================
+
+class VbaFormSiteObject : public AxPropertyObjectBase
+{
+public:
+ explicit VbaFormSiteObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData );
+
+protected:
+ virtual void implDumpShortProperties();
+
+private:
+ VbaFormSharedData& mrFormData;
+};
+
+// ============================================================================
+
+class VbaFormDesignExtObject : public AxPropertyObjectBase
+{
+public:
+ explicit VbaFormDesignExtObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+};
+
+// ============================================================================
+
+class VbaFStreamObject : public AxPropertyObjectBase
+{
+public:
+ explicit VbaFStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName,
+ VbaFormSharedData& rFormData );
+
+protected:
+ virtual void implDumpShortProperties();
+ virtual void implDumpExtended();
+
+private:
+ void dumpClassInfos();
+ void dumpFormSites( sal_uInt32 nCount );
+ void dumpSiteData();
+ void dumpDesignExtender();
+
+private:
+ VbaFormSharedData& mrFormData;
+ sal_uInt32 mnFlags;
+};
+
+// ============================================================================
+
+class VbaOStreamObject : public OleInputObjectBase
+{
+public:
+ explicit VbaOStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName,
+ VbaFormSharedData& rFormData );
+
+protected:
+ virtual void implDump();
+
+private:
+ VbaFormSharedData& mrFormData;
+};
+
+// ============================================================================
+
+class VbaPageObject : public AxPropertyObjectBase
+{
+public:
+ explicit VbaPageObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+};
+
+// ============================================================================
+
+class VbaMultiPageObject : public AxPropertyObjectBase
+{
+public:
+ explicit VbaMultiPageObject( const InputObjectBase& rParent );
+
+protected:
+ virtual void implDumpShortProperties();
+ virtual void implDumpExtended();
+
+private:
+ sal_Int32 mnPageCount;
+};
+
+// ============================================================================
+
+class VbaXStreamObject : public InputObjectBase
+{
+public:
+ explicit VbaXStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName,
+ VbaFormSharedData& rFormData );
+
+protected:
+ virtual void implDump();
+
+private:
+ VbaFormSharedData& mrFormData;
+};
+
+// ============================================================================
+
+class VbaContainerStorageObject : public OleStorageObject
+{
+public:
+ explicit VbaContainerStorageObject(
+ const ObjectBase& rParent,
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rSysPath );
+
+protected:
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+
+ virtual void implDumpStorage(
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rSysPath );
+
+private:
+ bool isFormStorage( const ::rtl::OUString& rStrgPath ) const;
+
+private:
+ VbaFormSharedData maFormData;
+};
+
+// ============================================================================
+// ============================================================================
+
+struct VbaSharedData
+{
+ typedef ::std::map< ::rtl::OUString, sal_Int32 > StreamOffsetMap;
+
+ StreamOffsetMap maStrmOffsets;
+ rtl_TextEncoding meTextEnc;
+
+ explicit VbaSharedData();
+
+ bool isModuleStream( const ::rtl::OUString& rStrmName ) const;
+ sal_Int32 getStreamOffset( const ::rtl::OUString& rStrmName ) const;
+};
+
+// ============================================================================
+
+class VbaDirStreamObject : public SequenceRecordObjectBase
+{
+public:
+ explicit VbaDirStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName,
+ VbaSharedData& rVbaData );
+
+protected:
+ virtual bool implIsValid() const;
+ virtual bool implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize );
+ virtual void implDumpRecordBody();
+
+private:
+ ::rtl::OUString dumpByteString( const String& rName = EMPTY_STRING );
+ ::rtl::OUString dumpUniString( const String& rName = EMPTY_STRING );
+
+ ::rtl::OUString dumpByteStringWithLength( const String& rName = EMPTY_STRING );
+
+private:
+ VbaSharedData& mrVbaData;
+ BinaryInputStreamRef mxInStrm;
+ ::rtl::OUString maCurrStream;
+ sal_Int32 mnCurrOffset;
+};
+
+// ============================================================================
+
+class VbaModuleStreamObject : public InputObjectBase
+{
+public:
+ explicit VbaModuleStreamObject(
+ const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName,
+ VbaSharedData& rVbaData,
+ sal_Int32 nStrmOffset );
+
+protected:
+ virtual void implDump();
+
+private:
+ VbaSharedData& mrVbaData;
+ sal_Int32 mnStrmOffset;
+};
+
+// ============================================================================
+
+class VbaStorageObject : public OleStorageObject
+{
+public:
+ explicit VbaStorageObject(
+ const ObjectBase& rParent,
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rSysPath,
+ VbaSharedData& rVbaData );
+
+protected:
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+
+private:
+ VbaSharedData& mrVbaData;
+};
+
+// ============================================================================
+
+class VbaFormStorageObject : public VbaContainerStorageObject
+{
+public:
+ explicit VbaFormStorageObject(
+ const ObjectBase& rParent,
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rSysPath,
+ VbaSharedData& rVbaData );
+
+protected:
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+
+private:
+ VbaSharedData& mrVbaData;
+};
+
+// ============================================================================
+
+class VbaProjectStorageObject : public OleStorageObject
+{
+public:
+ explicit VbaProjectStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const ::rtl::OUString& rSysPath );
+
+protected:
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+
+ virtual void implDumpStorage(
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rSysPath );
+
+private:
+ VbaSharedData maVbaData;
+};
+
+// ============================================================================
+// ============================================================================
+
+class ActiveXStorageObject : public VbaContainerStorageObject
+{
+public:
+ explicit ActiveXStorageObject(
+ const ObjectBase& rParent,
+ const StorageRef& rxStrg,
+ const ::rtl::OUString& rSysPath );
+
+protected:
+ virtual void implDumpBaseStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rSysFileName );
+};
+
+// ============================================================================
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
+#endif
+
diff --git a/oox/inc/oox/dump/pptxdumper.hxx b/oox/inc/oox/dump/pptxdumper.hxx
new file mode 100644
index 000000000000..535c7ceadc36
--- /dev/null
+++ b/oox/inc/oox/dump/pptxdumper.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DUMP_PPTXDUMPER_HXX
+#define OOX_DUMP_PPTXDUMPER_HXX
+
+#include "oox/dump/dumperbase.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+namespace pptx {
+
+// ============================================================================
+
+class RootStorageObject : public StorageObjectBase
+{
+public:
+ explicit RootStorageObject( const DumperBase& rParent );
+
+protected:
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+};
+
+// ============================================================================
+
+class Dumper : public DumperBase
+{
+public:
+ explicit Dumper( const ::oox::core::FilterBase& rFilter );
+
+ explicit Dumper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
+ const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual void implDump();
+};
+
+// ============================================================================
+
+} // namespace pptx
+} // namespace dump
+} // namespace oox
+
+#endif
+#endif
+
diff --git a/oox/inc/oox/dump/xlsbdumper.hxx b/oox/inc/oox/dump/xlsbdumper.hxx
new file mode 100644
index 000000000000..6fa1c9bd7e45
--- /dev/null
+++ b/oox/inc/oox/dump/xlsbdumper.hxx
@@ -0,0 +1,258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DUMP_XLSBDUMPER_HXX
+#define OOX_DUMP_XLSBDUMPER_HXX
+
+#include "oox/dump/dumperbase.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox { namespace xls {
+ class FontPortionModelList;
+ class PhoneticPortionModelList;
+ struct FunctionInfo;
+ class FunctionProvider;
+} }
+
+namespace oox {
+namespace dump {
+namespace xlsb {
+
+// ============================================================================
+
+class RecordObjectBase : public SequenceRecordObjectBase
+{
+protected:
+ explicit RecordObjectBase();
+ virtual ~RecordObjectBase();
+
+ using SequenceRecordObjectBase::construct;
+ void construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+ void construct( const RecordObjectBase& rParent );
+
+ virtual bool implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize );
+
+ ::rtl::OUString getErrorName( sal_uInt8 nErrCode ) const;
+
+ // ------------------------------------------------------------------------
+
+ void readAddress( Address& orAddress );
+ void readRange( Range& orRange );
+ void readRangeList( RangeList& orRanges );
+
+ // ------------------------------------------------------------------------
+
+ void writeBooleanItem( const String& rName, sal_uInt8 nBool );
+ void writeErrorCodeItem( const String& rName, sal_uInt8 nErrCode );
+
+ void writeFontPortions( const ::oox::xls::FontPortionModelList& rPortions );
+ void writePhoneticPortions( const ::oox::xls::PhoneticPortionModelList& rPhonetics );
+
+ // ------------------------------------------------------------------------
+
+ sal_uInt8 dumpBoolean( const String& rName = EMPTY_STRING );
+ sal_uInt8 dumpErrorCode( const String& rName = EMPTY_STRING );
+ ::rtl::OUString dumpString( const String& rName = EMPTY_STRING, bool bRich = false, bool b32BitLen = true );
+ void dumpColor( const String& rName = EMPTY_STRING );
+ ::com::sun::star::util::DateTime dumpPivotDateTime( const String& rName = EMPTY_STRING );
+
+ sal_Int32 dumpColIndex( const String& rName = EMPTY_STRING );
+ sal_Int32 dumpRowIndex( const String& rName = EMPTY_STRING );
+ sal_Int32 dumpColRange( const String& rName = EMPTY_STRING );
+ sal_Int32 dumpRowRange( const String& rName = EMPTY_STRING );
+
+ Address dumpAddress( const String& rName = EMPTY_STRING );
+ Range dumpRange( const String& rName = EMPTY_STRING );
+ void dumpRangeList( const String& rName = EMPTY_STRING );
+
+ // ------------------------------------------------------------------------
+private:
+ bool readCompressedInt( BinaryInputStream& rStrm, sal_Int32& ornValue );
+
+private:
+ typedef ::boost::shared_ptr< SequenceInputStream > SequenceInputStreamRef;
+
+ SequenceInputStreamRef mxBiffStrm;
+ NameListRef mxErrCodes;
+};
+
+// ============================================================================
+
+class FormulaObject : public RecordObjectBase
+{
+public:
+ explicit FormulaObject( const RecordObjectBase& rParent );
+ virtual ~FormulaObject();
+
+ void dumpCellFormula( const String& rName = EMPTY_STRING );
+ void dumpNameFormula( const String& rName = EMPTY_STRING );
+
+protected:
+ virtual void implDump();
+
+private:
+ void constructFmlaObj();
+
+ void dumpFormula( const String& rName, bool bNameMode );
+
+ TokenAddress createTokenAddress( sal_Int32 nCol, sal_Int32 nRow, bool bRelC, bool bRelR, bool bNameMode ) const;
+ ::rtl::OUString createRef( const ::rtl::OUString& rData ) const;
+ ::rtl::OUString createName( sal_Int32 nNameId ) const;
+ ::rtl::OUString createPlaceHolder( size_t nIdx ) const;
+ ::rtl::OUString createPlaceHolder() const;
+
+ ::rtl::OUString writeFuncIdItem( sal_uInt16 nFuncId, const ::oox::xls::FunctionInfo** oppFuncInfo = 0 );
+
+ sal_Int32 dumpTokenCol( const String& rName, bool& rbRelC, bool& rbRelR );
+ sal_Int32 dumpTokenRow( const String& rName );
+ TokenAddress dumpTokenAddress( bool bNameMode );
+ TokenRange dumpTokenRange( bool bNameMode );
+
+ sal_Int16 readTokenRefId();
+ ::rtl::OUString dumpTokenRefId();
+
+ void dumpIntToken();
+ void dumpDoubleToken();
+ void dumpStringToken();
+ void dumpBoolToken();
+ void dumpErrorToken();
+ void dumpMissArgToken();
+
+ void dumpArrayToken( const ::rtl::OUString& rTokClass );
+ void dumpNameToken( const ::rtl::OUString& rTokClass );
+ void dumpNameXToken( const ::rtl::OUString& rTokClass );
+ void dumpRefToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpAreaToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpRefErrToken( const ::rtl::OUString& rTokClass, bool bArea );
+ void dumpRef3dToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpArea3dToken( const ::rtl::OUString& rTokClass, bool bNameMode );
+ void dumpRefErr3dToken( const ::rtl::OUString& rTokClass, bool bArea );
+ void dumpMemFuncToken( const ::rtl::OUString& rTokClass );
+ void dumpMemAreaToken( const ::rtl::OUString& rTokClass, bool bAddData );
+
+ void dumpExpToken( const String& rName );
+ void dumpUnaryOpToken( const String& rLOp, const String& rROp );
+ void dumpBinaryOpToken( const String& rOp );
+ void dumpFuncToken( const ::rtl::OUString& rTokClass );
+ void dumpFuncVarToken( const ::rtl::OUString& rTokClass );
+ bool dumpTableToken();
+ bool dumpAttrToken();
+
+ void dumpAddTokenData();
+ void dumpAddDataExp( size_t nIdx );
+ void dumpAddDataArray( size_t nIdx );
+ void dumpAddDataMemArea( size_t nIdx );
+
+ void dumpaddDataArrayHeader( sal_Int32& rnCols, sal_Int32& rnRows );
+ ::rtl::OUString dumpaddDataArrayValue();
+
+private:
+ enum AddDataType { ADDDATA_EXP, ADDDATA_ARRAY, ADDDATA_MEMAREA };
+
+ typedef ::boost::shared_ptr< FormulaStack > FormulaStackRef;
+ typedef ::boost::shared_ptr< ::oox::xls::FunctionProvider > FuncProvRef;
+ typedef ::std::vector< AddDataType > AddDataTypeVec;
+
+ NameListRef mxTokens;
+ NameListRef mxClasses;
+ NameListRef mxRelFlags;
+ NameListRef mxAttrTypes;
+ NameListRef mxSpTypes;
+ sal_Int32 mnColCount;
+ sal_Int32 mnRowCount;
+
+ FormulaStackRef mxStack;
+ FuncProvRef mxFuncProv;
+ AddDataTypeVec maAddData;
+ ::rtl::OUString maRefPrefix;
+ ::rtl::OUString maName;
+ sal_Int32 mnSize;
+ bool mbNameMode;
+};
+
+// ============================================================================
+
+class RecordStreamObject : public RecordObjectBase
+{
+public:
+ explicit RecordStreamObject( ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual bool implIsValid() const;
+ virtual void implDumpRecordBody();
+
+private:
+ void dumpGradientHead();
+ void dumpCellHeader( bool bWithColumn );
+
+private:
+ typedef ::boost::shared_ptr< FormulaObject > FormulaObjectRef;
+
+ FormulaObjectRef mxFmlaObj;
+};
+
+// ============================================================================
+
+class RootStorageObject : public StorageObjectBase
+{
+public:
+ explicit RootStorageObject( const DumperBase& rParent );
+
+protected:
+ virtual void implDumpStream(
+ const BinaryInputStreamRef& rxStrm,
+ const ::rtl::OUString& rStrgPath,
+ const ::rtl::OUString& rStrmName,
+ const ::rtl::OUString& rSysFileName );
+};
+
+// ============================================================================
+
+class Dumper : public DumperBase
+{
+public:
+ explicit Dumper( const ::oox::core::FilterBase& rFilter );
+
+ explicit Dumper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
+ const ::rtl::OUString& rSysFileName );
+
+protected:
+ virtual void implDump();
+};
+
+// ============================================================================
+
+} // namespace xlsb
+} // namespace dump
+} // namespace oox
+
+#endif
+#endif
+
diff --git a/oox/inc/oox/export/drawingml.hxx b/oox/inc/oox/export/drawingml.hxx
new file mode 100644
index 000000000000..0859b15136d9
--- /dev/null
+++ b/oox/inc/oox/export/drawingml.hxx
@@ -0,0 +1,115 @@
+#ifndef _OOX_EXPORT_DRAWINGML_HXX_
+#define _OOX_EXPORT_DRAWINGML_HXX_
+
+#include <oox/dllapi.h>
+#include <sax/fshelper.hxx>
+#include <rtl/strbuf.hxx>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/uno/XReference.hpp>
+#include <tools/poly.hxx>
+#include <svx/escherex.hxx>
+
+class Graphic;
+class String;
+
+namespace com { namespace sun { namespace star {
+namespace beans {
+ class XPropertySet;
+ class XPropertyState;
+}
+namespace drawing {
+ class XShape;
+}
+namespace text {
+ class XTextContent;
+ class XTextRange;
+}
+}}}
+
+namespace oox {
+namespace core {
+ class XmlFilterBase;
+}
+
+namespace drawingml {
+
+class OOX_DLLPUBLIC DrawingML {
+public:
+ enum DocumentType { DOCUMENT_DOCX, DOCUMENT_PPTX, DOCUMENT_XLSX };
+
+private:
+ ::sax_fastparser::FSHelperPtr mpFS;
+ ::oox::core::XmlFilterBase* mpFB;
+
+ static int mnImageCounter;
+
+ /// To specify where write eg. the images to (like 'ppt', or 'word' - according to the OPC).
+ DocumentType meDocumentType;
+
+protected:
+ ::com::sun::star::uno::Any mAny;
+
+ bool GetProperty( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, String aName );
+ bool GetPropertyAndState( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet,
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > rXPropState,
+ String aName, ::com::sun::star::beans::PropertyState& eState );
+ const char* GetFieldType( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun );
+
+ rtl::OUString WriteImage( const rtl::OUString& rURL );
+
+public:
+ DrawingML( ::sax_fastparser::FSHelperPtr pFS, ::oox::core::XmlFilterBase* pFB = NULL, DocumentType eDocumentType = DOCUMENT_PPTX ) : mpFS( pFS ), mpFB( pFB ), meDocumentType( eDocumentType ) {}
+ void SetFS( ::sax_fastparser::FSHelperPtr pFS ) { mpFS = pFS; }
+ ::sax_fastparser::FSHelperPtr GetFS() { return mpFS; }
+ ::oox::core::XmlFilterBase* GetFB() { return mpFB; }
+
+ rtl::OUString WriteImage( const Graphic &rGraphic );
+
+ void WriteColor( sal_uInt32 nColor );
+ void WriteGradientStop( sal_uInt16 nStop, sal_uInt32 nColor );
+ void WriteLineArrow( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, sal_Bool bLineStart );
+ void WriteConnectorConnections( EscherConnectorListEntry& rConnectorEntry, sal_Int32 nStartID, sal_Int32 nEndID );
+
+ void WriteSolidFill( sal_uInt32 nColor );
+ void WriteSolidFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet );
+ void WriteGradientFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet );
+ void WriteBlipFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, String sURLPropName, sal_Int32 nXmlNamespace );
+ void WriteBlipFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, String sURLPropName );
+ void WriteOutline( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet );
+ void WriteStretch();
+
+ ::rtl::OUString WriteBlip( ::rtl::OUString& rURL );
+ void WriteBlipMode( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet );
+
+ void WriteShapeTransformation( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > rXShape,
+ sal_Bool bFlipH = false, sal_Bool bFlipV = false, sal_Int32 nRotation = 0 );
+ void WriteTransformation( const Rectangle& rRectangle,
+ sal_Bool bFlipH = false, sal_Bool bFlipV = false, sal_Int32 nRotation = 0 );
+
+ void WriteText( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > rXShape );
+ void WriteParagraph( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > rParagraph );
+ void WriteParagraphProperties( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > rParagraph );
+ void WriteParagraphNumbering( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet,
+ sal_Int16 nLevel );
+ void WriteRun( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun );
+ void WriteRunProperties( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun );
+
+ void WritePresetShape( const char* pShape );
+ void WritePresetShape( const char* pShape, MSO_SPT eShapeType, sal_Bool bPredefinedHandlesUsed, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, const ::com::sun::star::beans::PropertyValue& rProp );
+ void WritePolyPolygon( const PolyPolygon& rPolyPolygon );
+
+ static void ResetCounters();
+
+ void GetUUID( ::rtl::OStringBuffer& rBuffer );
+
+ static sal_Unicode SubstituteBullet( sal_Unicode cBulletId, ::com::sun::star::awt::FontDescriptor& rFontDesc );
+
+ sal_uInt32 ColorWithIntensity( sal_uInt32 nColor, sal_uInt32 nIntensity );
+
+ static const char* GetAlignment( sal_Int32 nAlignment );
+};
+
+}
+}
+
+#endif
diff --git a/oox/inc/oox/export/shapes.hxx b/oox/inc/oox/export/shapes.hxx
new file mode 100644
index 000000000000..ed9cf5b32970
--- /dev/null
+++ b/oox/inc/oox/export/shapes.hxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _OOX_EXPORT_SHAPES_HXX_
+#define _OOX_EXPORT_SHAPES_HXX_
+
+#include <oox/dllapi.h>
+#include <com/sun/star/uno/XReference.hpp>
+#include <oox/export/drawingml.hxx>
+#include <sax/fshelper.hxx>
+#include <vcl/mapmod.hxx>
+#include <hash_map>
+
+namespace com { namespace sun { namespace star {
+namespace beans {
+ class XPropertySet;
+}
+namespace drawing {
+ class XShape;
+ class XShapes;
+}
+}}}
+
+namespace oox { namespace drawingml {
+
+class OOX_DLLPUBLIC ShapeExport : public DrawingML {
+private:
+ sal_Int32 mnXmlNamespace;
+ sal_Int32 mnShapeIdMax, mnPictureIdMax;
+ Fraction maFraction;
+ MapMode maMapModeSrc, maMapModeDest;
+
+ ::com::sun::star::awt::Size MapSize( const ::com::sun::star::awt::Size& ) const;
+
+ struct ShapeCheck
+ {
+ bool operator()( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape> s1, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape> s2 ) const
+ {
+ return s1 == s2;
+ }
+ };
+
+ struct ShapeHash
+ {
+ std::hash<const char*> maHashFunction;
+
+ size_t operator()( const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape > ) const;
+ };
+
+ typedef std::hash_map< const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>, sal_Int32, ShapeHash, ShapeCheck> ShapeHashMap;
+ ShapeHashMap maShapeMap;
+
+public:
+ ShapeExport( sal_Int32 nXmlNamespace, ::sax_fastparser::FSHelperPtr pFS, ::oox::core::XmlFilterBase* pFB = NULL, DocumentType eDocumentType = DOCUMENT_PPTX );
+ virtual ~ShapeExport() {}
+
+ sal_Int32 GetXmlNamespace() const;
+ ShapeExport& SetXmlNamespace( sal_Int32 nXmlNamespace );
+
+ static sal_Bool NonEmptyText( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+ virtual ShapeExport&
+ WriteBezierShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, sal_Bool bClosed );
+ virtual ShapeExport&
+ WriteClosedBezierShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteConnectorShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteCustomShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteEllipseShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet );
+ virtual ShapeExport&
+ WriteGraphicObjectShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteLineShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteNonVisualDrawingProperties( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, const char* sName );
+ virtual ShapeExport&
+ WriteNonVisualProperties( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteOpenBezierShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteRectangleShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+ /**
+ * Write the DrawingML for a particular shape.
+ *
+ * <p>This is the member function you want. It performs the type lookup and
+ * invokes the appropriate corresponding Write*() method for the specific
+ * type.</p>
+ *
+ * <p>To write an XShape, XShape::getShapeType() is called to determine
+ * the shape type, and the corresponding method in this table is
+ * invoked:</p>
+ *
+ * <table>
+ * <tr><th>Shape Type</th><th>Method</th></tr>
+ * <tr><td><tt>com.sun.star.drawing.ClosedBezierShape</tt></td> <td>ShapeExport::WriteClosedBezierShape</td></tr>
+ * <tr><td><tt>com.sun.star.drawing.CustomShape</tt></td> <td>ShapeExport::WriteCustomShape</td></tr>
+ * <tr><td><tt>com.sun.star.drawing.EllipseShape</tt></td> <td>ShapeExport::WriteEllipseShape</td></tr>
+ * <tr><td><tt>com.sun.star.drawing.GraphicObjectShape</tt></td> <td>ShapeExport::WriteGraphicObjectShape</td></tr>
+ * <tr><td><tt>com.sun.star.drawing.LineShape</tt></td> <td>ShapeExport::WriteLineShape</td></tr>
+ * <tr><td><tt>com.sun.star.drawing.OpenBezierShape</tt></td> <td>ShapeExport::WriteOpenBezierShape</td></tr>
+ * <tr><td><tt>com.sun.star.drawing.RectangleShape</tt></td> <td>ShapeExport::WriteRectangleShape</td></tr>
+ * <tr><td><tt>com.sun.star.drawing.TextShape</tt></td> <td>ShapeExport::WriteTextShape</td></tr>
+ * <tr><td><tt>com.sun.star.presentation.DateTimeShape</tt></td> <td>ShapeExport::WriteTextShape</td></tr>
+ * <tr><td><tt>com.sun.star.presentation.FooterShape</tt></td> <td>ShapeExport::WriteTextShape</td></tr>
+ * <tr><td><tt>com.sun.star.presentation.HeaderShape</tt></td> <td>ShapeExport::WriteTextShape</td></tr>
+ * <tr><td><tt>com.sun.star.presentation.NotesShape</tt></td> <td>ShapeExport::WriteTextShape</td></tr>
+ * <tr><td><tt>com.sun.star.presentation.OutlinerShape</tt></td> <td>ShapeExport::WriteTextShape</td></tr>
+ * <tr><td><tt>com.sun.star.presentation.SlideNumberShape</tt></td><td>ShapeExport::WriteTextShape</td></tr>
+ * <tr><td><tt>com.sun.star.presentation.TitleTextShape</tt></td> <td>ShapeExport::WriteTextShape</td></tr>
+ * </table>
+ *
+ * <p>If the shape type is not recognized, then
+ * <tt>ShapeExport::WriteUnknownShape</tt> is called.</p>
+ *
+ * @param xShape The shape to export as DrawingML.
+ * @return <tt>*this</tt>
+ */
+ virtual ShapeExport&
+ WriteShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteTextBox( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteTextShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+ virtual ShapeExport&
+ WriteUnknownShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
+
+ sal_Int32 GetNewShapeID( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > rShape );
+ sal_Int32 GetShapeID( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > rShape );
+};
+
+}}
+
+#endif /* ndef _OOX_EXPORT_SHAPES_HXX_ */
diff --git a/oox/inc/oox/export/utils.hxx b/oox/inc/oox/export/utils.hxx
new file mode 100644
index 000000000000..ab0d2d23ab9d
--- /dev/null
+++ b/oox/inc/oox/export/utils.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _OOX_EXPORT_UTILS_HXX_
+#define _OOX_EXPORT_UTILS_HXX_
+
+#define S(x) String( RTL_CONSTASCII_USTRINGPARAM( x ) )
+#define US(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ))
+#define I32S(x) OString::valueOf( (sal_Int32) x ).getStr()
+#define I64S(x) OString::valueOf( (sal_Int64) x ).getStr()
+#define H32S(x) OString::valueOf( (sal_Int32) x, 16 ).getStr()
+#define H64S(x) OString::valueOf( (sal_Int64) x, 16 ).getStr()
+#define IS(x) OString::valueOf( x ).getStr()
+#define USS(x) OUStringToOString( x, RTL_TEXTENCODING_UTF8 ).getStr()
+#define ST(x) ByteString( x, RTL_TEXTENCODING_UTF8 ).GetBuffer()
+
+#ifndef DBG
+# if OSL_DEBUG_LEVEL > 0
+# define DBG(x) x
+# else
+# define DBG(x)
+# endif
+#endif
+
+// ---------------------------------------------------------------------------------------------
+
+static inline sal_Int64 PPTtoEMU( INT32 nPPT )
+{
+ return (sal_Int64)( (double)nPPT * 1587.5 );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+static inline sal_Int64 MM100toEMU( INT32 nMM100 )
+{
+ return (sal_Int64)nMM100 * 360;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+static inline sal_Int64 TwipsToEMU( sal_Int32 nTwips )
+{
+ return sal_Int64( nTwips ) * 635;
+}
+
+#endif
diff --git a/oox/inc/oox/export/vmlexport.hxx b/oox/inc/oox/export/vmlexport.hxx
new file mode 100644
index 000000000000..544074b7b18a
--- /dev/null
+++ b/oox/inc/oox/export/vmlexport.hxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <oox/dllapi.h>
+#include <sax/fshelper.hxx>
+#include <svx/escherex.hxx>
+
+namespace rtl {
+ class OString;
+ class OStringBuffer;
+}
+
+namespace oox {
+
+namespace vml {
+
+class OOX_DLLPUBLIC VMLExport : public EscherEx
+{
+ /// Fast serializer to output the data
+ ::sax_fastparser::FSHelperPtr m_pSerializer;
+
+ /// Fill the shape attributes as they come.
+ ::sax_fastparser::FastAttributeList *m_pShapeAttrList;
+
+ /// Remember the shape type.
+ sal_uInt32 m_nShapeType;
+
+ /// Remember the shape flags.
+ sal_uInt32 m_nShapeFlags;
+
+ /// Remember style, the most important shape attribute ;-)
+ rtl::OStringBuffer *m_pShapeStyle;
+
+ /// Remember which shape types we had already written.
+ bool *m_pShapeTypeWritten;
+
+public:
+ VMLExport( ::sax_fastparser::FSHelperPtr pSerializer );
+ virtual ~VMLExport();
+
+ ::sax_fastparser::FSHelperPtr
+ GetFS() { return m_pSerializer; }
+
+ /// Export the sdr object as VML.
+ ///
+ /// Call this when you need to export the object as VML.
+ using EscherEx::AddSdrObject;
+
+protected:
+ /// Add an attribute to the generated <v:shape/> element.
+ ///
+ /// This should be called from within StartShape() to ensure that the
+ /// added attribute is preserved.
+ void AddShapeAttribute( sal_Int32 nAttribute, const rtl::OString& sValue );
+
+ /// Start the shape for which we just collected the information.
+ ///
+ /// Returns the element's tag number, -1 means we wrote nothing.
+ virtual sal_Int32 StartShape();
+
+ /// End the shape.
+ ///
+ /// The parameter is just what we got from StartShape().
+ virtual void EndShape( sal_Int32 nShapeElement );
+
+ virtual void Commit( EscherPropertyContainer& rProps, const Rectangle& rRect );
+
+private:
+
+ virtual void OpenContainer( UINT16 nEscherContainer, int nRecInstance = 0 );
+ virtual void CloseContainer();
+
+ virtual UINT32 EnterGroup( const String& rShapeName, const Rectangle* pBoundRect = 0 );
+ virtual void LeaveGroup();
+
+ virtual void AddShape( UINT32 nShapeType, UINT32 nShapeFlags, UINT32 nShapeId = 0 );
+
+private:
+ /// Create an OString representing the id from a numerical id.
+ static rtl::OString ShapeIdString( sal_uInt32 nId );
+
+ /// Add starting and ending point of a line to the m_pShapeAttrList.
+ void AddLineDimensions( const Rectangle& rRectangle );
+
+ /// Add position and size to the OStringBuffer.
+ void AddRectangleDimensions( rtl::OStringBuffer& rBuffer, const Rectangle& rRectangle );
+};
+
+} // namespace vml
+
+} // namespace oox
diff --git a/oox/inc/oox/helper/attributelist.hxx b/oox/inc/oox/helper/attributelist.hxx
new file mode 100644
index 000000000000..87e21e553c2d
--- /dev/null
+++ b/oox/inc/oox/helper/attributelist.hxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_ATTRIBUTELIST_HXX
+#define OOX_HELPER_ATTRIBUTELIST_HXX
+
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+#include "oox/helper/helper.hxx"
+#include "oox/token/namespaces.hxx"
+#include "oox/token/tokens.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+/** Static helpers for conversion of strings to attribute values of various
+ different data types.
+ */
+class AttributeConversion
+{
+public:
+ /** Returns the XML token identifier from the passed string. */
+ static sal_Int32 decodeToken( const ::rtl::OUString& rValue );
+
+ /** Returns the decoded string value. All characters in the format
+ '_xHHHH_' (H being a hexadecimal digit), will be decoded. */
+ static ::rtl::OUString decodeXString( const ::rtl::OUString& rValue );
+
+ /** Returns the double value from the passed string. */
+ static double decodeDouble( const ::rtl::OUString& rValue );
+
+ /** Returns the 32-bit signed integer value from the passed string (decimal). */
+ static sal_Int32 decodeInteger( const ::rtl::OUString& rValue );
+
+ /** Returns the 32-bit unsigned integer value from the passed string (decimal). */
+ static sal_uInt32 decodeUnsigned( const ::rtl::OUString& rValue );
+
+ /** Returns the 64-bit signed integer value from the passed string (decimal). */
+ static sal_Int64 decodeHyper( const ::rtl::OUString& rValue );
+
+ /** Returns the 32-bit signed integer value from the passed string (hexadecimal). */
+ static sal_Int32 decodeIntegerHex( const ::rtl::OUString& rValue );
+
+ /** Returns the 32-bit unsigned integer value from the passed string (hexadecimal). */
+ static sal_uInt32 decodeUnsignedHex( const ::rtl::OUString& rValue );
+
+ /** Returns the 64-bit signed integer value from the passed string (hexadecimal). */
+ static sal_Int64 decodeHyperHex( const ::rtl::OUString& rValue );
+};
+
+// ============================================================================
+
+/** Provides access to attribute values of an element.
+
+ Wraps a com.sun.star.xml.sax.XFastAttributeList object. Provides
+ convenience functions that convert the string value of an attribute to
+ various other data types.
+ */
+class AttributeList
+{
+public:
+ explicit AttributeList(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs );
+
+ /** Returns the wrapped com.sun.star.xml.sax.XFastAttributeList object. */
+ inline ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >
+ getFastAttributeList() const { return mxAttribs; }
+
+ /** Returns true, if the specified attribute is present. */
+ bool hasAttribute( sal_Int32 nAttrToken ) const;
+
+ // optional return values -------------------------------------------------
+
+ /** Returns the token identifier of the value of the specified attribute. */
+ OptValue< sal_Int32 > getToken( sal_Int32 nAttrToken ) const;
+
+ /** Returns the string value of the specified attribute. */
+ OptValue< ::rtl::OUString > getString( sal_Int32 nAttrToken ) const;
+
+ /** Returns the string value of the specified attribute. All characters in
+ the format '_xHHHH_' (H being a hexadecimal digit), will be decoded. */
+ OptValue< ::rtl::OUString > getXString( sal_Int32 nAttrToken ) const;
+
+ /** Returns the double value of the specified attribute. */
+ OptValue< double > getDouble( sal_Int32 nAttrToken ) const;
+
+ /** Returns the 32-bit signed integer value of the specified attribute (decimal). */
+ OptValue< sal_Int32 > getInteger( sal_Int32 nAttrToken ) const;
+
+ /** Returns the 32-bit unsigned integer value of the specified attribute (decimal). */
+ OptValue< sal_uInt32 > getUnsigned( sal_Int32 nAttrToken ) const;
+
+ /** Returns the 64-bit signed integer value of the specified attribute (decimal). */
+ OptValue< sal_Int64 > getHyper( sal_Int32 nAttrToken ) const;
+
+ /** Returns the 32-bit signed integer value of the specified attribute (hexadecimal). */
+ OptValue< sal_Int32 > getIntegerHex( sal_Int32 nAttrToken ) const;
+
+ /** Returns the 32-bit unsigned integer value of the specified attribute (hexadecimal). */
+ OptValue< sal_uInt32 > getUnsignedHex( sal_Int32 nAttrToken ) const;
+
+ /** Returns the 64-bit signed integer value of the specified attribute (hexadecimal). */
+ OptValue< sal_Int64 > getHyperHex( sal_Int32 nAttrToken ) const;
+
+ /** Returns the boolean value of the specified attribute. */
+ OptValue< bool > getBool( sal_Int32 nAttrToken ) const;
+
+ /** Returns the date/time value of the specified attribute. */
+ OptValue< ::com::sun::star::util::DateTime > getDateTime( sal_Int32 nAttrToken ) const;
+
+ // defaulted return values ------------------------------------------------
+
+ /** Returns the token identifier of the value of the specified attribute,
+ or the passed default identifier if the attribute is missing. */
+ sal_Int32 getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const;
+
+ /** Returns the string value of the specified attribute, or the passed
+ default string if the attribute is missing. */
+ ::rtl::OUString getString( sal_Int32 nAttrToken, const ::rtl::OUString& rDefault ) const;
+
+ /** Returns the decoded string value of the specified attribute, or the
+ passed default string if the attribute is missing. */
+ ::rtl::OUString getXString( sal_Int32 nAttrToken, const ::rtl::OUString& rDefault ) const;
+
+ /** Returns the double value of the specified attribute, or the passed
+ default value if the attribute is missing or not convertible to a double. */
+ double getDouble( sal_Int32 nAttrToken, double fDefault ) const;
+
+ /** Returns the 32-bit signed integer value of the specified attribute, or the
+ passed default value if the attribute is missing or not convertible to integer. */
+ sal_Int32 getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const;
+
+ /** Returns the 32-bit unsigned integer value of the specified attribute, or the
+ passed default value if the attribute is missing or not convertible to unsigned. */
+ sal_uInt32 getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const;
+
+ /** Returns the 64-bit signed integer value of the specified attribute, or the
+ passed default value if the attribute is missing or not convertible to integer. */
+ sal_Int64 getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const;
+
+ /** Returns the 32-bit signed integer value of the specified attribute (hexadecimal),
+ or the passed default value if the attribute is missing or not convertible. */
+ sal_Int32 getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const;
+
+ /** Returns the 32-bit unsigned integer value of the specified attribute (hexadecimal),
+ or the passed default value if the attribute is missing or not convertible. */
+ sal_uInt32 getUnsignedHex( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const;
+
+ /** Returns the 64-bit signed integer value of the specified attribute (hexadecimal),
+ or the passed default value if the attribute is missing or not convertible. */
+ sal_Int64 getHyperHex( sal_Int32 nAttrToken, sal_Int64 nDefault ) const;
+
+ /** Returns the boolean value of the specified attribute, or the passed
+ default value if the attribute is missing or not convertible to bool. */
+ bool getBool( sal_Int32 nAttrToken, bool bDefault ) const;
+
+ /** Returns the date/time value of the specified attribute, or the default
+ value if the attribute is missing or not convertible to a date/time value. */
+ ::com::sun::star::util::DateTime getDateTime( sal_Int32 nAttrToken, const ::com::sun::star::util::DateTime& rDefault ) const;
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >
+ mxAttribs;
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/binaryinputstream.hxx b/oox/inc/oox/helper/binaryinputstream.hxx
new file mode 100644
index 000000000000..52a3a4de9f0f
--- /dev/null
+++ b/oox/inc/oox/helper/binaryinputstream.hxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_BINARYINPUTSTREAM_HXX
+#define OOX_HELPER_BINARYINPUTSTREAM_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include "oox/helper/binarystreambase.hxx"
+
+namespace oox {
+
+class BinaryOutputStream;
+
+// ============================================================================
+
+/** Interface for binary input stream classes.
+
+ The binary data in the stream is assumed to be in little-endian format.
+ */
+class BinaryInputStream : public virtual BinaryStreamBase
+{
+public:
+ /** Derived classes implement reading nBytes bytes to the passed sequence.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes ) = 0;
+ /** Derived classes implement reading nBytes bytes to the (existing) buffer opMem.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes ) = 0;
+ /** Derived classes implement seeking the stream forward by the passed
+ number of bytes. This should work for non-seekable streams too. */
+ virtual void skip( sal_Int32 nBytes ) = 0;
+
+ /** Reads a value from the stream and converts it to platform byte order.
+ Supported types: SAL integers (8 to 64 bit), float, double. */
+ template< typename Type >
+ void readValue( Type& ornValue );
+ /** Reads a value from the stream and converts it to platform byte order.
+ Supported types: SAL integers (8 to 64 bit), float, double. */
+ template< typename Type >
+ inline Type readValue() { Type nValue; readValue( nValue ); return nValue; }
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline BinaryInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
+
+ inline sal_Int8 readInt8() { return readValue< sal_Int8 >(); }
+ inline sal_uInt8 readuInt8() { return readValue< sal_uInt8 >(); }
+ inline sal_Int16 readInt16() { return readValue< sal_Int16 >(); }
+ inline sal_uInt16 readuInt16() { return readValue< sal_uInt16 >(); }
+ inline sal_Int32 readInt32() { return readValue< sal_Int32 >(); }
+ inline sal_uInt32 readuInt32() { return readValue< sal_uInt32 >(); }
+ inline sal_Int64 readInt64() { return readValue< sal_Int64 >(); }
+ inline sal_uInt64 readuInt64() { return readValue< sal_uInt64 >(); }
+ inline float readFloat() { return readValue< float >(); }
+ inline double readDouble() { return readValue< double >(); }
+
+ /** Reads a NUL-terminated byte character array and returns the string. */
+ ::rtl::OString readNulCharArray();
+
+ /** Reads a NUL-terminated byte character array and returns a Unicode string.
+ @param eTextEnc The text encoding used to create the Unicode string. */
+ ::rtl::OUString readNulCharArrayUC( rtl_TextEncoding eTextEnc );
+
+ /** Reads a NUL-terminated Unicode character array and returns the string. */
+ ::rtl::OUString readNulUnicodeArray();
+
+ /** Reads nChar byte characters and returns the string.
+ @param nChars Number of characters (bytes) to read from the stream.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default). */
+ ::rtl::OString readCharArray( sal_Int32 nChars, bool bAllowNulChars = false );
+
+ /** Reads nChar byte characters and returns a Unicode string.
+ @param nChars Number of characters (bytes) to read from the stream.
+ @param eTextEnc The text encoding used to create the Unicode string.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default). */
+ ::rtl::OUString readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars = false );
+
+ /** Reads nChars Unicode characters and returns the string.
+ @param nChars Number of 16-bit characters to read from the stream.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default). */
+ ::rtl::OUString readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars = false );
+
+ /** Copies nBytes bytes from the current position to the passed output stream. */
+ void copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes = SAL_MAX_INT64 );
+
+private:
+ /** Used by the readValue() template functions to read built-in types.
+ @descr Derived classes may overwrite this default implementation which
+ simply calls readMemory() with something own. */
+ virtual void readAtom( void* opMem, sal_uInt8 nSize );
+};
+
+typedef ::boost::shared_ptr< BinaryInputStream > BinaryInputStreamRef;
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void BinaryInputStream::readValue( Type& ornValue )
+{
+ // can be instanciated for all types supported in class ByteOrderConverter
+ readAtom( &ornValue, static_cast< sal_Int32 >( sizeof( Type ) ) );
+ ByteOrderConverter::convertLittleEndian( ornValue );
+}
+
+// ============================================================================
+
+/** Wraps a com.sun.star.io.XInputStream and provides convenient access functions.
+
+ The binary data in the stream is assumed to be in little-endian format.
+ */
+class BinaryXInputStream : public BinaryXSeekableStream, public BinaryInputStream
+{
+public:
+ /** Constructs the wrapper object for the passed input stream.
+
+ @param rxInStream The com.sun.star.io.XInputStream interface of the
+ input stream to be wrapped.
+ @param bAutoClose True = automatically close the wrapped input stream
+ on destruction of this wrapper.
+ */
+ explicit BinaryXInputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
+ bool bAutoClose );
+
+ virtual ~BinaryXInputStream();
+
+ /** Reads nBytes bytes to the passed sequence.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes );
+ /** Reads nBytes bytes to the (existing) buffer opMem.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes );
+ /** Seeks the stream forward by the passed number of bytes. This works for
+ non-seekable streams too. */
+ virtual void skip( sal_Int32 nBytes );
+
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline BinaryXInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
+
+ /** Returns the XInputStream interface of the wrapped input stream. */
+ inline ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ getXInputStream() const { return mxInStrm; }
+ /** Closes the wrapped XInputStream. */
+ void close();
+
+private:
+ StreamDataSequence maBuffer; /// Data buffer used in readMemory() function.
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ mxInStrm; /// Reference to the input stream.
+ bool mbAutoClose; /// True = automatically close stream on destruction.
+};
+
+typedef ::boost::shared_ptr< BinaryXInputStream > BinaryXInputStreamRef;
+
+// ============================================================================
+
+/** Wraps a StreamDataSequence and provides convenient access functions.
+
+ The binary data in the stream is assumed to be in little-endian format.
+ */
+class SequenceInputStream : public SequenceSeekableStream, public BinaryInputStream
+{
+public:
+ /** Constructs the wrapper object for the passed data sequence.
+
+ @attention
+ The passed data sequence MUST live at least as long as this stream
+ wrapper. The data sequence MUST NOT be changed from outside as long
+ as this stream wrapper is used to read from it.
+ */
+ explicit SequenceInputStream( const StreamDataSequence& rData );
+
+ /** Reads nBytes bytes to the passed sequence.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes );
+ /** Reads nBytes bytes to the (existing) buffer opMem.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes );
+ /** Seeks the stream forward by the passed number of bytes. This works for
+ non-seekable streams too. */
+ virtual void skip( sal_Int32 nBytes );
+
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline SequenceInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
+};
+
+typedef ::boost::shared_ptr< SequenceInputStream > SequenceInputStreamRef;
+
+// ============================================================================
+
+/** Wraps a BinaryInputStream and provides access to a specific part of the
+ stream data.
+
+ @descr
+ Provides access to the stream data block starting at the current
+ position of the stream, and with a specific length. If the wrapped
+ stream is seekable, this wrapper will treat the position the wrapped
+ has at construction time as position "0" (therefore the class name).
+ */
+class RelativeInputStream : public BinaryInputStream
+{
+public:
+ /** Constructs the wrapper object for the passed stream.
+
+ @attention
+ The passed input stream MUST live at least as long as this stream
+ wrapper. The stream MUST NOT be changed from outside as long as
+ this stream wrapper is used to read from it.
+
+ @param nLength
+ If specified, restricts the amount of data that can be read from
+ the passed input stream.
+ */
+ explicit RelativeInputStream(
+ BinaryInputStream& rInStrm,
+ sal_Int64 nLength = SAL_MAX_INT64 );
+
+ /** Returns whether the wrapped stream is seekable. */
+ virtual bool isSeekable() const;
+ /** Returns the size of the data block in the wrapped stream offered by
+ this wrapper. */
+ virtual sal_Int64 getLength() const;
+ /** Returns the current relative stream position. */
+ virtual sal_Int64 tell() const;
+ /** Seeks the stream to the passed relative position, if the wrapped stream
+ is seekable. */
+ virtual void seek( sal_Int64 nPos );
+
+ /** Reads nBytes bytes to the passed sequence. Does not read out of the
+ data block whose size has been specified on construction.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes );
+ /** Reads nBytes bytes to the (existing) buffer opMem. Does not read out of
+ the data block whose size has been specified on construction.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes );
+ /** Seeks the stream forward by the passed number of bytes. This works for
+ non-seekable streams too. Does not seek out of the data block. */
+ virtual void skip( sal_Int32 nBytes );
+
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline RelativeInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
+
+private:
+ BinaryInputStream& mrInStrm;
+ sal_Int64 mnStartPos;
+ sal_Int64 mnRelPos;
+ sal_Int64 mnLength;
+};
+
+typedef ::boost::shared_ptr< RelativeInputStream > RelativeInputStreamRef;
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/binaryoutputstream.hxx b/oox/inc/oox/helper/binaryoutputstream.hxx
new file mode 100644
index 000000000000..e24777c4f296
--- /dev/null
+++ b/oox/inc/oox/helper/binaryoutputstream.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_BINARYOUTPUTSTREAM_HXX
+#define OOX_HELPER_BINARYOUTPUTSTREAM_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include "oox/helper/binarystreambase.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+/** Interface for binary output stream classes.
+
+ The binary data in the stream is written in little-endian format.
+ */
+class BinaryOutputStream : public virtual BinaryStreamBase
+{
+public:
+ /** Derived classes implement writing the passed data sequence. */
+ virtual void writeData( const StreamDataSequence& rData ) = 0;
+ /** Derived classes implement writing from the (existing) buffer pMem. */
+ virtual void writeMemory( const void* pMem, sal_Int32 nBytes ) = 0;
+
+ /** Writes a value to the stream and converts it to platform byte order.
+ Supported types: SAL integers (8 to 64 bit), float, double. */
+ template< typename Type >
+ void writeValue( Type nValue );
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline BinaryOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }
+
+private:
+ /** Used by the writeValue() template function to write built-in types.
+ @descr Derived classes may overwrite this default implementation which
+ simply calls writeMemory() with something own. */
+ virtual void writeAtom( const void* pMem, sal_uInt8 nSize );
+};
+
+typedef ::boost::shared_ptr< BinaryOutputStream > BinaryOutputStreamRef;
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void BinaryOutputStream::writeValue( Type nValue )
+{
+ // can be instanciated for all types supported in class ByteOrderConverter
+ ByteOrderConverter::convertLittleEndian( nValue );
+ writeMemory( &nValue, static_cast< sal_Int32 >( sizeof( Type ) ) );
+}
+
+// ============================================================================
+
+/** Wraps a com.sun.star.io.XOutputStream and provides convenient access functions.
+
+ The binary data in the stream is written in little-endian format.
+ */
+class BinaryXOutputStream : public BinaryXSeekableStream, public BinaryOutputStream
+{
+public:
+ /** Constructs the wrapper object for the passed output stream.
+
+ @param rxOutStream The com.sun.star.io.XOutputStream interface of the
+ output stream to be wrapped.
+ @param bAutoClose True = automatically close the wrapped output stream
+ on destruction of this wrapper.
+ */
+ explicit BinaryXOutputStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rxOutStrm,
+ bool bAutoClose );
+
+ virtual ~BinaryXOutputStream();
+
+ /** Writes the passed data sequence. */
+ virtual void writeData( const StreamDataSequence& rData );
+ /** Write nBytes bytes from the (existing) buffer pMem. */
+ virtual void writeMemory( const void* pMem, sal_Int32 nBytes );
+
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline BinaryXOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }
+
+ /** Returns the XOutputStream interface of the wrapped output stream. */
+ inline ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ getXOutputStream() const { return mxOutStrm; }
+ /** Flushes and closes the wrapped XOutputStream. */
+ void close();
+
+private:
+ StreamDataSequence maBuffer; /// Data buffer used in writeMemory() function.
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ mxOutStrm; /// Reference to the output stream.
+ bool mbAutoClose; /// True = automatically close stream on destruction.
+};
+
+typedef ::boost::shared_ptr< BinaryXOutputStream > BinaryXOutputStreamRef;
+
+// ============================================================================
+
+/** Wraps a StreamDataSequence and provides convenient access functions.
+
+ The binary data in the stream is written in little-endian format. After
+ construction, the stream points to the beginning of the passed data
+ sequence. The data sequence is expanded automatically while writing to it.
+ */
+class SequenceOutputStream : public SequenceSeekableStream, public BinaryOutputStream
+{
+public:
+ /** Constructs the wrapper object for the passed data sequence.
+
+ @attention
+ The passed data sequence MUST live at least as long as this stream
+ wrapper. The data sequence MUST NOT be changed from outside as long
+ as this stream wrapper is used to write to it.
+ */
+ explicit SequenceOutputStream( StreamDataSequence& rData );
+
+ /** Writes the passed data sequence. */
+ virtual void writeData( const StreamDataSequence& rData );
+ /** Write nBytes bytes from the (existing) buffer pMem. */
+ virtual void writeMemory( const void* pMem, sal_Int32 nBytes );
+
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline SequenceOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }
+};
+
+typedef ::boost::shared_ptr< SequenceOutputStream > SequenceOutputStreamRef;
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/binarystreambase.hxx b/oox/inc/oox/helper/binarystreambase.hxx
new file mode 100644
index 000000000000..ba0f34b21f40
--- /dev/null
+++ b/oox/inc/oox/helper/binarystreambase.hxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_BINARYSTREAMBASE_HXX
+#define OOX_HELPER_BINARYSTREAMBASE_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/io/XSeekable.hpp>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+
+typedef ::com::sun::star::uno::Sequence< sal_Int8 > StreamDataSequence;
+
+// ============================================================================
+
+/** Base interface for binary stream classes. Implemenetations may or may not
+ support seeking the stream. */
+class BinaryStreamBase
+{
+public:
+ virtual ~BinaryStreamBase();
+
+ /** Derived classes return whether the stream is seekable. Default: false. */
+ virtual bool isSeekable() const;
+ /** Derived classes return the size of the stream, if possible,
+ otherwise/default: -1. May return something for unseekable streams. */
+ virtual sal_Int64 getLength() const;
+ /** Derived classes return the current stream position, if possible,
+ otherwise/default: -1. May return something for unseekable streams. */
+ virtual sal_Int64 tell() const;
+ /** Derived classes implement seeking the stream to the passed position, if
+ the stream is seekable. */
+ virtual void seek( sal_Int64 nPos );
+
+ /** Returns true, if the stream position is invalid (EOF). This flag turns
+ true *after* the first attempt to seek/read beyond the stream end. */
+ inline bool isEof() const { return mbEof; }
+
+ /** Returns the size of the remaining data, if stream is seekable, otherwise -1. */
+ sal_Int64 getRemaining() const;
+ /** Seeks the stream to the beginning, if stream is seekable. */
+ inline void seekToStart() { seek( 0 ); }
+ /** Seeks the stream to the end, if stream is seekable. */
+ inline void seekToEnd() { seek( getLength() ); }
+ /** Seeks the stream forward to a position that is a multiple of the passed
+ block size, relative to the passed stream position, if stream is seekable. */
+ void alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos = 0 );
+
+protected:
+ inline explicit BinaryStreamBase() : mbEof( false ) {}
+
+private:
+ BinaryStreamBase( const BinaryStreamBase& );
+ BinaryStreamBase& operator=( const BinaryStreamBase& );
+
+protected:
+ bool mbEof;
+};
+
+// ============================================================================
+
+/** Base class for binary input and output streams wrapping an API stream,
+ seekable via the com.sun.star.io.XSeekable interface.
+ */
+class BinaryXSeekableStream : public virtual BinaryStreamBase
+{
+public:
+ /** Returns true, if the wrapped stream is seekable. */
+ virtual bool isSeekable() const;
+ /** Returns the size of the stream, if stream is seekable, otherwise -1. */
+ virtual sal_Int64 getLength() const;
+ /** Returns the current stream position, if stream is seekable, otherwise -1. */
+ virtual sal_Int64 tell() const;
+ /** Seeks the stream to the passed position, if stream is seekable. */
+ virtual void seek( sal_Int64 nPos );
+
+protected:
+ explicit BinaryXSeekableStream(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable >& rxSeekable );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable >
+ mxSeekable; /// Stream seeking interface.
+};
+
+// ============================================================================
+
+/** Base class for binary input and output streams wrapping a
+ StreamDataSequence, which is always seekable. */
+class SequenceSeekableStream : public virtual BinaryStreamBase
+{
+public:
+ /** Returns true (data sequence streams are always seekable). */
+ virtual bool isSeekable() const;
+ /** Returns the size of the wrapped data sequence. */
+ virtual sal_Int64 getLength() const;
+ /** Returns the current stream position. */
+ virtual sal_Int64 tell() const;
+ /** Seeks the stream to the passed position. */
+ virtual void seek( sal_Int64 nPos );
+
+protected:
+ /** Constructs the wrapper object for the passed data sequence.
+
+ @attention
+ The passed data sequence MUST live at least as long as this stream
+ wrapper. The data sequence MUST NOT be changed from outside as long
+ as this stream wrapper is used to modify it.
+ */
+ inline explicit SequenceSeekableStream( const StreamDataSequence& rData ) : mrData( rData ), mnPos( 0 ) {}
+
+protected:
+ const StreamDataSequence& mrData; /// Wrapped data sequence.
+ sal_Int32 mnPos; /// Current position in the sequence.
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/containerhelper.hxx b/oox/inc/oox/helper/containerhelper.hxx
new file mode 100644
index 000000000000..96b9feeffe07
--- /dev/null
+++ b/oox/inc/oox/helper/containerhelper.hxx
@@ -0,0 +1,399 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_CONTAINERHELPER_HXX
+#define OOX_HELPER_CONTAINERHELPER_HXX
+
+#include <vector>
+#include <map>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Sequence.h>
+
+namespace rtl { class OUString; }
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XIndexAccess; }
+ namespace container { class XIndexContainer; }
+ namespace container { class XNameAccess; }
+ namespace container { class XNameContainer; }
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace oox {
+
+// ============================================================================
+
+/** Template for a 2-dimensional array of objects.
+
+ This class template provides a similar interface to the ::std::vector
+ template.
+ */
+template< typename Type >
+class Matrix
+{
+public:
+ typedef ::std::vector< Type > container_type;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::pointer pointer;
+ typedef typename container_type::reference reference;
+ typedef typename container_type::const_reference const_reference;
+ typedef typename container_type::size_type size_type;
+ typedef typename container_type::iterator iterator;
+ typedef typename container_type::const_iterator const_iterator;
+
+ inline explicit Matrix() : mnWidth( 0 ) {}
+ inline explicit Matrix( size_type nWidth, size_type nHeight ) { this->resize( nWidth, nHeight ); }
+ inline explicit Matrix( size_type nWidth, size_type nHeight, const_reference rData ) { this->resize( nWidth, nHeight, rData ); }
+
+ inline size_type capacity() const { return maData.capacity(); }
+ inline bool empty() const { return maData.empty(); }
+ inline size_type size() const { return maData.size(); }
+ inline size_type width() const { return mnWidth; }
+ inline size_type height() const { return this->empty() ? 0 : (this->size() / this->width()); }
+ inline bool has( size_type nX, size_type nY ) const { return (nX < this->width()) && (nY < this->height()); }
+
+ inline void reserve( size_type nWidth, size_type nHeight ) { maData.reserve( nWidth * nHeight ); }
+ inline void clear() { this->resize( 0, 0 ); }
+ inline void resize( size_type nWidth, size_type nHeight ) { mnWidth = nWidth; maData.resize( nWidth * nHeight ); }
+ inline void resize( size_type nWidth, size_type nHeight, const_reference rData ) { mnWidth = nWidth; maData.resize( nWidth * nHeight, rData ); }
+
+ inline iterator at( size_type nX, size_type nY ) { return maData.begin() + mnWidth * nY + nX; }
+ inline const_iterator at( size_type nX, size_type nY ) const { return maData.begin() + mnWidth * nY + nX; }
+
+ inline reference operator()( size_type nX, size_type nY ) { return *this->at( nX, nY ); }
+ inline const_reference operator()( size_type nX, size_type nY ) const { return *this->at( nX, nY ); }
+
+ inline iterator begin() { return maData.begin(); }
+ inline const_iterator begin() const { return maData.begin(); }
+ inline iterator end() { return maData.end(); }
+ inline const_iterator end() const { return maData.end(); }
+
+ inline reference front() { return maData.front(); }
+ inline const_reference front() const { return maData.front(); }
+ inline reference back() { return maData.back(); }
+ inline const_reference back() const { return maData.back(); }
+
+ inline iterator row_begin( size_type nY ) { return this->at( 0, nY ); }
+ inline const_iterator row_begin( size_type nY ) const { return this->at( 0, nY ); }
+ inline iterator row_end( size_type nY ) { return this->at( mnWidth, nY ); }
+ inline const_iterator row_end( size_type nY ) const { return this->at( mnWidth, nY ); }
+
+ inline reference row_front( size_type nY ) { return (*this)( 0, nY ); }
+ inline const_reference row_front( size_type nY ) const { return (*this)( 0, nY ); }
+ inline reference row_back( size_type nY ) { return (*this)( mnWidth - 1, nY ); }
+ inline const_reference row_back( size_type nY ) const { return (*this)( mnWidth - 1, nY ); }
+
+ inline void swap( Matrix& rMatrix ) { maData.swap( rMatrix.maData ); }
+
+private:
+ container_type maData;
+ size_type mnWidth;
+};
+
+// ============================================================================
+
+/** Static helper functions for improved API container handling. */
+class ContainerHelper
+{
+public:
+ // com.sun.star.container.XIndexContainer ---------------------------------
+
+ /** Creates a new index container object from scratch. */
+ static ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >
+ createIndexContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
+
+ /** Inserts an object into an indexed container.
+
+ @param rxIndexContainer com.sun.star.container.XIndexContainer
+ interface of the indexed container.
+
+ @param nIndex Insertion index for the object.
+
+ @param rObject The object to be inserted.
+
+ @return True = object successfully inserted.
+ */
+ static bool insertByIndex(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >& rxIndexContainer,
+ sal_Int32 nIndex,
+ const ::com::sun::star::uno::Any& rObject );
+
+ // com.sun.star.container.XNameContainer ----------------------------------
+
+ /** Creates a new name container object from scratch. */
+ static ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ createNameContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
+
+ /** Returns a name that is not used in the passed name container.
+
+ @param rxNameAccess com.sun.star.container.XNameAccess interface of
+ the name container.
+
+ @param rSuggestedName Suggested name for the object.
+
+ @return An unused name. Will be equal to the suggested name, if not
+ contained, otherwise a numerical index will be appended.
+ */
+ static ::rtl::OUString getUnusedName(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxNameAccess,
+ const ::rtl::OUString& rSuggestedName,
+ sal_Unicode cSeparator,
+ sal_Int32 nFirstIndexToAppend = 1 );
+
+ /** Inserts an object into a name container.
+
+ @param rxNameContainer com.sun.star.container.XNameContainer interface
+ of the name container.
+
+ @param rName Exact name for the object.
+
+ @param rObject The object to be inserted.
+
+ @return True = object successfully inserted.
+ */
+ static bool insertByName(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxNameContainer,
+ const ::rtl::OUString& rName,
+ const ::com::sun::star::uno::Any& rObject,
+ bool bReplaceOldExisting = true );
+
+ /** Inserts an object into a name container.
+
+ The function will use an unused name to insert the object, based on the
+ suggested object name. It is possible to specify whether the existing
+ object or the new inserted object will be renamed, if the container
+ already has an object with the name suggested for the new object.
+
+ @param rxNameContainer com.sun.star.container.XNameContainer interface
+ of the name container.
+
+ @param rSuggestedName Suggested name for the object.
+
+ @param rObject The object to be inserted.
+
+ @param bRenameOldExisting Specifies behaviour if an object with the
+ suggested name already exists. If false (default), the new object
+ will be inserted with a name not yet extant in the container (this
+ is done by appending a numerical index to the suggested name). If
+ true, the existing object will be removed and inserted with an
+ unused name, and the new object will be inserted with the suggested
+ name.
+
+ @return The final name the object is inserted with. Will always be
+ equal to the suggested name, if parameter bRenameOldExisting is
+ true.
+ */
+ static ::rtl::OUString insertByUnusedName(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxNameContainer,
+ const ::rtl::OUString& rSuggestedName,
+ sal_Unicode cSeparator,
+ const ::com::sun::star::uno::Any& rObject,
+ bool bRenameOldExisting = false );
+
+ // std::vector and std::map element access --------------------------------
+
+ /** Returns the pointer to an existing element of the passed vector, or a
+ null pointer, if the passed index is out of bounds. */
+ template< typename VectorType >
+ static const typename VectorType::value_type*
+ getVectorElement( const VectorType& rVector, sal_Int32 nIndex );
+
+ /** Returns the pointer to an existing element of the passed vector, or a
+ null pointer, if the passed index is out of bounds. */
+ template< typename VectorType >
+ static typename VectorType::value_type*
+ getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex );
+
+ /** Returns the reference to an existing element of the passed vector, or
+ the passed default value, if the passed index is out of bounds. */
+ template< typename VectorType >
+ static const typename VectorType::value_type&
+ getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault );
+
+ /** Returns the reference to an existing element of the passed vector, or
+ the passed default value, if the passed index is out of bounds. */
+ template< typename VectorType >
+ static typename VectorType::value_type&
+ getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex, typename VectorType::value_type& rDefault );
+
+ /** Returns the pointer to an existing element of the passed map, or a null
+ pointer, if an element with the passed key does not exist. */
+ template< typename MapType >
+ static const typename MapType::mapped_type*
+ getMapElement( const MapType& rMap, const typename MapType::key_type& rKey );
+
+ /** Returns the pointer to an existing element of the passed map, or a null
+ pointer, if an element with the passed key does not exist. */
+ template< typename MapType >
+ static typename MapType::mapped_type*
+ getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey );
+
+ /** Returns the reference to an existing element of the passed map, or the
+ passed default value, if an element with the passed key does not exist. */
+ template< typename MapType >
+ static const typename MapType::mapped_type&
+ getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault );
+
+ /** Returns the reference to an existing element of the passed map, or the
+ passed default value, if an element with the passed key does not exist. */
+ template< typename MapType >
+ static typename MapType::mapped_type&
+ getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey, typename MapType::mapped_type& rDefault );
+
+ // vector/map/matrix to UNO sequence --------------------------------------
+
+ /** Creates a UNO sequence from a std::vector with copies of all elements.
+
+ @param rVector The vector to be converted to a sequence.
+
+ @return A com.sun.star.uno.Sequence object with copies of all objects
+ contained in the passed vector.
+ */
+ template< typename VectorType >
+ static ::com::sun::star::uno::Sequence< typename VectorType::value_type >
+ vectorToSequence( const VectorType& rVector );
+
+ /** Creates a UNO sequence from a std::map with copies of all elements.
+
+ @param rMap The map to be converted to a sequence.
+
+ @return A com.sun.star.uno.Sequence object with copies of all objects
+ contained in the passed map.
+ */
+ template< typename MapType >
+ static ::com::sun::star::uno::Sequence< typename MapType::mapped_type >
+ mapToSequence( const MapType& rMap );
+
+ /** Creates a UNO sequence of sequences from a matrix with copies of all elements.
+
+ @param rMatrix The matrix to be converted to a sequence of sequences.
+
+ @return A com.sun.star.uno.Sequence object containing
+ com.sun.star.uno.Sequence objects with copies of all objects
+ contained in the passed matrix.
+ */
+ template< typename MatrixType >
+ static ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< typename MatrixType::value_type > >
+ matrixToSequenceSequence( const MatrixType& rMatrix );
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename VectorType >
+/*static*/ const typename VectorType::value_type* ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex )
+{
+ return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : 0;
+}
+
+template< typename VectorType >
+/*static*/ typename VectorType::value_type* ContainerHelper::getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex )
+{
+ return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : 0;
+}
+
+template< typename VectorType >
+/*static*/ const typename VectorType::value_type& ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault )
+{
+ return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? rVector[ static_cast< size_t >( nIndex ) ] : rDefault;
+}
+
+template< typename VectorType >
+/*static*/ typename VectorType::value_type& ContainerHelper::getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex, typename VectorType::value_type& rDefault )
+{
+ return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? rVector[ static_cast< size_t >( nIndex ) ] : rDefault;
+}
+
+template< typename MapType >
+/*static*/ const typename MapType::mapped_type* ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey )
+{
+ typename MapType::const_iterator aIt = rMap.find( rKey );
+ return (aIt == rMap.end()) ? 0 : &aIt->second;
+}
+
+template< typename MapType >
+/*static*/ typename MapType::mapped_type* ContainerHelper::getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey )
+{
+ typename MapType::iterator aIt = rMap.find( rKey );
+ return (aIt == rMap.end()) ? 0 : &aIt->second;
+}
+
+template< typename MapType >
+/*static*/ const typename MapType::mapped_type& ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault )
+{
+ typename MapType::const_iterator aIt = rMap.find( rKey );
+ return (aIt == rMap.end()) ? rDefault : aIt->second;
+}
+
+template< typename MapType >
+/*static*/ typename MapType::mapped_type& ContainerHelper::getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey, typename MapType::mapped_type& rDefault )
+{
+ typename MapType::iterator aIt = rMap.find( rKey );
+ return (aIt == rMap.end()) ? rDefault : aIt->second;
+}
+
+template< typename VectorType >
+/*static*/ ::com::sun::star::uno::Sequence< typename VectorType::value_type > ContainerHelper::vectorToSequence( const VectorType& rVector )
+{
+ typedef typename VectorType::value_type ValueType;
+ if( rVector.empty() )
+ return ::com::sun::star::uno::Sequence< ValueType >();
+ return ::com::sun::star::uno::Sequence< ValueType >( &rVector.front(), static_cast< sal_Int32 >( rVector.size() ) );
+}
+
+template< typename MapType >
+/*static*/ ::com::sun::star::uno::Sequence< typename MapType::mapped_type > ContainerHelper::mapToSequence( const MapType& rMap )
+{
+ typedef typename MapType::mapped_type ValueType;
+ if( rMap.empty() )
+ return ::com::sun::star::uno::Sequence< ValueType >();
+ ::com::sun::star::uno::Sequence< ValueType > aSeq( static_cast< sal_Int32 >( rMap.size() ) );
+ sal_Int32 nIndex = 0;
+ for( typename MapType::const_iterator aIt = rMap.begin(), aEnd = rMap.end(); aIt != aEnd; ++aIt, ++nIndex )
+ aSeq[ nIndex ] = *aIt;
+ return aSeq;
+}
+
+template< typename MatrixType >
+/*static*/ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< typename MatrixType::value_type > > ContainerHelper::matrixToSequenceSequence( const MatrixType& rMatrix )
+{
+ typedef typename MatrixType::value_type ValueType;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ValueType > > aSeq;
+ if( !rMatrix.empty() )
+ {
+ aSeq.realloc( static_cast< sal_Int32 >( rMatrix.height() ) );
+ for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow )
+ aSeq[ static_cast< sal_Int32 >( nRow ) ] =
+ ::com::sun::star::uno::Sequence< ValueType >( &rMatrix.row_front( nRow ), static_cast< sal_Int32 >( rMatrix.width() ) );
+ }
+ return aSeq;
+}
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/graphichelper.hxx b/oox/inc/oox/helper/graphichelper.hxx
new file mode 100644
index 000000000000..b2b9e1cd133b
--- /dev/null
+++ b/oox/inc/oox/helper/graphichelper.hxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_GRAPHICHELPER_HXX
+#define OOX_HELPER_GRAPHICHELPER_HXX
+
+#include <deque>
+#include <map>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/awt/DeviceInfo.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include "oox/helper/binarystreambase.hxx"
+#include "oox/helper/storagebase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Point; }
+ namespace awt { struct Size; }
+ namespace awt { class XUnitConversion; }
+ namespace io { class XInputStream; }
+ namespace frame { class XFrame; }
+ namespace graphic { class XGraphic; }
+ namespace graphic { class XGraphicObject; }
+ namespace graphic { class XGraphicProvider; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace oox {
+
+// ============================================================================
+
+/** Provides helper functions for colors, device measurement conversion,
+ graphics, and graphic objects handling.
+
+ All createGraphicObject() and importGraphicObject() functions create
+ persistent graphic objects internally and store them in an internal
+ container to prevent their early destruction. This makes it possible to use
+ the returned URL of the graphic object in any way (e.g. insert it into a
+ property map) without needing to store it immediatly at an object that
+ resolves the graphic object from the passed URL and thus prevents it from
+ being destroyed.
+ */
+class GraphicHelper
+{
+public:
+ explicit GraphicHelper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rxTargetFrame,
+ const StorageRef& rxStorage );
+ virtual ~GraphicHelper();
+
+ // System colors and predefined colors ------------------------------------
+
+ /** Returns a system color specified by the passed XML token identifier. */
+ sal_Int32 getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb = API_RGB_TRANSPARENT ) const;
+ /** Derived classes may implement to resolve a scheme color from the passed XML token identifier. */
+ virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const;
+ /** Derived classes may implement to resolve a palette index to an RGB color. */
+ virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const;
+
+ // Device info and device dependent unit conversion -----------------------
+
+ /** Returns information about the output device. */
+ const ::com::sun::star::awt::DeviceInfo& getDeviceInfo() const;
+
+ /** Converts the passed value from horizontal screen pixels to 1/100 mm. */
+ sal_Int32 convertScreenPixelXToHmm( double fPixelX ) const;
+ /** Converts the passed value from vertical screen pixels to 1/100 mm. */
+ sal_Int32 convertScreenPixelYToHmm( double fPixelY ) const;
+ /** Converts the passed point from screen pixels to 1/100 mm. */
+ ::com::sun::star::awt::Point convertScreenPixelToHmm( const ::com::sun::star::awt::Point& rPixel ) const;
+ /** Converts the passed size from screen pixels to 1/100 mm. */
+ ::com::sun::star::awt::Size convertScreenPixelToHmm( const ::com::sun::star::awt::Size& rPixel ) const;
+
+ /** Converts the passed value from 1/100 mm to horizontal screen pixels. */
+ double convertHmmToScreenPixelX( sal_Int32 nHmmX ) const;
+ /** Converts the passed value from 1/100 mm to vertical screen pixels. */
+ double convertHmmToScreenPixelY( sal_Int32 nHmmY ) const;
+ /** Converts the passed point from 1/100 mm to screen pixels. */
+ ::com::sun::star::awt::Point convertHmmToScreenPixel( const ::com::sun::star::awt::Point& rHmm ) const;
+ /** Converts the passed size from 1/100 mm to screen pixels. */
+ ::com::sun::star::awt::Size convertHmmToScreenPixel( const ::com::sun::star::awt::Size& rHmm ) const;
+
+ /** Converts the passed point from AppFont units to 1/100 mm. */
+ ::com::sun::star::awt::Point convertAppFontToHmm( const ::com::sun::star::awt::Point& rAppFont ) const;
+ /** Converts the passed point from AppFont units to 1/100 mm. */
+ ::com::sun::star::awt::Size convertAppFontToHmm( const ::com::sun::star::awt::Size& rAppFont ) const;
+
+ /** Converts the passed point from 1/100 mm to AppFont units. */
+ ::com::sun::star::awt::Point convertHmmToAppFont( const ::com::sun::star::awt::Point& rHmm ) const;
+ /** Converts the passed size from 1/100 mm to AppFont units. */
+ ::com::sun::star::awt::Size convertHmmToAppFont( const ::com::sun::star::awt::Size& rHmm ) const;
+
+ // Graphics and graphic objects ------------------------------------------
+
+ /** Imports a graphic from the passed input stream. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >
+ importGraphic(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm ) const;
+
+ /** Imports a graphic from the passed binary memory block. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >
+ importGraphic( const StreamDataSequence& rGraphicData ) const;
+
+ /** Imports a graphic from the storage stream with the passed path and name. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >
+ importEmbeddedGraphic( const ::rtl::OUString& rStreamName ) const;
+
+ /** Creates a persistent graphic object from the passed graphic.
+ @return The URL of the created and internally cached graphic object. */
+ ::rtl::OUString createGraphicObject(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rxGraphic ) const;
+
+ /** Creates a persistent graphic object from the passed input stream.
+ @return The URL of the created and internally cached graphic object. */
+ ::rtl::OUString importGraphicObject(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm ) const;
+
+ /** Creates a persistent graphic object from the passed binary memory block.
+ @return The URL of the created and internally cached graphic object. */
+ ::rtl::OUString importGraphicObject( const StreamDataSequence& rGraphicData ) const;
+
+ /** Imports a graphic object from the storage stream with the passed path and name.
+ @return The URL of the created and internally cached graphic object. */
+ ::rtl::OUString importEmbeddedGraphicObject( const ::rtl::OUString& rStreamName ) const;
+
+ /** calculates the orignal size of a graphic which is necessary to be able to calculate cropping values
+ @return The original Graphic size in 100thmm */
+ ::com::sun::star::awt::Size getOriginalSize( const ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rxGraphic ) const;
+
+ // ------------------------------------------------------------------------
+private:
+ typedef ::std::map< sal_Int32, sal_Int32 > SystemPalette;
+ typedef ::std::deque< ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphicObject > > GraphicObjectDeque;
+ typedef ::std::map< ::rtl::OUString, ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > > EmbeddedGraphicMap;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxCompContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphicProvider > mxGraphicProvider;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XUnitConversion > mxUnitConversion;
+ ::com::sun::star::awt::DeviceInfo maDeviceInfo; /// Current output device info.
+ SystemPalette maSystemPalette; /// Maps system colors (XML tokens) to RGB color values.
+ StorageRef mxStorage; /// Storage containing embedded graphics.
+ mutable GraphicObjectDeque maGraphicObjects; /// Caches all created graphic objects to keep them alive.
+ mutable EmbeddedGraphicMap maEmbeddedGraphics; /// Maps all embedded graphics by their storage path.
+ const ::rtl::OUString maGraphicObjScheme; /// The URL scheme name for graphic objects.
+ double mfPixelPerHmmX; /// Number of screen pixels per 1/100 mm in X direction.
+ double mfPixelPerHmmY; /// Number of screen pixels per 1/100 mm in Y direction.
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/helper.hxx b/oox/inc/oox/helper/helper.hxx
new file mode 100644
index 000000000000..84c501fae2e5
--- /dev/null
+++ b/oox/inc/oox/helper/helper.hxx
@@ -0,0 +1,324 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_HELPER_HXX
+#define OOX_HELPER_HELPER_HXX
+
+#include <algorithm>
+#include <limits>
+#include <boost/static_assert.hpp>
+#include <osl/endian.h>
+#include <rtl/math.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <string.h>
+
+namespace oox {
+
+// Helper macros ==============================================================
+
+/** Expands to the number of elements in a STATIC data array. */
+#define STATIC_ARRAY_SIZE( array ) \
+ (sizeof(array)/sizeof(*(array)))
+
+/** Expands to a pointer behind the last element of a STATIC data array (like
+ STL end()). */
+#define STATIC_ARRAY_END( array ) \
+ ((array)+STATIC_ARRAY_SIZE(array))
+
+/** Expands to the 'index'-th element of a STATIC data array, or to 'def', if
+ 'index' is out of the array limits. */
+#define STATIC_ARRAY_SELECT( array, index, def ) \
+ ((static_cast<size_t>(index) < STATIC_ARRAY_SIZE(array)) ? ((array)[static_cast<size_t>(index)]) : (def))
+
+/** Expands to a temporary ::rtl::OString, created from a literal(!) character
+ array. */
+#define CREATE_OSTRING( ascii ) \
+ ::rtl::OString( RTL_CONSTASCII_STRINGPARAM( ascii ) )
+
+/** Expands to a temporary ::rtl::OUString, created from a literal(!) ASCII(!)
+ character array. */
+#define CREATE_OUSTRING( ascii ) \
+ ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( ascii ) )
+
+/** Convert an OUString to an ASCII C string. Use for debug purposes only. */
+#define OUSTRING_TO_CSTR( str ) \
+ ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ).getStr()
+
+// Common constants ===========================================================
+
+const sal_uInt8 WINDOWS_CHARSET_ANSI = 0;
+const sal_uInt8 WINDOWS_CHARSET_DEFAULT = 1;
+const sal_uInt8 WINDOWS_CHARSET_SYMBOL = 2;
+const sal_uInt8 WINDOWS_CHARSET_APPLE_ROMAN = 77;
+const sal_uInt8 WINDOWS_CHARSET_SHIFTJIS = 128;
+const sal_uInt8 WINDOWS_CHARSET_HANGEUL = 129;
+const sal_uInt8 WINDOWS_CHARSET_JOHAB = 130;
+const sal_uInt8 WINDOWS_CHARSET_GB2312 = 134;
+const sal_uInt8 WINDOWS_CHARSET_BIG5 = 136;
+const sal_uInt8 WINDOWS_CHARSET_GREEK = 161;
+const sal_uInt8 WINDOWS_CHARSET_TURKISH = 162;
+const sal_uInt8 WINDOWS_CHARSET_VIETNAMESE = 163;
+const sal_uInt8 WINDOWS_CHARSET_HEBREW = 177;
+const sal_uInt8 WINDOWS_CHARSET_ARABIC = 178;
+const sal_uInt8 WINDOWS_CHARSET_BALTIC = 186;
+const sal_uInt8 WINDOWS_CHARSET_RUSSIAN = 204;
+const sal_uInt8 WINDOWS_CHARSET_THAI = 222;
+const sal_uInt8 WINDOWS_CHARSET_EASTERN = 238;
+const sal_uInt8 WINDOWS_CHARSET_OEM = 255;
+
+// ----------------------------------------------------------------------------
+
+const sal_Int32 API_RGB_TRANSPARENT = -1; /// Transparent color for API calls.
+const sal_Int32 API_RGB_BLACK = 0x00000; /// Black color for API calls.
+const sal_Int32 API_RGB_WHITE = 0xFFFFF; /// White color for API calls.
+
+const sal_Int16 API_LINE_NONE = 0;
+const sal_Int16 API_LINE_HAIR = 2;
+const sal_Int16 API_LINE_THIN = 35;
+const sal_Int16 API_LINE_MEDIUM = 88;
+const sal_Int16 API_LINE_THICK = 141;
+
+const sal_Int16 API_ESCAPE_NONE = 0; /// No escapement.
+const sal_Int16 API_ESCAPE_SUPERSCRIPT = 101; /// Superscript: raise characters automatically (magic value 101).
+const sal_Int16 API_ESCAPE_SUBSCRIPT = -101; /// Subscript: lower characters automatically (magic value -101).
+
+const sal_Int8 API_ESCAPEHEIGHT_NONE = 100; /// Relative character height if not escaped.
+const sal_Int8 API_ESCAPEHEIGHT_DEFAULT = 58; /// Relative character height if escaped.
+
+// ============================================================================
+
+// Limitate values ------------------------------------------------------------
+
+template< typename ReturnType, typename Type >
+inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax )
+{
+ return static_cast< ReturnType >( ::std::min( ::std::max( nValue, nMin ), nMax ) );
+}
+
+template< typename ReturnType, typename Type >
+inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd )
+{
+// this BOOST_STATIC_ASSERT fails with suncc
+// BOOST_STATIC_ASSERT( ::std::numeric_limits< Type >::is_integer );
+ Type nInterval = nEnd - nBegin;
+ Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval);
+ return static_cast< ReturnType >( nValue - nCount * nInterval );
+}
+
+template< typename ReturnType >
+inline ReturnType getDoubleIntervalValue( double fValue, double fBegin, double fEnd )
+{
+ double fInterval = fEnd - fBegin;
+ double fCount = (fValue < fBegin) ? -(::rtl::math::approxFloor( (fBegin - fValue - 1.0) / fInterval ) + 1.0) : ::rtl::math::approxFloor( (fValue - fBegin) / fInterval );
+ return static_cast< ReturnType >( fValue - fCount * fInterval );
+}
+
+// Read from bitfields --------------------------------------------------------
+
+/** Returns true, if at least one of the bits set in nMask is set in nBitField. */
+template< typename Type >
+inline bool getFlag( Type nBitField, Type nMask )
+{
+ return (nBitField & nMask) != 0;
+}
+
+/** Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. */
+template< typename ReturnType, typename Type >
+inline ReturnType getFlagValue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset )
+{
+ return getFlag( nBitField, nMask ) ? nSet : nUnset;
+}
+
+/** Extracts a value from a bit field.
+
+ Returns the data fragment from nBitField, that starts at bit nStartBit
+ (0-based, bit 0 is rightmost) with the width of nBitCount. The returned
+ value will be right-aligned (normalized).
+ For instance: extractValue<T>(0x4321,8,4) returns 3 (value in bits 8-11).
+ */
+template< typename ReturnType, typename Type >
+inline ReturnType extractValue( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
+{
+ sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
+ return static_cast< ReturnType >( nMask & (nBitField >> nStartBit) );
+}
+
+// Write to bitfields ---------------------------------------------------------
+
+/** Sets or clears (according to bSet) all set bits of nMask in ornBitField. */
+template< typename Type >
+inline void setFlag( Type& ornBitField, Type nMask, bool bSet = true )
+{
+ if( bSet ) ornBitField |= nMask; else ornBitField &= ~nMask;
+}
+
+/** Inserts a value into a bitfield.
+
+ Inserts the lower nBitCount bits of nValue into ornBitField, starting
+ there at bit nStartBit. Other contents of ornBitField keep unchanged.
+ */
+template< typename Type, typename InsertType >
+void insertValue( Type& ornBitField, InsertType nValue, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
+{
+ sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
+ Type nNewValue = static_cast< Type >( nValue & nMask );
+ (ornBitField &= ~(nMask << nStartBit)) |= (nNewValue << nStartBit);
+}
+
+// ============================================================================
+
+/** Optional value, similar to ::boost::optional<>, with convenience accessors.
+ */
+template< typename Type >
+class OptValue
+{
+public:
+ inline explicit OptValue() : mbHasValue( false ) {}
+ inline explicit OptValue( const Type& rValue ) : maValue( rValue ), mbHasValue( true ) {}
+ inline explicit OptValue( bool bHasValue, const Type& rValue ) : maValue( rValue ), mbHasValue( bHasValue ) {}
+
+ inline bool has() const { return mbHasValue; }
+ inline bool operator!() const { return !mbHasValue; }
+ inline bool differsFrom( const Type& rValue ) const { return mbHasValue && (maValue != rValue); }
+
+ inline const Type& get() const { return maValue; }
+ inline const Type& get( const Type& rDefValue ) const { return mbHasValue ? maValue : rDefValue; }
+
+ inline void reset() { mbHasValue = false; }
+ inline void set( const Type& rValue ) { maValue = rValue; mbHasValue = true; }
+ inline Type& use() { mbHasValue = true; return maValue; }
+
+ inline OptValue& operator=( const Type& rValue ) { set( rValue ); return *this; }
+ inline void assignIfUsed( const OptValue& rValue ) { if( rValue.mbHasValue ) set( rValue.maValue ); }
+
+private:
+ Type maValue;
+ bool mbHasValue;
+};
+
+// ============================================================================
+
+/** Provides platform independent functions to convert from or to little-endian
+ byte order, e.g. for reading data from or writing data to memory or a
+ binary stream.
+
+ On big-endian platforms, the byte order in the passed values is swapped,
+ this can be used for converting big-endian to and from little-endian data.
+
+ On little-endian platforms, the conversion functions are implemented empty,
+ thus compilers should completely optimize away the function call.
+ */
+class ByteOrderConverter
+{
+public:
+ inline static void convertLittleEndian( sal_Int8& ) {} // present for usage in templates
+ inline static void convertLittleEndian( sal_uInt8& ) {} // present for usage in templates
+#ifdef OSL_BIGENDIAN
+ inline static void convertLittleEndian( sal_Int16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
+ inline static void convertLittleEndian( sal_uInt16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
+ inline static void convertLittleEndian( sal_Int32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
+ inline static void convertLittleEndian( sal_uInt32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
+ inline static void convertLittleEndian( sal_Int64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
+ inline static void convertLittleEndian( sal_uInt64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
+ inline static void convertLittleEndian( float& rfValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
+ inline static void convertLittleEndian( double& rfValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
+#else
+ inline static void convertLittleEndian( sal_Int16& ) {}
+ inline static void convertLittleEndian( sal_uInt16& ) {}
+ inline static void convertLittleEndian( sal_Int32& ) {}
+ inline static void convertLittleEndian( sal_uInt32& ) {}
+ inline static void convertLittleEndian( sal_Int64& ) {}
+ inline static void convertLittleEndian( sal_uInt64& ) {}
+ inline static void convertLittleEndian( float& ) {}
+ inline static void convertLittleEndian( double& ) {}
+#endif
+
+ /** Reads a value from memory, assuming memory buffer in little-endian.
+ @param ornValue (out-parameter) Contains the value read from memory.
+ @param pSrcBuffer The memory buffer to read the value from.
+ */
+ template< typename Type >
+ inline static void readLittleEndian( Type& ornValue, const void* pSrcBuffer );
+
+ /** Writes a value to memory, while converting it to little-endian.
+ @param pDstBuffer The memory buffer to write the value to.
+ @param nValue The value to be written to memory in little-endian.
+ */
+ template< typename Type >
+ inline static void writeLittleEndian( void* pDstBuffer, Type nValue );
+
+#ifdef OSL_BIGENDIAN
+private:
+ inline static void swap2( sal_uInt8* pnData );
+ inline static void swap4( sal_uInt8* pnData );
+ inline static void swap8( sal_uInt8* pnData );
+#endif
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+inline void ByteOrderConverter::readLittleEndian( Type& ornValue, const void* pSrcBuffer )
+{
+ memcpy( &ornValue, pSrcBuffer, sizeof( Type ) );
+ convertLittleEndian( ornValue );
+}
+
+template< typename Type >
+inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer, Type nValue )
+{
+ convertLittleEndian( nValue );
+ memcpy( pDstBuffer, &nValue, sizeof( Type ) );
+}
+
+#ifdef OSL_BIGENDIAN
+inline void ByteOrderConverter::swap2( sal_uInt8* pnData )
+{
+ ::std::swap( pnData[ 0 ], pnData[ 1 ] );
+}
+
+inline void ByteOrderConverter::swap4( sal_uInt8* pnData )
+{
+ ::std::swap( pnData[ 0 ], pnData[ 3 ] );
+ ::std::swap( pnData[ 1 ], pnData[ 2 ] );
+}
+
+inline void ByteOrderConverter::swap8( sal_uInt8* pnData )
+{
+ ::std::swap( pnData[ 0 ], pnData[ 7 ] );
+ ::std::swap( pnData[ 1 ], pnData[ 6 ] );
+ ::std::swap( pnData[ 2 ], pnData[ 5 ] );
+ ::std::swap( pnData[ 3 ], pnData[ 4 ] );
+}
+#endif
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/modelobjecthelper.hxx b/oox/inc/oox/helper/modelobjecthelper.hxx
new file mode 100644
index 000000000000..e36e7001e613
--- /dev/null
+++ b/oox/inc/oox/helper/modelobjecthelper.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_MODELOBJECTHELPER_HXX
+#define OOX_HELPER_MODELOBJECTHELPER_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Gradient; }
+ namespace container { class XNameContainer; }
+ namespace drawing { struct LineDash; }
+ namespace drawing { struct PolyPolygonBezierCoords; }
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace oox {
+
+// ============================================================================
+
+/** This helper manages named objects in a container, which is created on demand.
+ */
+class ObjectContainer
+{
+public:
+ explicit ObjectContainer(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::rtl::OUString& rServiceName );
+ ~ObjectContainer();
+
+ /** Returns true, if the object with the passed name exists in the container. */
+ bool hasObject( const ::rtl::OUString& rObjName ) const;
+
+ /** Returns the object with the passed name from the container. */
+ ::com::sun::star::uno::Any getObject( const ::rtl::OUString& rObjName ) const;
+
+ /** Inserts the passed object into the container, returns its final name. */
+ ::rtl::OUString insertObject(
+ const ::rtl::OUString& rObjName,
+ const ::com::sun::star::uno::Any& rObj,
+ bool bInsertByUnusedName );
+
+private:
+ void createContainer() const;
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
+ mxFactory; /// Factory to create the container.
+ mutable ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ mxContainer; /// Container for the objects.
+ ::rtl::OUString maServiceName; /// Service name to create the container.
+ sal_Int32 mnIndex; /// Index to create unique identifiers.
+};
+
+// ============================================================================
+
+/** Contains tables for named drawing objects for a document model.
+
+ Contains tables for named line markers, line dashes, fill gradients, and
+ fill bitmaps. The class is needed to handle different document models in
+ the same filter (e.g. embedded charts) which carry their own drawing object
+ tables.
+ */
+class ModelObjectHelper
+{
+public:
+ explicit ModelObjectHelper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory );
+
+ /** Returns true, if the model contains a line marker with the passed name. */
+ bool hasLineMarker( const ::rtl::OUString& rMarkerName ) const;
+
+ /** Inserts a new named line marker, overwrites an existing line marker
+ with the same name. Returns true, if the marker could be inserted. */
+ bool insertLineMarker(
+ const ::rtl::OUString& rMarkerName,
+ const ::com::sun::star::drawing::PolyPolygonBezierCoords& rMarker );
+
+ /** Inserts a new named line dash, returns the line dash name, based on an
+ internal constant name with a new unused index appended. */
+ ::rtl::OUString insertLineDash( const ::com::sun::star::drawing::LineDash& rDash );
+
+ /** Inserts a new named fill gradient, returns the gradient name, based on
+ an internal constant name with a new unused index appended. */
+ ::rtl::OUString insertFillGradient( const ::com::sun::star::awt::Gradient& rGradient );
+
+ /** Inserts a new named fill bitmap, returns the bitmap name, based on an
+ internal constant name with a new unused index appended. */
+ ::rtl::OUString insertFillBitmap( const ::rtl::OUString& rGraphicUrl );
+
+private:
+ ObjectContainer maMarkerContainer; /// Contains all named line markers (line end polygons).
+ ObjectContainer maDashContainer; /// Contains all named line dsahes.
+ ObjectContainer maGradientContainer; /// Contains all named fill gradients.
+ ObjectContainer maBitmapContainer; /// Contains all named fill bitmaps.
+ const ::rtl::OUString maDashNameBase; /// Base name for all named line dashes.
+ const ::rtl::OUString maGradientNameBase; /// Base name for all named fill gradients.
+ const ::rtl::OUString maBitmapNameBase; /// Base name for all named fill bitmaps.
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/progressbar.hxx b/oox/inc/oox/helper/progressbar.hxx
new file mode 100644
index 000000000000..847d16ea9231
--- /dev/null
+++ b/oox/inc/oox/helper/progressbar.hxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_PROGRESSBAR_HXX
+#define OOX_HELPER_PROGRESSBAR_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace rtl { class OUString; }
+
+namespace com { namespace sun { namespace star {
+ namespace task { class XStatusIndicator; }
+} } }
+
+namespace oox {
+
+// Interfaces =================================================================
+
+/** Interface for progress bar classes.
+ */
+class IProgressBar
+{
+public:
+ virtual ~IProgressBar();
+
+ /** Returns the current position of the progress bar.
+
+ @return Position of the progress bar, in the range from 0.0 (beginning
+ of the progress bar) to 1.0 (end of the progress bar) inclusive.
+ */
+ virtual double getPosition() const = 0;
+
+ /** Sets the current position of the progress bar.
+
+ @param fPosition New position of the progress bar, in the range from
+ 0.0 (beginning of the progress bar) to 1.0 (end of the progress bar)
+ inclusive.
+ */
+ virtual void setPosition( double fPosition ) = 0;
+};
+
+typedef ::boost::shared_ptr< IProgressBar > IProgressBarRef;
+
+// ----------------------------------------------------------------------------
+
+class ISegmentProgressBar;
+typedef ::boost::shared_ptr< ISegmentProgressBar > ISegmentProgressBarRef;
+
+/** Interface for a segment in a progress bar, that is able to create sub
+ segments from itself.
+ */
+class ISegmentProgressBar : public IProgressBar
+{
+public:
+ virtual ~ISegmentProgressBar();
+
+ /** Returns the length that is still free for creating sub segments. */
+ virtual double getFreeLength() const = 0;
+
+ /** Adds a new segment with the specified length. */
+ virtual ISegmentProgressBarRef createSegment( double fLength ) = 0;
+};
+
+// ============================================================================
+// ============================================================================
+
+/** A simple progress bar.
+ */
+class ProgressBar : public IProgressBar
+{
+public:
+ explicit ProgressBar(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator >& rxIndicator,
+ const ::rtl::OUString& rText );
+
+ virtual ~ProgressBar();
+
+ /** Returns the current position of the progress bar. */
+ virtual double getPosition() const;
+ /** Sets the current position of the progress bar. */
+ virtual void setPosition( double fPosition );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator >
+ mxIndicator;
+ double mfPosition;
+};
+
+// ============================================================================
+
+/** A progress bar containing several independent segments.
+ */
+class SegmentProgressBar : public ISegmentProgressBar
+{
+public:
+ explicit SegmentProgressBar(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator >& rxIndicator,
+ const ::rtl::OUString& rText );
+
+ /** Returns the current position of the progress bar segment. */
+ virtual double getPosition() const;
+ /** Sets the current position of the progress bar segment. */
+ virtual void setPosition( double fPosition );
+
+ /** Returns the length that is still free for creating sub segments. */
+ virtual double getFreeLength() const;
+ /** Adds a new segment with the specified length. */
+ virtual ISegmentProgressBarRef createSegment( double fLength );
+
+private:
+ ProgressBar maProgress;
+ double mfFreeStart;
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/propertymap.hxx b/oox/inc/oox/helper/propertymap.hxx
new file mode 100644
index 000000000000..9e7196381002
--- /dev/null
+++ b/oox/inc/oox/helper/propertymap.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_PROPERTYMAP_HXX
+#define OOX_HELPER_PROPERTYMAP_HXX
+
+#include <vector>
+#include <map>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <rtl/ustring.hxx>
+#include "oox/token/properties.hxx"
+
+namespace com { namespace sun { namespace star { namespace beans {
+ struct PropertyValue;
+ class XPropertySet;
+} } } }
+
+namespace oox {
+
+struct PropertyNameVector;
+
+// ============================================================================
+
+typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > PropertyMapBase;
+
+/** A helper that maps property identifiers to property values.
+
+ The property identifiers are generated on compile time and refer to the
+ property name strings that are held by a static vector. The identifier to
+ name mapping is done internally while the properties are written to
+ property sets.
+ */
+class PropertyMap : public PropertyMapBase
+{
+public:
+ explicit PropertyMap();
+ ~PropertyMap();
+
+ /** Returns the name of the passed property identifier. */
+ static const ::rtl::OUString& getPropertyName( sal_Int32 nPropId );
+
+ /** Returns true, if the map contains a property with the passed identifier. */
+ inline bool hasProperty( sal_Int32 nPropId ) const
+ { return find( nPropId ) != end(); }
+
+ /** Returns the property value of the specified property, or 0 if not found. */
+ const ::com::sun::star::uno::Any* getProperty( sal_Int32 nPropId ) const;
+
+ /** Sets the specified property to the passed value. Does nothing, if the
+ identifier is invalid. */
+ template< typename Type >
+ inline void setProperty( sal_Int32 nPropId, const Type& rValue )
+ { if( nPropId >= 0 ) (*this)[ nPropId ] <<= rValue; }
+
+ /** Returns a sequence of property values, filled with all contained properties. */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
+ makePropertyValueSequence() const;
+
+ /** Fills the passed sequences of names and anys with all contained properties. */
+ void fillSequences(
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rValues ) const;
+
+ /** Creates and fills a new instance supporting the XPropertySet interface. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
+ makePropertySet() const;
+
+private:
+ const PropertyNameVector* mpPropNames;
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/propertyset.hxx b/oox/inc/oox/helper/propertyset.hxx
new file mode 100644
index 000000000000..9a49bb48cf92
--- /dev/null
+++ b/oox/inc/oox/helper/propertyset.hxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_PROPERTYSET_HXX
+#define OOX_HELPER_PROPERTYSET_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include "oox/token/properties.hxx"
+
+namespace oox {
+
+class PropertyMap;
+
+// ============================================================================
+
+/** A wrapper for a UNO property set.
+
+ This class provides functions to silently get and set properties (without
+ exceptions, without the need to check validity of the UNO property set).
+
+ An instance is constructed with the reference to a UNO property set or any
+ other interface (the constructor will query for the
+ com.sun.star.beans.XPropertySet interface then). The reference to the
+ property set will be kept as long as the instance of this class is alive.
+
+ The functions getProperties() and setProperties() try to handle all passed
+ values at once, using the com.sun.star.beans.XMultiPropertySet interface.
+ If the implementation does not support the XMultiPropertySet interface, all
+ properties are handled separately in a loop.
+ */
+class PropertySet
+{
+public:
+ inline explicit PropertySet() {}
+
+ /** Constructs a property set wrapper with the passed UNO property set. */
+ inline explicit PropertySet(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rxPropSet )
+ { set( rxPropSet ); }
+
+ /** Constructs a property set wrapper after querying the XPropertySet interface. */
+ template< typename Type >
+ inline explicit PropertySet( const Type& rObject ) { set( rObject ); }
+
+ /** Sets the passed UNO property set and releases the old UNO property set. */
+ void set( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rxPropSet );
+
+ /** Queries the passed object (interface or any) for an XPropertySet and releases the old UNO property set. */
+ template< typename Type >
+ inline void set( const Type& rObject )
+ { set( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >( rObject, ::com::sun::star::uno::UNO_QUERY ) ); }
+
+ /** Returns true, if the contained XPropertySet interface is valid. */
+ inline bool is() const { return mxPropSet.is(); }
+
+ /** Returns the contained XPropertySet interface. */
+ inline ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
+ getXPropertySet() const { return mxPropSet; }
+
+ // Get properties ---------------------------------------------------------
+
+ /** Gets the specified property from the property set.
+ @return true, if the any could be filled with the property value. */
+ bool getAnyProperty( ::com::sun::star::uno::Any& orValue, sal_Int32 nPropId ) const;
+
+ /** Gets the specified property from the property set.
+ @return true, if the passed variable could be filled with the property value. */
+ template< typename Type >
+ inline bool getProperty( Type& orValue, sal_Int32 nPropId ) const;
+
+ /** Gets the specified property from the property set.
+ @return the property value, or an empty Any, if the property is missing. */
+ ::com::sun::star::uno::Any getAnyProperty( sal_Int32 nPropId ) const;
+
+ /** Gets the specified boolean property from the property set.
+ @return true = property contains true; false = property contains false or error occured. */
+ bool getBoolProperty( sal_Int32 nPropId ) const;
+
+ /** Gets the specified properties from the property set. Tries to use the XMultiPropertySet interface.
+ @param orValues (out-parameter) The related property values.
+ @param rPropNames The property names. MUST be ordered alphabetically. */
+ void getProperties(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& orValues,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rPropNames ) const;
+
+ // Set properties ---------------------------------------------------------
+
+ /** Puts the passed any into the property set. */
+ void setAnyProperty( sal_Int32 nPropId, const ::com::sun::star::uno::Any& rValue );
+
+ /** Puts the passed value into the property set. */
+ template< typename Type >
+ inline void setProperty( sal_Int32 nPropId, const Type& rValue );
+
+ /** Puts the passed properties into the property set. Tries to use the XMultiPropertySet interface.
+ @param rPropNames The property names. MUST be ordered alphabetically.
+ @param rValues The related property values. */
+ void setProperties(
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rPropNames,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rValues );
+
+ /** Puts the passed property map into the property set. Tries to use the XMultiPropertySet interface.
+ @param rPropertyMap The property map. */
+ void setProperties( const PropertyMap& rPropertyMap );
+
+ // ------------------------------------------------------------------------
+private:
+ /** Gets the specified property from the property set.
+ @return true, if the any could be filled with the property value. */
+ bool getAnyProperty( ::com::sun::star::uno::Any& orValue, const ::rtl::OUString& rPropName ) const;
+
+ /** Puts the passed any into the property set. */
+ void setAnyProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any& rValue );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
+ mxPropSet; /// The mandatory property set interface.
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
+ mxMultiPropSet; /// The optional multi property set interface.
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+inline bool PropertySet::getProperty( Type& orValue, sal_Int32 nPropId ) const
+{
+ ::com::sun::star::uno::Any aAny;
+ return getAnyProperty( aAny, nPropId ) && (aAny >>= orValue);
+}
+
+template< typename Type >
+inline void PropertySet::setProperty( sal_Int32 nPropId, const Type& rValue )
+{
+ setAnyProperty( nPropId, ::com::sun::star::uno::Any( rValue ) );
+}
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/refmap.hxx b/oox/inc/oox/helper/refmap.hxx
new file mode 100755
index 000000000000..e833e1196c81
--- /dev/null
+++ b/oox/inc/oox/helper/refmap.hxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_REFMAP_HXX
+#define OOX_HELPER_REFMAP_HXX
+
+#include <map>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <sal/types.h>
+
+namespace oox {
+
+// ============================================================================
+
+/** Template for a map of ref-counted objects with additional accessor functions.
+
+ An instance of the class RefMap< Type > stores elements of the type
+ ::boost::shared_ptr< Type >. The new accessor functions has() and get()
+ work correctly for nonexisting keys, there is no need to check the passed
+ key before.
+ */
+template< typename KeyType, typename ObjType, typename CompType = ::std::less< KeyType > >
+class RefMap : public ::std::map< KeyType, ::boost::shared_ptr< ObjType >, CompType >
+{
+public:
+ typedef ::std::map< KeyType, ::boost::shared_ptr< ObjType >, CompType > container_type;
+ typedef typename container_type::key_type key_type;
+ typedef typename container_type::mapped_type mapped_type;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::key_compare key_compare;
+
+public:
+ /** Returns true, if the object accossiated to the passed key exists.
+ Returns false, if the key exists but points to an empty reference. */
+ inline bool has( key_type nKey ) const
+ {
+ const mapped_type* pxRef = getRef( nKey );
+ return pxRef && pxRef->get();
+ }
+
+ /** Returns a reference to the object accossiated to the passed key, or an
+ empty reference on error. */
+ inline mapped_type get( key_type nKey ) const
+ {
+ if( const mapped_type* pxRef = getRef( nKey ) ) return *pxRef;
+ return mapped_type();
+ }
+
+ /** Calls the passed functor for every contained object, automatically
+ skips all elements that are empty references. */
+ template< typename FunctorType >
+ inline void forEach( const FunctorType& rFunctor ) const
+ {
+ ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType >
+ inline void forEachMem( FuncType pFunc ) const
+ {
+ forEach( ::boost::bind( pFunc, _1 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType >
+ inline void forEachMem( FuncType pFunc, ParamType aParam ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType1, typename ParamType2 >
+ inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 >
+ inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) );
+ }
+ /** Calls the passed functor for every contained object. Passes the key as
+ first argument and the object reference as second argument to rFunctor. */
+ template< typename FunctorType >
+ inline void forEachWithKey( const FunctorType& rFunctor ) const
+ {
+ ::std::for_each( this->begin(), this->end(), ForEachFunctorWithKey< FunctorType >( rFunctor ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the object key as argument to the member function. */
+ template< typename FuncType >
+ inline void forEachMemWithKey( FuncType pFunc ) const
+ {
+ forEachWithKey( ::boost::bind( pFunc, _2, _1 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the object key as first argument to the member function. */
+ template< typename FuncType, typename ParamType >
+ inline void forEachMemWithKey( FuncType pFunc, ParamType aParam ) const
+ {
+ forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the object key as first argument to the member function. */
+ template< typename FuncType, typename ParamType1, typename ParamType2 >
+ inline void forEachMemWithKey( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const
+ {
+ forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the object key as first argument to the member function. */
+ template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 >
+ inline void forEachMemWithKey( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const
+ {
+ forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam1, aParam2, aParam3 ) );
+ }
+
+private:
+ template< typename FunctorType >
+ struct ForEachFunctor
+ {
+ FunctorType maFunctor;
+ inline explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {}
+ inline void operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( *rValue.second ); }
+ };
+
+ template< typename FunctorType >
+ struct ForEachFunctorWithKey
+ {
+ FunctorType maFunctor;
+ inline explicit ForEachFunctorWithKey( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {}
+ inline void operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( rValue.first, *rValue.second ); }
+ };
+
+ inline const mapped_type* getRef( key_type nKey ) const
+ {
+ typename container_type::const_iterator aIt = find( nKey );
+ return (aIt == this->end()) ? 0 : &aIt->second;
+ }
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/refvector.hxx b/oox/inc/oox/helper/refvector.hxx
new file mode 100755
index 000000000000..0a2d8be62e2f
--- /dev/null
+++ b/oox/inc/oox/helper/refvector.hxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_REFVECTOR_HXX
+#define OOX_HELPER_REFVECTOR_HXX
+
+#include <vector>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <sal/types.h>
+
+namespace oox {
+
+// ============================================================================
+
+/** Template for a vector of ref-counted objects with additional accessor functions.
+
+ An instance of the class RefVector< Type > stores elements of the type
+ ::boost::shared_ptr< Type >. The new accessor functions has() and get()
+ work correctly for indexes out of the current range, there is no need to
+ check the passed index before.
+ */
+template< typename ObjType >
+class RefVector : public ::std::vector< ::boost::shared_ptr< ObjType > >
+{
+public:
+ typedef ::std::vector< ::boost::shared_ptr< ObjType > > container_type;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::size_type size_type;
+
+public:
+ /** Returns true, if the object with the passed index exists. Returns
+ false, if the vector element exists but is an empty reference. */
+ inline bool has( sal_Int32 nIndex ) const
+ {
+ const value_type* pxRef = getRef( nIndex );
+ return pxRef && pxRef->get();
+ }
+
+ /** Returns a reference to the object with the passed index, or 0 on error. */
+ inline value_type get( sal_Int32 nIndex ) const
+ {
+ if( const value_type* pxRef = getRef( nIndex ) ) return *pxRef;
+ return value_type();
+ }
+
+ /** Returns the index of the last element, or -1, if the vector is empty.
+ Does *not* check whether the last element is an empty reference. */
+ inline sal_Int32 getLastIndex() const { return static_cast< sal_Int32 >( this->size() ) - 1; }
+
+ /** Calls the passed functor for every contained object, automatically
+ skips all elements that are empty references. */
+ template< typename FunctorType >
+ inline void forEach( FunctorType aFunctor ) const
+ {
+ ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( aFunctor ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType >
+ inline void forEachMem( FuncType pFunc ) const
+ {
+ forEach( ::boost::bind( pFunc, _1 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType >
+ inline void forEachMem( FuncType pFunc, ParamType aParam ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType1, typename ParamType2 >
+ inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 >
+ inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) );
+ }
+
+ /** Calls the passed functor for every contained object. Passes the index as
+ first argument and the object reference as second argument to rFunctor. */
+ template< typename FunctorType >
+ inline void forEachWithIndex( const FunctorType& rFunctor ) const
+ {
+ ::std::for_each( this->begin(), this->end(), ForEachFunctorWithIndex< FunctorType >( rFunctor ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the vector index to the member function. */
+ template< typename FuncType >
+ inline void forEachMemWithIndex( FuncType pFunc ) const
+ {
+ forEachWithIndex( ::boost::bind( pFunc, _2, _1 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the vector index as first argument to the member function. */
+ template< typename FuncType, typename ParamType >
+ inline void forEachMemWithIndex( FuncType pFunc, ParamType aParam ) const
+ {
+ forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the vector index as first argument to the member function. */
+ template< typename FuncType, typename ParamType1, typename ParamType2 >
+ inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const
+ {
+ forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) );
+ }
+
+ /** Calls the passed member function of ObjType on every contained object.
+ Passes the vector index as first argument to the member function. */
+ template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 >
+ inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const
+ {
+ forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2, aParam3 ) );
+ }
+
+ /** Searches for an element by using the passed functor that takes a
+ constant reference of the object type (const ObjType&). */
+ template< typename FunctorType >
+ inline value_type findIf( const FunctorType& rFunctor ) const
+ {
+ typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) );
+ return (aIt == this->end()) ? value_type() : *aIt;
+ }
+
+private:
+ template< typename FunctorType >
+ struct ForEachFunctor
+ {
+ FunctorType maFunctor;
+ inline explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {}
+ inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( *rxValue ); }
+ };
+
+ template< typename FunctorType >
+ struct ForEachFunctorWithIndex
+ {
+ FunctorType maFunctor;
+ sal_Int32 mnIndex;
+ inline explicit ForEachFunctorWithIndex( const FunctorType& rFunctor ) : maFunctor( rFunctor ), mnIndex( 0 ) {}
+ inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( mnIndex, *rxValue ); ++mnIndex; }
+ };
+
+ template< typename FunctorType >
+ struct FindFunctor
+ {
+ FunctorType maFunctor;
+ inline explicit FindFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {}
+ inline bool operator()( const value_type& rxValue ) { return rxValue.get() && maFunctor( *rxValue ); }
+ };
+
+ inline const value_type* getRef( sal_Int32 nIndex ) const
+ {
+ return ((0 <= nIndex) && (static_cast< size_type >( nIndex ) < this->size())) ?
+ &(*this)[ static_cast< size_type >( nIndex ) ] : 0;
+ }
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/storagebase.hxx b/oox/inc/oox/helper/storagebase.hxx
new file mode 100644
index 000000000000..d48e5fdd1844
--- /dev/null
+++ b/oox/inc/oox/helper/storagebase.hxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_STORAGEBASE_HXX
+#define OOX_HELPER_STORAGEBASE_HXX
+
+#include <vector>
+#include <com/sun/star/uno/Reference.hxx>
+#include "oox/helper/refmap.hxx"
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace embed { class XStorage; }
+ namespace io { class XInputStream; }
+ namespace io { class XOutputStream; }
+ namespace io { class XStream; }
+} } }
+
+namespace oox {
+
+// ============================================================================
+
+class StorageBase;
+typedef ::boost::shared_ptr< StorageBase > StorageRef;
+
+/** Base class for storage access implementations.
+
+ Derived classes will be used to encapsulate storage access implementations
+ for ZIP storages containing XML streams, and OLE storages containing binary
+ data streams.
+ */
+class OOX_DLLPUBLIC StorageBase
+{
+public:
+ explicit StorageBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream,
+ bool bBaseStreamAccess );
+
+ explicit StorageBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream,
+ bool bBaseStreamAccess );
+
+ virtual ~StorageBase();
+
+ /** Returns true, if the object represents a valid storage. */
+ bool isStorage() const;
+
+ /** Returns true, if the object represents the root storage. */
+ bool isRootStorage() const;
+
+ /** Returns true, if the storage operates in read-only mode (based on an
+ input stream). */
+ bool isReadOnly() const;
+
+ /** Returns the com.sun.star.embed.XStorage interface of the current storage. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ getXStorage() const;
+
+ /** Returns the element name of this storage. */
+ const ::rtl::OUString& getName() const;
+
+ /** Returns the full path of this storage. */
+ ::rtl::OUString getPath() const;
+
+ /** Fills the passed vector with the names of all direct elements of this
+ storage. */
+ void getElementNames( ::std::vector< ::rtl::OUString >& orElementNames ) const;
+
+ /** Opens and returns the specified sub storage from the storage.
+
+ @param rStorageName
+ The name of the embedded storage. The name may contain slashes to
+ open storages from embedded substorages.
+ @param bCreateMissing
+ True = create missing sub storages (for export filters). Must be
+ false for storages based on input streams.
+ */
+ StorageRef openSubStorage( const ::rtl::OUString& rStorageName, bool bCreateMissing );
+
+ /** Opens and returns the specified input stream from the storage.
+
+ @param rStreamName
+ The name of the embedded storage stream. The name may contain
+ slashes to open streams from embedded substorages. If base stream
+ access has been enabled in the constructor, the base stream can be
+ accessed by passing an empty string as stream name.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ openInputStream( const ::rtl::OUString& rStreamName );
+
+ /** Opens and returns the specified output stream from the storage.
+
+ @param rStreamName
+ The name of the embedded storage stream. The name may contain
+ slashes to create and open streams in embedded substorages. If base
+ stream access has been enabled in the constructor, the base stream
+ can be accessed by passing an empty string as stream name.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ openOutputStream( const ::rtl::OUString& rStreamName );
+
+ /** Copies the specified element from this storage to the passed
+ destination storage.
+
+ @param rElementName
+ The name of the embedded storage or stream. The name may contain
+ slashes to specify an element in an embedded substorage. In this
+ case, the element will be copied to the same substorage in the
+ destination storage.
+ */
+ void copyToStorage( StorageBase& rDestStrg, const ::rtl::OUString& rElementName );
+
+ /** Copies all streams of this storage and of all substorages to the passed
+ destination. */
+ void copyStorageToStorage( StorageBase& rDestStrg );
+
+ /** Commits the changes to the storage and all substorages. */
+ void commit();
+
+protected:
+ /** Special constructor for sub storage objects. */
+ explicit StorageBase( const StorageBase& rParentStorage, const ::rtl::OUString& rStorageName, bool bReadOnly );
+
+private:
+ StorageBase( const StorageBase& );
+ StorageBase& operator=( const StorageBase& );
+
+ /** Returns true, if the object represents a valid storage. */
+ virtual bool implIsStorage() const = 0;
+
+ /** Returns the com.sun.star.embed.XStorage interface of the current storage. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ implGetXStorage() const = 0;
+
+ /** Returns the names of all elements of this storage. */
+ virtual void implGetElementNames( ::std::vector< ::rtl::OUString >& orElementNames ) const = 0;
+
+ /** Implementation of opening a storage element. */
+ virtual StorageRef implOpenSubStorage( const ::rtl::OUString& rElementName, bool bCreate ) = 0;
+
+ /** Implementation of opening an input stream element. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ implOpenInputStream( const ::rtl::OUString& rElementName ) = 0;
+
+ /** Implementation of opening an output stream element. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ implOpenOutputStream( const ::rtl::OUString& rElementName ) = 0;
+
+ /** Commits the current storage. */
+ virtual void implCommit() const = 0;
+
+ /** Helper that opens and caches the specified direct substorage. */
+ StorageRef getSubStorage( const ::rtl::OUString& rElementName, bool bCreateMissing );
+
+private:
+ typedef RefMap< ::rtl::OUString, StorageBase > SubStorageMap;
+
+ SubStorageMap maSubStorages; /// Map of direct sub storages.
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ mxInStream; /// Cached base input stream (to keep it alive).
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >
+ mxOutStream; /// Cached base output stream (to keep it alive).
+ ::rtl::OUString maParentPath; /// Full path of parent storage.
+ ::rtl::OUString maStorageName; /// Name of this storage, if it is a substorage.
+ bool mbBaseStreamAccess; /// True = access base streams with empty stream name.
+ bool mbReadOnly; /// True = storage opened read-only (based on input stream).
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/textinputstream.hxx b/oox/inc/oox/helper/textinputstream.hxx
new file mode 100644
index 000000000000..2e98d3fc8c84
--- /dev/null
+++ b/oox/inc/oox/helper/textinputstream.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_RECORDINPUTSTREAM_HXX
+#define OOX_HELPER_RECORDINPUTSTREAM_HXX
+
+#include "oox/helper/binaryinputstream.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+class TextInputStream
+{
+public:
+ explicit TextInputStream( BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc );
+
+ /** Returns true, if the wrapped input stream is in EOF state. */
+ bool isEof() const;
+ /** Reads a text line from the stream. */
+ ::rtl::OUString readLine();
+
+private:
+ BinaryInputStream& mrInStrm;
+ rtl_TextEncoding meTextEnc;
+ sal_Unicode mcLastEolChar;
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/helper/zipstorage.hxx b/oox/inc/oox/helper/zipstorage.hxx
new file mode 100644
index 000000000000..0c9a15c10077
--- /dev/null
+++ b/oox/inc/oox/helper/zipstorage.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_HELPER_ZIPSTORAGE_HXX
+#define OOX_HELPER_ZIPSTORAGE_HXX
+
+#include "oox/helper/storagebase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace oox {
+
+// ============================================================================
+
+/** Implements stream access for ZIP storages containing XML streams. */
+class ZipStorage : public StorageBase
+{
+public:
+ explicit ZipStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream );
+
+ explicit ZipStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxStream );
+
+ virtual ~ZipStorage();
+
+private:
+ explicit ZipStorage(
+ const ZipStorage& rParentStorage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage,
+ const ::rtl::OUString& rElementName );
+
+ /** Returns true, if the object represents a valid storage. */
+ virtual bool implIsStorage() const;
+
+ /** Returns the com.sun.star.embed.XStorage interface of the current storage. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ implGetXStorage() const;
+
+ /** Returns the names of all elements of this storage. */
+ virtual void implGetElementNames( ::std::vector< ::rtl::OUString >& orElementNames ) const;
+
+ /** Opens and returns the specified sub storage from the storage. */
+ virtual StorageRef implOpenSubStorage( const ::rtl::OUString& rElementName, bool bCreateMissing );
+
+ /** Opens and returns the specified input stream from the storage. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ implOpenInputStream( const ::rtl::OUString& rElementName );
+
+ /** Opens and returns the specified output stream from the storage. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ implOpenOutputStream( const ::rtl::OUString& rElementName );
+
+ /** Commits the current storage. */
+ virtual void implCommit() const;
+
+private:
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > XStorageRef;
+
+ XStorageRef mxStorage; /// Storage based on input or output stream.
+};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/axbinaryreader.hxx b/oox/inc/oox/ole/axbinaryreader.hxx
new file mode 100644
index 000000000000..f26075ff52eb
--- /dev/null
+++ b/oox/inc/oox/ole/axbinaryreader.hxx
@@ -0,0 +1,298 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_AXBINARYREADER_HXX
+#define OOX_OLE_AXBINARYREADER_HXX
+
+#include <utility>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/refvector.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+/** A wrapper for a binary input stream that supports aligned read operations.
+
+ The implementation does not support seeking back the wrapped stream. All
+ seeking operations (tell, seek, align) are performed relative to the
+ position of the wrapped stream at construction time of this wrapper. It is
+ possible to construct this wrapper with an unseekable input stream without
+ loosing any functionality.
+ */
+class AxAlignedInputStream : public BinaryInputStream
+{
+public:
+ explicit AxAlignedInputStream( BinaryInputStream& rInStrm );
+
+ /** Return the current relative stream position (relative to position of
+ the wrapped stream at construction time). */
+ virtual sal_Int64 tell() const;
+ /** Seeks the stream to the passed relative position, if it is behind the
+ current position. */
+ virtual void seek( sal_Int64 nPos );
+
+ /** Reads nBytes bytes to the passed sequence.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes );
+ /** Reads nBytes bytes to the (existing) buffer opMem.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes );
+ /** Seeks the stream forward by the passed number of bytes. */
+ virtual void skip( sal_Int32 nBytes );
+
+ /** Aligns the stream to a multiple of the passed size (relative to the
+ position of the wrapped stream at construction time). */
+ void align( size_t nSize );
+
+ /** Aligns the stream according to the passed type and reads an atomar value. */
+ template< typename Type >
+ inline Type readAligned() { align( sizeof( Type ) ); return readValue< Type >(); }
+ /** Aligns the stream according to the passed type and skips the size of the type. */
+ template< typename Type >
+ inline void skipAligned() { align( sizeof( Type ) ); skip( sizeof( Type ) ); }
+
+private:
+ BinaryInputStream& mrInStrm; /// The wrapped input stream.
+ sal_Int64 mnStrmPos; /// Tracks relative position in the stream.
+};
+
+// ============================================================================
+
+/** A pair of integer values as a property. */
+typedef ::std::pair< sal_Int32, sal_Int32 > AxPairData;
+
+/** An array of string values as a property. */
+typedef ::std::vector< ::rtl::OUString > AxStringArray;
+
+// ============================================================================
+
+const sal_Char* const AX_GUID_CFONT = "{AFC20920-DA4E-11CE-B943-00AA006887B4}";
+
+const sal_uInt32 AX_FONTDATA_BOLD = 0x00000001;
+const sal_uInt32 AX_FONTDATA_ITALIC = 0x00000002;
+const sal_uInt32 AX_FONTDATA_UNDERLINE = 0x00000004;
+const sal_uInt32 AX_FONTDATA_STRIKEOUT = 0x00000008;
+const sal_uInt32 AX_FONTDATA_DISABLED = 0x00002000;
+const sal_uInt32 AX_FONTDATA_AUTOCOLOR = 0x40000000;
+
+const sal_Int32 AX_FONTDATA_LEFT = 1;
+const sal_Int32 AX_FONTDATA_RIGHT = 2;
+const sal_Int32 AX_FONTDATA_CENTER = 3;
+
+/** All entries of a font property. */
+struct AxFontData
+{
+ ::rtl::OUString maFontName; /// Name of the used font.
+ sal_uInt32 mnFontEffects; /// Font effect flags.
+ sal_Int32 mnFontHeight; /// Height of the font (not really twips, see code).
+ sal_Int32 mnFontCharSet; /// Windows character set of the font.
+ sal_Int32 mnHorAlign; /// Horizontal text alignment.
+ bool mbDblUnderline; /// True = double underline style (legacy VML drawing controls only).
+
+ explicit AxFontData();
+
+ /** Converts the internal representation of the font height to points. */
+ sal_Int16 getHeightPoints() const;
+ /** Converts the passed font height from points to the internal representation. */
+ void setHeightPoints( sal_Int16 nPoints );
+
+ /** Reads the font data settings from the passed input stream. */
+ bool importBinaryModel( BinaryInputStream& rInStrm );
+ /** Reads the font data settings from the passed input stream that contains
+ an OLE StdFont structure. */
+ bool importStdFont( BinaryInputStream& rInStrm );
+ /** Reads the font data settings from the passed input stream depending on
+ the GUID preceding the actual font data. */
+ bool importGuidAndFont( BinaryInputStream& rInStrm );
+};
+
+// ============================================================================
+
+/** Import helper to read simple and complex ActiveX form control properties
+ from a binary input stream. */
+class AxBinaryPropertyReader
+{
+public:
+ explicit AxBinaryPropertyReader( BinaryInputStream& rInStrm, bool b64BitPropFlags = false );
+
+ /** Reads the next integer property value from the stream, if the
+ respective flag in the property mask is set. */
+ template< typename StreamType, typename DataType >
+ inline void readIntProperty( DataType& ornValue )
+ { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
+ /** Reads the next boolean property value from the stream, if the
+ respective flag in the property mask is set. */
+ void readBoolProperty( bool& orbValue, bool bReverse = false );
+ /** Reads the next pair property from the stream, if the respective flag in
+ the property mask is set. */
+ void readPairProperty( AxPairData& orPairData );
+ /** Reads the next string property from the stream, if the respective flag
+ in the property mask is set. */
+ void readStringProperty( ::rtl::OUString& orValue );
+ /** Reads a string array property from the stream, if the respective flag
+ in the property mask is set. */
+ void readStringArrayProperty( AxStringArray& orArray );
+ /** Reads the next GUID property from the stream, if the respective flag
+ in the property mask is set. The GUID will be enclosed in braces. */
+ void readGuidProperty( ::rtl::OUString& orGuid );
+ /** Reads the next font property from the stream, if the respective flag in
+ the property mask is set. */
+ void readFontProperty( AxFontData& orFontData );
+ /** Reads the next picture property from the stream, if the respective flag
+ in the property mask is set. */
+ void readPictureProperty( StreamDataSequence& orPicData );
+
+ /** Skips the next integer property value in the stream, if the respective
+ flag in the property mask is set. */
+ template< typename StreamType >
+ inline void skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
+ /** Skips the next boolean property value in the stream, if the respective
+ flag in the property mask is set. */
+ inline void skipBoolProperty() { startNextProperty(); }
+ /** Skips the next pair property in the stream, if the respective flag in
+ the property mask is set. */
+ void skipPairProperty() { readPairProperty( maDummyPairData ); }
+ /** Skips the next string property in the stream, if the respective flag in
+ the property mask is set. */
+ inline void skipStringProperty() { readStringProperty( maDummyString ); }
+ /** Skips the next string array property in the stream, if the respective
+ flag in the property mask is set. */
+ inline void skipStringArrayProperty() { readStringArrayProperty( maDummyStringArray ); }
+ /** Skips the next GUID property in the stream, if the respective flag in
+ the property mask is set. */
+ inline void skipGuidProperty() { readGuidProperty( maDummyString ); }
+ /** Skips the next font property in the stream, if the respective flag in
+ the property mask is set. */
+ inline void skipFontProperty() { readFontProperty( maDummyFontData ); }
+ /** Skips the next picture property in the stream, if the respective flag
+ in the property mask is set. */
+ inline void skipPictureProperty() { readPictureProperty( maDummyPicData ); }
+ /** Has to be called for undefined properties. If the respective flag in
+ the mask is set, the property import cannot be finished successfully. */
+ inline void skipUndefinedProperty() { ensureValid( !startNextProperty() ); }
+
+ /** Final processing, reads contents of all complex properties. */
+ bool finalizeImport();
+
+private:
+ bool ensureValid( bool bCondition = true );
+ bool startNextProperty();
+
+private:
+ /** Base class for complex properties such as string, point, size, GUID, picture. */
+ struct ComplexProperty
+ {
+ virtual ~ComplexProperty();
+ virtual bool readProperty( AxAlignedInputStream& rInStrm ) = 0;
+ };
+
+ /** Complex property for a 32-bit value pair, e.g. point or size. */
+ struct PairProperty : public ComplexProperty
+ {
+ AxPairData& mrPairData;
+
+ inline explicit PairProperty( AxPairData& rPairData ) :
+ mrPairData( rPairData ) {}
+ virtual bool readProperty( AxAlignedInputStream& rInStrm );
+ };
+
+ /** Complex property for a string value. */
+ struct StringProperty : public ComplexProperty
+ {
+ ::rtl::OUString& mrValue;
+ sal_uInt32 mnSize;
+
+ inline explicit StringProperty( ::rtl::OUString& rValue, sal_uInt32 nSize ) :
+ mrValue( rValue ), mnSize( nSize ) {}
+ virtual bool readProperty( AxAlignedInputStream& rInStrm );
+ };
+
+ /** Complex property for an array of strings. */
+ struct StringArrayProperty : public ComplexProperty
+ {
+ AxStringArray& mrArray;
+ sal_uInt32 mnSize;
+ inline explicit StringArrayProperty( AxStringArray& rArray, sal_uInt32 nSize ) :
+ mrArray( rArray ), mnSize( nSize ) {}
+ virtual bool readProperty( AxAlignedInputStream& rInStrm );
+ };
+
+ /** Complex property for a GUID value. */
+ struct GuidProperty : public ComplexProperty
+ {
+ ::rtl::OUString& mrGuid;
+
+ inline explicit GuidProperty( ::rtl::OUString& rGuid ) :
+ mrGuid( rGuid ) {}
+ virtual bool readProperty( AxAlignedInputStream& rInStrm );
+ };
+
+ /** Stream property for a font structure. */
+ struct FontProperty : public ComplexProperty
+ {
+ AxFontData& mrFontData;
+
+ inline explicit FontProperty( AxFontData& rFontData ) :
+ mrFontData( rFontData ) {}
+ virtual bool readProperty( AxAlignedInputStream& rInStrm );
+ };
+
+ /** Stream property for a picture or mouse icon. */
+ struct PictureProperty : public ComplexProperty
+ {
+ StreamDataSequence& mrPicData;
+
+ inline explicit PictureProperty( StreamDataSequence& rPicData ) :
+ mrPicData( rPicData ) {}
+ virtual bool readProperty( AxAlignedInputStream& rInStrm );
+ };
+
+ typedef RefVector< ComplexProperty > ComplexPropVector;
+
+private:
+ AxAlignedInputStream maInStrm; /// The input stream to read from.
+ ComplexPropVector maLargeProps; /// Stores info for all used large properties.
+ ComplexPropVector maStreamProps; /// Stores info for all used stream data properties.
+ AxPairData maDummyPairData; /// Dummy pair for unsupported properties.
+ AxFontData maDummyFontData; /// Dummy font for unsupported properties.
+ StreamDataSequence maDummyPicData; /// Dummy picture for unsupported properties.
+ ::rtl::OUString maDummyString; /// Dummy string for unsupported properties.
+ AxStringArray maDummyStringArray; /// Dummy string array for unsupported properties.
+ sal_Int64 mnPropFlags; /// Flags specifying existing properties.
+ sal_Int64 mnNextProp; /// Next property to read.
+ sal_Int64 mnPropsEnd; /// End position of simple/large properties.
+ bool mbValid; /// True = stream still valid.
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/axcontrol.hxx b/oox/inc/oox/ole/axcontrol.hxx
new file mode 100644
index 000000000000..8bc9cd622b2b
--- /dev/null
+++ b/oox/inc/oox/ole/axcontrol.hxx
@@ -0,0 +1,955 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_AXCONTROL_HXX
+#define OOX_OLE_AXCONTROL_HXX
+
+#include <boost/shared_ptr.hpp>
+#include "oox/helper/binarystreambase.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/ole/axbinaryreader.hxx"
+#include "oox/ole/olehelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { class XControlModel; }
+ namespace container { class XIndexContainer; }
+ namespace drawing { class XDrawPage; }
+ namespace frame { class XModel; }
+ namespace form { class XFormsSupplier; }
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace oox {
+ class BinaryInputStream;
+ class GraphicHelper;
+ class PropertyMap;
+}
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+const sal_Char* const COMCTL_GUID_SCROLLBAR_60 = "{FE38753A-44A3-11D1-B5B7-0000C09000C4}";
+const sal_Char* const COMCTL_GUID_PROGRESSBAR_50 = "{0713E8D2-850A-101B-AFC0-4210102A8DA7}";
+const sal_Char* const COMCTL_GUID_PROGRESSBAR_60 = "{35053A22-8589-11D1-B16A-00C0F0283628}";
+
+const sal_uInt16 COMCTL_VERSION_50 = 5;
+const sal_uInt16 COMCTL_VERSION_60 = 6;
+
+// ----------------------------------------------------------------------------
+
+const sal_Char* const AX_GUID_COMMANDBUTTON = "{D7053240-CE69-11CD-A777-00DD01143C57}";
+const sal_Char* const AX_GUID_LABEL = "{978C9E23-D4B0-11CE-BF2D-00AA003F40D0}";
+const sal_Char* const AX_GUID_IMAGE = "{4C599241-6926-101B-9992-00000B65C6F9}";
+const sal_Char* const AX_GUID_TOGGLEBUTTON = "{8BD21D60-EC42-11CE-9E0D-00AA006002F3}";
+const sal_Char* const AX_GUID_CHECKBOX = "{8BD21D40-EC42-11CE-9E0D-00AA006002F3}";
+const sal_Char* const AX_GUID_OPTIONBUTTON = "{8BD21D50-EC42-11CE-9E0D-00AA006002F3}";
+const sal_Char* const AX_GUID_TEXTBOX = "{8BD21D10-EC42-11CE-9E0D-00AA006002F3}";
+const sal_Char* const AX_GUID_LISTBOX = "{8BD21D20-EC42-11CE-9E0D-00AA006002F3}";
+const sal_Char* const AX_GUID_COMBOBOX = "{8BD21D30-EC42-11CE-9E0D-00AA006002F3}";
+const sal_Char* const AX_GUID_SPINBUTTON = "{79176FB0-B7F2-11CE-97EF-00AA006D2776}";
+const sal_Char* const AX_GUID_SCROLLBAR = "{DFD181E0-5E2F-11CE-A449-00AA004A803D}";
+const sal_Char* const AX_GUID_FRAME = "{6E182020-F460-11CE-9BCD-00AA00608E01}";
+
+const sal_uInt32 AX_SYSCOLOR_WINDOWBACK = 0x80000005;
+const sal_uInt32 AX_SYSCOLOR_WINDOWFRAME = 0x80000006;
+const sal_uInt32 AX_SYSCOLOR_WINDOWTEXT = 0x80000008;
+const sal_uInt32 AX_SYSCOLOR_BUTTONFACE = 0x8000000F;
+const sal_uInt32 AX_SYSCOLOR_BUTTONTEXT = 0x80000012;
+
+const sal_uInt32 AX_FLAGS_ENABLED = 0x00000002;
+const sal_uInt32 AX_FLAGS_LOCKED = 0x00000004;
+const sal_uInt32 AX_FLAGS_OPAQUE = 0x00000008;
+const sal_uInt32 AX_FLAGS_COLUMNHEADS = 0x00000400;
+const sal_uInt32 AX_FLAGS_ENTIREROWS = 0x00000800;
+const sal_uInt32 AX_FLAGS_EXISTINGENTRIES = 0x00001000;
+const sal_uInt32 AX_FLAGS_CAPTIONLEFT = 0x00002000;
+const sal_uInt32 AX_FLAGS_EDITABLE = 0x00004000;
+const sal_uInt32 AX_FLAGS_IMEMODE_MASK = 0x00078000;
+const sal_uInt32 AX_FLAGS_DRAGENABLED = 0x00080000;
+const sal_uInt32 AX_FLAGS_ENTERASNEWLINE = 0x00100000;
+const sal_uInt32 AX_FLAGS_KEEPSELECTION = 0x00200000;
+const sal_uInt32 AX_FLAGS_TABASCHARACTER = 0x00400000;
+const sal_uInt32 AX_FLAGS_WORDWRAP = 0x00800000;
+const sal_uInt32 AX_FLAGS_BORDERSSUPPRESSED = 0x02000000;
+const sal_uInt32 AX_FLAGS_SELECTLINE = 0x04000000;
+const sal_uInt32 AX_FLAGS_SINGLECHARSELECT = 0x08000000;
+const sal_uInt32 AX_FLAGS_AUTOSIZE = 0x10000000;
+const sal_uInt32 AX_FLAGS_HIDESELECTION = 0x20000000;
+const sal_uInt32 AX_FLAGS_MAXLENAUTOTAB = 0x40000000;
+const sal_uInt32 AX_FLAGS_MULTILINE = 0x80000000;
+
+const sal_Int32 AX_BORDERSTYLE_NONE = 0;
+const sal_Int32 AX_BORDERSTYLE_SINGLE = 1;
+
+const sal_Int32 AX_SPECIALEFFECT_FLAT = 0;
+const sal_Int32 AX_SPECIALEFFECT_RAISED = 1;
+const sal_Int32 AX_SPECIALEFFECT_SUNKEN = 2;
+const sal_Int32 AX_SPECIALEFFECT_ETCHED = 3;
+const sal_Int32 AX_SPECIALEFFECT_BUMPED = 6;
+
+const sal_Int32 AX_PICSIZE_CLIP = 0;
+const sal_Int32 AX_PICSIZE_STRETCH = 1;
+const sal_Int32 AX_PICSIZE_ZOOM = 3;
+
+const sal_Int32 AX_PICALIGN_TOPLEFT = 0;
+const sal_Int32 AX_PICALIGN_TOPRIGHT = 1;
+const sal_Int32 AX_PICALIGN_CENTER = 2;
+const sal_Int32 AX_PICALIGN_BOTTOMLEFT = 3;
+const sal_Int32 AX_PICALIGN_BOTTOMRIGHT = 4;
+
+const sal_Int32 AX_DISPLAYSTYLE_TEXT = 1;
+const sal_Int32 AX_DISPLAYSTYLE_LISTBOX = 2;
+const sal_Int32 AX_DISPLAYSTYLE_COMBOBOX = 3;
+const sal_Int32 AX_DISPLAYSTYLE_CHECKBOX = 4;
+const sal_Int32 AX_DISPLAYSTYLE_OPTBUTTON = 5;
+const sal_Int32 AX_DISPLAYSTYLE_TOGGLE = 6;
+const sal_Int32 AX_DISPLAYSTYLE_DROPDOWN = 7;
+
+const sal_Int32 AX_SELCTION_SINGLE = 0;
+const sal_Int32 AX_SELCTION_MULTI = 1;
+const sal_Int32 AX_SELCTION_EXTENDED = 2;
+
+const sal_Int32 AX_SHOWDROPBUTTON_NEVER = 0;
+const sal_Int32 AX_SHOWDROPBUTTON_FOCUS = 1;
+const sal_Int32 AX_SHOWDROPBUTTON_ALWAYS = 2;
+
+const sal_Int32 AX_SCROLLBAR_NONE = 0x00;
+const sal_Int32 AX_SCROLLBAR_HORIZONTAL = 0x01;
+const sal_Int32 AX_SCROLLBAR_VERTICAL = 0x02;
+
+// ----------------------------------------------------------------------------
+
+/** Enumerates all UNO API control types supported by these filters. */
+enum ApiControlType
+{
+ API_CONTROL_BUTTON,
+ API_CONTROL_FIXEDTEXT,
+ API_CONTROL_IMAGE,
+ API_CONTROL_CHECKBOX,
+ API_CONTROL_RADIOBUTTON,
+ API_CONTROL_EDIT,
+ API_CONTROL_NUMERIC,
+ API_CONTROL_LISTBOX,
+ API_CONTROL_COMBOBOX,
+ API_CONTROL_SPINBUTTON,
+ API_CONTROL_SCROLLBAR,
+ API_CONTROL_TABSTRIP,
+ API_CONTROL_PROGRESSBAR,
+ API_CONTROL_GROUPBOX,
+ API_CONTROL_FRAME,
+ API_CONTROL_PAGE,
+ API_CONTROL_MULTIPAGE,
+ API_CONTROL_DIALOG
+};
+
+// ============================================================================
+
+/** Specifies how a form control supports transparent background. */
+enum ApiTransparencyMode
+{
+ API_TRANSPARENCY_NOTSUPPORTED, /// Control does not support transparency.
+ API_TRANSPARENCY_VOID, /// Transparency is enabled by missing fill color.
+ API_TRANSPARENCY_PAINTTRANSPARENT /// Transparency is enabled by the 'PaintTransparent' property.
+};
+
+/** Specifies how a form control supports the DefaultState property. */
+enum ApiDefaultStateMode
+{
+ API_DEFAULTSTATE_BOOLEAN, /// Control does not support tri-state, state is given as boolean.
+ API_DEFAULTSTATE_SHORT, /// Control does not support tri-state, state is given as short.
+ API_DEFAULTSTATE_TRISTATE /// Control supports tri-state, state is given as short.
+};
+
+// ----------------------------------------------------------------------------
+
+/** A base class with useful helper functions for something that is able to
+ convert ActiveX and ComCtl form controls.
+ */
+class ControlConverter
+{
+public:
+ explicit ControlConverter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
+ const GraphicHelper& rGraphicHelper,
+ bool bDefaultColorBgr = true );
+ virtual ~ControlConverter();
+
+ // Generic conversion -----------------------------------------------------
+
+ /** Converts the passed position in 1/100 mm to UNO properties. */
+ void convertPosition(
+ PropertyMap& rPropMap,
+ const AxPairData& rPos ) const;
+
+ /** Converts the passed size in 1/100 mm to UNO properties. */
+ void convertSize(
+ PropertyMap& rPropMap,
+ const AxPairData& rSize ) const;
+
+ /** Converts the passed encoded OLE color to UNO properties. */
+ void convertColor(
+ PropertyMap& rPropMap,
+ sal_Int32 nPropId,
+ sal_uInt32 nOleColor ) const;
+
+ /** Converts the passed StdPic picture stream to UNO properties. */
+ void convertPicture(
+ PropertyMap& rPropMap,
+ const StreamDataSequence& rPicData ) const;
+
+ /** Converts the control orientation to UNO properties. */
+ void convertOrientation(
+ PropertyMap& rPropMap,
+ bool bHorizontal ) const;
+
+ /** Converts the vertical alignment to UNO properties. */
+ void convertVerticalAlign(
+ PropertyMap& rPropMap,
+ sal_Int32 nVerticalAlign ) const;
+
+ /** Converts common scrollbar settings to UNO properties. */
+ void convertScrollBar(
+ PropertyMap& rPropMap,
+ sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nPosition,
+ sal_Int32 nSmallChange, sal_Int32 nLargeChange, bool bAwtModel ) const;
+
+ /** Binds the passed control model to the passed data sources. The
+ implementation will check which source types are supported. */
+ void bindToSources(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel,
+ const ::rtl::OUString& rCtrlSource,
+ const ::rtl::OUString& rRowSource,
+ sal_Int32 nRefSheet = 0 ) const;
+
+ // ActiveX (Forms 2.0) specific conversion --------------------------------
+
+ /** Converts the Forms 2.0 background formatting to UNO properties. */
+ void convertAxBackground(
+ PropertyMap& rPropMap,
+ sal_uInt32 nBackColor,
+ sal_uInt32 nFlags,
+ ApiTransparencyMode eTranspMode ) const;
+
+ /** Converts the Forms 2.0 border formatting to UNO properties. */
+ void convertAxBorder(
+ PropertyMap& rPropMap,
+ sal_uInt32 nBorderColor,
+ sal_Int32 nBorderStyle,
+ sal_Int32 nSpecialEffect ) const;
+
+ /** Converts the Forms 2.0 special effect to UNO properties. */
+ void convertAxVisualEffect(
+ PropertyMap& rPropMap,
+ sal_Int32 nSpecialEffect ) const;
+
+ /** Converts the passed picture stream and Forms 2.0 position to UNO
+ properties. */
+ void convertAxPicture(
+ PropertyMap& rPropMap,
+ const StreamDataSequence& rPicData,
+ sal_uInt32 nPicPos ) const;
+
+ /** Converts the passed picture stream and Forms 2.0 position to UNO
+ properties. */
+ void convertAxPicture(
+ PropertyMap& rPropMap,
+ const StreamDataSequence& rPicData,
+ sal_Int32 nPicSizeMode,
+ sal_Int32 nPicAlign,
+ bool bPicTiling ) const;
+
+ /** Converts the Forms 2.0 value for checked/unchecked/dontknow to UNO
+ properties. */
+ void convertAxState(
+ PropertyMap& rPropMap,
+ const ::rtl::OUString& rValue,
+ sal_Int32 nMultiSelect,
+ ApiDefaultStateMode eDefStateMode,
+ bool bAwtModel ) const;
+
+ /** Converts the Forms 2.0 control orientation to UNO properties. */
+ void convertAxOrientation(
+ PropertyMap& rPropMap,
+ const AxPairData& rSize,
+ sal_Int32 nOrientation ) const;
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxDocModel;
+ const GraphicHelper& mrGraphicHelper;
+ mutable PropertySet maAddressConverter;
+ mutable PropertySet maRangeConverter;
+ bool mbDefaultColorBgr;
+};
+
+// ============================================================================
+
+/** Base class for all models of form controls. */
+class ControlModelBase
+{
+public:
+ explicit ControlModelBase();
+ virtual ~ControlModelBase();
+
+ /** Sets this control model to AWT model mode. */
+ inline void setAwtModelMode() { mbAwtModel = true; }
+ /** Sets this control model to form component mode. */
+ inline void setFormComponentMode() { mbAwtModel = false; }
+
+ /** Returns the UNO service name used to construct the AWT control model,
+ or the control form component. */
+ ::rtl::OUString getServiceName() const;
+
+ /** Derived classes set specific OOXML properties at the model structure. */
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ /** Derived classes set binary data (picture, mouse icon) at the model structure. */
+ virtual void importPictureData( sal_Int32 nPropId, BinaryInputStream& rInStrm );
+ /** Derived classes import a form control model from the passed input stream. */
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm ) = 0;
+
+ /** Derived classes return the UNO control type enum value. */
+ virtual ApiControlType getControlType() const = 0;
+ /** Derived classes convert all control properties. */
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+ /** Converts the control size to UNO properties. */
+ void convertSize( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+public: // direct access needed for legacy VML drawing controls
+ AxPairData maSize; /// Size of the control in 1/100 mm.
+
+protected:
+ bool mbAwtModel; /// True = AWT control model, false = form component.
+};
+
+typedef ::boost::shared_ptr< ControlModelBase > ControlModelRef;
+
+// ============================================================================
+
+/** Base class for all models of ComCtl form controls. */
+class ComCtlModelBase : public ControlModelBase
+{
+public:
+ explicit ComCtlModelBase(
+ sal_uInt32 nDataPartId5, sal_uInt32 nDataPartId6, sal_uInt16 nVersion,
+ bool bCommonPart, bool bComplexPart );
+
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+protected:
+ virtual void importControlData( BinaryInputStream& rInStrm ) = 0;
+ virtual void importCommonExtraData( BinaryInputStream& rInStrm );
+ virtual void importCommonTrailingData( BinaryInputStream& rInStrm );
+
+private:
+ /** Returns the data part identifier according to the model version. */
+ sal_uInt32 getDataPartId() const;
+
+ bool readPartHeader( BinaryInputStream& rInStrm,
+ sal_uInt32 nExpPartId,
+ sal_uInt16 nExpMajor = SAL_MAX_UINT16,
+ sal_uInt16 nExpMinor = SAL_MAX_UINT16 );
+
+ bool importSizePart( BinaryInputStream& rInStrm );
+ bool importCommonPart( BinaryInputStream& rInStrm, sal_uInt32 nPartSize );
+ bool importComplexPart( BinaryInputStream& rInStrm );
+
+protected:
+ StdFontInfo maFontData; /// Font formatting.
+ StreamDataSequence maMouseIcon; /// Binary picture stream for mouse icon.
+ sal_uInt32 mnFlags; /// Common flags for ComCtl controls.
+ const sal_uInt16 mnVersion; /// Current version of the ComCtl control model.
+
+private:
+ sal_uInt32 mnDataPartId5; /// Identifier for version 5.0 control data.
+ sal_uInt32 mnDataPartId6; /// Identifier for version 6.0 control data.
+ bool mbCommonPart; /// True = the COMCTL_COMMONDATA part exists.
+ bool mbComplexPart; /// True = the COMCTL_COMPLEXDATA part exists.
+};
+
+// ============================================================================
+
+/** Model for a ComCtl scroll bar. */
+class ComCtlScrollBarModel : public ComCtlModelBase
+{
+public:
+ explicit ComCtlScrollBarModel( sal_uInt16 nVersion );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+protected:
+ virtual void importControlData( BinaryInputStream& rInStrm );
+
+private:
+ sal_uInt32 mnScrollBarFlags; /// Special flags for scroll bar model.
+ sal_Int32 mnLargeChange; /// Increment step size (thumb).
+ sal_Int32 mnSmallChange; /// Increment step size (buttons).
+ sal_Int32 mnMin; /// Minimum of the value range.
+ sal_Int32 mnMax; /// Maximum of the value range.
+ sal_Int32 mnPosition; /// Value of the spin button.
+};
+
+// ============================================================================
+
+/** Model for a ComCtl progress bar. */
+class ComCtlProgressBarModel : public ComCtlModelBase
+{
+public:
+ explicit ComCtlProgressBarModel( sal_uInt16 nVersion );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+protected:
+ virtual void importControlData( BinaryInputStream& rInStrm );
+
+private:
+ float mfMin; /// Minimum of the value range.
+ float mfMax; /// Maximum of the value range.
+ sal_uInt16 mnVertical; /// 0 = horizontal, 1 = vertical.
+ sal_uInt16 mnSmooth; /// 0 = progress blocks, 1 = pixel resolution.
+};
+
+// ============================================================================
+
+/** Base class for all models of Form 2.0 form controls. */
+class AxControlModelBase : public ControlModelBase
+{
+public:
+ explicit AxControlModelBase();
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+};
+
+// ============================================================================
+
+/** Base class for Forms 2.0 controls supporting text formatting. */
+class AxFontDataModel : public AxControlModelBase
+{
+public:
+ explicit AxFontDataModel( bool bSupportsAlign = true );
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+ /** Returns the font height in points. */
+ inline sal_Int16 getFontHeight() const { return maFontData.getHeightPoints(); }
+
+public: // direct access needed for legacy VML drawing controls
+ AxFontData maFontData; /// The font settings.
+
+private:
+ bool mbSupportsAlign; /// True = UNO model supports Align property.
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 command button. */
+class AxCommandButtonModel : public AxFontDataModel
+{
+public:
+ explicit AxCommandButtonModel();
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ virtual void importPictureData( sal_Int32 nPropId, BinaryInputStream& rInStrm );
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+public: // direct access needed for legacy VML drawing controls
+ StreamDataSequence maPictureData; /// Binary picture stream.
+ ::rtl::OUString maCaption; /// Visible caption of the button.
+ sal_uInt32 mnTextColor; /// Text color.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_uInt32 mnPicturePos; /// Position of the picture relative to text.
+ sal_Int32 mnVerticalAlign; /// Vertical alignment (legacy VML drawing controls only).
+ bool mbFocusOnClick; /// True = take focus on click.
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 label. */
+class AxLabelModel : public AxFontDataModel
+{
+public:
+ explicit AxLabelModel();
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+public: // direct access needed for legacy VML drawing controls
+ ::rtl::OUString maCaption; /// Visible caption of the button.
+ sal_uInt32 mnTextColor; /// Text color.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_uInt32 mnBorderColor; /// Flat border color.
+ sal_Int32 mnBorderStyle; /// Flat border style.
+ sal_Int32 mnSpecialEffect; /// 3D border effect.
+ sal_Int32 mnVerticalAlign; /// Vertical alignment (legacy VML drawing controls only).
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 image. */
+class AxImageModel : public AxControlModelBase
+{
+public:
+ explicit AxImageModel();
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ virtual void importPictureData( sal_Int32 nPropId, BinaryInputStream& rInStrm );
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+private:
+ StreamDataSequence maPictureData; /// Binary picture stream.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_uInt32 mnBorderColor; /// Flat border color.
+ sal_Int32 mnBorderStyle; /// Flat border style.
+ sal_Int32 mnSpecialEffect; /// 3D border effect.
+ sal_Int32 mnPicSizeMode; /// Clip, stretch, zoom.
+ sal_Int32 mnPicAlign; /// Anchor position of the picture.
+ bool mbPicTiling; /// True = picture is repeated.
+};
+
+// ============================================================================
+
+/** Base class for a Forms 2.0 morph data control. */
+class AxMorphDataModelBase : public AxFontDataModel
+{
+public:
+ explicit AxMorphDataModelBase();
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ virtual void importPictureData( sal_Int32 nPropId, BinaryInputStream& rInStrm );
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+public: // direct access needed for legacy VML drawing controls
+ StreamDataSequence maPictureData; /// Binary picture stream.
+ ::rtl::OUString maCaption; /// Visible caption of the button.
+ ::rtl::OUString maValue; /// Current value of the control.
+ ::rtl::OUString maGroupName; /// Group name for option buttons.
+ sal_uInt32 mnTextColor; /// Text color.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_uInt32 mnPicturePos; /// Position of the picture relative to text.
+ sal_uInt32 mnBorderColor; /// Flat border color.
+ sal_Int32 mnBorderStyle; /// Flat border style.
+ sal_Int32 mnSpecialEffect; /// 3D border effect.
+ sal_Int32 mnDisplayStyle; /// Type of the morph control.
+ sal_Int32 mnMultiSelect; /// Selection mode.
+ sal_Int32 mnScrollBars; /// Horizontal/vertical scroll bar.
+ sal_Int32 mnMatchEntry; /// Auto completion mode.
+ sal_Int32 mnShowDropButton; /// When to show the dropdown button.
+ sal_Int32 mnMaxLength; /// Maximum character count.
+ sal_Int32 mnPasswordChar; /// Password character in edit fields.
+ sal_Int32 mnListRows; /// Number of rows in dropdown box.
+ sal_Int32 mnVerticalAlign; /// Vertical alignment (legacy VML drawing controls only).
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 toggle button. */
+class AxToggleButtonModel : public AxMorphDataModelBase
+{
+public:
+ explicit AxToggleButtonModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 check box. */
+class AxCheckBoxModel : public AxMorphDataModelBase
+{
+public:
+ explicit AxCheckBoxModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 option button. */
+class AxOptionButtonModel : public AxMorphDataModelBase
+{
+public:
+ explicit AxOptionButtonModel();
+
+ /** Returns the group name used to goup several option buttons gogether. */
+ inline const ::rtl::OUString& getGroupName() const { return maGroupName; }
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 text box. */
+class AxTextBoxModel : public AxMorphDataModelBase
+{
+public:
+ explicit AxTextBoxModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a numeric field (legacy drawing controls only). */
+class AxNumericFieldModel : public AxMorphDataModelBase
+{
+public:
+ explicit AxNumericFieldModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 list box. */
+class AxListBoxModel : public AxMorphDataModelBase
+{
+public:
+ explicit AxListBoxModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 combo box. */
+class AxComboBoxModel : public AxMorphDataModelBase
+{
+public:
+ explicit AxComboBoxModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 spin button. */
+class AxSpinButtonModel : public AxControlModelBase
+{
+public:
+ explicit AxSpinButtonModel();
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+public: // direct access needed for legacy VML drawing controls
+ sal_uInt32 mnArrowColor; /// Button arrow color.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_Int32 mnOrientation; /// Orientation of the buttons.
+ sal_Int32 mnMin; /// Minimum of the value range.
+ sal_Int32 mnMax; /// Maximum of the value range.
+ sal_Int32 mnPosition; /// Value of the spin button.
+ sal_Int32 mnSmallChange; /// Increment step size.
+ sal_Int32 mnDelay; /// Repeat delay in milliseconds.
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 scroll bar. */
+class AxScrollBarModel : public AxControlModelBase
+{
+public:
+ explicit AxScrollBarModel();
+
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+public: // direct access needed for legacy VML drawing controls
+ sal_uInt32 mnArrowColor; /// Button arrow color.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_Int32 mnOrientation; /// Orientation of the buttons.
+ sal_Int32 mnPropThumb; /// Proportional thumb size.
+ sal_Int32 mnMin; /// Minimum of the value range.
+ sal_Int32 mnMax; /// Maximum of the value range.
+ sal_Int32 mnPosition; /// Value of the spin button.
+ sal_Int32 mnSmallChange; /// Increment step size (buttons).
+ sal_Int32 mnLargeChange; /// Increment step size (thumb).
+ sal_Int32 mnDelay; /// Repeat delay in milliseconds.
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 tabstrip control. */
+class AxTabStripModel : public AxFontDataModel
+{
+public:
+ explicit AxTabStripModel();
+
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+ /** Returns the caption with the specified zero-based index. */
+ ::rtl::OUString getCaption( sal_Int32 nIndex ) const;
+
+private:
+ AxStringArray maCaptions; /// Captions of all tabs.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnTextColor; /// Text color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_Int32 mnSelectedTab; /// The index of the selected tab.
+ sal_uInt32 mnTabStyle; /// Visual style of the tabs.
+ sal_Int32 mnTabFlagCount; /// Number of entries in tab flag array.
+};
+
+typedef ::boost::shared_ptr< AxTabStripModel > AxTabStripModelRef;
+
+// ============================================================================
+
+typedef ::std::vector< ::rtl::OUString > AxClassTable;
+
+/** Base class for ActiveX container controls. */
+class AxContainerModelBase : public AxFontDataModel
+{
+public:
+ explicit AxContainerModelBase( bool bFontSupport = false );
+
+ /** Allows to set single properties specified by XML token identifier. */
+ virtual void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ /** Reads the leading structure in the 'f' stream containing the model for
+ this control. */
+ virtual bool importBinaryModel( BinaryInputStream& rInStrm );
+ /** Converts font settings if supported. */
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+ /** Reads the class table structure for embedded controls following the own
+ model from the 'f' stream. */
+ bool importClassTable( BinaryInputStream& rInStrm, AxClassTable& orClassTable );
+
+public: // direct access needed for legacy VML drawing controls
+ StreamDataSequence maPictureData; /// Binary picture stream.
+ ::rtl::OUString maCaption; /// Visible caption of the form.
+ AxPairData maLogicalSize; /// Logical form size (scroll area).
+ AxPairData maScrollPos; /// Scroll position.
+ sal_uInt32 mnBackColor; /// Fill color.
+ sal_uInt32 mnTextColor; /// Text color.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_uInt32 mnBorderColor; /// Flat border color.
+ sal_Int32 mnBorderStyle; /// Flat border style.
+ sal_Int32 mnScrollBars; /// Horizontal/vertical scroll bar.
+ sal_Int32 mnCycleType; /// Cycle in all forms or in this form.
+ sal_Int32 mnSpecialEffect; /// 3D border effect.
+ sal_Int32 mnPicAlign; /// Anchor position of the picture.
+ sal_Int32 mnPicSizeMode; /// Clip, stretch, zoom.
+ bool mbPicTiling; /// True = picture is repeated.
+ bool mbFontSupport; /// True = control supports the font property.
+};
+
+typedef ::boost::shared_ptr< AxContainerModelBase > AxContainerModelRef;
+
+// ============================================================================
+
+/** Model for a Forms 2.0 frame control. */
+class AxFrameModel : public AxContainerModelBase
+{
+public:
+ explicit AxFrameModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 formpage control (a single page in a multipage control). */
+class AxFormPageModel : public AxContainerModelBase
+{
+public:
+ explicit AxFormPageModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 multipage control. Contains the tabstrip control
+ (class AxTabStripModel) and the single pages (class AxFormPageModel). */
+class AxMultiPageModel : public AxContainerModelBase
+{
+public:
+ explicit AxMultiPageModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+
+ /** Sets the tabstrip control model related to this multipage control.
+ Contains all formatting attributes of the page tabs. */
+ void setTabStripModel( const AxTabStripModelRef& rxTabStrip );
+
+private:
+ AxTabStripModelRef mxTabStrip;
+};
+
+// ============================================================================
+
+/** Model for a Forms 2.0 user form. */
+class AxUserFormModel : public AxContainerModelBase
+{
+public:
+ explicit AxUserFormModel();
+
+ virtual ApiControlType getControlType() const;
+ virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+// ============================================================================
+
+/** A form control embedded in a document draw page. Contains a specific model
+ structure according to the type of the control. */
+class EmbeddedControl
+{
+public:
+ explicit EmbeddedControl( const ::rtl::OUString& rName );
+ virtual ~EmbeddedControl();
+
+ /** Creates and returns the internal control model of the specified type. */
+ template< typename ModelType >
+ inline ModelType& createModel();
+
+ /** Creates and returns the internal control model of the specified type. */
+ template< typename ModelType, typename ParamType >
+ inline ModelType& createModel( const ParamType& rParam );
+
+ /** Creates and returns the internal control model according to the passed
+ MS class identifier. */
+ ControlModelBase* createModelFromGuid( const ::rtl::OUString& rClassId );
+
+ /** Returns true, if the internal control model exists. */
+ inline bool hasModel() const { return mxModel.get() != 0; }
+ /** Returns read-only access to the internal control model. */
+ inline const ControlModelBase* getModel() const { return mxModel.get(); }
+ /** Returns read/write access to the internal control model. */
+ inline ControlModelBase* getModel() { return mxModel.get(); }
+
+ /** Returns the UNO service name needed to construct the control model. */
+ ::rtl::OUString getServiceName() const;
+
+ /** Converts all control properties and inserts them into the passed model. */
+ bool convertProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel,
+ const ControlConverter& rConv ) const;
+
+private:
+ ControlModelRef mxModel; /// Control model containing the properties.
+ ::rtl::OUString maName; /// Name of the control.
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename ModelType >
+inline ModelType& EmbeddedControl::createModel()
+{
+ ::boost::shared_ptr< ModelType > xModel( new ModelType );
+ mxModel = xModel;
+ xModel->setFormComponentMode();
+ return *xModel;
+}
+
+template< typename ModelType, typename ParamType >
+inline ModelType& EmbeddedControl::createModel( const ParamType& rParam )
+{
+ ::boost::shared_ptr< ModelType > xModel( new ModelType( rParam ) );
+ mxModel = xModel;
+ xModel->setFormComponentMode();
+ return *xModel;
+}
+
+// ============================================================================
+
+/** A wrapper for a control form embedded directly in a draw page. */
+class EmbeddedForm
+{
+public:
+ explicit EmbeddedForm(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& rxDrawPage,
+ const GraphicHelper& rGraphicHelper,
+ bool bDefaultColorBgr = true );
+
+ /** Converts the passed control and inserts the control model into the form.
+ @return The API control model, if conversion was successful. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >
+ convertAndInsert( const EmbeddedControl& rControl, sal_Int32& rnCtrlIndex );
+
+ /** Returns the XIndexContainer interface of the UNO control form, if existing. */
+ inline ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >
+ getXForm() const { return mxFormIC; }
+
+private:
+ /** Creates the form that will hold the form controls. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >
+ createXForm();
+
+private:
+ ControlConverter maControlConv;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxModelFactory;
+ ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormsSupplier > mxFormsSupp;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > mxFormIC;
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/axcontrolfragment.hxx b/oox/inc/oox/ole/axcontrolfragment.hxx
new file mode 100644
index 000000000000..a5273070ba8f
--- /dev/null
+++ b/oox/inc/oox/ole/axcontrolfragment.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_AXCONTROLFRAGMENT_HXX
+#define OOX_OLE_AXCONTROLFRAGMENT_HXX
+
+#include "oox/core/fragmenthandler2.hxx"
+
+namespace oox {
+namespace ole {
+
+class ControlModelBase;
+class EmbeddedControl;
+
+// ============================================================================
+
+/** Context handler for ActiveX form control model properties. */
+class AxControlPropertyContext : public ::oox::core::ContextHandler2
+{
+public:
+ explicit AxControlPropertyContext(
+ ::oox::core::FragmentHandler2& rFragment,
+ ControlModelBase& rModel );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ ControlModelBase& mrModel;
+ sal_Int32 mnPropId; /// Identifier of currently processed property.
+};
+
+// ============================================================================
+
+/** Fragment handler for an embedded ActiveX form control fragment. */
+class AxControlFragment : public ::oox::core::FragmentHandler2
+{
+public:
+ explicit AxControlFragment(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ EmbeddedControl& rControl );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ EmbeddedControl& mrControl;
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/olehelper.hxx b/oox/inc/oox/ole/olehelper.hxx
new file mode 100644
index 000000000000..98085e66cfd8
--- /dev/null
+++ b/oox/inc/oox/ole/olehelper.hxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_OLEHELPER_HXX
+#define OOX_OLE_OLEHELPER_HXX
+
+#include <rtl/ustring.hxx>
+#include "oox/helper/binarystreambase.hxx"
+
+namespace oox {
+ class BinaryInputStream;
+ class GraphicHelper;
+}
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+const sal_Char* const OLE_GUID_STDFONT = "{0BE35203-8F91-11CE-9DE3-00AA004BB851}";
+const sal_Char* const OLE_GUID_STDPIC = "{0BE35204-8F91-11CE-9DE3-00AA004BB851}";
+const sal_Char* const OLE_GUID_STDHLINK = "{79EAC9D0-BAF9-11CE-8C82-00AA004BA90B}";
+
+// ============================================================================
+
+const sal_uInt16 OLE_STDFONT_NORMAL = 400;
+const sal_uInt16 OLE_STDFONT_BOLD = 700;
+
+const sal_uInt8 OLE_STDFONT_ITALIC = 0x02;
+const sal_uInt8 OLE_STDFONT_UNDERLINE = 0x04;
+const sal_uInt8 OLE_STDFONT_STRIKE = 0x08;
+
+/** Stores data about a StdFont font structure. */
+struct StdFontInfo
+{
+ ::rtl::OUString maName; /// Font name.
+ sal_uInt32 mnHeight; /// Font height (1/10,000 points).
+ sal_uInt16 mnWeight; /// Font weight (normal/bold).
+ sal_uInt16 mnCharSet; /// Font charset.
+ sal_uInt8 mnFlags; /// Font flags.
+
+ explicit StdFontInfo();
+ explicit StdFontInfo(
+ const ::rtl::OUString& rName,
+ sal_uInt32 nHeight,
+ sal_uInt16 nWeight = OLE_STDFONT_NORMAL,
+ sal_uInt16 nCharSet = WINDOWS_CHARSET_ANSI,
+ sal_uInt8 nFlags = 0 );
+};
+
+// ============================================================================
+
+/** Stores data about a StdHlink hyperlink. */
+struct StdHlinkInfo
+{
+ ::rtl::OUString maTarget;
+ ::rtl::OUString maLocation;
+ ::rtl::OUString maDisplay;
+ ::rtl::OUString maFrame;
+};
+
+// ============================================================================
+
+/** Static helper functions for OLE import/export. */
+class OleHelper
+{
+public:
+ /** Returns the UNO RGB color from the passed encoded OLE color.
+
+ @param bDefaultColorBgr
+ True = OLE default color type is treated as BGR color.
+ False = OLE default color type is treated as palette color.
+ */
+ static sal_Int32 decodeOleColor(
+ const GraphicHelper& rGraphicHelper,
+ sal_uInt32 nOleColor,
+ bool bDefaultColorBgr = true );
+
+ /** Returns the OLE color from the passed UNO RGB color.
+ */
+ static sal_uInt32 encodeOleColor( sal_Int32 nRgbColor );
+
+ /** Imports a GUID from the passed binary stream and returns its string
+ representation (in uppercase characters).
+ */
+ static ::rtl::OUString importGuid( BinaryInputStream& rInStrm );
+
+ /** Imports an OLE StdFont font structure from the current position of the
+ passed binary stream.
+ */
+ static bool importStdFont(
+ StdFontInfo& orFontInfo,
+ BinaryInputStream& rInStrm,
+ bool bWithGuid );
+
+ /** Imports an OLE StdPic picture from the current position of the passed
+ binary stream.
+ */
+ static bool importStdPic(
+ StreamDataSequence& orGraphicData,
+ BinaryInputStream& rInStrm,
+ bool bWithGuid );
+
+ /** Imports an OLE StdHlink from the current position of the passed binary
+ stream.
+ */
+ static bool importStdHlink(
+ StdHlinkInfo& orHlinkInfo,
+ BinaryInputStream& rInStrm,
+ bool bWithGuid );
+
+private:
+ OleHelper(); // not implemented
+ ~OleHelper(); // not implemented
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/oleobjecthelper.hxx b/oox/inc/oox/ole/oleobjecthelper.hxx
new file mode 100644
index 000000000000..c3a58213abc9
--- /dev/null
+++ b/oox/inc/oox/ole/oleobjecthelper.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_OLEOBJECTHELPER_HXX
+#define OOX_OLE_OLEOBJECTHELPER_HXX
+
+#include "oox/helper/binarystreambase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Size; }
+ namespace document { class XEmbeddedObjectResolver; }
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace oox { class PropertyMap; }
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+/** Contains generic information about an OLE object. */
+struct OleObjectInfo
+{
+ StreamDataSequence maEmbeddedData; /// Data of an embedded OLE object.
+ ::rtl::OUString maTargetLink; /// Path to external data for linked OLE object.
+ ::rtl::OUString maProgId;
+ bool mbLinked; /// True = linked OLE object, false = embedded OLE object.
+ bool mbShowAsIcon; /// True = show as icon, false = show contents.
+ bool mbAutoUpdate;
+
+ explicit OleObjectInfo();
+};
+
+// ============================================================================
+
+/** Helper for OLE object handling. */
+class OleObjectHelper
+{
+public:
+ explicit OleObjectHelper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
+ ~OleObjectHelper();
+
+ bool importOleObject(
+ PropertyMap& rPropMap,
+ const OleObjectInfo& rOleObject,
+ const ::com::sun::star::awt::Size& rObjSize );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedObjectResolver > mxResolver;
+ const ::rtl::OUString maEmbeddedObjScheme;
+ sal_Int32 mnObjectId;
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/olestorage.hxx b/oox/inc/oox/ole/olestorage.hxx
new file mode 100644
index 000000000000..eabcfd4d0f87
--- /dev/null
+++ b/oox/inc/oox/ole/olestorage.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_OLESTORAGE_HXX
+#define OOX_OLE_OLESTORAGE_HXX
+
+#include "oox/helper/storagebase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameContainer; }
+ namespace lang { class XMultiServiceFactory; }
+} } }
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+/** Implements stream access for binary OLE storages. */
+class OleStorage : public StorageBase
+{
+public:
+ explicit OleStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream,
+ bool bBaseStreamAccess );
+
+ explicit OleStorage(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream,
+ bool bBaseStreamAccess );
+
+ virtual ~OleStorage();
+
+private:
+ explicit OleStorage(
+ const OleStorage& rParentStorage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxStorage,
+ const ::rtl::OUString& rElementName,
+ bool bReadOnly );
+ explicit OleStorage(
+ const OleStorage& rParentStorage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream,
+ const ::rtl::OUString& rElementName );
+
+ /** Initializes the API storage object for input. */
+ void initStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream );
+ /** Initializes the API storage object for input/output. */
+ void initStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream );
+
+ /** Returns true, if the object represents a valid storage. */
+ virtual bool implIsStorage() const;
+
+ /** Returns the com.sun.star.embed.XStorage interface of the current storage.
+
+ @attention
+ This function is not implemented for binary OLE storages.
+ */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ implGetXStorage() const;
+
+ /** Returns the names of all elements of this storage. */
+ virtual void implGetElementNames( ::std::vector< ::rtl::OUString >& orElementNames ) const;
+
+ /** Opens and returns the specified sub storage from the storage. */
+ virtual StorageRef implOpenSubStorage( const ::rtl::OUString& rElementName, bool bCreateMissing );
+
+ /** Opens and returns the specified input stream from the storage. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ implOpenInputStream( const ::rtl::OUString& rElementName );
+
+ /** Opens and returns the specified output stream from the storage. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ implOpenOutputStream( const ::rtl::OUString& rElementName );
+
+ /** Commits the current storage. */
+ virtual void implCommit() const;
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
+ mxFactory; /// Factory for storage/stream creation.
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ mxStorage; /// Access to elements of this sub storage.
+ const OleStorage* mpParentStorage; /// Parent OLE storage that contains this storage.
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/vbacontrol.hxx b/oox/inc/oox/ole/vbacontrol.hxx
new file mode 100644
index 000000000000..8c4274ffda7e
--- /dev/null
+++ b/oox/inc/oox/ole/vbacontrol.hxx
@@ -0,0 +1,219 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_VBACONTROL_HXX
+#define OOX_OLE_VBACONTROL_HXX
+
+#include "oox/ole/axcontrol.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameContainer; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace oox { class StorageBase; }
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+/** Common properties for all controls that are part of a VBA user form or of
+ another container control in a VBA user form. */
+class VbaSiteModel
+{
+public:
+ explicit VbaSiteModel();
+ virtual ~VbaSiteModel();
+
+ /** Allows to set single properties specified by XML token identifier. */
+ void importProperty( sal_Int32 nPropId, const ::rtl::OUString& rValue );
+ /** Imports the site model data from the passed input stream. */
+ bool importBinaryModel( BinaryInputStream& rInStrm );
+ /** Moves the control relative to its current position by the passed distance. */
+ void moveRelative( const AxPairData& rDistance );
+
+ /** Returns the programmatical name of the control. */
+ inline const ::rtl::OUString& getName() const { return maName; }
+ /** Returns the position of the control in its parent. */
+ inline const AxPairData& getPosition() const { return maPos; }
+ /** Returns the unique identifier of this control. */
+ inline sal_Int32 getId() const { return mnId; }
+ /** Returns true, if the control is visible. */
+ bool isVisible() const;
+ /** Returns true, if this control is a container control. */
+ bool isContainer() const;
+ /** Returns the length of the stream data for stream based controls. */
+ sal_uInt32 getStreamLength() const;
+ /** Returns the name of the substorage for the container control data. */
+ ::rtl::OUString getSubStorageName() const;
+ /** Returns the tab index of the control. */
+ inline sal_Int16 getTabIndex() const { return mnTabIndex; }
+
+ /** Tries to create the control model according to the site model. */
+ ControlModelRef createControlModel( const AxClassTable& rClassTable ) const;
+ /** Converts all form site properties. */
+ void convertProperties(
+ PropertyMap& rPropMap,
+ const ControlConverter& rConv,
+ ApiControlType eCtrlType,
+ sal_Int32 nCtrlIndex ) const;
+
+ /** Binds the passed control model to the data sources. The implementation
+ will check which source types are supported. */
+ void bindToSources(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel,
+ const ControlConverter& rConv ) const;
+
+protected:
+ ::rtl::OUString maName; /// Name of the control.
+ ::rtl::OUString maTag; /// User defined tag.
+ ::rtl::OUString maToolTip; /// Tool tip for the control.
+ ::rtl::OUString maControlSource; /// Linked cell for the control value in a spreadsheet.
+ ::rtl::OUString maRowSource; /// Source data for the control in a spreadsheet.
+ AxPairData maPos; /// Position in parent container.
+ sal_Int32 mnId; /// Control identifier.
+ sal_Int32 mnHelpContextId; /// Help context identifier.
+ sal_uInt32 mnFlags; /// Various flags.
+ sal_uInt32 mnStreamLen; /// Size of control stream data.
+ sal_Int16 mnTabIndex; /// Tab order index.
+ sal_uInt16 mnClassIdOrCache; /// Class name identifier or GUID cache index.
+ sal_uInt16 mnGroupId; /// Group identifier for grouped controls.
+};
+
+typedef ::boost::shared_ptr< VbaSiteModel > VbaSiteModelRef;
+
+// ============================================================================
+
+/** A control that is embedded in a VBA user form or in another container
+ control in a VBA user form.
+
+ The control may be a 'simple' control with its data stored in the 'o'
+ stream, or it may be a container control with its data stored in an own
+ substorage.
+ */
+class VbaFormControl
+{
+public:
+ explicit VbaFormControl();
+ virtual ~VbaFormControl();
+
+ /** Imports the model from the passed stream or storage, depending on the
+ control's type. Imports all embedded controls, if this is a container. */
+ void importModelOrStorage(
+ BinaryInputStream& rInStrm,
+ StorageBase& rStrg,
+ const AxClassTable& rClassTable );
+
+ /** Returns the programmatical name of the control. */
+ ::rtl::OUString getControlName() const;
+ /** Returns the unique identifier of this control. */
+ sal_Int32 getControlId() const;
+
+ /** Creates the UNO control model, inserts it into the passed container,
+ and converts all control properties. */
+ void createAndConvert(
+ sal_Int32 nCtrlIndex,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxParentNC,
+ const ControlConverter& rConv ) const;
+
+protected:
+ /** Creates and imports the control model containing properties of the control. */
+ void importControlModel( BinaryInputStream& rInStrm, const AxClassTable& rClassTable );
+ /** Creates and imports the control model, and imports all embedded
+ controls from the passed substorage. */
+ void importStorage( StorageBase& rStrg, const AxClassTable& rClassTable );
+
+ /** Converts all control properties, and inserts and converts embedded controls. */
+ bool convertProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel,
+ const ControlConverter& rConv,
+ sal_Int32 nCtrlIndex ) const;
+
+private:
+ typedef RefVector< VbaFormControl > VbaFormControlVector;
+ typedef VbaFormControlVector::value_type VbaFormControlRef;
+
+ /** Creates the control model according to the current site model. */
+ void createControlModel( const AxClassTable& rClassTable );
+ /** Imports the site model data containing common properties of the control. */
+ bool importSiteModel( BinaryInputStream& rInStrm );
+
+ /** Imports the site models of all embedded controls from the 'f' stream. */
+ bool importEmbeddedSiteModels( BinaryInputStream& rInStrm );
+ /* Final processing of all embedded controls after import. */
+ void finalizeEmbeddedControls();
+
+ /** Moves the control relative to its current position by the passed distance. */
+ void moveRelative( const AxPairData& rDistance );
+ /** Moves all embedded controls from their relative position in this
+ control to an absolute position in the parent of this control. */
+ void moveEmbeddedToAbsoluteParent();
+
+ /** Functor for comparing controls by their tab index. */
+ static bool compareByTabIndex( const VbaFormControlRef& rxLeft, const VbaFormControlRef& rxRight );
+
+protected:
+ VbaSiteModelRef mxSiteModel; /// Common control properties.
+ ControlModelRef mxCtrlModel; /// Specific control properties.
+
+private:
+ VbaFormControlVector maControls; /// All embedded form controls.
+ AxClassTable maClassTable; /// Class identifiers for exotic embedded controls.
+};
+
+// ============================================================================
+
+class VbaUserForm : public VbaFormControl
+{
+public:
+ explicit VbaUserForm(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
+ const GraphicHelper& rGraphicHelper,
+ bool bDefaultColorBgr = true );
+
+ /** Imports the form and its embedded controls, and inserts the form with
+ all its controls into the passed dialog library. */
+ void importForm(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxDialogLib,
+ StorageBase& rVbaFormStrg,
+ const ::rtl::OUString& rModuleName,
+ rtl_TextEncoding eTextEnc );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxCompContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxDocModel;
+ ControlConverter maConverter;
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/vbahelper.hxx b/oox/inc/oox/ole/vbahelper.hxx
new file mode 100644
index 000000000000..aa7b3a081c8d
--- /dev/null
+++ b/oox/inc/oox/ole/vbahelper.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_VBAHELPER_HXX
+#define OOX_OLE_VBAHELPER_HXX
+
+#include "oox/helper/binarystreambase.hxx"
+
+namespace oox { class BinaryInputStream; }
+
+namespace oox {
+namespace ole {
+
+// Directory stream record identifiers ========================================
+
+const sal_uInt16 VBA_ID_MODULECOOKIE = 0x002C;
+const sal_uInt16 VBA_ID_MODULEDOCSTRING = 0x001C;
+const sal_uInt16 VBA_ID_MODULEDOCSTRINGUNICODE = 0x0048;
+const sal_uInt16 VBA_ID_MODULEEND = 0x002B;
+const sal_uInt16 VBA_ID_MODULEHELPCONTEXT = 0x001E;
+const sal_uInt16 VBA_ID_MODULENAME = 0x0019;
+const sal_uInt16 VBA_ID_MODULENAMEUNICODE = 0x0047;
+const sal_uInt16 VBA_ID_MODULEOFFSET = 0x0031;
+const sal_uInt16 VBA_ID_MODULEPRIVATE = 0x0028;
+const sal_uInt16 VBA_ID_MODULEREADONLY = 0x0025;
+const sal_uInt16 VBA_ID_MODULESTREAMNAME = 0x001A;
+const sal_uInt16 VBA_ID_MODULESTREAMNAMEUNICODE = 0x0032;
+const sal_uInt16 VBA_ID_MODULETYPEDOCUMENT = 0x0022;
+const sal_uInt16 VBA_ID_MODULETYPEPROCEDURAL = 0x0021;
+const sal_uInt16 VBA_ID_PROJECTCODEPAGE = 0x0003;
+const sal_uInt16 VBA_ID_PROJECTEND = 0x0010;
+const sal_uInt16 VBA_ID_PROJECTMODULES = 0x000F;
+const sal_uInt16 VBA_ID_PROJECTNAME = 0x0004;
+const sal_uInt16 VBA_ID_PROJECTVERSION = 0x0009;
+
+// ============================================================================
+
+/** Static helper functions for the VBA filters. */
+class VbaHelper
+{
+public:
+ /** Returns the full Basic script URL from a VBA module and macro name.
+ The script is assumed to be in a document library. */
+ static ::rtl::OUString getBasicScriptUrl(
+ const ::rtl::OUString& rLibraryName,
+ const ::rtl::OUString& rModuleName,
+ const ::rtl::OUString& rMacroName );
+
+ /** Reads the next record from the VBA directory stream 'dir'.
+
+ @param rnRecId (out parameter) The record identifier of the new record.
+ @param rRecData (out parameter) The contents of the new record.
+ @param rInStrm The 'dir' stream.
+
+ @return True = next record successfully read. False on any error, or
+ if the stream is EOF.
+ */
+ static bool readDirRecord(
+ sal_uInt16& rnRecId,
+ StreamDataSequence& rRecData,
+ BinaryInputStream& rInStrm );
+
+ /** Extracts a key/value pair from a string separated by an equality sign.
+
+ @param rKey (out parameter) The key before the separator.
+ @param rValue (out parameter) The value following the separator.
+ @param rCodeLine The source key/value pair.
+
+ @return True = Equality sign separator found, and the returned key and
+ value are not empty. False otherwise.
+ */
+ static bool extractKeyValue(
+ ::rtl::OUString& rKey,
+ ::rtl::OUString& rValue,
+ const ::rtl::OUString& rKeyValue );
+
+private:
+ VbaHelper();
+ ~VbaHelper();
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/vbainputstream.hxx b/oox/inc/oox/ole/vbainputstream.hxx
new file mode 100644
index 000000000000..858698518968
--- /dev/null
+++ b/oox/inc/oox/ole/vbainputstream.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_VBAINPUTSTREAM_HXX
+#define OOX_OLE_VBAINPUTSTREAM_HXX
+
+#include <vector>
+#include "oox/helper/binaryinputstream.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+/** A non-seekable input stream that implements run-length decompression. */
+class VbaInputStream : public BinaryInputStream
+{
+public:
+ explicit VbaInputStream( BinaryInputStream& rInStrm );
+
+ /** Reads nBytes bytes to the passed sequence.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes );
+ /** Reads nBytes bytes to the (existing) buffer opMem.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes );
+ /** Seeks the stream forward by the passed number of bytes. */
+ virtual void skip( sal_Int32 nBytes );
+
+private:
+ /** If no data left in chunk buffer, reads the next chunk from stream. */
+ bool updateChunk();
+
+private:
+ typedef ::std::vector< sal_uInt8 > ChunkBuffer;
+
+ BinaryInputStream& mrInStrm;
+ ChunkBuffer maChunk;
+ size_t mnChunkPos;
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/vbamodule.hxx b/oox/inc/oox/ole/vbamodule.hxx
new file mode 100644
index 000000000000..52b2261e55b5
--- /dev/null
+++ b/oox/inc/oox/ole/vbamodule.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_VBAMODULE_HXX
+#define OOX_OLE_VBAMODULE_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ustring.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameAccess; }
+ namespace container { class XNameContainer; }
+ namespace frame { class XModel; }
+} } }
+
+namespace oox {
+ class BinaryInputStream;
+ class StorageBase;
+}
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+class VbaModule
+{
+public:
+ explicit VbaModule(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
+ const ::rtl::OUString& rName,
+ rtl_TextEncoding eTextEnc,
+ bool bExecutable );
+
+ /** Returns the module type (com.sun.star.script.ModuleType constant). */
+ inline sal_Int32 getType() const { return mnType; }
+ /** Sets the passed module type. */
+ inline void setType( sal_Int32 nType ) { mnType = nType; }
+
+ /** Returns the name of the module. */
+ inline const ::rtl::OUString& getName() const { return maName; }
+ /** Returns the stream name of the module. */
+ inline const ::rtl::OUString& getStreamName() const { return maStreamName; }
+
+ /** Imports all records for this module until the MODULEEND record. */
+ void importDirRecords( BinaryInputStream& rDirStrm );
+
+ /** Imports the VBA source code into the passed Basic library. */
+ void createAndImportModule(
+ StorageBase& rVbaStrg,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
+ /** Creates an empty Basic module in the passed Basic library. */
+ void createEmptyModule(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
+
+private:
+ /** Reads and returns the VBA source code from the passed storage. */
+ ::rtl::OUString readSourceCode( StorageBase& rVbaStrg ) const;
+
+ /** Creates a new Basic module and inserts it into the passed Basic library. */
+ void createModule(
+ const ::rtl::OUString& rVBASourceCode,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
+ mxDocModel; /// Document model used to import/export the VBA project.
+ ::rtl::OUString maName;
+ ::rtl::OUString maStreamName;
+ ::rtl::OUString maDocString;
+ rtl_TextEncoding meTextEnc;
+ sal_Int32 mnType;
+ sal_uInt32 mnOffset;
+ bool mbReadOnly;
+ bool mbPrivate;
+ bool mbExecutable;
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/vbaproject.hxx b/oox/inc/oox/ole/vbaproject.hxx
new file mode 100644
index 000000000000..40e81c923d25
--- /dev/null
+++ b/oox/inc/oox/ole/vbaproject.hxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_VBAPROJECT_HXX
+#define OOX_OLE_VBAPROJECT_HXX
+
+#include <map>
+#include <com/sun/star/uno/XInterface.hpp>
+#include "oox/helper/refvector.hxx"
+#include "oox/helper/storagebase.hxx"
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameContainer; }
+ namespace document { class XEventsSupplier; }
+ namespace frame { class XModel; }
+ namespace script { class XLibraryContainer; }
+ namespace script { namespace vba { class XVBAMacroResolver; } }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace oox { class GraphicHelper; }
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+class OOX_DLLPUBLIC VbaFilterConfig
+{
+public:
+ explicit VbaFilterConfig(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
+ const ::rtl::OUString& rConfigCompName );
+ ~VbaFilterConfig();
+
+ /** Returns true, if the VBA source code and forms should be imported. */
+ bool isImportVba() const;
+ /** Returns true, if the VBA source code should be imported executable. */
+ bool isImportVbaExecutable() const;
+ /** Returns true, if the VBA source code and forms should be exported. */
+ bool isExportVba() const;
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ mxConfigAccess;
+};
+
+// ============================================================================
+
+/** Base class for objects that attach a amcro to a specific action.
+
+ Purpose is to collect objects that need to attach a VBA macro to an action.
+ The VBA project will be loaded at a very late point of the document import
+ process, because it depends on an initialized core document model (e.g.
+ spreadsheet codenames). Some objects that want to attach a VBA macro to an
+ action (e.g. mouse click action for drawing shapes) are loaded long before
+ the VBA project. The drawback is that in most cases macros are specified
+ without module name, or the VBA project name is part of the macro name.
+ In the former case, all code modules have to be scanned for the macro to be
+ able to create a valid script URL.
+
+ The import code will register these requests to attach a VBA macro with an
+ instance of a class derived from this base class. The derived class will
+ store all information needed to finally attach the macro to the action,
+ once the VBA project has been imported.
+ */
+class VbaMacroAttacherBase
+{
+public:
+ explicit VbaMacroAttacherBase( const ::rtl::OUString& rMacroName );
+ virtual ~VbaMacroAttacherBase();
+
+ /** Resolves the internal macro name to the related macro URL, and attaches
+ the macro to the object. */
+ void resolveAndAttachMacro(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::script::vba::XVBAMacroResolver >& rxResolver );
+
+private:
+ /** Called after the VBA project has been imported. Derived classes will
+ attach the passed script to the object represented by this instance. */
+ virtual void attachMacro( const ::rtl::OUString& rScriptUrl ) = 0;
+
+private:
+ ::rtl::OUString maMacroName;
+};
+
+typedef ::boost::shared_ptr< VbaMacroAttacherBase > VbaMacroAttacherRef;
+
+// ============================================================================
+
+class OOX_DLLPUBLIC VbaProject : public VbaFilterConfig
+{
+public:
+ explicit VbaProject(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
+ const ::rtl::OUString& rConfigCompName );
+ virtual ~VbaProject();
+
+ /** Imports the entire VBA project from the passed storage.
+
+ @param rVbaPrjStrg The root storage of the entire VBA project.
+ */
+ void importVbaProject(
+ StorageBase& rVbaPrjStrg,
+ const GraphicHelper& rGraphicHelper,
+ bool bDefaultColorBgr = true );
+
+ /** Registers a macro atatcher object. For details, see description of the
+ VbaMacroAttacherBase class. */
+ void registerMacroAttacher( const VbaMacroAttacherRef& rxAttacher );
+
+ /** Returns true, if the document contains at least one code module. */
+ bool hasModules() const;
+ /** Returns true, if the document contains the specified code module. */
+ bool hasModule( const ::rtl::OUString& rModuleName ) const;
+
+ /** Returns true, if the document contains at least one dialog. */
+ bool hasDialogs() const;
+ /** Returns true, if the document contains the specified dialog. */
+ bool hasDialog( const ::rtl::OUString& rDialogName ) const;
+
+protected:
+ /** Registers a dummy module that will be created when the VBA project is
+ imported. */
+ void addDummyModule( const ::rtl::OUString& rName, sal_Int32 nType );
+
+ /** Called when the import process of the VBA project has been started. */
+ virtual void prepareImport();
+ /** Called when the import process of the VBA project is finished. */
+ virtual void finalizeImport();
+
+private:
+ VbaProject( const VbaProject& );
+ VbaProject& operator=( const VbaProject& );
+
+ /** Returns the Basic or dialog library container. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >
+ getLibraryContainer( sal_Int32 nPropId );
+ /** Opens a Basic or dialog library (creates missing if specified). */
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ openLibrary( sal_Int32 nPropId, bool bCreateMissing );
+ /** Creates and returns the Basic library of the document used for import. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ createBasicLibrary();
+ /** Creates and returns the dialog library of the document used for import. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ createDialogLibrary();
+
+ /** Imports the VBA code modules and forms. */
+ void importVba(
+ StorageBase& rVbaPrjStrg,
+ const GraphicHelper& rGraphicHelper,
+ bool bDefaultColorBgr );
+
+ /** Attaches VBA macros to objects registered via registerMacroAttacher(). */
+ void attachMacros();
+
+ /** Copies the entire VBA project storage to the passed document model. */
+ void copyStorage( StorageBase& rVbaPrjStrg );
+
+private:
+ typedef RefVector< VbaMacroAttacherBase > MacroAttacherVector;
+ typedef ::std::map< ::rtl::OUString, sal_Int32 > DummyModuleMap;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
+ mxCompContext; /// Component context with service manager.
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
+ mxDocModel; /// Document model used to import/export the VBA project.
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ mxBasicLib; /// The Basic library of the document used for import.
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ mxDialogLib; /// The dialog library of the document used for import.
+ MacroAttacherVector maMacroAttachers; /// Objects that want to attach a VBA macro to an action.
+ DummyModuleMap maDummyModules; /// Additional empty modules created on import.
+ ::rtl::OUString maPrjName; /// Name of the VBA project.
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ole/vbaprojectfilter.hxx b/oox/inc/oox/ole/vbaprojectfilter.hxx
new file mode 100755
index 000000000000..c8a0a1b0ce74
--- /dev/null
+++ b/oox/inc/oox/ole/vbaprojectfilter.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_OLE_VBAPROJECTFILTER_HXX
+#define OOX_OLE_VBAPROJECTFILTER_HXX
+
+#include "oox/core/binaryfilterbase.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+class VbaProjectFilterBase : public ::oox::core::BinaryFilterBase
+{
+public:
+ explicit VbaProjectFilterBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
+ const ::rtl::OUString& rAppName,
+ const ::rtl::OUString& rStorageName )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual bool importDocument() throw();
+ virtual bool exportDocument() throw();
+
+private:
+ virtual VbaProject* implCreateVbaProject() const;
+
+private:
+ ::rtl::OUString maAppName;
+ ::rtl::OUString maStorageName;
+};
+
+// ============================================================================
+
+class WordVbaProjectFilter : public VbaProjectFilterBase
+{
+public:
+ explicit WordVbaProjectFilter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+ virtual ::rtl::OUString implGetImplementationName() const;
+};
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/ppt/animationspersist.hxx b/oox/inc/oox/ppt/animationspersist.hxx
new file mode 100644
index 000000000000..0ff930bfa080
--- /dev/null
+++ b/oox/inc/oox/ppt/animationspersist.hxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_PPT_ANIMATIONPERSIST
+#define OOX_PPT_ANIMATIONPERSIST
+
+#include <list>
+#include <boost/shared_ptr.hpp>
+#include <boost/array.hpp>
+
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/ppt/slidepersist.hxx"
+
+namespace oox { namespace ppt {
+
+ enum {
+ NP_TO = 0,
+ NP_FROM, NP_BY, NP_USERDATA, NP_ATTRIBUTENAME,
+ NP_ACCELERATION, NP_AUTOREVERSE, NP_DECELERATE, NP_DURATION, NP_FILL,
+ NP_REPEATCOUNT, NP_REPEATDURATION, NP_RESTART,
+ NP_DIRECTION, NP_COLORINTERPOLATION, NP_CALCMODE, NP_TRANSFORMTYPE,
+ NP_PATH,
+ NP_ENDSYNC, NP_ITERATETYPE, NP_ITERATEINTERVAL,
+ NP_SUBITEM, NP_TARGET, NP_COMMAND, NP_PARAMETER,
+ NP_VALUES, NP_FORMULA, NP_KEYTIMES, NP_DISPLAY,
+ _NP_SIZE
+ };
+
+ typedef boost::array< ::com::sun::star::uno::Any, _NP_SIZE > NodePropertyMap;
+
+
+ /** data for CT_TLShapeTargetElement */
+ struct ShapeTargetElement
+ {
+ ShapeTargetElement()
+ : mnType( 0 )
+ {}
+ void convert( ::com::sun::star::uno::Any & aAny, sal_Int16 & rSubType ) const;
+
+ sal_Int32 mnType;
+ sal_Int32 mnRangeType;
+ drawingml::IndexRange maRange;
+ ::rtl::OUString msSubShapeId;
+ };
+
+
+ /** data for CT_TLTimeTargetElement */
+ struct AnimTargetElement
+ {
+ AnimTargetElement()
+ : mnType( 0 )
+ {}
+ /** convert to a set of properties */
+ ::com::sun::star::uno::Any convert(const SlidePersistPtr & pSlide, sal_Int16 & nSubType) const;
+
+ sal_Int32 mnType;
+ ::rtl::OUString msValue;
+
+ ShapeTargetElement maShapeTarget;
+ };
+
+ typedef boost::shared_ptr< AnimTargetElement > AnimTargetElementPtr;
+
+ struct AnimationCondition;
+
+ typedef ::std::list< AnimationCondition > AnimationConditionList;
+
+ /** data for CT_TLTimeCondition */
+ struct AnimationCondition
+ {
+ AnimationCondition()
+ : mnType( 0 )
+ {}
+
+ ::com::sun::star::uno::Any convert(const SlidePersistPtr & pSlide) const;
+ static ::com::sun::star::uno::Any convertList(const SlidePersistPtr & pSlide, const AnimationConditionList & l);
+
+ AnimTargetElementPtr & getTarget()
+ { if(!mpTarget) mpTarget.reset( new AnimTargetElement ); return mpTarget; }
+ ::com::sun::star::uno::Any maValue;
+ sal_Int32 mnType;
+ private:
+ AnimTargetElementPtr mpTarget;
+ };
+
+
+ struct TimeAnimationValue
+ {
+ ::rtl::OUString msFormula;
+ ::rtl::OUString msTime;
+ ::com::sun::star::uno::Any maValue;
+ };
+
+ typedef ::std::list< TimeAnimationValue > TimeAnimationValueList;
+
+} }
+
+
+
+
+
+#endif
diff --git a/oox/inc/oox/ppt/backgroundproperties.hxx b/oox/inc/oox/ppt/backgroundproperties.hxx
new file mode 100644
index 000000000000..7972d20844e1
--- /dev/null
+++ b/oox/inc/oox/ppt/backgroundproperties.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_POWERPOINT_BACKGROUNDPROPERTIES_HXX
+#define OOX_POWERPOINT_BACKGROUNDPROPERTIES_HXX
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+
+namespace oox { namespace ppt {
+
+// ---------------------------------------------------------------------
+
+class BackgroundPropertiesContext : public ::oox::core::ContextHandler
+{
+public:
+ BackgroundPropertiesContext( ::oox::core::ContextHandler& rParent, ::oox::drawingml::FillProperties& rFillProperties ) throw();
+ 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::FillProperties& mrFillProperties;
+};
+
+} }
+
+#endif // OOX_POWERPOINT_BACKGROUNDPROPERTIES_HXX
diff --git a/oox/inc/oox/ppt/headerfooter.hxx b/oox/inc/oox/ppt/headerfooter.hxx
new file mode 100644
index 000000000000..f29124240cb7
--- /dev/null
+++ b/oox/inc/oox/ppt/headerfooter.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_HEADERFOOTER
+#define OOX_PPT_HEADERFOOTER
+
+#include <sal/types.h>
+
+namespace oox { namespace ppt {
+
+ struct HeaderFooter
+ {
+ sal_Bool mbSlideNumber;
+ sal_Bool mbHeader;
+ sal_Bool mbFooter;
+ sal_Bool mbDateTime;
+
+ HeaderFooter()
+ : mbSlideNumber( sal_True )
+ , mbHeader( sal_True )
+ , mbFooter( sal_True )
+ , mbDateTime( sal_True ) {};
+ };
+
+} }
+
+#endif
diff --git a/oox/inc/oox/ppt/layoutfragmenthandler.hxx b/oox/inc/oox/ppt/layoutfragmenthandler.hxx
new file mode 100644
index 000000000000..bde8a46b0a94
--- /dev/null
+++ b/oox/inc/oox/ppt/layoutfragmenthandler.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_LAYOUTFRAGMENTHANDLER
+#define OOX_PPT_LAYOUTFRAGMENTHANDLER
+
+#include "oox/ppt/slidefragmenthandler.hxx"
+
+#include <vector>
+
+namespace oox { namespace ppt {
+
+class LayoutFragmentHandler : public SlideFragmentHandler
+{
+public:
+ LayoutFragmentHandler( ::oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, SlidePersistPtr pMasterPersistPtr ) throw();
+ virtual ~LayoutFragmentHandler() throw();
+
+ virtual void SAL_CALL endDocument() 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);
+};
+
+} }
+
+#endif // OOX_PPT_LAYOUTFRAGMENTHANDLER
diff --git a/oox/inc/oox/ppt/pptimport.hxx b/oox/inc/oox/ppt/pptimport.hxx
new file mode 100644
index 000000000000..158584eeb3f5
--- /dev/null
+++ b/oox/inc/oox/ppt/pptimport.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_POWERPOINT_POWERPOINTIMPORT_HXX
+#define OOX_POWERPOINT_POWERPOINTIMPORT_HXX
+
+#include "oox/core/xmlfilterbase.hxx"
+
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <oox/drawingml/theme.hxx>
+#include "oox/ppt/presentationfragmenthandler.hxx"
+#include "oox/ppt/slidepersist.hxx"
+#include <vector>
+#include <map>
+
+namespace oox { namespace ppt {
+
+// ---------------------------------------------------------------------
+
+class PowerPointImport : public oox::core::XmlFilterBase
+{
+public:
+
+ PowerPointImport( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ~PowerPointImport();
+
+ // from FilterBase
+ virtual bool importDocument() throw();
+ virtual bool exportDocument() throw();
+
+ virtual const ::oox::drawingml::Theme* getCurrentTheme() const;
+ virtual ::oox::vml::Drawing* getVmlDrawing();
+ virtual const oox::drawingml::table::TableStyleListPtr getTableStyles();
+ virtual ::oox::drawingml::chart::ChartConverter& getChartConverter();
+
+ void setActualSlidePersist( SlidePersistPtr pActualSlidePersist ){ mpActualSlidePersist = pActualSlidePersist; };
+ std::map< rtl::OUString, oox::drawingml::ThemePtr >& getThemes(){ return maThemes; };
+ std::vector< SlidePersistPtr >& getDrawPages(){ return maDrawPages; };
+ std::vector< SlidePersistPtr >& getMasterPages(){ return maMasterPages; };
+ std::vector< SlidePersistPtr >& getNotesPages(){ return maNotesPages; };
+
+ sal_Int32 getSchemeColor( sal_Int32 nToken ) const;
+
+private:
+ virtual GraphicHelper* implCreateGraphicHelper() const;
+ virtual ::oox::ole::VbaProject* implCreateVbaProject() const;
+ virtual ::rtl::OUString implGetImplementationName() const;
+
+private:
+ rtl::OUString maTableStyleListPath;
+ oox::drawingml::table::TableStyleListPtr mpTableStyleList;
+
+ SlidePersistPtr mpActualSlidePersist;
+ std::map< rtl::OUString, oox::drawingml::ThemePtr > maThemes;
+
+ std::vector< SlidePersistPtr > maDrawPages;
+ std::vector< SlidePersistPtr > maMasterPages;
+ std::vector< SlidePersistPtr > maNotesPages;
+
+ ::boost::shared_ptr< ::oox::drawingml::chart::ChartConverter > mxChartConv;
+};
+
+} }
+
+#endif // OOX_POWERPOINT_POWERPOINTIMPORT_HXX
diff --git a/oox/inc/oox/ppt/pptshape.hxx b/oox/inc/oox/ppt/pptshape.hxx
new file mode 100644
index 000000000000..be200859c6e6
--- /dev/null
+++ b/oox/inc/oox/ppt/pptshape.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_PRESENTATION_PPTSHAPE_HXX
+#define OOX_PPT_PRESENTATION_PPTSHAPE_HXX
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/ppt/slidepersist.hxx"
+
+namespace oox { namespace ppt {
+
+class PPTShape : public oox::drawingml::Shape
+{
+ ShapeLocation meShapeLocation; // placeholdershapes (mnSubType != 0) on Master are never displayed
+ sal_Bool mbReferenced; // placeholdershapes on Layout are displayed only, if they are not referenced
+ // placeholdershapes on Slide are displayed always
+
+public:
+
+ PPTShape( const oox::ppt::ShapeLocation eShapeLocation,
+ const sal_Char* pServiceType = NULL );
+ virtual ~PPTShape();
+
+ using oox::drawingml::Shape::addShape;
+ // addShape is creating and inserting the corresponding XShape.
+ void addShape(
+ oox::core::XmlFilterBase& rFilterBase,
+ const SlidePersist& rPersist,
+ const oox::drawingml::Theme* pTheme,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const com::sun::star::awt::Rectangle* pShapeRect = 0,
+ ::oox::drawingml::ShapeIdMap* pShapeMap = 0 );
+
+ virtual void applyShapeReference( const oox::drawingml::Shape& rReferencedShape );
+
+ void setShapeLocation( const oox::ppt::ShapeLocation eShapeLocation ) { meShapeLocation = eShapeLocation; };
+ ShapeLocation getShapeLocation() const { return meShapeLocation; };
+ sal_Bool isReferenced() const { return mbReferenced; };
+ void setReferenced( sal_Bool bReferenced ){ mbReferenced = bReferenced; };
+
+ static oox::drawingml::ShapePtr findPlaceholder( const sal_Int32 nMasterPlaceholder, std::vector< oox::drawingml::ShapePtr >& rShapes );
+ static oox::drawingml::ShapePtr findPlaceholderByIndex( const sal_Int32 nIdx, std::vector< oox::drawingml::ShapePtr >& rShapes );
+ static oox::drawingml::ShapePtr findPlaceholder( sal_Int32 nFirstPlaceholder, sal_Int32 nSecondPlaceholder, std::vector< oox::drawingml::ShapePtr >& rShapes );
+};
+
+} }
+
+#endif // OOX_PPT_PRESENTATION_PPTSHAPE_HXX
diff --git a/oox/inc/oox/ppt/pptshapecontext.hxx b/oox/inc/oox/ppt/pptshapecontext.hxx
new file mode 100644
index 000000000000..aff410db7fb7
--- /dev/null
+++ b/oox/inc/oox/ppt/pptshapecontext.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_PPTSHAPECONTEXT_HXX
+#define OOX_PPT_PPTSHAPECONTEXT_HXX
+
+#include "oox/drawingml/shapecontext.hxx"
+
+namespace oox { namespace ppt {
+
+class PPTShapeContext : public ::oox::drawingml::ShapeContext
+{
+ SlidePersistPtr mpSlidePersistPtr;
+
+public:
+ PPTShapeContext( ::oox::core::ContextHandler& rParent, const SlidePersistPtr pSlidePersistPtr, oox::drawingml::ShapePtr pMasterShapePtr, oox::drawingml::ShapePtr pShapePtr );
+ 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);
+};
+
+} }
+
+#endif // OOX_PPT_PPTSHAPEGROUPCONTEXT_HXX
diff --git a/oox/inc/oox/ppt/pptshapegroupcontext.hxx b/oox/inc/oox/ppt/pptshapegroupcontext.hxx
new file mode 100644
index 000000000000..c69a6de78155
--- /dev/null
+++ b/oox/inc/oox/ppt/pptshapegroupcontext.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_PPTSHAPEGROUPCONTEXT_HXX
+#define OOX_PPT_PPTSHAPEGROUPCONTEXT_HXX
+
+#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/ppt/slidepersist.hxx"
+
+namespace oox { namespace ppt {
+
+class PPTShapeGroupContext : public ::oox::drawingml::ShapeGroupContext
+{
+ SlidePersistPtr mpSlidePersistPtr;
+ ShapeLocation meShapeLocation;
+
+public:
+ PPTShapeGroupContext(
+ ::oox::core::ContextHandler& rParent,
+ const oox::ppt::SlidePersistPtr pSlidePersistPtr,
+ const oox::ppt::ShapeLocation eShapeLocation,
+ oox::drawingml::ShapePtr pMasterShapePtr,
+ oox::drawingml::ShapePtr pGroupShapePtr );
+
+ 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:
+
+};
+
+} }
+
+#endif // OOX_PPT_PPTSHAPEGROUPCONTEXT_HXX
diff --git a/oox/inc/oox/ppt/pptshapepropertiescontext.hxx b/oox/inc/oox/ppt/pptshapepropertiescontext.hxx
new file mode 100644
index 000000000000..9cbab5755b51
--- /dev/null
+++ b/oox/inc/oox/ppt/pptshapepropertiescontext.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_PPTSHAPEPROPERTIESCONTEXT_HXX
+#define OOX_PPT_PPTSHAPEPROPERTIESCONTEXT_HXX
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+
+namespace oox { namespace ppt {
+
+class PPTShapePropertiesContext : public ::oox::drawingml::ShapePropertiesContext
+{
+public:
+ PPTShapePropertiesContext( ::oox::core::ContextHandler& rParent, ::oox::drawingml::Shape& rShape );
+ 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);
+};
+
+} }
+
+#endif // OOX_PPT_PPTSHAPEGROUPCONTEXT_HXX
diff --git a/oox/inc/oox/ppt/presentationfragmenthandler.hxx b/oox/inc/oox/ppt/presentationfragmenthandler.hxx
new file mode 100644
index 000000000000..281b3d333d56
--- /dev/null
+++ b/oox/inc/oox/ppt/presentationfragmenthandler.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_PRESENTATION_FRAGMENTHANDLER
+#define OOX_PPT_PRESENTATION_FRAGMENTHANDLER
+
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include "oox/drawingml/textliststyle.hxx"
+#include "oox/ppt/slidepersist.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/core/relations.hxx"
+#include "customshowlistcontext.hxx"
+
+#include <stack>
+#include <vector>
+
+namespace oox { namespace ppt {
+
+class PresentationFragmentHandler : public ::oox::core::FragmentHandler
+{
+public:
+ PresentationFragmentHandler( ::oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath ) throw();
+ virtual ~PresentationFragmentHandler() throw();
+
+ virtual void SAL_CALL startDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocument( ) 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:
+ bool importSlide( const ::oox::core::FragmentHandlerRef& rxSlideFragmentHandler,
+ const oox::ppt::SlidePersistPtr pPersist );
+
+private:
+ std::vector< rtl::OUString > maSlideMasterVector;
+ std::vector< rtl::OUString > maSlidesVector;
+ std::vector< rtl::OUString > maNotesMasterVector;
+ ::oox::drawingml::TextListStylePtr mpTextListStyle;
+
+ ::com::sun::star::awt::Size maSlideSize;
+ ::com::sun::star::awt::Size maNotesSize;
+
+ std::vector< CustomShow > maCustomShowList;
+};
+
+} }
+
+#endif // OOX_PPT_PRESENTATION_FRAGMENTHANDLER
diff --git a/oox/inc/oox/ppt/slidefragmenthandler.hxx b/oox/inc/oox/ppt/slidefragmenthandler.hxx
new file mode 100644
index 000000000000..4fe0e3f6a30f
--- /dev/null
+++ b/oox/inc/oox/ppt/slidefragmenthandler.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_SLIDEFRAGMENTHANDLER
+#define OOX_PPT_SLIDEFRAGMENTHANDLER
+
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/ppt/slidepersist.hxx"
+
+#include <stack>
+#include <vector>
+#include <map>
+
+namespace oox { namespace ppt {
+
+class SlideFragmentHandler : public ::oox::core::FragmentHandler
+{
+public:
+ SlideFragmentHandler( ::oox::core::XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, SlidePersistPtr pPersistPtr, const ShapeLocation eShapeLocation ) throw();
+ virtual ~SlideFragmentHandler() throw();
+
+ virtual void SAL_CALL endDocument( ) 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:
+ SlidePersistPtr mpSlidePersistPtr;
+ ShapeLocation meShapeLocation;
+
+private:
+ ::rtl::OUString maSlideName;
+ PropertyMap maSlideProperties;
+};
+
+} }
+
+#endif // OOX_PPT_SLIDEFRAGMENTHANDLER
diff --git a/oox/inc/oox/ppt/slidemastertextstylescontext.hxx b/oox/inc/oox/ppt/slidemastertextstylescontext.hxx
new file mode 100644
index 000000000000..03b7a51faa2e
--- /dev/null
+++ b/oox/inc/oox/ppt/slidemastertextstylescontext.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_SLIDEMASTERTEXTSTYLESCONTEXT_HXX
+#define OOX_DRAWINGML_SLIDEMASTERTEXTSTYLESCONTEXT_HXX
+
+#include "oox/drawingml/theme.hxx"
+#include "oox/core/contexthandler.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/ppt/slidepersist.hxx"
+
+namespace oox { namespace ppt {
+
+class SlideMasterTextStylesContext : public oox::core::ContextHandler
+{
+public:
+ SlideMasterTextStylesContext( ::oox::core::ContextHandler& rParent, SlidePersistPtr pSlidePersistPtr );
+ ~SlideMasterTextStylesContext();
+ 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:
+ SlidePersistPtr mpSlidePersistPtr;
+};
+
+} }
+
+#endif // OOX_DRAWINGML_SLIDEMASTERTEXTSTYLESCONTEXT_HXX
diff --git a/oox/inc/oox/ppt/slidepersist.hxx b/oox/inc/oox/ppt/slidepersist.hxx
new file mode 100644
index 000000000000..a6561772ed3a
--- /dev/null
+++ b/oox/inc/oox/ppt/slidepersist.hxx
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_POWERPOINT_SLIDEPERSIST_HXX
+#define OOX_POWERPOINT_SLIDEPERSIST_HXX
+
+#include <boost/shared_ptr.hpp>
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/theme.hxx"
+#include "oox/drawingml/clrscheme.hxx"
+#include "oox/drawingml/textliststyle.hxx"
+#include "oox/drawingml/textparagraphproperties.hxx"
+#include <oox/ppt/headerfooter.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include "oox/core/fragmenthandler.hxx"
+
+#include <list>
+
+namespace oox { namespace vml { class Drawing; } }
+
+namespace oox { namespace ppt {
+
+enum ShapeLocation
+{
+ Master,
+ Layout,
+ Slide
+};
+
+// ---------------------------------------------------------------------
+class TimeNode;
+class SlidePersist;
+
+typedef boost::shared_ptr< SlidePersist > SlidePersistPtr;
+
+class SlidePersist : public boost::enable_shared_from_this< SlidePersist >
+{
+
+public:
+ SlidePersist( oox::core::XmlFilterBase& rFilter, sal_Bool bMaster, sal_Bool bNotes,
+ const com::sun::star::uno::Reference< com::sun::star::drawing::XDrawPage >&,
+ oox::drawingml::ShapePtr pShapesPtr, const ::oox::drawingml::TextListStylePtr & );
+ ~SlidePersist();
+
+ com::sun::star::uno::Reference< com::sun::star::drawing::XDrawPage > getPage() const { return mxPage; };
+
+ void setMasterPersist( SlidePersistPtr pMasterPersistPtr ){ mpMasterPagePtr = pMasterPersistPtr; }
+ SlidePersistPtr getMasterPersist() const { return mpMasterPagePtr; }
+
+ void setPath( const rtl::OUString& rPath ) { maPath = rPath; }
+ const rtl::OUString getPath() const { return maPath; }
+
+ void setLayoutPath( const rtl::OUString& rLayoutPath ) { maLayoutPath = rLayoutPath; }
+ const rtl::OUString getLayoutPath() const { return maLayoutPath; }
+
+ void setTheme( const oox::drawingml::ThemePtr pThemePtr ){ mpThemePtr = pThemePtr; }
+ oox::drawingml::ThemePtr getTheme() const { return mpThemePtr; }
+
+ void setClrScheme( const oox::drawingml::ClrSchemePtr pClrSchemePtr ){ mpClrSchemePtr = pClrSchemePtr; }
+ oox::drawingml::ClrSchemePtr getClrScheme() const { return mpClrSchemePtr; }
+
+ void setClrMap( const oox::drawingml::ClrMapPtr pClrMapPtr ){ mpClrMapPtr = pClrMapPtr; }
+ oox::drawingml::ClrMapPtr getClrMap() const { return mpClrMapPtr; }
+
+ void setBackgroundProperties( const oox::drawingml::FillPropertiesPtr pFillPropertiesPtr ){ mpBackgroundPropertiesPtr = pFillPropertiesPtr; }
+ oox::drawingml::FillPropertiesPtr getBackgroundProperties() const { return mpBackgroundPropertiesPtr; }
+ oox::drawingml::Color& getBackgroundColorRef() { return maBackgroundColorRef; }
+
+ sal_Bool isMasterPage() const { return mbMaster; }
+ sal_Bool isNotesPage() const { return mbNotes; }
+
+ void setLayoutValueToken( sal_Int32 nLayoutValueToken ) { mnLayoutValueToken = nLayoutValueToken; }
+ short getLayoutFromValueToken();
+
+
+ oox::drawingml::TextListStylePtr getDefaultTextStyle() const { return maDefaultTextStylePtr; }
+ oox::drawingml::TextListStylePtr getTitleTextStyle() const { return maTitleTextStylePtr; }
+ oox::drawingml::TextListStylePtr getBodyTextStyle() const { return maBodyTextStylePtr; }
+ oox::drawingml::TextListStylePtr getNotesTextStyle() const { return maNotesTextStylePtr; }
+ oox::drawingml::TextListStylePtr getOtherTextStyle() const { return maOtherTextStylePtr; }
+
+ oox::drawingml::ShapePtr getShapes() { return maShapesPtr; }
+ ::std::list< boost::shared_ptr< TimeNode > >& getTimeNodeList() { return maTimeNodeList; }
+ oox::ppt::HeaderFooter& getHeaderFooter(){ return maHeaderFooter; };
+
+ oox::vml::Drawing* getDrawing() { return mpDrawingPtr.get(); }
+
+ void createXShapes( oox::core::XmlFilterBase& rFilterBase );
+ void createBackground( const oox::core::XmlFilterBase& rFilterBase );
+ void applyTextStyles( const oox::core::XmlFilterBase& rFilterBase );
+
+ std::map< ::rtl::OUString, ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > >& getAnimNodesMap() { return maAnimNodesMap; };
+ ::oox::drawingml::ShapePtr getShape( const ::rtl::OUString & id ) { return maShapeMap[ id ]; }
+ ::oox::drawingml::ShapeIdMap& getShapeMap() { return maShapeMap; }
+
+private:
+ rtl::OUString maPath;
+ rtl::OUString maLayoutPath;
+ ::boost::shared_ptr< oox::vml::Drawing > mpDrawingPtr;
+ com::sun::star::uno::Reference< com::sun::star::drawing::XDrawPage > mxPage;
+ oox::drawingml::ThemePtr mpThemePtr; // the theme that is used
+ oox::drawingml::ClrSchemePtr mpClrSchemePtr; // the local color scheme (if any)
+ oox::drawingml::ClrMapPtr mpClrMapPtr; // color mapping (if any)
+ SlidePersistPtr mpMasterPagePtr;
+
+ oox::drawingml::ShapePtr maShapesPtr;
+ oox::drawingml::Color maBackgroundColorRef;
+ oox::drawingml::FillPropertiesPtr mpBackgroundPropertiesPtr;
+ ::std::list< boost::shared_ptr< TimeNode > > maTimeNodeList;
+
+ oox::ppt::HeaderFooter maHeaderFooter;
+ sal_Int32 mnLayoutValueToken;
+ sal_Bool mbMaster;
+ sal_Bool mbNotes;
+
+ oox::drawingml::TextListStylePtr maDefaultTextStylePtr;
+ oox::drawingml::TextListStylePtr maTitleTextStylePtr;
+ oox::drawingml::TextListStylePtr maBodyTextStylePtr;
+ oox::drawingml::TextListStylePtr maNotesTextStylePtr;
+ oox::drawingml::TextListStylePtr maOtherTextStylePtr;
+
+ std::map< ::rtl::OUString, ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > > maAnimNodesMap;
+ std::map< ::rtl::OUString, ::oox::drawingml::ShapePtr > maShapeMap;
+};
+
+} }
+
+#endif // OOX_POWERPOINT_SLIDEPERSIST_HXX
diff --git a/oox/inc/oox/ppt/slidetimingcontext.hxx b/oox/inc/oox/ppt/slidetimingcontext.hxx
new file mode 100644
index 000000000000..911b6cbcdfb4
--- /dev/null
+++ b/oox/inc/oox/ppt/slidetimingcontext.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_SLIDETIMINGCONTEXT
+#define OOX_PPT_SLIDETIMINGCONTEXT
+
+#include <com/sun/star/animations/XTimeContainer.hpp>
+#include "oox/ppt/timenode.hxx"
+#include "oox/core/contexthandler.hxx"
+
+#include <stack>
+#include <vector>
+
+namespace oox { namespace ppt {
+
+class SlideTimingContext : public ::oox::core::ContextHandler
+{
+public:
+ SlideTimingContext( ::oox::core::ContextHandler& rParent, TimeNodePtrList & aTimeNodeList ) throw();
+ virtual ~SlideTimingContext() throw();
+
+ virtual void SAL_CALL endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ 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 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:
+ TimeNodePtrList & maTimeNodeList;
+};
+
+} }
+
+#endif // OOX_PPT_SLIDETIMINGCONTEXT
diff --git a/oox/inc/oox/ppt/slidetransition.hxx b/oox/inc/oox/ppt/slidetransition.hxx
new file mode 100644
index 000000000000..df2eed4d6083
--- /dev/null
+++ b/oox/inc/oox/ppt/slidetransition.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_PPT_SLIDETRANSITION
+#define OOX_PPT_SLIDETRANSITION
+
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/animations/XTransitionFilter.hpp>
+
+namespace oox { class PropertyMap; }
+
+namespace oox { namespace ppt {
+
+ class SlideTransition
+ {
+ public:
+ SlideTransition();
+ explicit SlideTransition(const ::rtl::OUString & );
+
+ void setSlideProperties( PropertyMap& props );
+ void setTransitionFilterProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XTransitionFilter > & xFilter );
+
+ void setOoxTransitionSpeed( sal_Int32 nToken );
+ void setFadeColor( sal_Int32 nColor )
+ { mnFadeColor = nColor; }
+ void setMode( sal_Bool bMode )
+ { mbMode = bMode; }
+
+ static sal_Int16 ooxToOdpDirection( ::sal_Int32 nOoxType );
+ static sal_Int16 ooxToOdpEightDirections( ::sal_Int32 nOoxType );
+ static sal_Int16 ooxToOdpCornerDirections( ::sal_Int32 nOoxType );
+ static sal_Int16 ooxToOdpBorderDirections( ::sal_Int32 nOoxType );
+ static sal_Int16 ooxToOdpSideDirections( ::sal_Int32 nOoxType );
+ static sal_Bool ooxToOdpSideDirectionsDirectionNormal( ::sal_Int32 nOoxType );
+
+ void setOoxTransitionType( ::sal_Int32 OoxType,
+ ::sal_Int32 param1, ::sal_Int32 param2 );
+ private:
+ ::sal_Int16 mnTransitionType;
+ ::sal_Int16 mnTransitionSubType;
+ ::sal_Bool mbTransitionDirectionNormal;
+ ::sal_Int16 mnAnimationSpeed;
+ ::sal_Int32 mnFadeColor;
+ ::sal_Bool mbMode; /**< http://api.openoffice.org/docs/common/ref/com/sun/star/animations/XTransitionFilter.html Mode property */
+ };
+
+} }
+
+#endif
diff --git a/oox/inc/oox/ppt/slidetransitioncontext.hxx b/oox/inc/oox/ppt/slidetransitioncontext.hxx
new file mode 100644
index 000000000000..047c417936e7
--- /dev/null
+++ b/oox/inc/oox/ppt/slidetransitioncontext.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_SLIDETRANSITIONCONTEXT
+#define OOX_PPT_SLIDETRANSITIONCONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/ppt/slidetransition.hxx"
+
+namespace oox { class PropertyMap; }
+
+namespace oox { namespace ppt {
+
+ class SlideTransitionContext : public ::oox::core::ContextHandler
+ {
+ public:
+ SlideTransitionContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes,
+ PropertyMap & aProperties ) throw();
+ virtual ~SlideTransitionContext() 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 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:
+ PropertyMap& maSlideProperties;
+ ::sal_Bool mbHasTransition;
+ SlideTransition maTransition;
+ };
+
+} }
+
+#endif // OOX_PPT_SLIDEFRAGMENTHANDLER
diff --git a/oox/inc/oox/ppt/soundactioncontext.hxx b/oox/inc/oox/ppt/soundactioncontext.hxx
new file mode 100644
index 000000000000..48cfb072be78
--- /dev/null
+++ b/oox/inc/oox/ppt/soundactioncontext.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_PPT_SOUNDACTIONCONTEXT
+#define OOX_PPT_SOUNDACTIONCONTEXT
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { class PropertyMap; }
+
+namespace oox { namespace ppt {
+
+class SoundActionContext : public ::oox::core::ContextHandler
+{
+public:
+ SoundActionContext( ::oox::core::ContextHandler& rParent, PropertyMap & aProperties ) throw();
+ virtual ~SoundActionContext() 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 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:
+ PropertyMap& maSlideProperties;
+ bool mbHasStartSound;
+ bool mbLoopSound;
+ bool mbStopSound;
+ ::rtl::OUString msEmbedded;
+ ::rtl::OUString msLink;
+ ::rtl::OUString msSndName;
+};
+
+} }
+
+
+
+#endif
diff --git a/oox/inc/oox/ppt/timenode.hxx b/oox/inc/oox/ppt/timenode.hxx
new file mode 100644
index 000000000000..117d9ee7161c
--- /dev/null
+++ b/oox/inc/oox/ppt/timenode.hxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef OOX_DRAWINGML_TIMENODE_HXX
+#define OOX_DRAWINGML_TIMENODE_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <list>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include "oox/helper/propertymap.hxx"
+#include "oox/ppt/slidetransition.hxx"
+#include "oox/ppt/slidepersist.hxx"
+#include "oox/ppt/animationspersist.hxx"
+#include "oox/ppt/timenode.hxx"
+
+namespace oox { namespace ppt {
+
+ class TimeNode;
+ class SlideTransition;
+
+ typedef boost::shared_ptr< TimeNode > TimeNodePtr;
+ typedef ::std::list< TimeNodePtr > TimeNodePtrList;
+
+ class TimeNode
+ {
+ public:
+ typedef ::std::map< ::rtl::OUString, ::com::sun::star::uno::Any > UserDataMap;
+
+ TimeNode( sal_Int16 nNodeType );
+ virtual ~TimeNode();
+
+ NodePropertyMap & getNodeProperties() { return maNodeProperties; }
+ UserDataMap & getUserData() { return maUserData; }
+ void addChild( const TimeNodePtr & pChildPtr )
+ { maChildren.push_back( pChildPtr ); }
+
+ TimeNodePtrList & getChildren()
+ { return maChildren; }
+
+ void setId( sal_Int32 nId );
+ const ::rtl::OUString & getId() const { return msId; }
+
+ void addNode(
+ const ::oox::core::XmlFilterBase& rFilter,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& rxNode,
+ const SlidePersistPtr & slide);
+ // data setters
+ void setTo( const ::com::sun::star::uno::Any & aTo );
+ void setFrom( const ::com::sun::star::uno::Any & aFrom );
+ void setBy( const ::com::sun::star::uno::Any & aBy );
+ void setTransitionFilter( const SlideTransition & aTransition)
+ { maTransitionFilter = aTransition; }
+
+ void setNode(
+ const ::oox::core::XmlFilterBase& rFilter,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode,
+ const SlidePersistPtr & pSlide );
+
+ AnimTargetElementPtr getTarget()
+ {
+ if( !mpTarget )
+ mpTarget.reset( new AnimTargetElement );
+ return mpTarget;
+ }
+
+ AnimationConditionList &getStartCondition()
+ { return maStCondList; }
+ AnimationConditionList &getEndCondition()
+ { return maEndCondList; }
+ AnimationConditionList &getNextCondition()
+ { return maNextCondList; }
+ AnimationConditionList &getPrevCondition()
+ { return maPrevCondList; }
+ AnimationCondition & getEndSyncValue()
+ { mbHasEndSyncValue = true; return maEndSyncValue; }
+ protected:
+
+ static rtl::OUString getServiceName( sal_Int16 nNodeType );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >
+ createAndInsert(
+ const ::oox::core::XmlFilterBase& rFilter,
+ const rtl::OUString& rServiceName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& rxNode );
+
+ private:
+ const sal_Int16 mnNodeType;
+
+ TimeNodePtrList maChildren;
+
+ rtl::OUString msId;
+ NodePropertyMap maNodeProperties;
+ UserDataMap maUserData; // a sequence to be stored as "UserData" property
+ SlideTransition maTransitionFilter;
+ AnimTargetElementPtr mpTarget;
+ bool mbHasEndSyncValue; // set to true if we try to get the endSync.
+ AnimationCondition maEndSyncValue;
+ AnimationConditionList maStCondList, maEndCondList;
+ AnimationConditionList maPrevCondList, maNextCondList;
+ };
+
+} }
+
+
+#endif
diff --git a/oox/inc/oox/ppt/timenodelistcontext.hxx b/oox/inc/oox/ppt/timenodelistcontext.hxx
new file mode 100644
index 000000000000..8dbe54425125
--- /dev/null
+++ b/oox/inc/oox/ppt/timenodelistcontext.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_TIMENODELISTCONTEXT
+#define OOX_PPT_TIMENODELISTCONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/ppt/timenode.hxx"
+
+#include <com/sun/star/animations/XTimeContainer.hpp>
+
+namespace oox { namespace ppt {
+
+
+ class TimeNodeContext : public ::oox::core::ContextHandler
+ {
+ public:
+ virtual ~TimeNodeContext() throw();
+
+ static TimeNodeContext * SAL_CALL makeContext( ::oox::core::ContextHandler& rParent, sal_Int32 aElement, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs, const TimeNodePtr & pNode );
+
+ protected:
+ TimeNodeContext( ::oox::core::ContextHandler& rParent, sal_Int32 aElement, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs, const TimeNodePtr & pNode ) throw();
+
+ sal_Int32 mnElement;
+ TimeNodePtr mpNode;
+ };
+
+
+
+/** FastParser context for XML_tnLst, XML_subTnLst and XML_childTnLst */
+class TimeNodeListContext : public ::oox::core::ContextHandler
+{
+public:
+ TimeNodeListContext( ::oox::core::ContextHandler& rParent, TimeNodePtrList & aList ) throw();
+
+ virtual ~TimeNodeListContext() throw();
+
+ 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:
+ TimeNodePtrList & maList;
+};
+
+} }
+
+#endif // OOX_PPT_SLIDEFRAGMENTHANDLER
diff --git a/oox/inc/oox/token/namespacemap.hxx b/oox/inc/oox/token/namespacemap.hxx
new file mode 100755
index 000000000000..e4daa18f6b56
--- /dev/null
+++ b/oox/inc/oox/token/namespacemap.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_TOKEN_NAMESPACEMAP_HXX
+#define OOX_TOKEN_NAMESPACEMAP_HXX
+
+#include <map>
+#include <rtl/instance.hxx>
+#include <rtl/ustring.hxx>
+
+namespace oox {
+
+// ============================================================================
+
+/** A map that contains all XML namespace URLs used in the filters. */
+struct NamespaceMap : public ::std::map< sal_Int32, ::rtl::OUString > { NamespaceMap(); };
+
+/** Thread-save singleton of a map of all supported XML namespace URLs. */
+struct StaticNamespaceMap : public ::rtl::Static< NamespaceMap, StaticNamespaceMap > {};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/token/propertynames.hxx b/oox/inc/oox/token/propertynames.hxx
new file mode 100644
index 000000000000..5f94e74c2b96
--- /dev/null
+++ b/oox/inc/oox/token/propertynames.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_TOKEN_PROPERTYNAMES_HXX
+#define OOX_TOKEN_PROPERTYNAMES_HXX
+
+#include <vector>
+#include <rtl/instance.hxx>
+#include <rtl/ustring.hxx>
+
+namespace oox {
+
+// ============================================================================
+
+/** A vector that contains all predefined property names used in the filters. */
+struct PropertyNameVector : public ::std::vector< ::rtl::OUString > { PropertyNameVector(); };
+
+/** Thread-save singleton of a vector of all supported property names. */
+struct StaticPropertyNameVector : public ::rtl::Static< PropertyNameVector, StaticPropertyNameVector > {};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/token/tokenmap.hxx b/oox/inc/oox/token/tokenmap.hxx
new file mode 100644
index 000000000000..b197c491ac51
--- /dev/null
+++ b/oox/inc/oox/token/tokenmap.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_TOKEN_TOKENMAP_HXX
+#define OOX_TOKEN_TOKENMAP_HXX
+
+#include <vector>
+#include <rtl/instance.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace oox {
+
+// ============================================================================
+
+class TokenMap
+{
+public:
+ explicit TokenMap();
+ ~TokenMap();
+
+ /** Returns the Unicode name of the passed token identifier. */
+ ::rtl::OUString getUnicodeTokenName( sal_Int32 nToken ) const;
+
+ /** Returns the token identifier for the passed Unicode token name. */
+ sal_Int32 getTokenFromUnicode( const ::rtl::OUString& rUnicodeName ) const;
+
+ /** Returns the UTF8 name of the passed token identifier as byte sequence. */
+ ::com::sun::star::uno::Sequence< sal_Int8 >
+ getUtf8TokenName( sal_Int32 nToken ) const;
+
+ /** Returns the token identifier for the passed UTF8 token name. */
+ sal_Int32 getTokenFromUtf8(
+ const ::com::sun::star::uno::Sequence< sal_Int8 >& rUtf8Name ) const;
+
+private:
+ struct TokenName
+ {
+ ::rtl::OUString maUniName;
+ ::com::sun::star::uno::Sequence< sal_Int8 > maUtf8Name;
+ };
+ typedef ::std::vector< TokenName > TokenNameVector;
+
+ TokenNameVector maTokenNames;
+};
+
+// ============================================================================
+
+struct StaticTokenMap : public ::rtl::Static< TokenMap, StaticTokenMap > {};
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/vml/vmldrawing.hxx b/oox/inc/oox/vml/vmldrawing.hxx
new file mode 100644
index 000000000000..0d87dae3138b
--- /dev/null
+++ b/oox/inc/oox/vml/vmldrawing.hxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLDRAWING_HXX
+#define OOX_VML_VMLDRAWING_HXX
+
+#include <map>
+#include <memory>
+#include <vector>
+#include "oox/ole/oleobjecthelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Rectangle; }
+ namespace awt { class XControlModel; }
+ namespace drawing { class XDrawPage; }
+ namespace drawing { class XShape; }
+ namespace drawing { class XShapes; }
+} } }
+
+namespace oox {
+ namespace core { class XmlFilterBase; }
+ namespace ole { class EmbeddedControl; }
+ namespace ole { class EmbeddedForm; }
+}
+
+namespace oox {
+namespace vml {
+
+class ShapeBase;
+class ShapeContainer;
+struct ClientData;
+
+// ============================================================================
+
+/** Enumerates different types of VML drawings. */
+enum DrawingType
+{
+ VMLDRAWING_WORD, /// Word: One shape per drawing.
+ VMLDRAWING_EXCEL, /// Excel: OLE objects are part of VML.
+ VMLDRAWING_POWERPOINT /// PowerPoint: OLE objects are part of DrawingML.
+};
+
+// ============================================================================
+
+/** Contains information about an OLE object embedded in a draw page. */
+struct OleObjectInfo : public ::oox::ole::OleObjectInfo
+{
+ ::rtl::OUString maShapeId; /// Shape identifier for shape lookup.
+ ::rtl::OUString maName; /// Programmatical name of the OLE object.
+ bool mbAutoLoad;
+ const bool mbDmlShape; /// True = DrawingML shape (PowerPoint), false = VML shape (Excel/Word).
+
+ explicit OleObjectInfo( bool bDmlShape = false );
+
+ /** Sets the string representation of the passed numeric shape identifier. */
+ void setShapeId( sal_Int32 nShapeId );
+};
+
+// ============================================================================
+
+/** Contains information about a form control embedded in a draw page. */
+struct ControlInfo
+{
+ ::rtl::OUString maShapeId; /// Shape identifier for shape lookup.
+ ::rtl::OUString maFragmentPath; /// Path to the fragment describing the form control properties.
+ ::rtl::OUString maName; /// Programmatical name of the form control.
+
+ explicit ControlInfo();
+
+ /** Sets the string representation of the passed numeric shape identifier. */
+ void setShapeId( sal_Int32 nShapeId );
+};
+
+// ============================================================================
+
+/** Represents the collection of VML shapes for a complete draw page. */
+class Drawing
+{
+public:
+ explicit Drawing(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& rxDrawPage,
+ DrawingType eType );
+
+ virtual ~Drawing();
+
+ /** Returns the filter object that imports/exports this VML drawing. */
+ inline ::oox::core::XmlFilterBase& getFilter() const { return mrFilter; }
+ /** Returns the application type containing the drawing. */
+ inline DrawingType getType() const { return meType; }
+ /** Returns read/write access to the container of shapes and templates. */
+ inline ShapeContainer& getShapes() { return *mxShapes; }
+ /** Returns read access to the container of shapes and templates. */
+ inline const ShapeContainer& getShapes() const { return *mxShapes; }
+ /** Returns the form object used to process ActiveX form controls. */
+ ::oox::ole::EmbeddedForm& getControlForm() const;
+
+ /** Registers a block of shape identifiers reserved by this drawing. Block
+ size is 1024, shape identifiers are one-based (block 1 => 1025-2048). */
+ void registerBlockId( sal_Int32 nBlockId );
+ /** Registers the passed embedded OLE object. The related shape will then
+ load the OLE object data from the specified fragment. */
+ void registerOleObject( const OleObjectInfo& rOleObject );
+ /** Registers the passed embedded form control. The related shape will then
+ load the control properties from the specified fragment. */
+ void registerControl( const ControlInfo& rControl );
+
+ /** Final processing after import of the fragment. */
+ void finalizeFragmentImport();
+
+ /** Creates and inserts all UNO shapes into the passed container. The virtual
+ function notifyXShapeInserted() will be called for each new shape. */
+ void convertAndInsert() const;
+
+ /** Returns the local shape index from the passed global shape identifier. */
+ sal_Int32 getLocalShapeIndex( const ::rtl::OUString& rShapeId ) const;
+ /** Returns the registered info structure for an OLE object, if extant. */
+ const OleObjectInfo* getOleObjectInfo( const ::rtl::OUString& rShapeId ) const;
+ /** Returns the registered info structure for a form control, if extant. */
+ const ControlInfo* getControlInfo( const ::rtl::OUString& rShapeId ) const;
+
+ /** Creates a new UNO shape object, inserts it into the passed UNO shape
+ container, and sets the shape position and size. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createAndInsertXShape(
+ const ::rtl::OUString& rService,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+
+ /** Creates a new UNO shape object for a form control, inserts the control
+ model into the form, and the shape into the passed UNO shape container. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createAndInsertXControlShape(
+ const ::oox::ole::EmbeddedControl& rControl,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect,
+ sal_Int32& rnCtrlIndex ) const;
+
+ /** Derived classes may disable conversion of specific shapes. */
+ virtual bool isShapeSupported( const ShapeBase& rShape ) const;
+
+ /** Derived classes may return additional base names for automatic shape
+ name creation. */
+ virtual ::rtl::OUString getShapeBaseName( const ShapeBase& rShape ) const;
+
+ /** Derived classes may calculate the shape rectangle from a non-standard
+ anchor information string. */
+ virtual bool convertClientAnchor(
+ ::com::sun::star::awt::Rectangle& orShapeRect,
+ const ::rtl::OUString& rShapeAnchor ) const;
+
+ /** Derived classes create a UNO shape according to the passed shape model.
+ Called for shape models that specify being under host control. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createAndInsertClientXShape(
+ const ShapeBase& rShape,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+
+ /** Derived classes may want to know that a UNO shape has been inserted.
+ Will be called from the convertAndInsert() implementation.
+ @param bGroupChild True = inserted into a group shape,
+ false = inserted directly into this drawing. */
+ virtual void notifyXShapeInserted(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ const ::com::sun::star::awt::Rectangle& rShapeRect,
+ const ShapeBase& rShape, bool bGroupChild );
+
+private:
+ typedef ::std::vector< sal_Int32 > BlockIdVector;
+ typedef ::std::auto_ptr< ::oox::ole::EmbeddedForm > EmbeddedFormPtr;
+ typedef ::std::auto_ptr< ShapeContainer > ShapeContainerPtr;
+ typedef ::std::map< ::rtl::OUString, OleObjectInfo > OleObjectInfoMap;
+ typedef ::std::map< ::rtl::OUString, ControlInfo > ControlInfoMap;
+
+ ::oox::core::XmlFilterBase& mrFilter; /// Filter object that imports/exports the VML drawing.
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >
+ mxDrawPage; /// UNO draw page used to insert the shapes.
+ mutable EmbeddedFormPtr mxCtrlForm; /// The control form used to process embedded controls.
+ mutable BlockIdVector maBlockIds; /// Block identifiers used by this drawing.
+ ShapeContainerPtr mxShapes; /// All shapes and shape templates.
+ OleObjectInfoMap maOleObjects; /// Info about all embedded OLE objects, mapped by shape id.
+ ControlInfoMap maControls; /// Info about all embedded form controls, mapped by control name.
+ const DrawingType meType; /// Application type containing the drawing.
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmldrawingfragment.hxx b/oox/inc/oox/vml/vmldrawingfragment.hxx
new file mode 100644
index 000000000000..0c961db1aabf
--- /dev/null
+++ b/oox/inc/oox/vml/vmldrawingfragment.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLDRAWINGFRAGMENT_HXX
+#define OOX_VML_VMLDRAWINGFRAGMENT_HXX
+
+#include "oox/core/fragmenthandler2.hxx"
+
+namespace oox {
+namespace vml {
+
+class Drawing;
+
+// ============================================================================
+
+class DrawingFragment : public ::oox::core::FragmentHandler2
+{
+public:
+ explicit DrawingFragment(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath,
+ Drawing& rDrawing );
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ openFragmentStream() const;
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+ virtual void finalizeImport();
+
+private:
+ Drawing& mrDrawing;
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmlformatting.hxx b/oox/inc/oox/vml/vmlformatting.hxx
new file mode 100644
index 000000000000..934be61e5a65
--- /dev/null
+++ b/oox/inc/oox/vml/vmlformatting.hxx
@@ -0,0 +1,219 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLFORMATTING_HXX
+#define OOX_VML_VMLFORMATTING_HXX
+
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+ class GraphicHelper;
+ class ModelObjectHelper;
+ class PropertyMap;
+ namespace drawingml { class Color; }
+}
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+typedef ::std::pair< sal_Int32, sal_Int32 > Int32Pair;
+typedef ::std::pair< double, double > DoublePair;
+
+// ============================================================================
+
+class ConversionHelper
+{
+public:
+ /** Returns two values contained in rValue separated by cSep.
+ */
+ static bool separatePair(
+ ::rtl::OUString& orValue1, ::rtl::OUString& orValue2,
+ const ::rtl::OUString& rValue, sal_Unicode cSep );
+
+ /** Returns the boolean value from the passed string of a VML attribute.
+ Supported values: 'f', 't', 'false', 'true'. False for anything else.
+ */
+ static bool decodeBool( const ::rtl::OUString& rValue );
+
+ /** Converts the passed VML percentage measure string to a normalized
+ floating-point value.
+
+ @param rValue The VML percentage value. This is a floating-point value
+ with optional following '%' sign. If the '%' sign is missing, the
+ floating point value will be returned unmodified. If the '%' sign
+ is present, the value will be divided by 100.
+ */
+ static double decodePercent(
+ const ::rtl::OUString& rValue,
+ double fDefValue );
+
+ /** Converts the passed VML measure string to EMU (English Metric Units).
+
+ @param rGraphicHelper The graphic helper needed to perform pixel
+ conversion according to the current output device.
+
+ @param rValue The VML measure value. This is a floating-point value
+ with optional measure string following the value.
+
+ @param nRefValue Reference value needed for percentage measure.
+
+ @param bPixelX Set to true if the value is oriented horizontally (e.g.
+ X coordinates, widths). Set to false if the value is oriented
+ vertically (e.g. Y coordinates, heights). This is needed because
+ output devices may specify different width and height for a pixel.
+
+ @param bDefaultAsPixel Set to true if omitted measure unit means
+ pixel. Set to false if omitted measure unit means EMU.
+ */
+ static sal_Int32 decodeMeasureToEmu(
+ const GraphicHelper& rGraphicHelper,
+ const ::rtl::OUString& rValue,
+ sal_Int32 nRefValue,
+ bool bPixelX,
+ bool bDefaultAsPixel );
+
+ /** Converts the passed VML measure string to 1/100 mm.
+
+ @param rGraphicHelper See above.
+ @param rValue See above.
+ @param nRefValue See above.
+ @param bPixelX See above.
+ @param bDefaultAsPixel See above.
+ */
+ static sal_Int32 decodeMeasureToHmm(
+ const GraphicHelper& rGraphicHelper,
+ const ::rtl::OUString& rValue,
+ sal_Int32 nRefValue,
+ bool bPixelX,
+ bool bDefaultAsPixel );
+
+ /** Converts VML color attributes to a DrawingML color.
+
+ @param roVmlColor The VML string representation of the color. If
+ existing, this can be a 3-digit or 6-digit hexadecimal RGB value
+ with leading '#' character, a predefined color name (e.g. 'black',
+ 'red', etc.), the index into an application defined color palette
+ in brackets with leading color name (e.g. 'red [9]' or
+ 'windowColor [64]'), or a color modifier used in one-color
+ gradients (e.g. 'fill darken(128)' or 'fill lighten(0)').
+
+ @param roVmlOpacity The opacity of the color. If existing, this should
+ be a floating-point value in the range [0.0;1.0].
+
+ @param nDefaultRgb Deafult RGB color used if the parameter roVmlColor
+ is empty.
+
+ @param nPrimaryRgb If set to something else than API_RGB_TRANSPARENT,
+ specifies the color to be used to resolve the color modifiers used
+ in one-color gradients.
+
+ @return The resulting DrawingML color.
+ */
+ static ::oox::drawingml::Color decodeColor(
+ const GraphicHelper& rGraphicHelper,
+ const OptValue< ::rtl::OUString >& roVmlColor,
+ const OptValue< double >& roVmlOpacity,
+ sal_Int32 nDefaultRgb,
+ sal_Int32 nPrimaryRgb = API_RGB_TRANSPARENT );
+
+private:
+ ConversionHelper();
+ ~ConversionHelper();
+};
+
+// ============================================================================
+
+/** The stroke arrow model structure contains all properties for an line end arrow. */
+struct StrokeArrowModel
+{
+ OptValue< sal_Int32 > moArrowType;
+ OptValue< sal_Int32 > moArrowWidth;
+ OptValue< sal_Int32 > moArrowLength;
+
+ void assignUsed( const StrokeArrowModel& rSource );
+};
+
+// ============================================================================
+
+/** The stroke model structure contains all shape border properties. */
+struct StrokeModel
+{
+ OptValue< bool > moStroked; /// Shape border line on/off.
+ StrokeArrowModel maStartArrow; /// Start line arrow style.
+ StrokeArrowModel maEndArrow; /// End line arrow style.
+ OptValue< ::rtl::OUString > moColor; /// Solid line color.
+ OptValue< double > moOpacity; /// Solid line color opacity.
+ OptValue< ::rtl::OUString > moWeight; /// Line width.
+ OptValue< ::rtl::OUString > moDashStyle; /// Line dash (predefined or manually).
+ OptValue< sal_Int32 > moLineStyle; /// Line style (single, double, ...).
+ OptValue< sal_Int32 > moEndCap; /// Type of line end cap.
+ OptValue< sal_Int32 > moJoinStyle; /// Type of line join.
+
+ void assignUsed( const StrokeModel& rSource );
+
+ /** Writes the properties to the passed property map. */
+ void pushToPropMap(
+ PropertyMap& rPropMap,
+ ModelObjectHelper& rModelObjectHelper,
+ const GraphicHelper& rGraphicHelper ) const;
+};
+
+// ============================================================================
+
+/** The fill model structure contains all shape fill properties. */
+struct FillModel
+{
+ OptValue< bool > moFilled; /// Shape fill on/off.
+ OptValue< ::rtl::OUString > moColor; /// Solid fill color.
+ OptValue< double > moOpacity; /// Solid fill color opacity.
+ OptValue< ::rtl::OUString > moColor2; /// End color of gradient.
+ OptValue< double > moOpacity2; /// End color opycity of gradient.
+ OptValue< sal_Int32 > moType; /// Fill type.
+ OptValue< sal_Int32 > moAngle; /// Gradient rotation angle.
+ OptValue< double > moFocus; /// Linear gradient focus of second color.
+ OptValue< DoublePair > moFocusPos; /// Rectanguar gradient focus position of second color.
+ OptValue< DoublePair > moFocusSize; /// Rectanguar gradient focus size of second color.
+ OptValue< ::rtl::OUString > moBitmapPath; /// Path to fill bitmap fragment.
+ OptValue< bool > moRotate; /// True = rotate gradient/bitmap with shape.
+
+ void assignUsed( const FillModel& rSource );
+
+ /** Writes the properties to the passed property map. */
+ void pushToPropMap(
+ PropertyMap& rPropMap,
+ ModelObjectHelper& rModelObjectHelper,
+ const GraphicHelper& rGraphicHelper ) const;
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmlinputstream.hxx b/oox/inc/oox/vml/vmlinputstream.hxx
new file mode 100644
index 000000000000..a425425cd0cb
--- /dev/null
+++ b/oox/inc/oox/vml/vmlinputstream.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLINPUTSTREAM_HXX
+#define OOX_VML_VMLINPUTSTREAM_HXX
+
+#include <comphelper/seqstream.hxx>
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+struct StreamDataContainer
+{
+ ::comphelper::ByteSequence maDataSeq;
+
+ explicit StreamDataContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm );
+};
+
+// ============================================================================
+
+/** An input stream class for VML streams.
+
+ This stream reads the entire data from the input stream passed to the
+ constructor, and parses all XML elements for features unsupported by the
+ current Expat parser.
+
+ All elements that have the form '<![inst]>' where 'inst' is any string not
+ containing the characters '<' and '>' are stripped from the input stream.
+ */
+class InputStream : private StreamDataContainer, public ::comphelper::SequenceInputStream
+{
+public:
+ explicit InputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm );
+ virtual ~InputStream();
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmlshape.hxx b/oox/inc/oox/vml/vmlshape.hxx
new file mode 100644
index 000000000000..ee95c6b61e29
--- /dev/null
+++ b/oox/inc/oox/vml/vmlshape.hxx
@@ -0,0 +1,377 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLSHAPE_HXX
+#define OOX_VML_VMLSHAPE_HXX
+
+#include <memory>
+#include <vector>
+#include <com/sun/star/awt/Point.hpp>
+#include "oox/vml/vmlformatting.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Rectangle; }
+ namespace drawing { class XShape; }
+ namespace drawing { class XShapes; }
+} } }
+
+namespace oox {
+namespace vml {
+
+class Drawing;
+struct ShapeParentAnchor;
+class ShapeContainer;
+class TextBox;
+
+// ============================================================================
+
+const sal_Int32 VML_CLIENTDATA_UNCHECKED = 0;
+const sal_Int32 VML_CLIENTDATA_CHECKED = 1;
+const sal_Int32 VML_CLIENTDATA_MIXED = 2;
+
+const sal_Int32 VML_CLIENTDATA_TEXT = 0;
+const sal_Int32 VML_CLIENTDATA_INTEGER = 1;
+const sal_Int32 VML_CLIENTDATA_NUMBER = 2;
+const sal_Int32 VML_CLIENTDATA_REFERENCE = 3;
+const sal_Int32 VML_CLIENTDATA_FORMULA = 4;
+
+// ============================================================================
+
+/** The shape model structure contains all properties shared by all types of shapes. */
+struct ShapeTypeModel
+{
+ ::rtl::OUString maShapeId; /// Unique identifier of the shape.
+ ::rtl::OUString maShapeName; /// Name of the shape, if present.
+ OptValue< sal_Int32 > moShapeType; /// Builtin shape type identifier.
+
+ OptValue< Int32Pair > moCoordPos; /// Top-left position of coordinate system for children scaling.
+ OptValue< Int32Pair > moCoordSize; /// Size of coordinate system for children scaling.
+ ::rtl::OUString maPosition; /// Position type of the shape.
+ ::rtl::OUString maLeft; /// X position of the shape bounding box (number with unit).
+ ::rtl::OUString maTop; /// Y position of the shape bounding box (number with unit).
+ ::rtl::OUString maWidth; /// Width of the shape bounding box (number with unit).
+ ::rtl::OUString maHeight; /// Height of the shape bounding box (number with unit).
+ ::rtl::OUString maMarginLeft; /// X position of the shape bounding box to shape anchor (number with unit).
+ ::rtl::OUString maMarginTop; /// Y position of the shape bounding box to shape anchor (number with unit).
+
+ StrokeModel maStrokeModel; /// Border line formatting.
+ FillModel maFillModel; /// Shape fill formatting.
+
+ OptValue< ::rtl::OUString > moGraphicPath; /// Path to a graphic for this shape.
+ OptValue< ::rtl::OUString > moGraphicTitle; /// Title of the graphic.
+
+ explicit ShapeTypeModel();
+
+ void assignUsed( const ShapeTypeModel& rSource );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A shape template contains all formatting properties of shapes and can serve
+ as templates for several shapes in a drawing. */
+class ShapeType
+{
+public:
+ explicit ShapeType( Drawing& rDrawing );
+ virtual ~ShapeType();
+
+ /** Returns read/write access to the shape template model structure. */
+ inline ShapeTypeModel& getTypeModel() { return maTypeModel; }
+ /** Returns read access to the shape template model structure. */
+ inline const ShapeTypeModel& getTypeModel() const { return maTypeModel; }
+
+ /** Returns the shape identifier (which is unique through the containing drawing). */
+ inline const ::rtl::OUString& getShapeId() const { return maTypeModel.maShapeId; }
+ /** Returns the application defined shape type. */
+ sal_Int32 getShapeType() const;
+ /** Returns the fragment path to the embedded graphic used by this shape. */
+ ::rtl::OUString getGraphicPath() const;
+
+protected:
+ /** Returns the coordinate system of this shape. */
+ ::com::sun::star::awt::Rectangle getCoordSystem() const;
+ /** Returns the absolute shape rectangle according to the passed anchor. */
+ ::com::sun::star::awt::Rectangle getRectangle( const ShapeParentAnchor* pParentAnchor ) const;
+
+private:
+ /** Returns the absolute shape rectangle. */
+ ::com::sun::star::awt::Rectangle getAbsRectangle() const;
+ /** Returns the rectangle relative to the parent coordinate system. */
+ ::com::sun::star::awt::Rectangle getRelRectangle() const;
+
+protected:
+ Drawing& mrDrawing; /// The VML drawing page that contains this shape.
+ ShapeTypeModel maTypeModel; /// The model structure containing shape type data.
+};
+
+// ============================================================================
+
+/** Excel specific shape client data (such as cell anchor). */
+struct ClientData
+{
+ ::rtl::OUString maAnchor; /// Cell anchor as comma-separated string.
+ ::rtl::OUString maFmlaMacro; /// Link to macro associated to the control.
+ ::rtl::OUString maFmlaPict; /// Target cell range of picture links.
+ ::rtl::OUString maFmlaLink; /// Link to value cell associated to the control.
+ ::rtl::OUString maFmlaRange; /// Link to cell range used as data source for the control.
+ ::rtl::OUString maFmlaGroup; /// Link to value cell associated to a group of option buttons.
+ sal_Int32 mnObjType; /// Type of the shape.
+ sal_Int32 mnTextHAlign; /// Horizontal text alignment.
+ sal_Int32 mnTextVAlign; /// Vertical text alignment.
+ sal_Int32 mnCol; /// Column index for spreadsheet cell note.
+ sal_Int32 mnRow; /// Row index for spreadsheet cell note.
+ sal_Int32 mnChecked; /// State for checkboxes and option buttons.
+ sal_Int32 mnDropStyle; /// Drop down box style (read-only or editable).
+ sal_Int32 mnDropLines; /// Number of lines in drop down box.
+ sal_Int32 mnVal; /// Current value of spin buttons and scroll bars.
+ sal_Int32 mnMin; /// Minimum value of spin buttons and scroll bars.
+ sal_Int32 mnMax; /// Maximum value of spin buttons and scroll bars.
+ sal_Int32 mnInc; /// Small increment of spin buttons and scroll bars.
+ sal_Int32 mnPage; /// Large increment of spin buttons and scroll bars.
+ sal_Int32 mnSelType; /// Listbox selection type.
+ sal_Int32 mnVTEdit; /// Data type of the textbox.
+ bool mbPrintObject; /// True = print the object.
+ bool mbVisible; /// True = cell note is visible.
+ bool mbDde; /// True = object is linked through DDE.
+ bool mbNo3D; /// True = flat style, false = 3D style.
+ bool mbNo3D2; /// True = flat style, false = 3D style (listboxes and dropdowns).
+ bool mbMultiLine; /// True = textbox allows line breaks.
+ bool mbVScroll; /// True = textbox has a vertical scrollbar.
+ bool mbSecretEdit; /// True = textbox is a password edit field.
+
+ explicit ClientData();
+};
+
+// ----------------------------------------------------------------------------
+
+struct ShapeModel
+{
+ typedef ::std::vector< ::com::sun::star::awt::Point > PointVector;
+ typedef ::std::auto_ptr< TextBox > TextBoxPtr;
+ typedef ::std::auto_ptr< ClientData > ClientDataPtr;
+
+ ::rtl::OUString maType; /// Shape template with default properties.
+ PointVector maPoints; /// Points for the polyline shape.
+ TextBoxPtr mxTextBox; /// Text contents and properties.
+ ClientDataPtr mxClientData; /// Excel specific client data.
+
+ explicit ShapeModel();
+ ~ShapeModel();
+
+ /** Creates and returns a new shape textbox structure. */
+ TextBox& createTextBox();
+ /** Creates and returns a new shape client data structure. */
+ ClientData& createClientData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** A shape object that is part of a drawing. May inherit properties from a
+ shape template. */
+class ShapeBase : public ShapeType
+{
+public:
+ /** Returns read/write access to the shape model structure. */
+ inline ShapeModel& getShapeModel() { return maShapeModel; }
+ /** Returns read access to the shape model structure. */
+ inline const ShapeModel& getShapeModel() const { return maShapeModel; }
+
+ /** Returns read access to the shape textbox. */
+ inline const TextBox* getTextBox() const { return maShapeModel.mxTextBox.get(); }
+ /** Returns read access to the shape client data structure. */
+ inline const ClientData* getClientData() const { return maShapeModel.mxClientData.get(); }
+
+ /** Final processing after import of the drawing fragment. */
+ virtual void finalizeFragmentImport();
+
+ /** Returns the real shape name if existing, or a generated shape name. */
+ ::rtl::OUString getShapeName() const;
+
+ /** Returns the shape template with the passed identifier from the child shapes. */
+ virtual const ShapeType* getChildTypeById( const ::rtl::OUString& rShapeId ) const;
+ /** Returns the shape with the passed identifier from the child shapes. */
+ virtual const ShapeBase* getChildById( const ::rtl::OUString& rShapeId ) const;
+
+ /** Creates the corresponding XShape and inserts it into the passed container. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ convertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ShapeParentAnchor* pParentAnchor = 0 ) const;
+
+ /** Converts position and formatting into the passed existing XShape. */
+ void convertFormatting(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ const ShapeParentAnchor* pParentAnchor = 0 ) const;
+
+protected:
+ explicit ShapeBase( Drawing& rDrawing );
+
+ /** Derived classes create the corresponding XShape and insert it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const = 0;
+
+ /** Calculates the final shape rectangle according to the passed anchor,
+ if present, otherwise according to the own anchor settings. */
+ ::com::sun::star::awt::Rectangle calcShapeRectangle(
+ const ShapeParentAnchor* pParentAnchor ) const;
+
+ /** Converts common shape properties such as formatting attributes. */
+ void convertShapeProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape ) const;
+
+protected:
+ ShapeModel maShapeModel; /// The model structure containing shape data.
+};
+
+// ============================================================================
+
+/** A simple shape object based on a specific UNO shape service. */
+class SimpleShape : public ShapeBase
+{
+public:
+ explicit SimpleShape( Drawing& rDrawing, const ::rtl::OUString& rService );
+
+protected:
+ /** Creates the corresponding XShape and inserts it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+
+private:
+ ::rtl::OUString maService; /// Name of the UNO shape service.
+};
+
+// ============================================================================
+
+/** A rectangular shape object. */
+class RectangleShape : public SimpleShape
+{
+public:
+ explicit RectangleShape( Drawing& rDrawing );
+};
+
+// ============================================================================
+
+/** An oval shape object. */
+class EllipseShape : public SimpleShape
+{
+public:
+ explicit EllipseShape( Drawing& rDrawing );
+};
+
+// ============================================================================
+
+/** A polygon shape object. */
+class PolyLineShape : public SimpleShape
+{
+public:
+ explicit PolyLineShape( Drawing& rDrawing );
+
+protected:
+ /** Creates the corresponding XShape and inserts it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+};
+
+// ============================================================================
+
+/** A shape object with custom geometry. */
+class CustomShape : public SimpleShape
+{
+public:
+ explicit CustomShape( Drawing& rDrawing );
+
+protected:
+ /** Creates the corresponding XShape and inserts it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+};
+
+// ============================================================================
+
+/** A complex shape object. This can be a picture shape, a custom shape, an OLE
+ object, or an ActiveX form control. */
+class ComplexShape : public CustomShape
+{
+public:
+ explicit ComplexShape( Drawing& rDrawing );
+
+protected:
+ /** Creates the corresponding XShape and inserts it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+};
+
+// ============================================================================
+
+/** A group shape that extends the basic shape by a container of child shapes. */
+class GroupShape : public ShapeBase
+{
+public:
+ explicit GroupShape( Drawing& rDrawing );
+ virtual ~GroupShape();
+
+ /** Returns read/write access to the container of child shapes and templates. */
+ inline ShapeContainer& getChildren() { return *mxChildren; }
+ /** Returns read access to the container of child shapes and templates. */
+ inline const ShapeContainer& getChildren() const { return *mxChildren; }
+
+ /** Final processing after import of the drawing fragment. */
+ virtual void finalizeFragmentImport();
+
+ /** Returns the shape template with the passed identifier from the child shapes. */
+ virtual const ShapeType* getChildTypeById( const ::rtl::OUString& rShapeId ) const;
+ /** Returns the shape with the passed identifier from the child shapes. */
+ virtual const ShapeBase* getChildById( const ::rtl::OUString& rShapeId ) const;
+
+protected:
+ /** Creates the corresponding XShape and inserts it into the passed container. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ implConvertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+
+private:
+ typedef ::std::auto_ptr< ShapeContainer > ShapeContainerPtr;
+ ShapeContainerPtr mxChildren; /// Shapes and templates that are part of this group.
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx
new file mode 100644
index 000000000000..7b13763e0e40
--- /dev/null
+++ b/oox/inc/oox/vml/vmlshapecontainer.hxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLSHAPECONTAINER_HXX
+#define OOX_VML_VMLSHAPECONTAINER_HXX
+
+#include <com/sun/star/awt/Rectangle.hpp>
+#include "oox/helper/refmap.hxx"
+#include "oox/helper/refvector.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace drawing { class XShapes; }
+} } }
+
+namespace oox {
+namespace vml {
+
+class Drawing;
+class ShapeType;
+class ShapeBase;
+
+// ============================================================================
+
+struct ShapeParentAnchor
+{
+ ::com::sun::star::awt::Rectangle maShapeRect;
+ ::com::sun::star::awt::Rectangle maCoordSys;
+};
+
+// ============================================================================
+
+/** Container that holds a list of shapes and shape templates. */
+class ShapeContainer
+{
+public:
+ explicit ShapeContainer( Drawing& rDrawing );
+ ~ShapeContainer();
+
+ /** Returns the drawing this shape container is part of. */
+ inline Drawing& getDrawing() { return mrDrawing; }
+
+ /** Creates and returns a new shape template object. */
+ ShapeType& createShapeType();
+ /** Creates and returns a new shape object of the specified type. */
+ template< typename ShapeT >
+ ShapeT& createShape();
+
+ /** Final processing after import of the drawing fragment. */
+ void finalizeFragmentImport();
+
+ /** Returns true, if this contaikner does not contain any shapes. */
+ inline bool empty() const { return maShapes.empty(); }
+
+ /** Returns the shape template with the passed identifier.
+ @param bDeep True = searches in all group shapes too. */
+ const ShapeType* getShapeTypeById( const ::rtl::OUString& rShapeId, bool bDeep ) const;
+ /** Returns the shape with the passed identifier.
+ @param bDeep True = searches in all group shapes too. */
+ const ShapeBase* getShapeById( const ::rtl::OUString& rShapeId, bool bDeep ) const;
+
+ /** Searches for a shape type by using the passed functor that takes a
+ constant reference of a ShapeType object. */
+ template< typename Functor >
+ const ShapeType* findShapeType( const Functor& rFunctor ) const;
+ /** Searches for a shape by using the passed functor that takes a constant
+ reference of a ShapeBase object. */
+ template< typename Functor >
+ const ShapeBase* findShape( const Functor& rFunctor ) const;
+
+ /** Returns the first shape in the collection (Word only). */
+ const ShapeBase* getFirstShape() const;
+
+ /** Creates and inserts all UNO shapes into the passed container. */
+ void convertAndInsert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ShapeParentAnchor* pParentAnchor = 0 ) const;
+
+private:
+ typedef RefVector< ShapeType > ShapeTypeVector;
+ typedef RefVector< ShapeBase > ShapeVector;
+ typedef RefMap< ::rtl::OUString, ShapeType > ShapeTypeMap;
+ typedef RefMap< ::rtl::OUString, ShapeBase > ShapeMap;
+
+ Drawing& mrDrawing; /// The VML drawing page that contains this shape.
+ ShapeTypeVector maTypes; /// All shape templates.
+ ShapeVector maShapes; /// All shape definitions.
+ ShapeTypeMap maTypesById; /// All shape templates mapped by identifier.
+ ShapeMap maShapesById; /// All shape definitions mapped by identifier.
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename ShapeT >
+ShapeT& ShapeContainer::createShape()
+{
+ ::boost::shared_ptr< ShapeT > xShape( new ShapeT( mrDrawing ) );
+ maShapes.push_back( xShape );
+ return *xShape;
+}
+
+template< typename Functor >
+const ShapeType* ShapeContainer::findShapeType( const Functor& rFunctor ) const
+{
+ return maTypes.findIf( rFunctor ).get();
+}
+
+template< typename Functor >
+const ShapeBase* ShapeContainer::findShape( const Functor& rFunctor ) const
+{
+ return maShapes.findIf( rFunctor ).get();
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmlshapecontext.hxx b/oox/inc/oox/vml/vmlshapecontext.hxx
new file mode 100644
index 000000000000..7236fe7fef2c
--- /dev/null
+++ b/oox/inc/oox/vml/vmlshapecontext.hxx
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLSHAPECONTEXT_HXX
+#define OOX_VML_VMLSHAPECONTEXT_HXX
+
+#include "oox/core/contexthandler2.hxx"
+
+namespace oox {
+namespace vml {
+
+class Drawing;
+
+struct ShapeTypeModel;
+class ShapeType;
+
+struct ClientData;
+struct ShapeModel;
+class ShapeBase;
+class GroupShape;
+
+class ShapeContainer;
+
+// ============================================================================
+
+class ShapeLayoutContext : public ::oox::core::ContextHandler2
+{
+public:
+ explicit ShapeLayoutContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ Drawing& rDrawing );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ Drawing& mrDrawing;
+};
+
+// ============================================================================
+
+class ClientDataContext : public ::oox::core::ContextHandler2
+{
+public:
+ explicit ClientDataContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ ClientData& rClientData,
+ const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+private:
+ ClientData& mrClientData;
+ ::rtl::OUString maElementText;
+};
+
+// ============================================================================
+
+class ShapeContextBase : public ::oox::core::ContextHandler2
+{
+public:
+ static ::oox::core::ContextHandlerRef
+ createShapeContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ ShapeContainer& rShapes,
+ sal_Int32 nElement,
+ const AttributeList& rAttribs );
+
+protected:
+ explicit ShapeContextBase( ::oox::core::ContextHandler2Helper& rParent );
+};
+
+// ============================================================================
+
+class ShapeTypeContext : public ShapeContextBase
+{
+public:
+ explicit ShapeTypeContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ ShapeType& rShapeType,
+ const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ /** Processes the 'style' attribute. */
+ void setStyle( const ::rtl::OUString& rStyle );
+
+ /** Resolve a relation identifier to a fragment path. */
+ OptValue< ::rtl::OUString > decodeFragmentPath( const AttributeList& rAttribs, sal_Int32 nToken ) const;
+
+private:
+ ShapeTypeModel& mrTypeModel;
+};
+
+// ============================================================================
+
+class ShapeContext : public ShapeTypeContext
+{
+public:
+ explicit ShapeContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ ShapeBase& rShape,
+ const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ /** Processes the 'points' attribute. */
+ void setPoints( const ::rtl::OUString& rPoints );
+
+private:
+ ShapeModel& mrShapeModel;
+};
+
+// ============================================================================
+
+class GroupShapeContext : public ShapeContext
+{
+public:
+ explicit GroupShapeContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ GroupShape& rShape,
+ const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ ShapeContainer& mrShapes;
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmltextbox.hxx b/oox/inc/oox/vml/vmltextbox.hxx
new file mode 100755
index 000000000000..5aedaf86bc74
--- /dev/null
+++ b/oox/inc/oox/vml/vmltextbox.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLTEXTBOX_HXX
+#define OOX_VML_VMLTEXTBOX_HXX
+
+#include <vector>
+#include <rtl/ustring.hxx>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+/** Font settings for a text portion in a textbox. */
+struct TextFontModel
+{
+ OptValue< ::rtl::OUString > moName; /// Font name.
+ OptValue< ::rtl::OUString > moColor; /// Font color, HTML encoded, sort of.
+ OptValue< sal_Int32 > monSize; /// Font size in twips.
+ OptValue< sal_Int32 > monUnderline; /// Single or double underline.
+ OptValue< sal_Int32 > monEscapement; /// Subscript or superscript.
+ OptValue< bool > mobBold;
+ OptValue< bool > mobItalic;
+ OptValue< bool > mobStrikeout;
+
+ explicit TextFontModel();
+};
+
+// ============================================================================
+
+/** A text portion in a textbox with the same formatting for all characters. */
+struct TextPortionModel
+{
+ TextFontModel maFont;
+ ::rtl::OUString maText;
+
+ explicit TextPortionModel( const TextFontModel& rFont, const ::rtl::OUString& rText );
+};
+
+// ============================================================================
+
+/** The textbox contains all text contents and properties. */
+class TextBox
+{
+public:
+ explicit TextBox();
+
+ /** Appends a new text portion to the textbox. */
+ void appendPortion( const TextFontModel& rFont, const ::rtl::OUString& rText );
+
+ /** Returns the current number of text portions. */
+ inline size_t getPortionCount() const { return maPortions.size(); }
+ /** Returns the font settings of the first text portion. */
+ const TextFontModel* getFirstFont() const;
+ /** Returns the entire text of all text portions. */
+ ::rtl::OUString getText() const;
+
+private:
+ typedef ::std::vector< TextPortionModel > PortionVector;
+
+ PortionVector maPortions;
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/vml/vmltextboxcontext.hxx b/oox/inc/oox/vml/vmltextboxcontext.hxx
new file mode 100755
index 000000000000..1dc8832f9cc4
--- /dev/null
+++ b/oox/inc/oox/vml/vmltextboxcontext.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_VML_VMLTEXTBOXCONTEXT_HXX
+#define OOX_VML_VMLTEXTBOXCONTEXT_HXX
+
+#include "oox/core/contexthandler2.hxx"
+#include "oox/vml/vmltextbox.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+class TextPortionContext : public ::oox::core::ContextHandler2
+{
+public:
+ explicit TextPortionContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ TextBox& rTextBox,
+ const TextFontModel& rParentFont,
+ sal_Int32 nElement,
+ const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+private:
+ TextBox& mrTextBox;
+ TextFontModel maFont;
+ size_t mnInitialPortions;
+};
+
+// ============================================================================
+
+class TextBoxContext : public ::oox::core::ContextHandler2
+{
+public:
+ explicit TextBoxContext(
+ ::oox::core::ContextHandler2Helper& rParent,
+ TextBox& rTextBox,
+ const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef
+ onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ TextBox& mrTextBox;
+};
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/addressconverter.hxx b/oox/inc/oox/xls/addressconverter.hxx
new file mode 100644
index 000000000000..11b5e74ccd5c
--- /dev/null
+++ b/oox/inc/oox/xls/addressconverter.hxx
@@ -0,0 +1,691 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_ADDRESSCONVERTER_HXX
+#define OOX_XLS_ADDRESSCONVERTER_HXX
+
+#include <vector>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "oox/xls/workbookhelper.hxx"
+
+namespace oox {
+namespace xls {
+
+class BiffInputStream;
+class BiffOutputStream;
+
+// ============================================================================
+// ============================================================================
+
+/** A vector of com.sun.star.table.CellRangeAddress elements and additional
+ functionality. */
+class ApiCellRangeList : public ::std::vector< ::com::sun::star::table::CellRangeAddress >
+{
+public:
+ inline explicit ApiCellRangeList() {}
+
+ /** Returns the base address of this range list (top-left cell of first range). */
+ ::com::sun::star::table::CellAddress
+ getBaseAddress() const;
+};
+
+// ============================================================================
+
+/** A 2D cell address struct for binary filters. */
+struct BinAddress
+{
+ sal_Int32 mnCol;
+ sal_Int32 mnRow;
+
+ inline explicit BinAddress() : mnCol( 0 ), mnRow( 0 ) {}
+ inline explicit BinAddress( sal_Int32 nCol, sal_Int32 nRow ) : mnCol( nCol ), mnRow( nRow ) {}
+ inline explicit BinAddress( const ::com::sun::star::table::CellAddress& rAddr ) : mnCol( rAddr.Column ), mnRow( rAddr.Row ) {}
+
+ inline void set( sal_Int32 nCol, sal_Int32 nRow ) { mnCol = nCol; mnRow = nRow; }
+ inline void set( const ::com::sun::star::table::CellAddress& rAddr ) { mnCol = rAddr.Column; mnRow = rAddr.Row; }
+
+ void read( SequenceInputStream& rStrm );
+ void read( BiffInputStream& rStrm, bool bCol16Bit = true, bool bRow32Bit = false );
+ void write( BiffOutputStream& rStrm, bool bCol16Bit = true, bool bRow32Bit = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+inline bool operator==( const BinAddress& rL, const BinAddress& rR )
+{
+ return (rL.mnCol == rR.mnCol) && (rL.mnRow == rR.mnRow);
+}
+
+inline bool operator<( const BinAddress& rL, const BinAddress& rR )
+{
+ return (rL.mnCol < rR.mnCol) || ((rL.mnCol == rR.mnCol) && (rL.mnRow < rR.mnRow));
+}
+
+inline SequenceInputStream& operator>>( SequenceInputStream& rStrm, BinAddress& orPos )
+{
+ orPos.read( rStrm );
+ return rStrm;
+}
+
+inline BiffInputStream& operator>>( BiffInputStream& rStrm, BinAddress& orPos )
+{
+ orPos.read( rStrm );
+ return rStrm;
+}
+
+inline BiffOutputStream& operator<<( BiffOutputStream& rStrm, const BinAddress& rPos )
+{
+ rPos.write( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+/** A 2D cell range address struct for binary filters. */
+struct BinRange
+{
+ BinAddress maFirst;
+ BinAddress maLast;
+
+ inline explicit BinRange() {}
+ inline explicit BinRange( const BinAddress& rAddr ) : maFirst( rAddr ), maLast( rAddr ) {}
+ inline explicit BinRange( const BinAddress& rFirst, const BinAddress& rLast ) : maFirst( rFirst ), maLast( rLast ) {}
+ inline explicit BinRange( sal_Int32 nCol1, sal_Int32 nRow1, sal_Int32 nCol2, sal_Int32 nRow2 ) :
+ maFirst( nCol1, nRow1 ), maLast( nCol2, nRow2 ) {}
+ inline explicit BinRange( const ::com::sun::star::table::CellAddress& rAddr ) : maFirst( rAddr ), maLast( rAddr ) {}
+ inline explicit BinRange( const ::com::sun::star::table::CellAddress& rFirst, const ::com::sun::star::table::CellAddress& rLast ) : maFirst( rFirst ), maLast( rLast ) {}
+ inline explicit BinRange( const ::com::sun::star::table::CellRangeAddress& rRange ) : maFirst( rRange.StartColumn, rRange.StartRow ), maLast( rRange.EndColumn, rRange.EndRow ) {}
+
+ inline void set( const BinAddress& rFirst, const BinAddress& rLast )
+ { maFirst = rFirst; maLast = rLast; }
+ inline void set( sal_Int32 nCol1, sal_Int32 nRow1, sal_Int32 nCol2, sal_Int32 nRow2 )
+ { maFirst.set( nCol1, nRow1 ); maLast.set( nCol2, nRow2 ); }
+ inline void set( const ::com::sun::star::table::CellAddress& rFirst, const ::com::sun::star::table::CellAddress& rLast )
+ { maFirst.set( rFirst ); maLast.set( rLast ); }
+ inline void set( const ::com::sun::star::table::CellRangeAddress& rRange )
+ { maFirst.set( rRange.StartColumn, rRange.StartRow ); maLast.set( rRange.EndColumn, rRange.EndRow ); }
+
+ inline sal_Int32 getColCount() const { return maLast.mnCol - maFirst.mnCol + 1; }
+ inline sal_Int32 getRowCount() const { return maLast.mnRow - maFirst.mnRow + 1; }
+ bool contains( const BinAddress& rAddr ) const;
+
+ void read( SequenceInputStream& rStrm );
+ void read( BiffInputStream& rStrm, bool bCol16Bit = true, bool bRow32Bit = false );
+ void write( BiffOutputStream& rStrm, bool bCol16Bit = true, bool bRow32Bit = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+inline bool operator==( const BinRange& rL, const BinRange& rR )
+{
+ return (rL.maFirst == rR.maFirst) && (rL.maLast == rR.maLast);
+}
+
+inline bool operator<( const BinRange& rL, const BinRange& rR )
+{
+ return (rL.maFirst < rR.maFirst) || ((rL.maFirst == rR.maFirst) && (rL.maLast < rR.maLast));
+}
+
+inline SequenceInputStream& operator>>( SequenceInputStream& rStrm, BinRange& orRange )
+{
+ orRange.read( rStrm );
+ return rStrm;
+}
+
+inline BiffInputStream& operator>>( BiffInputStream& rStrm, BinRange& orRange )
+{
+ orRange.read( rStrm );
+ return rStrm;
+}
+
+inline BiffOutputStream& operator<<( BiffOutputStream& rStrm, const BinRange& rRange )
+{
+ rRange.write( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+/** A 2D cell range address list for binary filters. */
+class BinRangeList : public ::std::vector< BinRange >
+{
+public:
+ inline explicit BinRangeList() {}
+
+ BinRange getEnclosingRange() const;
+
+ void read( SequenceInputStream& rStrm );
+ void read( BiffInputStream& rStrm, bool bCol16Bit = true, bool bRow32Bit = false );
+ void write( BiffOutputStream& rStrm, bool bCol16Bit = true, bool bRow32Bit = false ) const;
+ void writeSubList( BiffOutputStream& rStrm,
+ size_t nBegin, size_t nCount, bool bCol16Bit = true, bool bRow32Bit = false ) const;
+};
+
+// ----------------------------------------------------------------------------
+
+inline SequenceInputStream& operator>>( SequenceInputStream& rStrm, BinRangeList& orRanges )
+{
+ orRanges.read( rStrm );
+ return rStrm;
+}
+
+inline BiffInputStream& operator>>( BiffInputStream& rStrm, BinRangeList& orRanges )
+{
+ orRanges.read( rStrm );
+ return rStrm;
+}
+
+inline BiffOutputStream& operator<<( BiffOutputStream& rStrm, const BinRangeList& rRanges )
+{
+ rRanges.write( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+/** Different target types that can be encoded in a BIFF URL. */
+enum BiffTargetType
+{
+ BIFF_TARGETTYPE_URL, /// URL, URL with sheet name, or sheet name.
+ BIFF_TARGETTYPE_SAMESHEET, /// Target for special '!A1' syntax to refer to current sheet.
+ BIFF_TARGETTYPE_LIBRARY, /// Library directory in application installation.
+ BIFF_TARGETTYPE_DDE_OLE, /// DDE server/topic or OLE class/target.
+ BIFF_TARGETTYPE_UNKNOWN /// Unknown/unsupported target type.
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Converter for cell addresses and cell ranges for OOXML and BIFF filters.
+ */
+class AddressConverter : public WorkbookHelper
+{
+public:
+ explicit AddressConverter( const WorkbookHelper& rHelper );
+
+ // ------------------------------------------------------------------------
+
+ /** Tries to parse the passed string for a 2d cell address in A1 notation.
+
+ This function accepts all strings that match the regular expression
+ "[a-zA-Z]{1,6}0*[1-9][0-9]{0,8}" (without quotes), i.e. 1 to 6 letters
+ for the column index (translated to 0-based column indexes from 0 to
+ 321,272,405), and 1 to 9 digits for the 1-based row index (translated
+ to 0-based row indexes from 0 to 999,999,998). The row number part may
+ contain leading zeros, they will be ignored. It is up to the caller to
+ handle cell addresses outside of a specific valid range (e.g. the
+ entire spreadsheet).
+
+ @param ornColumn (out-parameter) Returns the converted column index.
+ @param ornRow (out-parameter) returns the converted row index.
+ @param rString The string containing the cell address.
+ @param nStart Start index of string part in rString to be parsed.
+ @param nLength Length of string part in rString to be parsed.
+
+ @return true = Parsed string was valid, returned values can be used.
+ */
+ static bool parseOoxAddress2d(
+ sal_Int32& ornColumn, sal_Int32& ornRow,
+ const ::rtl::OUString& rString,
+ sal_Int32 nStart = 0,
+ sal_Int32 nLength = SAL_MAX_INT32 );
+
+ /** Tries to parse the passed string for a 2d cell range in A1 notation.
+
+ This function accepts all strings that match the regular expression
+ "ADDR(:ADDR)?" (without quotes), where ADDR is a cell address accepted
+ by the parseOoxAddress2d() function of this class. It is up to the
+ caller to handle cell ranges outside of a specific valid range (e.g.
+ the entire spreadsheet).
+
+ @param ornStartColumn (out-parameter) Returns the converted start column index.
+ @param ornStartRow (out-parameter) returns the converted start row index.
+ @param ornEndColumn (out-parameter) Returns the converted end column index.
+ @param ornEndRow (out-parameter) returns the converted end row index.
+ @param rString The string containing the cell address.
+ @param nStart Start index of string part in rString to be parsed.
+ @param nLength Length of string part in rString to be parsed.
+
+ @return true = Parsed string was valid, returned values can be used.
+ */
+ static bool parseOoxRange2d(
+ sal_Int32& ornStartColumn, sal_Int32& ornStartRow,
+ sal_Int32& ornEndColumn, sal_Int32& ornEndRow,
+ const ::rtl::OUString& rString,
+ sal_Int32 nStart = 0,
+ sal_Int32 nLength = SAL_MAX_INT32 );
+
+ /** Tries to parse an encoded name of an external link target in BIFF
+ documents, e.g. from EXTERNSHEET or SUPBOOK records.
+
+ @param orClassName (out-parameter) DDE server name or OLE class name.
+ @param orTargetUrl (out-parameter) Target URL, DDE topic or OLE object name.
+ @param orSheetName (out-parameter) Sheet name in target document.
+ @param rBiffEncoded Encoded name of the external link target.
+ @param bFromDConRec True = path from DCONREF/DCONNAME/DCONBINAME records, false = other records.
+
+ @return Type of the decoded target.
+ */
+ BiffTargetType parseBiffTargetUrl(
+ ::rtl::OUString& orClassName,
+ ::rtl::OUString& orTargetUrl,
+ ::rtl::OUString& orSheetName,
+ const ::rtl::OUString& rBiffTargetUrl,
+ bool bFromDConRec = false );
+
+ // ------------------------------------------------------------------------
+
+ /** Returns the biggest valid cell address in the own Calc document. */
+ inline const ::com::sun::star::table::CellAddress&
+ getMaxApiAddress() const { return maMaxApiPos; }
+
+ /** Returns the biggest valid cell address in the imported/exported
+ Excel document. */
+ inline const ::com::sun::star::table::CellAddress&
+ getMaxXlsAddress() const { return maMaxXlsPos; }
+
+ /** Returns the biggest valid cell address in both Calc and the
+ imported/exported Excel document. */
+ inline const ::com::sun::star::table::CellAddress&
+ getMaxAddress() const { return maMaxPos; }
+
+ /** Returns the column overflow status. */
+ inline bool isColOverflow() const { return mbColOverflow; }
+ /** Returns the row overflow status. */
+ inline bool isRowOverflow() const { return mbRowOverflow; }
+ /** Returns the sheet overflow status. */
+ inline bool isTabOverflow() const { return mbTabOverflow; }
+
+ // ------------------------------------------------------------------------
+
+ /** Checks if the passed column index is valid.
+
+ @param nCol The column index to check.
+ @param bTrackOverflow true = Update the internal overflow flag, if the
+ column index is outside of the supported limits.
+ @return true = Passed column index is valid (no index overflow).
+ */
+ bool checkCol( sal_Int32 nCol, bool bTrackOverflow );
+
+ /** Checks if the passed row index is valid.
+
+ @param nRow The row index to check.
+ @param bTrackOverflow true = Update the internal overflow flag, if the
+ row index is outside of the supported limits.
+ @return true = Passed row index is valid (no index overflow).
+ */
+ bool checkRow( sal_Int32 nRow, bool bTrackOverflow );
+
+ /** Checks if the passed sheet index is valid.
+
+ @param nSheet The sheet index to check.
+ @param bTrackOverflow true = Update the internal overflow flag, if the
+ sheet index is outside of the supported limits.
+ @return true = Passed sheet index is valid (no index overflow).
+ */
+ bool checkTab( sal_Int16 nSheet, bool bTrackOverflow );
+
+ // ------------------------------------------------------------------------
+
+ /** Checks the passed cell address if it fits into the spreadsheet limits.
+
+ @param rAddress The cell address to be checked.
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the address is outside of the supported sheet limits.
+ @return true = Passed address is valid (no index overflow).
+ */
+ bool checkCellAddress(
+ const ::com::sun::star::table::CellAddress& rAddress,
+ bool bTrackOverflow );
+
+ /** Converts the passed string to a single cell address, without checking
+ any sheet limits.
+
+ @param orAddress (out-parameter) Returns the converted cell address.
+ @param rString Cell address string in A1 notation.
+ @param nSheet Sheet index to be inserted into orAddress.
+ @return true = Cell address could be parsed from the passed string.
+ */
+ bool convertToCellAddressUnchecked(
+ ::com::sun::star::table::CellAddress& orAddress,
+ const ::rtl::OUString& rString,
+ sal_Int16 nSheet );
+
+ /** Tries to convert the passed string to a single cell address.
+
+ @param orAddress (out-parameter) Returns the converted cell address.
+ @param rString Cell address string in A1 notation.
+ @param nSheet Sheet index to be inserted into orAddress (will be checked).
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the address is outside of the supported sheet limits.
+ @return true = Converted address is valid (no index overflow).
+ */
+ bool convertToCellAddress(
+ ::com::sun::star::table::CellAddress& orAddress,
+ const ::rtl::OUString& rString,
+ sal_Int16 nSheet,
+ bool bTrackOverflow );
+
+ /** Returns a valid cell address by moving it into allowed dimensions.
+
+ @param rString Cell address string in A1 notation.
+ @param nSheet Sheet index for the returned address (will be checked).
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the address is outside of the supported sheet limits.
+ @return A valid API cell address struct. */
+ ::com::sun::star::table::CellAddress
+ createValidCellAddress(
+ const ::rtl::OUString& rString,
+ sal_Int16 nSheet,
+ bool bTrackOverflow );
+
+ /** Converts the passed address to a single cell address, without checking
+ any sheet limits.
+
+ @param orAddress (out-parameter) Returns the converted cell address.
+ @param rBinAddress Binary cell address struct.
+ @param nSheet Sheet index to be inserted into orAddress.
+ */
+ void convertToCellAddressUnchecked(
+ ::com::sun::star::table::CellAddress& orAddress,
+ const BinAddress& rBinAddress,
+ sal_Int16 nSheet );
+
+ /** Tries to convert the passed address to a single cell address.
+
+ @param orAddress (out-parameter) Returns the converted cell address.
+ @param rBinAddress Binary cell address struct.
+ @param nSheet Sheet index to be inserted into orAddress (will be checked).
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the address is outside of the supported sheet limits.
+ @return true = Converted address is valid (no index overflow).
+ */
+ bool convertToCellAddress(
+ ::com::sun::star::table::CellAddress& orAddress,
+ const BinAddress& rBinAddress,
+ sal_Int16 nSheet,
+ bool bTrackOverflow );
+
+ /** Returns a valid cell address by moving it into allowed dimensions.
+
+ @param rBinAddress Binary cell address struct.
+ @param nSheet Sheet index for the returned address (will be checked).
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the address is outside of the supported sheet limits.
+ @return A valid API cell address struct. */
+ ::com::sun::star::table::CellAddress
+ createValidCellAddress(
+ const BinAddress& rBinAddress,
+ sal_Int16 nSheet,
+ bool bTrackOverflow );
+
+ // ------------------------------------------------------------------------
+
+ /** Checks the passed cell range if it fits into the spreadsheet limits.
+
+ @param rRange The cell range address to be checked.
+ @param bAllowOverflow true = Allow ranges that start inside the
+ supported sheet limits but may end outside of these limits.
+ false = Do not allow ranges that overflow the supported limits.
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the passed range contains cells outside of the supported sheet
+ limits.
+ @return true = Cell range is valid. This function returns also true,
+ if only parts of the range are outside the current sheet limits and
+ such an overflow is allowed via parameter bAllowOverflow. Returns
+ false, if the entire range is outside the sheet limits, or if
+ overflow is not allowed via parameter bAllowOverflow.
+ */
+ bool checkCellRange(
+ const ::com::sun::star::table::CellRangeAddress& rRange,
+ bool bAllowOverflow, bool bTrackOverflow );
+
+ /** Checks the passed cell range, may try to fit it to current sheet limits.
+
+ First, this function reorders the column and row indexes so that the
+ starting indexes are less than or equal to the end indexes. Then,
+ depending on the parameter bAllowOverflow, the range is just checked or
+ cropped to the current sheet limits.
+
+ @param orRange (in-out-parameter) Converts the passed cell range
+ into a valid cell range address. If the passed range contains cells
+ outside the currently supported spreadsheet limits, it will be
+ cropped to these limits.
+ @param bAllowOverflow true = Allow ranges that start inside the
+ supported sheet limits but may end outside of these limits. The
+ cell range returned in orRange will be cropped to these limits.
+ false = Do not allow ranges that overflow the supported limits. The
+ function will return false when the range overflows the sheet limits.
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the original range contains cells outside of the supported sheet
+ limits.
+ @return true = Converted range address is valid. This function
+ returns also true, if overflowing ranges are allowed via parameter
+ bAllowOverflow and the range has been cropped, but still contains
+ cells inside the current sheet limits. Returns false, if the entire
+ range is outside the sheet limits or overflowing ranges are not
+ allowed via parameter bAllowOverflow.
+ */
+ bool validateCellRange(
+ ::com::sun::star::table::CellRangeAddress& orRange,
+ bool bAllowOverflow, bool bTrackOverflow );
+
+ /** Converts the passed string to a cell range address, without checking
+ any sheet limits.
+
+ @param orRange (out-parameter) Returns the converted range address.
+ @param rString Cell range string in A1 notation.
+ @param nSheet Sheet index to be inserted into orRange.
+ @return true = Range address could be parsed from the passed string.
+ */
+ bool convertToCellRangeUnchecked(
+ ::com::sun::star::table::CellRangeAddress& orRange,
+ const ::rtl::OUString& rString,
+ sal_Int16 nSheet );
+
+ /** Tries to convert the passed string to a cell range address.
+
+ @param orRange (out-parameter) Returns the converted cell range
+ address. If the original range in the passed string contains cells
+ outside the currently supported spreadsheet limits, and parameter
+ bAllowOverflow is set to true, the range will be cropped to these
+ limits. Example: the range string "A1:ZZ100000" may be converted to
+ the range A1:IV65536.
+ @param rString Cell range string in A1 notation.
+ @param nSheet Sheet index to be inserted into orRange (will be checked).
+ @param bAllowOverflow true = Allow ranges that start inside the
+ supported sheet limits but may end outside of these limits. The
+ cell range returned in orRange will be cropped to these limits.
+ false = Do not allow ranges that overflow the supported limits.
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the original range contains cells outside of the supported sheet
+ limits.
+ @return true = Converted and returned range is valid. This function
+ returns also true, if overflowing ranges are allowed via parameter
+ bAllowOverflow and the range has been cropped, but still contains
+ cells inside the current sheet limits. Returns false, if the entire
+ range is outside the sheet limits or overflowing ranges are not
+ allowed via parameter bAllowOverflow.
+ */
+ bool convertToCellRange(
+ ::com::sun::star::table::CellRangeAddress& orRange,
+ const ::rtl::OUString& rString,
+ sal_Int16 nSheet,
+ bool bAllowOverflow, bool bTrackOverflow );
+
+ /** Converts the passed range to a cell range address, without checking any
+ sheet limits.
+
+ @param orRange (out-parameter) Returns the converted range address.
+ @param rBinRange Binary cell range struct.
+ @param nSheet Sheet index to be inserted into orRange.
+ */
+ void convertToCellRangeUnchecked(
+ ::com::sun::star::table::CellRangeAddress& orRange,
+ const BinRange& rBinRange,
+ sal_Int16 nSheet );
+
+ /** Tries to convert the passed range to a cell range address.
+
+ @param orRange (out-parameter) Returns the converted cell range
+ address. If the passed original range contains cells outside the
+ currently supported spreadsheet limits, and parameter bAllowOverflow
+ is set to true, the range will be cropped to these limits.
+ @param rBinRange Binary cell range struct.
+ @param nSheet Sheet index to be inserted into orRange (will be checked).
+ @param bAllowOverflow true = Allow ranges that start inside the
+ supported sheet limits but may end outside of these limits. The
+ cell range returned in orRange will be cropped to these limits.
+ false = Do not allow ranges that overflow the supported limits.
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the original range contains cells outside of the supported sheet
+ limits.
+ @return true = Converted and returned range is valid. This function
+ returns also true, if overflowing ranges are allowed via parameter
+ bAllowOverflow and the range has been cropped, but still contains
+ cells inside the current sheet limits. Returns false, if the entire
+ range is outside the sheet limits or if overflowing ranges are not
+ allowed via parameter bAllowOverflow.
+ */
+ bool convertToCellRange(
+ ::com::sun::star::table::CellRangeAddress& orRange,
+ const BinRange& rBinRange,
+ sal_Int16 nSheet,
+ bool bAllowOverflow, bool bTrackOverflow );
+
+ // ------------------------------------------------------------------------
+
+ /** Checks the passed cell range list if it fits into the spreadsheet limits.
+
+ @param rRanges The cell range list to be checked.
+ @param bAllowOverflow true = Allow ranges that start inside the
+ supported sheet limits but may end outside of these limits.
+ false = Do not allow ranges that overflow the supported limits.
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the passed range list contains cells outside of the supported sheet
+ limits.
+ @return true = All cell ranges are valid. This function returns also
+ true, if overflowing ranges are allowed via parameter bAllowOverflow
+ and only parts of the ranges are outside the current sheet limits.
+ Returns false, if one of the ranges is completely outside the sheet
+ limits or if overflowing ranges are not allowed via parameter
+ bAllowOverflow.
+ */
+ bool checkCellRangeList(
+ const ApiCellRangeList& rRanges,
+ bool bAllowOverflow, bool bTrackOverflow );
+
+ /** Tries to restrict the passed cell range list to current sheet limits.
+
+ @param orRanges (in-out-parameter) Restricts the cell range addresses
+ in the passed list to the current sheet limits and removes invalid
+ ranges from the list.
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the original ranges contain cells outside of the supported sheet
+ limits.
+ */
+ void validateCellRangeList(
+ ApiCellRangeList& orRanges,
+ bool bTrackOverflow );
+
+ /** Tries to convert the passed string to a cell range list.
+
+ @param orRanges (out-parameter) Returns the converted cell range
+ addresses. If a range in the passed string contains cells outside
+ the currently supported spreadsheet limits, it will be cropped to
+ these limits. Example: the range string "A1:ZZ100000" may be
+ converted to the range A1:IV65536. If a range is completely outside
+ the limits, it will be omitted.
+ @param rString Cell range list string in A1 notation, space separated.
+ @param nSheet Sheet index to be inserted into orRanges (will be checked).
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the original ranges contain cells outside of the supported sheet
+ limits.
+ */
+ void convertToCellRangeList(
+ ApiCellRangeList& orRanges,
+ const ::rtl::OUString& rString,
+ sal_Int16 nSheet,
+ bool bTrackOverflow );
+
+ /** Tries to convert the passed range list to a cell range list.
+
+ @param orRanges (out-parameter) Returns the converted cell range
+ addresses. If a range in the passed string contains cells outside
+ the currently supported spreadsheet limits, it will be cropped to
+ these limits. Example: the range string "A1:ZZ100000" may be
+ converted to the range A1:IV65536. If a range is completely outside
+ the limits, it will be omitted.
+ @param rBinRanges List of binary cell range objects.
+ @param nSheet Sheet index to be inserted into orRanges (will be checked).
+ @param bTrackOverflow true = Update the internal overflow flags, if
+ the original ranges contain cells outside of the supported sheet
+ limits.
+ */
+ void convertToCellRangeList(
+ ApiCellRangeList& orRanges,
+ const BinRangeList& rBinRanges,
+ sal_Int16 nSheet,
+ bool bTrackOverflow );
+
+ // ------------------------------------------------------------------------
+private:
+ void initializeMaxPos(
+ sal_Int16 nMaxXlsTab, sal_Int32 nMaxXlsCol, sal_Int32 nMaxXlsRow );
+
+private:
+ struct ControlCharacters
+ {
+ sal_Unicode mcThisWorkbook; /// Control character: Link to current workbook.
+ sal_Unicode mcExternal; /// Control character: Link to external workbook/sheet.
+ sal_Unicode mcThisSheet; /// Control character: Link to current sheet.
+ sal_Unicode mcInternal; /// Control character: Link to internal sheet.
+ sal_Unicode mcSameSheet; /// Control character: Link to same sheet (special '!A1' syntax).
+
+ void set(
+ sal_Unicode cThisWorkbook, sal_Unicode cExternal,
+ sal_Unicode cThisSheet, sal_Unicode cInternal,
+ sal_Unicode cSameSheet );
+ };
+
+ ::com::sun::star::table::CellAddress maMaxApiPos; /// Maximum valid cell address in Calc.
+ ::com::sun::star::table::CellAddress maMaxXlsPos; /// Maximum valid cell address in Excel.
+ ::com::sun::star::table::CellAddress maMaxPos; /// Maximum valid cell address in Calc/Excel.
+ ControlCharacters maLinkChars; /// Control characters for external link import (BIFF).
+ ControlCharacters maDConChars; /// Control characters for DCON* record import (BIFF).
+ bool mbColOverflow; /// Flag for "columns overflow".
+ bool mbRowOverflow; /// Flag for "rows overflow".
+ bool mbTabOverflow; /// Flag for "tables overflow".
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/autofilterbuffer.hxx b/oox/inc/oox/xls/autofilterbuffer.hxx
new file mode 100755
index 000000000000..ddf083c2ea98
--- /dev/null
+++ b/oox/inc/oox/xls/autofilterbuffer.hxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_AUTOFILTERBUFFER_HXX
+#define OOX_XLS_AUTOFILTERBUFFER_HXX
+
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { struct TableFilterField2; }
+ namespace sheet { class XDatabaseRange; }
+ namespace sheet { class XSheetFilterDescriptor2; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Contains UNO API filter settings for a column in a filtered range. */
+struct ApiFilterSettings
+{
+ typedef ::std::vector< ::com::sun::star::sheet::TableFilterField2 > FilterFieldVector;
+
+ FilterFieldVector maFilterFields; /// List of UNO API filter settings.
+ OptValue< bool > mobNeedsRegExp; /// If set, requires regular expressions to be enabled/disabled.
+
+ explicit ApiFilterSettings();
+
+ void appendField( bool bAnd, sal_Int32 nOperator, double fValue );
+ void appendField( bool bAnd, sal_Int32 nOperator, const ::rtl::OUString& rValue );
+};
+
+// ============================================================================
+
+/** Base class for specific filter settings for a column in a filtered range.
+ */
+class FilterSettingsBase : public WorkbookHelper
+{
+public:
+ explicit FilterSettingsBase( const WorkbookHelper& rHelper );
+
+ /** Derived classes import filter settings from the passed attribute list. */
+ virtual void importAttribs( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Derived classes import filter settings from the passed record. */
+ virtual void importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ /** Derived classes import filter settings from the FILTERCOLUMN record. */
+ virtual void importBiffRecord( BiffInputStream& rStrm, sal_uInt16 nFlags );
+
+ /** Derived classes return converted UNO API filter settings representing all filter settings. */
+ virtual ApiFilterSettings finalizeImport( sal_Int32 nMaxCount );
+};
+
+typedef ::boost::shared_ptr< FilterSettingsBase > FilterSettingsRef;
+
+// ============================================================================
+
+/** Settings for a discrete filter, specifying a list of values to be shown in
+ the filtered range.
+ */
+class DiscreteFilter : public FilterSettingsBase
+{
+public:
+ explicit DiscreteFilter( const WorkbookHelper& rHelper );
+
+ /** Imports filter settings from the filters and filter elements. */
+ virtual void importAttribs( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Imports filter settings from the FILTERS and FILTER records. */
+ virtual void importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ /** Returns converted UNO API filter settings representing all filter settings. */
+ virtual ApiFilterSettings finalizeImport( sal_Int32 nMaxCount );
+
+private:
+ typedef ::std::vector< ::rtl::OUString > FilterValueVector;
+
+ FilterValueVector maValues;
+ sal_Int32 mnCalendarType;
+ bool mbShowBlank;
+};
+
+// ============================================================================
+
+/** Settings for a top-10 filter. */
+class Top10Filter : public FilterSettingsBase
+{
+public:
+ explicit Top10Filter( const WorkbookHelper& rHelper );
+
+ /** Imports filter settings from the filters and filter elements. */
+ virtual void importAttribs( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Imports filter settings from the FILTERS and FILTER records. */
+ virtual void importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ /** Imports filter settings from the FILTERCOLUMN record. */
+ virtual void importBiffRecord( BiffInputStream& rStrm, sal_uInt16 nFlags );
+
+ /** Returns converted UNO API filter settings representing all filter settings. */
+ virtual ApiFilterSettings finalizeImport( sal_Int32 nMaxCount );
+
+private:
+ double mfValue; /// Number of items or percentage.
+ bool mbTop; /// True = show top (greatest) items/percentage.
+ bool mbPercent; /// True = percentage, false = number of items.
+};
+
+// ============================================================================
+
+/** A filter criterion for a custom filter. */
+struct FilterCriterionModel
+{
+ ::com::sun::star::uno::Any maValue; /// Comparison operand.
+ sal_Int32 mnOperator; /// Comparison operator.
+ sal_uInt8 mnDataType; /// Operand data type (BIFF only).
+ sal_uInt8 mnStrLen; /// Length of string operand (BIFF5-BIFF8 only).
+
+ explicit FilterCriterionModel();
+
+ /** Sets the passed BIFF operator constant. */
+ void setBiffOperator( sal_uInt8 nOperator );
+
+ /** Imports the criterion model from the passed BIFF12 stream. */
+ void readBiffData( SequenceInputStream& rStrm );
+ /** Imports the initial criterion data from the passed BIFF5/BIFF8 stream. */
+ void readBiffData( BiffInputStream& rStrm );
+ /** Imports the trailing string data from the passed BIFF5/BIFF8 stream. */
+ void readString( BiffInputStream& rStrm, BiffType eBiff, rtl_TextEncoding eTextEnc );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Settings for a custom filter, specifying one or two comparison operators
+ associated with some values.
+ */
+class CustomFilter : public FilterSettingsBase
+{
+public:
+ explicit CustomFilter( const WorkbookHelper& rHelper );
+
+ /** Imports filter settings from the filters and filter elements. */
+ virtual void importAttribs( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Imports filter settings from the FILTERS and FILTER records. */
+ virtual void importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ /** Imports filter settings from the FILTERCOLUMN record. */
+ virtual void importBiffRecord( BiffInputStream& rStrm, sal_uInt16 nFlags );
+
+ /** Returns converted UNO API filter settings representing all filter settings. */
+ virtual ApiFilterSettings finalizeImport( sal_Int32 nMaxCount );
+
+private:
+ /** Apeends the passed filter criteriom, if it contains valid settings. */
+ void appendCriterion( const FilterCriterionModel& rCriterion );
+
+private:
+ typedef ::std::vector< FilterCriterionModel > FilterCriterionVector;
+
+ FilterCriterionVector maCriteria;
+ bool mbAnd;
+};
+
+// ============================================================================
+
+/** A column in a filtered range. Contains an object with specific filter
+ settings for the cells in the column.
+ */
+class FilterColumn : public WorkbookHelper
+{
+public:
+ explicit FilterColumn( const WorkbookHelper& rHelper );
+
+ /** Imports auto filter column settings from the filterColumn element. */
+ void importFilterColumn( const AttributeList& rAttribs );
+ /** Imports auto filter column settings from the FILTERCOLUMN record. */
+ void importFilterColumn( SequenceInputStream& rStrm );
+ /** Imports auto filter column settings from the FILTERCOLUMN record. */
+ void importFilterColumn( BiffInputStream& rStrm );
+
+ /** Creates and returns the specified filter settings object. */
+ template< typename FilterSettingsType >
+ inline FilterSettingsBase& createFilterSettings()
+ { mxSettings.reset( new FilterSettingsType( *this ) ); return *mxSettings; }
+
+ /** Returns the index of the column in the filtered range this object is related to. */
+ inline sal_Int32 getColumnId() const { return mnColId; }
+
+ /** Returns converted UNO API filter settings representing all filter
+ settings of this column. */
+ ApiFilterSettings finalizeImport( sal_Int32 nMaxCount );
+
+private:
+ FilterSettingsRef mxSettings;
+ sal_Int32 mnColId;
+ bool mbHiddenButton;
+ bool mbShowButton;
+};
+
+// ============================================================================
+
+class AutoFilter : public WorkbookHelper
+{
+public:
+ explicit AutoFilter( const WorkbookHelper& rHelper );
+
+ /** Imports auto filter settings from the autoFilter element. */
+ void importAutoFilter( const AttributeList& rAttribs, sal_Int16 nSheet );
+ /** Imports auto filter settings from the AUTOFILTER record. */
+ void importAutoFilter( SequenceInputStream& rStrm, sal_Int16 nSheet );
+
+ /** Creates a new auto filter column and stores it internally. */
+ FilterColumn& createFilterColumn();
+
+ /** Applies the filter to the passed filter descriptor. */
+ void finalizeImport( const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSheetFilterDescriptor2 >& rxFilterDesc );
+
+private:
+ typedef RefVector< FilterColumn > FilterColumnVector;
+
+ FilterColumnVector maFilterColumns;
+ ::com::sun::star::table::CellRangeAddress maRange;
+};
+
+// ============================================================================
+
+class AutoFilterBuffer : public WorkbookHelper
+{
+public:
+ explicit AutoFilterBuffer( const WorkbookHelper& rHelper );
+
+ /** Creates a new auto filter and stores it internally. */
+ AutoFilter& createAutoFilter();
+
+ /** Applies filter settings to a new database range object (used for sheet
+ autofilter or advanced filter as specified by built-in defined names). */
+ void finalizeImport( sal_Int16 nSheet );
+
+ /** Applies the filters to the passed database range object.
+ @return True = this buffer contains valid auto filter settings. */
+ bool finalizeImport( const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDatabaseRange >& rxDatabaseRange );
+
+private:
+ /** Returns the auto filter object used to perform auto filtering. */
+ AutoFilter* getActiveAutoFilter();
+
+private:
+ typedef RefVector< AutoFilter > AutoFilterVector;
+ AutoFilterVector maAutoFilters;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/autofiltercontext.hxx b/oox/inc/oox/xls/autofiltercontext.hxx
new file mode 100644
index 000000000000..13508bbf5e63
--- /dev/null
+++ b/oox/inc/oox/xls/autofiltercontext.hxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_AUTOFILTERCONTEXT_HXX
+#define OOX_XLS_AUTOFILTERCONTEXT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+class AutoFilter;
+class FilterColumn;
+class FilterSettingsBase;
+
+// ============================================================================
+
+class FilterSettingsContext : public WorksheetContextBase
+{
+public:
+ explicit FilterSettingsContext( WorksheetContextBase& rParent, FilterSettingsBase& rFilterSettings );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ FilterSettingsBase& mrFilterSettings;
+};
+
+// ============================================================================
+
+class FilterColumnContext : public WorksheetContextBase
+{
+public:
+ explicit FilterColumnContext( WorksheetContextBase& rParent, FilterColumn& rFilterColumn );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ FilterColumn& mrFilterColumn;
+};
+
+// ============================================================================
+
+class AutoFilterContext : public WorksheetContextBase
+{
+public:
+ explicit AutoFilterContext( WorksheetFragmentBase& rFragment, AutoFilter& rAutoFilter );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ AutoFilter& mrAutoFilter;
+};
+
+// ============================================================================
+
+class BiffAutoFilterContext : public BiffWorksheetContextBase
+{
+public:
+ explicit BiffAutoFilterContext( const WorksheetHelper& rHelper, AutoFilter& rAutoFilter );
+
+protected:
+ /** Imports all records related to the current auto filter. */
+ virtual void importRecord( BiffInputStream& rStrm );
+
+private:
+ AutoFilter& mrAutoFilter;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/biffcodec.hxx b/oox/inc/oox/xls/biffcodec.hxx
new file mode 100644
index 000000000000..9b9157c7e494
--- /dev/null
+++ b/oox/inc/oox/xls/biffcodec.hxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_BIFFCODEC_HXX
+#define OOX_XLS_BIFFCODEC_HXX
+
+#include <vector>
+#include <comphelper/docpasswordhelper.hxx>
+#include "oox/core/binarycodec.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+const sal_Int64 BIFF_RCF_BLOCKSIZE = 1024;
+
+// ============================================================================
+
+/** Base class for BIFF stream decoders. */
+class BiffDecoderBase : public ::comphelper::IDocPasswordVerifier
+{
+public:
+ explicit BiffDecoderBase();
+ virtual ~BiffDecoderBase();
+
+ /** Derived classes return a clone of the decoder for usage in new streams. */
+ inline BiffDecoderBase* clone() { return implClone(); }
+
+ /** Implementation of the ::comphelper::IDocPasswordVerifier interface. */
+ virtual ::comphelper::DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData );
+ virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData );
+
+ /** Returns true, if the decoder has been initialized correctly. */
+ inline bool isValid() const { return mbValid; }
+
+ /** Decodes nBytes bytes and writes encrypted data into the buffer pnDestData. */
+ void decode(
+ sal_uInt8* pnDestData,
+ const sal_uInt8* pnSrcData,
+ sal_Int64 nStreamPos,
+ sal_uInt16 nBytes );
+
+private:
+ /** Derived classes return a clone of the decoder for usage in new streams. */
+ virtual BiffDecoderBase* implClone() = 0;
+
+ /** Derived classes implement password verification and initialization of
+ the decoder. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword ) = 0;
+ virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ) = 0;
+
+ /** Implementation of decryption of a memory block. */
+ virtual void implDecode(
+ sal_uInt8* pnDestData,
+ const sal_uInt8* pnSrcData,
+ sal_Int64 nStreamPos,
+ sal_uInt16 nBytes ) = 0;
+
+private:
+ bool mbValid; /// True = decoder is correctly initialized.
+};
+
+typedef ::boost::shared_ptr< BiffDecoderBase > BiffDecoderRef;
+
+// ============================================================================
+
+/** Decodes BIFF stream contents that are encoded using the old XOR algorithm. */
+class BiffDecoder_XOR : public BiffDecoderBase
+{
+public:
+ explicit BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash );
+
+private:
+ /** Copy constructor for cloning. */
+ BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder );
+
+ /** Returns a clone of the decoder for usage in new streams. */
+ virtual BiffDecoder_XOR* implClone();
+
+ /** Implements password verification and initialization of the decoder. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword );
+ virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData );
+
+
+ /** Implementation of decryption of a memory block. */
+ virtual void implDecode(
+ sal_uInt8* pnDestData,
+ const sal_uInt8* pnSrcData,
+ sal_Int64 nStreamPos,
+ sal_uInt16 nBytes );
+
+private:
+ ::oox::core::BinaryCodec_XOR maCodec; /// Cipher algorithm implementation.
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData;
+ sal_uInt16 mnKey;
+ sal_uInt16 mnHash;
+};
+
+// ============================================================================
+
+/** Decodes BIFF stream contents that are encoded using the RC4 algorithm. */
+class BiffDecoder_RCF : public BiffDecoderBase
+{
+public:
+ explicit BiffDecoder_RCF(
+ sal_uInt8 pnSalt[ 16 ],
+ sal_uInt8 pnVerifier[ 16 ],
+ sal_uInt8 pnVerifierHash[ 16 ] );
+
+private:
+ /** Copy constructor for cloning. */
+ BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder );
+
+ /** Returns a clone of the decoder for usage in new streams. */
+ virtual BiffDecoder_RCF* implClone();
+
+ /** Implements password verification and initialization of the decoder. */
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword );
+ virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData );
+
+ /** Implementation of decryption of a memory block. */
+ virtual void implDecode(
+ sal_uInt8* pnDestData,
+ const sal_uInt8* pnSrcData,
+ sal_Int64 nStreamPos,
+ sal_uInt16 nBytes );
+
+private:
+ ::oox::core::BinaryCodec_RCF maCodec; /// Cipher algorithm implementation.
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData;
+ ::std::vector< sal_uInt8 > maSalt;
+ ::std::vector< sal_uInt8 > maVerifier;
+ ::std::vector< sal_uInt8 > maVerifierHash;
+};
+
+// ============================================================================
+
+/** Helper for BIFF stream codecs. Holds the used codec object. */
+class BiffCodecHelper : public WorkbookHelper
+{
+public:
+ explicit BiffCodecHelper( const WorkbookHelper& rHelper );
+
+ /** Implementation helper, reads the FILEPASS and returns a decoder object. */
+ static BiffDecoderRef implReadFilePass( BiffInputStream& rStrm, BiffType eBiff );
+
+ /** Imports the FILEPASS record, asks for a password and sets a decoder at the stream. */
+ bool importFilePass( BiffInputStream& rStrm );
+ /** Clones the contained decoder object if existing and sets it at the passed stream. */
+ void cloneDecoder( BiffInputStream& rStrm );
+
+private:
+ BiffDecoderRef mxDecoder; /// The decoder for import filter.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/biffdetector.hxx b/oox/inc/oox/xls/biffdetector.hxx
new file mode 100644
index 000000000000..df372c76d7cc
--- /dev/null
+++ b/oox/inc/oox/xls/biffdetector.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_BIFFDETECTOR_HXX
+#define OOX_XLS_BIFFDETECTOR_HXX
+
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include "oox/helper/storagebase.hxx"
+#include "oox/xls/biffhelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace beans { struct PropertyValue; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace oox { class BinaryInputStream; }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Detection service for BIFF streams or storages. */
+class BiffDetector : public ::cppu::WeakImplHelper2<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::document::XExtendedFilterDetection >
+{
+public:
+ explicit BiffDetector(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ~BiffDetector();
+
+ /** Detects the BIFF version of the passed stream. */
+ static BiffType detectStreamBiffVersion( BinaryInputStream& rInStream );
+
+ /** Detects the BIFF version and workbook stream name of the passed storage. */
+ static BiffType detectStorageBiffVersion(
+ ::rtl::OUString& orWorkbookStreamName,
+ const StorageRef& rxStorage );
+
+ // com.sun.star.lang.XServiceInfo interface -------------------------------
+
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& rService )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.document.XExtendedFilterDetect interface ------------------
+
+ virtual ::rtl::OUString SAL_CALL
+ detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& orDescriptor )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
+ mxContext;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/biffhelper.hxx b/oox/inc/oox/xls/biffhelper.hxx
new file mode 100644
index 000000000000..5552a5e5ce52
--- /dev/null
+++ b/oox/inc/oox/xls/biffhelper.hxx
@@ -0,0 +1,668 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_BIFFHELPER_HXX
+#define OOX_XLS_BIFFHELPER_HXX
+
+#include "oox/helper/binarystreambase.hxx"
+
+namespace oox { class SequenceInputStream; }
+
+namespace oox {
+namespace xls {
+
+class BiffInputStream;
+
+// BIFF12 record identifiers ==================================================
+
+const sal_Int32 BIFF12_ID_ARRAY = 0x01AA;
+const sal_Int32 BIFF12_ID_AUTOFILTER = 0x00A1;
+const sal_Int32 BIFF12_ID_AUTOSORTSCOPE = 0x01CB;
+const sal_Int32 BIFF12_ID_BINARYINDEXBLOCK = 0x002A;
+const sal_Int32 BIFF12_ID_BINARYINDEXROWS = 0x0028;
+const sal_Int32 BIFF12_ID_BOOKVIEWS = 0x0087;
+const sal_Int32 BIFF12_ID_BORDER = 0x002E;
+const sal_Int32 BIFF12_ID_BORDERS = 0x0265;
+const sal_Int32 BIFF12_ID_BRK = 0x018C;
+const sal_Int32 BIFF12_ID_CALCPR = 0x009D;
+const sal_Int32 BIFF12_ID_CELL_BLANK = 0x0001;
+const sal_Int32 BIFF12_ID_CELL_BOOL = 0x0004;
+const sal_Int32 BIFF12_ID_CELL_DOUBLE = 0x0005;
+const sal_Int32 BIFF12_ID_CELL_ERROR = 0x0003;
+const sal_Int32 BIFF12_ID_CELL_RK = 0x0002;
+const sal_Int32 BIFF12_ID_CELL_RSTRING = 0x003E;
+const sal_Int32 BIFF12_ID_CELL_SI = 0x0007;
+const sal_Int32 BIFF12_ID_CELL_STRING = 0x0006;
+const sal_Int32 BIFF12_ID_CELLSTYLE = 0x0030;
+const sal_Int32 BIFF12_ID_CELLSTYLES = 0x026B;
+const sal_Int32 BIFF12_ID_CELLSTYLEXFS = 0x0272;
+const sal_Int32 BIFF12_ID_CELLXFS = 0x0269;
+const sal_Int32 BIFF12_ID_CFCOLOR = 0x0234;
+const sal_Int32 BIFF12_ID_CFRULE = 0x01CF;
+const sal_Int32 BIFF12_ID_CHARTPAGESETUP = 0x028C;
+const sal_Int32 BIFF12_ID_CHARTPROTECTION = 0x029D;
+const sal_Int32 BIFF12_ID_CHARTSHEETPR = 0x028B;
+const sal_Int32 BIFF12_ID_CHARTSHEETVIEW = 0x008D;
+const sal_Int32 BIFF12_ID_CHARTSHEETVIEWS = 0x008B;
+const sal_Int32 BIFF12_ID_COL = 0x003C;
+const sal_Int32 BIFF12_ID_COLBREAKS = 0x018A;
+const sal_Int32 BIFF12_ID_COLOR = 0x023C;
+const sal_Int32 BIFF12_ID_COLORS = 0x01D9;
+const sal_Int32 BIFF12_ID_COLORSCALE = 0x01D5;
+const sal_Int32 BIFF12_ID_COLS = 0x0186;
+const sal_Int32 BIFF12_ID_COMMENT = 0x027B;
+const sal_Int32 BIFF12_ID_COMMENTAUTHOR = 0x0278;
+const sal_Int32 BIFF12_ID_COMMENTAUTHORS = 0x0276;
+const sal_Int32 BIFF12_ID_COMMENTLIST = 0x0279;
+const sal_Int32 BIFF12_ID_COMMENTS = 0x0274;
+const sal_Int32 BIFF12_ID_COMMENTTEXT = 0x027D;
+const sal_Int32 BIFF12_ID_CONDFORMATTING = 0x01CD;
+const sal_Int32 BIFF12_ID_CONNECTION = 0x00C9;
+const sal_Int32 BIFF12_ID_CONNECTIONS = 0x01AD;
+const sal_Int32 BIFF12_ID_CONTROL = 0x0284;
+const sal_Int32 BIFF12_ID_CONTROLS = 0x0283;
+const sal_Int32 BIFF12_ID_CUSTOMCHARTVIEW = 0x028F;
+const sal_Int32 BIFF12_ID_CUSTOMCHARTVIEWS = 0x028D;
+const sal_Int32 BIFF12_ID_CUSTOMFILTER = 0x00AE;
+const sal_Int32 BIFF12_ID_CUSTOMFILTERS = 0x00AC;
+const sal_Int32 BIFF12_ID_CUSTOMSHEETVIEW = 0x01A7;
+const sal_Int32 BIFF12_ID_CUSTOMSHEETVIEWS = 0x01A6;
+const sal_Int32 BIFF12_ID_CUSTOMWORKBOOKVIEW= 0x018D;
+const sal_Int32 BIFF12_ID_DATABAR = 0x01D3;
+const sal_Int32 BIFF12_ID_DATATABLE = 0x01AC;
+const sal_Int32 BIFF12_ID_DATAVALIDATION = 0x0040;
+const sal_Int32 BIFF12_ID_DATAVALIDATIONS = 0x023D;
+const sal_Int32 BIFF12_ID_DDEITEMVALUES = 0x0242;
+const sal_Int32 BIFF12_ID_DDEITEM_BOOL = 0x0248;
+const sal_Int32 BIFF12_ID_DDEITEM_DOUBLE = 0x0244;
+const sal_Int32 BIFF12_ID_DDEITEM_ERROR = 0x0245;
+const sal_Int32 BIFF12_ID_DDEITEM_STRING = 0x0246;
+const sal_Int32 BIFF12_ID_DEFINEDNAME = 0x0027;
+const sal_Int32 BIFF12_ID_DIMENSION = 0x0094;
+const sal_Int32 BIFF12_ID_DISCRETEFILTER = 0x00A7;
+const sal_Int32 BIFF12_ID_DISCRETEFILTERS = 0x00A5;
+const sal_Int32 BIFF12_ID_DRAWING = 0x0226;
+const sal_Int32 BIFF12_ID_DXF = 0x01FB;
+const sal_Int32 BIFF12_ID_DXFS = 0x01F9;
+const sal_Int32 BIFF12_ID_EXTCELL_BLANK = 0x016F;
+const sal_Int32 BIFF12_ID_EXTCELL_BOOL = 0x0171;
+const sal_Int32 BIFF12_ID_EXTCELL_DOUBLE = 0x0170;
+const sal_Int32 BIFF12_ID_EXTCELL_ERROR = 0x0172;
+const sal_Int32 BIFF12_ID_EXTCELL_STRING = 0x0173;
+const sal_Int32 BIFF12_ID_EXTERNALADDIN = 0x029B;
+const sal_Int32 BIFF12_ID_EXTERNALBOOK = 0x0168;
+const sal_Int32 BIFF12_ID_EXTERNALNAME = 0x0241;
+const sal_Int32 BIFF12_ID_EXTERNALREF = 0x0163;
+const sal_Int32 BIFF12_ID_EXTERNALREFS = 0x0161;
+const sal_Int32 BIFF12_ID_EXTERNALSELF = 0x0165;
+const sal_Int32 BIFF12_ID_EXTERNALSAME = 0x0166;
+const sal_Int32 BIFF12_ID_EXTERNALSHEETS = 0x016A;
+const sal_Int32 BIFF12_ID_EXTROW = 0x016E;
+const sal_Int32 BIFF12_ID_EXTSHEETDATA = 0x016B;
+const sal_Int32 BIFF12_ID_EXTERNALNAMEFLAGS = 0x024A;
+const sal_Int32 BIFF12_ID_EXTSHEETNAMES = 0x0167;
+const sal_Int32 BIFF12_ID_FILESHARING = 0x0224;
+const sal_Int32 BIFF12_ID_FILEVERSION = 0x0080;
+const sal_Int32 BIFF12_ID_FILL = 0x002D;
+const sal_Int32 BIFF12_ID_FILLS = 0x025B;
+const sal_Int32 BIFF12_ID_FILTERCOLUMN = 0x00A3;
+const sal_Int32 BIFF12_ID_FONT = 0x002B;
+const sal_Int32 BIFF12_ID_FONTS = 0x0263;
+const sal_Int32 BIFF12_ID_FORMULA_STRING = 0x0008;
+const sal_Int32 BIFF12_ID_FORMULA_DOUBLE = 0x0009;
+const sal_Int32 BIFF12_ID_FORMULA_BOOL = 0x000A;
+const sal_Int32 BIFF12_ID_FORMULA_ERROR = 0x000B;
+const sal_Int32 BIFF12_ID_FUNCTIONGROUP = 0x0299;
+const sal_Int32 BIFF12_ID_FUNCTIONGROUPS = 0x0298;
+const sal_Int32 BIFF12_ID_HEADERFOOTER = 0x01DF;
+const sal_Int32 BIFF12_ID_HYPERLINK = 0x01EE;
+const sal_Int32 BIFF12_ID_ICONSET = 0x01D1;
+const sal_Int32 BIFF12_ID_INDEXEDCOLORS = 0x0235;
+const sal_Int32 BIFF12_ID_INPUTCELLS = 0x01F8;
+const sal_Int32 BIFF12_ID_LEGACYDRAWING = 0x0227;
+const sal_Int32 BIFF12_ID_MERGECELL = 0x00B0;
+const sal_Int32 BIFF12_ID_MERGECELLS = 0x00B1;
+const sal_Int32 BIFF12_ID_MRUCOLORS = 0x0239;
+const sal_Int32 BIFF12_ID_MULTCELL_BLANK = 0x000C;
+const sal_Int32 BIFF12_ID_MULTCELL_BOOL = 0x000F;
+const sal_Int32 BIFF12_ID_MULTCELL_DOUBLE = 0x0010;
+const sal_Int32 BIFF12_ID_MULTCELL_ERROR = 0x000E;
+const sal_Int32 BIFF12_ID_MULTCELL_RK = 0x000D;
+const sal_Int32 BIFF12_ID_MULTCELL_RSTRING = 0x003D;
+const sal_Int32 BIFF12_ID_MULTCELL_SI = 0x0012;
+const sal_Int32 BIFF12_ID_MULTCELL_STRING = 0x0011;
+const sal_Int32 BIFF12_ID_NUMFMT = 0x002C;
+const sal_Int32 BIFF12_ID_NUMFMTS = 0x0267;
+const sal_Int32 BIFF12_ID_OLEOBJECT = 0x027F;
+const sal_Int32 BIFF12_ID_OLEOBJECTS = 0x027E;
+const sal_Int32 BIFF12_ID_OLESIZE = 0x0225;
+const sal_Int32 BIFF12_ID_PAGEMARGINS = 0x01DC;
+const sal_Int32 BIFF12_ID_PAGESETUP = 0x01DE;
+const sal_Int32 BIFF12_ID_PANE = 0x0097;
+const sal_Int32 BIFF12_ID_PCDEFINITION = 0x00B3;
+const sal_Int32 BIFF12_ID_PCDFDISCRETEPR = 0x00E1;
+const sal_Int32 BIFF12_ID_PCDFGROUPITEMS = 0x00DD;
+const sal_Int32 BIFF12_ID_PCDFIELD = 0x00B7;
+const sal_Int32 BIFF12_ID_PCDFIELDGROUP = 0x00DB;
+const sal_Int32 BIFF12_ID_PCDFIELDS = 0x00B5;
+const sal_Int32 BIFF12_ID_PCDFRANGEPR = 0x00DF;
+const sal_Int32 BIFF12_ID_PCDFSHAREDITEMS = 0x00BD;
+const sal_Int32 BIFF12_ID_PCDSHEETSOURCE = 0x00BB;
+const sal_Int32 BIFF12_ID_PCDSOURCE = 0x00B9;
+const sal_Int32 BIFF12_ID_PCITEM_ARRAY = 0x00BF;
+const sal_Int32 BIFF12_ID_PCITEM_BOOL = 0x0016;
+const sal_Int32 BIFF12_ID_PCITEM_DATE = 0x0019;
+const sal_Int32 BIFF12_ID_PCITEM_DOUBLE = 0x0015;
+const sal_Int32 BIFF12_ID_PCITEM_ERROR = 0x0017;
+const sal_Int32 BIFF12_ID_PCITEM_INDEX = 0x001A;
+const sal_Int32 BIFF12_ID_PCITEM_MISSING = 0x0014;
+const sal_Int32 BIFF12_ID_PCITEM_STRING = 0x0018;
+const sal_Int32 BIFF12_ID_PCITEMA_BOOL = 0x001D;
+const sal_Int32 BIFF12_ID_PCITEMA_DATE = 0x0020;
+const sal_Int32 BIFF12_ID_PCITEMA_DOUBLE = 0x001C;
+const sal_Int32 BIFF12_ID_PCITEMA_ERROR = 0x001E;
+const sal_Int32 BIFF12_ID_PCITEMA_MISSING = 0x001B;
+const sal_Int32 BIFF12_ID_PCITEMA_STRING = 0x001F;
+const sal_Int32 BIFF12_ID_PCRECORD = 0x0021;
+const sal_Int32 BIFF12_ID_PCRECORDDT = 0x0022;
+const sal_Int32 BIFF12_ID_PCRECORDS = 0x00C1;
+const sal_Int32 BIFF12_ID_PHONETICPR = 0x0219;
+const sal_Int32 BIFF12_ID_PICTURE = 0x0232;
+const sal_Int32 BIFF12_ID_PIVOTAREA = 0x00F7;
+const sal_Int32 BIFF12_ID_PIVOTCACHE = 0x0182;
+const sal_Int32 BIFF12_ID_PIVOTCACHES = 0x0180;
+const sal_Int32 BIFF12_ID_PRINTOPTIONS = 0x01DD;
+const sal_Int32 BIFF12_ID_PTCOLFIELDS = 0x0137;
+const sal_Int32 BIFF12_ID_PTDATAFIELD = 0x0125;
+const sal_Int32 BIFF12_ID_PTDATAFIELDS = 0x0127;
+const sal_Int32 BIFF12_ID_PTDEFINITION = 0x0118;
+const sal_Int32 BIFF12_ID_PTFIELD = 0x011D;
+const sal_Int32 BIFF12_ID_PTFIELDS = 0x011F;
+const sal_Int32 BIFF12_ID_PTFILTER = 0x0259;
+const sal_Int32 BIFF12_ID_PTFILTERS = 0x0257;
+const sal_Int32 BIFF12_ID_PTFITEM = 0x011A;
+const sal_Int32 BIFF12_ID_PTFITEMS = 0x011B;
+const sal_Int32 BIFF12_ID_PTLOCATION = 0x013A;
+const sal_Int32 BIFF12_ID_PTPAGEFIELD = 0x0121;
+const sal_Int32 BIFF12_ID_PTPAGEFIELDS = 0x0123;
+const sal_Int32 BIFF12_ID_PTREFERENCE = 0x00FB;
+const sal_Int32 BIFF12_ID_PTREFERENCEITEM = 0x017E;
+const sal_Int32 BIFF12_ID_PTREFERENCES = 0x00F9;
+const sal_Int32 BIFF12_ID_PTROWFIELDS = 0x0135;
+const sal_Int32 BIFF12_ID_QUERYTABLE = 0x01BF;
+const sal_Int32 BIFF12_ID_QUERYTABLEREFRESH = 0x01C1;
+const sal_Int32 BIFF12_ID_RGBCOLOR = 0x01DB;
+const sal_Int32 BIFF12_ID_ROW = 0x0000;
+const sal_Int32 BIFF12_ID_ROWBREAKS = 0x0188;
+const sal_Int32 BIFF12_ID_SCENARIO = 0x01F6;
+const sal_Int32 BIFF12_ID_SCENARIOS = 0x01F4;
+const sal_Int32 BIFF12_ID_SELECTION = 0x0098;
+const sal_Int32 BIFF12_ID_SHAREDFMLA = 0x01AB;
+const sal_Int32 BIFF12_ID_SHEET = 0x009C;
+const sal_Int32 BIFF12_ID_SHEETDATA = 0x0091;
+const sal_Int32 BIFF12_ID_SHEETFORMATPR = 0x01E5;
+const sal_Int32 BIFF12_ID_SHEETPR = 0x0093;
+const sal_Int32 BIFF12_ID_SHEETPROTECTION = 0x0217;
+const sal_Int32 BIFF12_ID_SHEETS = 0x008F;
+const sal_Int32 BIFF12_ID_SHEETVIEW = 0x0089;
+const sal_Int32 BIFF12_ID_SHEETVIEWS = 0x0085;
+const sal_Int32 BIFF12_ID_SI = 0x0013;
+const sal_Int32 BIFF12_ID_SST = 0x009F;
+const sal_Int32 BIFF12_ID_STYLESHEET = 0x0116;
+const sal_Int32 BIFF12_ID_TABLE = 0x0157;
+const sal_Int32 BIFF12_ID_TABLEPART = 0x0295;
+const sal_Int32 BIFF12_ID_TABLEPARTS = 0x0294;
+const sal_Int32 BIFF12_ID_TABLESTYLEINFO = 0x0201;
+const sal_Int32 BIFF12_ID_TABLESTYLES = 0x01FC;
+const sal_Int32 BIFF12_ID_TOP10FILTER = 0x00AA;
+const sal_Int32 BIFF12_ID_VOLTYPE = 0x0204;
+const sal_Int32 BIFF12_ID_VOLTYPEMAIN = 0x0206;
+const sal_Int32 BIFF12_ID_VOLTYPES = 0x0202;
+const sal_Int32 BIFF12_ID_VOLTYPESTP = 0x020A;
+const sal_Int32 BIFF12_ID_VOLTYPETR = 0x020B;
+const sal_Int32 BIFF12_ID_WEBPR = 0x0105;
+const sal_Int32 BIFF12_ID_WEBPRTABLES = 0x0107;
+const sal_Int32 BIFF12_ID_WORKBOOK = 0x0083;
+const sal_Int32 BIFF12_ID_WORKBOOKPR = 0x0099;
+const sal_Int32 BIFF12_ID_WORKBOOKVIEW = 0x009E;
+const sal_Int32 BIFF12_ID_WORKSHEET = 0x0081;
+const sal_Int32 BIFF12_ID_XF = 0x002F;
+
+// BIFF2-BIFF8 record identifiers =============================================
+
+/** An enumeration for all binary Excel file format types (BIFF types). */
+enum BiffType
+{
+ BIFF2 = 0, /// MS Excel 2.1.
+ BIFF3, /// MS Excel 3.0.
+ BIFF4, /// MS Excel 4.0.
+ BIFF5, /// MS Excel 5.0, MS Excel 7.0 (95).
+ BIFF8, /// MS Excel 8.0 (97), 9.0 (2000), 10.0 (XP), 11.0 (2003).
+ BIFF_UNKNOWN /// Unknown BIFF version.
+};
+
+const sal_uInt16 BIFF2_MAXRECSIZE = 2080;
+const sal_uInt16 BIFF8_MAXRECSIZE = 8224;
+
+// record identifiers ---------------------------------------------------------
+
+const sal_uInt16 BIFF2_ID_ARRAY = 0x0021;
+const sal_uInt16 BIFF3_ID_ARRAY = 0x0221;
+const sal_uInt16 BIFF_ID_AUTOFILTER = 0x009D;
+const sal_uInt16 BIFF2_ID_BLANK = 0x0001;
+const sal_uInt16 BIFF3_ID_BLANK = 0x0201;
+const sal_uInt16 BIFF2_ID_BOF = 0x0009;
+const sal_uInt16 BIFF3_ID_BOF = 0x0209;
+const sal_uInt16 BIFF4_ID_BOF = 0x0409;
+const sal_uInt16 BIFF5_ID_BOF = 0x0809;
+const sal_uInt16 BIFF_ID_BOOKBOOL = 0x00DA;
+const sal_uInt16 BIFF_ID_BOOKEXT = 0x0863;
+const sal_uInt16 BIFF2_ID_BOOLERR = 0x0005;
+const sal_uInt16 BIFF3_ID_BOOLERR = 0x0205;
+const sal_uInt16 BIFF_ID_BOTTOMMARGIN = 0x0029;
+const sal_uInt16 BIFF_ID_CALCCOUNT = 0x000C;
+const sal_uInt16 BIFF_ID_CALCMODE = 0x000D;
+const sal_uInt16 BIFF_ID_CFHEADER = 0x01B0;
+const sal_uInt16 BIFF_ID_CFRULE = 0x01B1;
+const sal_uInt16 BIFF_ID_CFRULE12 = 0x087A;
+const sal_uInt16 BIFF_ID_CFRULEEXT = 0x087B;
+const sal_uInt16 BIFF_ID_CH3DDATAFORMAT = 0x105F;
+const sal_uInt16 BIFF_ID_CHAREA = 0x101A;
+const sal_uInt16 BIFF_ID_CHAREAFORMAT = 0x100A;
+const sal_uInt16 BIFF_ID_CHATTACHEDLABEL = 0x100C;
+const sal_uInt16 BIFF_ID_CHAXESSET = 0x1041;
+const sal_uInt16 BIFF_ID_CHAXIS = 0x101D;
+const sal_uInt16 BIFF_ID_CHAXISLINE = 0x1021;
+const sal_uInt16 BIFF_ID_CHBAR = 0x1017;
+const sal_uInt16 BIFF_ID_CHBEGIN = 0x1033;
+const sal_uInt16 BIFF_ID_CHCHART = 0x1002;
+const sal_uInt16 BIFF_ID_CHCHART3D = 0x103A;
+const sal_uInt16 BIFF_ID_CHCHARTLINE = 0x101C;
+const sal_uInt16 BIFF_ID_CHDATAFORMAT = 0x1006;
+const sal_uInt16 BIFF_ID_CHDATERANGE = 0x1062;
+const sal_uInt16 BIFF_ID_CHDEFAULTTEXT = 0x1024;
+const sal_uInt16 BIFF_ID_CHDROPBAR = 0x103D;
+const sal_uInt16 BIFF_ID_CHECKCOMPAT = 0x088C;
+const sal_uInt16 BIFF_ID_CHEND = 0x1034;
+const sal_uInt16 BIFF_ID_CHESCHERFORMAT = 0x1066;
+const sal_uInt16 BIFF_ID_CHFONT = 0x1026;
+const sal_uInt16 BIFF_ID_CHFORMAT = 0x104E;
+const sal_uInt16 BIFF_ID_CHFORMATRUNS = 0x1050;
+const sal_uInt16 BIFF_ID_CHFRAME = 0x1032;
+const sal_uInt16 BIFF_ID_CHFRAMEPOS = 0x104F;
+const sal_uInt16 BIFF_ID_CHFRBLOCKBEGIN = 0x0852;
+const sal_uInt16 BIFF_ID_CHFRBLOCKEND = 0x0853;
+const sal_uInt16 BIFF_ID_CHFRCATEGORYPROPS = 0x0856;
+const sal_uInt16 BIFF_ID_CHFREXTPROPS = 0x089E;
+const sal_uInt16 BIFF_ID_CHFREXTPROPSCONT = 0x089F;
+const sal_uInt16 BIFF_ID_CHFRINFO = 0x0850;
+const sal_uInt16 BIFF_ID_CHFRLABELPROPS = 0x086B;
+const sal_uInt16 BIFF_ID_CHFRLAYOUT = 0x089D;
+const sal_uInt16 BIFF_ID_CHFRPLOTAREALAYOUT = 0x08A7;
+const sal_uInt16 BIFF_ID_CHFRSHAPEPROPS = 0x08A4;
+const sal_uInt16 BIFF_ID_CHFRTEXTPROPS = 0x08A5;
+const sal_uInt16 BIFF_ID_CHFRUNITPROPS = 0x0857;
+const sal_uInt16 BIFF_ID_CHFRWRAPPER = 0x0851;
+const sal_uInt16 BIFF_ID_CHLABELRANGE = 0x1020;
+const sal_uInt16 BIFF_ID_CHLEGEND = 0x1015;
+const sal_uInt16 BIFF_ID_CHLINE = 0x1018;
+const sal_uInt16 BIFF_ID_CHLINEFORMAT = 0x1007;
+const sal_uInt16 BIFF_ID_CHMARKERFORMAT = 0x1009;
+const sal_uInt16 BIFF_ID_CHOBJECTLINK = 0x1027;
+const sal_uInt16 BIFF_ID_CHPICFORMAT = 0x103C;
+const sal_uInt16 BIFF_ID_CHPIE = 0x1019;
+const sal_uInt16 BIFF_ID_CHPIEEXT = 0x1061;
+const sal_uInt16 BIFF_ID_CHPIEFORMAT = 0x100B;
+const sal_uInt16 BIFF_ID_CHPIVOTFLAGS = 0x0859;
+const sal_uInt16 BIFF5_ID_CHPIVOTREF = 0x1048;
+const sal_uInt16 BIFF8_ID_CHPIVOTREF = 0x0858;
+const sal_uInt16 BIFF_ID_CHPLOTFRAME = 0x1035;
+const sal_uInt16 BIFF_ID_CHPLOTGROWTH = 0x1064;
+const sal_uInt16 BIFF_ID_CHPROPERTIES = 0x1044;
+const sal_uInt16 BIFF_ID_CHRADARLINE = 0x103E;
+const sal_uInt16 BIFF_ID_CHRADARAREA = 0x1040;
+const sal_uInt16 BIFF_ID_CHSCATTER = 0x101B;
+const sal_uInt16 BIFF_ID_CHSERERRORBAR = 0x105B;
+const sal_uInt16 BIFF_ID_CHSERGROUP = 0x1045;
+const sal_uInt16 BIFF_ID_CHSERIES = 0x1003;
+const sal_uInt16 BIFF_ID_CHSERIESFORMAT = 0x105D;
+const sal_uInt16 BIFF_ID_CHSERPARENT = 0x104A;
+const sal_uInt16 BIFF_ID_CHSERTRENDLINE = 0x104B;
+const sal_uInt16 BIFF_ID_CHSOURCELINK = 0x1051;
+const sal_uInt16 BIFF_ID_CHSTRING = 0x100D;
+const sal_uInt16 BIFF_ID_CHSURFACE = 0x103F;
+const sal_uInt16 BIFF_ID_CHTEXT = 0x1025;
+const sal_uInt16 BIFF_ID_CHTICK = 0x101E;
+const sal_uInt16 BIFF_ID_CHTYPEGROUP = 0x1014;
+const sal_uInt16 BIFF_ID_CHVALUERANGE = 0x101F;
+const sal_uInt16 BIFF_ID_CODENAME = 0x01BA;
+const sal_uInt16 BIFF_ID_CODEPAGE = 0x0042;
+const sal_uInt16 BIFF_ID_COLINFO = 0x007D;
+const sal_uInt16 BIFF_ID_COLUMNDEFAULT = 0x0020;
+const sal_uInt16 BIFF_ID_COLWIDTH = 0x0024;
+const sal_uInt16 BIFF_ID_COMPRESSPICS = 0x089B;
+const sal_uInt16 BIFF_ID_CONNECTION = 0x0876;
+const sal_uInt16 BIFF_ID_CONT = 0x003C;
+const sal_uInt16 BIFF_ID_COORDLIST = 0x00A9;
+const sal_uInt16 BIFF_ID_COUNTRY = 0x008C;
+const sal_uInt16 BIFF_ID_CRN = 0x005A;
+const sal_uInt16 BIFF2_ID_DATATABLE = 0x0036;
+const sal_uInt16 BIFF3_ID_DATATABLE = 0x0236;
+const sal_uInt16 BIFF2_ID_DATATABLE2 = 0x0037;
+const sal_uInt16 BIFF_ID_DATAVALIDATION = 0x01BE;
+const sal_uInt16 BIFF_ID_DATAVALIDATIONS = 0x01B2;
+const sal_uInt16 BIFF_ID_DATEMODE = 0x0022;
+const sal_uInt16 BIFF_ID_DBCELL = 0x00D7;
+const sal_uInt16 BIFF_ID_DBQUERY = 0x00DC;
+const sal_uInt16 BIFF_ID_DCONBINAME = 0x01B5;
+const sal_uInt16 BIFF_ID_DCONNAME = 0x0052;
+const sal_uInt16 BIFF_ID_DCONREF = 0x0051;
+const sal_uInt16 BIFF_ID_DEFCOLWIDTH = 0x0055;
+const sal_uInt16 BIFF2_ID_DEFINEDNAME = 0x0018;
+const sal_uInt16 BIFF3_ID_DEFINEDNAME = 0x0218;
+const sal_uInt16 BIFF5_ID_DEFINEDNAME = 0x0018;
+const sal_uInt16 BIFF2_ID_DEFROWHEIGHT = 0x0025;
+const sal_uInt16 BIFF3_ID_DEFROWHEIGHT = 0x0225;
+const sal_uInt16 BIFF_ID_DELTA = 0x0010;
+const sal_uInt16 BIFF2_ID_DIMENSION = 0x0000;
+const sal_uInt16 BIFF3_ID_DIMENSION = 0x0200;
+const sal_uInt16 BIFF_ID_DXF = 0x088D;
+const sal_uInt16 BIFF_ID_EOF = 0x000A;
+const sal_uInt16 BIFF_ID_EXTERNALBOOK = 0x01AE;
+const sal_uInt16 BIFF2_ID_EXTERNALNAME = 0x0023;
+const sal_uInt16 BIFF3_ID_EXTERNALNAME = 0x0223;
+const sal_uInt16 BIFF5_ID_EXTERNALNAME = 0x0023;
+const sal_uInt16 BIFF_ID_EXTERNSHEET = 0x0017;
+const sal_uInt16 BIFF_ID_EXTSST = 0x00FF;
+const sal_uInt16 BIFF_ID_FILEPASS = 0x002F;
+const sal_uInt16 BIFF_ID_FILESHARING = 0x005B;
+const sal_uInt16 BIFF_ID_FILTERCOLUMN = 0x009E;
+const sal_uInt16 BIFF_ID_FILTERMODE = 0x009B;
+const sal_uInt16 BIFF2_ID_FONT = 0x0031;
+const sal_uInt16 BIFF3_ID_FONT = 0x0231;
+const sal_uInt16 BIFF5_ID_FONT = 0x0031;
+const sal_uInt16 BIFF_ID_FONTCOLOR = 0x0045;
+const sal_uInt16 BIFF_ID_FOOTER = 0x0015;
+const sal_uInt16 BIFF_ID_FORCEFULLCALC = 0x08A3;
+const sal_uInt16 BIFF2_ID_FORMAT = 0x001E;
+const sal_uInt16 BIFF4_ID_FORMAT = 0x041E;
+const sal_uInt16 BIFF2_ID_FORMULA = 0x0006;
+const sal_uInt16 BIFF3_ID_FORMULA = 0x0206;
+const sal_uInt16 BIFF4_ID_FORMULA = 0x0406;
+const sal_uInt16 BIFF5_ID_FORMULA = 0x0006;
+const sal_uInt16 BIFF_ID_GUTS = 0x0080;
+const sal_uInt16 BIFF_ID_HCENTER = 0x0083;
+const sal_uInt16 BIFF_ID_HEADER = 0x0014;
+const sal_uInt16 BIFF_ID_HEADERFOOTER = 0x089C;
+const sal_uInt16 BIFF_ID_HIDEOBJ = 0x008D;
+const sal_uInt16 BIFF_ID_HORPAGEBREAKS = 0x001B;
+const sal_uInt16 BIFF_ID_HYPERLINK = 0x01B8;
+const sal_uInt16 BIFF3_ID_IMGDATA = 0x007F;
+const sal_uInt16 BIFF8_ID_IMGDATA = 0x00E9;
+const sal_uInt16 BIFF2_ID_INDEX = 0x000B;
+const sal_uInt16 BIFF3_ID_INDEX = 0x020B;
+const sal_uInt16 BIFF2_ID_INTEGER = 0x0002;
+const sal_uInt16 BIFF_ID_INTERFACEHDR = 0x00E1;
+const sal_uInt16 BIFF_ID_ITERATION = 0x0011;
+const sal_uInt16 BIFF_ID_IXFE = 0x0044;
+const sal_uInt16 BIFF2_ID_LABEL = 0x0004;
+const sal_uInt16 BIFF3_ID_LABEL = 0x0204;
+const sal_uInt16 BIFF_ID_LABELRANGES = 0x015F;
+const sal_uInt16 BIFF_ID_LABELSST = 0x00FD;
+const sal_uInt16 BIFF_ID_LEFTMARGIN = 0x0026;
+const sal_uInt16 BIFF_ID_MERGEDCELLS = 0x00E5;
+const sal_uInt16 BIFF_ID_MSODRAWING = 0x00EC;
+const sal_uInt16 BIFF_ID_MSODRAWINGGROUP = 0x00EB;
+const sal_uInt16 BIFF_ID_MSODRAWINGSEL = 0x00ED;
+const sal_uInt16 BIFF_ID_MTHREADSETTINGS = 0x089A;
+const sal_uInt16 BIFF_ID_MULTBLANK = 0x00BE;
+const sal_uInt16 BIFF_ID_MULTRK = 0x00BD;
+const sal_uInt16 BIFF_ID_NOTE = 0x001C;
+const sal_uInt16 BIFF2_ID_NUMBER = 0x0003;
+const sal_uInt16 BIFF3_ID_NUMBER = 0x0203;
+const sal_uInt16 BIFF_ID_OBJ = 0x005D;
+const sal_uInt16 BIFF_ID_OBJECTPROTECT = 0x0063;
+const sal_uInt16 BIFF_ID_OLESIZE = 0x00DE;
+const sal_uInt16 BIFF_ID_PAGELAYOUTVIEW = 0x088B;
+const sal_uInt16 BIFF_ID_PAGESETUP = 0x00A1;
+const sal_uInt16 BIFF_ID_PALETTE = 0x0092;
+const sal_uInt16 BIFF_ID_PANE = 0x0041;
+const sal_uInt16 BIFF_ID_PARAMQUERY = 0x00DC;
+const sal_uInt16 BIFF_ID_PASSWORD = 0x0013;
+const sal_uInt16 BIFF_ID_PCDEFINITION = 0x00C6;
+const sal_uInt16 BIFF_ID_PCDEFINITION2 = 0x0122;
+const sal_uInt16 BIFF_ID_PCDFDISCRETEPR = 0x00D9;
+const sal_uInt16 BIFF_ID_PCDFIELD = 0x00C7;
+const sal_uInt16 BIFF_ID_PCDFIELDINDEX = 0x0103;
+const sal_uInt16 BIFF_ID_PCDFORMULAFIELD = 0x00F9;
+const sal_uInt16 BIFF_ID_PCDFRANGEPR = 0x00D8;
+const sal_uInt16 BIFF_ID_PCDFSQLTYPE = 0x01BB;
+const sal_uInt16 BIFF_ID_PCDSOURCE = 0x00E3;
+const sal_uInt16 BIFF_ID_PCITEM_BOOL = 0x00CA;
+const sal_uInt16 BIFF_ID_PCITEM_DATE = 0x00CE;
+const sal_uInt16 BIFF_ID_PCITEM_DOUBLE = 0x00C9;
+const sal_uInt16 BIFF_ID_PCITEM_ERROR = 0x00CB;
+const sal_uInt16 BIFF_ID_PCITEM_INDEXLIST = 0x00C8;
+const sal_uInt16 BIFF_ID_PCITEM_INTEGER = 0x00CC;
+const sal_uInt16 BIFF_ID_PCITEM_MISSING = 0x00CF;
+const sal_uInt16 BIFF_ID_PCITEM_STRING = 0x00CD;
+const sal_uInt16 BIFF_ID_PHONETICPR = 0x00EF;
+const sal_uInt16 BIFF_ID_PICTURE = 0x00E9;
+const sal_uInt16 BIFF_ID_PIVOTCACHE = 0x00D5;
+const sal_uInt16 BIFF_ID_PRECISION = 0x000E;
+const sal_uInt16 BIFF_ID_PRINTGRIDLINES = 0x002B;
+const sal_uInt16 BIFF_ID_PRINTHEADERS = 0x002A;
+const sal_uInt16 BIFF_ID_PROJEXTSHEET = 0x00A3;
+const sal_uInt16 BIFF_ID_PROTECT = 0x0012;
+const sal_uInt16 BIFF_ID_PTDATAFIELD = 0x00C5;
+const sal_uInt16 BIFF_ID_PTDEFINITION = 0x00B0;
+const sal_uInt16 BIFF_ID_PTDEFINITION2 = 0x00F1;
+const sal_uInt16 BIFF_ID_PTFIELD = 0x00B1;
+const sal_uInt16 BIFF_ID_PTFIELD2 = 0x0100;
+const sal_uInt16 BIFF_ID_PTFITEM = 0x00B2;
+const sal_uInt16 BIFF_ID_PTPAGEFIELDS = 0x00B6;
+const sal_uInt16 BIFF_ID_PTROWCOLFIELDS = 0x00B4;
+const sal_uInt16 BIFF_ID_PTROWCOLITEMS = 0x00B5;
+const sal_uInt16 BIFF_ID_QUERYTABLE = 0x01AD;
+const sal_uInt16 BIFF_ID_QUERYTABLEREFRESH = 0x0802;
+const sal_uInt16 BIFF_ID_QUERYTABLESETTINGS = 0x0803;
+const sal_uInt16 BIFF_ID_QUERYTABLESTRING = 0x0804;
+const sal_uInt16 BIFF_ID_RECALCID = 0x01C1;
+const sal_uInt16 BIFF_ID_REFMODE = 0x000F;
+const sal_uInt16 BIFF_ID_RIGHTMARGIN = 0x0027;
+const sal_uInt16 BIFF_ID_RK = 0x027E;
+const sal_uInt16 BIFF2_ID_ROW = 0x0008;
+const sal_uInt16 BIFF3_ID_ROW = 0x0208;
+const sal_uInt16 BIFF_ID_RSTRING = 0x00D6;
+const sal_uInt16 BIFF_ID_SAVERECALC = 0x005F;
+const sal_uInt16 BIFF_ID_SCENARIO = 0x00AF;
+const sal_uInt16 BIFF_ID_SCENARIOS = 0x00AE;
+const sal_uInt16 BIFF_ID_SCL = 0x00A0;
+const sal_uInt16 BIFF_ID_SCENPROTECT = 0x00DD;
+const sal_uInt16 BIFF_ID_SCREENTIP = 0x0800;
+const sal_uInt16 BIFF_ID_SELECTION = 0x001D;
+const sal_uInt16 BIFF_ID_SHAREDFEATHEAD = 0x0867;
+const sal_uInt16 BIFF_ID_SHAREDFMLA = 0x04BC;
+const sal_uInt16 BIFF_ID_SHEET = 0x0085;
+const sal_uInt16 BIFF_ID_SHEETEXT = 0x0862;
+const sal_uInt16 BIFF_ID_SHEETHEADER = 0x008F;
+const sal_uInt16 BIFF_ID_SHEETPR = 0x0081;
+const sal_uInt16 BIFF_ID_SST = 0x00FC;
+const sal_uInt16 BIFF_ID_STANDARDWIDTH = 0x0099;
+const sal_uInt16 BIFF2_ID_STRING = 0x0007;
+const sal_uInt16 BIFF3_ID_STRING = 0x0207;
+const sal_uInt16 BIFF_ID_STYLE = 0x0293;
+const sal_uInt16 BIFF_ID_STYLEEXT = 0x0892;
+const sal_uInt16 BIFF_ID_TABLESTYLES = 0x088E;
+const sal_uInt16 BIFF_ID_THEME = 0x0896;
+const sal_uInt16 BIFF_ID_TOPMARGIN = 0x0028;
+const sal_uInt16 BIFF_ID_TXO = 0x01B6;
+const sal_uInt16 BIFF_ID_UNCALCED = 0x005E;
+const sal_uInt16 BIFF_ID_USESELFS = 0x0160;
+const sal_uInt16 BIFF_ID_VBAPROJECT = 0x00D3;
+const sal_uInt16 BIFF_ID_VBAPROJECTEMPTY = 0x01BD;
+const sal_uInt16 BIFF_ID_VCENTER = 0x0084;
+const sal_uInt16 BIFF_ID_VERPAGEBREAKS = 0x001A;
+const sal_uInt16 BIFF_ID_WINDOW1 = 0x003D;
+const sal_uInt16 BIFF2_ID_WINDOW2 = 0x003E;
+const sal_uInt16 BIFF3_ID_WINDOW2 = 0x023E;
+const sal_uInt16 BIFF_ID_WRITEACCESS = 0x005C;
+const sal_uInt16 BIFF_ID_XCT = 0x0059;
+const sal_uInt16 BIFF2_ID_XF = 0x0043;
+const sal_uInt16 BIFF3_ID_XF = 0x0243;
+const sal_uInt16 BIFF4_ID_XF = 0x0443;
+const sal_uInt16 BIFF5_ID_XF = 0x00E0;
+const sal_uInt16 BIFF_ID_XFCRC = 0x087C;
+const sal_uInt16 BIFF_ID_XFEXT = 0x087D;
+
+const sal_uInt16 BIFF_ID_UNKNOWN = SAL_MAX_UINT16;
+
+// OBJ subrecord identifiers --------------------------------------------------
+
+const sal_uInt16 BIFF_ID_OBJEND = 0x0000; /// End of OBJ.
+const sal_uInt16 BIFF_ID_OBJMACRO = 0x0004; /// Macro link.
+const sal_uInt16 BIFF_ID_OBJBUTTON = 0x0005; /// Button data.
+const sal_uInt16 BIFF_ID_OBJGMO = 0x0006; /// Group marker.
+const sal_uInt16 BIFF_ID_OBJCF = 0x0007; /// Clipboard format.
+const sal_uInt16 BIFF_ID_OBJFLAGS = 0x0008; /// Option flags.
+const sal_uInt16 BIFF_ID_OBJPICTFMLA = 0x0009; /// OLE link formula.
+const sal_uInt16 BIFF_ID_OBJCBLS = 0x000A; /// Check box/radio button data.
+const sal_uInt16 BIFF_ID_OBJRBO = 0x000B; /// Radio button group data.
+const sal_uInt16 BIFF_ID_OBJSBS = 0x000C; /// Scroll bar data.
+const sal_uInt16 BIFF_ID_OBJNTS = 0x000C; /// Note data.
+const sal_uInt16 BIFF_ID_OBJSBSFMLA = 0x000E; /// Scroll bar/list box/combo box cell link.
+const sal_uInt16 BIFF_ID_OBJGBODATA = 0x000F; /// Group box data.
+const sal_uInt16 BIFF_ID_OBJEDODATA = 0x0010; /// Edit box data.
+const sal_uInt16 BIFF_ID_OBJRBODATA = 0x0011; /// Radio button group data.
+const sal_uInt16 BIFF_ID_OBJCBLSDATA = 0x0012; /// Check box/radio button data.
+const sal_uInt16 BIFF_ID_OBJLBSDATA = 0x0013; /// List box/combo box data.
+const sal_uInt16 BIFF_ID_OBJCBLSFMLA = 0x0014; /// Check box/radio button cell link.
+const sal_uInt16 BIFF_ID_OBJCMO = 0x0015; /// Common object settings.
+
+// record constants -----------------------------------------------------------
+
+const sal_uInt16 BIFF_BOF_BIFF2 = 0x0200;
+const sal_uInt16 BIFF_BOF_BIFF3 = 0x0300;
+const sal_uInt16 BIFF_BOF_BIFF4 = 0x0400;
+const sal_uInt16 BIFF_BOF_BIFF5 = 0x0500;
+const sal_uInt16 BIFF_BOF_BIFF8 = 0x0600;
+
+const sal_uInt8 BIFF_ERR_NULL = 0x00;
+const sal_uInt8 BIFF_ERR_DIV0 = 0x07;
+const sal_uInt8 BIFF_ERR_VALUE = 0x0F;
+const sal_uInt8 BIFF_ERR_REF = 0x17;
+const sal_uInt8 BIFF_ERR_NAME = 0x1D;
+const sal_uInt8 BIFF_ERR_NUM = 0x24;
+const sal_uInt8 BIFF_ERR_NA = 0x2A;
+
+const sal_uInt8 BIFF_DATATYPE_EMPTY = 0;
+const sal_uInt8 BIFF_DATATYPE_DOUBLE = 1;
+const sal_uInt8 BIFF_DATATYPE_STRING = 2;
+const sal_uInt8 BIFF_DATATYPE_BOOL = 4;
+const sal_uInt8 BIFF_DATATYPE_ERROR = 16;
+
+const sal_uInt8 BIFF_BOOLERR_BOOL = 0;
+const sal_uInt8 BIFF_BOOLERR_ERROR = 1;
+
+// BIFF8 unicode strings ------------------------------------------------------
+
+const sal_uInt8 BIFF_STRF_16BIT = 0x01;
+const sal_uInt8 BIFF_STRF_PHONETIC = 0x04;
+const sal_uInt8 BIFF_STRF_RICH = 0x08;
+const sal_uInt8 BIFF_STRF_UNKNOWN = 0xF2;
+
+// ============================================================================
+
+/** Static helper functions for BIFF filters. */
+class BiffHelper
+{
+public:
+ // conversion -------------------------------------------------------------
+
+ /** Converts the passed packed number to a double. */
+ static double calcDoubleFromRk( sal_Int32 nRkValue );
+ /** Converts the passed double to a packed number, returns true on success. */
+ static bool calcRkFromDouble( sal_Int32& ornRkValue, double fValue );
+
+ /** Converts the passed BIFF error to a double containing the respective Calc error code. */
+ static double calcDoubleFromError( sal_uInt8 nErrorCode );
+
+ /** Returns a text encoding from an Windows code page.
+ @return The corresponding text encoding or RTL_TEXTENCODING_DONTKNOW. */
+ static rtl_TextEncoding calcTextEncodingFromCodePage( sal_uInt16 nCodePage );
+ /** Returns a Windows code page from a text encoding. */
+ static sal_uInt16 calcCodePageFromTextEncoding( rtl_TextEncoding eTextEnc );
+
+ // BIFF12 import ----------------------------------------------------------
+
+ /** Reads a BIFF12 string with leading 16-bit or 32-bit length field. */
+ static ::rtl::OUString readString( SequenceInputStream& rStrm, bool b32BitLen = true );
+
+ // BIFF2-BIFF8 import -----------------------------------------------------
+
+ /** Returns true, if the current record of the stream is a BOF record. */
+ static bool isBofRecord( BiffInputStream& rStrm );
+
+ /** Skips a block of records up to the specified end record.
+
+ Skips all records until next end record. When this function returns,
+ the stream points to the end record, and the next call of the function
+ startNextRecord() at the stream will start the record following the end
+ record.
+
+ The identifier of the record that is active while this function is
+ called is used as start record identifier. This identifier is used to
+ correctly skip embedded record blocks with the same start and end
+ record identifier.
+
+ @return True = stream points to the end record.
+ */
+ static bool skipRecordBlock( BiffInputStream& rStrm, sal_uInt16 nEndRecId );
+
+ /** Imports a picture from an IMGDATA record. */
+ static void importImgData( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, BiffType eBiff );
+
+private:
+ BiffHelper(); // not implemented
+ ~BiffHelper(); // not implemented
+};
+
+// ----------------------------------------------------------------------------
+
+/** BIFF12 stream operator for an ::rtl::OUString, reads 32-bit string length and Unicode array. */
+inline SequenceInputStream& operator>>( SequenceInputStream& rStrm, ::rtl::OUString& orString )
+{
+ orString = BiffHelper::readString( rStrm );
+ return rStrm;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/biffinputstream.hxx b/oox/inc/oox/xls/biffinputstream.hxx
new file mode 100644
index 000000000000..003ab28be34f
--- /dev/null
+++ b/oox/inc/oox/xls/biffinputstream.hxx
@@ -0,0 +1,446 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_BIFFINPUTSTREAM_HXX
+#define OOX_XLS_BIFFINPUTSTREAM_HXX
+
+#include <vector>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/xls/biffhelper.hxx"
+#include "oox/xls/biffcodec.hxx"
+
+namespace rtl { class OUStringBuffer; }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace prv {
+
+/** Buffers the contents of a raw record and encapsulates stream decoding. */
+class BiffInputRecordBuffer
+{
+public:
+ explicit BiffInputRecordBuffer( BinaryInputStream& rInStrm );
+
+ /** Returns the wrapped binary base stream. */
+ inline const BinaryInputStream& getBaseStream() const { return mrInStrm; }
+
+ /** Sets a decoder object and decrypts buffered record data. */
+ void setDecoder( const BiffDecoderRef& rxDecoder );
+ /** Returns the current decoder object. */
+ inline BiffDecoderRef getDecoder() const { return mxDecoder; }
+ /** Enables/disables usage of current decoder. */
+ void enableDecoder( bool bEnable );
+
+ /** Restarts the stream at the passed position. Buffer is invalid until the
+ next call of startRecord() or startNextRecord(). */
+ void restartAt( sal_Int64 nPos );
+
+ /** Reads the record header at the passed position. */
+ bool startRecord( sal_Int64 nHeaderPos );
+ /** Reads the next record header from the stream. */
+ bool startNextRecord();
+ /** Returns the start position of the record header in the core stream. */
+ sal_uInt16 getNextRecId();
+
+ /** Returns the start position of the record header in the core stream. */
+ inline sal_Int64 getRecHeaderPos() const { return mnHeaderPos; }
+ /** Returns the current record identifier. */
+ inline sal_uInt16 getRecId() const { return mnRecId; }
+ /** Returns the current record size. */
+ inline sal_uInt16 getRecSize() const { return mnRecSize; }
+ /** Returns the current read position in the current record body. */
+ inline sal_uInt16 getRecPos() const { return mnRecPos; }
+ /** Returns the number of remaining bytes in the current record body. */
+ inline sal_uInt16 getRecLeft() const { return mnRecSize - mnRecPos; }
+
+ /** Reads nBytes bytes to the existing buffer opData. Must NOT overread the source buffer. */
+ void read( void* opData, sal_uInt16 nBytes );
+ /** Ignores nBytes bytes. Must NOT overread the buffer. */
+ void skip( sal_uInt16 nBytes );
+
+private:
+ /** Updates data buffer from stream, if needed. */
+ void updateBuffer();
+ /** Updates decoded data from original data. */
+ void updateDecoded();
+
+private:
+ typedef ::std::vector< sal_uInt8 > DataBuffer;
+
+ BinaryInputStream& mrInStrm; /// Core input stream.
+ DataBuffer maOriginalData; /// Original data read from stream.
+ DataBuffer maDecodedData; /// Decoded data.
+ DataBuffer* mpCurrentData; /// Points to data buffer currently in use.
+ BiffDecoderRef mxDecoder; /// Decoder object.
+ sal_Int64 mnHeaderPos; /// Stream start position of current record header.
+ sal_Int64 mnBodyPos; /// Stream start position of current record body.
+ sal_Int64 mnBufferBodyPos; /// Stream start position of buffered data.
+ sal_Int64 mnNextHeaderPos; /// Stream start position of next record header.
+ sal_uInt16 mnRecId; /// Current record identifier.
+ sal_uInt16 mnRecSize; /// Current record size.
+ sal_uInt16 mnRecPos; /// Current position in record body.
+ bool mbValidHeader; /// True = valid record header.
+};
+
+} // namespace prv
+
+// ============================================================================
+
+/** This class is used to read BIFF record streams.
+
+ An instance is constructed with a BinaryInputStream object. The passed
+ stream is reset to its start while constructing this stream.
+
+ To start reading a record call startNextRecord(). Now it is possible to
+ read all contents of the record using operator>>() or any of the read***()
+ functions. If some data exceeds the record size limit, the stream looks for
+ a following CONTINUE record and jumps automatically to it. It is NOT
+ allowed that an atomic data type is split into two records (e.g. 4 bytes of
+ a double in one record and the other 4 bytes in a following CONTINUE).
+
+ Trying to read over the record limits results in a stream error. The
+ isValid() function indicates that by returning false. From now on the data
+ returned by the read functions is undefined. The error state will be reset,
+ if the record is reset (with the function resetRecord()), or if the next
+ record is started.
+
+ To switch off the automatic lookup of CONTINUE records, use resetRecord()
+ with false parameter. This is useful e.g. on import of drawing layer data,
+ where sometimes solely CONTINUE records will occur. The automatic lookup
+ keeps switched off until the method resetRecord() is called with parameter
+ true. All other settings done on the stream (e.g. alternative CONTINUE
+ record identifier, enabled decryption, NUL substitution character) will be
+ reset to default values, if a new record is started.
+
+ The import stream supports decrypting the stream data. The contents of a
+ record (not the record header) will be encrypted by Excel if the file has
+ been stored with password protection. The functions setDecoder() and
+ enableDecoder() control the usage of the decryption algorithms.
+ setDecoder() sets a new decryption algorithm and initially enables it.
+ enableDecoder( false ) may be used to stop the usage of the decryption
+ temporarily (sometimes record contents are never encrypted, e.g. all BOF
+ records or the stream position in SHEET records). Decryption will be
+ reenabled automatically, if a new record is started with the function
+ startNextRecord().
+*/
+class BiffInputStream : public BinaryInputStream
+{
+public:
+ /** Constructs the BIFF record stream using the passed binary stream.
+
+ @param rInStream
+ The base input stream. Must be seekable. Will be seeked to its
+ start position.
+
+ @param bContLookup Automatic CONTINUE lookup on/off.
+ */
+ explicit BiffInputStream(
+ BinaryInputStream& rInStream,
+ bool bContLookup = true );
+
+ // record control ---------------------------------------------------------
+
+ /** Sets stream pointer to the start of the next record content.
+
+ Ignores all CONTINUE records of the current record, if automatic
+ CONTINUE usage is switched on.
+
+ @return False = no record found (end of stream).
+ */
+ bool startNextRecord();
+
+ /** Sets stream pointer to the start of the content of the specified record.
+
+ The handle of the current record can be received and stored using the
+ function getRecHandle() for later usage with this function. The record
+ handle is equivalent to the position of the underlying binary stream,
+ thus the function can be used to perform a hard seek to a specific
+ position, if it is sure that a record starts exactly at this position.
+
+ @return False = no record found (invalid handle passed).
+ */
+ bool startRecordByHandle( sal_Int64 nRecHandle );
+
+ /** Sets stream pointer to begin of record content.
+
+ @param bContLookup
+ Automatic CONTINUE lookup on/off. In difference to other stream
+ settings, this setting is persistent until next call of this
+ function (because it is wanted to receive the next CONTINUE records
+ separately).
+ @param nAltContId
+ Sets an alternative record identifier for content continuation.
+ This value is reset automatically when a new record is started with
+ startNextRecord().
+ */
+ void resetRecord(
+ bool bContLookup,
+ sal_uInt16 nAltContId = BIFF_ID_UNKNOWN );
+
+ /** Sets stream pointer before current record and invalidates stream.
+
+ The next call to startNextRecord() will start again the current record.
+ This can be used in situations where a loop or a function leaves on a
+ specific record, but the parent context expects to start this record by
+ itself. The stream is invalid as long as the first record has not been
+ started (it is not allowed to call any other stream operation then).
+ */
+ void rewindRecord();
+
+ // decoder ----------------------------------------------------------------
+
+ /** Sets a new decoder object.
+
+ Enables decryption of record contents for the rest of the stream.
+ */
+ void setDecoder( const BiffDecoderRef& rxDecoder );
+
+ /** Enables/disables usage of current decoder.
+
+ Decryption is reenabled automatically, if a new record is started using
+ the function startNextRecord().
+ */
+ void enableDecoder( bool bEnable = true );
+
+ // stream/record state and info -------------------------------------------
+
+ /** Returns the current record identifier. */
+ inline sal_uInt16 getRecId() const { return mnRecId; }
+ /** Returns the record identifier of the following record. */
+ sal_uInt16 getNextRecId();
+
+ /** Returns a unique handle for the current record that can be used with
+ the function startRecordByHandle(). */
+ inline sal_Int64 getRecHandle() const { return mnRecHandle; }
+
+ // BinaryStreamBase interface (seeking) -----------------------------------
+
+ /** Returns true, as the BIFF input stream is required to be seekable. */
+ virtual bool isSeekable() const;
+ /** Returns the position inside of the whole record content. */
+ virtual sal_Int64 tell() const;
+ /** Returns the data size of the whole record without record headers. */
+ virtual sal_Int64 getLength() const;
+ /** Seeks in record content to the specified position. */
+ virtual void seek( sal_Int64 nRecPos );
+
+ /** Returns the absolute position in the wrapped binary stream. */
+ sal_Int64 tellBase() const;
+ /** Returns the total size of the wrapped binary stream. */
+ sal_Int64 getBaseLength() const;
+
+ // BinaryInputStream interface (stream read access) -----------------------
+
+ /** Reads nBytes bytes to the passed sequence.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readData( StreamDataSequence& orData, sal_Int32 nBytes );
+ /** Reads nBytes bytes and copies them to the passed buffer opMem.
+ @return Number of bytes really read. */
+ virtual sal_Int32 readMemory( void* opMem, sal_Int32 nBytes );
+ /** Seeks forward inside the current record. */
+ virtual void skip( sal_Int32 nBytes );
+
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline BiffInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
+
+ // byte strings -----------------------------------------------------------
+
+ /** Reads 8/16 bit string length and character array, and returns the string.
+ @param b16BitLen
+ True = Read 16-bit string length field before the character array.
+ False = Read 8-bit string length field before the character array.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default).
+ */
+ ::rtl::OString readByteString( bool b16BitLen, bool bAllowNulChars = false );
+
+ /** Reads 8/16 bit string length and character array, and returns a Unicode string.
+ @param b16BitLen
+ True = Read 16-bit string length field before the character array.
+ False = Read 8-bit string length field before the character array.
+ @param eTextEnc The text encoding used to create the Unicode string.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default).
+ */
+ ::rtl::OUString readByteStringUC( bool b16BitLen, rtl_TextEncoding eTextEnc, bool bAllowNulChars = false );
+
+ /** Ignores 8/16 bit string length and character array.
+ @param b16BitLen
+ True = Read 16-bit string length field before the character array.
+ False = Read 8-bit string length field before the character array.
+ */
+ void skipByteString( bool b16BitLen );
+
+ // Unicode strings --------------------------------------------------------
+
+ /** Reads nChars characters of a BIFF8 string, and returns the string.
+ @param nChars Number of characters to read from the stream.
+ @param b16BitChars
+ True = The character array contains 16-bit characters.
+ False = The character array contains truncated 8-bit characters.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default).
+ */
+ ::rtl::OUString readUniStringChars( sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars = false );
+
+ /** Reads 8-bit flags, extended header, nChar characters, extended data of
+ a BIFF8 string, and returns the string.
+ @param nChars Number of characters to read from the stream.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default).
+ */
+ ::rtl::OUString readUniStringBody( sal_uInt16 nChars, bool bAllowNulChars = false );
+
+ /** Reads 16-bit character count, 8-bit flags, extended header, character
+ array, extended data of a BIFF8 string, and returns the string.
+ @param bAllowNulChars
+ True = NUL characters are inserted into the imported string.
+ False = NUL characters are replaced by question marks (default).
+ */
+ ::rtl::OUString readUniString( bool bAllowNulChars = false );
+
+ /** Ignores nChars characters of a BIFF8 string.
+ @param nChars Number of characters to skip in the stream.
+ @param b16BitChars
+ True = The character array contains 16-bit characters.
+ False = The character array contains truncated 8-bit characters.
+ */
+ void skipUniStringChars( sal_uInt16 nChars, bool b16BitChars );
+
+ /** Ignores 8-bit flags, extended header, nChar characters, extended data
+ of a BIFF8 string.
+ @param nChars Number of characters to skip in the stream.
+ */
+ void skipUniStringBody( sal_uInt16 nChars );
+
+ /** Ignores 16-bit character count, 8-bit flags, extended header, character
+ array, extended data of a BIFF8 string.
+ */
+ void skipUniString();
+
+ // ------------------------------------------------------------------------
+private:
+ /** Forwards calls of readValue() template functions to the record buffer. */
+ virtual void readAtom( void* opMem, sal_uInt8 nSize );
+
+ /** Initializes all members after base stream has been seeked to new record. */
+ void setupRecord();
+ /** Restarts the current record from the beginning. */
+ void restartRecord( bool bInvalidateRecSize );
+ /** Sets stream pointer before specified record and invalidates stream. */
+ void rewindToRecord( sal_Int64 nRecHandle );
+ /** Returns true, if stream was able to start a valid record. */
+ inline bool isInRecord() const { return mnRecHandle >= 0; }
+
+ /** Returns true, if the passed ID is real or alternative continuation record ID. */
+ bool isContinueId( sal_uInt16 nRecId ) const;
+ /** Goes to start of the next CONTINUE record.
+ @descr Stream must be located at the end of a raw record, and handling
+ of CONTINUE records must be enabled.
+ @return True if next CONTINUE record has been found and initialized. */
+ bool jumpToNextContinue();
+ /** Goes to start of the next CONTINUE record while reading strings.
+ @descr Stream must be located at the end of a raw record. If reading
+ has been started in a CONTINUE record, jumps to an existing following
+ CONTINUE record, even if handling of CONTINUE records is disabled (this
+ is a special handling for TXO string data). Reads additional Unicode
+ flag byte at start of the new raw record and sets or resets rb16BitChars.
+ @return True if next CONTINUE record has been found and initialized. */
+ bool jumpToNextStringContinue( bool& rb16BitChars );
+ /** Calculates the complete length of the current record including CONTINUE
+ records, stores the length in mnComplRecSize. */
+ void calcRecordLength();
+
+ /** Ensures that reading nBytes bytes is possible with next stream access.
+ @descr Stream must be located at the end of a raw record, and handling
+ of CONTINUE records must be enabled.
+ @return True if nBytes can be read from stream. */
+ bool ensureRawReadSize( sal_uInt16 nBytes );
+ /** Returns the maximum size of raw data possible to read in one block. */
+ sal_uInt16 getMaxRawReadSize( sal_Int32 nBytes ) const;
+
+ /** Reads an array of Unicode characters and appends them to the passed buffer. */
+ void appendUnicodeArray( ::rtl::OUStringBuffer& orBuffer, sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars );
+ /** Reads the BIFF8 Unicode string header fields. */
+ void readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize );
+
+private:
+ prv::BiffInputRecordBuffer maRecBuffer; /// Raw record data buffer.
+
+ sal_Int64 mnRecHandle; /// Handle of current record.
+ sal_uInt16 mnRecId; /// Identifier of current record (not the CONTINUE ID).
+ sal_uInt16 mnAltContId; /// Alternative identifier for content continuation records.
+
+ sal_Int64 mnCurrRecSize; /// Helper for record size and position.
+ sal_Int64 mnComplRecSize; /// Size of complete record data (with CONTINUEs).
+ bool mbHasComplRec; /// True = mnComplRecSize is valid.
+
+ bool mbCont; /// True = automatic CONTINUE lookup enabled.
+};
+
+// ============================================================================
+
+class BiffInputStreamPos
+{
+public:
+ explicit BiffInputStreamPos( BiffInputStream& rStrm );
+
+ bool restorePosition();
+
+ inline BiffInputStream& getStream() { return mrStrm; }
+
+private:
+ BiffInputStream& mrStrm;
+ sal_Int64 mnRecHandle;
+ sal_Int64 mnRecPos;
+};
+
+// ============================================================================
+
+/** Stores the current position of the passed stream on construction and
+ restores it automatically on destruction. */
+class BiffInputStreamPosGuard : private BiffInputStreamPos
+{
+public:
+ explicit BiffInputStreamPosGuard( BiffInputStream& rStrm );
+ ~BiffInputStreamPosGuard();
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/biffoutputstream.hxx b/oox/inc/oox/xls/biffoutputstream.hxx
new file mode 100644
index 000000000000..ada646bd879a
--- /dev/null
+++ b/oox/inc/oox/xls/biffoutputstream.hxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_BIFFOUTPUTSTREAM_HXX
+#define OOX_XLS_BIFFOUTPUTSTREAM_HXX
+
+#include <vector>
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/xls/biffhelper.hxx"
+
+namespace oox { class BinaryOutputStream; }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace prv {
+
+/** Buffers the contents of a raw record. */
+class BiffOutputRecordBuffer
+{
+public:
+ explicit BiffOutputRecordBuffer(
+ BinaryOutputStream& rOutStrm,
+ sal_uInt16 nMaxRecSize );
+
+ /** Returns the wrapped binary base stream. */
+ inline const BinaryOutputStream& getBaseStream() const { return mrOutStrm; }
+
+ /** Starts a new record. */
+ void startRecord( sal_uInt16 nRecId );
+ /** Finishes the current record. Must be called for every started record. */
+ void endRecord();
+
+ /** Returns the number of remaining bytes in the current record body. */
+ inline sal_uInt16 getRecLeft() const { return static_cast< sal_uInt16 >( mnMaxRecSize - maData.size() ); }
+
+ /** Writes nBytes bytes from the existing buffer pData. Must NOT overwrite the destination buffer. */
+ void write( const void* pData, sal_uInt16 nBytes );
+ /** Writes a sequence of nBytes bytes with the passed value. */
+ void fill( sal_uInt8 nValue, sal_uInt16 nBytes );
+
+private:
+ typedef ::std::vector< sal_uInt8 > DataBuffer;
+
+ BinaryOutputStream& mrOutStrm; /// Core ouput stream.
+ DataBuffer maData; /// Record data buffer.
+ sal_uInt16 mnMaxRecSize; /// Maximum size of record contents.
+ sal_uInt16 mnRecId; /// Current record identifier.
+ bool mbInRec; /// True = currently writing inside of a record.
+};
+
+} // namespace prv
+
+// ============================================================================
+
+/** This class is used to write BIFF record streams.
+
+ An instance is constructed with a BinaryOutputStream object and the
+ maximum size of BIFF record contents (e.g. 2080 bytes in BIFF2-BIFF5, or
+ 8224 bytes in BIFF8).
+
+ To start writing a record, call startRecord() with the record identifier.
+ Each record must be closed by calling endRecord().
+
+ If some data exceeds the record size limit, a CONTINUE record will be
+ started automatically and the new data will be written to this record. If
+ specific data pieces must not be split into the current and a following
+ CONTINUE record, use setPortionSize(). Example: To write a sequence of
+ 16-bit values where 4 values form a unit and cannot be split, call
+ setPortionSize(8) first (4*2 bytes == 8).
+
+ To write unicode character arrays, call writeUnicodeBuffer(). It creates
+ CONTINUE records and repeats the unicode string flag byte automatically.
+*/
+class BiffOutputStream : public BinaryOutputStream
+{
+public:
+ explicit BiffOutputStream(
+ BinaryOutputStream& rOutStream,
+ sal_uInt16 nMaxRecSize );
+
+ // record control ---------------------------------------------------------
+
+ /** Starts a new record. */
+ void startRecord( sal_uInt16 nRecId );
+
+ /** Finishes the current record. Must be called for every started record. */
+ void endRecord();
+
+ /** Sets size of data portion in bytes. 0 means no portions are used. */
+ void setPortionSize( sal_uInt16 nSize );
+
+ // BinaryStreamBase interface (seeking) -----------------------------------
+
+ /** Returns the absolute position in the wrapped binary stream. */
+ sal_Int64 tellBase() const;
+ /** Returns the total size of the wrapped binary stream. */
+ sal_Int64 getBaseLength() const;
+
+ // BinaryOutputStream interface (stream write access) ---------------------
+
+ /** Writes the passed data sequence. */
+ virtual void writeData( const StreamDataSequence& rData );
+ /** Writes nBytes bytes from the passed buffer pMem. */
+ virtual void writeMemory( const void* pMem, sal_Int32 nBytes );
+
+ /** Writes a sequence of nBytes bytes with the passed value. */
+ void fill( sal_uInt8 nValue, sal_Int32 nBytes );
+ /** Writes a block of memory, ensures that it is not split to a CONTINUE record. */
+ void writeBlock( const void* pMem, sal_uInt16 nBytes );
+
+ /** Stream operator for integral and floating-point types. */
+ template< typename Type >
+ inline BiffOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }
+
+ // ------------------------------------------------------------------------
+private:
+ /** Forwards calls of writeValue() template functions to the record buffer. */
+ virtual void writeAtom( const void* pMem, sal_uInt8 nSize );
+
+ /** Checks the remaining size in the current record, creates CONTINUE record if needed. */
+ void ensureRawBlock( sal_uInt16 nSize );
+ /** Checks the remaining size in the current record and creates CONTINUE record if needed.
+ @return Maximum size left for writing to current record. */
+ sal_uInt16 prepareRawBlock( sal_Int32 nTotalSize );
+
+private:
+ prv::BiffOutputRecordBuffer maRecBuffer; /// Raw record data buffer.
+ sal_uInt16 mnPortionSize; /// Size of data portions.
+ sal_uInt16 mnPortionPos; /// Position in current portion.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/chartsheetfragment.hxx b/oox/inc/oox/xls/chartsheetfragment.hxx
new file mode 100644
index 000000000000..8dfedc5ba48e
--- /dev/null
+++ b/oox/inc/oox/xls/chartsheetfragment.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_CHARTSHEETFRAGMENT_HXX
+#define OOX_XLS_CHARTSHEETFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class ChartsheetFragment : public WorksheetFragmentBase
+{
+public:
+ explicit ChartsheetFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath,
+ const ISegmentProgressBarRef& rxProgressBar,
+ sal_Int16 nSheet );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+ virtual void initializeImport();
+ virtual void finalizeImport();
+
+private:
+ /** Imports the the relation identifier for the DrawingML part. */
+ void importDrawing( const AttributeList& rAttribs );
+ /** Imports the DRAWING record containing the relation identifier for the DrawingML part. */
+ void importDrawing( SequenceInputStream& rStrm );
+};
+
+// ============================================================================
+
+class BiffChartsheetFragment : public BiffWorksheetFragmentBase
+{
+public:
+ explicit BiffChartsheetFragment(
+ const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar,
+ sal_Int16 nSheet );
+
+ /** Imports the entire sheet fragment, returns true, if EOF record has been reached. */
+ virtual bool importFragment();
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/commentsbuffer.hxx b/oox/inc/oox/xls/commentsbuffer.hxx
new file mode 100644
index 000000000000..e87d52ff03a2
--- /dev/null
+++ b/oox/inc/oox/xls/commentsbuffer.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_COMMENTSBUFFER_HXX
+#define OOX_XLS_COMMENTSBUFFER_HXX
+
+#include "oox/xls/richstring.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+struct CommentModel
+{
+ ::com::sun::star::table::CellRangeAddress
+ maRange; /// Position of the comment in the worksheet.
+ RichStringRef mxText; /// Formatted text of the comment.
+ sal_Int32 mnAuthorId; /// Identifier of the comment's author.
+
+ explicit CommentModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class Comment : public WorksheetHelper
+{
+public:
+ explicit Comment( const WorksheetHelper& rHelper );
+
+ /** Imports a cell comment from the passed attributes of the comment element. */
+ void importComment( const AttributeList& rAttribs );
+ /** Imports a cell comment from the passed stream of a COMMENT record. */
+ void importComment( SequenceInputStream& rStrm );
+
+ /** Creates and returns a new rich-string object for the comment text. */
+ RichStringRef createText();
+
+ /** Finalizes the formatted string of the comment. */
+ void finalizeImport();
+
+private:
+ CommentModel maModel;
+};
+
+typedef ::boost::shared_ptr< Comment > CommentRef;
+
+// ============================================================================
+
+class CommentsBuffer : public WorksheetHelper
+{
+public:
+ explicit CommentsBuffer( const WorksheetHelper& rHelper );
+
+ /** Appends a new author to the list of comment authors. */
+ void appendAuthor( const ::rtl::OUString& rAuthor );
+ /** Creates and returns a new comment. */
+ CommentRef createComment();
+
+ /** Finalizes the formatted string of all comments. */
+ void finalizeImport();
+
+private:
+ typedef ::std::vector< ::rtl::OUString > OUStringVector;
+ typedef RefVector< Comment > CommentVector;
+
+ OUStringVector maAuthors;
+ CommentVector maComments;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/commentsfragment.hxx b/oox/inc/oox/xls/commentsfragment.hxx
new file mode 100644
index 000000000000..3751cde764f4
--- /dev/null
+++ b/oox/inc/oox/xls/commentsfragment.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ***********************************************************************/
+
+#ifndef OOX_XLS_COMMENTSFRAGMENT_HXX
+#define OOX_XLS_COMMENTSFRAGMENT_HXX
+
+#include "oox/xls/commentsbuffer.hxx"
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class CommentsFragment : public WorksheetFragmentBase
+{
+public:
+ explicit CommentsFragment(
+ const WorksheetHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onEndRecord();
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+
+private:
+ /** Imports comment data from the comment element. */
+ void importComment( const AttributeList& rAttribs );
+ /** Imports comment data from the COMMENT record. */
+ void importComment( SequenceInputStream& rStrm );
+
+private:
+ CommentRef mxComment;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/condformatbuffer.hxx b/oox/inc/oox/xls/condformatbuffer.hxx
new file mode 100644
index 000000000000..fae6381f6402
--- /dev/null
+++ b/oox/inc/oox/xls/condformatbuffer.hxx
@@ -0,0 +1,193 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_CONDFORMATBUFFER_HXX
+#define OOX_XLS_CONDFORMATBUFFER_HXX
+
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XSheetConditionalEntries; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Model for a single rule in a conditional formatting. */
+struct CondFormatRuleModel
+{
+ typedef ::std::vector< TokensFormulaContext > ContextVector;
+
+ ContextVector maFormulas; /// Formulas for rule conditions.
+ ::rtl::OUString maText; /// Text for 'contains' rules.
+ sal_Int32 mnPriority; /// Priority of this rule.
+ sal_Int32 mnType; /// Type of the rule.
+ sal_Int32 mnOperator; /// In cell-is rules: Comparison operator.
+ sal_Int32 mnTimePeriod; /// In time-period rules: Type of time period.
+ sal_Int32 mnRank; /// In top-10 rules: True = bottom, false = top.
+ sal_Int32 mnStdDev; /// In average rules: Number of std deviations.
+ sal_Int32 mnDxfId; /// Differential formatting identifier.
+ bool mbStopIfTrue; /// True = stop evaluating rules, if this rule is true.
+ bool mbBottom; /// In top-10 rules: True = bottom, false = top.
+ bool mbPercent; /// In top-10 rules: True = percent, false = rank.
+ bool mbAboveAverage; /// In average rules: True = above average, false = below.
+ bool mbEqualAverage; /// In average rules: True = include average, false = exclude.
+
+ explicit CondFormatRuleModel();
+
+ /** Sets the passed BIFF operator for condition type cellIs. */
+ void setBiffOperator( sal_Int32 nOperator );
+
+ /** Sets the passed BIFF12 text comparison type and operator. */
+ void setBiff12TextType( sal_Int32 nOperator );
+};
+
+// ============================================================================
+
+class CondFormat;
+
+/** Represents a single rule in a conditional formatting. */
+class CondFormatRule : public WorksheetHelper
+{
+public:
+ explicit CondFormatRule( const CondFormat& rCondFormat );
+
+ /** Imports rule settings from the cfRule element. */
+ void importCfRule( const AttributeList& rAttribs );
+ /** Appends a new condition formula string. */
+ void appendFormula( const ::rtl::OUString& rFormula );
+
+ /** Imports rule settings from a CFRULE record. */
+ void importCfRule( SequenceInputStream& rStrm );
+
+ /** Imports rule settings from a CFRULE record. */
+ void importCfRule( BiffInputStream& rStrm, sal_Int32 nPriority );
+
+ /** Creates a conditional formatting rule in the Calc document. */
+ void finalizeImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSheetConditionalEntries >& rxEntries );
+
+ /** Returns the priority of this rule. */
+ inline sal_Int32 getPriority() const { return maModel.mnPriority; }
+
+private:
+ const CondFormat& mrCondFormat;
+ CondFormatRuleModel maModel;
+};
+
+typedef ::boost::shared_ptr< CondFormatRule > CondFormatRuleRef;
+
+// ============================================================================
+
+/** Model for a conditional formatting object. */
+struct CondFormatModel
+{
+ ApiCellRangeList maRanges; /// Cell ranges for this conditional format.
+ bool mbPivot; /// Conditional formatting belongs to pivot table.
+
+ explicit CondFormatModel();
+};
+
+// ============================================================================
+
+/** Represents a conditional formatting object with a list of affected cell ranges. */
+class CondFormat : public WorksheetHelper
+{
+public:
+ explicit CondFormat( const WorksheetHelper& rHelper );
+
+ /** Imports settings from the conditionalFormatting element. */
+ void importConditionalFormatting( const AttributeList& rAttribs );
+ /** Imports a conditional formatting rule from the cfRule element. */
+ CondFormatRuleRef importCfRule( const AttributeList& rAttribs );
+
+ /** Imports settings from the CONDFORMATTING record. */
+ void importCondFormatting( SequenceInputStream& rStrm );
+ /** Imports a conditional formatting rule from the CFRULE record. */
+ void importCfRule( SequenceInputStream& rStrm );
+
+ /** Imports settings from the CFHEADER record. */
+ void importCfHeader( BiffInputStream& rStrm );
+
+ /** Creates the conditional formatting in the Calc document. */
+ void finalizeImport();
+
+ /** Returns the cell ranges this conditional formatting belongs to. */
+ inline const ApiCellRangeList& getRanges() const { return maModel.maRanges; }
+
+private:
+ CondFormatRuleRef createRule();
+ void insertRule( CondFormatRuleRef xRule );
+
+private:
+ typedef RefMap< sal_Int32, CondFormatRule > CondFormatRuleMap;
+
+ CondFormatModel maModel; /// Model of this conditional formatting.
+ CondFormatRuleMap maRules; /// Maps formatting rules by priority.
+};
+
+typedef ::boost::shared_ptr< CondFormat > CondFormatRef;
+
+// ============================================================================
+
+class CondFormatBuffer : public WorksheetHelper
+{
+public:
+ explicit CondFormatBuffer( const WorksheetHelper& rHelper );
+
+ /** Imports settings from the conditionalFormatting element. */
+ CondFormatRef importConditionalFormatting( const AttributeList& rAttribs );
+ /** Imports settings from the CONDFORMATTING record. */
+ CondFormatRef importCondFormatting( SequenceInputStream& rStrm );
+ /** Imports settings from the CFHEADER record. */
+ void importCfHeader( BiffInputStream& rStrm );
+
+ /** Creates all conditional formattings in the Calc document. */
+ void finalizeImport();
+
+ /** Converts an OOXML condition operator token to the API constant. */
+ static ::com::sun::star::sheet::ConditionOperator
+ convertToApiOperator( sal_Int32 nToken );
+
+private:
+ CondFormatRef createCondFormat();
+
+private:
+ typedef RefVector< CondFormat > CondFormatVec;
+ CondFormatVec maCondFormats; /// All conditional formattings in a sheet.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/condformatcontext.hxx b/oox/inc/oox/xls/condformatcontext.hxx
new file mode 100644
index 000000000000..44c9fe592250
--- /dev/null
+++ b/oox/inc/oox/xls/condformatcontext.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_CONDFORMATCONTEXT_HXX
+#define OOX_XLS_CONDFORMATCONTEXT_HXX
+
+#include "oox/xls/condformatbuffer.hxx"
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class CondFormatContext : public WorksheetContextBase
+{
+public:
+ explicit CondFormatContext( WorksheetFragmentBase& rFragment );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ CondFormatRef mxCondFmt;
+ CondFormatRuleRef mxRule;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/connectionsbuffer.hxx b/oox/inc/oox/xls/connectionsbuffer.hxx
new file mode 100755
index 000000000000..98a5bea17bc6
--- /dev/null
+++ b/oox/inc/oox/xls/connectionsbuffer.hxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_CONNECTIONSBUFFER_HXX
+#define OOX_XLS_CONNECTIONSBUFFER_HXX
+
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+const sal_Int32 BIFF12_CONNECTION_UNKNOWN = 0;
+const sal_Int32 BIFF12_CONNECTION_ODBC = 1;
+const sal_Int32 BIFF12_CONNECTION_DAO = 2;
+const sal_Int32 BIFF12_CONNECTION_FILE = 3;
+const sal_Int32 BIFF12_CONNECTION_HTML = 4;
+const sal_Int32 BIFF12_CONNECTION_OLEDB = 5;
+const sal_Int32 BIFF12_CONNECTION_TEXT = 6;
+const sal_Int32 BIFF12_CONNECTION_ADO = 7;
+const sal_Int32 BIFF12_CONNECTION_DSP = 8;
+
+// ============================================================================
+
+/** Special properties for data connections representing web queries. */
+struct WebPrModel
+{
+ typedef ::std::vector< ::com::sun::star::uno::Any > TablesVector;
+
+ TablesVector maTables; /// Names or indexes of the web query tables.
+ ::rtl::OUString maUrl; /// Source URL to refresh the data.
+ ::rtl::OUString maPostMethod; /// POST method to query data.
+ ::rtl::OUString maEditPage; /// Web page showing query data (for XML queries).
+ sal_Int32 mnHtmlFormat; /// Plain text, rich text, or HTML.
+ bool mbXml; /// True = XML query, false = HTML query.
+ bool mbSourceData; /// True = import XML source data referred by HTML table.
+ bool mbParsePre; /// True = parse preformatted sections (<pre> tag).
+ bool mbConsecutive; /// True = join consecutive delimiters.
+ bool mbFirstRow; /// True = use column withs of first row for entire <pre> tag.
+ bool mbXl97Created; /// True = web query created with Excel 97.
+ bool mbTextDates; /// True = read date values as text, false = parse dates.
+ bool mbXl2000Refreshed; /// True = refreshed with Excel 2000 or newer.
+ bool mbHtmlTables; /// True = HTML tables, false = entire document.
+
+ explicit WebPrModel();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Common properties of an external data connection. */
+struct ConnectionModel
+{
+ typedef ::std::auto_ptr< WebPrModel > WebPrModelPtr;
+
+ WebPrModelPtr mxWebPr; /// Special settings for web queries.
+ ::rtl::OUString maName; /// Unique name of this connection.
+ ::rtl::OUString maDescription; /// User description of this connection.
+ ::rtl::OUString maSourceFile; /// URL of a source data file.
+ ::rtl::OUString maSourceConnFile; /// URL of a source connection file.
+ ::rtl::OUString maSsoId; /// Single sign-on identifier.
+ sal_Int32 mnId; /// Unique connection identifier.
+ sal_Int32 mnType; /// Data source type.
+ sal_Int32 mnReconnectMethod; /// Reconnection method.
+ sal_Int32 mnCredentials; /// Credentials method.
+ sal_Int32 mnInterval; /// Refresh interval in minutes.
+ bool mbKeepAlive; /// True = keep connection open after import.
+ bool mbNew; /// True = new connection, never updated.
+ bool mbDeleted; /// True = connection has been deleted.
+ bool mbOnlyUseConnFile; /// True = use maSourceConnFile, ignore mnReconnectMethod.
+ bool mbBackground; /// True = background refresh enabled.
+ bool mbRefreshOnLoad; /// True = refresh connection on import.
+ bool mbSaveData; /// True = save cached data with connection.
+ bool mbSavePassword; /// True = save password in connection string.
+
+ explicit ConnectionModel();
+
+ WebPrModel& createWebPr();
+};
+
+// ----------------------------------------------------------------------------
+
+/** An external data connection (database, web query, etc.). */
+class Connection : public WorkbookHelper
+{
+public:
+ explicit Connection( const WorkbookHelper& rHelper, sal_Int32 nConnId = -1 );
+
+ /** Imports connection settings from the connection element. */
+ void importConnection( const AttributeList& rAttribs );
+ /** Imports web query settings from the webPr element. */
+ void importWebPr( const AttributeList& rAttribs );
+ /** Imports web query table settings from the tables element. */
+ void importTables( const AttributeList& rAttribs );
+ /** Imports a web query table identifier from the m, s, or x element. */
+ void importTable( const AttributeList& rAttribs, sal_Int32 nElement );
+
+ /** Imports connection settings from the CONNECTION record. */
+ void importConnection( SequenceInputStream& rStrm );
+ /** Imports web query settings from the WEBPR record. */
+ void importWebPr( SequenceInputStream& rStrm );
+ /** Imports web query table settings from the WEBPRTABLES record. */
+ void importWebPrTables( SequenceInputStream& rStrm );
+ /** Imports a web query table identifier from the PCITEM_MISSING, PCITEM_STRING, or PCITEM_INDEX record. */
+ void importWebPrTable( SequenceInputStream& rStrm, sal_Int32 nRecId );
+
+ /** Imports connection settings from the DBQUERY record. */
+ void importDbQuery( BiffInputStream& rStrm );
+ /** Imports connection settings from the QUERYTABLESETTINGS record. */
+ void importQueryTableSettings( BiffInputStream& rStrm );
+
+ /** Returns the unique connection identifier. */
+ inline sal_Int32 getConnectionId() const { return maModel.mnId; }
+ /** Returns the source data type of the connection. */
+ inline sal_Int32 getConnectionType() const { return maModel.mnType; }
+ /** Returns read-only access to the connection model data. */
+ const ConnectionModel& getModel() const { return maModel; }
+
+private:
+ ConnectionModel maModel;
+};
+
+typedef ::boost::shared_ptr< Connection > ConnectionRef;
+
+// ============================================================================
+
+class ConnectionsBuffer : public WorkbookHelper
+{
+public:
+ explicit ConnectionsBuffer( const WorkbookHelper& rHelper );
+
+ /** Creates a new empty connection. */
+ Connection& createConnection();
+ /** Creates a new empty connection with a valid but unused identifier. */
+ Connection& createConnectionWithId();
+
+ /** Maps all connections by their identifier. */
+ void finalizeImport();
+
+ /** Returns a data connection by its unique identifier. */
+ ConnectionRef getConnection( sal_Int32 nConnId ) const;
+
+private:
+ /** Inserts the passed connection into the map according to its identifier. */
+ void insertConnectionToMap( const ConnectionRef& rxConnection );
+
+private:
+ typedef RefVector< Connection > ConnectionVector;
+ typedef RefMap< sal_Int32, Connection > ConnectionMap;
+
+ ConnectionVector maConnections;
+ ConnectionMap maConnectionsById;
+ sal_Int32 mnUnusedId;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/connectionsfragment.hxx b/oox/inc/oox/xls/connectionsfragment.hxx
new file mode 100644
index 000000000000..5a9a9085c6c5
--- /dev/null
+++ b/oox/inc/oox/xls/connectionsfragment.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_CONNECTIONSFRAGMENT_HXX
+#define OOX_XLS_CONNECTIONSFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+class Connection;
+
+// ============================================================================
+
+class ConnectionContext : public WorkbookContextBase
+{
+public:
+ explicit ConnectionContext( WorkbookFragmentBase& rParent, Connection& rConnection );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ Connection& mrConnection;
+};
+
+// ============================================================================
+
+class ConnectionsFragment : public WorkbookFragmentBase
+{
+public:
+ explicit ConnectionsFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+ virtual void finalizeImport();
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/defnamesbuffer.hxx b/oox/inc/oox/xls/defnamesbuffer.hxx
new file mode 100644
index 000000000000..5374c47f6a07
--- /dev/null
+++ b/oox/inc/oox/xls/defnamesbuffer.hxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_DEFINEDNAMESBUFFER_HXX
+#define OOX_XLS_DEFINEDNAMESBUFFER_HXX
+
+#include "oox/xls/formulabase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XNamedRange; }
+} } }
+
+namespace oox {
+namespace xls {
+
+class FormulaContext;
+class BiffInputStreamPos;
+
+// ============================================================================
+
+// codes for built-in names
+const sal_Unicode BIFF_DEFNAME_CONSOLIDATEAREA = '\x00';
+const sal_Unicode BIFF_DEFNAME_AUTOOPEN = '\x01'; // Sheet macro executed when workbook is opened.
+const sal_Unicode BIFF_DEFNAME_AUTOCLOSE = '\x02'; // Sheet macro executed when workbook is closed.
+const sal_Unicode BIFF_DEFNAME_EXTRACT = '\x03'; // Filter output destination for advanced filter.
+const sal_Unicode BIFF_DEFNAME_DATABASE = '\x04';
+const sal_Unicode BIFF_DEFNAME_CRITERIA = '\x05'; // Filter criteria source range for advanced filter.
+const sal_Unicode BIFF_DEFNAME_PRINTAREA = '\x06'; // Print ranges.
+const sal_Unicode BIFF_DEFNAME_PRINTTITLES = '\x07'; // Rows/columns repeated on each page when printing.
+const sal_Unicode BIFF_DEFNAME_RECORDER = '\x08';
+const sal_Unicode BIFF_DEFNAME_DATAFORM = '\x09';
+const sal_Unicode BIFF_DEFNAME_AUTOACTIVATE = '\x0A'; // Sheet macro executed when workbook is activated.
+const sal_Unicode BIFF_DEFNAME_AUTODEACTIVATE = '\x0B'; // Sheet macro executed when workbook is deactivated.
+const sal_Unicode BIFF_DEFNAME_SHEETTITLE = '\x0C';
+const sal_Unicode BIFF_DEFNAME_FILTERDATABASE = '\x0D'; // Sheet range autofilter or advanced filter works on.
+const sal_Unicode BIFF_DEFNAME_UNKNOWN = '\x0E';
+
+// ============================================================================
+
+struct DefinedNameModel
+{
+ ::rtl::OUString maName; /// The original name.
+ ::rtl::OUString maFormula; /// The formula string.
+ sal_Int32 mnSheet; /// Sheet index for local names.
+ sal_Int32 mnFuncGroupId; /// Function group identifier.
+ bool mbMacro; /// True = Macro name (VBA or sheet macro).
+ bool mbFunction; /// True = function, false = command.
+ bool mbVBName; /// True = VBA macro, false = sheet macro.
+ bool mbHidden; /// True = name hidden in UI.
+
+ explicit DefinedNameModel();
+};
+
+// ============================================================================
+
+/** Base class for defined names and external names. */
+class DefinedNameBase : public WorkbookHelper
+{
+public:
+ explicit DefinedNameBase( const WorkbookHelper& rHelper );
+
+ /** Returns the original name as imported from or exported to the file. */
+ inline const ::rtl::OUString& getModelName() const { return maModel.maName; }
+ /** Returns the name as used in the Calc document. */
+ inline const ::rtl::OUString& getCalcName() const { return maCalcName; }
+
+ /** Returns the original name as imported from or exported to the file. */
+ const ::rtl::OUString& getUpcaseModelName() const;
+ /** Returns an Any with a SingleReference or ComplexReference, or an empty Any. */
+ ::com::sun::star::uno::Any getReference( const ::com::sun::star::table::CellAddress& rBaseAddress ) const;
+
+protected:
+ /** Imports the OOXML formula string, using the passed formula context. */
+ void importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet );
+ /** Imports the BIFF12 formula, using the passed formula context. */
+ void importBiff12Formula( FormulaContext& rContext, sal_Int16 nBaseSheet, SequenceInputStream& rStrm );
+ /** Imports the BIFF formula, using the passed formula context. */
+ void importBiffFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 );
+
+ /** Tries to convert the passed token sequence to a SingleReference or ComplexReference. */
+ void extractReference( const ApiTokenSequence& rTokens );
+
+protected:
+ DefinedNameModel maModel; /// Model data for this defined name.
+ mutable ::rtl::OUString maUpModelName; /// Model name converted to uppercase ASCII.
+ ::rtl::OUString maCalcName; /// Final name used in the Calc document.
+ ::com::sun::star::uno::Any maRefAny; /// Single cell/range reference.
+};
+
+// ============================================================================
+
+class DefinedName : public DefinedNameBase
+{
+public:
+ explicit DefinedName( const WorkbookHelper& rHelper );
+
+ /** Sets the attributes for this defined name from the passed attribute set. */
+ void importDefinedName( const AttributeList& rAttribs );
+ /** Sets the formula string from the body of the definedName element. */
+ void setFormula( const ::rtl::OUString& rFormula );
+ /** Imports the defined name from a DEFINEDNAME record in the passed stream. */
+ void importDefinedName( SequenceInputStream& rStrm );
+ /** Imports the defined name from a DEFINEDNAME record in the passed BIFF stream. */
+ void importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet );
+
+ /** Creates a defined name in the Calc document. */
+ void createNameObject();
+ /** Converts the formula string or BIFF token array for this defined name. */
+ void convertFormula();
+
+ /** Returns true, if this defined name is global in the document. */
+ inline bool isGlobalName() const { return mnCalcSheet < 0; }
+ /** Returns true, if this defined name is a special builtin name. */
+ inline bool isBuiltinName() const { return mcBuiltinId != BIFF_DEFNAME_UNKNOWN; }
+ /** Returns true, if this defined name is a macro function call. */
+ inline bool isMacroFunction() const { return maModel.mbMacro && maModel.mbFunction; }
+ /** Returns true, if this defined name is a reference to a VBA macro. */
+ inline bool isVBName() const { return maModel.mbMacro && maModel.mbVBName; }
+
+ /** Returns the 0-based sheet index for local names, or -1 for global names. */
+ inline sal_Int16 getLocalCalcSheet() const { return mnCalcSheet; }
+ /** Returns the built-in identifier of the defined name. */
+ inline sal_Unicode getBuiltinId() const { return mcBuiltinId; }
+ /** Returns the token index used in API token arrays (com.sun.star.sheet.FormulaToken). */
+ inline sal_Int32 getTokenIndex() const { return mnTokenIndex; }
+ /** Tries to resolve the defined name to an absolute cell range. */
+ bool getAbsoluteRange( ::com::sun::star::table::CellRangeAddress& orRange ) const;
+
+private:
+ /** Imports the OOXML or BIFF12 formula, using the passed formula context. */
+ void implImportOoxFormula( FormulaContext& rContext );
+ /** Imports the BIFF formula, using the passed formula context. */
+ void implImportBiffFormula( FormulaContext& rContext );
+
+private:
+ typedef ::std::auto_ptr< StreamDataSequence > StreamDataSeqPtr;
+ typedef ::std::auto_ptr< BiffInputStreamPos > BiffStreamPosPtr;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange >
+ mxNamedRange; /// XNamedRange interface of the defined name.
+ sal_Int32 mnTokenIndex; /// Name index used in API token array.
+ sal_Int16 mnCalcSheet; /// Calc sheet index for sheet-local names.
+ sal_Unicode mcBuiltinId; /// Identifier for built-in defined names.
+ StreamDataSeqPtr mxFormula; /// Formula data for BIFF12 import.
+ BiffStreamPosPtr mxBiffStrm; /// Cached BIFF stream for formula import.
+ sal_uInt16 mnFmlaSize; /// Cached BIFF formula size for formula import.
+};
+
+typedef ::boost::shared_ptr< DefinedName > DefinedNameRef;
+
+// ============================================================================
+
+class DefinedNamesBuffer : public WorkbookHelper
+{
+public:
+ explicit DefinedNamesBuffer( const WorkbookHelper& rHelper );
+
+ /** Sets the sheet index for local names (BIFF2-BIFF4 only). */
+ void setLocalCalcSheet( sal_Int16 nCalcSheet );
+
+ /** Imports a defined name from the passed attribute set. */
+ DefinedNameRef importDefinedName( const AttributeList& rAttribs );
+ /** Imports a defined name from a DEFINEDNAME record in the passed stream. */
+ void importDefinedName( SequenceInputStream& rStrm );
+ /** Imports a defined name from a DEFINEDNAME record in the passed BIFF stream. */
+ void importDefinedName( BiffInputStream& rStrm );
+
+ /** Creates all defined names in the document. */
+ void finalizeImport();
+
+ /** Returns a defined name by zero-based index (order of appearence). */
+ DefinedNameRef getByIndex( sal_Int32 nIndex ) const;
+ /** Returns a defined name by token index (index in XDefinedNames container). */
+ DefinedNameRef getByTokenIndex( sal_Int32 nIndex ) const;
+ /** Returns a defined name by its model name.
+ @param nSheet The sheet index for local names or -1 for global names.
+ If no local name is found, tries to find a matching global name.
+ @return Reference to the defined name or empty reference. */
+ DefinedNameRef getByModelName( const ::rtl::OUString& rModelName, sal_Int16 nCalcSheet = -1 ) const;
+ /** Returns a built-in defined name by its built-in identifier.
+ @param nSheet The sheet index of the built-in name.
+ @return Reference to the defined name or empty reference. */
+ DefinedNameRef getByBuiltinId( sal_Unicode cBuiltinId, sal_Int16 nCalcSheet ) const;
+
+private:
+ DefinedNameRef createDefinedName();
+
+private:
+ typedef ::std::pair< sal_Int16, ::rtl::OUString > SheetNameKey;
+ typedef ::std::pair< sal_Int16, sal_Unicode > BuiltinKey;
+
+ typedef RefVector< DefinedName > DefNameVector;
+ typedef RefMap< SheetNameKey, DefinedName > DefNameNameMap;
+ typedef RefMap< BuiltinKey, DefinedName > DefNameBuiltinMap;
+ typedef RefMap< sal_Int32, DefinedName > DefNameTokenIdMap;
+
+ DefNameVector maDefNames; /// List of all defined names in insertion order.
+ DefNameNameMap maModelNameMap; /// Maps all defined names by sheet index and model name.
+ DefNameBuiltinMap maBuiltinMap; /// Maps all defined names by sheet index and built-in identifier.
+ DefNameTokenIdMap maTokenIdMap; /// Maps all defined names by API token index.
+ sal_Int16 mnCalcSheet; /// Current sheet index for BIFF2-BIFF4 names (always sheet-local).
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/drawingfragment.hxx b/oox/inc/oox/xls/drawingfragment.hxx
new file mode 100644
index 000000000000..0d3360323a94
--- /dev/null
+++ b/oox/inc/oox/xls/drawingfragment.hxx
@@ -0,0 +1,326 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_DRAWINGFRAGMENT_HXX
+#define OOX_XLS_DRAWINGFRAGMENT_HXX
+
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/ole/axcontrol.hxx"
+#include "oox/ole/vbaproject.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmldrawingfragment.hxx"
+#include "oox/vml/vmltextbox.hxx"
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox { namespace ole {
+ struct AxFontData;
+ class AxMorphDataModelBase;
+} }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+// DrawingML
+// ============================================================================
+
+/** Absolute position in spreadsheet (in EMUs) independent from cells. */
+struct AnchorPosModel : public ::oox::drawingml::EmuPoint
+{
+ inline explicit AnchorPosModel() : ::oox::drawingml::EmuPoint( -1, -1 ) {}
+ inline bool isValid() const { return (X >= 0) && (Y >= 0); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Absolute size in spreadsheet (in EMUs). */
+struct AnchorSizeModel : public ::oox::drawingml::EmuSize
+{
+ inline explicit AnchorSizeModel() : ::oox::drawingml::EmuSize( -1, -1 ) {}
+ inline bool isValid() const { return (Width >= 0) && (Height >= 0); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Position in spreadsheet (cell position and offset inside cell in EMUs). */
+struct AnchorCellModel
+{
+ sal_Int32 mnCol; /// Column index.
+ sal_Int32 mnRow; /// Row index.
+ sal_Int64 mnColOffset; /// X offset in column mnCol (EMUs).
+ sal_Int64 mnRowOffset; /// Y offset in row mnRow (EMUs).
+
+ explicit AnchorCellModel();
+ inline bool isValid() const { return (mnCol >= 0) && (mnRow >= 0); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Application-specific client data of a shape. */
+struct AnchorClientDataModel
+{
+ bool mbLocksWithSheet;
+ bool mbPrintsWithSheet;
+
+ explicit AnchorClientDataModel();
+};
+
+// ============================================================================
+
+/** Contains the position of a shape in the spreadsheet. Supports different
+ shape anchor modes (absolute, one-cell, two-cell). */
+class ShapeAnchor : public WorksheetHelper
+{
+public:
+ explicit ShapeAnchor( const WorksheetHelper& rHelper );
+
+ /** Imports the shape anchor (one of the elements xdr:absoluteAnchor, xdr:oneCellAnchor, xdr:twoCellAnchor). */
+ void importAnchor( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Imports the absolute anchor position from the xdr:pos element. */
+ void importPos( const AttributeList& rAttribs );
+ /** Imports the absolute anchor size from the xdr:ext element. */
+ void importExt( const AttributeList& rAttribs );
+ /** Imports the shape client data from the xdr:clientData element. */
+ void importClientData( const AttributeList& rAttribs );
+ /** Sets an attribute of the cell-dependent anchor position from xdr:from and xdr:to elements. */
+ void setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const ::rtl::OUString& rValue );
+ /** Imports and converts the VML specific client anchor. */
+ void importVmlAnchor( const ::rtl::OUString& rAnchor );
+
+ /** Returns true, if the anchor contains valid position and size settings. */
+ bool isValidAnchor() const;
+
+ /** Calculates the resulting shape anchor in 1/100 mm. */
+ ::com::sun::star::awt::Rectangle
+ calcApiLocation(
+ const ::com::sun::star::awt::Size& rApiSheetSize,
+ const AnchorSizeModel& rEmuSheetSize ) const;
+
+ /** Calculates the resulting shape anchor in EMUs. */
+ ::com::sun::star::awt::Rectangle
+ calcEmuLocation( const AnchorSizeModel& rEmuSheetSize ) const;
+
+private:
+ enum AnchorType { ANCHOR_ABSOLUTE, ANCHOR_ONECELL, ANCHOR_TWOCELL, ANCHOR_VML, ANCHOR_INVALID };
+
+ AnchorType meType; /// Type of this shape anchor.
+ AnchorPosModel maPos; /// Top-left position, if anchor is of type absolute.
+ AnchorSizeModel maSize; /// Anchor size, if anchor is not of type two-cell.
+ AnchorCellModel maFrom; /// Top-left position, if anchor is not of type absolute.
+ AnchorCellModel maTo; /// Bottom-right position, if anchor is of type two-cell.
+ AnchorClientDataModel maClientData; /// Shape client data.
+ sal_Int32 mnEditAs; /// Anchor mode as shown in the UI.
+};
+
+typedef ::boost::shared_ptr< ShapeAnchor > ShapeAnchorRef;
+
+// ============================================================================
+
+class ShapeMacroAttacher : public ::oox::ole::VbaMacroAttacherBase
+{
+public:
+ explicit ShapeMacroAttacher( const ::rtl::OUString& rMacroName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape );
+
+private:
+ virtual void attachMacro( const ::rtl::OUString& rMacroUrl );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxShape;
+};
+
+// ============================================================================
+
+class Shape : public ::oox::drawingml::Shape, public WorksheetHelper
+{
+public:
+ explicit Shape(
+ const WorksheetHelper& rHelper,
+ const AttributeList& rAttribs,
+ const sal_Char* pcServiceName = 0 );
+
+protected:
+ virtual void finalizeXShape(
+ ::oox::core::XmlFilterBase& rFilter,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes );
+
+private:
+ ::rtl::OUString maMacroName;
+};
+
+// ============================================================================
+
+/** Context handler for creation of shapes embedded in group shapes. */
+class GroupShapeContext : public ::oox::drawingml::ShapeGroupContext, public WorksheetHelper
+{
+public:
+ explicit GroupShapeContext(
+ ::oox::core::ContextHandler& rParent,
+ const WorksheetHelper& rHelper,
+ const ::oox::drawingml::ShapePtr& rxParentShape,
+ const ::oox::drawingml::ShapePtr& rxShape );
+
+ static ::oox::core::ContextHandlerRef
+ createShapeContext(
+ ::oox::core::ContextHandler& rParent,
+ const WorksheetHelper& rHelper,
+ sal_Int32 nElement,
+ const AttributeList& rAttribs,
+ const ::oox::drawingml::ShapePtr& rxParentShape,
+ ::oox::drawingml::ShapePtr* pxShape = 0 );
+
+protected:
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext(
+ sal_Int32 nElement,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
+ throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+};
+
+// ============================================================================
+
+/** Fragment handler for a complete sheet drawing. */
+class DrawingFragment : public WorksheetFragmentBase
+{
+public:
+ explicit DrawingFragment(
+ const WorksheetHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
+ mxDrawPage; /// Drawing page of this sheet.
+ ::com::sun::star::awt::Size maApiSheetSize; /// Sheet size in 1/100 mm.
+ AnchorSizeModel maEmuSheetSize; /// Sheet size in EMU.
+ ::oox::drawingml::ShapePtr mxShape; /// Current top-level shape.
+ ShapeAnchorRef mxAnchor; /// Current anchor of top-level shape.
+};
+
+// ============================================================================
+// VML
+// ============================================================================
+
+class VmlControlMacroAttacher : public ::oox::ole::VbaMacroAttacherBase
+{
+public:
+ explicit VmlControlMacroAttacher( const ::rtl::OUString& rMacroName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >& rxCtrlFormIC,
+ sal_Int32 nCtrlIndex, sal_Int32 nCtrlType, sal_Int32 nDropStyle );
+
+private:
+ virtual void attachMacro( const ::rtl::OUString& rMacroUrl );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > mxCtrlFormIC;
+ sal_Int32 mnCtrlIndex;
+ sal_Int32 mnCtrlType;
+ sal_Int32 mnDropStyle;
+};
+
+// ============================================================================
+
+class VmlDrawing : public ::oox::vml::Drawing, public WorksheetHelper
+{
+public:
+ explicit VmlDrawing( const WorksheetHelper& rHelper );
+
+ /** Returns the drawing shape for a cell note at the specified position. */
+ const ::oox::vml::ShapeBase* getNoteShape( const ::com::sun::star::table::CellAddress& rPos ) const;
+
+ /** Filters cell note shapes. */
+ virtual bool isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const;
+
+ /** Returns additional base names for automatic shape name creation. */
+ virtual ::rtl::OUString getShapeBaseName( const ::oox::vml::ShapeBase& rShape ) const;
+
+ /** Calculates the shape rectangle from a cell anchor string. */
+ virtual bool convertClientAnchor(
+ ::com::sun::star::awt::Rectangle& orShapeRect,
+ const ::rtl::OUString& rShapeAnchor ) const;
+
+ /** Creates a UNO control shape for legacy drawing controls. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createAndInsertClientXShape(
+ const ::oox::vml::ShapeBase& rShape,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::com::sun::star::awt::Rectangle& rShapeRect ) const;
+
+ /** Updates the bounding box covering all shapes of this drawing. */
+ virtual void notifyXShapeInserted(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
+ const ::com::sun::star::awt::Rectangle& rShapeRect,
+ const ::oox::vml::ShapeBase& rShape, bool bGroupChild );
+
+private:
+ /** Converts the passed VML textbox text color to an OLE color. */
+ sal_uInt32 convertControlTextColor( const ::rtl::OUString& rTextColor ) const;
+ /** Converts the passed VML textbox font to an ActiveX form control font. */
+ void convertControlFontData(
+ ::oox::ole::AxFontData& rAxFontData, sal_uInt32& rnOleTextColor,
+ const ::oox::vml::TextFontModel& rFontModel ) const;
+ /** Converts the caption, the font settings, and the horizontal alignment
+ from the passed VML textbox to ActiveX form control settings. */
+ void convertControlText(
+ ::oox::ole::AxFontData& rAxFontData, sal_uInt32& rnOleTextColor, ::rtl::OUString& rCaption,
+ const ::oox::vml::TextBox* pTextBox, sal_Int32 nTextHAlign ) const;
+ /** Converts the passed VML shape background formatting to ActiveX control formatting. */
+ void convertControlBackground(
+ ::oox::ole::AxMorphDataModelBase& rAxModel,
+ const ::oox::vml::ShapeBase& rShape ) const;
+
+private:
+ ::oox::ole::ControlConverter maControlConv;
+ ::oox::vml::TextFontModel maListBoxFont;
+};
+
+// ============================================================================
+
+class VmlDrawingFragment : public ::oox::vml::DrawingFragment, public WorksheetHelper
+{
+public:
+ explicit VmlDrawingFragment(
+ const WorksheetHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual void finalizeImport();
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/excelchartconverter.hxx b/oox/inc/oox/xls/excelchartconverter.hxx
new file mode 100644
index 000000000000..a46d484f2074
--- /dev/null
+++ b/oox/inc/oox/xls/excelchartconverter.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_EXCELCHARTCONVERTER_HXX
+#define OOX_XLS_EXCELCHARTCONVERTER_HXX
+
+#include "oox/drawingml/chart/chartconverter.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class ExcelChartConverter : public ::oox::drawingml::chart::ChartConverter, public WorkbookHelper
+{
+public:
+ explicit ExcelChartConverter( const WorkbookHelper& rHelper );
+ virtual ~ExcelChartConverter();
+
+ /** Creates an external data provider that is able to use spreadsheet data. */
+ virtual void createDataProvider(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc );
+
+ /** Creates a data sequence from the passed formula. */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >
+ createDataSequence(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >& rxDataProvider,
+ const ::oox::drawingml::chart::DataSequenceModel& rDataSeq );
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/excelfilter.hxx b/oox/inc/oox/xls/excelfilter.hxx
new file mode 100644
index 000000000000..789cbc99cb07
--- /dev/null
+++ b/oox/inc/oox/xls/excelfilter.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_EXCELFILTER_HXX
+#define OOX_XLS_EXCELFILTER_HXX
+
+#include "oox/core/binaryfilterbase.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+
+namespace oox {
+namespace xls {
+
+class WorkbookData;
+
+// ============================================================================
+
+class ExcelFilterBase
+{
+public:
+ void registerWorkbookData( WorkbookData& rData );
+ WorkbookData& getWorkbookData() const;
+ void unregisterWorkbookData();
+
+protected:
+ explicit ExcelFilterBase();
+ virtual ~ExcelFilterBase();
+
+private:
+ WorkbookData* mpData;
+};
+
+// ============================================================================
+
+class ExcelFilter : public ::oox::core::XmlFilterBase, public ExcelFilterBase
+{
+public:
+ explicit ExcelFilter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ~ExcelFilter();
+
+ virtual bool importDocument() throw();
+ virtual bool exportDocument() throw();
+
+ virtual const ::oox::drawingml::Theme* getCurrentTheme() const;
+ virtual ::oox::vml::Drawing* getVmlDrawing();
+ virtual const ::oox::drawingml::table::TableStyleListPtr getTableStyles();
+ virtual ::oox::drawingml::chart::ChartConverter& getChartConverter();
+
+private:
+ virtual GraphicHelper* implCreateGraphicHelper() const;
+ virtual ::oox::ole::VbaProject* implCreateVbaProject() const;
+ virtual ::rtl::OUString implGetImplementationName() const;
+};
+
+// ============================================================================
+
+class ExcelBiffFilter : public ::oox::core::BinaryFilterBase, public ExcelFilterBase
+{
+public:
+ explicit ExcelBiffFilter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ~ExcelBiffFilter();
+
+ virtual bool importDocument() throw();
+ virtual bool exportDocument() throw();
+
+private:
+ virtual GraphicHelper* implCreateGraphicHelper() const;
+ virtual ::oox::ole::VbaProject* implCreateVbaProject() const;
+ virtual ::rtl::OUString implGetImplementationName() const;
+};
+
+// ============================================================================
+
+class ExcelVbaProjectFilter : public ExcelBiffFilter
+{
+public:
+ explicit ExcelVbaProjectFilter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual bool importDocument() throw();
+ virtual bool exportDocument() throw();
+
+private:
+ virtual ::rtl::OUString implGetImplementationName() const;
+};
+ // ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/excelhandlers.hxx b/oox/inc/oox/xls/excelhandlers.hxx
new file mode 100644
index 000000000000..864f5f9a9e44
--- /dev/null
+++ b/oox/inc/oox/xls/excelhandlers.hxx
@@ -0,0 +1,307 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_EXCELHANDLERS_HXX
+#define OOX_XLS_EXCELHANDLERS_HXX
+
+#include "oox/core/fragmenthandler2.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+// ============================================================================
+
+/** Context handler derived from the WorkbookHelper helper class.
+
+ Used to import contexts in global workbook fragments.
+ */
+class WorkbookContextBase : public ::oox::core::ContextHandler2, public WorkbookHelper
+{
+public:
+ template< typename ParentType >
+ explicit WorkbookContextBase( ParentType& rParent );
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename ParentType >
+WorkbookContextBase::WorkbookContextBase( ParentType& rParent ) :
+ ::oox::core::ContextHandler2( rParent ),
+ WorkbookHelper( rParent )
+{
+}
+
+// ============================================================================
+
+/** Context handler derived from the WorksheetHelper helper class.
+
+ Used to import contexts in sheet fragments.
+ */
+class WorksheetContextBase : public ::oox::core::ContextHandler2, public WorksheetHelperRoot
+{
+public:
+ template< typename ParentType >
+ explicit WorksheetContextBase(
+ ParentType& rParent,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+
+ template< typename ParentType >
+ explicit WorksheetContextBase( ParentType& rParent );
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename ParentType >
+WorksheetContextBase::WorksheetContextBase( ParentType& rParent,
+ const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ ::oox::core::ContextHandler2( rParent ),
+ WorksheetHelperRoot( rParent, rxProgressBar, eSheetType, nSheet )
+{
+}
+
+template< typename ParentType >
+WorksheetContextBase::WorksheetContextBase( ParentType& rParent ) :
+ ::oox::core::ContextHandler2( rParent ),
+ WorksheetHelperRoot( rParent )
+{
+}
+
+// ============================================================================
+
+/** Fragment handler derived from the WorkbookHelper helper class.
+
+ Used to import global workbook fragments.
+ */
+class WorkbookFragmentBase : public ::oox::core::FragmentHandler2, public WorkbookHelper
+{
+public:
+ explicit WorkbookFragmentBase(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+};
+
+// ============================================================================
+
+/** Fragment handler derived from the WorksheetHelper helper class.
+
+ Used to import sheet fragments.
+ */
+class WorksheetFragmentBase : public ::oox::core::FragmentHandler2, public WorksheetHelperRoot
+{
+public:
+ explicit WorksheetFragmentBase(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+
+ explicit WorksheetFragmentBase(
+ const WorksheetHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Base class for all BIFF context handlers.
+
+ Derived handlers have to implement the importRecord() function that has to
+ import the record the passed BIFF input stream currently points to.
+ */
+class BiffContextHandler
+{
+public:
+ virtual ~BiffContextHandler();
+
+ /** Derived classes have to implement importing the current record. */
+ virtual void importRecord( BiffInputStream& rStrm ) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Context handler derived from the WorkbookHelper helper class.
+
+ Used to import contexts in global workbook fragments.
+ */
+class BiffWorkbookContextBase : public BiffContextHandler, public WorkbookHelper
+{
+protected:
+ explicit BiffWorkbookContextBase( const WorkbookHelper& rHelper );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Context handler derived from the WorksheetHelper helper class.
+
+ Used to import contexts in sheet fragments.
+ */
+class BiffWorksheetContextBase : public BiffContextHandler, public WorksheetHelperRoot
+{
+protected:
+ explicit BiffWorksheetContextBase(
+ const WorkbookHelper& rHelper,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+
+ explicit BiffWorksheetContextBase( const WorksheetHelper& rHelper );
+};
+
+// ============================================================================
+
+/** An enumeration for all types of fragments in a BIFF workbook stream. */
+enum BiffFragmentType
+{
+ BIFF_FRAGMENT_GLOBALS, /// Workbook globals fragment.
+ BIFF_FRAGMENT_WORKSHEET, /// Worksheet fragment.
+ BIFF_FRAGMENT_CHARTSHEET, /// Chart sheet fragment.
+ BIFF_FRAGMENT_MACROSHEET, /// Macro sheet fragment.
+ BIFF_FRAGMENT_MODULESHEET, /// BIFF5 VB module fragment.
+ BIFF_FRAGMENT_EMPTYSHEET, /// Sheet fragment of unsupported type.
+ BIFF_FRAGMENT_WORKSPACE, /// BIFF4 workspace/workbook globals.
+ BIFF_FRAGMENT_UNKNOWN /// Unknown fragment/error.
+};
+
+// ----------------------------------------------------------------------------
+
+class BiffFragmentHandler
+{
+public:
+ /** Opens the stream with the passed full name. */
+ explicit BiffFragmentHandler(
+ const ::oox::core::FilterBase& rFilter,
+ const ::rtl::OUString& rStrmName );
+
+ virtual ~BiffFragmentHandler();
+
+ /** Imports the fragment, returns true, if EOF record has been reached. */
+ virtual bool importFragment() = 0;
+
+protected:
+ /** Returns the BIFF input stream of this fragment. */
+ inline BiffInputStream& getInputStream() { return *mxBiffStrm; }
+
+ /** Starts a new fragment in a workbbok stream and returns the fragment type.
+
+ The passed stream must point before a BOF record. The function will
+ try to start the next record and read the contents of the BOF record,
+ if extant.
+
+ @return Fragment type according to the imported BOF record.
+ */
+ BiffFragmentType startFragment( BiffType eBiff );
+
+ /** Starts a new fragment at a specific position in the workbbok stream and
+ returns the fragment type.
+
+ The passed record handle must specify the stream position of the BOF
+ record of the fragment substream. The function will try to start the
+ next record and read the contents of the BOF record, if extant.
+
+ @return Fragment type according to the imported BOF record.
+ */
+ BiffFragmentType startFragment( BiffType eBiff, sal_Int64 nRecHandle );
+
+ /** Skips the current fragment up to its trailing EOF record.
+
+ Skips all records until next EOF record. When this function returns,
+ stream points to the EOF record, and the next call of startNextRecord()
+ at the stream will start the record following the EOF record.
+
+ Embedded fragments enclosed in BOF/EOF records (e.g. embedded chart
+ objects) are skipped correctly.
+
+ @return True = stream points to the EOF record of the current fragment.
+ */
+ bool skipFragment();
+
+private:
+ typedef ::boost::shared_ptr< BinaryXInputStream > XInputStreamRef;
+ typedef ::boost::shared_ptr< BiffInputStream > BiffInputStreamRef;
+
+ XInputStreamRef mxXInStrm;
+ BiffInputStreamRef mxBiffStrm;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Fragment handler derived from the WorkbookHelper helper class.
+
+ Used to import global workbook fragments.
+ */
+class BiffWorkbookFragmentBase : public BiffFragmentHandler, public WorkbookHelper
+{
+protected:
+ explicit BiffWorkbookFragmentBase(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rStrmName,
+ bool bCloneDecoder = false );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Fragment handler derived from the WorksheetHelper helper class.
+
+ Used to import sheet fragments.
+ */
+class BiffWorksheetFragmentBase : public BiffFragmentHandler, public WorksheetHelperRoot
+{
+protected:
+ explicit BiffWorksheetFragmentBase(
+ const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Special fragment handler for worksheets that have to be skipped.
+ */
+class BiffSkipWorksheetFragment : public BiffWorksheetFragmentBase
+{
+public:
+ explicit BiffSkipWorksheetFragment(
+ const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar,
+ sal_Int16 nSheet );
+
+ virtual bool importFragment();
+};
+
+// ============================================================================
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/excelvbaproject.hxx b/oox/inc/oox/xls/excelvbaproject.hxx
new file mode 100755
index 000000000000..96dabd08b5d7
--- /dev/null
+++ b/oox/inc/oox/xls/excelvbaproject.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_EXCELVBAPROJECT_HXX
+#define OOX_XLS_EXCELVBAPROJECT_HXX
+
+#include "oox/ole/vbaproject.hxx"
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XSpreadsheetDocument; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Special implementation of the VBA project for the Excel filters. */
+class OOX_DLLPUBLIC ExcelVbaProject : public ::oox::ole::VbaProject
+{
+public:
+ explicit ExcelVbaProject(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& rxDocument );
+
+protected:
+ /** Adds dummy modules for sheets without imported code name. */
+ virtual void prepareImport();
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
+ mxDocument;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/externallinkbuffer.hxx b/oox/inc/oox/xls/externallinkbuffer.hxx
new file mode 100644
index 000000000000..c616a2b97e97
--- /dev/null
+++ b/oox/inc/oox/xls/externallinkbuffer.hxx
@@ -0,0 +1,404 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_EXTERNALLINKBUFFER_HXX
+#define OOX_XLS_EXTERNALLINKBUFFER_HXX
+
+#include <com/sun/star/sheet/ExternalLinkInfo.hpp>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { struct DDEItemInfo; }
+ namespace sheet { class XDDELink; }
+ namespace sheet { class XExternalDocLink; }
+ namespace sheet { class XExternalSheetCache; }
+} } }
+
+namespace oox { namespace core {
+ class Relations;
+} }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+struct ExternalNameModel
+{
+ bool mbBuiltIn; /// Name is a built-in name.
+ bool mbNotify; /// Notify application on data change.
+ bool mbPreferPic; /// Picture link.
+ bool mbStdDocName; /// Name is the StdDocumentName for DDE.
+ bool mbOleObj; /// Name is an OLE object.
+ bool mbIconified; /// Iconified object link.
+
+ explicit ExternalNameModel();
+};
+
+// ============================================================================
+
+class ExternalLink;
+
+class ExternalName : public DefinedNameBase
+{
+public:
+ explicit ExternalName( const ExternalLink& rParentLink );
+
+ /** Appends the passed value to the result set. */
+ template< typename Type >
+ inline void appendResultValue( const Type& rValue )
+ { if( maCurrIt != maResults.end() ) (*maCurrIt++) <<= rValue; }
+
+ /** Imports the definedName element. */
+ void importDefinedName( const AttributeList& rAttribs );
+ /** Imports the ddeItem element describing an item of a DDE link. */
+ void importDdeItem( const AttributeList& rAttribs );
+ /** Imports the values element containing the size of the DDE result matrix. */
+ void importValues( const AttributeList& rAttribs );
+ /** Imports the oleItem element describing an object of an OLE link. */
+ void importOleItem( const AttributeList& rAttribs );
+
+ /** Imports the EXTERNALNAME record containing the name (only). */
+ void importExternalName( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALNAMEFLAGS record containing the settings of an external name. */
+ void importExternalNameFlags( SequenceInputStream& rStrm );
+ /** Imports the DDEITEMVALUES record containing the size of the DDE result matrix. */
+ void importDdeItemValues( SequenceInputStream& rStrm );
+ /** Imports the DDEITEM_BOOL record containing a boolean value in a link result. */
+ void importDdeItemBool( SequenceInputStream& rStrm );
+ /** Imports the DDEITEM_DOUBLE record containing a double value in a link result. */
+ void importDdeItemDouble( SequenceInputStream& rStrm );
+ /** Imports the DDEITEM_ERROR record containing an error code in a link result. */
+ void importDdeItemError( SequenceInputStream& rStrm );
+ /** Imports the DDEITEM_STRING record containing a string in a link result. */
+ void importDdeItemString( SequenceInputStream& rStrm );
+
+ /** Imports the EXTERNALNAME record from the passed stream. */
+ void importExternalName( BiffInputStream& rStrm );
+
+ /** Returns true, if the name refers to an OLE object. */
+ inline bool isOleObject() const { return maExtNameModel.mbOleObj; }
+
+#if 0
+ /** Returns the sheet cache index if this is a sheet-local external name. */
+ sal_Int32 getSheetCacheIndex() const;
+#endif
+
+ /** Returns the DDE item info needed by the XML formula parser. */
+ bool getDdeItemInfo(
+ ::com::sun::star::sheet::DDEItemInfo& orItemInfo ) const;
+
+ /** Returns the complete DDE link data of this DDE item. */
+ bool getDdeLinkData(
+ ::rtl::OUString& orDdeServer,
+ ::rtl::OUString& orDdeTopic,
+ ::rtl::OUString& orDdeItem );
+
+private:
+ /** Tries to convert the passed token sequence to an ExternalReference. */
+ void extractExternalReference( const ApiTokenSequence& rTokens );
+ /** Sets the size of the result matrix. */
+ void setResultSize( sal_Int32 nColumns, sal_Int32 nRows );
+
+private:
+ typedef Matrix< ::com::sun::star::uno::Any > ResultMatrix;
+
+ const ExternalLink& mrParentLink; /// External link this name belongs to.
+ ExternalNameModel maExtNameModel; /// Additional name data.
+ ResultMatrix maResults; /// DDE/OLE link results.
+ ResultMatrix::iterator maCurrIt; /// Current position in result matrix.
+ sal_uInt32 mnStorageId; /// OLE storage identifier (BIFF).
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDDELink >
+ mxDdeLink; /// Interface of a DDE link.
+ bool mbDdeLinkCreated; /// True = already tried to create the DDE link.
+};
+
+typedef ::boost::shared_ptr< ExternalName > ExternalNameRef;
+
+// ============================================================================
+
+/** Contains indexes for a range of sheets in the spreadsheet document. */
+class LinkSheetRange
+{
+public:
+ inline explicit LinkSheetRange() { setDeleted(); }
+ inline explicit LinkSheetRange( sal_Int32 nFirst, sal_Int32 nLast ) { setRange( nFirst, nLast ); }
+ inline explicit LinkSheetRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast ) { setExternalRange( nDocLink, nFirst, nLast ); }
+
+ /** Sets this struct to deleted state. */
+ void setDeleted();
+ /** Sets this struct to "use current sheet" state. */
+ void setSameSheet();
+ /** Sets the passed absolute sheet range to the members of this struct. */
+ void setRange( sal_Int32 nFirst, sal_Int32 nLast );
+ /** Sets the passed external sheet cache range to the members of this struct. */
+ void setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast );
+
+ /** Returns true, if the sheet indexes are valid and different. */
+ inline bool isDeleted() const { return mnFirst < 0; }
+ /** Returns true, if the sheet range points to an external document. */
+ inline bool isExternal() const { return !isDeleted() && (meType == LINKSHEETRANGE_EXTERNAL); }
+ /** Returns true, if the sheet indexes are valid and different. */
+ inline bool isSameSheet() const { return meType == LINKSHEETRANGE_SAMESHEET; }
+ /** Returns true, if the sheet indexes are valid and different. */
+ inline bool is3dRange() const { return (0 <= mnFirst) && (mnFirst < mnLast); }
+
+ inline sal_Int32 getDocLinkIndex() const { return mnDocLink; }
+ inline sal_Int32 getFirstSheet() const { return mnFirst; }
+ inline sal_Int32 getLastSheet() const { return mnLast; }
+
+private:
+ enum LinkSheetRangeType
+ {
+ LINKSHEETRANGE_INTERNAL, /// Sheet range in the own document.
+ LINKSHEETRANGE_EXTERNAL, /// Sheet range in an external document.
+ LINKSHEETRANGE_SAMESHEET /// Current sheet depending on context.
+ };
+
+ LinkSheetRangeType meType; /// Link sheet range type.
+ sal_Int32 mnDocLink; /// Document link token index for external links.
+ sal_Int32 mnFirst; /// Index of the first sheet or index of first external sheet cache.
+ sal_Int32 mnLast; /// Index of the last sheet or index of last external sheet cache.
+};
+
+// ============================================================================
+
+enum ExternalLinkType
+{
+ LINKTYPE_SELF, /// Link refers to the current workbook.
+ LINKTYPE_SAME, /// Link refers to the current sheet.
+ LINKTYPE_INTERNAL, /// Link refers to a sheet in the own workbook.
+ LINKTYPE_EXTERNAL, /// Link refers to an external spreadsheet document.
+ LINKTYPE_ANALYSIS, /// Link refers to the Analysis add-in.
+ LINKTYPE_LIBRARY, /// Link refers to an external add-in.
+ LINKTYPE_DDE, /// DDE link.
+ LINKTYPE_OLE, /// OLE link.
+ LINKTYPE_MAYBE_DDE_OLE, /// Could be DDE or OLE link (BIFF only).
+ LINKTYPE_UNKNOWN /// Unknown or unsupported link type.
+};
+
+// ----------------------------------------------------------------------------
+
+class ExternalLink : public WorkbookHelper
+{
+public:
+ explicit ExternalLink( const WorkbookHelper& rHelper );
+
+ /** Imports the externalReference element containing the relation identifier. */
+ void importExternalReference( const AttributeList& rAttribs );
+ /** Imports the externalBook element describing an externally linked document. */
+ void importExternalBook( const ::oox::core::Relations& rRelations, const AttributeList& rAttribs );
+ /** Imports the sheetName element containing the sheet name in an externally linked document. */
+ void importSheetName( const AttributeList& rAttribs );
+ /** Imports the definedName element describing an external name. */
+ void importDefinedName( const AttributeList& rAttribs );
+ /** Imports the ddeLink element describing a DDE link. */
+ void importDdeLink( const AttributeList& rAttribs );
+ /** Imports the ddeItem element describing an item of a DDE link. */
+ ExternalNameRef importDdeItem( const AttributeList& rAttribs );
+ /** Imports the oleLink element describing an OLE link. */
+ void importOleLink( const ::oox::core::Relations& rRelations, const AttributeList& rAttribs );
+ /** Imports the oleItem element describing an object of an OLE link. */
+ ExternalNameRef importOleItem( const AttributeList& rAttribs );
+
+ /** Imports the EXTERNALBOOK record describing an externally linked document, DDE link, or OLE link. */
+ void importExternalBook( const ::oox::core::Relations& rRelations, SequenceInputStream& rStrm );
+ /** Imports the EXTSHEETNAMES record containing the sheet names in an externally linked document. */
+ void importExtSheetNames( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALNAME record describing an external name. */
+ ExternalNameRef importExternalName( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALREF record from the passed stream. */
+ void importExternalRef( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALSELF record from the passed stream. */
+ void importExternalSelf( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALSAME record from the passed stream. */
+ void importExternalSame( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALADDIN record from the passed stream. */
+ void importExternalAddin( SequenceInputStream& rStrm );
+
+ /** Imports the EXTERNSHEET record from the passed stream. */
+ void importExternSheet( BiffInputStream& rStrm );
+ /** Imports the EXTERNALBOOK record from the passed stream. */
+ void importExternalBook( BiffInputStream& rStrm );
+ /** Imports the EXTERNALNAME record from the passed stream. */
+ void importExternalName( BiffInputStream& rStrm );
+
+ /** Sets the link type to 'self reference'. */
+ inline void setSelfLinkType() { meLinkType = LINKTYPE_SELF; }
+
+ /** Returns the type of this external link. */
+ inline ExternalLinkType getLinkType() const { return meLinkType; }
+ /** Returns true, if the link refers to the current workbook. */
+ inline bool isInternalLink() const { return (meLinkType == LINKTYPE_SELF) || (meLinkType == LINKTYPE_INTERNAL); }
+
+ /** Returns the relation identifier for the external link fragment. */
+ inline const ::rtl::OUString& getRelId() const { return maRelId; }
+ /** Returns the class name of this external link. */
+ inline const ::rtl::OUString& getClassName() const { return maClassName; }
+ /** Returns the target URL of this external link. */
+ inline const ::rtl::OUString& getTargetUrl() const { return maTargetUrl; }
+ /** Returns the link info needed by the XML formula parser. */
+ ::com::sun::star::sheet::ExternalLinkInfo getLinkInfo() const;
+
+ /** Returns the type of the external library if this is a library link. */
+ FunctionLibraryType getFuncLibraryType() const;
+
+ /** Returns the internal Calc sheet index or for the passed sheet. */
+ sal_Int16 getCalcSheetIndex( sal_Int32 nTabId = 0 ) const;
+
+ /** Returns the token index of the external document. */
+ sal_Int32 getDocumentLinkIndex() const;
+ /** Returns the external sheet cache index or for the passed sheet. */
+ sal_Int32 getSheetCacheIndex( sal_Int32 nTabId = 0 ) const;
+ /** Returns the sheet cache of the external sheet with the passed index. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache >
+ getSheetCache( sal_Int32 nTabId ) const;
+
+ /** Returns the internal sheet range or range of external sheet caches for the passed sheet range (BIFF only). */
+ void getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const;
+
+ /** Returns the external name with the passed zero-based index. */
+ ExternalNameRef getNameByIndex( sal_Int32 nIndex ) const;
+
+private:
+ void setExternalTargetUrl( const ::rtl::OUString& rTargetUrl, const ::rtl::OUString& rTargetType );
+ void setDdeOleTargetUrl( const ::rtl::OUString& rClassName, const ::rtl::OUString& rTargetUrl, ExternalLinkType eLinkType );
+ void parseExternalReference( const ::oox::core::Relations& rRelations, const ::rtl::OUString& rRelId );
+ ::rtl::OUString parseBiffTargetUrl( const ::rtl::OUString& rBiffTargetUrl );
+
+ /** Creates an external locument link and the sheet cache for the passed sheet name. */
+ void insertExternalSheet( const ::rtl::OUString& rSheetName );
+
+ ExternalNameRef createExternalName();
+
+private:
+ typedef ::std::vector< sal_Int16 > Int16Vector;
+ typedef ::std::vector< sal_Int32 > Int32Vector;
+ typedef RefVector< ExternalName > ExternalNameVector;
+
+ ExternalLinkType meLinkType; /// Type of this link object.
+ FunctionLibraryType meFuncLibType; /// Type of the function library, if link type is LINKTYPE_LIBRARY.
+ ::rtl::OUString maRelId; /// Relation identifier for the external link fragment.
+ ::rtl::OUString maClassName; /// DDE service, OLE class name.
+ ::rtl::OUString maTargetUrl; /// Target link, DDE topic, OLE target.
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalDocLink >
+ mxDocLink; /// Interface for an external document.
+ Int16Vector maCalcSheets; /// Internal sheet indexes.
+ Int32Vector maSheetCaches; /// External sheet cache indexes.
+ ExternalNameVector maExtNames; /// Defined names in external document.
+};
+
+typedef ::boost::shared_ptr< ExternalLink > ExternalLinkRef;
+
+// ============================================================================
+
+/** Represents a REF entry in the BIFF12 EXTERNALSHEETS or in the BIFF8
+ EXTERNSHEET record.
+
+ This struct is used to map ref identifiers to external books (BIFF12:
+ EXTERNALREF records, BIFF8: EXTERNALBOOK records), and provides sheet
+ indexes into the sheet list of the external document.
+ */
+struct RefSheetsModel
+{
+ sal_Int32 mnExtRefId; /// Zero-based index into list of external documents.
+ sal_Int32 mnTabId1; /// Zero-based index to first sheet in external document.
+ sal_Int32 mnTabId2; /// Zero-based index to last sheet in external document.
+
+ explicit RefSheetsModel();
+
+ void readBiff12Data( SequenceInputStream& rStrm );
+ void readBiff8Data( BiffInputStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+class ExternalLinkBuffer : public WorkbookHelper
+{
+public:
+ explicit ExternalLinkBuffer( const WorkbookHelper& rHelper );
+
+ /** Imports the externalReference element containing . */
+ ExternalLinkRef importExternalReference( const AttributeList& rAttribs );
+
+ /** Imports the EXTERNALREF record from the passed stream. */
+ ExternalLinkRef importExternalRef( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALSELF record from the passed stream. */
+ void importExternalSelf( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALSAME record from the passed stream. */
+ void importExternalSame( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALADDIN record from the passed stream. */
+ void importExternalAddin( SequenceInputStream& rStrm );
+ /** Imports the EXTERNALSHEETS record from the passed stream. */
+ void importExternalSheets( SequenceInputStream& rStrm );
+
+ /** Imports the EXTERNSHEET record from the passed stream. */
+ ExternalLinkRef importExternSheet( BiffInputStream& rStrm );
+ /** Imports the EXTERNALBOOK record from the passed stream. */
+ ExternalLinkRef importExternalBook( BiffInputStream& rStrm );
+ /** Imports the EXTERNALNAME record from the passed stream. */
+ void importExternalName( BiffInputStream& rStrm );
+ /** Imports the BIFF8 EXTERNSHEET record from the passed stream. */
+ void importExternSheet8( BiffInputStream& rStrm );
+
+ /** Returns the sequence of link infos needed by the XML formula parser. */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::ExternalLinkInfo >
+ getLinkInfos() const;
+
+ /** Returns the external link for the passed reference identifier. */
+ ExternalLinkRef getExternalLink( sal_Int32 nRefId, bool bUseRefSheets = true ) const;
+
+ /** Returns the sheet range for the specified reference (BIFF2-BIFF5 only). */
+ LinkSheetRange getSheetRange( sal_Int32 nRefId, sal_Int16 nTabId1, sal_Int16 nTabId2 ) const;
+ /** Returns the sheet range for the specified reference (BIFF8 only). */
+ LinkSheetRange getSheetRange( sal_Int32 nRefId ) const;
+
+private:
+ /** Creates a new external link and inserts it into the list of links. */
+ ExternalLinkRef createExternalLink();
+
+ /** Returns the specified sheet indexes for a reference identifier. */
+ const RefSheetsModel* getRefSheets( sal_Int32 nRefId ) const;
+
+private:
+ typedef RefVector< ExternalLink > ExternalLinkVec;
+ typedef ::std::vector< RefSheetsModel > RefSheetsModelVec;
+
+ ExternalLinkRef mxSelfRef; /// Implicit self reference at index 0.
+ ExternalLinkVec maLinks; /// List of link structures for all kinds of links.
+ ExternalLinkVec maExtLinks; /// Real external links needed for formula parser.
+ RefSheetsModelVec maRefSheets; /// Sheet indexes for reference ids.
+ bool mbUseRefSheets; /// True = use maRefSheets list (BIFF12 only).
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/externallinkfragment.hxx b/oox/inc/oox/xls/externallinkfragment.hxx
new file mode 100644
index 000000000000..0e1f293d2444
--- /dev/null
+++ b/oox/inc/oox/xls/externallinkfragment.hxx
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_EXTERNALLINKFRAGMENT_HXX
+#define OOX_XLS_EXTERNALLINKFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+class ExternalLink;
+
+// ============================================================================
+// ============================================================================
+
+/** This class implements importing the sheetData element in external sheets.
+
+ The sheetData element embedded in the externalBook element contains cached
+ cells from externally linked sheets.
+ */
+class ExternalSheetDataContext : public WorkbookContextBase
+{
+public:
+ explicit ExternalSheetDataContext(
+ WorkbookFragmentBase& rFragment,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache >& rxSheetCache );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+private:
+ /** Imports cell settings from a c element. */
+ void importCell( const AttributeList& rAttribs );
+
+ /** Imports the EXTCELL_BLANK from the passed stream. */
+ void importExtCellBlank( SequenceInputStream& rStrm );
+ /** Imports the EXTCELL_BOOL from the passed stream. */
+ void importExtCellBool( SequenceInputStream& rStrm );
+ /** Imports the EXTCELL_DOUBLE from the passed stream. */
+ void importExtCellDouble( SequenceInputStream& rStrm );
+ /** Imports the EXTCELL_ERROR from the passed stream. */
+ void importExtCellError( SequenceInputStream& rStrm );
+ /** Imports the EXTCELL_STRING from the passed stream. */
+ void importExtCellString( SequenceInputStream& rStrm );
+
+ /** Sets the passed cell value to the current position in the sheet cache. */
+ void setCellValue( const ::com::sun::star::uno::Any& rValue );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache >
+ mxSheetCache; /// The sheet cache used to store external cell values.
+ ::com::sun::star::table::CellAddress maCurrPos; /// Position of current cell.
+ sal_Int32 mnCurrType; /// Data type of current cell.
+};
+
+// ============================================================================
+
+class ExternalLinkFragment : public WorkbookFragmentBase
+{
+public:
+ explicit ExternalLinkFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath,
+ ExternalLink& rExtLink );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+
+private:
+ ::oox::core::ContextHandlerRef createSheetDataContext( sal_Int32 nSheetId );
+
+private:
+ ExternalLink& mrExtLink;
+ ExternalNameRef mxExtName;
+ ::rtl::OUString maResultValue;
+ sal_Int32 mnResultType;
+};
+
+// ============================================================================
+// ============================================================================
+
+class BiffExternalSheetDataContext : public BiffWorkbookContextBase
+{
+public:
+ explicit BiffExternalSheetDataContext( const WorkbookHelper& rHelper, bool bImportDefNames );
+ virtual ~BiffExternalSheetDataContext();
+
+ /** Tries to import a record related to external links and defined names. */
+ virtual void importRecord( BiffInputStream& rStrm );
+
+private:
+ void importExternSheet( BiffInputStream& rStrm );
+ void importExternalBook( BiffInputStream& rStrm );
+ void importExternalName( BiffInputStream& rStrm );
+ void importXct( BiffInputStream& rStrm );
+ void importCrn( BiffInputStream& rStrm );
+ void importDefinedName( BiffInputStream& rStrm );
+
+ /** Sets the passed cell value to the passed position in the sheet cache. */
+ void setCellValue( const BinAddress& rBinAddr, const ::com::sun::star::uno::Any& rValue );
+
+private:
+ ExternalLinkRef mxExtLink; /// Current external link.
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache >
+ mxSheetCache; /// The sheet cache used to store external cell values.
+ bool mbImportDefNames;
+};
+
+// ============================================================================
+
+class BiffExternalLinkFragment : public BiffWorkbookFragmentBase
+{
+public:
+ explicit BiffExternalLinkFragment( const BiffWorkbookFragmentBase& rParent );
+
+ /** Imports all records related to external links. */
+ virtual bool importFragment();
+};
+
+// ============================================================================
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/formulabase.hxx b/oox/inc/oox/xls/formulabase.hxx
new file mode 100644
index 000000000000..013e63f3bf30
--- /dev/null
+++ b/oox/inc/oox/xls/formulabase.hxx
@@ -0,0 +1,924 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_FORMULABASE_HXX
+#define OOX_XLS_FORMULABASE_HXX
+
+#include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
+#include <com/sun/star/sheet/FormulaToken.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/addressconverter.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XFormulaOpCodeMapper; }
+ namespace sheet { class XFormulaParser; }
+ namespace sheet { class XFormulaTokens; }
+} } }
+
+namespace oox { template< typename Type > class Matrix; }
+
+namespace oox {
+namespace xls {
+
+// Constants ==================================================================
+
+const size_t BIFF_TOKARR_MAXLEN = 4096; /// Maximum size of a token array.
+
+// token class flags ----------------------------------------------------------
+
+const sal_uInt8 BIFF_TOKCLASS_MASK = 0x60;
+const sal_uInt8 BIFF_TOKCLASS_NONE = 0x00; /// 00-1F: Base tokens.
+const sal_uInt8 BIFF_TOKCLASS_REF = 0x20; /// 20-3F: Reference class tokens.
+const sal_uInt8 BIFF_TOKCLASS_VAL = 0x40; /// 40-5F: Value class tokens.
+const sal_uInt8 BIFF_TOKCLASS_ARR = 0x60; /// 60-7F: Array class tokens.
+
+const sal_uInt8 BIFF_TOKFLAG_INVALID = 0x80; /// This bit must be null for a valid token identifier.
+
+// base token identifiers -----------------------------------------------------
+
+const sal_uInt8 BIFF_TOKID_MASK = 0x1F;
+
+const sal_uInt8 BIFF_TOKID_NONE = 0x00; /// Placeholder for invalid token id.
+const sal_uInt8 BIFF_TOKID_EXP = 0x01; /// Array or shared formula reference.
+const sal_uInt8 BIFF_TOKID_TBL = 0x02; /// Multiple operation reference.
+const sal_uInt8 BIFF_TOKID_ADD = 0x03; /// Addition operator.
+const sal_uInt8 BIFF_TOKID_SUB = 0x04; /// Subtraction operator.
+const sal_uInt8 BIFF_TOKID_MUL = 0x05; /// Multiplication operator.
+const sal_uInt8 BIFF_TOKID_DIV = 0x06; /// Division operator.
+const sal_uInt8 BIFF_TOKID_POWER = 0x07; /// Power operator.
+const sal_uInt8 BIFF_TOKID_CONCAT = 0x08; /// String concatenation operator.
+const sal_uInt8 BIFF_TOKID_LT = 0x09; /// Less than operator.
+const sal_uInt8 BIFF_TOKID_LE = 0x0A; /// Less than or equal operator.
+const sal_uInt8 BIFF_TOKID_EQ = 0x0B; /// Equal operator.
+const sal_uInt8 BIFF_TOKID_GE = 0x0C; /// Greater than or equal operator.
+const sal_uInt8 BIFF_TOKID_GT = 0x0D; /// Greater than operator.
+const sal_uInt8 BIFF_TOKID_NE = 0x0E; /// Not equal operator.
+const sal_uInt8 BIFF_TOKID_ISECT = 0x0F; /// Intersection operator.
+const sal_uInt8 BIFF_TOKID_LIST = 0x10; /// List operator.
+const sal_uInt8 BIFF_TOKID_RANGE = 0x11; /// Range operator.
+const sal_uInt8 BIFF_TOKID_UPLUS = 0x12; /// Unary plus.
+const sal_uInt8 BIFF_TOKID_UMINUS = 0x13; /// Unary minus.
+const sal_uInt8 BIFF_TOKID_PERCENT = 0x14; /// Percent sign.
+const sal_uInt8 BIFF_TOKID_PAREN = 0x15; /// Parentheses.
+const sal_uInt8 BIFF_TOKID_MISSARG = 0x16; /// Missing argument.
+const sal_uInt8 BIFF_TOKID_STR = 0x17; /// String constant.
+const sal_uInt8 BIFF_TOKID_NLR = 0x18; /// Natural language reference (NLR).
+const sal_uInt8 BIFF_TOKID_ATTR = 0x19; /// Special attribute.
+const sal_uInt8 BIFF_TOKID_SHEET = 0x1A; /// Start of a sheet reference (BIFF2-BIFF4).
+const sal_uInt8 BIFF_TOKID_ENDSHEET = 0x1B; /// End of a sheet reference (BIFF2-BIFF4).
+const sal_uInt8 BIFF_TOKID_ERR = 0x1C; /// Error constant.
+const sal_uInt8 BIFF_TOKID_BOOL = 0x1D; /// Boolean constant.
+const sal_uInt8 BIFF_TOKID_INT = 0x1E; /// Integer constant.
+const sal_uInt8 BIFF_TOKID_NUM = 0x1F; /// Floating-point constant.
+
+// base identifiers of classified tokens --------------------------------------
+
+const sal_uInt8 BIFF_TOKID_ARRAY = 0x00; /// Array constant.
+const sal_uInt8 BIFF_TOKID_FUNC = 0x01; /// Function, fixed number of arguments.
+const sal_uInt8 BIFF_TOKID_FUNCVAR = 0x02; /// Function, variable number of arguments.
+const sal_uInt8 BIFF_TOKID_NAME = 0x03; /// Defined name.
+const sal_uInt8 BIFF_TOKID_REF = 0x04; /// 2D cell reference.
+const sal_uInt8 BIFF_TOKID_AREA = 0x05; /// 2D area reference.
+const sal_uInt8 BIFF_TOKID_MEMAREA = 0x06; /// Constant reference subexpression.
+const sal_uInt8 BIFF_TOKID_MEMERR = 0x07; /// Deleted reference subexpression.
+const sal_uInt8 BIFF_TOKID_MEMNOMEM = 0x08; /// Constant reference subexpression without result.
+const sal_uInt8 BIFF_TOKID_MEMFUNC = 0x09; /// Variable reference subexpression.
+const sal_uInt8 BIFF_TOKID_REFERR = 0x0A; /// Deleted 2D cell reference.
+const sal_uInt8 BIFF_TOKID_AREAERR = 0x0B; /// Deleted 2D area reference.
+const sal_uInt8 BIFF_TOKID_REFN = 0x0C; /// Relative 2D cell reference (in names).
+const sal_uInt8 BIFF_TOKID_AREAN = 0x0D; /// Relative 2D area reference (in names).
+const sal_uInt8 BIFF_TOKID_MEMAREAN = 0x0E; /// Reference subexpression (in names).
+const sal_uInt8 BIFF_TOKID_MEMNOMEMN = 0x0F; /// Reference subexpression (in names) without result.
+const sal_uInt8 BIFF_TOKID_FUNCCE = 0x18;
+const sal_uInt8 BIFF_TOKID_NAMEX = 0x19; /// External reference.
+const sal_uInt8 BIFF_TOKID_REF3D = 0x1A; /// 3D cell reference.
+const sal_uInt8 BIFF_TOKID_AREA3D = 0x1B; /// 3D area reference.
+const sal_uInt8 BIFF_TOKID_REFERR3D = 0x1C; /// Deleted 3D cell reference.
+const sal_uInt8 BIFF_TOKID_AREAERR3D = 0x1D; /// Deleted 3D area reference
+
+// specific token constants ---------------------------------------------------
+
+const sal_uInt8 BIFF_TOK_ARRAY_DOUBLE = 0; /// Double value in an array.
+const sal_uInt8 BIFF_TOK_ARRAY_STRING = 1; /// String value in an array.
+const sal_uInt8 BIFF_TOK_ARRAY_BOOL = 2; /// Boolean value in an array.
+const sal_uInt8 BIFF_TOK_ARRAY_ERROR = 4; /// Error code in an array.
+
+const sal_uInt8 BIFF_TOK_BOOL_FALSE = 0; /// FALSE value of a tBool token.
+const sal_uInt8 BIFF_TOK_BOOL_TRUE = 1; /// TRUE value of a tBool token.
+
+const sal_uInt8 BIFF_TOK_ATTR_VOLATILE = 0x01; /// Volatile function.
+const sal_uInt8 BIFF_TOK_ATTR_IF = 0x02; /// Start of true condition in IF function.
+const sal_uInt8 BIFF_TOK_ATTR_CHOOSE = 0x04; /// Jump array of CHOOSE function.
+const sal_uInt8 BIFF_TOK_ATTR_SKIP = 0x08; /// Skip tokens.
+const sal_uInt8 BIFF_TOK_ATTR_SUM = 0x10; /// SUM function with one parameter.
+const sal_uInt8 BIFF_TOK_ATTR_ASSIGN = 0x20; /// BASIC style assignment.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE = 0x40; /// Spaces in formula representation.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_VOLATILE = 0x41; /// Leading spaces and volatile formula.
+const sal_uInt8 BIFF_TOK_ATTR_IFERROR = 0x80; /// Start of condition in IFERROR function (BIFF12 only).
+
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP = 0x00; /// Spaces before next token.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR = 0x01; /// Line breaks before next token.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_OPEN = 0x02; /// Spaces before opening parenthesis.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR_OPEN = 0x03; /// Line breaks before opening parenthesis.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_CLOSE = 0x04; /// Spaces before closing parenthesis.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR_CLOSE = 0x05; /// Line breaks before closing parenthesis.
+const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_PRE = 0x06; /// Spaces before formula (BIFF3).
+
+const sal_uInt16 BIFF_TOK_FUNCVAR_CMD = 0x8000; /// Macro command.
+const sal_uInt16 BIFF_TOK_FUNCVAR_FUNCIDMASK = 0x7FFF; /// Mask for function/command index.
+const sal_uInt8 BIFF_TOK_FUNCVAR_CMDPROMPT = 0x80; /// User prompt for macro commands.
+const sal_uInt8 BIFF_TOK_FUNCVAR_COUNTMASK = 0x7F; /// Mask for parameter count.
+
+const sal_uInt16 BIFF12_TOK_REF_COLMASK = 0x3FFF; /// Mask to extract column from reference (BIFF12).
+const sal_Int32 BIFF12_TOK_REF_ROWMASK = 0xFFFFF; /// Mask to extract row from reference (BIFF12).
+const sal_uInt16 BIFF12_TOK_REF_COLREL = 0x4000; /// True = column is relative (BIFF12).
+const sal_uInt16 BIFF12_TOK_REF_ROWREL = 0x8000; /// True = row is relative (BIFF12).
+
+const sal_uInt16 BIFF_TOK_REF_COLMASK = 0x00FF; /// Mask to extract BIFF8 column from reference.
+const sal_uInt16 BIFF_TOK_REF_ROWMASK = 0x3FFF; /// Mask to extract BIFF2-BIFF5 row from reference.
+const sal_uInt16 BIFF_TOK_REF_COLREL = 0x4000; /// True = column is relative.
+const sal_uInt16 BIFF_TOK_REF_ROWREL = 0x8000; /// True = row is relative.
+
+const sal_uInt16 BIFF12_TOK_TABLE_COLUMN = 0x0001; /// Table reference: Single column.
+const sal_uInt16 BIFF12_TOK_TABLE_COLRANGE = 0x0002; /// Table reference: Range of columns.
+const sal_uInt16 BIFF12_TOK_TABLE_ALL = 0x0004; /// Table reference: Special [#All] range.
+const sal_uInt16 BIFF12_TOK_TABLE_HEADERS = 0x0008; /// Table reference: Special [#Headers] range.
+const sal_uInt16 BIFF12_TOK_TABLE_DATA = 0x0010; /// Table reference: Special [#Data] range.
+const sal_uInt16 BIFF12_TOK_TABLE_TOTALS = 0x0020; /// Table reference: Special [#Totals] range.
+const sal_uInt16 BIFF12_TOK_TABLE_THISROW = 0x0040; /// Table reference: Special [#This Row] range.
+const sal_uInt16 BIFF12_TOK_TABLE_SP_BRACKETS = 0x0080; /// Table reference: Spaces in outer brackets.
+const sal_uInt16 BIFF12_TOK_TABLE_SP_SEP = 0x0100; /// Table reference: Spaces after separators.
+const sal_uInt16 BIFF12_TOK_TABLE_ROW = 0x0200; /// Table reference: Single row.
+const sal_uInt16 BIFF12_TOK_TABLE_CELL = 0x0400; /// Table reference: Single cell.
+
+const sal_uInt8 BIFF_TOK_NLR_ERR = 0x01; /// NLR: Invalid/deleted.
+const sal_uInt8 BIFF_TOK_NLR_ROWR = 0x02; /// NLR: Row index.
+const sal_uInt8 BIFF_TOK_NLR_COLR = 0x03; /// NLR: Column index.
+const sal_uInt8 BIFF_TOK_NLR_ROWV = 0x06; /// NLR: Value in row.
+const sal_uInt8 BIFF_TOK_NLR_COLV = 0x07; /// NLR: Value in column.
+const sal_uInt8 BIFF_TOK_NLR_RANGE = 0x0A; /// NLR: Range.
+const sal_uInt8 BIFF_TOK_NLR_SRANGE = 0x0B; /// Stacked NLR: Range.
+const sal_uInt8 BIFF_TOK_NLR_SROWR = 0x0C; /// Stacked NLR: Row index.
+const sal_uInt8 BIFF_TOK_NLR_SCOLR = 0x0D; /// Stacked NLR: Column index.
+const sal_uInt8 BIFF_TOK_NLR_SROWV = 0x0E; /// Stacked NLR: Value in row.
+const sal_uInt8 BIFF_TOK_NLR_SCOLV = 0x0F; /// Stacked NLR: Value in column.
+const sal_uInt8 BIFF_TOK_NLR_RANGEERR = 0x10; /// NLR: Invalid/deleted range.
+const sal_uInt8 BIFF_TOK_NLR_SXNAME = 0x1D; /// NLR: Pivot table name.
+const sal_uInt16 BIFF_TOK_NLR_REL = 0x8000; /// True = NLR is relative.
+const sal_uInt16 BIFF_TOK_NLR_MASK = 0x3FFF; /// Mask to extract BIFF8 column from NLR.
+
+const sal_uInt32 BIFF_TOK_NLR_ADDREL = 0x80000000; /// NLR relative (in appended data).
+const sal_uInt32 BIFF_TOK_NLR_ADDMASK = 0x3FFFFFFF; /// Mask for number of appended ranges.
+
+// function constants ---------------------------------------------------------
+
+const sal_uInt8 OOX_MAX_PARAMCOUNT = 255; /// Maximum parameter count for OOXML/BIFF12 files.
+const sal_uInt8 BIFF_MAX_PARAMCOUNT = 30; /// Maximum parameter count for BIFF2-BIFF8 files.
+
+const sal_uInt16 BIFF_FUNC_IF = 1; /// Function identifier of the IF function.
+const sal_uInt16 BIFF_FUNC_SUM = 4; /// Function identifier of the SUM function.
+const sal_uInt16 BIFF_FUNC_TRUE = 34; /// Function identifier of the TRUE function.
+const sal_uInt16 BIFF_FUNC_FALSE = 35; /// Function identifier of the FALSE function.
+const sal_uInt16 BIFF_FUNC_ROWS = 76; /// Function identifier of the ROWS function.
+const sal_uInt16 BIFF_FUNC_COLUMNS = 77; /// Function identifier of the COLUMNS function.
+const sal_uInt16 BIFF_FUNC_OFFSET = 78; /// Function identifier of the OFFSET function.
+const sal_uInt16 BIFF_FUNC_EXTERNCALL = 255; /// BIFF function id of the EXTERN.CALL function.
+const sal_uInt16 BIFF_FUNC_FLOOR = 285; /// Function identifier of the FLOOR function.
+const sal_uInt16 BIFF_FUNC_CEILING = 288; /// Function identifier of the CEILING function.
+const sal_uInt16 BIFF_FUNC_HYPERLINK = 359; /// Function identifier of the HYPERLINK function.
+const sal_uInt16 BIFF_FUNC_WEEKNUM = 465; /// Function identifier of the WEEKNUM function.
+
+// reference helpers ==========================================================
+
+/** A 2D formula cell reference struct with relative flags. */
+struct BinSingleRef2d
+{
+ sal_Int32 mnCol; /// Column index.
+ sal_Int32 mnRow; /// Row index.
+ bool mbColRel; /// True = relative column reference.
+ bool mbRowRel; /// True = relative row reference.
+
+ explicit BinSingleRef2d();
+
+ void setBiff12Data( sal_uInt16 nCol, sal_Int32 nRow, bool bRelativeAsOffset );
+ void setBiff2Data( sal_uInt8 nCol, sal_uInt16 nRow, bool bRelativeAsOffset );
+ void setBiff8Data( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelativeAsOffset );
+
+ void readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset );
+ void readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
+ void readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A 2D formula cell range reference struct with relative flags. */
+struct BinComplexRef2d
+{
+ BinSingleRef2d maRef1; /// Start (top-left) cell address.
+ BinSingleRef2d maRef2; /// End (bottom-right) cell address.
+
+ void readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset );
+ void readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
+ void readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
+};
+
+// token vector, sequence =====================================================
+
+typedef ::com::sun::star::sheet::FormulaToken ApiToken;
+typedef ::com::sun::star::uno::Sequence< ApiToken > ApiTokenSequence;
+
+/** A vector of formula tokens with additional convenience functions. */
+class ApiTokenVector : public ::std::vector< ApiToken >
+{
+public:
+ explicit ApiTokenVector();
+
+ /** Appends a new token with the passed op-code, returns its data field. */
+ ::com::sun::star::uno::Any&
+ append( sal_Int32 nOpCode );
+
+ /** Appends a new token with the passed op-code and data. */
+ template< typename Type >
+ inline void append( sal_Int32 nOpCode, const Type& rData ) { append( nOpCode ) <<= rData; }
+};
+
+// token sequence iterator ====================================================
+
+/** Token sequence iterator that is able to skip space tokens. */
+class ApiTokenIterator
+{
+public:
+ explicit ApiTokenIterator( const ApiTokenSequence& rTokens, sal_Int32 nSpacesOpCode, bool bSkipSpaces );
+ /** Copy constructor that allows to change the skip spaces mode. */
+ explicit ApiTokenIterator( const ApiTokenIterator& rIter, bool bSkipSpaces );
+
+ inline bool is() const { return mpToken != mpTokenEnd; }
+ inline const ApiToken* get() const { return mpToken; }
+ inline const ApiToken* operator->() const { return mpToken; }
+ inline const ApiToken& operator*() const { return *mpToken; }
+
+ ApiTokenIterator& operator++();
+
+private:
+ void skipSpaces();
+
+private:
+ const ApiToken* mpToken; /// Pointer to current token of the token sequence.
+ const ApiToken* mpTokenEnd; /// Pointer behind last token of the token sequence.
+ const sal_Int32 mnSpacesOpCode; /// Op-code for whitespace tokens.
+ const bool mbSkipSpaces; /// true = Skip whitespace tokens.
+};
+
+// list of API op-codes =======================================================
+
+/** Contains all API op-codes needed to build formulas with tokens. */
+struct ApiOpCodes
+{
+ // special
+ sal_Int32 OPCODE_UNKNOWN; /// Internal: function name unknown to mapper.
+ sal_Int32 OPCODE_EXTERNAL; /// External function call (e.g. add-ins).
+ // formula structure
+ sal_Int32 OPCODE_PUSH; /// Op-code for common value operands.
+ sal_Int32 OPCODE_MISSING; /// Placeholder for a missing function parameter.
+ sal_Int32 OPCODE_SPACES; /// Spaces between other formula tokens.
+ sal_Int32 OPCODE_NAME; /// Index of a defined name.
+ sal_Int32 OPCODE_DBAREA; /// Index of a database area.
+ sal_Int32 OPCODE_NLR; /// Natural language reference.
+ sal_Int32 OPCODE_DDE; /// DDE link function.
+ sal_Int32 OPCODE_MACRO; /// Macro function call.
+ sal_Int32 OPCODE_BAD; /// Bad token (unknown name, formula error).
+ sal_Int32 OPCODE_NONAME; /// Function style #NAME? error.
+ // separators
+ sal_Int32 OPCODE_OPEN; /// Opening parenthesis.
+ sal_Int32 OPCODE_CLOSE; /// Closing parenthesis.
+ sal_Int32 OPCODE_SEP; /// Function parameter separator.
+ // array separators
+ sal_Int32 OPCODE_ARRAY_OPEN; /// Opening brace for constant arrays.
+ sal_Int32 OPCODE_ARRAY_CLOSE; /// Closing brace for constant arrays.
+ sal_Int32 OPCODE_ARRAY_ROWSEP; /// Row separator in constant arrays.
+ sal_Int32 OPCODE_ARRAY_COLSEP; /// Column separator in constant arrays.
+ // unary operators
+ sal_Int32 OPCODE_PLUS_SIGN; /// Unary plus sign.
+ sal_Int32 OPCODE_MINUS_SIGN; /// Unary minus sign.
+ sal_Int32 OPCODE_PERCENT; /// Percent sign.
+ // binary operators
+ sal_Int32 OPCODE_ADD; /// Addition operator.
+ sal_Int32 OPCODE_SUB; /// Subtraction operator.
+ sal_Int32 OPCODE_MULT; /// Multiplication operator.
+ sal_Int32 OPCODE_DIV; /// Division operator.
+ sal_Int32 OPCODE_POWER; /// Power operator.
+ sal_Int32 OPCODE_CONCAT; /// String concatenation operator.
+ sal_Int32 OPCODE_EQUAL; /// Compare equal operator.
+ sal_Int32 OPCODE_NOT_EQUAL; /// Compare not equal operator.
+ sal_Int32 OPCODE_LESS; /// Compare less operator.
+ sal_Int32 OPCODE_LESS_EQUAL; /// Compare less or equal operator.
+ sal_Int32 OPCODE_GREATER; /// Compare greater operator.
+ sal_Int32 OPCODE_GREATER_EQUAL; /// Compare greater or equal operator.
+ sal_Int32 OPCODE_INTERSECT; /// Range intersection operator.
+ sal_Int32 OPCODE_LIST; /// Range list operator.
+ sal_Int32 OPCODE_RANGE; /// Range operator.
+};
+
+// Function parameter info ====================================================
+
+/** Enumerates validity modes for a function parameter. */
+enum FuncParamValidity
+{
+ FUNC_PARAM_NONE = 0, /// Default for an unspecified entry in a C-array.
+ FUNC_PARAM_REGULAR, /// Parameter supported by Calc and Excel.
+ FUNC_PARAM_CALCONLY, /// Parameter supported by Calc only.
+ FUNC_PARAM_EXCELONLY /// Parameter supported by Excel only.
+};
+
+/** Enumerates different types of token class conversion in function parameters. */
+enum FuncParamConversion
+{
+ FUNC_PARAMCONV_ORG, /// Use original class of current token.
+ FUNC_PARAMCONV_VAL, /// Convert tokens to VAL class.
+ FUNC_PARAMCONV_ARR, /// Convert tokens to ARR class.
+ FUNC_PARAMCONV_RPT, /// Repeat parent conversion in VALTYPE parameters.
+ FUNC_PARAMCONV_RPX, /// Repeat parent conversion in REFTYPE parameters.
+ FUNC_PARAMCONV_RPO /// Repeat parent conversion in operands of operators.
+};
+
+/** Structure that contains all needed information for a parameter in a
+ function.
+
+ The member meValid specifies which application supports the parameter. If
+ set to CALCONLY, import filters have to insert a default value for this
+ parameter, and export filters have to skip the parameter. If set to
+ EXCELONLY, import filters have to skip the parameter, and export filters
+ have to insert a default value for this parameter.
+
+ The member mbValType specifies whether the parameter requires tokens to be
+ of value type (VAL or ARR class).
+
+ If set to false, the parameter is called to be REFTYPE. Tokens with REF
+ default class can be inserted for the parameter (e.g. tAreaR tokens).
+
+ If set to true, the parameter is called to be VALTYPE. Tokens with REF
+ class need to be converted to VAL tokens first (e.g. tAreaR will be
+ converted to tAreaV), and further conversion is done according to this
+ new token class.
+
+ The member meConv specifies how to convert the current token class of the
+ token inserted for the parameter. If the token class is still REF this
+ means that the token has default REF class and the parameter is REFTYPE
+ (see member mbValType), the token will not be converted at all and remains
+ in REF class. Otherwise, token class conversion is depending on the actual
+ token class of the return value of the function containing this parameter.
+ The function may return REF class (tFuncR, tFuncVarR, tFuncCER), or it may
+ return VAL or ARR class (tFuncV, tFuncA, tFuncVarV, tFuncVarA, tFuncCEV,
+ tFuncCEA). Even if the function is able to return REF class, it may return
+ VAL or ARR class instead due to the VALTYPE data type of the parent
+ function parameter that calls the own function. Example: The INDIRECT
+ function returns REF class by default. But if called from a VALTYPE
+ function parameter, e.g. in the formula =ABS(INDIRECT("A1")), it returns
+ VAL or ARR class instead. Additionally, the repeating conversion types RPT
+ and RPX rely on the conversion executed for the function token class.
+
+ 1) ORG:
+ Use the original class of the token (VAL or ARR), regardless of any
+ conversion done for the function return class.
+
+ 2) VAL:
+ Convert ARR tokens to VAL class, regardless of any conversion done for
+ the function return class.
+
+ 3) ARR:
+ Convert VAL tokens to ARR class, regardless of any conversion done for
+ the function return class.
+
+ 4) RPT:
+ If the own function returns REF class (thus it is called from a REFTYPE
+ parameter, see above), and the parent conversion type (for the function
+ return class) was ORG, VAL, or ARR, ignore that conversion and always
+ use VAL conversion for the own token instead. If the parent conversion
+ type was RPT or RPX, repeat the conversion that would have been used if
+ the function would return value type.
+ If the own function returns value type (VAL or ARR class, see above),
+ and the parent conversion type (for the function return class) was ORG,
+ VAL, ARR, or RPT, repeat this conversion for the own token. If the
+ parent conversion type was RPX, always use ORG conversion type for the
+ own token instead.
+
+ 5) RPX:
+ This type of conversion only occurs in functions returning VAL class by
+ default. If the own token is value type, and the VAL return class of
+ the own function has been changed to ARR class (due to direct ARR
+ conversion, or due to ARR conversion repeated by RPT or RPX), set the
+ own token to ARR type. Otherwise use the original token type (VAL
+ conversion from parent parameter will not be repeated at all). If
+ nested functions have RPT or value-type RPX parameters, they will not
+ repeat this conversion type, but will use ORG conversion instead (see
+ description of RPT above).
+
+ 6) RPO:
+ This type of conversion is only used for the operands of all operators
+ (unary and binary arithmetic operators, comparison operators, and range
+ operators). It is not used for function parameters. On conversion, it
+ will be replaced by the last conversion type that was not the RPO
+ conversion. This leads to a slightly different behaviour than the RPT
+ conversion for operands in conjunction with a parent RPX conversion.
+ */
+struct FunctionParamInfo
+{
+ FuncParamValidity meValid; /// Parameter validity.
+ FuncParamConversion meConv; /// Token class conversion type.
+ bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
+};
+
+// function data ==============================================================
+
+/** This enumeration contains constants for all known external libraries
+ containing supported sheet functions. */
+enum FunctionLibraryType
+{
+ FUNCLIB_EUROTOOL, /// EuroTool add-in with EUROCONVERT function.
+ FUNCLIB_UNKNOWN /// Unknown library.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents information for a spreadsheet function.
+
+ The member mpParamInfos points to an array of type information structures
+ for all parameters of the function. The last initialized structure
+ describing a regular parameter (member meValid == EXC_PARAMVALID_ALWAYS) in
+ this array is used repeatedly for all following parameters supported by a
+ function.
+ */
+struct FunctionInfo
+{
+ ::rtl::OUString maOdfFuncName; /// ODF function name.
+ ::rtl::OUString maOoxFuncName; /// OOXML function name.
+ ::rtl::OUString maBiffMacroName; /// Expected macro name in EXTERN.CALL function.
+ ::rtl::OUString maExtProgName; /// Programmatic function name for external functions.
+ FunctionLibraryType meFuncLibType; /// The external library this function is part of.
+ sal_Int32 mnApiOpCode; /// API function opcode.
+ sal_uInt16 mnBiff12FuncId; /// BIFF12 function identifier.
+ sal_uInt16 mnBiffFuncId; /// BIFF2-BIFF8 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.
+ const FunctionParamInfo* mpParamInfos; /// Information about all parameters.
+ bool mbParamPairs; /// true = optional parameters are expected to appear in pairs.
+ bool mbVolatile; /// True = volatile function.
+ bool mbExternal; /// True = external function in Calc.
+ bool mbMacroFunc; /// True = macro sheet function or command.
+ bool mbVarParam; /// True = use a tFuncVar token, also if min/max are equal.
+};
+
+typedef RefVector< FunctionInfo > FunctionInfoVector;
+
+// function info parameter class iterator =====================================
+
+/** Iterator working on the mpParamInfos member of the FunctionInfo struct.
+
+ This iterator can be used to iterate through the array containing the
+ token class conversion information of function parameters. This iterator
+ repeats the last valid structure in the array - it stops automatically
+ before the first empty array entry or before the end of the array, even for
+ repeated calls to the increment operator.
+ */
+class FunctionParamInfoIterator
+{
+public:
+ explicit FunctionParamInfoIterator( const FunctionInfo& rFuncInfo );
+
+ const FunctionParamInfo& getParamInfo() const;
+ bool isCalcOnlyParam() const;
+ bool isExcelOnlyParam() const;
+ FunctionParamInfoIterator& operator++();
+
+private:
+ const FunctionParamInfo* mpParamInfo;
+ const FunctionParamInfo* mpParamInfoEnd;
+ bool mbParamPairs;
+};
+
+// base function provider =====================================================
+
+struct FunctionProviderImpl;
+
+/** Provides access to function info structs for all available sheet functions.
+ */
+class FunctionProvider // not derived from WorkbookHelper to make it usable in file dumpers
+{
+public:
+ explicit FunctionProvider( FilterType eFilter, BiffType eBiff, bool bImportFilter );
+ virtual ~FunctionProvider();
+
+ /** Returns the function info for an ODF function name, or 0 on error. */
+ const FunctionInfo* getFuncInfoFromOdfFuncName( const ::rtl::OUString& rFuncName ) const;
+
+ /** Returns the function info for an OOXML function name, or 0 on error. */
+ const FunctionInfo* getFuncInfoFromOoxFuncName( const ::rtl::OUString& rFuncName ) const;
+
+ /** Returns the function info for a BIFF12 function index, or 0 on error. */
+ const FunctionInfo* getFuncInfoFromBiff12FuncId( sal_uInt16 nFuncId ) const;
+
+ /** Returns the function info for a BIFF2-BIFF8 function index, or 0 on error. */
+ const FunctionInfo* getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const;
+
+ /** Returns the function info for a macro function referred by the
+ EXTERN.CALL function, or 0 on error. */
+ const FunctionInfo* getFuncInfoFromMacroName( const ::rtl::OUString& rFuncName ) const;
+
+ /** Returns the library type associated with the passed URL of a function
+ library (function add-in). */
+ FunctionLibraryType getFuncLibTypeFromLibraryName( const ::rtl::OUString& rLibraryName ) const;
+
+protected:
+ /** Returns the list of all function infos. */
+ const FunctionInfoVector& getFuncs() const;
+
+private:
+ typedef ::boost::shared_ptr< FunctionProviderImpl > FunctionProviderImplRef;
+ FunctionProviderImplRef mxFuncImpl; /// Shared implementation between all copies of the provider.
+};
+
+// op-code and function provider ==============================================
+
+struct OpCodeProviderImpl;
+
+/** Provides access to API op-codes for all available formula tokens and to
+ function info structs for all available sheet functions.
+ */
+class OpCodeProvider : public FunctionProvider // not derived from WorkbookHelper to make it usable as UNO service
+{
+public:
+ explicit OpCodeProvider(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ FilterType eFilter, BiffType eBiff, bool bImportFilter );
+ virtual ~OpCodeProvider();
+
+ /** Returns the structure containing all token op-codes for operators and
+ special tokens used by the Calc document and its formula parser. */
+ const ApiOpCodes& getOpCodes() const;
+
+ /** Returns the function info for an API token, or 0 on error. */
+ const FunctionInfo* getFuncInfoFromApiToken( const ApiToken& rToken ) const;
+
+ /** Returns the op-code map that is used by the OOXML formula parser. */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaOpCodeMapEntry >
+ getOoxParserMap() const;
+
+private:
+ typedef ::boost::shared_ptr< OpCodeProviderImpl > OpCodeProviderImplRef;
+ OpCodeProviderImplRef mxOpCodeImpl; /// Shared implementation between all copies of the provider.
+};
+
+// API formula parser wrapper =================================================
+
+/** A wrapper around the FormulaParser service provided by the Calc document. */
+class ApiParserWrapper : public OpCodeProvider
+{
+public:
+ explicit ApiParserWrapper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
+ const OpCodeProvider& rOpCodeProv );
+
+ /** Returns read/write access to the formula parser property set. */
+ inline PropertySet& getParserProperties() { return maParserProps; }
+
+ /** Calls the XFormulaParser::parseFormula() function of the API parser. */
+ ApiTokenSequence parseFormula(
+ const ::rtl::OUString& rFormula,
+ const ::com::sun::star::table::CellAddress& rRefPos );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser >
+ mxParser;
+ PropertySet maParserProps;
+};
+
+// formula contexts ===========================================================
+
+class FormulaContext
+{
+public:
+ inline void setBaseAddress( const ::com::sun::star::table::CellAddress& rBaseAddress )
+ { maBaseAddress = rBaseAddress; }
+
+ inline const ::com::sun::star::table::CellAddress& getBaseAddress() const { return maBaseAddress; }
+ inline bool isRelativeAsOffset() const { return mbRelativeAsOffset; }
+ inline bool is2dRefsAs3dRefs() const { return mb2dRefsAs3dRefs; }
+ inline bool isNulCharsAllowed() const { return mbAllowNulChars; }
+
+ virtual void setTokens( const ApiTokenSequence& rTokens ) = 0;
+ virtual void setSharedFormula( const ::com::sun::star::table::CellAddress& rBaseAddr );
+
+protected:
+ explicit FormulaContext(
+ bool bRelativeAsOffset,
+ bool b2dRefsAs3dRefs,
+ bool bAllowNulChars = false );
+ virtual ~FormulaContext();
+
+private:
+ ::com::sun::star::table::CellAddress maBaseAddress;
+ bool mbRelativeAsOffset;
+ bool mb2dRefsAs3dRefs;
+ bool mbAllowNulChars;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores the converted formula token sequence in a class member. */
+class TokensFormulaContext : public FormulaContext
+{
+public:
+ explicit TokensFormulaContext(
+ bool bRelativeAsOffset,
+ bool b2dRefsAs3dRefs,
+ bool bAllowNulChars = false );
+
+ inline const ApiTokenSequence& getTokens() const { return maTokens; }
+
+ virtual void setTokens( const ApiTokenSequence& rTokens );
+
+private:
+ ApiTokenSequence maTokens;
+};
+
+// ----------------------------------------------------------------------------
+
+/** Uses the com.sun.star.sheet.XFormulaTokens interface to set a token sequence. */
+class SimpleFormulaContext : public FormulaContext
+{
+public:
+ explicit SimpleFormulaContext(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaTokens >& rxTokens,
+ bool bRelativeAsOffset,
+ bool b2dRefsAs3dRefs,
+ bool bAllowNulChars = false );
+
+ virtual void setTokens( const ApiTokenSequence& rTokens );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaTokens > mxTokens;
+};
+
+// formula parser/printer base class for filters ==============================
+
+/** Base class for import formula parsers and export formula compilers. */
+class FormulaProcessorBase : public OpCodeProvider, protected ApiOpCodes, public WorkbookHelper
+{
+public:
+ explicit FormulaProcessorBase( const WorkbookHelper& rHelper );
+
+ // ------------------------------------------------------------------------
+
+ /** Generates a cell address string in A1 notation from the passed cell
+ address.
+
+ @param rAddress The cell address containing column and row index.
+ @param bAbsolute True = adds dollar signs before column and row.
+ */
+ static ::rtl::OUString generateAddress2dString(
+ const ::com::sun::star::table::CellAddress& rAddress,
+ bool bAbsolute );
+
+ /** Generates a cell address string in A1 notation from the passed binary
+ cell address.
+
+ @param rAddress The cell address containing column and row index.
+ @param bAbsolute True = adds dollar signs before column and row.
+ */
+ static ::rtl::OUString generateAddress2dString(
+ const BinAddress& rAddress,
+ bool bAbsolute );
+
+ /** Generates a cell range string in A1:A1 notation from the passed cell
+ range address.
+
+ @param rRange The cell range address containing column and row indexes.
+ @param bAbsolute True = adds dollar signs before columns and rows.
+ */
+ static ::rtl::OUString generateRange2dString(
+ const ::com::sun::star::table::CellRangeAddress& rRange,
+ bool bAbsolute );
+
+ /** Generates a cell range string in A1:A1 notation from the passed binary
+ cell range address.
+
+ @param rRange The cell range address containing column and row indexes.
+ @param bAbsolute True = adds dollar signs before columns and rows.
+ */
+ static ::rtl::OUString generateRange2dString(
+ const BinRange& rRange,
+ bool bAbsolute );
+
+ /** Generates a cell range list string in A1:A1 notation from the passed
+ cell range addresses. May enclose multiple ranges into parentheses.
+
+ @param rRanges The list of cell range addresses.
+ @param bAbsolute True = adds dollar signs before columns and rows.
+ @param cSeparator Separator character between ranges.
+ @param bEncloseMultiple True = enclose multiple ranges in parentheses.
+ */
+ static ::rtl::OUString generateRangeList2dString(
+ const ApiCellRangeList& rRanges,
+ bool bAbsolute,
+ sal_Unicode cSeparator,
+ bool bEncloseMultiple );
+
+ // ------------------------------------------------------------------------
+
+ /** Generates a cell address string in Calc's absolute $Sheet.$A$1 notation
+ from the passed cell address.
+
+ @param rAddress The cell address to be converted to a string.
+ */
+ ::rtl::OUString generateApiAddressString(
+ const ::com::sun::star::table::CellAddress& rAddress ) const;
+
+ /** Generates a cell range string in Calc's absolute $Sheet.$A$1:$A$
+ notation from the passed cell range address.
+
+ @param rRange The cell range address to be converted to a string.
+ */
+ ::rtl::OUString generateApiRangeString(
+ const ::com::sun::star::table::CellRangeAddress& rRange ) const;
+
+ /** Generates a cell range list string in Calc's absolute $Sheet.$A$1:$A$1
+ notation from the passed cell range addresses.
+
+ @param rRanges The list of cell ranges to be converted to a string.
+ */
+ ::rtl::OUString generateApiRangeListString( const ApiCellRangeList& rRanges ) const;
+
+ /** Generates a string in Calc formula notation from the passed string.
+
+ @param rString The string value.
+
+ @return The string enclosed in double quotes, where all contained
+ quote characters are doubled.
+ */
+ static ::rtl::OUString generateApiString( const ::rtl::OUString& rString );
+
+ /** Generates an array string in Calc formula notation from the passed
+ matrix with Any's containing double values or strings.
+
+ @param rMatrix The matrix containing double values or strings.
+ */
+ static ::rtl::OUString generateApiArray( const Matrix< ::com::sun::star::uno::Any >& rMatrix );
+
+ // ------------------------------------------------------------------------
+
+ /** Tries to extract a single cell reference from a formula token sequence.
+
+ @param rTokens The token sequence to be parsed. Should contain exactly
+ one address token or cell range address token. The token sequence
+ may contain whitespace tokens.
+
+ @return If the token sequence is valid, this function returns an Any
+ containing a com.sun.star.sheet.SingleReference object, or a
+ com.sun.star.sheet.ComplexReference object. If the token sequence
+ contains too many, or unexpected tokens, an empty Any is returned.
+ */
+ ::com::sun::star::uno::Any
+ extractReference( const ApiTokenSequence& rTokens ) const;
+
+ /** Tries to extract a single cell address from a formula token sequence.
+
+ @param orAddress (output parameter) If the token sequence is valid,
+ this parameter will contain the extracted cell address. If the
+ token sequence contains unexpected tokens, nothing meaningful is
+ inserted, and the function returns false.
+
+ @param rTokens The token sequence to be parsed. Should contain exactly
+ one cell address token. The token sequence may contain whitespace
+ tokens.
+
+ @param bAllowRelative True = it is allowed that rTokens contains
+ relative references (based on cell A1 of the current sheet).
+ False = only real absolute references will be accepted.
+
+ @return True, if the token sequence contains a valid cell address
+ which has been extracted to orAddress, false otherwise.
+ */
+ bool extractCellAddress(
+ ::com::sun::star::table::CellAddress& orAddress,
+ const ApiTokenSequence& rTokens,
+ bool bAllowRelative ) const;
+
+ /** Tries to extract a cell range address from a formula token sequence.
+
+ @param orAddress (output parameter) If the token sequence is valid,
+ this parameter will contain the extracted cell range address. If
+ the token sequence contains unexpected tokens, nothing meaningful
+ is inserted, and the function returns false.
+
+ @param rTokens The token sequence to be parsed. Should contain exactly
+ one cell range address token. The token sequence may contain
+ whitespace tokens.
+
+ @param bAllowRelative True = it is allowed that rTokens contains
+ relative references (based on cell A1 of the current sheet).
+ False = only real absolute references will be accepted.
+
+ @return True, if the token sequence contains a valid cell range
+ address which has been extracted to orRange, false otherwise.
+ */
+ bool extractCellRange(
+ ::com::sun::star::table::CellRangeAddress& orRange,
+ const ApiTokenSequence& rTokens,
+ bool bAllowRelative ) const;
+
+ /** Tries to extract a cell range list from a formula token sequence.
+
+ @param orRanges (output parameter) If the token sequence is valid,
+ this parameter will contain the extracted cell range list. Deleted
+ cells or cell ranges (shown as #REF! error in a formula) will be
+ skipped. If the token sequence contains unexpected tokens, an empty
+ list is returned here.
+
+ @param rTokens The token sequence to be parsed. Should contain cell
+ address tokens or cell range address tokens, separated by the
+ standard function parameter separator token. The token sequence may
+ contain parentheses and whitespace tokens.
+
+ @param bAllowRelative True = it is allowed that rTokens contains
+ relative references (based on cell A1 of the current sheet).
+ False = only real absolute references will be accepted.
+
+ @param nFilterBySheet If non-negative, this function returns only cell
+ ranges located in the specified sheet, otherwise returns all cell
+ ranges contained in the token sequence.
+ */
+ void extractCellRangeList(
+ ApiCellRangeList& orRanges,
+ const ApiTokenSequence& rTokens,
+ bool bAllowRelative,
+ sal_Int32 nFilterBySheet = -1 ) const;
+
+ /** Tries to extract a string from a formula token sequence.
+
+ @param orString (output parameter) The extracted string.
+
+ @param rTokens The token sequence to be parsed. Should contain exactly
+ one string token, may contain whitespace tokens.
+
+ @return True = token sequence is valid, output parameter orString
+ contains the string extracted from the token sequence.
+ */
+ bool extractString(
+ ::rtl::OUString& orString,
+ const ApiTokenSequence& rTokens ) const;
+
+ /** Converts a single string with separators in the passed formula token
+ sequence to a list of string tokens.
+
+ @param orTokens (input/output parameter) Expects a single string token
+ in this token sequence (whitespace tokens are allowed). The string
+ is split into substrings. A list of string tokens separated with
+ parameter separator tokens is returned in this psrameter.
+
+ @param cStringSep The separator character used to split the input
+ string.
+
+ @param bTrimLeadingSpaces True = removes leading whitespace from all
+ substrings inserted into the formula token sequence.
+ */
+ void convertStringToStringList(
+ ApiTokenSequence& orTokens,
+ sal_Unicode cStringSep,
+ bool bTrimLeadingSpaces ) const;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/formulaparser.hxx b/oox/inc/oox/xls/formulaparser.hxx
new file mode 100644
index 000000000000..c595993264d9
--- /dev/null
+++ b/oox/inc/oox/xls/formulaparser.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_FORMULAPARSER_HXX
+#define OOX_XLS_FORMULAPARSER_HXX
+
+#include "oox/xls/formulabase.hxx"
+
+namespace oox {
+namespace xls {
+
+// formula finalizer ==========================================================
+
+/** A generic formula token array finalizer.
+
+ After building a formula token array from alien binary file formats, or
+ parsing an XML formula string using the com.sun.star.sheet.FormulaParser
+ service, the token array is still not ready to be put into the spreadsheet
+ document. There may be functions with a wrong number of parameters (missing
+ but required parameters, or unsupported parameters) or intermediate tokens
+ used to encode references to macro functions or add-in functions. This
+ helper processes a passed token array and builds a new compatible token
+ array.
+
+ Derived classes may add more functionality by overwriting the virtual
+ functions.
+ */
+class FormulaFinalizer : public OpCodeProvider, protected ApiOpCodes
+{
+public:
+ explicit FormulaFinalizer( const OpCodeProvider& rOpCodeProv );
+
+ /** Finalizes and returns the passed token array. */
+ ApiTokenSequence finalizeTokenArray( const ApiTokenSequence& rTokens );
+
+protected:
+ /** Derived classed may try to find a function info struct from the passed
+ string extracted from an OPCODE_BAD token.
+
+ @param rTokenData The string that has been found in an OPCODE_BAD
+ token preceding the function parentheses.
+ */
+ virtual const FunctionInfo* resolveBadFuncName( const ::rtl::OUString& rTokenData ) const;
+
+ /** Derived classed may try to find the name of a defined name with the
+ passed index extracted from an OPCODE_NAME token.
+
+ @param nTokenIndex The index of the defined name that has been found
+ in an OPCODE_NAME token preceding the function parentheses.
+ */
+ virtual ::rtl::OUString resolveDefinedName( sal_Int32 nTokenIndex ) const;
+
+private:
+ typedef ::std::vector< const ApiToken* > ParameterPosVector;
+
+ const FunctionInfo* getFunctionInfo( ApiToken& orFuncToken );
+ const FunctionInfo* getExternCallInfo( ApiToken& orFuncToken, const ApiToken& rECToken );
+
+ 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;
+ const ApiToken* getSingleToken( 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 );
+
+ bool appendFinalToken( const ApiToken& rToken );
+
+private:
+ ApiTokenVector maTokens;
+};
+
+// ============================================================================
+
+class FormulaParserImpl;
+
+/** Import formula parser for OOXML and BIFF filters.
+
+ This class implements formula import for the OOXML and BIFF filter. One
+ instance is contained in the global filter data to prevent construction and
+ destruction of internal buffers for every imported formula.
+ */
+class FormulaParser : public FormulaProcessorBase
+{
+public:
+ explicit FormulaParser( const WorkbookHelper& rHelper );
+ virtual ~FormulaParser();
+
+ /** Converts an OOXML formula string. */
+ void importFormula(
+ FormulaContext& rContext,
+ const ::rtl::OUString& rFormulaString ) const;
+
+ /** Imports and converts a BIFF12 token array from the passed stream. */
+ void importFormula(
+ FormulaContext& rContext,
+ SequenceInputStream& rStrm ) const;
+
+ /** Imports and converts a BIFF2-BIFF8 token array from the passed stream.
+ @param pnFmlaSize Size of the token array. If null is passed, reads
+ it from stream (1 byte in BIFF2, 2 bytes otherwise) first. */
+ void importFormula(
+ FormulaContext& rContext,
+ BiffInputStream& rStrm,
+ const sal_uInt16* pnFmlaSize = 0 ) const;
+
+ /** Converts the passed BIFF error code to a similar formula. */
+ void convertErrorToFormula(
+ FormulaContext& rContext,
+ sal_uInt8 nErrorCode ) const;
+
+ /** Converts the passed token index of a defined name to a formula calling that name. */
+ void convertNameToFormula(
+ FormulaContext& rContext,
+ sal_Int32 nTokenIndex ) const;
+
+ /** Converts the passed number into a HYPERLINK formula with the passed URL. */
+ void convertNumberToHyperlink(
+ FormulaContext& rContext,
+ const ::rtl::OUString& rUrl,
+ double fValue ) const;
+
+ /** Converts the passed XML formula to an OLE link target. */
+ ::rtl::OUString importOleTargetLink( const ::rtl::OUString& rFormulaString );
+
+ /** Imports and converts an OLE link target from the passed stream. */
+ ::rtl::OUString importOleTargetLink( SequenceInputStream& rStrm );
+
+ /** Imports and converts an OLE link target from the passed stream. */
+ ::rtl::OUString importOleTargetLink(
+ BiffInputStream& rStrm,
+ const sal_uInt16* pnFmlaSize = 0 ) const;
+
+ /** Converts the passed formula to a macro name for a drawing shape. */
+ ::rtl::OUString importMacroName( const ::rtl::OUString& rFormulaString );
+
+private:
+ ::std::auto_ptr< FormulaParserImpl > mxImpl;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/numberformatsbuffer.hxx b/oox/inc/oox/xls/numberformatsbuffer.hxx
new file mode 100644
index 000000000000..768572a5839c
--- /dev/null
+++ b/oox/inc/oox/xls/numberformatsbuffer.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_NUMBERFORMATSBUFFER_HXX
+#define OOX_XLS_NUMBERFORMATSBUFFER_HXX
+
+#include <com/sun/star/lang/Locale.hpp>
+#include "oox/xls/workbookhelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace util { class XNumberFormats; }
+} } }
+
+namespace oox { class PropertyMap; }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+struct NumFmtModel
+{
+ ::com::sun::star::lang::Locale maLocale;
+ ::rtl::OUString maFmtCode;
+ sal_Int16 mnPredefId;
+
+ explicit NumFmtModel();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all API number format attributes. */
+struct ApiNumFmtData
+{
+ sal_Int32 mnIndex; /// API number format index.
+
+ explicit ApiNumFmtData();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all data for a number format code. */
+class NumberFormat : public WorkbookHelper
+{
+public:
+ explicit NumberFormat( const WorkbookHelper& rHelper );
+
+ /** Sets the passed format code. */
+ void setFormatCode( const ::rtl::OUString& rFmtCode );
+ /** Sets the passed format code, encoded in UTF-8. */
+ void setFormatCode(
+ const ::com::sun::star::lang::Locale& rLocale,
+ const sal_Char* pcFmtCode );
+ /** Sets the passed predefined format code identifier. */
+ void setPredefinedId(
+ const ::com::sun::star::lang::Locale& rLocale,
+ sal_Int16 nPredefId );
+
+ /** Final processing after import of all style settings. Returns the API format index. */
+ sal_Int32 finalizeImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats >& rxNumFmts,
+ const ::com::sun::star::lang::Locale& rFromLocale );
+
+ /** Writes the number format to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap ) const;
+
+private:
+ NumFmtModel maModel;
+ ApiNumFmtData maApiData;
+};
+
+typedef ::boost::shared_ptr< NumberFormat > NumberFormatRef;
+
+// ============================================================================
+
+class NumberFormatsBuffer : public WorkbookHelper
+{
+public:
+ explicit NumberFormatsBuffer( const WorkbookHelper& rHelper );
+
+ /** Inserts a new number format. */
+ NumberFormatRef createNumFmt( sal_Int32 nNumFmtId, const ::rtl::OUString& rFmtCode );
+
+ /** Inserts a new number format code. */
+ NumberFormatRef importNumFmt( const AttributeList& rAttribs );
+ /** Inserts a new number format code from a NUMFMT record. */
+ void importNumFmt( SequenceInputStream& rStrm );
+ /** Inserts a new number format code from a FORMAT record. */
+ void importFormat( BiffInputStream& rStrm );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Writes the specified number format to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const;
+
+private:
+ /** Inserts built-in number formats for the current system language. */
+ void insertBuiltinFormats();
+
+private:
+ typedef RefMap< sal_Int32, NumberFormat > NumberFormatMap;
+
+ NumberFormatMap maNumFmts; /// List of number formats.
+ ::rtl::OUString maLocaleStr; /// Current office locale.
+ sal_Int32 mnNextBiffIndex; /// Format id counter for BIFF2-BIFF4.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/ooxformulaparser.hxx b/oox/inc/oox/xls/ooxformulaparser.hxx
new file mode 100644
index 000000000000..7bc1bbdd4909
--- /dev/null
+++ b/oox/inc/oox/xls/ooxformulaparser.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_OOXFORMULAPARSER_HXX
+#define OOX_XLS_OOXFORMULAPARSER_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sheet/XFilterFormulaParser.hpp>
+#include <cppuhelper/implbase3.hxx>
+
+namespace oox {
+namespace xls {
+
+class OOXMLFormulaParserImpl;
+class OOXMLFormulaPrinterImpl;
+
+// ============================================================================
+
+typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::sheet::XFilterFormulaParser > OOXMLFormulaParserBase;
+
+/** OOXML formula parser/compiler service for usage in ODF filters. */
+class OOXMLFormulaParser : public OOXMLFormulaParserBase
+{
+public:
+ explicit OOXMLFormulaParser();
+ virtual ~OOXMLFormulaParser();
+
+ // com.sun.star.lang.XServiceInfo interface -------------------------------
+
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& rService )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.lang.XInitialization interface ----------------------------
+
+ virtual void SAL_CALL initialize(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rArgs )
+ throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.sheet.XFilterFormulaParser interface ----------------------
+
+ virtual ::rtl::OUString SAL_CALL
+ getSupportedNamespace()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // com.sun.star.sheet.XFormulaParser interface ----------------------------
+
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL
+ parseFormula(
+ const ::rtl::OUString& rFormula,
+ const ::com::sun::star::table::CellAddress& rReferencePos )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::rtl::OUString SAL_CALL
+ printFormula(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >& rTokens,
+ const ::com::sun::star::table::CellAddress& rReferencePos )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+ typedef ::boost::shared_ptr< OOXMLFormulaParserImpl > ParserImplRef;
+ typedef ::boost::shared_ptr< OOXMLFormulaPrinterImpl > PrinterImplRef;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
+ mxComponent;
+ ParserImplRef mxParserImpl; /// Implementation of import parser.
+ PrinterImplRef mxPrinterImpl; /// Implementation of export printer.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/pagesettings.hxx b/oox/inc/oox/xls/pagesettings.hxx
new file mode 100644
index 000000000000..6ff896b1bb51
--- /dev/null
+++ b/oox/inc/oox/xls/pagesettings.hxx
@@ -0,0 +1,219 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_PAGESETTINGS_HXX
+#define OOX_XLS_PAGESETTINGS_HXX
+
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox { class PropertySet; }
+namespace oox { namespace core { class Relations; } }
+
+namespace oox {
+namespace xls {
+
+class HeaderFooterParser;
+
+// ============================================================================
+
+/** Holds page style data for a single sheet. */
+struct PageSettingsModel
+{
+ ::rtl::OUString maGraphicUrl; /// URL of the graphic object.
+ ::rtl::OUString maBinSettPath; /// Relation identifier of binary printer settings.
+ ::rtl::OUString maOddHeader; /// Header string for odd pages.
+ ::rtl::OUString maOddFooter; /// Footer string for odd pages.
+ ::rtl::OUString maEvenHeader; /// Header string for even pages.
+ ::rtl::OUString maEvenFooter; /// Footer string for even pages.
+ ::rtl::OUString maFirstHeader; /// Header string for first page of the sheet.
+ ::rtl::OUString maFirstFooter; /// Footer string for first page of the sheet.
+ double mfLeftMargin; /// Margin between left edge of page and begin of sheet area.
+ double mfRightMargin; /// Margin between end of sheet area and right edge of page.
+ double mfTopMargin; /// Margin between top egde of page and begin of sheet area.
+ double mfBottomMargin; /// Margin between end of sheet area and bottom edge of page.
+ double mfHeaderMargin; /// Margin between top edge of page and begin of header.
+ double mfFooterMargin; /// Margin between end of footer and bottom edge of page.
+ sal_Int32 mnPaperSize; /// Paper size (enumeration).
+ sal_Int32 mnCopies; /// Number of copies to print.
+ sal_Int32 mnScale; /// Page scale (zoom in percent).
+ sal_Int32 mnFirstPage; /// First page number.
+ sal_Int32 mnFitToWidth; /// Fit to number of pages in horizontal direction.
+ sal_Int32 mnFitToHeight; /// Fit to number of pages in vertical direction.
+ sal_Int32 mnHorPrintRes; /// Horizontal printing resolution in DPI.
+ sal_Int32 mnVerPrintRes; /// Vertical printing resolution in DPI.
+ sal_Int32 mnOrientation; /// Landscape or portrait.
+ sal_Int32 mnPageOrder; /// Page order through sheet area (to left or down).
+ sal_Int32 mnCellComments; /// Cell comments printing mode.
+ sal_Int32 mnPrintErrors; /// Cell error printing mode.
+ bool mbUseEvenHF; /// True = use maEvenHeader/maEvenFooter.
+ bool mbUseFirstHF; /// True = use maFirstHeader/maFirstFooter.
+ bool mbValidSettings; /// True = use imported settings.
+ bool mbUseFirstPage; /// True = start page numbering with mnFirstPage.
+ bool mbBlackWhite; /// True = print black and white.
+ bool mbDraftQuality; /// True = print in draft quality.
+ bool mbFitToPages; /// True = Fit to width/height; false = scale in percent.
+ bool mbHorCenter; /// True = horizontally centered.
+ bool mbVerCenter; /// True = vertically centered.
+ bool mbPrintGrid; /// True = print grid lines.
+ bool mbPrintHeadings; /// True = print column/row headings.
+
+ explicit PageSettingsModel();
+
+ /** Sets the BIFF print errors mode. */
+ void setBiffPrintErrors( sal_uInt8 nPrintErrors );
+};
+
+// ============================================================================
+
+class PageSettings : public WorksheetHelper
+{
+public:
+ explicit PageSettings( const WorksheetHelper& rHelper );
+
+ /** Imports printing options from a printOptions element. */
+ void importPrintOptions( const AttributeList& rAttribs );
+ /** Imports pageMarings element containing page margins. */
+ void importPageMargins( const AttributeList& rAttribs );
+ /** Imports pageSetup element for worksheets. */
+ void importPageSetup( const ::oox::core::Relations& rRelations, const AttributeList& rAttribs );
+ /** Imports pageSetup element for chart sheets. */
+ void importChartPageSetup( const ::oox::core::Relations& rRelations, const AttributeList& rAttribs );
+ /** Imports header and footer settings from a headerFooter element. */
+ void importHeaderFooter( const AttributeList& rAttribs );
+ /** Imports header/footer characters from a headerFooter element. */
+ void importHeaderFooterCharacters( const ::rtl::OUString& rChars, sal_Int32 nElement );
+ /** Imports the picture element. */
+ void importPicture( const ::oox::core::Relations& rRelations, const AttributeList& rAttribs );
+
+ /** Imports the PRINTOPTIONS record from the passed stream. */
+ void importPrintOptions( SequenceInputStream& rStrm );
+ /** Imports the PAGEMARGINS record from the passed stream. */
+ void importPageMargins( SequenceInputStream& rStrm );
+ /** Imports the PAGESETUP record from the passed stream. */
+ void importPageSetup( const ::oox::core::Relations& rRelations, SequenceInputStream& rStrm );
+ /** Imports the CHARTPAGESETUP record from the passed stream. */
+ void importChartPageSetup( const ::oox::core::Relations& rRelations, SequenceInputStream& rStrm );
+ /** Imports the HEADERFOOTER record from the passed stream. */
+ void importHeaderFooter( SequenceInputStream& rStrm );
+ /** Imports the PICTURE record from the passed stream. */
+ void importPicture( const ::oox::core::Relations& rRelations, SequenceInputStream& rStrm );
+
+ /** Imports the LEFTMARGIN record from the passed BIFF stream. */
+ void importLeftMargin( BiffInputStream& rStrm );
+ /** Imports the RIGHTMARGIN record from the passed BIFF stream. */
+ void importRightMargin( BiffInputStream& rStrm );
+ /** Imports the TOPMARGIN record from the passed BIFF stream. */
+ void importTopMargin( BiffInputStream& rStrm );
+ /** Imports the BOTTOMMARGIN record from the passed BIFF stream. */
+ void importBottomMargin( BiffInputStream& rStrm );
+ /** Imports the SETUP record from the passed BIFF stream. */
+ void importPageSetup( BiffInputStream& rStrm );
+ /** Imports the HCENTER record from the passed BIFF stream. */
+ void importHorCenter( BiffInputStream& rStrm );
+ /** Imports the VCENTER record from the passed BIFF stream. */
+ void importVerCenter( BiffInputStream& rStrm );
+ /** Imports the PRINTHEADERS record from the passed BIFF stream. */
+ void importPrintHeaders( BiffInputStream& rStrm );
+ /** Imports the PRINTGRIDLINES record from the passed BIFF stream. */
+ void importPrintGridLines( BiffInputStream& rStrm );
+ /** Imports the HEADER record from the passed BIFF stream. */
+ void importHeader( BiffInputStream& rStrm );
+ /** Imports the FOOTER record from the passed BIFF stream. */
+ void importFooter( BiffInputStream& rStrm );
+ /** Imports the PICTURE record from the passed BIFF stream. */
+ void importPicture( BiffInputStream& rStrm );
+
+ /** Sets whether percentual scaling or fit to width/height scaling is used. */
+ void setFitToPagesMode( bool bFitToPages );
+
+ /** Creates a page style for the spreadsheet and sets all page properties. */
+ void finalizeImport();
+
+private:
+ /** Imports the binary picture data from the fragment with the passed identifier. */
+ void importPictureData( const ::oox::core::Relations& rRelations, const ::rtl::OUString& rRelId );
+
+private:
+ PageSettingsModel maModel;
+};
+
+// ============================================================================
+
+class PageSettingsConverter : public WorkbookHelper
+{
+public:
+ explicit PageSettingsConverter( const WorkbookHelper& rHelper );
+ virtual ~PageSettingsConverter();
+
+ /** Writes all properties to the passed property set of a page style object. */
+ void writePageSettingsProperties(
+ PropertySet& rPropSet,
+ const PageSettingsModel& rModel,
+ WorksheetType eSheetType );
+
+private:
+ struct HFHelperData
+ {
+ sal_Int32 mnLeftPropId;
+ sal_Int32 mnRightPropId;
+ sal_Int32 mnHeight;
+ sal_Int32 mnBodyDist;
+ bool mbHasContent;
+ bool mbShareOddEven;
+ bool mbDynamicHeight;
+
+ explicit HFHelperData( sal_Int32 nLeftPropId, sal_Int32 nRightPropId );
+ };
+
+private:
+ void convertHeaderFooterData(
+ PropertySet& rPropSet,
+ HFHelperData& orHFData,
+ const ::rtl::OUString rOddContent,
+ const ::rtl::OUString rEvenContent,
+ bool bUseEvenContent,
+ double fPageMargin,
+ double fContentMargin );
+
+ sal_Int32 writeHeaderFooter(
+ PropertySet& rPropSet,
+ sal_Int32 nPropId,
+ const ::rtl::OUString& rContent );
+
+private:
+ typedef ::std::auto_ptr< HeaderFooterParser > HeaderFooterParserPtr;
+ HeaderFooterParserPtr mxHFParser;
+ HFHelperData maHeaderData;
+ HFHelperData maFooterData;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/pivotcachebuffer.hxx b/oox/inc/oox/xls/pivotcachebuffer.hxx
new file mode 100644
index 000000000000..2e32d0faa7e5
--- /dev/null
+++ b/oox/inc/oox/xls/pivotcachebuffer.hxx
@@ -0,0 +1,510 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_PIVOTCACHEBUFFER_HXX
+#define OOX_XLS_PIVOTCACHEBUFFER_HXX
+
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XDataPilotField; }
+} } }
+
+namespace oox { namespace core { class Relations; } }
+
+namespace oox {
+namespace xls {
+
+class WorksheetHelper;
+
+// ============================================================================
+
+class PivotCacheItem
+{
+public:
+ explicit PivotCacheItem();
+
+ /** Reads the string value from a pivot cache item. */
+ void readString( const AttributeList& rAttribs );
+ /** Reads the double value from a pivot cache item. */
+ void readNumeric( const AttributeList& rAttribs );
+ /** Reads the date/time value from a pivot cache item. */
+ void readDate( const AttributeList& rAttribs );
+ /** Reads the boolean value from a pivot cache item. */
+ void readBool( const AttributeList& rAttribs );
+ /** Reads the error code value from a pivot cache item. */
+ void readError( const AttributeList& rAttribs, const UnitConverter& rUnitConverter );
+ /** Reads the index of a shared item. */
+ void readIndex( const AttributeList& rAttribs );
+
+ /** Reads the string value from a pivot cache item. */
+ void readString( SequenceInputStream& rStrm );
+ /** Reads the double value from a pivot cache item. */
+ void readDouble( SequenceInputStream& rStrm );
+ /** Reads the date/time value from a pivot cache item. */
+ void readDate( SequenceInputStream& rStrm );
+ /** Reads the boolean value from a pivot cache item. */
+ void readBool( SequenceInputStream& rStrm );
+ /** Reads the error code value from a pivot cache item. */
+ void readError( SequenceInputStream& rStrm );
+ /** Reads the index of a shared item. */
+ void readIndex( SequenceInputStream& rStrm );
+
+ /** Reads the string value from a pivot cache item. */
+ void readString( BiffInputStream& rStrm, const WorkbookHelper& rHelper );
+ /** Reads the double value from a pivot cache item. */
+ void readDouble( BiffInputStream& rStrm );
+ /** Reads the integer value from a pivot cache item. */
+ void readInteger( BiffInputStream& rStrm );
+ /** Reads the date/time value from a pivot cache item. */
+ void readDate( BiffInputStream& rStrm );
+ /** Reads the boolean value from a pivot cache item. */
+ void readBool( BiffInputStream& rStrm );
+ /** Reads the error code value from a pivot cache item. */
+ void readError( BiffInputStream& rStrm );
+
+ /** Returns the type of the item. */
+ inline sal_Int32 getType() const { return mnType; }
+ /** Returns the value of the item. */
+ inline const ::com::sun::star::uno::Any& getValue() const { return maValue; }
+ /** Returns the string representation of the item. */
+ ::rtl::OUString getName() const;
+
+private:
+ ::com::sun::star::uno::Any maValue; /// Value of the item.
+ sal_Int32 mnType; /// Value type (OOXML token identifier).
+};
+
+// ----------------------------------------------------------------------------
+
+class PivotCacheItemList : public WorkbookHelper
+{
+public:
+ explicit PivotCacheItemList( const WorkbookHelper& rHelper );
+
+ /** Imports the item from the passed attribute list. */
+ void importItem( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Imports the item from the passed stream and record. */
+ void importItem( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ /** Imports a complete item list from the passed stream. */
+ void importItemList( BiffInputStream& rStrm, sal_uInt16 nCount );
+
+ /** Returns true, if this item list is empty. */
+ inline bool empty() const { return maItems.empty(); }
+ /** Returns the size of the item list. */
+ inline size_t size() const { return maItems.size(); }
+
+ /** Returns the specified item. */
+ const PivotCacheItem* getCacheItem( sal_Int32 nItemIdx ) const;
+ /** Returns the names of all items. */
+ void getCacheItemNames( ::std::vector< ::rtl::OUString >& orItemNames ) const;
+
+private:
+ /** Creates and returns a new item at the end of the items list. */
+ PivotCacheItem& createItem();
+ /** Imports an array of items from the PCITEM_ARRAY record */
+ void importArray( SequenceInputStream& rStrm );
+
+private:
+ typedef ::std::vector< PivotCacheItem > CacheItemVector;
+ CacheItemVector maItems; /// All items of this list.
+};
+
+// ============================================================================
+
+struct PCFieldModel
+{
+ ::rtl::OUString maName; /// Fixed name of the cache field.
+ ::rtl::OUString maCaption; /// Caption of the ccahe field.
+ ::rtl::OUString maPropertyName; /// OLAP property name.
+ ::rtl::OUString maFormula; /// Formula of a calculated field.
+ sal_Int32 mnNumFmtId; /// Number format for all items.
+ sal_Int32 mnSqlType; /// Data type from ODBC data source.
+ sal_Int32 mnHierarchy; /// Hierarchy this field is part of.
+ sal_Int32 mnLevel; /// Hierarchy level this field is part of.
+ sal_Int32 mnMappingCount; /// Number of property mappings.
+ bool mbDatabaseField; /// True = field from source data; false = calculated field.
+ bool mbServerField; /// True = ODBC server-based page field.
+ bool mbUniqueList; /// True = list of unique ODBC items exists.
+ bool mbMemberPropField; /// True = contains OLAP member properties.
+
+ explicit PCFieldModel();
+};
+
+// ----------------------------------------------------------------------------
+
+struct PCSharedItemsModel
+{
+ bool mbHasSemiMixed; /// True = has (blank|string|bool|error) item(s), maybe other types.
+ bool mbHasNonDate; /// True = has non-date item(s), maybe date items.
+ bool mbHasDate; /// True = has date item(s), maybe other types.
+ bool mbHasString; /// True = has (string|bool|error) item(s), maybe other types.
+ bool mbHasBlank; /// True = has blank item(s), maybe other types.
+ bool mbHasMixed; /// True = has [(string|bool|error) and (number|date)] or (number and date).
+ bool mbIsNumeric; /// True = has numeric item(s), maybe other types except date.
+ bool mbIsInteger; /// True = has numeric item(s) with only integers, maybe other types except date.
+ bool mbHasLongText; /// True = contains strings with >255 charascters.
+ bool mbHasLongIndexes; /// True = indexes to shared items are 16-bit (BIFF only).
+
+ explicit PCSharedItemsModel();
+};
+
+// ----------------------------------------------------------------------------
+
+struct PCFieldGroupModel
+{
+ ::com::sun::star::util::DateTime maStartDate; /// Manual or calculated start date for range grouping.
+ ::com::sun::star::util::DateTime maEndDate; /// Manual or calculated end date for range grouping.
+ double mfStartValue; /// Manual or calculated start value for range grouping.
+ double mfEndValue; /// Manual or calculated end value for range grouping.
+ double mfInterval; /// Interval for numeric range grouping.
+ sal_Int32 mnParentField; /// Index of cache field that contains item groups based on this field.
+ sal_Int32 mnBaseField; /// Index of cache field this grouped field is based on.
+ sal_Int32 mnGroupBy; /// Type of numeric or date range grouping.
+ bool mbRangeGroup; /// True = items are grouped by numeric ranges or date ranges.
+ bool mbDateGroup; /// True = items are grouped by date ranges or by item names.
+ bool mbAutoStart; /// True = start value for range groups is calculated from source data.
+ bool mbAutoEnd; /// True = end value for range groups is calculated from source data.
+
+ explicit PCFieldGroupModel();
+
+ /** Sets the group-by value for BIFF import. */
+ void setBiffGroupBy( sal_uInt8 nGroupBy );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Helper struct for mapping original item names from/to group item names. */
+struct PivotCacheGroupItem
+{
+ ::rtl::OUString maOrigName;
+ ::rtl::OUString maGroupName;
+
+ inline explicit PivotCacheGroupItem( const ::rtl::OUString& rItemName ) :
+ maOrigName( rItemName ), maGroupName( rItemName ) {}
+};
+
+typedef ::std::vector< PivotCacheGroupItem > PivotCacheGroupItemVector;
+
+// ----------------------------------------------------------------------------
+
+class PivotCacheField : public WorkbookHelper
+{
+public:
+ explicit PivotCacheField( const WorkbookHelper& rHelper, bool bIsDatabaseField );
+
+ /** Imports pivot cache field settings from the cacheField element. */
+ void importCacheField( const AttributeList& rAttribs );
+ /** Imports shared items settings from the sharedItems element. */
+ void importSharedItems( const AttributeList& rAttribs );
+ /** Imports a shared item from the passed element. */
+ void importSharedItem( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Imports grouping settings from the fieldGroup element. */
+ void importFieldGroup( const AttributeList& rAttribs );
+ /** Imports numeric grouping settings from the rangePr element. */
+ void importRangePr( const AttributeList& rAttribs );
+ /** Imports an item of the mapping between group items and base items from the passed element. */
+ void importDiscretePrItem( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Imports a group item from the passed element. */
+ void importGroupItem( sal_Int32 nElement, const AttributeList& rAttribs );
+
+ /** Imports pivot cache field settings from the PCDFIELD record. */
+ void importPCDField( SequenceInputStream& rStrm );
+ /** Imports shared items settings from the PCDFSHAREDITEMS record. */
+ void importPCDFSharedItems( SequenceInputStream& rStrm );
+ /** Imports one or more shared items from the passed record. */
+ void importPCDFSharedItem( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ /** Imports grouping settings from the PCDFIELDGROUP record. */
+ void importPCDFieldGroup( SequenceInputStream& rStrm );
+ /** Imports numeric grouping settings from the PCDFRANGEPR record. */
+ void importPCDFRangePr( SequenceInputStream& rStrm );
+ /** Imports an item of the mapping between group items and base items from the passed record. */
+ void importPCDFDiscretePrItem( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ /** Imports one or more group items from the passed record. */
+ void importPCDFGroupItem( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ /** Imports pivot cache field settings from the PCDFIELD record. */
+ void importPCDField( BiffInputStream& rStrm );
+ /** Imports numeric grouping settings from the PCDFRANGEPR record. */
+ void importPCDFRangePr( BiffInputStream& rStrm );
+ /** Imports the mapping between group items and base items from the PCDFDISCRETEPR record. */
+ void importPCDFDiscretePr( BiffInputStream& rStrm );
+
+ /** Returns true, if the field is based on source data, or false if it is grouped or calculated. */
+ inline bool isDatabaseField() const { return maFieldModel.mbDatabaseField; }
+
+ /** Returns true, if the field contains a list of shared items. */
+ inline bool hasSharedItems() const { return !maSharedItems.empty(); }
+ /** Returns true, if the field contains a list of grouping items. */
+ inline bool hasGroupItems() const { return !maGroupItems.empty(); }
+ /** Returns true, if the field has inplace numeric grouping settings. */
+ inline bool hasNumericGrouping() const { return maFieldGroupModel.mbRangeGroup && !maFieldGroupModel.mbDateGroup; }
+ /** Returns true, if the field has inplace date grouping settings. */
+ inline bool hasDateGrouping() const { return maFieldGroupModel.mbRangeGroup && maFieldGroupModel.mbDateGroup; }
+ /** Returns true, if the field has a parent group field that groups the items of this field. */
+ inline bool hasParentGrouping() const { return maFieldGroupModel.mnParentField >= 0; }
+
+ /** Returns the name of the cache field. */
+ inline const ::rtl::OUString& getName() const { return maFieldModel.maName; }
+ /** Returns the index of the parent group field that groups the items of this field. */
+ inline sal_Int32 getParentGroupField() const { return maFieldGroupModel.mnParentField; }
+ /** Returns the index of the base field grouping is based on. */
+ inline sal_Int32 getGroupBaseField() const { return maFieldGroupModel.mnBaseField; }
+
+ /** Returns the shared or group item with the specified index. */
+ const PivotCacheItem* getCacheItem( sal_Int32 nItemIdx ) const;
+ /** Returns the names of all shared or group items. */
+ void getCacheItemNames( ::std::vector< ::rtl::OUString >& orItemNames ) const;
+
+ /** Creates inplace numeric grouping settings. */
+ void convertNumericGrouping(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >& rxDPField ) const;
+ /** Creates inplace date grouping settings or a new date group field. */
+ ::rtl::OUString createDateGroupField(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >& rxBaseDPField ) const;
+ /** Creates a new grouped DataPilot field and returns its name. */
+ ::rtl::OUString createParentGroupField(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >& rxBaseDPField,
+ PivotCacheGroupItemVector& orItemNames ) const;
+
+ /** Writes the title of the field into the passed sheet at the passed address. */
+ void writeSourceHeaderCell( WorksheetHelper& rSheetHelper,
+ sal_Int32 nCol, sal_Int32 nRow ) const;
+ /** Writes a source field item value into the passed sheet. */
+ void writeSourceDataCell( WorksheetHelper& rSheetHelper,
+ sal_Int32 nCol, sal_Int32 nRow,
+ const PivotCacheItem& rItem ) const;
+
+ /** Reads an item from the PCRECORD record and writes it to the passed sheet. */
+ void importPCRecordItem( SequenceInputStream& rStrm,
+ WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const;
+ /** Reads an item index from the PCITEM_INDEXLIST record and writes the item to the passed sheet. */
+ void importPCItemIndex( BiffInputStream& rStrm,
+ WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const;
+
+
+private:
+ /** Tries to write the passed value to the passed sheet position. */
+ void writeItemToSourceDataCell( WorksheetHelper& rSheetHelper,
+ sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const;
+ /** Tries to write the value of a shared item to the passed sheet position. */
+ void writeSharedItemToSourceDataCell( WorksheetHelper& rSheetHelper,
+ sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nItemIdx ) const;
+
+private:
+ typedef ::std::vector< sal_Int32 > IndexVector;
+
+ PivotCacheItemList maSharedItems; /// All shared items of this field.
+ PivotCacheItemList maGroupItems; /// All group items of this field.
+ IndexVector maDiscreteItems; /// Mapping between group and base items.
+ PCFieldModel maFieldModel; /// Settings for this cache field.
+ PCSharedItemsModel maSharedItemsModel; /// Settings for shared items.
+ PCFieldGroupModel maFieldGroupModel; /// Settings for item grouping.
+};
+
+// ============================================================================
+
+struct PCDefinitionModel
+{
+ ::rtl::OUString maRelId; /// Relation identifier for cache records fragment.
+ ::rtl::OUString maRefreshedBy; /// Name of user who last refreshed the cache.
+ double mfRefreshedDate; /// Date/time of last refresh.
+ sal_Int32 mnRecords; /// Number of data records in the cache.
+ sal_Int32 mnMissItemsLimit; /// Limit for discarding unused items.
+ sal_uInt16 mnDatabaseFields; /// Number of database (source data) fields (BIFF only).
+ bool mbInvalid; /// True = cache needs refresh.
+ bool mbSaveData; /// True = cached item values are present.
+ bool mbRefreshOnLoad; /// True = try to refresh cache on load.
+ bool mbOptimizeMemory; /// True = application may optimize memory usage.
+ bool mbEnableRefresh; /// True = refreshing cache is enabled in UI.
+ bool mbBackgroundQuery; /// True = application queries data asynchonously.
+ bool mbUpgradeOnRefresh; /// True = application may upgrade cache version.
+ bool mbTupleCache; /// True = cache stores OLAP functions.
+ bool mbSupportSubquery; /// True = data source supports subqueries.
+ bool mbSupportDrill; /// True = data source supports drilldown.
+
+ explicit PCDefinitionModel();
+};
+
+// ----------------------------------------------------------------------------
+
+struct PCSourceModel
+{
+ sal_Int32 mnSourceType; /// Type of the source data (sheet, consolidation, scenario, external).
+ sal_Int32 mnConnectionId; /// Connection identifier for external data source.
+
+ explicit PCSourceModel();
+};
+
+// ----------------------------------------------------------------------------
+
+struct PCWorksheetSourceModel
+{
+ ::rtl::OUString maRelId; /// Relation identifier for an external document URL.
+ ::rtl::OUString maSheet; /// Sheet name for cell range or sheet-local defined names.
+ ::rtl::OUString maDefName; /// Defined name containing a cell range if present.
+ ::com::sun::star::table::CellRangeAddress
+ maRange; /// Source cell range of the data.
+
+ explicit PCWorksheetSourceModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class PivotCache : public WorkbookHelper
+{
+public:
+ explicit PivotCache( const WorkbookHelper& rHelper );
+
+ /** Reads pivot cache global settings from the pivotCacheDefinition element. */
+ void importPivotCacheDefinition( const AttributeList& rAttribs );
+ /** Reads cache source settings from the cacheSource element. */
+ void importCacheSource( const AttributeList& rAttribs );
+ /** Reads sheet source settings from the worksheetSource element. */
+ void importWorksheetSource( const AttributeList& rAttribs, const ::oox::core::Relations& rRelations );
+
+ /** Reads pivot cache global settings from the PCDEFINITION record. */
+ void importPCDefinition( SequenceInputStream& rStrm );
+ /** Reads cache source settings from the PCDSOURCE record. */
+ void importPCDSource( SequenceInputStream& rStrm );
+ /** Reads sheet source settings from the PCDSHEETSOURCE record. */
+ void importPCDSheetSource( SequenceInputStream& rStrm, const ::oox::core::Relations& rRelations );
+
+ /** Reads cache source settings from the PCDSOURCE record. */
+ void importPCDSource( BiffInputStream& rStrm );
+ /** Reads pivot cache global settings from the PCDEFINITION record. */
+ void importPCDefinition( BiffInputStream& rStrm );
+
+ /** Creates and returns a new pivot cache field. */
+ PivotCacheField& createCacheField( bool bInitDatabaseField = false );
+ /** Checks validity of source data and creates a dummy data sheet for external sheet sources. */
+ void finalizeImport();
+
+ /** Returns true, if the pivot cache is based on a valid data source, so
+ that pivot tables can be created based on this pivot cache. */
+ inline bool isValidDataSource() const { return mbValidSource; }
+ /** Returns true, if the pivot cache is based on a dummy sheet created in finalizeImport. */
+ inline bool isBasedOnDummySheet() const { return mbDummySheet; }
+ /** Returns the internal cell range the cache is based on. */
+ inline const ::com::sun::star::table::CellRangeAddress&
+ getSourceRange() const { return maSheetSrcModel.maRange; }
+ /** Returns the relation identifier of the pivot cache records fragment. */
+ inline const ::rtl::OUString& getRecordsRelId() const { return maDefModel.maRelId; }
+
+ /** Returns the number of pivot cache fields. */
+ sal_Int32 getCacheFieldCount() const;
+ /** Returns the cache field with the specified index. */
+ const PivotCacheField* getCacheField( sal_Int32 nFieldIdx ) const;
+ /** Returns the source column index of the field with the passed index. */
+ sal_Int32 getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const;
+
+ /** Writes the titles of all source fields into the passed sheet. */
+ void writeSourceHeaderCells( WorksheetHelper& rSheetHelper ) const;
+ /** Writes a source field item value into the passed sheet. */
+ void writeSourceDataCell( WorksheetHelper& rSheetHelper,
+ sal_Int32 nCol, sal_Int32 nRow,
+ const PivotCacheItem& rItem ) const;
+
+ /** Reads a PCRECORD record and writes all item values to the passed sheet. */
+ void importPCRecord( SequenceInputStream& rStrm,
+ WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const;
+ /** Reads a PCITEM_INDEXLIST record and writes all item values to the passed sheet. */
+ void importPCItemIndexList( BiffInputStream& rStrm,
+ WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const;
+
+private:
+ /** Reads the worksheet source range from the DCONREF record. */
+ void importDConRef( BiffInputStream& rStrm );
+ /** Reads the defined name used for source data from the DCONNAME record. */
+ void importDConName( BiffInputStream& rStrm );
+ /** Reads the built-in defined name used for source data from the DCONBINAME record. */
+ void importDConBIName( BiffInputStream& rStrm );
+ /** Reads the sheet name and URL from the DCONREF, DCONNAME, or DCONBINAME records. */
+ void importDConUrl( BiffInputStream& rStrm );
+
+ /** Finalizes the pivot cache if it is based on internal sheet data. */
+ void finalizeInternalSheetSource();
+ /** Finalizes the pivot cache if it is based on sheet data of an external spreadsheet document. */
+ void finalizeExternalSheetSource();
+ /** Creates a dummy sheet that will be filled with the pivot cache data. */
+ void prepareSourceDataSheet();
+
+private:
+ typedef RefVector< PivotCacheField > PivotCacheFieldVector;
+ typedef ::std::vector< sal_Int32 > IndexVector;
+
+ PivotCacheFieldVector maFields; /// All pivot cache fields.
+ PivotCacheFieldVector maDatabaseFields; /// All cache fields that are based on source data.
+ IndexVector maDatabaseIndexes; /// Database field index for all fields.
+ PCDefinitionModel maDefModel; /// Global pivot cache settings.
+ PCSourceModel maSourceModel; /// Pivot cache source settings.
+ PCWorksheetSourceModel maSheetSrcModel; /// Sheet source data if cache type is sheet.
+ ::rtl::OUString maTargetUrl; /// URL of an external source document.
+ bool mbValidSource; /// True = pivot cache is based on supported data source.
+ bool mbDummySheet; /// True = pivot cache is based on a dummy sheet.
+};
+
+// ============================================================================
+
+class PivotCacheBuffer : public WorkbookHelper
+{
+public:
+ explicit PivotCacheBuffer( const WorkbookHelper& rHelper );
+
+ /** Registers a pivot cache definition fragment. The fragment will be loaded on demand (OOXML/BIFF12 only). */
+ void registerPivotCacheFragment( sal_Int32 nCacheId, const ::rtl::OUString& rFragmentPath );
+ /** Reads the reference to a pivot cache stream. The stream will be loaded on demand (BIFF2-BIFF8 only). */
+ void importPivotCacheRef( BiffInputStream& rStrm );
+
+ /** Imports and stores a pivot cache definition fragment on first call,
+ returns the imported cache on subsequent calls with the same identifier. */
+ PivotCache* importPivotCacheFragment( sal_Int32 nCacheId );
+
+private:
+ /** Creates and returns a new pivot cache object with the passed identifier. */
+ PivotCache& createPivotCache( sal_Int32 nCacheId );
+
+private:
+ typedef ::std::map< sal_Int32, ::rtl::OUString > FragmentPathMap;
+ typedef RefMap< sal_Int32, PivotCache > PivotCacheMap;
+ typedef ::std::vector< sal_Int32 > PivotCacheIdVector;
+
+ FragmentPathMap maFragmentPaths;
+ PivotCacheMap maCaches;
+ PivotCacheIdVector maCacheIds;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/pivotcachefragment.hxx b/oox/inc/oox/xls/pivotcachefragment.hxx
new file mode 100644
index 000000000000..34a833e26525
--- /dev/null
+++ b/oox/inc/oox/xls/pivotcachefragment.hxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_PIVOTCACHEFRAGMENT_HXX
+#define OOX_XLS_PIVOTCACHEFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+class PivotCache;
+class PivotCacheField;
+
+// ============================================================================
+
+class PivotCacheFieldContext : public WorkbookContextBase
+{
+public:
+ explicit PivotCacheFieldContext(
+ WorkbookFragmentBase& rFragment,
+ PivotCacheField& rCacheField );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ PivotCacheField& mrCacheField;
+};
+
+// ============================================================================
+
+class PivotCacheDefinitionFragment : public WorkbookFragmentBase
+{
+public:
+ explicit PivotCacheDefinitionFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath,
+ PivotCache& rPivotCache );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+ virtual void finalizeImport();
+
+private:
+ PivotCache& mrPivotCache;
+};
+
+// ============================================================================
+
+class PivotCacheRecordsFragment : public WorksheetFragmentBase
+{
+public:
+ explicit PivotCacheRecordsFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath,
+ const PivotCache& rPivotCache );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+
+private:
+ void startCacheRecord();
+ void importPCRecord( SequenceInputStream& rStrm );
+ void importPCRecordItem( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+private:
+ const PivotCache& mrPivotCache;
+ sal_Int32 mnCol;
+ sal_Int32 mnRow;
+ bool mbInRecord;
+};
+
+// ============================================================================
+// ============================================================================
+
+class BiffPivotCacheFragment : public BiffWorkbookFragmentBase
+{
+public:
+ explicit BiffPivotCacheFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rStrmName,
+ PivotCache& rPivotCache );
+
+ /** Imports the entire fragment, returns true, if EOF record has been reached. */
+ virtual bool importFragment();
+
+private:
+ PivotCache& mrPivotCache;
+};
+
+// ============================================================================
+
+class BiffPivotCacheRecordsContext : public BiffWorksheetContextBase
+{
+public:
+ explicit BiffPivotCacheRecordsContext(
+ const WorkbookHelper& rHelper,
+ const PivotCache& rPivotCache );
+
+ /** Reads the current record from stream and tries to insert a cell into
+ the source data sheet. */
+ virtual void importRecord( BiffInputStream& rStrm );
+
+private:
+ void startNextRow();
+
+private:
+ typedef ::std::vector< sal_Int32 > ColumnIndexVector;
+
+ const PivotCache& mrPivotCache;
+ ColumnIndexVector maUnsharedCols; /// Column indexes of all unshared cache fields.
+ size_t mnColIdx; /// Current index into maUnsharedCols.
+ sal_Int32 mnRow; /// Current row in source data (0-based).
+ bool mbHasShared; /// True = pivot cache contains fields with shared items.
+ bool mbInRow; /// True = a data row has been started.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/pivottablebuffer.hxx b/oox/inc/oox/xls/pivottablebuffer.hxx
new file mode 100644
index 000000000000..7732037bd579
--- /dev/null
+++ b/oox/inc/oox/xls/pivottablebuffer.hxx
@@ -0,0 +1,448 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_PIVOTTABLEBUFFER_HXX
+#define OOX_XLS_PIVOTTABLEBUFFER_HXX
+
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "oox/xls/pivotcachebuffer.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XDataPilotDescriptor; }
+ namespace sheet { class XDataPilotField; }
+} } }
+
+namespace oox {
+namespace xls {
+
+class PivotTable;
+
+// ============================================================================
+
+struct PTFieldItemModel
+{
+ sal_Int32 mnCacheItem; /// Index to shared item in pivot cache.
+ sal_Int32 mnType; /// Type of the item.
+ bool mbShowDetails; /// True = show item details (items of child fields).
+ bool mbHidden; /// True = item is hidden.
+
+ explicit PTFieldItemModel();
+
+ /** Sets item type for BIFF import. */
+ void setBiffType( sal_uInt16 nType );
+};
+
+// ----------------------------------------------------------------------------
+
+struct PTFieldModel
+{
+ sal_Int32 mnAxis; /// Axis this field is assigned to (none, row, column, page).
+ sal_Int32 mnNumFmtId; /// Number format for field items.
+ sal_Int32 mnAutoShowItems; /// Number of items (or percent/sum) to be shown in auto show filter.
+ sal_Int32 mnAutoShowRankBy; /// Index of the data field auto show filter is based on.
+ sal_Int32 mnSortType; /// Autosorting type.
+ sal_Int32 mnSortRefField; /// Reference field for autosorting.
+ sal_Int32 mnSortRefItem; /// Item in reference field for autosorting.
+ bool mbDataField; /// True = field appears in data area.
+ bool mbDefaultSubtotal; /// True = show default subtotals.
+ bool mbSumSubtotal; /// True = show sum subtotals.
+ bool mbCountASubtotal; /// True = show count all subtotals.
+ bool mbAverageSubtotal; /// True = show average subtotals.
+ bool mbMaxSubtotal; /// True = show maximum subtotals.
+ bool mbMinSubtotal; /// True = show minimum subtotals.
+ bool mbProductSubtotal; /// True = show product subtotals.
+ bool mbCountSubtotal; /// True = show count numbers subtotals.
+ bool mbStdDevSubtotal; /// True = show standard deviation subtotals.
+ bool mbStdDevPSubtotal; /// True = show standard deviation of population subtotals.
+ bool mbVarSubtotal; /// True = show variance subtotals.
+ bool mbVarPSubtotal; /// True = show variance of population subtotals.
+ bool mbShowAll; /// True = show items without data.
+ bool mbOutline; /// True = show in outline view, false = show in tabular view.
+ bool mbSubtotalTop; /// True = show subtotals on top of items in outline or compact mode.
+ bool mbInsertBlankRow; /// True = insert blank rows after items.
+ bool mbInsertPageBreak; /// True = insert page breaks after items.
+ bool mbAutoShow; /// True = auto show (top 10) filter enabled.
+ bool mbTopAutoShow; /// True = auto show filter shows top entries, false = bottom.
+ bool mbMultiPageItems; /// True = multiple items selectable in page diemsion.
+
+ explicit PTFieldModel();
+
+ /** Sets axis type for BIFF import. */
+ void setBiffAxis( sal_uInt8 nAxisFlags );
+};
+
+// ----------------------------------------------------------------------------
+
+struct PTPageFieldModel
+{
+ ::rtl::OUString maName; /// Unique name of the page field.
+ sal_Int32 mnField; /// Base pivot field.
+ sal_Int32 mnItem; /// Index of field item that is shown by the page field.
+
+ explicit PTPageFieldModel();
+};
+
+// ----------------------------------------------------------------------------
+
+struct PTDataFieldModel
+{
+ ::rtl::OUString maName; /// Name of the data field.
+ sal_Int32 mnField; /// Base pivot field.
+ sal_Int32 mnSubtotal; /// Subtotal aggregation function.
+ sal_Int32 mnShowDataAs; /// Show data as, based on another field.
+ sal_Int32 mnBaseField; /// Base field for 'show data as'.
+ sal_Int32 mnBaseItem; /// Base item for 'show data as'.
+ sal_Int32 mnNumFmtId; /// Number format for the result.
+
+ explicit PTDataFieldModel();
+
+ /** Sets the subtotal aggregation function for BIFF import. */
+ void setBiffSubtotal( sal_Int32 nSubtotal );
+ /** Sets the 'show data as' type for BIFF import. */
+ void setBiffShowDataAs( sal_Int32 nShowDataAs );
+};
+
+// ----------------------------------------------------------------------------
+
+class PivotTableField : public WorkbookHelper
+{
+public:
+ explicit PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex );
+
+ /** Imports pivot field settings from the pivotField element. */
+ void importPivotField( const AttributeList& rAttribs );
+ /** Imports settings of an item in this pivot field from the item element. */
+ void importItem( const AttributeList& rAttribs );
+ /** Imports pivot field reference settings from the reference element. */
+ void importReference( const AttributeList& rAttribs );
+ /** Imports pivot field item reference settings from the x element. */
+ void importReferenceItem( const AttributeList& rAttribs );
+
+ /** Imports pivot field settings from the PTFIELD record. */
+ void importPTField( SequenceInputStream& rStrm );
+ /** Imports settings of an item in this pivot field from the PTFITEM record. */
+ void importPTFItem( SequenceInputStream& rStrm );
+ /** Imports pivot field reference settings from the PTREFERENCE record. */
+ void importPTReference( SequenceInputStream& rStrm );
+ /** Imports pivot field item reference settings from the PTREFERENCEITEM record. */
+ void importPTReferenceItem( SequenceInputStream& rStrm );
+
+ /** Imports pivot field settings from the PTFIELD and following records. */
+ void importPTField( BiffInputStream& rStrm );
+ /** Imports pivot field settings from the PTFIELD2 record. */
+ void importPTField2( BiffInputStream& rStrm );
+ /** Imports settings of an item in this pivot field from the PTFITEM record. */
+ void importPTFItem( BiffInputStream& rStrm );
+
+ /** Finalizes the field after import, creates grouping and other settings. */
+ void finalizeImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotDescriptor >& rxDPDesc );
+ /** Finalizes the grouped date field after import. */
+ void finalizeDateGroupingImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >& rxBaseDPField,
+ sal_Int32 nBaseFieldIdx );
+ /** Finalizes the grouped field after import. */
+ void finalizeParentGroupingImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >& rxBaseDPField,
+ PivotCacheGroupItemVector& orItemNames );
+
+ /** Returns the name of the DataPilot field in the fields collection. */
+ inline const ::rtl::OUString& getDPFieldName() const { return maDPFieldName; }
+
+ /** Converts dimension and other settings for a row field. */
+ void convertRowField();
+ /** Converts dimension and other settings for a column field. */
+ void convertColField();
+ /** Converts dimension and other settings for a hidden field. */
+ void convertHiddenField();
+ /** Converts dimension and other settings for a page field */
+ void convertPageField( const PTPageFieldModel& rPageField );
+ /** Converts dimension and other settings for a data field. */
+ void convertDataField( const PTDataFieldModel& rDataField );
+
+private:
+ /** Converts dimension and other settings for row, column, page, or hidden fields. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >
+ convertRowColPageField( sal_Int32 nAxis );
+
+private:
+ typedef ::std::vector< PTFieldItemModel > ItemModelVector;
+
+ PivotTable& mrPivotTable; /// The parent pivot table object.
+ ItemModelVector maItems; /// All items of this field.
+ PTFieldModel maModel; /// Pivot field settings.
+ ::rtl::OUString maDPFieldName; /// Name of the field in DataPilot field collection.
+ sal_Int32 mnFieldIndex; /// Zero-based index of this field.
+};
+
+// ============================================================================
+
+struct PTFilterModel
+{
+ ::rtl::OUString maName; /// Name of the field filter.
+ ::rtl::OUString maDescription; /// Description of the field filter.
+ ::rtl::OUString maStrValue1; /// First string value for label filter.
+ ::rtl::OUString maStrValue2; /// Second string value for label filter.
+ double mfValue; /// Number of items or percent or sum to be shown.
+ sal_Int32 mnField; /// Base pivot field.
+ sal_Int32 mnMemPropField; /// Member property field.
+ sal_Int32 mnType; /// Filter type.
+ sal_Int32 mnEvalOrder; /// Evaluation order index.
+ sal_Int32 mnId; /// Unique identifier.
+ sal_Int32 mnMeasureField; /// Data field for filter calculation.
+ sal_Int32 mnMeasureHier; /// Hierarchy for filter calculation.
+ bool mbTopFilter; /// True = filter shows top entries, false = bottom.
+
+ explicit PTFilterModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class PivotTableFilter : public WorkbookHelper
+{
+public:
+ explicit PivotTableFilter( const PivotTable& rPivotTable );
+
+ /** Reads the settings of a field filter from the filter element. */
+ void importFilter( const AttributeList& rAttribs );
+ /** Reads additional settings of a field filter from the top10 element. */
+ void importTop10( const AttributeList& rAttribs );
+
+ /** Reads the settings of a field filter from the PTFILTER record. */
+ void importPTFilter( SequenceInputStream& rStrm );
+ /** Reads additional settings of a field filter from the TOP10FILTER record. */
+ void importTop10Filter( SequenceInputStream& rStrm );
+
+ /** Applies the filter to the associated pivot table field if possible. */
+ void finalizeImport();
+
+private:
+ const PivotTable& mrPivotTable;
+ PTFilterModel maModel;
+};
+
+// ============================================================================
+
+struct PTDefinitionModel : public AutoFormatModel
+{
+ ::rtl::OUString maName;
+ ::rtl::OUString maDataCaption;
+ ::rtl::OUString maGrandTotalCaption;
+ ::rtl::OUString maRowHeaderCaption;
+ ::rtl::OUString maColHeaderCaption;
+ ::rtl::OUString maErrorCaption;
+ ::rtl::OUString maMissingCaption;
+ ::rtl::OUString maPageStyle;
+ ::rtl::OUString maPivotTableStyle;
+ ::rtl::OUString maVacatedStyle;
+ ::rtl::OUString maTag;
+ sal_Int32 mnCacheId;
+ sal_Int32 mnDataPosition;
+ sal_Int32 mnPageWrap;
+ sal_Int32 mnIndent;
+ sal_Int32 mnChartFormat;
+ sal_uInt16 mnRowFields;
+ sal_uInt16 mnColFields;
+ bool mbDataOnRows;
+ bool mbShowError;
+ bool mbShowMissing;
+ bool mbShowItems;
+ bool mbDisableFieldList;
+ bool mbShowCalcMembers;
+ bool mbVisualTotals;
+ bool mbShowDataDropDown;
+ bool mbShowDrill;
+ bool mbPrintDrill;
+ bool mbEnableDrill;
+ bool mbPreserveFormatting;
+ bool mbUseAutoFormat;
+ bool mbPageOverThenDown;
+ bool mbSubtotalHiddenItems;
+ bool mbRowGrandTotals;
+ bool mbColGrandTotals;
+ bool mbFieldPrintTitles;
+ bool mbItemPrintTitles;
+ bool mbMergeItem;
+ bool mbShowEmptyRow;
+ bool mbShowEmptyCol;
+ bool mbShowHeaders;
+ bool mbFieldListSortAsc;
+ bool mbCustomListSort;
+
+ explicit PTDefinitionModel();
+};
+
+// ----------------------------------------------------------------------------
+
+struct PTLocationModel
+{
+ ::com::sun::star::table::CellRangeAddress
+ maRange; /// Target cell range for the pivot table.
+ sal_Int32 mnFirstHeaderRow; /// First row of header cells (relative in pivot table).
+ sal_Int32 mnFirstDataRow; /// First row of data cells (relative in pivot table).
+ sal_Int32 mnFirstDataCol; /// First column of data cells (relative in pivot table).
+ sal_Int32 mnRowPageCount; /// Number of rows in page filter area.
+ sal_Int32 mnColPageCount; /// Number of columns in page filter area.
+
+ explicit PTLocationModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class PivotTable : public WorkbookHelper
+{
+public:
+ explicit PivotTable( const WorkbookHelper& rHelper );
+
+ /** Reads global pivot table settings from the pivotTableDefinition element. */
+ void importPivotTableDefinition( const AttributeList& rAttribs );
+ /** Reads the location of the pivot table from the location element. */
+ void importLocation( const AttributeList& rAttribs, sal_Int16 nSheet );
+ /** Reads the index of a field located in the row dimension. */
+ void importRowField( const AttributeList& rAttribs );
+ /** Reads the index of a field located in the column dimension. */
+ void importColField( const AttributeList& rAttribs );
+ /** Reads the settings of a field located in the page dimension from the pageField element. */
+ void importPageField( const AttributeList& rAttribs );
+ /** Reads the settings of a field located in the data dimension from the dataField element. */
+ void importDataField( const AttributeList& rAttribs );
+
+ /** Reads global pivot table settings from the PTDEFINITION record. */
+ void importPTDefinition( SequenceInputStream& rStrm );
+ /** Reads the location of the pivot table from the PTLOCATION record. */
+ void importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet );
+ /** Reads the indexes of all fields located in the row dimension from a PTROWFIELDS record. */
+ void importPTRowFields( SequenceInputStream& rStrm );
+ /** Reads the indexes of all fields located in the column dimension from a PTCOLFIELDS record. */
+ void importPTColFields( SequenceInputStream& rStrm );
+ /** Reads the settings of a field located in the page dimension from the PTPAGEFIELD record. */
+ void importPTPageField( SequenceInputStream& rStrm );
+ /** Reads the settings of a field located in the data dimension from the PTDATAFIELD record. */
+ void importPTDataField( SequenceInputStream& rStrm );
+
+ /** Reads global pivot table settings from the PTDEFINITION record. */
+ void importPTDefinition( BiffInputStream& rStrm, sal_Int16 nSheet );
+ /** Reads additional global pivot table settings from the PTDEFINITION2 record. */
+ void importPTDefinition2( BiffInputStream& rStrm );
+ /** Reads the indexes of all fields located in the row or column dimension from a PTROWCOLFIELDS record. */
+ void importPTRowColFields( BiffInputStream& rStrm );
+ /** Reads the settings of all fields located in the page dimension from a PTPAGEFIELDS record. */
+ void importPTPageFields( BiffInputStream& rStrm );
+ /** Reads the settings of a field located in the data dimension from a PTDATAFIELD record. */
+ void importPTDataField( BiffInputStream& rStrm );
+
+ /** Creates and returns a new pivot table field. */
+ PivotTableField& createTableField();
+ /** Creates and returns a new pivot table filter. */
+ PivotTableFilter& createTableFilter();
+ /** Inserts the pivot table into the sheet. */
+ void finalizeImport();
+ /** Creates all date group fields for the specified cache field after import. */
+ void finalizeDateGroupingImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >& rxBaseDPField,
+ sal_Int32 nBaseFieldIdx );
+ /** Creates all grouped fields for the specified cache field after import. */
+ void finalizeParentGroupingImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >& rxBaseDPField,
+ const PivotCacheField& rBaseCacheField,
+ PivotCacheGroupItemVector& orItemNames );
+
+ /** Returns the associated data pilot field for the specified pivot table field. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >
+ getDataPilotField( const ::rtl::OUString& rFieldName ) const;
+ /** Returns the associated data pilot field for the specified pivot table field. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >
+ getDataPilotField( sal_Int32 nFieldIdx ) const;
+ /** Returns the data layout field used to store all data fields in row/col dimension. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotField >
+ getDataLayoutField() const;
+
+ /** Returns the cache field with the specified index. */
+ const PivotCacheField* getCacheField( sal_Int32 nFieldIdx ) const;
+ /** Returns the base cache field of the data field item with the specified index. */
+ const PivotCacheField* getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const;
+ /** Returns the source column index of the pivot field with the passed index, or -1. */
+ sal_Int32 getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const;
+
+private:
+ typedef RefVector< PivotTableField > PivotTableFieldVector;
+ typedef RefVector< PivotTableFilter > PivotTableFilterVector;
+ typedef ::std::vector< sal_Int32 > IndexVector;
+ typedef ::std::vector< PTPageFieldModel > PageFieldVector;
+ typedef ::std::vector< PTDataFieldModel > DataFieldVector;
+
+private:
+ /** Returns a pivot table field by its index. */
+ PivotTableField* getTableField( sal_Int32 nFieldIdx );
+
+ /** Reads a field index for the row or column dimension. */
+ static void importField( IndexVector& orFields, const AttributeList& rAttribs );
+ /** Reads an array of field indexes for the row or column dimension. */
+ static void importFields( IndexVector& orFields, SequenceInputStream& rStrm );
+ /** Reads an array of field indexes for the row or column dimension. */
+ static void importFields( IndexVector& orFields, BiffInputStream& rStrm, sal_Int32 nCount );
+
+private:
+ PivotTableFieldVector maFields; /// All pivot table fields.
+ PivotTableField maDataField; /// Data layout field.
+ IndexVector maRowFields; /// Indexes to fields in row dimension.
+ IndexVector maColFields; /// Indexes to fields in column dimension.
+ PageFieldVector maPageFields; /// Settings for all fields in page dimension.
+ DataFieldVector maDataFields; /// Settings for all fields in data area.
+ PivotTableFilterVector maFilters; /// All field filters.
+ PTDefinitionModel maDefModel; /// Global pivot table settings.
+ PTLocationModel maLocationModel; /// Location settings of the pivot table.
+ const PivotCache* mpPivotCache; /// The pivot cache this table is based on.
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDataPilotDescriptor >
+ mxDPDescriptor; /// Descriptor of the DataPilot object.
+};
+
+// ============================================================================
+
+class PivotTableBuffer : public WorkbookHelper
+{
+public:
+ explicit PivotTableBuffer( const WorkbookHelper& rHelper );
+
+ /** Creates and returns a new pivot table. */
+ PivotTable& createPivotTable();
+
+ /** Inserts all pivot tables into the sheet. */
+ void finalizeImport();
+
+private:
+ typedef RefVector< PivotTable > PivotTableVector;
+ PivotTableVector maTables;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/pivottablefragment.hxx b/oox/inc/oox/xls/pivottablefragment.hxx
new file mode 100644
index 000000000000..aafae063990c
--- /dev/null
+++ b/oox/inc/oox/xls/pivottablefragment.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_PIVOTTABLEFRAGMENT_HXX
+#define OOX_XLS_PIVOTTABLEFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox {
+namespace xls {
+
+class PivotTable;
+class PivotTableField;
+class PivotTableFilter;
+
+// ============================================================================
+
+class PivotTableFieldContext : public WorksheetContextBase
+{
+public:
+ explicit PivotTableFieldContext(
+ WorksheetFragmentBase& rFragment,
+ PivotTableField& rTableField );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ PivotTableField& mrTableField;
+};
+
+// ============================================================================
+
+class PivotTableFilterContext : public WorksheetContextBase
+{
+public:
+ explicit PivotTableFilterContext(
+ WorksheetFragmentBase& rFragment,
+ PivotTableFilter& rTableFilter );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ PivotTableFilter& mrTableFilter;
+};
+
+// ============================================================================
+
+class PivotTableFragment : public WorksheetFragmentBase
+{
+public:
+ explicit PivotTableFragment(
+ const WorksheetHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+
+private:
+ PivotTable& mrPivotTable;
+};
+
+// ============================================================================
+// ============================================================================
+
+class BiffPivotTableContext : public BiffWorksheetContextBase
+{
+public:
+ explicit BiffPivotTableContext( const WorksheetHelper& rHelper );
+
+ /** Imports all records related to the current pivot table. */
+ virtual void importRecord( BiffInputStream& rStrm );
+
+private:
+ PivotTable& mrPivotTable;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/querytablebuffer.hxx b/oox/inc/oox/xls/querytablebuffer.hxx
new file mode 100644
index 000000000000..fa67ca8874c0
--- /dev/null
+++ b/oox/inc/oox/xls/querytablebuffer.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_QUERYTABLEBUFFER_HXX
+#define OOX_XLS_QUERYTABLEBUFFER_HXX
+
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+struct QueryTableModel : public AutoFormatModel
+{
+ ::rtl::OUString maDefName; /// Defined name containing the target cell range.
+ sal_Int32 mnConnId; /// Identifier of the external connection used to query the data.
+ sal_Int32 mnGrowShrinkType; /// Behaviour when source data size changes.
+ bool mbHeaders; /// True = source data contains a header row.
+ bool mbRowNumbers; /// True = first column contains row numbers.
+ bool mbDisableRefresh; /// True = refreshing data disabled.
+ bool mbBackground; /// True = refresh asynchronously.
+ bool mbFirstBackground; /// True = first background refresh not yet finished.
+ bool mbRefreshOnLoad; /// True = refresh table after import.
+ bool mbFillFormulas; /// True = expand formulas next to range when source data grows.
+ bool mbRemoveDataOnSave; /// True = remove querried data before saving.
+ bool mbDisableEdit; /// True = connection locked for editing.
+ bool mbPreserveFormat; /// True = use existing formatting for new rows.
+ bool mbAdjustColWidth; /// True = adjust column widths after refresh.
+ bool mbIntermediate; /// True = query table defined but not built yet.
+
+ explicit QueryTableModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class QueryTable : public WorksheetHelper
+{
+public:
+ explicit QueryTable( const WorksheetHelper& rHelper );
+
+ /** Imports query table settings from the queryTable element. */
+ void importQueryTable( const AttributeList& rAttribs );
+ /** Imports query table settings from the QUERYTABLE record. */
+ void importQueryTable( SequenceInputStream& rStrm );
+
+ /** Imports query table settings from the QUERYTABLE record. */
+ void importQueryTable( BiffInputStream& rStrm );
+ /** Imports query table settings from the QUERYTABLEREFRESH record. */
+ void importQueryTableRefresh( BiffInputStream& rStrm );
+ /** Imports query table settings from the QUERYTABLESETTINGS record. */
+ void importQueryTableSettings( BiffInputStream& rStrm );
+
+ /** Inserts a web query into the sheet. */
+ void finalizeImport();
+
+private:
+ QueryTableModel maModel;
+};
+
+// ============================================================================
+
+class QueryTableBuffer : public WorksheetHelper
+{
+public:
+ explicit QueryTableBuffer( const WorksheetHelper& rHelper );
+
+ /** Creates a new query table and stores it into the internal vector. */
+ QueryTable& createQueryTable();
+
+ /** Inserts all web queries into the sheet. */
+ void finalizeImport();
+
+private:
+ typedef RefVector< QueryTable > QueryTableVector;
+ QueryTableVector maQueryTables;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/querytablefragment.hxx b/oox/inc/oox/xls/querytablefragment.hxx
new file mode 100644
index 000000000000..6eb561aa5a5e
--- /dev/null
+++ b/oox/inc/oox/xls/querytablefragment.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_QUERYTABLEFRAGMENT_HXX
+#define OOX_XLS_QUERYTABLEFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+class QueryTable;
+
+// ============================================================================
+
+class QueryTableFragment : public WorksheetFragmentBase
+{
+public:
+ explicit QueryTableFragment(
+ const WorksheetHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+
+private:
+ QueryTable& mrQueryTable;
+};
+
+// ============================================================================
+
+class BiffQueryTableContext : public BiffWorksheetContextBase
+{
+public:
+ explicit BiffQueryTableContext( const WorksheetHelper& rHelper );
+
+ /** Imports all records related to the current query table. */
+ virtual void importRecord( BiffInputStream& rStrm );
+
+private:
+ QueryTable& mrQueryTable;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/richstring.hxx b/oox/inc/oox/xls/richstring.hxx
new file mode 100644
index 000000000000..f21e2a021111
--- /dev/null
+++ b/oox/inc/oox/xls/richstring.hxx
@@ -0,0 +1,294 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_RICHSTRING_HXX
+#define OOX_XLS_RICHSTRING_HXX
+
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace text { class XText; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Flags used to specify import/export mode of strings. */
+typedef sal_Int32 BiffStringFlags;
+
+const BiffStringFlags BIFF_STR_DEFAULT = 0x0000; /// Default string settings.
+const BiffStringFlags BIFF_STR_FORCEUNICODE = 0x0001; /// Always use UCS-2 characters (default: try to compress). BIFF8 export only.
+const BiffStringFlags BIFF_STR_8BITLENGTH = 0x0002; /// 8-bit string length field (default: 16-bit).
+const BiffStringFlags BIFF_STR_SMARTFLAGS = 0x0004; /// Omit flags on empty string (default: read/write always). BIFF8 only.
+const BiffStringFlags BIFF_STR_KEEPFONTS = 0x0008; /// Keep old fonts when reading unformatted string (default: clear fonts). Import only.
+const BiffStringFlags BIFF_STR_EXTRAFONTS = 0x0010; /// Read trailing rich-string font array (default: nothing). BIFF2-BIFF5 import only.
+
+// ============================================================================
+
+/** Contains text data and font attributes for a part of a rich formatted string. */
+class RichStringPortion : public WorkbookHelper
+{
+public:
+ explicit RichStringPortion( const WorkbookHelper& rHelper );
+
+ /** Sets text data for this portion. */
+ void setText( const ::rtl::OUString& rText );
+ /** Creates and returns a new font formatting object. */
+ FontRef createFont();
+ /** Links this portion to a font object from the global font list. */
+ void setFontId( sal_Int32 nFontId );
+
+ /** Final processing after import of all strings. */
+ void finalizeImport();
+
+ /** Returns the text data of this portion. */
+ inline const ::rtl::OUString& getText() const { return maText; }
+
+ /** Converts the portion and appends it to the passed XText. */
+ void convert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >& rxText,
+ sal_Int32 nXfId );
+
+private:
+ ::rtl::OUString maText; /// Portion text.
+ FontRef mxFont; /// Embedded portion font, may be empty.
+ sal_Int32 mnFontId; /// Link to global font list.
+};
+
+typedef ::boost::shared_ptr< RichStringPortion > RichStringPortionRef;
+
+// ----------------------------------------------------------------------------
+
+enum BiffFontPortionMode
+{
+ BIFF_FONTPORTION_8BIT, /// Font portion with 8-bit values.
+ BIFF_FONTPORTION_16BIT, /// Font portion with 16-bit values.
+ BIFF_FONTPORTION_OBJ /// Font portion in OBJ or TXO record.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Represents a position in a rich-string containing current font identifier.
+
+ This object stores the position of a formatted character in a rich-string
+ and the identifier of a font from the global font list used to format this
+ and the following characters. Used in binary filters only.
+ */
+struct FontPortionModel
+{
+ sal_Int32 mnPos; /// First character in the string.
+ sal_Int32 mnFontId; /// Font identifier for the next characters.
+
+ explicit inline FontPortionModel() : mnPos( 0 ), mnFontId( -1 ) {}
+ explicit inline FontPortionModel( sal_Int32 nPos, sal_Int32 nFontId ) :
+ mnPos( nPos ), mnFontId( nFontId ) {}
+
+ void read( SequenceInputStream& rStrm );
+ void read( BiffInputStream& rStrm, BiffFontPortionMode eMode );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A vector with all font portions in a rich-string. */
+class FontPortionModelList : public ::std::vector< FontPortionModel >
+{
+public:
+ inline explicit FontPortionModelList() {}
+
+ /** Appends a rich-string font identifier. */
+ void appendPortion( const FontPortionModel& rPortion );
+ /** Reads count and font identifiers from the passed stream. */
+ void importPortions( SequenceInputStream& rStrm );
+ /** Reads nCount font identifiers from the passed stream. */
+ void importPortions( BiffInputStream& rStrm, sal_uInt16 nCount, BiffFontPortionMode eMode );
+ /** Reads count and font identifiers from the passed stream. */
+ void importPortions( BiffInputStream& rStrm, bool b16Bit );
+};
+
+// ============================================================================
+
+struct PhoneticDataModel
+{
+ sal_Int32 mnFontId; /// Font identifier for text formatting.
+ sal_Int32 mnType; /// Phonetic text type.
+ sal_Int32 mnAlignment; /// Phonetic portion alignment.
+
+ explicit PhoneticDataModel();
+
+ /** Sets the passed data from binary import. */
+ void setBiffData( sal_Int32 nType, sal_Int32 nAlignment );
+};
+
+// ----------------------------------------------------------------------------
+
+class PhoneticSettings : public WorkbookHelper
+{
+public:
+ explicit PhoneticSettings( const WorkbookHelper& rHelper );
+
+ /** Imports phonetic settings from the phoneticPr element. */
+ void importPhoneticPr( const AttributeList& rAttribs );
+ /** Imports phonetic settings from the PHONETICPR record. */
+ void importPhoneticPr( SequenceInputStream& rStrm );
+ /** Imports phonetic settings from the PHONETICPR record. */
+ void importPhoneticPr( BiffInputStream& rStrm );
+
+ /** Imports phonetic settings from a rich string. */
+ void importStringData( SequenceInputStream& rStrm );
+ /** Imports phonetic settings from a rich string. */
+ void importStringData( BiffInputStream& rStrm );
+
+private:
+ PhoneticDataModel maModel;
+};
+
+// ============================================================================
+
+/** Contains text data and positioning information for a phonetic text portion. */
+class RichStringPhonetic : public WorkbookHelper
+{
+public:
+ explicit RichStringPhonetic( const WorkbookHelper& rHelper );
+
+ /** Sets text data for this phonetic portion. */
+ void setText( const ::rtl::OUString& rText );
+ /** Imports attributes of a phonetic run (rPh element). */
+ void importPhoneticRun( const AttributeList& rAttribs );
+ /** Sets the associated range in base text for this phonetic portion. */
+ void setBaseRange( sal_Int32 nBasePos, sal_Int32 nBaseEnd );
+
+private:
+ ::rtl::OUString maText; /// Portion text.
+ sal_Int32 mnBasePos; /// Start position in base text.
+ sal_Int32 mnBaseEnd; /// One-past-end position in base text.
+};
+
+typedef ::boost::shared_ptr< RichStringPhonetic > RichStringPhoneticRef;
+
+// ----------------------------------------------------------------------------
+
+/** Represents a phonetic text portion in a rich-string with phonetic text.
+ Used in binary filters only. */
+struct PhoneticPortionModel
+{
+ sal_Int32 mnPos; /// First character in phonetic text.
+ sal_Int32 mnBasePos; /// First character in base text.
+ sal_Int32 mnBaseLen; /// Number of characters in base text.
+
+ explicit inline PhoneticPortionModel() : mnPos( -1 ), mnBasePos( -1 ), mnBaseLen( 0 ) {}
+ explicit inline PhoneticPortionModel( sal_Int32 nPos, sal_Int32 nBasePos, sal_Int32 nBaseLen ) :
+ mnPos( nPos ), mnBasePos( nBasePos ), mnBaseLen( nBaseLen ) {}
+
+ void read( SequenceInputStream& rStrm );
+ void read( BiffInputStream& rStrm );
+};
+
+// ----------------------------------------------------------------------------
+
+/** A vector with all phonetic portions in a rich-string. */
+class PhoneticPortionModelList : public ::std::vector< PhoneticPortionModel >
+{
+public:
+ inline explicit PhoneticPortionModelList() {}
+
+ /** Appends a rich-string phonetic portion. */
+ void appendPortion( const PhoneticPortionModel& rPortion );
+ /** Reads all phonetic portions from the passed stream. */
+ void importPortions( SequenceInputStream& rStrm );
+ /** Reads phonetic portion data from the passed stream. */
+ ::rtl::OUString importPortions( BiffInputStream& rStrm, sal_Int32 nPhoneticSize );
+};
+
+// ============================================================================
+
+/** Contains string data and a list of formatting runs for a rich formatted string. */
+class RichString : public WorkbookHelper
+{
+public:
+ explicit RichString( const WorkbookHelper& rHelper );
+
+ /** Appends and returns a portion object for a plain string (t element). */
+ RichStringPortionRef importText( const AttributeList& rAttribs );
+ /** Appends and returns a portion object for a new formatting run (r element). */
+ RichStringPortionRef importRun( const AttributeList& rAttribs );
+ /** Appends and returns a phonetic text object for a new phonetic run (rPh element). */
+ RichStringPhoneticRef importPhoneticRun( const AttributeList& rAttribs );
+ /** Imports phonetic settings from the rPhoneticPr element. */
+ void importPhoneticPr( const AttributeList& rAttribs );
+
+ /** Imports a Unicode rich-string from the passed record stream. */
+ void importString( SequenceInputStream& rStrm, bool bRich );
+
+ /** Imports a byte string from the passed BIFF stream. */
+ void importByteString( BiffInputStream& rStrm, rtl_TextEncoding eDefaultTextEnc, BiffStringFlags nFlags = BIFF_STR_DEFAULT );
+ /** Imports a Unicode rich-string from the passed BIFF stream. */
+ void importUniString( BiffInputStream& rStrm, BiffStringFlags nFlags = BIFF_STR_DEFAULT );
+
+ /** Final processing after import of all strings. */
+ void finalizeImport();
+
+ /** Returns the plain text concatenated from all string portions. */
+ ::rtl::OUString getPlainText() const;
+
+ /** Converts the string and writes it into the passed XText. */
+ void convert(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >& rxText,
+ sal_Int32 nXfId ) const;
+
+private:
+ /** Creates, appends, and returns a new empty string portion. */
+ RichStringPortionRef createPortion();
+ /** Creates, appends, and returns a new empty phonetic text portion. */
+ RichStringPhoneticRef createPhonetic();
+
+ /** Create base text portions from the passed string and character formatting. */
+ void createFontPortions( const ::rtl::OString& rText, rtl_TextEncoding eDefaultTextEnc, FontPortionModelList& rPortions );
+ /** Create base text portions from the passed string and character formatting. */
+ void createFontPortions( const ::rtl::OUString& rText, FontPortionModelList& rPortions );
+ /** Create phonetic text portions from the passed string and portion data. */
+ void createPhoneticPortions( const ::rtl::OUString& rText, PhoneticPortionModelList& rPortions, sal_Int32 nBaseLen );
+
+private:
+ typedef RefVector< RichStringPortion > PortionVec;
+ typedef RefVector< RichStringPhonetic > PhoneticVec;
+
+ PortionVec maFontPortions; /// String portions with font data.
+ PhoneticSettings maPhonSettings; /// Phonetic settings for this string.
+ PhoneticVec maPhonPortions; /// Phonetic text portions.
+};
+
+typedef ::boost::shared_ptr< RichString > RichStringRef;
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/richstringcontext.hxx b/oox/inc/oox/xls/richstringcontext.hxx
new file mode 100644
index 000000000000..df3f412d87ec
--- /dev/null
+++ b/oox/inc/oox/xls/richstringcontext.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_RICHSTRINGCONTEXT_HXX
+#define OOX_XLS_RICHSTRINGCONTEXT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/richstring.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class RichStringContext : public WorkbookContextBase
+{
+public:
+ template< typename ParentType >
+ explicit RichStringContext( ParentType& rParent, RichStringRef xString );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+private:
+ RichStringRef mxString; /// Processed string.
+ RichStringPortionRef mxPortion; /// Processed portion in the string.
+ RichStringPhoneticRef mxPhonetic; /// Processed phonetic text portion.
+ FontRef mxFont; /// Processed font of the portion.
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename ParentType >
+RichStringContext::RichStringContext( ParentType& rParent, RichStringRef xString ) :
+ WorkbookContextBase( rParent ),
+ mxString( xString )
+{
+ OSL_ENSURE( mxString.get(), "RichStringContext::RichStringContext - missing string object" );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/scenariobuffer.hxx b/oox/inc/oox/xls/scenariobuffer.hxx
new file mode 100644
index 000000000000..ed8d4e919bd2
--- /dev/null
+++ b/oox/inc/oox/xls/scenariobuffer.hxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_SCENARIOBUFFER_HXX
+#define OOX_XLS_SCENARIOBUFFER_HXX
+
+#include <com/sun/star/table/CellAddress.hpp>
+#include "oox/helper/refmap.hxx"
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+struct ScenarioCellModel
+{
+ ::com::sun::star::table::CellAddress maPos;
+ ::rtl::OUString maValue;
+ sal_Int32 mnNumFmtId;
+ bool mbDeleted;
+
+ explicit ScenarioCellModel();
+};
+
+// ----------------------------------------------------------------------------
+
+struct ScenarioModel
+{
+ ::rtl::OUString maName; /// Name of the scenario.
+ ::rtl::OUString maComment; /// Comment.
+ ::rtl::OUString maUser; /// Name of user created the scenario.
+ bool mbLocked; /// True = input cell values locked.
+ bool mbHidden; /// True = scenario is hidden.
+
+ explicit ScenarioModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class Scenario : public WorkbookHelper
+{
+public:
+ explicit Scenario( const WorkbookHelper& rHelper, sal_Int16 nSheet );
+
+ /** Imports a scenario definition from a scenario element. */
+ void importScenario( const AttributeList& rAttribs );
+ /** Imports a new cell for this scenario from a inputCells element. */
+ void importInputCells( const AttributeList& rAttribs );
+
+ /** Imports a scenario definition from a SCENARIO record. */
+ void importScenario( SequenceInputStream& rStrm );
+ /** Imports a new cell for this scenario from a INPUTCELLS record. */
+ void importInputCells( SequenceInputStream& rStrm );
+
+ /** Imports a scenario definition from a SCENARIO record. */
+ void importScenario( BiffInputStream& rStrm );
+
+ /** Creates the scenario in the Calc document. */
+ void finalizeImport();
+
+private:
+ typedef ::std::vector< ScenarioCellModel > ScenarioCellVector;
+
+ ScenarioCellVector maCells; /// Scenario cells.
+ ScenarioModel maModel; /// Scenario model data.
+ sal_Int16 mnSheet; /// Index of the sheet this scenario is based on.
+};
+
+// ============================================================================
+
+struct SheetScenariosModel
+{
+ sal_Int32 mnCurrent; /// Selected scenario.
+ sal_Int32 mnShown; /// Visible scenario.
+
+ explicit SheetScenariosModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class SheetScenarios : public WorkbookHelper
+{
+public:
+ explicit SheetScenarios( const WorkbookHelper& rHelper, sal_Int16 nSheet );
+
+ /** Imports sheet scenario settings from a scenarios element. */
+ void importScenarios( const AttributeList& rAttribs );
+ /** Imports sheet scenario settings from a SCENARIOS record. */
+ void importScenarios( SequenceInputStream& rStrm );
+ /** Imports sheet scenario settings from a SCENARIOS record. */
+ void importScenarios( BiffInputStream& rStrm );
+
+ /** Creates and returns a new scenario in this collection. */
+ Scenario& createScenario();
+
+ /** Creates all scenarios in the Calc sheet. */
+ void finalizeImport();
+
+private:
+ typedef RefVector< Scenario > ScenarioVector;
+ ScenarioVector maScenarios;
+ SheetScenariosModel maModel;
+ sal_Int16 mnSheet;
+};
+
+// ============================================================================
+
+class ScenarioBuffer : public WorkbookHelper
+{
+public:
+ explicit ScenarioBuffer( const WorkbookHelper& rHelper );
+
+ /** Creates and returns a scenario collection for the passed sheet. */
+ SheetScenarios& createSheetScenarios( sal_Int16 nSheet );
+
+ /** Creates all scenarios in the Calc dcument. */
+ void finalizeImport();
+
+private:
+ typedef RefMap< sal_Int16, SheetScenarios, ::std::greater< sal_Int16 > > SheetScenariosMap;
+ SheetScenariosMap maSheetScenarios;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/scenariocontext.hxx b/oox/inc/oox/xls/scenariocontext.hxx
new file mode 100644
index 000000000000..3e6ccc5c22d6
--- /dev/null
+++ b/oox/inc/oox/xls/scenariocontext.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_SCENARIOCONTEXT_HXX
+#define OOX_XLS_SCENARIOCONTEXT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+class Scenario;
+class SheetScenarios;
+
+// ============================================================================
+
+class ScenarioContext : public WorksheetContextBase
+{
+public:
+ explicit ScenarioContext( WorksheetContextBase& rParent, SheetScenarios& rSheetScenarios );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ Scenario& mrScenario;
+};
+
+// ============================================================================
+
+class ScenariosContext : public WorksheetContextBase
+{
+public:
+ explicit ScenariosContext( WorksheetFragmentBase& rFragment );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onStartElement( const AttributeList& rAttribs );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+ virtual void onStartRecord( SequenceInputStream& rStrm );
+
+private:
+ SheetScenarios& mrSheetScenarios;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/sharedformulabuffer.hxx b/oox/inc/oox/xls/sharedformulabuffer.hxx
new file mode 100644
index 000000000000..94b7572dcfd9
--- /dev/null
+++ b/oox/inc/oox/xls/sharedformulabuffer.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_SHAREDFORMULABUFFER_HXX
+#define OOX_XLS_SHAREDFORMULABUFFER_HXX
+
+#include <map>
+#include <memory>
+#include "oox/xls/worksheethelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XFormulaTokens; }
+ namespace sheet { class XNamedRange; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Formula context that supports shared formulas. */
+class ExtCellFormulaContext : public SimpleFormulaContext, public WorksheetHelper
+{
+public:
+ explicit ExtCellFormulaContext(
+ const WorksheetHelper& rHelper,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaTokens >& rxTokens,
+ const ::com::sun::star::table::CellAddress& rCellPos );
+
+ virtual void setSharedFormula( const ::com::sun::star::table::CellAddress& rBaseAddr );
+};
+
+// ============================================================================
+
+class SharedFormulaBuffer : public WorksheetHelper
+{
+public:
+ explicit SharedFormulaBuffer( const WorksheetHelper& rHelper );
+
+ /** Imports a shared formula from a OOXML formula string. */
+ void importSharedFmla( const ::rtl::OUString& rFormula,
+ const ::rtl::OUString& rSharedRange, sal_Int32 nId,
+ const ::com::sun::star::table::CellAddress& rBaseAddr );
+ /** Imports a shared formula from a SHAREDFORMULA record in the passed stream */
+ void importSharedFmla( SequenceInputStream& rStrm,
+ const ::com::sun::star::table::CellAddress& rBaseAddr );
+ /** Imports a shared formula from a SHAREDFMLA record in the passed stream. */
+ void importSharedFmla( BiffInputStream& rStrm,
+ const ::com::sun::star::table::CellAddress& rBaseAddr );
+
+ /** Inserts a shared formula with the passed base address into a cell
+ described by the passed formula context. */
+ void setSharedFormulaCell(
+ ExtCellFormulaContext& rContext,
+ const ::com::sun::star::table::CellAddress& rBaseAddr );
+ /** Inserts a shared formula with the passed base address into a cell
+ described by the passed formula context. */
+ void setSharedFormulaCell(
+ ExtCellFormulaContext& rContext,
+ sal_Int32 nSharedId );
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange >
+ createDefinedName( const BinAddress& rMapKey );
+
+ bool implSetSharedFormulaCell(
+ ExtCellFormulaContext& rContext,
+ const BinAddress& rMapKey );
+
+ void updateCachedCell(
+ const ::com::sun::star::table::CellAddress& rBaseAddr,
+ const BinAddress& rMapKey );
+
+private:
+ typedef ::std::map< BinAddress, sal_Int32 > TokenIndexMap;
+ typedef ::std::auto_ptr< ExtCellFormulaContext > ContextPtr;
+
+ TokenIndexMap maIndexMap; /// Maps shared formula base address to defined name identifier.
+ ContextPtr mxLastContext; /// Cached formula context for leading formula cell.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/sharedstringsbuffer.hxx b/oox/inc/oox/xls/sharedstringsbuffer.hxx
new file mode 100644
index 000000000000..eff8ab4e7738
--- /dev/null
+++ b/oox/inc/oox/xls/sharedstringsbuffer.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_SHAREDSTRINGSBUFFER_HXX
+#define OOX_XLS_SHAREDSTRINGSBUFFER_HXX
+
+#include "oox/xls/richstring.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Collects all strings from the shared strings substream. */
+class SharedStringsBuffer : public WorkbookHelper
+{
+public:
+ explicit SharedStringsBuffer( const WorkbookHelper& rHelper );
+
+ /** Creates and returns a new string entry. */
+ RichStringRef createRichString();
+ /** Imports the complete shared string table from a BIFF file. */
+ void importSst( BiffInputStream& rStrm );
+
+ /** Final processing after import of all strings. */
+ void finalizeImport();
+
+ /** Converts the specified string table entry. */
+ void convertString(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >& rxText,
+ sal_Int32 nStringId,
+ sal_Int32 nXfId ) const;
+
+private:
+ typedef RefVector< RichString > StringVec;
+ StringVec maStrings;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/sharedstringsfragment.hxx b/oox/inc/oox/xls/sharedstringsfragment.hxx
new file mode 100644
index 000000000000..bc3a23122d19
--- /dev/null
+++ b/oox/inc/oox/xls/sharedstringsfragment.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_SHAREDSTRINGSFRAGMENT_HXX
+#define OOX_XLS_SHAREDSTRINGSFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class SharedStringsFragment : public WorkbookFragmentBase
+{
+public:
+ explicit SharedStringsFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+ virtual void finalizeImport();
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/sheetdatacontext.hxx b/oox/inc/oox/xls/sheetdatacontext.hxx
new file mode 100644
index 000000000000..fdbc0ba21231
--- /dev/null
+++ b/oox/inc/oox/xls/sheetdatacontext.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_SHEETDATACONTEXT_HXX
+#define OOX_XLS_SHEETDATACONTEXT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/richstring.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace table { class XCell; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** This class implements importing the sheetData element.
+
+ The sheetData element contains all row settings and all cells in a single
+ sheet of a spreadsheet document.
+ */
+class SheetDataContext : public WorksheetContextBase
+{
+public:
+ explicit SheetDataContext( WorksheetFragmentBase& rFragment );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+private:
+ /** Different types of cell records. */
+ enum CellType { CELLTYPE_VALUE, CELLTYPE_MULTI, CELLTYPE_FORMULA };
+
+ /** Imports row settings from a row element. */
+ void importRow( const AttributeList& rAttribs );
+ /** Imports cell settings from a c element. */
+ void importCell( const AttributeList& rAttribs );
+ /** Imports cell settings from an f element. */
+ void importFormula( const AttributeList& rAttribs );
+
+ /** Imports a cell address and the following XF identifier. */
+ void importCellHeader( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports an empty cell from a CELL_BLANK or MULTCELL_BLANK record. */
+ void importCellBlank( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports a boolean cell from a CELL_BOOL, MULTCELL_BOOL, or FORMULA_BOOL record. */
+ void importCellBool( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports a numeric cell from a CELL_DOUBLE, MULTCELL_DOUBLE, or FORMULA_DOUBLE record. */
+ void importCellDouble( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports an error code cell from a CELL_ERROR, MULTCELL_ERROR, or FORMULA_ERROR record. */
+ void importCellError( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports an encoded numeric cell from a CELL_RK or MULTCELL_RK record. */
+ void importCellRk( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports a rich-string cell from a CELL_RSTRING or MULTCELL_RSTRING record. */
+ void importCellRString( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports a string cell from a CELL_SI or MULTCELL_SI record. */
+ void importCellSi( SequenceInputStream& rStrm, CellType eCellType );
+ /** Imports a string cell from a CELL_STRING, MULTCELL_STRING, or FORMULA_STRING record. */
+ void importCellString( SequenceInputStream& rStrm, CellType eCellType );
+
+ /** Imports a cell formula for the current cell. */
+ void importCellFormula( SequenceInputStream& rStrm );
+
+ /** Imports row settings from a ROW record. */
+ void importRow( SequenceInputStream& rStrm );
+ /** Imports an array formula from an ARRAY record. */
+ void importArray( SequenceInputStream& rStrm );
+ /** Imports a shared formula from a SHAREDFORMULA record. */
+ void importSharedFmla( SequenceInputStream& rStrm );
+ /** Imports table operation from a DATATABLE record. */
+ void importDataTable( SequenceInputStream& rStrm );
+
+private:
+ CellModel maCurrCell; /// Position and formatting of current imported cell.
+ DataTableModel maTableData; /// Additional data for table operation ranges.
+ BinAddress maCurrPos; /// Current position for binary import.
+ RichStringRef mxInlineStr; /// Inline rich string from 'is' element.
+};
+
+// ============================================================================
+
+/** This class implements importing row settings and all cells of a sheet.
+ */
+class BiffSheetDataContext : public BiffWorksheetContextBase
+{
+public:
+ explicit BiffSheetDataContext( const WorksheetHelper& rHelper );
+
+ /** Tries to import a sheet data record. */
+ virtual void importRecord( BiffInputStream& rStrm );
+
+private:
+ /** Sets current cell according to the passed address. */
+ void setCurrCell( const BinAddress& rAddr );
+
+ /** Imports an XF identifier and sets the mnXfId member. */
+ void importXfId( BiffInputStream& rStrm, bool bBiff2 );
+ /** Imports a BIFF cell address and the following XF identifier. */
+ void importCellHeader( BiffInputStream& rStrm, bool bBiff2 );
+
+ /** Imports a BLANK record describing a blank but formatted cell. */
+ void importBlank( BiffInputStream& rStrm );
+ /** Imports a BOOLERR record describing a boolean or error code cell. */
+ void importBoolErr( BiffInputStream& rStrm );
+ /** Imports a FORMULA record describing a formula cell. */
+ void importFormula( BiffInputStream& rStrm );
+ /** Imports an INTEGER record describing a BIFF2 integer cell. */
+ void importInteger( BiffInputStream& rStrm );
+ /** Imports a LABEL record describing an unformatted string cell. */
+ void importLabel( BiffInputStream& rStrm );
+ /** Imports a LABELSST record describing a string cell using the shared string list. */
+ void importLabelSst( BiffInputStream& rStrm );
+ /** Imports a MULTBLANK record describing a range of blank but formatted cells. */
+ void importMultBlank( BiffInputStream& rStrm );
+ /** Imports a MULTRK record describing a range of numeric cells. */
+ void importMultRk( BiffInputStream& rStrm );
+ /** Imports a NUMBER record describing a floating-point cell. */
+ void importNumber( BiffInputStream& rStrm );
+ /** Imports an RK record describing a numeric cell. */
+ void importRk( BiffInputStream& rStrm );
+
+ /** Imports row settings from a ROW record. */
+ void importRow( BiffInputStream& rStrm );
+ /** Imports an ARRAY record describing an array formula of a cell range. */
+ void importArray( BiffInputStream& rStrm );
+ /** Imports a SHAREDFMLA record describing a shared formula in a cell range. */
+ void importSharedFmla( BiffInputStream& rStrm );
+ /** Imports table operation from a DATATABLE or DATATABLE2 record. */
+ void importDataTable( BiffInputStream& rStrm );
+
+private:
+ CellModel maCurrCell; /// Position and formatting of current imported cell.
+ sal_uInt32 mnFormulaIgnoreSize; /// Number of bytes to be ignored in FORMULA record.
+ sal_uInt32 mnArrayIgnoreSize; /// Number of bytes to be ignored in ARRAY record.
+ sal_uInt16 mnBiff2XfId; /// Current XF identifier from IXFE record.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/stylesbuffer.hxx b/oox/inc/oox/xls/stylesbuffer.hxx
new file mode 100644
index 000000000000..64a56968aa37
--- /dev/null
+++ b/oox/inc/oox/xls/stylesbuffer.hxx
@@ -0,0 +1,1098 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_STYLESBUFFER_HXX
+#define OOX_XLS_STYLESBUFFER_HXX
+
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/table/CellHoriJustify.hpp>
+#include <com/sun/star/table/CellOrientation.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/util/CellProtection.hpp>
+#include "oox/drawingml/color.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/refmap.hxx"
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/numberformatsbuffer.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct FontDescrtiptor; }
+} } }
+
+namespace oox { class PropertySet; }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+const sal_Int32 OOX_COLOR_WINDOWTEXT3 = 24; /// System window text color (BIFF3-BIFF4).
+const sal_Int32 OOX_COLOR_WINDOWBACK3 = 25; /// System window background color (BIFF3-BIFF4).
+const sal_Int32 OOX_COLOR_WINDOWTEXT = 64; /// System window text color (BIFF5+).
+const sal_Int32 OOX_COLOR_WINDOWBACK = 65; /// System window background color (BIFF5+).
+const sal_Int32 OOX_COLOR_BUTTONBACK = 67; /// System button background color (face color).
+const sal_Int32 OOX_COLOR_CHWINDOWTEXT = 77; /// System window text color (BIFF8 charts).
+const sal_Int32 OOX_COLOR_CHWINDOWBACK = 78; /// System window background color (BIFF8 charts).
+const sal_Int32 OOX_COLOR_CHBORDERAUTO = 79; /// Automatic frame border (BIFF8 charts).
+const sal_Int32 OOX_COLOR_NOTEBACK = 80; /// Note background color.
+const sal_Int32 OOX_COLOR_NOTETEXT = 81; /// Note text color.
+const sal_Int32 OOX_COLOR_FONTAUTO = 0x7FFF; /// Font auto color (system window text color).
+
+// ----------------------------------------------------------------------------
+
+const sal_Int16 API_LINE_NONE = 0;
+const sal_Int16 API_LINE_HAIR = 2;
+const sal_Int16 API_LINE_THIN = 35;
+const sal_Int16 API_LINE_MEDIUM = 88;
+const sal_Int16 API_LINE_THICK = 141;
+
+const sal_Int16 API_ESCAPE_NONE = 0; /// No escapement.
+const sal_Int16 API_ESCAPE_SUPERSCRIPT = 101; /// Superscript: raise characters automatically (magic value 101).
+const sal_Int16 API_ESCAPE_SUBSCRIPT = -101; /// Subscript: lower characters automatically (magic value -101).
+
+const sal_Int8 API_ESCAPEHEIGHT_NONE = 100; /// Relative character height if not escaped.
+const sal_Int8 API_ESCAPEHEIGHT_DEFAULT = 58; /// Relative character height if escaped.
+
+// ============================================================================
+
+/** Special implementation of the GraphicHelper for Excel palette and scheme
+ colors.
+ */
+class ExcelGraphicHelper : public GraphicHelper, public WorkbookHelper
+{
+public:
+ explicit ExcelGraphicHelper( const WorkbookHelper& rHelper );
+
+ /** Derived classes may implement to resolve a scheme color from the passed XML token identifier. */
+ virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const;
+ /** Derived classes may implement to resolve a palette index to an RGB color. */
+ virtual sal_Int32 getPaletteColor( sal_Int32 nPaletteIdx ) const;
+};
+
+// ============================================================================
+
+class Color : public ::oox::drawingml::Color
+{
+public:
+ /** Sets the color to automatic. */
+ void setAuto();
+ /** Sets the color to the passed RGB value. */
+ void setRgb( sal_Int32 nRgbValue, double fTint = 0.0 );
+ /** Sets the color to the passed theme index. */
+ void setTheme( sal_Int32 nThemeIdx, double fTint = 0.0 );
+ /** Sets the color to the passed palette index. */
+ void setIndexed( sal_Int32 nPaletteIdx, double fTint = 0.0 );
+
+ /** Imports the color from the passed attribute list. */
+ void importColor( const AttributeList& rAttribs );
+
+ /** Imports a 64-bit color from the passed binary stream. */
+ void importColor( SequenceInputStream& rStrm );
+ /** Imports a 32-bit palette color identifier from the passed BIFF12 stream. */
+ void importColorId( SequenceInputStream& rStrm );
+ /** Imports a 32-bit RGBA color value from the passed BIFF12 stream. */
+ void importColorRgb( SequenceInputStream& rStrm );
+
+ /** Imports an 8-bit or 16-bit palette color identifier from the passed BIFF stream. */
+ void importColorId( BiffInputStream& rStrm, bool b16Bit = true );
+ /** Imports a 32-bit RGBA color value from the passed BIFF stream. */
+ void importColorRgb( BiffInputStream& rStrm );
+
+ /** Returns true, if the color is set to automatic. */
+ inline bool isAuto() const { return isPlaceHolder(); }
+};
+
+// ----------------------------------------------------------------------------
+
+SequenceInputStream& operator>>( SequenceInputStream& rStrm, Color& orColor );
+
+// ============================================================================
+
+/** Stores all colors of the color palette. */
+class ColorPalette : public WorkbookHelper
+{
+public:
+ /** Constructs the color palette with predefined color values. */
+ explicit ColorPalette( const WorkbookHelper& rHelper );
+
+ /** Appends a new color from the passed attributes. */
+ void importPaletteColor( const AttributeList& rAttribs );
+ /** Appends a new color from the passed RGBCOLOR record. */
+ void importPaletteColor( SequenceInputStream& rStrm );
+ /** Imports the PALETTE record from the passed stream. */
+ void importPalette( BiffInputStream& rStrm );
+ /** Imports a color palette from a UNO sequence in the passed any. */
+ void importPalette( const ::com::sun::star::uno::Any& rPalette );
+
+ /** Rturns the RGB value of the color with the passed index. */
+ sal_Int32 getColor( sal_Int32 nPaletteIdx ) const;
+
+private:
+ /** Appends the passed color. */
+ void appendColor( sal_Int32 nRGBValue );
+
+private:
+ ::std::vector< sal_Int32 > maColors; /// List of RGB values.
+ size_t mnAppendIndex; /// Index to append a new color.
+};
+
+// ============================================================================
+
+/** Contains all XML font attributes, e.g. from a font or rPr element. */
+struct FontModel
+{
+ ::rtl::OUString maName; /// Font name.
+ Color maColor; /// Font color.
+ sal_Int32 mnScheme; /// Major/minor scheme font.
+ sal_Int32 mnFamily; /// Font family.
+ sal_Int32 mnCharSet; /// Windows font character set.
+ double mfHeight; /// Font height in points.
+ sal_Int32 mnUnderline; /// Underline style.
+ sal_Int32 mnEscapement; /// Escapement style.
+ bool mbBold; /// True = bold characters.
+ bool mbItalic; /// True = italic characters.
+ bool mbStrikeout; /// True = Strike out characters.
+ bool mbOutline; /// True = outlined characters.
+ bool mbShadow; /// True = shadowed chgaracters.
+
+ explicit FontModel();
+
+ void setBiff12Scheme( sal_uInt8 nScheme );
+ void setBiffHeight( sal_uInt16 nHeight );
+ void setBiffWeight( sal_uInt16 nWeight );
+ void setBiffUnderline( sal_uInt16 nUnderline );
+ void setBiffEscapement( sal_uInt16 nEscapement );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Enumerates different types of API font property sets. */
+enum FontPropertyType
+{
+ FONT_PROPTYPE_CELL, /// Font properties in a spreadsheet cell (table::Cell service).
+ FONT_PROPTYPE_TEXT /// Font properties in a text object (text::Text service).
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains used flags for all API font attributes. */
+struct ApiFontUsedFlags
+{
+ bool mbNameUsed; /// True = font name/family/char set are used.
+ bool mbColorUsed; /// True = font color is used.
+ bool mbSchemeUsed; /// True = font scheme is used.
+ bool mbHeightUsed; /// True = font height is used.
+ bool mbUnderlineUsed; /// True = underline style is used.
+ bool mbEscapementUsed; /// True = escapement style is used.
+ bool mbWeightUsed; /// True = font weight (boldness) is used.
+ bool mbPostureUsed; /// True = font posture (italic) is used.
+ bool mbStrikeoutUsed; /// True = strike out style is used.
+ bool mbOutlineUsed; /// True = outline style is used.
+ bool mbShadowUsed; /// True = shadow style is used.
+
+ explicit ApiFontUsedFlags( bool bAllUsed );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains API font name, family, and charset for a script type. */
+struct ApiScriptFontName
+{
+ ::rtl::OUString maName; /// Font name.
+ sal_Int16 mnFamily; /// Font family.
+ sal_Int16 mnTextEnc; /// Font text encoding.
+
+ explicit ApiScriptFontName();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all API font attributes. */
+struct ApiFontData
+{
+ typedef ::com::sun::star::awt::FontDescriptor ApiFontDescriptor;
+
+ ApiScriptFontName maLatinFont; /// Font name for latin scripts.
+ ApiScriptFontName maAsianFont; /// Font name for east-asian scripts.
+ ApiScriptFontName maCmplxFont; /// Font name for complex scripts.
+ ApiFontDescriptor maDesc; /// Font descriptor (height in twips, weight in %).
+ sal_Int32 mnColor; /// Font color.
+ sal_Int16 mnEscapement; /// Escapement style.
+ sal_Int8 mnEscapeHeight; /// Escapement font height.
+ bool mbOutline; /// True = outlined characters.
+ bool mbShadow; /// True = shadowed chgaracters.
+
+ explicit ApiFontData();
+};
+
+// ============================================================================
+
+class Font : public WorkbookHelper
+{
+public:
+ explicit Font( const WorkbookHelper& rHelper, bool bDxf );
+ explicit Font( const WorkbookHelper& rHelper, const FontModel& rModel );
+
+ /** Sets font formatting attributes for the passed element. */
+ void importAttribs( sal_Int32 nElement, const AttributeList& rAttribs );
+
+ /** Imports the FONT record from the passed stream. */
+ void importFont( SequenceInputStream& rStrm );
+ /** Imports the font name from a DXF record. */
+ void importDxfName( SequenceInputStream& rStrm );
+ /** Imports the font color from a DXF record. */
+ void importDxfColor( SequenceInputStream& rStrm );
+ /** Imports the font scheme from a DXF record. */
+ void importDxfScheme( SequenceInputStream& rStrm );
+ /** Imports the font height from a DXF record. */
+ void importDxfHeight( SequenceInputStream& rStrm );
+ /** Imports the font weight from a DXF record. */
+ void importDxfWeight( SequenceInputStream& rStrm );
+ /** Imports the font underline style from a DXF record. */
+ void importDxfUnderline( SequenceInputStream& rStrm );
+ /** Imports the font escapement style from a DXF record. */
+ void importDxfEscapement( SequenceInputStream& rStrm );
+ /** Imports a font style flag from a DXF record. */
+ void importDxfFlag( sal_Int32 nElement, SequenceInputStream& rStrm );
+
+ /** Imports the FONT record from the passed stream. */
+ void importFont( BiffInputStream& rStrm );
+ /** Imports the FONTCOLOR record from the passed stream. */
+ void importFontColor( BiffInputStream& rStrm );
+ /** Sets the font attributes from the font block of a CFRULE record. */
+ void importCfRule( BiffInputStream& rStrm );
+
+ /** Returns the font model structure. This function can be called before
+ finalizeImport() has been called. */
+ inline const FontModel& getModel() const { return maModel; }
+ /** Returns the text encoding for strings used with this font. This
+ function can be called before finalizeImport() has been called. */
+ rtl_TextEncoding getFontEncoding() const;
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns an API font descriptor with own font information. */
+ const ::com::sun::star::awt::FontDescriptor& getFontDescriptor() const;
+ /** Returns true, if the font requires rich text formatting in Calc.
+ @descr Example: Font escapement is a cell attribute in Excel, but Calc
+ needs an rich text cell for this attribute. */
+ bool needsRichTextFormat() const;
+
+ /** Writes all font attributes to the passed property map. */
+ void writeToPropertyMap(
+ PropertyMap& rPropMap,
+ FontPropertyType ePropType ) const;
+ /** Writes all font attributes to the passed property set. */
+ void writeToPropertySet(
+ PropertySet& rPropSet,
+ FontPropertyType ePropType ) const;
+
+private:
+ /** Reads and sets height and flags. */
+ void importFontData2( BiffInputStream& rStrm );
+ /** Reads and sets weight, escapement, underline, family, charset (BIFF5+). */
+ void importFontData5( BiffInputStream& rStrm );
+
+ /** Reads and sets a byte string as font name. */
+ void importFontName2( BiffInputStream& rStrm );
+ /** Reads and sets a Unicode string as font name. */
+ void importFontName8( BiffInputStream& rStrm );
+
+private:
+ FontModel maModel;
+ ApiFontData maApiData;
+ ApiFontUsedFlags maUsedFlags;
+ bool mbDxf;
+};
+
+typedef ::boost::shared_ptr< Font > FontRef;
+
+// ============================================================================
+
+/** Contains all XML cell alignment attributes, e.g. from an alignment element. */
+struct AlignmentModel
+{
+ sal_Int32 mnHorAlign; /// Horizontal alignment.
+ sal_Int32 mnVerAlign; /// Vertical alignment.
+ sal_Int32 mnTextDir; /// CTL text direction.
+ sal_Int32 mnRotation; /// Text rotation angle.
+ sal_Int32 mnIndent; /// Indentation.
+ bool mbWrapText; /// True = multi-line text.
+ bool mbShrink; /// True = shrink to fit cell size.
+ bool mbJustLastLine; /// True = justify last line in block text.
+
+ explicit AlignmentModel();
+
+ /** Sets horizontal alignment from the passed BIFF data. */
+ void setBiffHorAlign( sal_uInt8 nHorAlign );
+ /** Sets vertical alignment from the passed BIFF data. */
+ void setBiffVerAlign( sal_uInt8 nVerAlign );
+ /** Sets rotation from the passed BIFF text orientation. */
+ void setBiffTextOrient( sal_uInt8 nTextOrient );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all API cell alignment attributes. */
+struct ApiAlignmentData
+{
+ typedef ::com::sun::star::table::CellHoriJustify ApiCellHoriJustify;
+ typedef ::com::sun::star::table::CellVertJustify ApiCellVertJustify;
+ typedef ::com::sun::star::table::CellOrientation ApiCellOrientation;
+
+ ApiCellHoriJustify meHorJustify; /// Horizontal alignment.
+ ApiCellVertJustify meVerJustify; /// Vertical alignment.
+ ApiCellOrientation meOrientation; /// Normal or stacked text.
+ sal_Int32 mnRotation; /// Text rotation angle.
+ sal_Int16 mnWritingMode; /// CTL text direction.
+ sal_Int16 mnIndent; /// Indentation.
+ bool mbWrapText; /// True = multi-line text.
+ bool mbShrink; /// True = shrink to fit cell size.
+
+ explicit ApiAlignmentData();
+};
+
+bool operator==( const ApiAlignmentData& rLeft, const ApiAlignmentData& rRight );
+
+// ============================================================================
+
+class Alignment : public WorkbookHelper
+{
+public:
+ explicit Alignment( const WorkbookHelper& rHelper );
+
+ /** Sets all attributes from the alignment element. */
+ void importAlignment( const AttributeList& rAttribs );
+
+ /** Sets the alignment attributes from the passed BIFF12 XF record data. */
+ void setBiff12Data( sal_uInt32 nFlags );
+ /** Sets the alignment attributes from the passed BIFF2 XF record data. */
+ void setBiff2Data( sal_uInt8 nFlags );
+ /** Sets the alignment attributes from the passed BIFF3 XF record data. */
+ void setBiff3Data( sal_uInt16 nAlign );
+ /** Sets the alignment attributes from the passed BIFF4 XF record data. */
+ void setBiff4Data( sal_uInt16 nAlign );
+ /** Sets the alignment attributes from the passed BIFF5 XF record data. */
+ void setBiff5Data( sal_uInt16 nAlign );
+ /** Sets the alignment attributes from the passed BIFF8 XF record data. */
+ void setBiff8Data( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns the alignment model structure. */
+ inline const AlignmentModel& getModel() const { return maModel; }
+ /** Returns the converted API alignment data struct. */
+ inline const ApiAlignmentData& getApiData() const { return maApiData; }
+
+ /** Writes all alignment attributes to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap ) const;
+
+private:
+ AlignmentModel maModel; /// Alignment model data.
+ ApiAlignmentData maApiData; /// Alignment data converted to API constants.
+};
+
+typedef ::boost::shared_ptr< Alignment > AlignmentRef;
+
+// ============================================================================
+
+/** Contains all XML cell protection attributes, e.g. from a protection element. */
+struct ProtectionModel
+{
+ bool mbLocked; /// True = locked against editing.
+ bool mbHidden; /// True = formula is hidden.
+
+ explicit ProtectionModel();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all API cell protection attributes. */
+struct ApiProtectionData
+{
+ typedef ::com::sun::star::util::CellProtection ApiCellProtection;
+
+ ApiCellProtection maCellProt;
+
+ explicit ApiProtectionData();
+};
+
+bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight );
+
+// ============================================================================
+
+class Protection : public WorkbookHelper
+{
+public:
+ explicit Protection( const WorkbookHelper& rHelper );
+
+ /** Sets all attributes from the protection element. */
+ void importProtection( const AttributeList& rAttribs );
+
+ /** Sets the protection attributes from the passed BIFF12 XF record data. */
+ void setBiff12Data( sal_uInt32 nFlags );
+ /** Sets the protection attributes from the passed BIFF2 XF record data. */
+ void setBiff2Data( sal_uInt8 nNumFmt );
+ /** Sets the protection attributes from the passed BIFF3-BIFF8 XF record data. */
+ void setBiff3Data( sal_uInt16 nProt );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns the protection model structure. */
+ inline const ProtectionModel& getModel() const { return maModel; }
+ /** Returns the converted API protection data struct. */
+ inline const ApiProtectionData& getApiData() const { return maApiData; }
+
+ /** Writes all protection attributes to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap ) const;
+
+private:
+ ProtectionModel maModel; /// Protection model data.
+ ApiProtectionData maApiData; /// Protection data converted to API constants.
+};
+
+typedef ::boost::shared_ptr< Protection > ProtectionRef;
+
+// ============================================================================
+
+/** Contains XML attributes of a single border line. */
+struct BorderLineModel
+{
+ Color maColor; /// Borderline color.
+ sal_Int32 mnStyle; /// Border line style.
+ bool mbUsed; /// True = line format used.
+
+ explicit BorderLineModel( bool bDxf );
+
+ /** Sets the passed BIFF line style. */
+ void setBiffStyle( sal_Int32 nLineStyle );
+ /** Sets line style and line color from the passed BIFF data. */
+ void setBiffData( sal_uInt8 nLineStyle, sal_uInt16 nLineColor );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains XML attributes of a complete cell border. */
+struct BorderModel
+{
+ BorderLineModel maLeft; /// Left line format.
+ BorderLineModel maRight; /// Right line format.
+ BorderLineModel maTop; /// Top line format.
+ BorderLineModel maBottom; /// Bottom line format.
+ BorderLineModel maDiagonal; /// Diagonal line format.
+ bool mbDiagTLtoBR; /// True = top-left to bottom-right on.
+ bool mbDiagBLtoTR; /// True = bottom-left to top-right on.
+
+ explicit BorderModel( bool bDxf );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains API attributes of a complete cell border. */
+struct ApiBorderData
+{
+ typedef ::com::sun::star::table::TableBorder ApiTableBorder;
+ typedef ::com::sun::star::table::BorderLine ApiBorderLine;
+
+ ApiTableBorder maBorder; /// Left/right/top/bottom line format.
+ ApiBorderLine maTLtoBR; /// Diagonal top-left to bottom-right line format.
+ ApiBorderLine maBLtoTR; /// Diagonal bottom-left to top-right line format.
+ bool mbBorderUsed; /// True = left/right/top/bottom line format used.
+ bool mbDiagUsed; /// True = diagonal line format used.
+
+ explicit ApiBorderData();
+
+ /** Returns true, if any of the outer border lines is visible. */
+ bool hasAnyOuterBorder() const;
+};
+
+bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight );
+
+// ============================================================================
+
+class Border : public WorkbookHelper
+{
+public:
+ explicit Border( const WorkbookHelper& rHelper, bool bDxf );
+
+ /** Sets global border attributes from the border element. */
+ void importBorder( const AttributeList& rAttribs );
+ /** Sets border attributes for the border line with the passed element identifier. */
+ void importStyle( sal_Int32 nElement, const AttributeList& rAttribs );
+ /** Sets color attributes for the border line with the passed element identifier. */
+ void importColor( sal_Int32 nElement, const AttributeList& rAttribs );
+
+ /** Imports the BORDER record from the passed stream. */
+ void importBorder( SequenceInputStream& rStrm );
+ /** Imports a border from a DXF record from the passed stream. */
+ void importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm );
+
+ /** Sets the border attributes from the passed BIFF2 XF record data. */
+ void setBiff2Data( sal_uInt8 nFlags );
+ /** Sets the border attributes from the passed BIFF3/BIFF4 XF record data. */
+ void setBiff3Data( sal_uInt32 nBorder );
+ /** Sets the border attributes from the passed BIFF5 XF record data. */
+ void setBiff5Data( sal_uInt32 nBorder, sal_uInt32 nArea );
+ /** Sets the border attributes from the passed BIFF8 XF record data. */
+ void setBiff8Data( sal_uInt32 nBorder1, sal_uInt32 nBorder2 );
+ /** Sets the border attributes from the border block of a CFRULE record. */
+ void importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns the border model structure. */
+ inline const BorderModel& getModel() const { return maModel; }
+ /** Returns the converted API border data struct. */
+ inline const ApiBorderData& getApiData() const { return maApiData; }
+
+ /** Writes all border attributes to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap ) const;
+
+private:
+ /** Returns the border line struct specified by the passed XML token identifier. */
+ BorderLineModel* getBorderLine( sal_Int32 nElement );
+
+ /** Converts border line data to an API struct, returns true, if the line is marked as used. */
+ bool convertBorderLine(
+ ::com::sun::star::table::BorderLine& rBorderLine,
+ const BorderLineModel& rModel );
+
+private:
+ BorderModel maModel;
+ ApiBorderData maApiData;
+ bool mbDxf;
+};
+
+typedef ::boost::shared_ptr< Border > BorderRef;
+
+// ============================================================================
+
+/** Contains XML pattern fill attributes from the patternFill element. */
+struct PatternFillModel
+{
+ Color maPatternColor; /// Pattern foreground color.
+ Color maFillColor; /// Background fill color.
+ sal_Int32 mnPattern; /// Pattern identifier (e.g. solid).
+ bool mbPattColorUsed; /// True = pattern foreground color used.
+ bool mbFillColorUsed; /// True = background fill color used.
+ bool mbPatternUsed; /// True = pattern used.
+
+ explicit PatternFillModel( bool bDxf );
+
+ /** Sets the passed BIFF pattern identifier. */
+ void setBiffPattern( sal_Int32 nPattern );
+ /** Sets the pattern and pattern colors from the passed BIFF data. */
+ void setBiffData( sal_uInt16 nPatternColor, sal_uInt16 nFillColor, sal_uInt8 nPattern );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains XML gradient fill attributes from the gradientFill element. */
+struct GradientFillModel
+{
+ typedef ::std::map< double, Color > ColorMap;
+
+ sal_Int32 mnType; /// Gradient type, linear or path.
+ double mfAngle; /// Rotation angle for type linear.
+ double mfLeft; /// Left convergence for type path.
+ double mfRight; /// Right convergence for type path.
+ double mfTop; /// Top convergence for type path.
+ double mfBottom; /// Bottom convergence for type path.
+ ColorMap maColors; /// Gradient colors.
+
+ explicit GradientFillModel();
+
+ /** Reads BIFF12 gradient settings from a FILL or DXF record. */
+ void readGradient( SequenceInputStream& rStrm );
+ /** Reads BIFF12 gradient stop settings from a FILL or DXF record. */
+ void readGradientStop( SequenceInputStream& rStrm, bool bDxf );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains API fill attributes. */
+struct ApiSolidFillData
+{
+ sal_Int32 mnColor; /// Fill color.
+ bool mbTransparent; /// True = transparent area.
+ bool mbUsed; /// True = fill data is valid.
+
+ explicit ApiSolidFillData();
+};
+
+bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight );
+
+// ============================================================================
+
+/** Contains cell fill attributes, either a pattern fill or a gradient fill. */
+class Fill : public WorkbookHelper
+{
+public:
+ explicit Fill( const WorkbookHelper& rHelper, bool bDxf );
+
+ /** Sets attributes of a patternFill element. */
+ void importPatternFill( const AttributeList& rAttribs );
+ /** Sets the pattern color from the fgColor element. */
+ void importFgColor( const AttributeList& rAttribs );
+ /** Sets the background color from the bgColor element. */
+ void importBgColor( const AttributeList& rAttribs );
+ /** Sets attributes of a gradientFill element. */
+ void importGradientFill( const AttributeList& rAttribs );
+ /** Sets a color from the color element in a gradient fill. */
+ void importColor( const AttributeList& rAttribs, double fPosition );
+
+ /** Imports the FILL record from the passed stream. */
+ void importFill( SequenceInputStream& rStrm );
+ /** Imports the fill pattern from a DXF record. */
+ void importDxfPattern( SequenceInputStream& rStrm );
+ /** Imports the pattern color from a DXF record. */
+ void importDxfFgColor( SequenceInputStream& rStrm );
+ /** Imports the background color from a DXF record. */
+ void importDxfBgColor( SequenceInputStream& rStrm );
+ /** Imports gradient settings from a DXF record. */
+ void importDxfGradient( SequenceInputStream& rStrm );
+ /** Imports gradient stop settings from a DXF record. */
+ void importDxfStop( SequenceInputStream& rStrm );
+
+ /** Sets the fill attributes from the passed BIFF2 XF record data. */
+ void setBiff2Data( sal_uInt8 nFlags );
+ /** Sets the fill attributes from the passed BIFF3/BIFF4 XF record data. */
+ void setBiff3Data( sal_uInt16 nArea );
+ /** Sets the fill attributes from the passed BIFF5 XF record data. */
+ void setBiff5Data( sal_uInt32 nArea );
+ /** Sets the fill attributes from the passed BIFF8 XF record data. */
+ void setBiff8Data( sal_uInt32 nBorder2, sal_uInt16 nArea );
+ /** Sets the fill attributes from the fill block of a CFRULE record. */
+ void importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns the fill pattern model structure, if extant. */
+ inline const PatternFillModel* getPatternModel() const { return mxPatternModel.get(); }
+ /** Returns the fill gradient model structure, if extant. */
+ inline const GradientFillModel* getGradientModel() const { return mxGradientModel.get(); }
+ /** Returns the converted API fill data struct. */
+ inline const ApiSolidFillData& getApiData() const { return maApiData; }
+
+ /** Writes all fill attributes to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap ) const;
+
+private:
+ typedef ::boost::shared_ptr< PatternFillModel > PatternModelRef;
+ typedef ::boost::shared_ptr< GradientFillModel > GradientModelRef;
+
+ PatternModelRef mxPatternModel;
+ GradientModelRef mxGradientModel;
+ ApiSolidFillData maApiData;
+ bool mbDxf;
+};
+
+typedef ::boost::shared_ptr< Fill > FillRef;
+
+// ============================================================================
+
+/** Contains all data for a cell format or cell style. */
+struct XfModel
+{
+ sal_Int32 mnStyleXfId; /// Index to parent style XF.
+ sal_Int32 mnFontId; /// Index to font data list.
+ sal_Int32 mnNumFmtId; /// Index to number format list.
+ sal_Int32 mnBorderId; /// Index to list of cell borders.
+ sal_Int32 mnFillId; /// Index to list of cell areas.
+ bool mbCellXf; /// True = cell XF, false = style XF.
+ bool mbFontUsed; /// True = font index used.
+ bool mbNumFmtUsed; /// True = number format used.
+ bool mbAlignUsed; /// True = alignment used.
+ bool mbProtUsed; /// True = cell protection used.
+ bool mbBorderUsed; /// True = border data used.
+ bool mbAreaUsed; /// True = area data used.
+
+ explicit XfModel();
+};
+
+// ============================================================================
+
+/** Represents a cell format or a cell style (called XF, extended format).
+
+ This class stores the type (cell/style), the index to the parent style (if
+ it is a cell format) and all "attribute used" flags, which reflect the
+ state of specific attribute groups (true = user has changed the attributes)
+ and all formatting data.
+ */
+class Xf : public WorkbookHelper
+{
+public:
+ explicit Xf( const WorkbookHelper& rHelper );
+
+ /** Sets all "attribute used" flags to the passed state. */
+ void setAllUsedFlags( bool bUsed );
+
+ /** Sets all attributes from the xf element. */
+ void importXf( const AttributeList& rAttribs, bool bCellXf );
+ /** Sets all attributes from the alignment element. */
+ void importAlignment( const AttributeList& rAttribs );
+ /** Sets all attributes from the protection element. */
+ void importProtection( const AttributeList& rAttribs );
+
+ /** Imports the XF record from the passed stream. */
+ void importXf( SequenceInputStream& rStrm, bool bCellXf );
+
+ /** Imports the XF record from the passed stream. */
+ void importXf( BiffInputStream& rStrm );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns true, if the XF is a cell XF, and false, if it is a style XF. */
+ inline bool isCellXf() const { return maModel.mbCellXf; }
+
+ /** Returns the referred font object. */
+ FontRef getFont() const;
+ /** Returns the alignment data of this style. */
+ inline const Alignment& getAlignment() const { return maAlignment; }
+ /** Returns the cell protection data of this style. */
+ inline const Protection& getProtection() const { return maProtection; }
+ /** Returns true, if any "attribute used" flags are ste in this XF. */
+ bool hasAnyUsedFlags() const;
+
+ /** Writes all formatting attributes to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap ) const;
+ /** Writes all formatting attributes to the passed property set. */
+ void writeToPropertySet( PropertySet& rPropSet ) const;
+
+private:
+ /** Sets 'attribute used' flags from the passed BIFF bit field. */
+ void setBiffUsedFlags( sal_uInt8 nUsedFlags );
+
+private:
+ XfModel maModel; /// Cell XF or style XF model data.
+ Alignment maAlignment; /// Cell alignment data.
+ Protection maProtection; /// Cell protection data.
+ ::com::sun::star::table::CellVertJustify
+ meRotationRef; /// Rotation reference dependent on border.
+};
+
+typedef ::boost::shared_ptr< Xf > XfRef;
+
+// ============================================================================
+
+class Dxf : public WorkbookHelper
+{
+public:
+ explicit Dxf( const WorkbookHelper& rHelper );
+
+ /** Creates a new empty font object. */
+ FontRef createFont( bool bAlwaysNew = true );
+ /** Creates a new empty border object. */
+ BorderRef createBorder( bool bAlwaysNew = true );
+ /** Creates a new empty fill object. */
+ FillRef createFill( bool bAlwaysNew = true );
+
+ /** Inserts a new number format code. */
+ void importNumFmt( const AttributeList& rAttribs );
+ /** Sets all attributes from the alignment element. */
+ void importAlignment( const AttributeList& rAttribs );
+ /** Sets all attributes from the protection element. */
+ void importProtection( const AttributeList& rAttribs );
+
+ /** Imports the DXF record from the passed stream. */
+ void importDxf( SequenceInputStream& rStrm );
+
+ /** Imports font, border, and fill settings from the CFRULE record. */
+ void importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Writes all formatting attributes to the passed property map. */
+ void writeToPropertyMap( PropertyMap& rPropMap ) const;
+ /** Writes all formatting attributes to the passed property set. */
+ void writeToPropertySet( PropertySet& rPropSet ) const;
+
+private:
+ FontRef mxFont; /// Font data.
+ NumberFormatRef mxNumFmt; /// Number format data.
+ AlignmentRef mxAlignment; /// Alignment data.
+ ProtectionRef mxProtection; /// Protection data.
+ BorderRef mxBorder; /// Border data.
+ FillRef mxFill; /// Fill data.
+};
+
+typedef ::boost::shared_ptr< Dxf > DxfRef;
+
+// ============================================================================
+
+/** Contains attributes of a cell style, e.g. from the cellStyle element. */
+struct CellStyleModel
+{
+ ::rtl::OUString maName; /// Cell style name.
+ sal_Int32 mnXfId; /// Formatting for this cell style.
+ sal_Int32 mnBuiltinId; /// Identifier for builtin styles.
+ sal_Int32 mnLevel; /// Level for builtin column/row styles.
+ bool mbBuiltin; /// True = builtin style.
+ bool mbCustom; /// True = customized builtin style.
+ bool mbHidden; /// True = style not visible in GUI.
+
+ explicit CellStyleModel();
+
+ /** Returns true, if this style is a builtin style. */
+ bool isBuiltin() const;
+ /** Returns true, if this style represents the default document cell style. */
+ bool isDefaultStyle() const;
+};
+
+// ============================================================================
+
+class CellStyle : public WorkbookHelper
+{
+public:
+ explicit CellStyle( const WorkbookHelper& rHelper );
+
+ /** Imports passed attributes from the cellStyle element. */
+ void importCellStyle( const AttributeList& rAttribs );
+ /** Imports style settings from a CELLSTYLE record. */
+ void importCellStyle( SequenceInputStream& rStrm );
+ /** Imports style settings from a STYLE record. */
+ void importStyle( BiffInputStream& rStrm );
+
+ /** Creates the style sheet in the document described by this cell style object. */
+ void createCellStyle();
+ /** Stores tha passed final style name and creates the cell style, if it is
+ user-defined or modified built-in. */
+ void finalizeImport( const ::rtl::OUString& rFinalName );
+
+ /** Returns the cell style model structure. */
+ inline const CellStyleModel& getModel() const { return maModel; }
+ /** Returns the final style name used in the document. */
+ inline const ::rtl::OUString& getFinalStyleName() const { return maFinalName; }
+
+private:
+ CellStyleModel maModel;
+ ::rtl::OUString maFinalName; /// Final style name used in API.
+ bool mbCreated; /// True = style sheet created.
+};
+
+typedef ::boost::shared_ptr< CellStyle > CellStyleRef;
+
+// ============================================================================
+
+class CellStyleBuffer : public WorkbookHelper
+{
+public:
+ explicit CellStyleBuffer( const WorkbookHelper& rHelper );
+
+ /** Appends and returns a new named cell style object. */
+ CellStyleRef importCellStyle( const AttributeList& rAttribs );
+ /** Imports the CELLSTYLE record from the passed stream. */
+ CellStyleRef importCellStyle( SequenceInputStream& rStrm );
+ /** Imports the STYLE record from the passed stream. */
+ CellStyleRef importStyle( BiffInputStream& rStrm );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns the XF identifier associated to the default cell style. */
+ sal_Int32 getDefaultXfId() const;
+ /** Returns the default style sheet for unused cells. */
+ ::rtl::OUString getDefaultStyleName() const;
+ /** Creates the style sheet described by the style XF with the passed identifier. */
+ ::rtl::OUString createCellStyle( sal_Int32 nXfId ) const;
+
+private:
+ /** Inserts the passed cell style object into the internal maps. */
+ void insertCellStyle( CellStyleRef xCellStyle );
+ /** Creates the style sheet described by the passed cell style object. */
+ ::rtl::OUString createCellStyle( const CellStyleRef& rxCellStyle ) const;
+
+private:
+ typedef RefVector< CellStyle > CellStyleVector;
+ typedef RefMap< sal_Int32, CellStyle > CellStyleXfIdMap;
+
+ CellStyleVector maBuiltinStyles; /// All built-in cell styles.
+ CellStyleVector maUserStyles; /// All user defined cell styles.
+ CellStyleXfIdMap maStylesByXf; /// All cell styles, mapped by XF identifier.
+ CellStyleRef mxDefStyle; /// Default cell style.
+};
+
+// ============================================================================
+
+struct AutoFormatModel
+{
+ sal_Int32 mnAutoFormatId; /// Index of predefined autoformatting.
+ bool mbApplyNumFmt; /// True = apply number format from autoformatting.
+ bool mbApplyFont; /// True = apply font from autoformatting.
+ bool mbApplyAlignment; /// True = apply alignment from autoformatting.
+ bool mbApplyBorder; /// True = apply border from autoformatting.
+ bool mbApplyFill; /// True = apply fill from autoformatting.
+ bool mbApplyProtection; /// True = apply protection from autoformatting.
+
+ explicit AutoFormatModel();
+};
+
+// ============================================================================
+
+class StylesBuffer : public WorkbookHelper
+{
+public:
+ explicit StylesBuffer( const WorkbookHelper& rHelper );
+
+ /** Creates a new empty font object.
+ @param opnFontId (out-param) The identifier of the new font object. */
+ FontRef createFont( sal_Int32* opnFontId = 0 );
+ /** Creates a number format. */
+ NumberFormatRef createNumFmt( sal_Int32 nNumFmtId, const ::rtl::OUString& rFmtCode );
+ /** Creates a new empty border object.
+ @param opnBorderId (out-param) The identifier of the new border object. */
+ BorderRef createBorder( sal_Int32* opnBorderId = 0 );
+ /** Creates a new empty fill object.
+ @param opnFillId (out-param) The identifier of the new fill object. */
+ FillRef createFill( sal_Int32* opnFillId = 0 );
+ /** Creates a new empty cell formatting object.
+ @param opnXfId (out-param) The identifier of the new XF object. */
+ XfRef createCellXf( sal_Int32* opnXfId = 0 );
+ /** Creates a new empty style formatting object.
+ @param opnXfId (out-param) The identifier of the new XF object. */
+ XfRef createStyleXf( sal_Int32* opnXfId = 0 );
+ /** Creates a new empty differential formatting object.
+ @param opnDxfId (out-param) The identifier of the new DXF object. */
+ DxfRef createDxf( sal_Int32* opnDxfId = 0 );
+
+ /** Appends a new color to the color palette. */
+ void importPaletteColor( const AttributeList& rAttribs );
+ /** Inserts a new number format code. */
+ NumberFormatRef importNumFmt( const AttributeList& rAttribs );
+ /** Appends and returns a new named cell style object. */
+ CellStyleRef importCellStyle( const AttributeList& rAttribs );
+
+ /** Appends a new color to the color palette. */
+ void importPaletteColor( SequenceInputStream& rStrm );
+ /** Imports the NUMFMT record from the passed stream. */
+ void importNumFmt( SequenceInputStream& rStrm );
+ /** Imports the CELLSTYLE record from the passed stream. */
+ void importCellStyle( SequenceInputStream& rStrm );
+
+ /** Imports the PALETTE record from the passed stream. */
+ void importPalette( BiffInputStream& rStrm );
+ /** Imports the FONT record from the passed stream. */
+ void importFont( BiffInputStream& rStrm );
+ /** Imports the FONTCOLOR record from the passed stream. */
+ void importFontColor( BiffInputStream& rStrm );
+ /** Imports the FORMAT record from the passed stream. */
+ void importFormat( BiffInputStream& rStrm );
+ /** Imports the XF record from the passed stream. */
+ void importXf( BiffInputStream& rStrm );
+ /** Imports the STYLE record from the passed stream. */
+ void importStyle( BiffInputStream& rStrm );
+
+ /** Imports a color palette from a UNO sequence in the passed any. */
+ void importPalette( const ::com::sun::star::uno::Any& rPalette );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+
+ /** Returns the palette color with the specified index. */
+ sal_Int32 getPaletteColor( sal_Int32 nIndex ) const;
+ /** Returns the specified font object. */
+ FontRef getFont( sal_Int32 nFontId ) const;
+ /** Returns the specified border object. */
+ BorderRef getBorder( sal_Int32 nBorderId ) const;
+ /** Returns the specified cell format object. */
+ XfRef getCellXf( sal_Int32 nXfId ) const;
+ /** Returns the specified style format object. */
+ XfRef getStyleXf( sal_Int32 nXfId ) const;
+ /** Returns the specified diferential cell format object. */
+ DxfRef getDxf( sal_Int32 nDxfId ) const;
+
+ /** Returns the font object of the specified cell XF. */
+ FontRef getFontFromCellXf( sal_Int32 nXfId ) const;
+ /** Returns the default application font (used in the "Normal" cell style). */
+ FontRef getDefaultFont() const;
+ /** Returns the model of the default application font (used in the "Normal" cell style). */
+ const FontModel& getDefaultFontModel() const;
+
+ /** Returns true, if the specified borders are equal. */
+ bool equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const;
+ /** Returns true, if the specified fills are equal. */
+ bool equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const;
+
+ /** Returns the default style sheet for unused cells. */
+ ::rtl::OUString getDefaultStyleName() const;
+ /** Creates the style sheet described by the style XF with the passed identifier. */
+ ::rtl::OUString createCellStyle( sal_Int32 nXfId ) const;
+ /** Creates the style sheet described by the DXF with the passed identifier. */
+ ::rtl::OUString createDxfStyle( sal_Int32 nDxfId ) const;
+
+ /** Writes the font attributes of the specified font data to the passed property map. */
+ void writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const;
+ /** Writes the specified number format to the passed property map. */
+ void writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const;
+ /** Writes the border attributes of the specified border data to the passed property map. */
+ void writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const;
+ /** Writes the fill attributes of the specified fill data to the passed property map. */
+ void writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const;
+ /** Writes the cell formatting attributes of the specified XF to the passed property map. */
+ void writeCellXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const;
+ /** Writes the cell formatting attributes of the specified style XF to the passed property map. */
+ void writeStyleXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const;
+
+ /** Writes the cell formatting attributes of the specified XF to the passed property set. */
+ void writeCellXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const;
+ /** Writes the cell formatting attributes of the specified style XF to the passed property set. */
+ void writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const;
+
+private:
+ typedef RefVector< Font > FontVector;
+ typedef RefVector< Border > BorderVector;
+ typedef RefVector< Fill > FillVector;
+ typedef RefVector< Xf > XfVector;
+ typedef RefVector< Dxf > DxfVector;
+ typedef ::std::map< sal_Int32, ::rtl::OUString > DxfStyleMap;
+
+ ColorPalette maPalette; /// Color palette.
+ FontVector maFonts; /// List of font objects.
+ NumberFormatsBuffer maNumFmts; /// List of all number format codes.
+ BorderVector maBorders; /// List of cell border objects.
+ FillVector maFills; /// List of cell area fill objects.
+ XfVector maCellXfs; /// List of cell formats.
+ XfVector maStyleXfs; /// List of cell styles.
+ CellStyleBuffer maCellStyles; /// All built-in and user defined cell styles.
+ DxfVector maDxfs; /// List of differential cell styles.
+ mutable DxfStyleMap maDxfStyles; /// Maps DXF identifiers to Calc style sheet names.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/stylesfragment.hxx b/oox/inc/oox/xls/stylesfragment.hxx
new file mode 100644
index 000000000000..eb1af53d9cdb
--- /dev/null
+++ b/oox/inc/oox/xls/stylesfragment.hxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ***********************************************************************/
+
+#ifndef OOX_XLS_STYLESFRAGMENT_HXX
+#define OOX_XLS_STYLESFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class IndexedColorsContext : public WorkbookContextBase
+{
+public:
+ explicit IndexedColorsContext( WorkbookFragmentBase& rFragment );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+};
+
+// ============================================================================
+
+class FontContext : public WorkbookContextBase
+{
+public:
+ template< typename ParentType >
+ inline explicit FontContext( ParentType& rParent, const FontRef& rxFont ) :
+ WorkbookContextBase( rParent ), mxFont( rxFont ) {}
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ FontRef mxFont;
+};
+
+// ============================================================================
+
+class BorderContext : public WorkbookContextBase
+{
+public:
+ template< typename ParentType >
+ inline explicit BorderContext( ParentType& rParent, const BorderRef& rxBorder ) :
+ WorkbookContextBase( rParent ), mxBorder( rxBorder ) {}
+
+protected:
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ BorderRef mxBorder;
+};
+
+// ============================================================================
+
+class FillContext : public WorkbookContextBase
+{
+public:
+ template< typename ParentType >
+ inline explicit FillContext( ParentType& rParent, const FillRef& rxFill ) :
+ WorkbookContextBase( rParent ), mxFill( rxFill ), mfGradPos( -1.0 ) {}
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ FillRef mxFill;
+ double mfGradPos; /// Gradient color position.
+};
+
+// ============================================================================
+
+class XfContext : public WorkbookContextBase
+{
+public:
+ template< typename ParentType >
+ inline explicit XfContext( ParentType& rParent, const XfRef& rxXf, bool bCellXf ) :
+ WorkbookContextBase( rParent ), mxXf( rxXf ), mbCellXf( bCellXf ) {}
+
+protected:
+ virtual void onStartElement( const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ XfRef mxXf;
+ bool mbCellXf; /// True = cell XF, false = style XF.
+};
+
+// ============================================================================
+
+class DxfContext : public WorkbookContextBase
+{
+public:
+ template< typename ParentType >
+ inline explicit DxfContext( ParentType& rParent, const DxfRef& rxDxf ) :
+ WorkbookContextBase( rParent ), mxDxf( rxDxf ) {}
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+
+private:
+ DxfRef mxDxf;
+};
+
+// ============================================================================
+
+class StylesFragment : public WorkbookFragmentBase
+{
+public:
+ explicit StylesFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+ virtual void finalizeImport();
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/tablebuffer.hxx b/oox/inc/oox/xls/tablebuffer.hxx
new file mode 100644
index 000000000000..d643fbc40728
--- /dev/null
+++ b/oox/inc/oox/xls/tablebuffer.hxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_TABLEBUFFER_HXX
+#define OOX_XLS_TABLEBUFFER_HXX
+
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "oox/xls/autofilterbuffer.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+struct TableModel
+{
+ ::com::sun::star::table::CellRangeAddress
+ maRange; /// Original (unchecked) range of the table.
+ ::rtl::OUString maProgName; /// Programmatical name.
+ ::rtl::OUString maDisplayName; /// Display name.
+ sal_Int32 mnId; /// Unique table identifier.
+ sal_Int32 mnType; /// Table type (worksheet, query, etc.).
+ sal_Int32 mnHeaderRows; /// Number of header rows.
+ sal_Int32 mnTotalsRows; /// Number of totals rows.
+
+ explicit TableModel();
+};
+
+// ----------------------------------------------------------------------------
+
+class Table : public WorkbookHelper
+{
+public:
+ explicit Table( const WorkbookHelper& rHelper );
+
+ /** Imports a table definition from the passed attributes. */
+ void importTable( const AttributeList& rAttribs, sal_Int16 nSheet );
+ /** Imports a table definition from a TABLE record. */
+ void importTable( SequenceInputStream& rStrm, sal_Int16 nSheet );
+ /** Creates a new auto filter and stores it internally. */
+ inline AutoFilter& createAutoFilter() { return maAutoFilters.createAutoFilter(); }
+
+ /** Creates a database range from this tables. */
+ void finalizeImport();
+
+ /** Returns the unique table identifier. */
+ inline sal_Int32 getTableId() const { return maModel.mnId; }
+ /** Returns the token index used in API token arrays (com.sun.star.sheet.FormulaToken). */
+ inline sal_Int32 getTokenIndex() const { return mnTokenIndex; }
+ /** Returns the original display name of the table. */
+ inline const ::rtl::OUString& getDisplayName() const { return maModel.maDisplayName; }
+
+ /** Returns the original (unchecked) total range of the table. */
+ inline const ::com::sun::star::table::CellRangeAddress& getOriginalRange() const { return maModel.maRange; }
+ /** Returns the cell range of this table. */
+ inline const ::com::sun::star::table::CellRangeAddress& getRange() const { return maDestRange; }
+ /** Returns the number of columns of this table. */
+ inline sal_Int32 getWidth() const { return maDestRange.EndColumn - maDestRange.StartColumn + 1; }
+ /** Returns the number of rows of this table. */
+ inline sal_Int32 getHeight() const { return maDestRange.EndRow - maDestRange.StartRow + 1; }
+ /** Returns the number of header rows in the table range. */
+ inline sal_Int32 getHeaderRows() const { return maModel.mnHeaderRows; }
+ /** Returns the number of totals rows in the table range. */
+ inline sal_Int32 getTotalsRows() const { return maModel.mnTotalsRows; }
+
+private:
+ TableModel maModel;
+ AutoFilterBuffer maAutoFilters; /// Filter settings for this table.
+ ::rtl::OUString maDBRangeName; /// Name of the databae range in the Calc document.
+ ::com::sun::star::table::CellRangeAddress
+ maDestRange; /// Validated range of the table in the worksheet.
+ sal_Int32 mnTokenIndex; /// Token index used in API token array.
+};
+
+typedef ::boost::shared_ptr< Table > TableRef;
+
+// ============================================================================
+
+class TableBuffer : public WorkbookHelper
+{
+public:
+ explicit TableBuffer( const WorkbookHelper& rHelper );
+
+ /** Creates a new empty table. */
+ Table& createTable();
+
+ /** Creates database ranges from all imported tables. */
+ void finalizeImport();
+
+ /** Returns a table by its identifier. */
+ TableRef getTable( sal_Int32 nTableId ) const;
+ /** Returns a table by its display name. */
+ TableRef getTable( const ::rtl::OUString& rDispName ) const;
+
+private:
+ /** Inserts the passed table into the maps according to its identifier and name. */
+ void insertTableToMaps( const TableRef& rxTable );
+
+private:
+ typedef RefVector< Table > TableVector;
+ typedef RefMap< sal_Int32, Table > TableIdMap;
+ typedef RefMap< ::rtl::OUString, Table > TableNameMap;
+
+ TableVector maTables;
+ TableIdMap maIdTables;
+ TableNameMap maNameTables;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/tablefragment.hxx b/oox/inc/oox/xls/tablefragment.hxx
new file mode 100644
index 000000000000..9c2678405ee5
--- /dev/null
+++ b/oox/inc/oox/xls/tablefragment.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_TABLEFRAGMENT_HXX
+#define OOX_XLS_TABLEFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+class Table;
+
+// ============================================================================
+
+class TableFragment : public WorksheetFragmentBase
+{
+public:
+ explicit TableFragment(
+ const WorksheetHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+
+private:
+ Table& mrTable;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/themebuffer.hxx b/oox/inc/oox/xls/themebuffer.hxx
new file mode 100644
index 000000000000..95d092198b95
--- /dev/null
+++ b/oox/inc/oox/xls/themebuffer.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_THEMEBUFFER_HXX
+#define OOX_XLS_THEMEBUFFER_HXX
+
+#include "oox/drawingml/theme.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace oox {
+namespace xls {
+
+struct FontModel;
+
+// ============================================================================
+
+class ThemeBuffer : public ::oox::drawingml::Theme, public WorkbookHelper
+{
+public:
+ explicit ThemeBuffer( const WorkbookHelper& rHelper );
+ virtual ~ThemeBuffer();
+
+ /** Returns the theme color with the specified token identifier. */
+ sal_Int32 getColorByToken( sal_Int32 nToken ) const;
+
+ /** Returns the default font data for the current file type. */
+ inline const FontModel& getDefaultFontModel() const { return *mxDefFontModel; }
+
+private:
+ typedef ::std::auto_ptr< FontModel > FontModelPtr;
+ FontModelPtr mxDefFontModel;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/unitconverter.hxx b/oox/inc/oox/xls/unitconverter.hxx
new file mode 100644
index 000000000000..1ea4180bc6fd
--- /dev/null
+++ b/oox/inc/oox/xls/unitconverter.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_UNITCONVERTER_HXX
+#define OOX_XLS_UNITCONVERTER_HXX
+
+#include <map>
+#include <vector>
+#include "oox/xls/workbookhelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace util { struct Date; struct DateTime; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Units supported by the UnitConverter class. */
+enum Unit
+{
+ UNIT_INCH, /// Inches.
+ UNIT_POINT, /// Points.
+ UNIT_TWIP, /// Twips (1/20 point).
+ UNIT_EMU, /// English Metric Unit (1/360,000 cm).
+ UNIT_SCREENX, /// Horizontal screen pixels.
+ UNIT_SCREENY, /// Vertical screen pixels.
+ UNIT_REFDEVX, /// Horizontal pixels in Calc reference device.
+ UNIT_REFDEVY, /// Vertical pixels in Calc reference device.
+ UNIT_DIGIT, /// Digit width of document default font.
+ UNIT_SPACE, /// Space character width of document default font.
+
+ UNIT_ENUM_SIZE
+};
+
+/** Helper class that provides functions to convert values from and to
+ different units.
+
+ Provides functions to calculate the width of certain characters of the
+ default font of the imported/exported document. The default font is always
+ the first font in the styles font list, and is always referenced by the
+ default cell style ("Normal" style in Excel) which is used by all empty
+ unformatted cells in the document. To be able to calculate the charcter
+ width correctly, the default font must be known, which is the case after
+ the finalizeImport() or finalizeExport() functions have been called. Caller
+ must make sure to not call the character width conversion functions before.
+ */
+class UnitConverter : public WorkbookHelper
+{
+public:
+ explicit UnitConverter( const WorkbookHelper& rHelper );
+
+ /** Final processing after import of all style settings. */
+ void finalizeImport();
+ /** Updates internal nulldate for date/serial conversion. */
+ void finalizeNullDate( const ::com::sun::star::util::Date& rNullDate );
+
+ /** Converts the passed value between the passed units. */
+ double scaleValue( double fValue, Unit eFromUnit, Unit eToUnit ) const;
+
+ /** Converts the passed value to 1/100 millimeters. */
+ sal_Int32 scaleToMm100( double fValue, Unit eUnit ) const;
+ /** Converts the passed value from 1/100 millimeters to the passed unit. */
+ double scaleFromMm100( sal_Int32 nMm100, Unit eUnit ) const;
+
+ /** Returns the serial value of the passed datetime, based on current nulldate. */
+ double calcSerialFromDateTime( const ::com::sun::star::util::DateTime& rDateTime ) const;
+ /** Returns the datetime of the passed serial value, based on current nulldate. */
+ ::com::sun::star::util::DateTime calcDateTimeFromSerial( double fSerial ) const;
+
+ /** Returns an error string from the passed BIFF error code. */
+ ::rtl::OUString calcOoxErrorCode( sal_uInt8 nErrorCode ) const;
+ /** Returns a BIFF error code from the passed error string. */
+ sal_uInt8 calcBiffErrorCode( const ::rtl::OUString& rErrorCode ) const;
+
+private:
+ /** Adds an error code to the internal maps. */
+ void addErrorCode( sal_uInt8 nErrorCode, const ::rtl::OUString& rErrorCode );
+ /** Returns the conversion coefficient for the passed unit. */
+ double getCoefficient( Unit eUnit ) const;
+
+private:
+ typedef ::std::vector< double > DoubleVector;
+ typedef ::std::map< ::rtl::OUString, sal_uInt8 > OoxErrorCodeMap;
+ typedef ::std::map< sal_uInt8, ::rtl::OUString > BiffErrorCodeMap;
+
+ DoubleVector maCoeffs; /// Coefficients for unit conversion.
+ OoxErrorCodeMap maOoxErrCodes; /// Maps error code strings to BIFF error constants.
+ BiffErrorCodeMap maBiffErrCodes; /// Maps BIFF error constants to error code strings.
+ sal_Int32 mnNullDate; /// Nulldate of this workbook (number of days since 0000-01-01).
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/viewsettings.hxx b/oox/inc/oox/xls/viewsettings.hxx
new file mode 100644
index 000000000000..c5880bf077fe
--- /dev/null
+++ b/oox/inc/oox/xls/viewsettings.hxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_VIEWSETTINGS_HXX
+#define OOX_XLS_VIEWSETTINGS_HXX
+
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Contains all settings for a selection in a single pane of a sheet. */
+struct PaneSelectionModel
+{
+ ::com::sun::star::table::CellAddress maActiveCell; /// Position of active cell (cursor).
+ ApiCellRangeList maSelection; /// Selected cell ranges.
+ sal_Int32 mnActiveCellId; /// Index of active cell in selection list.
+
+ explicit PaneSelectionModel();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Contains all view settings for a single sheet. */
+struct SheetViewModel
+{
+ typedef RefMap< sal_Int32, PaneSelectionModel > PaneSelectionModelMap;
+
+ PaneSelectionModelMap maPaneSelMap; /// Selections of all panes.
+ Color maGridColor; /// Grid color.
+ ::com::sun::star::table::CellAddress maFirstPos; /// First visible cell.
+ ::com::sun::star::table::CellAddress maSecondPos; /// First visible cell in additional panes.
+ sal_Int32 mnWorkbookViewId; /// Index into list of workbookView elements.
+ sal_Int32 mnViewType; /// View type (normal, page break, layout).
+ sal_Int32 mnActivePaneId; /// Active pane (with cell cursor).
+ sal_Int32 mnPaneState; /// Pane state (frozen, split).
+ double mfSplitX; /// Split X position (twips), or number of frozen columns.
+ double mfSplitY; /// Split Y position (twips), or number of frozen rows.
+ sal_Int32 mnCurrentZoom; /// Zoom factor for current view.
+ sal_Int32 mnNormalZoom; /// Zoom factor for normal view.
+ sal_Int32 mnSheetLayoutZoom; /// Zoom factor for pagebreak preview.
+ sal_Int32 mnPageLayoutZoom; /// Zoom factor for page layout view.
+ bool mbSelected; /// True = sheet is selected.
+ bool mbRightToLeft; /// True = sheet in right-to-left mode.
+ bool mbDefGridColor; /// True = default grid color.
+ bool mbShowFormulas; /// True = show formulas instead of results.
+ bool mbShowGrid; /// True = show cell grid.
+ bool mbShowHeadings; /// True = show column/row headings.
+ bool mbShowZeros; /// True = show zero value zells.
+ bool mbShowOutline; /// True = show outlines.
+ bool mbZoomToFit; /// True = zoom chart sheet to fit window.
+
+ explicit SheetViewModel();
+
+ /** Returns true, if page break preview is active. */
+ bool isPageBreakPreview() const;
+ /** Returns the zoom in normal view (returns default, if current value is 0). */
+ sal_Int32 getNormalZoom() const;
+ /** Returns the zoom in pagebreak preview (returns default, if current value is 0). */
+ sal_Int32 getPageBreakZoom() const;
+ /** Returns the grid color as RGB value. */
+ sal_Int32 getGridColor( const ::oox::core::FilterBase& rFilter ) const;
+
+ /** Returns the selection data, if available, otherwise 0. */
+ const PaneSelectionModel* getPaneSelection( sal_Int32 nPaneId ) const;
+ /** Returns the selection data of the active pane. */
+ const PaneSelectionModel* getActiveSelection() const;
+ /** Returns read/write access to the selection data of the specified pane. */
+ PaneSelectionModel& createPaneSelection( sal_Int32 nPaneId );
+};
+
+typedef ::boost::shared_ptr< SheetViewModel > SheetViewModelRef;
+
+// ----------------------------------------------------------------------------
+
+class SheetViewSettings : public WorksheetHelper
+{
+public:
+ explicit SheetViewSettings( const WorksheetHelper& rHelper );
+
+ /** Imports the sheetView element containing sheet view settings. */
+ void importSheetView( const AttributeList& rAttribs );
+ /** Imports the pane element containing sheet pane settings. */
+ void importPane( const AttributeList& rAttribs );
+ /** Imports the selection element containing selection settings for a pane. */
+ void importSelection( const AttributeList& rAttribs );
+ /** Imports the sheetView element containing view settings of a chart sheet. */
+ void importChartSheetView( const AttributeList& rAttribs );
+
+ /** Imports the SHEETVIEW record containing sheet view settings. */
+ void importSheetView( SequenceInputStream& rStrm );
+ /** Imports the PANE record containing sheet pane settings. */
+ void importPane( SequenceInputStream& rStrm );
+ /** Imports the SELECTION record containing selection settings for a pane. */
+ void importSelection( SequenceInputStream& rStrm );
+ /** Imports the CHARTSHEETVIEW record containing view settings of a chart sheet. */
+ void importChartSheetView( SequenceInputStream& rStrm );
+
+ /** Imports the WINDOW2 record containing sheet view settings. */
+ void importWindow2( BiffInputStream& rStrm );
+ /** Imports the PANE record containing sheet pane settings. */
+ void importPane( BiffInputStream& rStrm );
+ /** Imports the SCL record containing sheet zoom settings. */
+ void importScl( BiffInputStream& rStrm );
+ /** Imports the SELECTION record containing selection settings for a pane. */
+ void importSelection( BiffInputStream& rStrm );
+
+ /** Converts all imported sheet view settings. */
+ void finalizeImport();
+
+ /** Returns true, if the sheet layout is set to right-to-left. */
+ bool isSheetRightToLeft() const;
+
+private:
+ SheetViewModelRef createSheetView();
+
+private:
+ typedef RefVector< SheetViewModel > SheetViewModelVec;
+ SheetViewModelVec maSheetViews;
+};
+
+// ============================================================================
+
+/** Contains all view settings for the entire document. */
+struct WorkbookViewModel
+{
+ sal_Int32 mnWinX; /// X position of the workbook window (twips).
+ sal_Int32 mnWinY; /// Y position of the workbook window (twips).
+ sal_Int32 mnWinWidth; /// Width of the workbook window (twips).
+ sal_Int32 mnWinHeight; /// Height of the workbook window (twips).
+ sal_Int32 mnActiveSheet; /// Displayed (active) sheet.
+ sal_Int32 mnFirstVisSheet; /// First visible sheet in sheet tabbar.
+ sal_Int32 mnTabBarWidth; /// Width of sheet tabbar (1/1000 of window width).
+ sal_Int32 mnVisibility; /// Visibility state of workbook window.
+ bool mbShowTabBar; /// True = show sheet tabbar.
+ bool mbShowHorScroll; /// True = show horizontal sheet scrollbars.
+ bool mbShowVerScroll; /// True = show vertical sheet scrollbars.
+ bool mbMinimized; /// True = workbook window is minimized.
+
+ explicit WorkbookViewModel();
+};
+
+typedef ::boost::shared_ptr< WorkbookViewModel > WorkbookViewModelRef;
+
+// ----------------------------------------------------------------------------
+
+class ViewSettings : public WorkbookHelper
+{
+public:
+ explicit ViewSettings( const WorkbookHelper& rHelper );
+
+ /** Imports the workbookView element containing workbook view settings. */
+ void importWorkbookView( const AttributeList& rAttribs );
+ /** Imports the oleSize element containing the visible size of the workbook. */
+ void importOleSize( const AttributeList& rAttribs );
+ /** Imports the WORKBOOKVIEW record containing workbook view settings. */
+ void importWorkbookView( SequenceInputStream& rStrm );
+ /** Imports the OLESIZE record containing the visible size of the workbook. */
+ void importOleSize( SequenceInputStream& rStrm );
+ /** Imports the WINDOW1 record containing workbook view settings. */
+ void importWindow1( BiffInputStream& rStrm );
+ /** Imports the OLESIZE record containing the visible size of the workbook. */
+ void importOleSize( BiffInputStream& rStrm );
+
+ /** Stores converted view settings for a specific worksheet. */
+ void setSheetViewSettings( sal_Int16 nSheet,
+ const SheetViewModelRef& rxSheetView,
+ const ::com::sun::star::uno::Any& rProperties );
+ /** Stores the used area for a specific worksheet. */
+ void setSheetUsedArea(
+ const ::com::sun::star::table::CellRangeAddress& rUsedArea );
+
+ /** Converts all imported document view settings. */
+ void finalizeImport();
+
+ /** Returns the Calc index of the active sheet. */
+ sal_Int16 getActiveCalcSheet() const;
+
+private:
+ WorkbookViewModel& createWorkbookView();
+
+private:
+ typedef RefVector< WorkbookViewModel > WorkbookViewModelVec;
+ typedef RefMap< sal_Int16, SheetViewModel > SheetViewModelMap;
+ typedef ::std::map< sal_Int16, ::com::sun::star::uno::Any > SheetPropertiesMap;
+ typedef ::std::map< sal_Int16, ::com::sun::star::table::CellRangeAddress > SheetUsedAreaMap;
+
+ WorkbookViewModelVec maBookViews; /// Workbook view models.
+ SheetViewModelMap maSheetViews; /// Active view model for each sheet.
+ SheetPropertiesMap maSheetProps; /// Converted property sequences for each sheet.
+ SheetUsedAreaMap maSheetUsedAreas; /// Used area (cell range) of every sheet.
+ ::com::sun::star::table::CellRangeAddress
+ maOleSize; /// Visible area if this is an embedded OLE object.
+ bool mbValidOleSize; /// True = imported OLE size is a valid cell range.
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/workbookfragment.hxx b/oox/inc/oox/xls/workbookfragment.hxx
new file mode 100644
index 000000000000..d0b0cadd416b
--- /dev/null
+++ b/oox/inc/oox/xls/workbookfragment.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_WORKBOOKFRAGMENT_HXX
+#define OOX_XLS_WORKBOOKFRAGMENT_HXX
+
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+class ExternalLink;
+
+// ============================================================================
+
+class WorkbookFragment : public WorkbookFragmentBase
+{
+public:
+ explicit WorkbookFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+ virtual void finalizeImport();
+
+private:
+ void importExternalReference( const AttributeList& rAttribs );
+ void importDefinedName( const AttributeList& rAttribs );
+ void importPivotCache( const AttributeList& rAttribs );
+
+ void importExternalRef( SequenceInputStream& rStrm );
+ void importPivotCache( SequenceInputStream& rStrm );
+
+ void importExternalLinkFragment( ExternalLink& rExtLink );
+ void importPivotCacheDefFragment( const ::rtl::OUString& rRelId, sal_Int32 nCacheId );
+
+private:
+ DefinedNameRef mxCurrName;
+};
+
+// ============================================================================
+
+class BiffWorkbookFragment : public BiffWorkbookFragmentBase
+{
+public:
+ explicit BiffWorkbookFragment( const WorkbookHelper& rHelper, const ::rtl::OUString& rStrmName );
+
+ /** Imports the entire workbook stream, including all contained worksheets. */
+ virtual bool importFragment();
+
+private:
+ /** Imports a complete BIFF4 workspace fragment (with embedded sheets). */
+ bool importWorkspaceFragment();
+ /** Imports the workbook globals fragment from current stream position. */
+ bool importGlobalsFragment( ISegmentProgressBar& rProgressBar );
+ /** Imports a sheet fragment with passed type from current stream position. */
+ bool importSheetFragment(
+ ISegmentProgressBar& rProgressBar,
+ BiffFragmentType eFragment, sal_Int16 nCalcSheet );
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/workbookhelper.hxx b/oox/inc/oox/xls/workbookhelper.hxx
new file mode 100644
index 000000000000..ecf824076ef5
--- /dev/null
+++ b/oox/inc/oox/xls/workbookhelper.hxx
@@ -0,0 +1,325 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_WORKBOOKHELPER_HXX
+#define OOX_XLS_WORKBOOKHELPER_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <rtl/ref.hxx>
+#include "oox/helper/storagebase.hxx"
+#include "oox/xls/biffhelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XNameAccess; }
+ namespace container { class XNameContainer; }
+ namespace lang { class XMultiServiceFactory; }
+ namespace sheet { class XDatabaseRange; }
+ namespace sheet { class XNamedRange; }
+ namespace sheet { class XSpreadsheet; }
+ namespace sheet { class XSpreadsheetDocument; }
+ namespace style { class XStyle; }
+ namespace table { struct CellAddress; }
+ namespace table { struct CellRangeAddress; }
+ namespace table { class XCell; }
+ namespace table { class XCellRange; }
+} } }
+
+namespace oox {
+ class AttributeList;
+ class SegmentProgressBar;
+ class SequenceInputStream;
+}
+
+namespace oox { namespace core {
+ class BinaryFilterBase;
+ class FilterBase;
+ class FragmentHandler;
+ class XmlFilterBase;
+} }
+
+namespace oox { namespace drawingml {
+ class Theme;
+} }
+
+namespace oox {
+namespace xls {
+
+class ExcelFilter;
+class ExcelBiffFilter;
+
+// ============================================================================
+
+/** An enumeration for all supported spreadsheet filter types. */
+enum FilterType
+{
+ FILTER_OOXML, /// MS Excel OOXML (Office Open XML) or BIFF12.
+ FILTER_BIFF, /// MS Excel BIFF2-BIFF8 (Binary Interchange File Format).
+ FILTER_UNKNOWN /// Unknown filter type.
+};
+
+// ============================================================================
+
+/** Functor for case-insensitive string comparison, usable in maps etc. */
+struct IgnoreCaseCompare
+{
+ bool operator()( const ::rtl::OUString& rName1, const ::rtl::OUString& rName2 ) const;
+};
+
+// ============================================================================
+
+class AddressConverter;
+class BiffCodecHelper;
+class ConnectionsBuffer;
+class DefinedNamesBuffer;
+class ExcelChartConverter;
+class ExternalLinkBuffer;
+class FormulaParser;
+class PageSettingsConverter;
+class PivotCacheBuffer;
+class PivotTableBuffer;
+class ScenarioBuffer;
+class SharedStringsBuffer;
+class StylesBuffer;
+class TableBuffer;
+class ThemeBuffer;
+class UnitConverter;
+class ViewSettings;
+class WorkbookData;
+class WorkbookSettings;
+class WorksheetBuffer;
+
+/** Helper class to provice access to global workbook data.
+
+ All classes derived from this helper class will have access to a singleton
+ object of type WorkbookData containing global workbook settings, buffers,
+ converters, etc. Nearly all classes in this filter implementation are
+ derived directly or indirectly from this class.
+
+ This class contains just a simple reference to the WorkbookData object to
+ prevent circular references, as the WorkbookData object contains a lot of
+ objects derived from this class.
+ */
+class WorkbookHelper
+{
+public:
+ inline /*implicit*/ WorkbookHelper( WorkbookData& rBookData ) : mrBookData( rBookData ) {}
+ virtual ~WorkbookHelper();
+
+ // filter -----------------------------------------------------------------
+
+ /** Returns the base filter object (base class of all filters). */
+ ::oox::core::FilterBase& getBaseFilter() const;
+ /** Returns a reference to the global service factory. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
+ getGlobalFactory() const;
+ /** Returns the file type of the current filter. */
+ FilterType getFilterType() const;
+ /** Returns the filter progress bar. */
+ SegmentProgressBar& getProgressBar() const;
+ /** Returns true, if the file is a multi-sheet document, or false if single-sheet. */
+ bool isWorkbookFile() const;
+ /** Returns the index of the current sheet in the Calc document. */
+ sal_Int16 getCurrentSheetIndex() const;
+
+ /** Sets the index of the current sheet in the Calc document. */
+ void setCurrentSheetIndex( sal_Int16 nSheet );
+ /** Sets the VBA project storage. */
+ void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg );
+ /** Final conversion after importing the workbook. */
+ void finalizeWorkbookImport();
+
+ // document model ---------------------------------------------------------
+
+ /** Returns a reference to the source/target spreadsheet document model. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
+ getDocument() const;
+ /** Returns a reference to the service factory of the spreadsheet document model. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
+ getDocumentFactory() const;
+
+ /** Returns a reference to the specified spreadsheet in the document model. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >
+ getSheetFromDoc( sal_Int16 nSheet ) const;
+ /** Returns a reference to the specified spreadsheet in the document model. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >
+ getSheetFromDoc( const ::rtl::OUString& rSheet ) const;
+
+ /** Returns the XCell interface for the passed cell address. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >
+ getCellFromDoc(
+ const ::com::sun::star::table::CellAddress& rAddress ) const;
+ /** Returns the XCellRange interface for the passed cell range address. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ getCellRangeFromDoc(
+ const ::com::sun::star::table::CellRangeAddress& rRange ) const;
+
+ /** Returns the cell or page styles container from the Calc document. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ getStyleFamily( bool bPageStyles ) const;
+ /** Returns the specified cell or page style from the Calc document. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >
+ getStyleObject( const ::rtl::OUString& rStyleName, bool bPageStyle ) const;
+
+ /** Creates and returns a defined name on-the-fly in the Calc document.
+ The name will not be buffered in the global defined names buffer.
+ @param orName (in/out-parameter) Returns the resulting used name. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XNamedRange >
+ createNamedRangeObject(
+ ::rtl::OUString& orName,
+ sal_Int32 nNameFlags = 0 ) const;
+
+ /** Creates and returns a database range on-the-fly in the Calc document.
+ The range will not be buffered in the global table buffer.
+ @param orName (in/out-parameter) Returns the resulting used name. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDatabaseRange >
+ createDatabaseRangeObject(
+ ::rtl::OUString& orName,
+ const ::com::sun::star::table::CellRangeAddress& rRangeAddr ) const;
+
+ /** Creates and returns a com.sun.star.style.Style object for cells or pages. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >
+ createStyleObject(
+ ::rtl::OUString& orStyleName,
+ bool bPageStyle ) const;
+
+ // buffers ----------------------------------------------------------------
+
+ /** Returns the global workbook settings object. */
+ WorkbookSettings& getWorkbookSettings() const;
+ /** Returns the workbook and sheet view settings object. */
+ ViewSettings& getViewSettings() const;
+ /** Returns the worksheet buffer containing sheet names and properties. */
+ WorksheetBuffer& getWorksheets() const;
+ /** Returns the office theme object read from the theme substorage. */
+ ThemeBuffer& getTheme() const;
+ /** Returns all cell formatting objects read from the styles substream. */
+ StylesBuffer& getStyles() const;
+ /** Returns the shared strings read from the shared strings substream. */
+ SharedStringsBuffer& getSharedStrings() const;
+ /** Returns the external links read from the external links substream. */
+ ExternalLinkBuffer& getExternalLinks() const;
+ /** Returns the defined names read from the workbook globals. */
+ DefinedNamesBuffer& getDefinedNames() const;
+ /** Returns the tables collection (equivalent to Calc's database ranges). */
+ TableBuffer& getTables() const;
+ /** Returns the scenarios collection. */
+ ScenarioBuffer& getScenarios() const;
+ /** Returns the collection of external data connections. */
+ ConnectionsBuffer& getConnections() const;
+ /** Returns the collection of pivot caches. */
+ PivotCacheBuffer& getPivotCaches() const;
+ /** Returns the collection of pivot tables. */
+ PivotTableBuffer& getPivotTables() const;
+
+ // converters -------------------------------------------------------------
+
+ /** Returns the import formula parser (import filter only!). */
+ FormulaParser& getFormulaParser() const;
+ /** Returns the measurement unit converter. */
+ UnitConverter& getUnitConverter() const;
+ /** Returns the converter for string to cell address/range conversion. */
+ AddressConverter& getAddressConverter() const;
+ /** Returns the chart object converter. */
+ ExcelChartConverter& getChartConverter() const;
+ /** Returns the page and print settings converter. */
+ PageSettingsConverter& getPageSettingsConverter() const;
+
+ // OOXML/BIFF12 specific (MUST NOT be called in BIFF filter) --------------
+
+ /** Returns the base OOXML/BIFF12 filter object.
+ Must not be called, if current filter is not the OOXML/BIFF12 filter. */
+ ::oox::core::XmlFilterBase& getOoxFilter() const;
+
+ /** Imports a fragment using the passed fragment handler, which contains
+ the full path to the fragment stream. */
+ bool importOoxFragment( const ::rtl::Reference< ::oox::core::FragmentHandler >& rxHandler );
+
+ // BIFF2-BIFF8 specific (MUST NOT be called in OOXML/BIFF12 filter) -------
+
+ /** Returns the base BIFF filter object. */
+ ::oox::core::BinaryFilterBase& getBiffFilter() const;
+ /** Returns the BIFF type in binary filter. */
+ BiffType getBiff() const;
+
+ /** Returns the text encoding used to import/export byte strings. */
+ rtl_TextEncoding getTextEncoding() const;
+ /** 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( sal_Int16 nSheet );
+
+ /** Returns the codec helper that stores the encoder/decoder object. */
+ BiffCodecHelper& getCodecHelper() const;
+
+private:
+ WorkbookData& mrBookData;
+};
+
+// ============================================================================
+
+namespace prv {
+
+typedef ::boost::shared_ptr< WorkbookData > WorkbookDataRef;
+
+struct WorkbookDataOwner
+{
+ explicit WorkbookDataOwner( WorkbookDataRef xBookData );
+ virtual ~WorkbookDataOwner();
+ WorkbookDataRef mxBookData;
+};
+
+} // namespace prv
+
+// ----------------------------------------------------------------------------
+
+class WorkbookHelperRoot : private prv::WorkbookDataOwner, public WorkbookHelper
+{
+public:
+ explicit WorkbookHelperRoot( ExcelFilter& rFilter );
+ explicit WorkbookHelperRoot( ExcelBiffFilter& rFilter, BiffType eBiff );
+
+ /** Returns true, if this helper refers to a valid document. */
+ bool isValid() const;
+
+private:
+ WorkbookHelperRoot( const WorkbookHelperRoot& );
+ WorkbookHelperRoot& operator=( const WorkbookHelperRoot& );
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/workbooksettings.hxx b/oox/inc/oox/xls/workbooksettings.hxx
new file mode 100644
index 000000000000..858e886df778
--- /dev/null
+++ b/oox/inc/oox/xls/workbooksettings.hxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_WORKBOOKSETTINGS_HXX
+#define OOX_XLS_WORKBOOKSETTINGS_HXX
+
+#include "oox/xls/workbookhelper.hxx"
+
+namespace com { namespace sun { namespace star { namespace util { struct Date; } } } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Settings for workbook write protection. */
+struct FileSharingModel
+{
+ ::rtl::OUString maUserName; /// User who added the write protection password.
+ sal_uInt16 mnPasswordHash; /// Hash value of the write protection password.
+ bool mbRecommendReadOnly; /// True = recommend read-only mode on opening.
+
+ explicit FileSharingModel();
+};
+
+// ============================================================================
+
+/** Global workbook settings. */
+struct WorkbookSettingsModel
+{
+ ::rtl::OUString maCodeName; /// VBA codename for the workbook.
+ sal_Int32 mnShowObjectMode; /// Specifies how objects are shown.
+ sal_Int32 mnUpdateLinksMode; /// Specifies how external links are updated.
+ sal_Int32 mnDefaultThemeVer; /// Default theme version.
+ bool mbDateMode1904; /// True = null date is 1904-01-01.
+ bool mbSaveExtLinkValues; /// True = save cached cell values for external links.
+
+ explicit WorkbookSettingsModel();
+
+ /** Sets BIFF object visibility mode. */
+ void setBiffObjectMode( sal_uInt16 nObjMode );
+};
+
+// ============================================================================
+
+/** Workbook calculation settings. */
+struct CalcSettingsModel
+{
+ double mfIterateDelta; /// Minimum change in circular references.
+ sal_Int32 mnCalcId; /// Calculation engine identifier.
+ sal_Int32 mnRefMode; /// Cell reference mode: A1 or R1C1.
+ sal_Int32 mnCalcMode; /// Automatic or manual recalculation.
+ sal_Int32 mnIterateCount; /// Number of iterations in circular references.
+ sal_Int32 mnProcCount; /// Number of processors for concurrent calculation.
+ bool mbCalcOnSave; /// True = always recalculate formulas before save.
+ bool mbCalcCompleted; /// True = formulas have been recalculated before save.
+ bool mbFullPrecision; /// True = use full precision on calculation.
+ bool mbIterate; /// True = allow circular references.
+ bool mbConcurrent; /// True = concurrent calculation enabled.
+ bool mbUseNlr; /// True = use natural language references in formulas.
+
+ explicit CalcSettingsModel();
+};
+
+// ============================================================================
+
+class WorkbookSettings : public WorkbookHelper
+{
+public:
+ explicit WorkbookSettings( const WorkbookHelper& rHelper );
+
+ /** Imports the fileSharing element containing write protection settings. */
+ void importFileSharing( const AttributeList& rAttribs );
+ /** Imports the workbookPr element containing global workbook settings. */
+ void importWorkbookPr( const AttributeList& rAttribs );
+ /** Imports the calcPr element containing workbook calculation settings. */
+ void importCalcPr( const AttributeList& rAttribs );
+
+ /** Imports the FILESHARING record containing write protection settings. */
+ void importFileSharing( SequenceInputStream& rStrm );
+ /** Imports the WORKBOOKPR record containing global workbook settings. */
+ void importWorkbookPr( SequenceInputStream& rStrm );
+ /** Imports the CALCPR record containing workbook calculation settings. */
+ void importCalcPr( SequenceInputStream& rStrm );
+
+ /** Sets the save external linked values flag, e.g. from the WSBOOL record. */
+ void setSaveExtLinkValues( bool bSaveExtLinks );
+ /** Imports the BOOKBOOL record. */
+ void importBookBool( BiffInputStream& rStrm );
+ /** Imports the CALCCOUNT record. */
+ void importCalcCount( BiffInputStream& rStrm );
+ /** Imports the CALCMODE record. */
+ void importCalcMode( BiffInputStream& rStrm );
+ /** Imports the CODENAME record. */
+ void importCodeName( BiffInputStream& rStrm );
+ /** Imports the DATEMODE record. */
+ void importDateMode( BiffInputStream& rStrm );
+ /** Imports the DELTA record. */
+ void importDelta( BiffInputStream& rStrm );
+ /** Imports the FILESHARING record. */
+ void importFileSharing( BiffInputStream& rStrm );
+ /** Imports the HIDEOBJ record. */
+ void importHideObj( BiffInputStream& rStrm );
+ /** Imports the ITERATION record. */
+ void importIteration( BiffInputStream& rStrm );
+ /** Imports the PRECISION record. */
+ void importPrecision( BiffInputStream& rStrm );
+ /** Imports the REFMODE record. */
+ void importRefMode( BiffInputStream& rStrm );
+ /** Imports the SAVERECALC record. */
+ void importSaveRecalc( BiffInputStream& rStrm );
+ /** Imports the UNCALCED record. */
+ void importUncalced( BiffInputStream& rStrm );
+ /** Imports the USESELFS record. */
+ void importUsesElfs( BiffInputStream& rStrm );
+
+ /** Converts the imported workbook settings. */
+ void finalizeImport();
+
+ /** Returns the show objects mode (considered a view setting in Calc). */
+ sal_Int16 getApiShowObjectMode() const;
+ /** Returns the nulldate of this workbook. */
+ ::com::sun::star::util::Date getNullDate() const;
+
+private:
+ /** Updates date mode and unit converter nulldate. */
+ void setDateMode( bool bDateMode1904 );
+
+private:
+ FileSharingModel maFileSharing;
+ WorkbookSettingsModel maBookSettings;
+ CalcSettingsModel maCalcSettings;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/worksheetbuffer.hxx b/oox/inc/oox/xls/worksheetbuffer.hxx
new file mode 100644
index 000000000000..7c59cce988dd
--- /dev/null
+++ b/oox/inc/oox/xls/worksheetbuffer.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_WORKSHEETBUFFER_HXX
+#define OOX_XLS_WORKSHEETBUFFER_HXX
+
+#include <utility>
+#include "oox/helper/refmap.hxx"
+#include "oox/helper/refvector.hxx"
+#include "oox/xls/workbookhelper.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace i18n { class XCharacterClassification; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Contains data from the 'sheet' element describing a sheet in the workbook. */
+struct SheetInfoModel
+{
+ ::rtl::OUString maRelId; /// Relation identifier for the sheet substream.
+ ::rtl::OUString maName; /// Original name of the sheet.
+ sal_Int64 mnBiffHandle; /// BIFF record handle of the sheet substream.
+ sal_Int32 mnSheetId; /// Sheet identifier.
+ sal_Int32 mnState; /// Visibility state.
+
+ explicit SheetInfoModel();
+};
+
+// ============================================================================
+
+/** Stores information about all sheets in a spreadsheet document.
+
+ Information about sheets includes the sheet name, the visibility state, and
+ for the OOXML filter, the relation identifier of the sheet used to obtain
+ the related worksheet fragment.
+ */
+class WorksheetBuffer : public WorkbookHelper
+{
+public:
+ explicit WorksheetBuffer( const WorkbookHelper& rHelper );
+
+ /** Returns the base file name without path and file extension. */
+ static ::rtl::OUString getBaseFileName( const ::rtl::OUString& rUrl );
+
+ /** Initializes the buffer for single sheet files (BIFF2-BIFF4). */
+ void initializeSingleSheet();
+
+ /** Imports the attributes of a sheet element. */
+ void importSheet( const AttributeList& rAttribs );
+ /** Imports the SHEET record from the passed BIFF12 stream. */
+ void importSheet( SequenceInputStream& rStrm );
+ /** Imports the SHEET record from the passed BIFF stream. */
+ void importSheet( BiffInputStream& rStrm );
+ /** Inserts a new empty sheet into the document. Looks for an unused name.
+ @return Index of the new sheet in the Calc document. */
+ sal_Int16 insertEmptySheet( const ::rtl::OUString& rPreferredName, bool bVisible );
+
+ /** Returns the number of original sheets contained in the workbook. */
+ sal_Int32 getWorksheetCount() const;
+ /** Returns the OOXML relation identifier of the specified worksheet. */
+ ::rtl::OUString getWorksheetRelId( sal_Int32 nWorksheet ) const;
+ /** Returns the BIFF record handle of the associated sheet substream. */
+ sal_Int64 getBiffRecordHandle( sal_Int32 nWorksheet ) const;
+
+ /** Returns the Calc index of the specified worksheet. */
+ sal_Int16 getCalcSheetIndex( sal_Int32 nWorksheet ) const;
+ /** Returns the finalized name of the specified worksheet. */
+ ::rtl::OUString getCalcSheetName( sal_Int32 nWorksheet ) const;
+
+ /** Returns the Calc index of the sheet with the passed original worksheet name. */
+ sal_Int16 getCalcSheetIndex( const ::rtl::OUString& rWorksheetName ) const;
+ /** Returns the finalized name of the sheet with the passed worksheet name. */
+ ::rtl::OUString getCalcSheetName( const ::rtl::OUString& rWorksheetName ) const;
+
+private:
+ struct SheetInfo : public SheetInfoModel
+ {
+ ::rtl::OUString maCalcName;
+ ::rtl::OUString maCalcQuotedName;
+ sal_Int16 mnCalcSheet;
+
+ explicit SheetInfo( const SheetInfoModel& rModel, sal_Int16 nCalcSheet, const ::rtl::OUString& rCalcName );
+ };
+
+ typedef ::std::pair< sal_Int16, ::rtl::OUString > IndexNamePair;
+
+ /** Creates a new sheet in the Calc document. Does not insert anything in the own lists. */
+ IndexNamePair createSheet( const ::rtl::OUString& rPreferredName, sal_Int32 nSheetPos, bool bVisible );
+ /** Creates a new sheet in the Calc document and inserts the related SheetInfo. */
+ void insertSheet( const SheetInfoModel& rModel );
+
+private:
+ typedef RefVector< SheetInfo > SheetInfoVector;
+ SheetInfoVector maSheetInfos;
+
+ typedef RefMap< ::rtl::OUString, SheetInfo, IgnoreCaseCompare > SheetInfoMap;
+ SheetInfoMap maSheetInfosByName;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/worksheetfragment.hxx b/oox/inc/oox/xls/worksheetfragment.hxx
new file mode 100644
index 000000000000..4fe3bf4240dd
--- /dev/null
+++ b/oox/inc/oox/xls/worksheetfragment.hxx
@@ -0,0 +1,193 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_WORKSHEETFRAGMENT_HXX
+#define OOX_XLS_WORKSHEETFRAGMENT_HXX
+
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+class DataValidationsContext : public WorksheetContextBase
+{
+public:
+ explicit DataValidationsContext( WorksheetFragmentBase& rFragment );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+ virtual void onEndElement();
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+private:
+ /** Imports the dataValidation element containing data validation settings. */
+ void importDataValidation( const AttributeList& rAttribs );
+ /** Imports the DATAVALIDATION record containing data validation settings. */
+ void importDataValidation( SequenceInputStream& rStrm );
+
+private:
+ ::std::auto_ptr< ValidationModel > mxValModel;
+};
+
+// ============================================================================
+
+class WorksheetFragment : public WorksheetFragmentBase
+{
+public:
+ explicit WorksheetFragment(
+ const WorkbookHelper& rHelper,
+ const ::rtl::OUString& rFragmentPath,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
+ virtual void onCharacters( const ::rtl::OUString& rChars );
+
+ virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
+
+ virtual const ::oox::core::RecordInfo* getRecordInfos() const;
+ virtual void initializeImport();
+ virtual void finalizeImport();
+
+private:
+ /** Imports page settings from a pageSetUpPr element. */
+ void importPageSetUpPr( const AttributeList& rAttribs );
+ /** Imports the dimension element containing the used area of the sheet. */
+ void importDimension( const AttributeList& rAttribs );
+ /** Imports sheet format properties from a sheetFormatPr element. */
+ void importSheetFormatPr( const AttributeList& rAttribs );
+ /** Imports column settings from a col element. */
+ void importCol( const AttributeList& rAttribs );
+ /** Imports a merged cell range from a mergeCell element. */
+ void importMergeCell( const AttributeList& rAttribs );
+ /** Imports the hyperlink element containing a hyperlink for a cell range. */
+ void importHyperlink( const AttributeList& rAttribs );
+ /** Imports individual break that is either within row or column break context. */
+ void importBrk( const AttributeList& rAttribs, bool bRowBreak );
+ /** Imports the the relation identifier for the DrawingML part. */
+ void importDrawing( const AttributeList& rAttribs );
+ /** Imports the the relation identifier for the legacy VML drawing part. */
+ void importLegacyDrawing( const AttributeList& rAttribs );
+ /** Imports additional data for an OLE object. */
+ void importOleObject( const AttributeList& rAttribs );
+ /** Imports additional data for an OCX form control. */
+ void importControl( const AttributeList& rAttribs );
+
+ /** Imports the DIMENSION record containing the used area of the sheet. */
+ void importDimension( SequenceInputStream& rStrm );
+ /** Imports sheet format properties from a SHEETFORMATPR record. */
+ void importSheetFormatPr( SequenceInputStream& rStrm );
+ /** Imports column settings from a COL record. */
+ void importCol( SequenceInputStream& rStrm );
+ /** Imports a merged cell range from a MERGECELL record. */
+ void importMergeCell( SequenceInputStream& rStrm );
+ /** Imports a hyperlink for a cell range from a HYPERLINK record. */
+ void importHyperlink( SequenceInputStream& rStrm );
+ /** Imports the BRK record for an individual row or column page break. */
+ void importBrk( SequenceInputStream& rStrm, bool bRowBreak );
+ /** Imports the DRAWING record containing the relation identifier for the DrawingML part. */
+ void importDrawing( SequenceInputStream& rStrm );
+ /** Imports the LEGACYDRAWING record containing the relation identifier for the VML drawing part. */
+ void importLegacyDrawing( SequenceInputStream& rStrm );
+ /** Imports additional data for an OLE object. */
+ void importOleObject( SequenceInputStream& rStrm );
+ /** Imports additional data for an OCX form control. */
+ void importControl( SequenceInputStream& rStrm );
+
+ /** Imports the binary data of an embedded OLE object from the fragment with the passed ID. */
+ void importEmbeddedOleData( StreamDataSequence& orEmbeddedData, const ::rtl::OUString& rRelId );
+};
+
+// ============================================================================
+
+class BiffWorksheetFragment : public BiffWorksheetFragmentBase
+{
+public:
+ explicit BiffWorksheetFragment(
+ const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+ virtual ~BiffWorksheetFragment();
+
+ /** Imports the entire worksheet fragment, returns true, if EOF record has been reached. */
+ virtual bool importFragment();
+
+private:
+ /** Imports the AUTOFILTER and following records with auto filter settings. */
+ void importAutoFilter( BiffInputStream& rStrm );
+ /** Imports the COLINFO record and sets column properties and formatting. */
+ void importColInfo( BiffInputStream& rStrm );
+ /** Imports the BIFF2 COLUMNDEFAULT record and sets column default formatting. */
+ void importColumnDefault( BiffInputStream& rStrm );
+ /** Imports the BIFF2 COLWIDTH record and sets column width. */
+ void importColWidth( BiffInputStream& rStrm );
+ /** Imports the DATAVALIDATION record containing cell ranges with data validation settings. */
+ void importDataValidation( BiffInputStream& rStrm );
+ /** Imports the DATAVALIDATIONS record containing global data validation settings. */
+ void importDataValidations( BiffInputStream& rStrm );
+ /** Imports the DEFCOLWIDTH record and sets default column width. */
+ void importDefColWidth( BiffInputStream& rStrm );
+ /** Imports the DEFROWHEIGHT record and sets default row height and properties. */
+ void importDefRowHeight( BiffInputStream& rStrm );
+ /** Imports the DIMENSION record containing the used area of the sheet. */
+ void importDimension( BiffInputStream& rStrm );
+ /** Imports the HYPERLINK record and sets a cell hyperlink. */
+ void importHyperlink( BiffInputStream& rStrm );
+ /** Imports the LABELRANGES record and sets the imported label ranges. */
+ void importLabelRanges( BiffInputStream& rStrm );
+ /** Imports the MEREDCELLS record and merges all cells in the document. */
+ void importMergedCells( BiffInputStream& rStrm );
+ /** Imports the HORPAGEBREAKS or VERPAGEBREAKS record and inserts page breaks. */
+ void importPageBreaks( BiffInputStream& rStrm, bool bRowBreak );
+ /** Imports a pivot table. */
+ void importPTDefinition( BiffInputStream& rStrm );
+ /** Imports the QUERYTABLE and following records and inserts a web query. */
+ void importQueryTable( BiffInputStream& rStrm );
+ /** Imports the SCENARIOS record and the following scenarios. */
+ void importScenarios( BiffInputStream& rStrm );
+ /** Imports the SHAREDFEATHEAD record. */
+ void importSharedFeatHead( BiffInputStream& rStrm );
+ /** Imports the STANDARDWIDTH record and sets standard column width. */
+ void importStandardWidth( BiffInputStream& rStrm );
+
+private:
+ ::boost::shared_ptr< BiffWorksheetContextBase > mxContext;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/worksheethelper.hxx b/oox/inc/oox/xls/worksheethelper.hxx
new file mode 100644
index 000000000000..55bf1c044e30
--- /dev/null
+++ b/oox/inc/oox/xls/worksheethelper.hxx
@@ -0,0 +1,475 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_WORKSHEETHELPER_HXX
+#define OOX_XLS_WORKSHEETHELPER_HXX
+
+#include "oox/helper/progressbar.hxx"
+#include "oox/ole/olehelper.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/formulabase.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace awt { struct Point; }
+ namespace awt { struct Rectangle; }
+ namespace awt { struct Size; }
+ namespace drawing { class XDrawPage; }
+ namespace sheet { class XSheetCellRanges; }
+ namespace sheet { class XSpreadsheet; }
+ namespace table { class XCell; }
+ namespace table { class XCellRange; }
+ namespace table { class XTableColumns; }
+ namespace table { class XTableRows; }
+ namespace util { struct DateTime; }
+} } }
+
+namespace oox {
+namespace xls {
+
+class AutoFilterBuffer;
+struct BinAddress;
+struct BinRange;
+class BinRangeList;
+class CommentsBuffer;
+class CondFormatBuffer;
+class PageSettings;
+class QueryTableBuffer;
+class SharedFormulaBuffer;
+class SheetViewSettings;
+class VmlDrawing;
+class WorksheetSettings;
+
+// ============================================================================
+// ============================================================================
+
+/** An enumeration for all types of sheets in a workbook. */
+enum WorksheetType
+{
+ SHEETTYPE_WORKSHEET, /// Worksheet.
+ SHEETTYPE_CHARTSHEET, /// Chart sheet.
+ SHEETTYPE_MACROSHEET, /// Macro sheet.
+ SHEETTYPE_DIALOGSHEET, /// Dialog sheet (BIFF5+).
+ SHEETTYPE_MODULESHEET, /// VB module sheet (BIFF5 only).
+ SHEETTYPE_EMPTYSHEET /// Other (unsupported) sheet type.
+};
+
+// ============================================================================
+
+/** Stores some data about a cell. */
+struct CellModel
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > mxCell;
+ ::com::sun::star::table::CellAddress maAddress;
+ ::rtl::OUString maValueStr; /// String containing cell value data.
+ ::rtl::OUString maFormulaRef; /// String containing formula range for array/shared formulas.
+ sal_Int32 mnCellType; /// Data type of the cell.
+ sal_Int32 mnFormulaType; /// Type of the imported formula.
+ sal_Int32 mnSharedId; /// Shared formula identifier for current cell.
+ sal_Int32 mnXfId; /// XF identifier for the cell.
+ sal_Int32 mnNumFmtId; /// Forced number format for the cell.
+ bool mbHasValueStr; /// True = contents of maValueStr are valid.
+ bool mbShowPhonetic; /// True = show phonetic text.
+
+ inline explicit CellModel() { reset(); }
+ void reset();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores data about a data table a.k.a. multiple operation range. */
+struct DataTableModel
+{
+ ::rtl::OUString maRef1; /// String containing first reference cell for data table formulas.
+ ::rtl::OUString maRef2; /// String containing second reference cell for data table formulas.
+ bool mb2dTable; /// True = 2-dimensional data table.
+ bool mbRowTable; /// True = row oriented data table.
+ bool mbRef1Deleted; /// True = first reference cell deleted.
+ bool mbRef2Deleted; /// True = second reference cell deleted.
+
+ explicit DataTableModel();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores formatting data about a range of columns. */
+struct ColumnModel
+{
+ sal_Int32 mnFirstCol; /// 1-based (!) index of first column.
+ sal_Int32 mnLastCol; /// 1-based (!) index of last column.
+ double mfWidth; /// Column width in number of characters.
+ sal_Int32 mnXfId; /// Column default formatting.
+ sal_Int32 mnLevel; /// Column outline level.
+ bool mbShowPhonetic; /// True = cells in column show phonetic settings.
+ bool mbHidden; /// True = column is hidden.
+ bool mbCollapsed; /// True = column outline is collapsed.
+
+ explicit ColumnModel();
+
+ /** Expands this entry with the passed column range, if column settings are equal. */
+ bool tryExpand( const ColumnModel& rModel );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores formatting data about a range of rows. */
+struct RowModel
+{
+ sal_Int32 mnFirstRow; /// 1-based (!) index of first row.
+ sal_Int32 mnLastRow; /// 1-based (!) index of last row.
+ double mfHeight; /// Row height in points.
+ sal_Int32 mnXfId; /// Row default formatting (see mbIsFormatted).
+ sal_Int32 mnLevel; /// Row outline level.
+ bool mbCustomHeight; /// True = row has custom height.
+ bool mbCustomFormat; /// True = cells in row have explicit formatting.
+ bool mbShowPhonetic; /// True = cells in row show phonetic settings.
+ bool mbHidden; /// True = row is hidden.
+ bool mbCollapsed; /// True = row outline is collapsed.
+ bool mbThickTop; /// True = row has extra space above text.
+ bool mbThickBottom; /// True = row has extra space below text.
+
+ explicit RowModel();
+
+ /** Expands this entry with the passed row range, if row settings are equal. */
+ bool tryExpand( const RowModel& rModel );
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores formatting data about a page break. */
+struct PageBreakModel
+{
+ sal_Int32 mnColRow; /// 0-based (!) index of column/row.
+ sal_Int32 mnMin; /// Start of limited break.
+ sal_Int32 mnMax; /// End of limited break.
+ bool mbManual; /// True = manual page break.
+
+ explicit PageBreakModel();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores data about a hyperlink range. */
+struct HyperlinkModel : public ::oox::ole::StdHlinkInfo
+{
+ ::com::sun::star::table::CellRangeAddress
+ maRange; /// The cell area containing the hyperlink.
+ ::rtl::OUString maTooltip; /// Additional tooltip text.
+
+ explicit HyperlinkModel();
+};
+
+// ----------------------------------------------------------------------------
+
+/** Stores data about ranges with data validation settings. */
+struct ValidationModel
+{
+ ApiCellRangeList maRanges;
+ ApiTokenSequence maTokens1;
+ ApiTokenSequence maTokens2;
+ ::rtl::OUString maInputTitle;
+ ::rtl::OUString maInputMessage;
+ ::rtl::OUString maErrorTitle;
+ ::rtl::OUString maErrorMessage;
+ sal_Int32 mnType;
+ sal_Int32 mnOperator;
+ sal_Int32 mnErrorStyle;
+ bool mbShowInputMsg;
+ bool mbShowErrorMsg;
+ bool mbNoDropDown;
+ bool mbAllowBlank;
+
+ explicit ValidationModel();
+
+ /** Sets the passed BIFF validation type. */
+ void setBiffType( sal_uInt8 nType );
+ /** Sets the passed BIFF operator. */
+ void setBiffOperator( sal_uInt8 nOperator );
+ /** Sets the passed BIFF error style. */
+ void setBiffErrorStyle( sal_uInt8 nErrorStyle );
+};
+
+// ============================================================================
+// ============================================================================
+
+class WorksheetData;
+
+class WorksheetHelper : public WorkbookHelper
+{
+public:
+ /*implicit*/ WorksheetHelper( WorksheetData& rSheetData );
+
+ /** Returns the type of this sheet. */
+ WorksheetType getSheetType() const;
+ /** Returns the index of the current sheet. */
+ sal_Int16 getSheetIndex() const;
+ /** Returns the XSpreadsheet interface of the current sheet. */
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >&
+ getSheet() const;
+
+ /** Returns the XCell interface for the passed cell address. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >
+ getCell(
+ const ::com::sun::star::table::CellAddress& rAddress ) const;
+ /** Returns the XCell interface for the passed cell address string. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >
+ getCell(
+ const ::rtl::OUString& rAddressStr,
+ ::com::sun::star::table::CellAddress* opAddress = 0 ) const;
+ /** Returns the XCell interface for the passed cell address. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >
+ getCell(
+ const BinAddress& rBinAddress,
+ ::com::sun::star::table::CellAddress* opAddress = 0 ) const;
+
+ /** Returns the XCellRange interface for the passed cell range address. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ getCellRange(
+ const ::com::sun::star::table::CellRangeAddress& rRange ) const;
+ /** Returns the XCellRange interface for the passed range address string. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ getCellRange(
+ const ::rtl::OUString& rRangeStr,
+ ::com::sun::star::table::CellRangeAddress* opRange = 0 ) const;
+ /** Returns the XCellRange interface for the passed range address. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ getCellRange(
+ const BinRange& rBinRange,
+ ::com::sun::star::table::CellRangeAddress* opRange = 0 ) const;
+
+ /** Returns the XSheetCellRanges interface for the passed cell range addresses. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSheetCellRanges >
+ getCellRangeList( const ApiCellRangeList& rRanges ) const;
+ /** Returns the XSheetCellRanges interface for the passed space-separated range list. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSheetCellRanges >
+ getCellRangeList(
+ const ::rtl::OUString& rRangesStr,
+ ApiCellRangeList* opRanges = 0 ) const;
+ /** Returns the XSheetCellRanges interface for the passed range list. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSheetCellRanges >
+ getCellRangeList(
+ const BinRangeList& rBinRanges,
+ ApiCellRangeList* opRanges = 0 ) const;
+
+ /** Returns the address of the passed cell. The cell reference must be valid. */
+ static ::com::sun::star::table::CellAddress
+ getCellAddress(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell );
+ /** Returns the address of the passed cell range. The range reference must be valid. */
+ static ::com::sun::star::table::CellRangeAddress
+ getRangeAddress(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >& rxRange );
+
+ /** Returns the XCellRange interface for a column. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ getColumn( sal_Int32 nCol ) const;
+ /** Returns the XCellRange interface for a row. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >
+ getRow( sal_Int32 nRow ) const;
+
+ /** Returns the XTableColumns interface for a range of columns. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XTableColumns >
+ getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const;
+ /** Returns the XTableRows interface for a range of rows. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::table::XTableRows >
+ getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const;
+
+ /** Returns the XDrawPage interface of the draw page of the current sheet. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >
+ getDrawPage() const;
+
+ /** Returns the absolute cell position in 1/100 mm. */
+ ::com::sun::star::awt::Point getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const;
+ /** Returns the cell size in 1/100 mm. */
+ ::com::sun::star::awt::Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const;
+ /** Returns the size of the entire drawing page in 1/100 mm. */
+ ::com::sun::star::awt::Size getDrawPageSize() const;
+
+ /** Returns the worksheet settings object. */
+ WorksheetSettings& getWorksheetSettings() const;
+ /** Returns the buffer containing all shared formulas in this sheet. */
+ SharedFormulaBuffer& getSharedFormulas() const;
+ /** Returns the conditional formattings in this sheet. */
+ CondFormatBuffer& getCondFormats() const;
+ /** Returns the buffer for all cell comments in this sheet. */
+ CommentsBuffer& getComments() const;
+ /** Returns the auto filters for the sheet. */
+ AutoFilterBuffer& getAutoFilters() const;
+ /** Returns the buffer for all web query tables in this sheet. */
+ QueryTableBuffer& getQueryTables() const;
+ /** Returns the page/print settings for this sheet. */
+ PageSettings& getPageSettings() const;
+ /** Returns the view settings for this sheet. */
+ SheetViewSettings& getSheetViewSettings() const;
+ /** Returns the VML drawing page for this sheet. */
+ VmlDrawing& getVmlDrawing() const;
+
+ /** Sets the passed string to the cell. */
+ void setStringCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell,
+ const ::rtl::OUString& rText ) const;
+ /** Sets the shared string with the passed identifier to the cell. */
+ void setSharedStringCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell,
+ sal_Int32 nStringId,
+ sal_Int32 nXfId ) const;
+ /** Sets the passed date/time value to the cell and adjusts number format. */
+ void setDateTimeCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell,
+ const ::com::sun::star::util::DateTime& rDateTime ) const;
+ /** Sets the passed boolean value to the cell and adjusts number format. */
+ void setBooleanCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell,
+ bool bValue ) const;
+ /** Sets the passed BIFF error code to the cell (by converting it to a formula). */
+ void setErrorCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell,
+ const ::rtl::OUString& rErrorCode ) const;
+ /** Sets the passed BIFF error code to the cell (by converting it to a formula). */
+ void setErrorCell(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell,
+ sal_uInt8 nErrorCode ) const;
+ /** Sets cell contents to the cell specified in the passed cell model. */
+ void setCell( CellModel& orModel ) const;
+
+ /** Sets a standard number format (constant from com.sun.star.util.NumberFormat) to the passed cell. */
+ void setStandardNumFmt(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >& rxCell,
+ sal_Int16 nStdNumFmt ) const;
+
+ /** Changes the current sheet type. */
+ void setSheetType( WorksheetType eSheetType );
+ /** Stores the cell formatting data of the current cell. */
+ void setCellFormat( const CellModel& rModel );
+ /** Merges the cells in the passed cell range. */
+ void setMergedRange( const ::com::sun::star::table::CellRangeAddress& rRange );
+ /** Sets a column or row page break described in the passed struct. */
+ void setPageBreak( const PageBreakModel& rModel, bool bRowBreak );
+ /** Inserts the hyperlink URL into the spreadsheet. */
+ void setHyperlink( const HyperlinkModel& rModel );
+ /** Inserts the data validation settings into the spreadsheet. */
+ void setValidation( const ValidationModel& rModel );
+ /** Sets a multiple table operation to the passed range. */
+ void setTableOperation(
+ const ::com::sun::star::table::CellRangeAddress& rRange,
+ const DataTableModel& rModel ) const;
+ /** Sets the passed label ranges to the current sheet. */
+ void setLabelRanges(
+ const ApiCellRangeList& rColRanges,
+ const ApiCellRangeList& rRowRanges );
+ /** Sets the path to the DrawingML fragment of this sheet. */
+ void setDrawingPath( const ::rtl::OUString& rDrawingPath );
+ /** Sets the path to the legacy VML drawing fragment of this sheet. */
+ void setVmlDrawingPath( const ::rtl::OUString& rVmlDrawingPath );
+
+ /** Extends the used area of this sheet by the passed cell position. */
+ void extendUsedArea( const ::com::sun::star::table::CellAddress& rAddress );
+ /** Extends the used area of this sheet by the passed cell range. */
+ void extendUsedArea( const ::com::sun::star::table::CellRangeAddress& rRange );
+ /** Extends the shape bounding box by the position and size of the passed rectangle (in 1/100 mm). */
+ void extendShapeBoundingBox( const ::com::sun::star::awt::Rectangle& rShapeRect );
+
+ /** Sets base width for all columns (without padding pixels). This value
+ is only used, if 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 );
+ /** Converts default cell formatting for a range of columns. */
+ void setDefaultColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId );
+ /** Sets column settings for a specific range of columns.
+ @descr Column default formatting is converted directly, other settings
+ are cached and converted in the finalizeWorksheetImport() call. */
+ void setColumnModel( const ColumnModel& rModel );
+
+ /** 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 range of rows.
+ @descr Row default formatting is converted directly, other settings
+ are cached and converted in the finalizeWorksheetImport() call. */
+ void setRowModel( const RowModel& rModel );
+
+ /** Initial conversion before importing the worksheet. */
+ void initializeWorksheetImport();
+ /** Final conversion after importing the worksheet. */
+ void finalizeWorksheetImport();
+
+private:
+ WorksheetData& mrSheetData;
+};
+
+// ============================================================================
+
+namespace prv {
+
+typedef ::boost::shared_ptr< WorksheetData > WorksheetDataRef;
+
+struct WorksheetDataOwner
+{
+ explicit WorksheetDataOwner( WorksheetDataRef xSheetData );
+ virtual ~WorksheetDataOwner();
+ WorksheetDataRef mxSheetData;
+};
+
+} // namespace prv
+
+// ----------------------------------------------------------------------------
+
+class WorksheetHelperRoot : private prv::WorksheetDataOwner, public WorksheetHelper
+{
+public:
+ /** Returns true, if this helper refers to an existing Calc sheet. */
+ bool isValidSheet() const;
+
+protected:
+ /** Constructs from the passed data, creates and owns a new data object. */
+ explicit WorksheetHelperRoot(
+ const WorkbookHelper& rHelper,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+
+ /** Constructs from another sheet helper, does not create a data object. */
+ explicit WorksheetHelperRoot(
+ const WorksheetHelper& rHelper );
+
+ /** Constructs from another sheet helper, shares ownership of the passed helper. */
+ explicit WorksheetHelperRoot(
+ const WorksheetHelperRoot& rHelper );
+
+private:
+ WorksheetHelperRoot& operator=( const WorksheetHelperRoot& );
+};
+
+// ============================================================================
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/inc/oox/xls/worksheetsettings.hxx b/oox/inc/oox/xls/worksheetsettings.hxx
new file mode 100644
index 000000000000..6d6c8a4912d2
--- /dev/null
+++ b/oox/inc/oox/xls/worksheetsettings.hxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_XLS_WORKSHEETSETTINGS_HXX
+#define OOX_XLS_WORKSHEETSETTINGS_HXX
+
+#include "oox/xls/richstring.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Sheet and outline settings. */
+struct SheetSettingsModel
+{
+ ::rtl::OUString maCodeName; /// VBA module codename.
+ Color maTabColor; /// Sheet tab color.
+ bool mbFilterMode; /// True = sheet contains active filter.
+ bool mbApplyStyles; /// True = automatic styles when creating outlines.
+ bool mbSummaryBelow; /// True = row outline symbols below group.
+ bool mbSummaryRight; /// True = column outline symbols right of group.
+
+ explicit SheetSettingsModel();
+};
+
+// ============================================================================
+
+/** Sheet protection settings. */
+struct SheetProtectionModel
+{
+ sal_uInt16 mnPasswordHash; /// Hash value from sheet protection password.
+ bool mbSheet; /// True = sheet protection enabled, locked cells are protcted.
+ bool mbObjects; /// True = objects locked.
+ bool mbScenarios; /// True = scenarios locked.
+ bool mbFormatCells; /// True = format cells locked.
+ bool mbFormatColumns; /// True = format columns locked.
+ bool mbFormatRows; /// True = format rows locked.
+ bool mbInsertColumns; /// True = insert columns locked.
+ bool mbInsertRows; /// True = insert rows locked.
+ bool mbInsertHyperlinks; /// True = insert hyperlinks locked.
+ bool mbDeleteColumns; /// True = delete columns locked.
+ bool mbDeleteRows; /// True = delete rows locked.
+ bool mbSelectLocked; /// True = select locked cells locked.
+ bool mbSort; /// True = sorting locked.
+ bool mbAutoFilter; /// True = autofilters locked.
+ bool mbPivotTables; /// True = pivot tables locked.
+ bool mbSelectUnlocked; /// True = select unlocked cells locked.
+
+ explicit SheetProtectionModel();
+};
+
+// ============================================================================
+
+class WorksheetSettings : public WorksheetHelper
+{
+public:
+ explicit WorksheetSettings( const WorksheetHelper& rHelper );
+
+ /** Imports sheet settings from the sheetPr element. */
+ void importSheetPr( const AttributeList& rAttribs );
+ /** Imports chart sheet settings from the sheetPr element. */
+ void importChartSheetPr( const AttributeList& rAttribs );
+ /** Imports the sheet tab color from the tabColor element. */
+ void importTabColor( const AttributeList& rAttribs );
+ /** Imports outline settings from the outlinePr element. */
+ void importOutlinePr( const AttributeList& rAttribs );
+ /** Imports protection settings from the sheetProtection element. */
+ void importSheetProtection( const AttributeList& rAttribs );
+ /** Imports protection settings from the sheetProtection element of a chart sheet. */
+ void importChartProtection( const AttributeList& rAttribs );
+ /** Imports phonetic settings from the phoneticPr element. */
+ void importPhoneticPr( const AttributeList& rAttribs );
+
+ /** Imports sheet properties from the SHEETPR record. */
+ void importSheetPr( SequenceInputStream& rStrm );
+ /** Imports sheet properties from the CHARTSHEETPR record. */
+ void importChartSheetPr( SequenceInputStream& rStrm );
+ /** Imports sheet protection settings from the SHEETPROTECTION record. */
+ void importSheetProtection( SequenceInputStream& rStrm );
+ /** Imports chart sheet protection settings from the CHARTPROTECTION record. */
+ void importChartProtection( SequenceInputStream& rStrm );
+ /** Imports phonetic settings from the PHONETICPR record. */
+ void importPhoneticPr( SequenceInputStream& rStrm );
+
+ /** Imports sheet properties from a SHEETEXT record. */
+ void importSheetExt( BiffInputStream& rStrm );
+ /** Imports sheet properties from a SHEETPR record. */
+ void importSheetPr( BiffInputStream& rStrm );
+ /** Imports protection status from the PROTECT record. */
+ void importProtect( BiffInputStream& rStrm );
+ /** Imports object protection status from the OBJECTPROTECT record. */
+ void importObjectProtect( BiffInputStream& rStrm );
+ /** Imports scenario protection status from the SCENPROTECT record. */
+ void importScenProtect( BiffInputStream& rStrm );
+ /** Imports sheet password hash from the PASSWORD record. */
+ void importPassword( BiffInputStream& rStrm );
+ /** Imports protection settings from the SHEETPROTECTION record. */
+ void importSheetProtection( BiffInputStream& rStrm );
+ /** Imports the VBA code module name from the CODENAME record. */
+ void importCodeName( BiffInputStream& rStrm );
+ /** Imports phonetic settings from the PHONETICPR record. */
+ void importPhoneticPr( BiffInputStream& rStrm );
+
+ /** Converts the imported worksheet settings. */
+ void finalizeImport();
+
+private:
+ PhoneticSettings maPhoneticSett;
+ SheetSettingsModel maSheetSettings;
+ SheetProtectionModel maSheetProt;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/prj/build.lst b/oox/prj/build.lst
new file mode 100644
index 000000000000..03735c73dd11
--- /dev/null
+++ b/oox/prj/build.lst
@@ -0,0 +1,18 @@
+oox oox : vos cppu cppuhelper comphelper sal offapi sax basegfx xmlscript tools vcl BOOST:boost OPENSSL:openssl LIBXSLT:libxslt NULL
+oox oox usr1 - all oox_mkout NULL
+oox oox\prj get - all oox_prj NULL
+oox oox\source\token nmake - all oox_token NULL
+oox oox\source\helper nmake - all oox_helper oox_token NULL
+oox oox\source\core nmake - all oox_core oox_token NULL
+oox oox\source\ole nmake - all oox_ole oox_token NULL
+oox oox\source\docprop nmake - all oox_docprop oox_token NULL
+oox oox\source\drawingml nmake - all oox_drawingml oox_token NULL
+oox oox\source\drawingml\diagram nmake - all oox_diagram oox_token NULL
+oox oox\source\drawingml\chart nmake - all oox_chart oox_token NULL
+oox oox\source\drawingml\table nmake - all oox_table oox_token NULL
+oox oox\source\ppt nmake - all oox_ppt oox_token NULL
+oox oox\source\vml nmake - all oox_vml oox_token NULL
+oox oox\source\xls nmake - all oox_xls oox_token NULL
+oox oox\source\dump nmake - all oox_dump oox_token NULL
+oox oox\source\shape nmake - all oox_shape oox_token NULL
+oox oox\util nmake - all oox_util oox_token oox_helper oox_core oox_ole oox_vml oox_drawingml oox_diagram oox_chart oox_table oox_ppt oox_xls oox_dump oox_shape oox_docprop NULL
diff --git a/oox/prj/d.lst b/oox/prj/d.lst
new file mode 100644
index 000000000000..69ff66b95bc5
--- /dev/null
+++ b/oox/prj/d.lst
@@ -0,0 +1,46 @@
+mkdir: %_DEST%\inc%_EXT%\oox
+mkdir: %_DEST%\inc%_EXT%\oox\core
+mkdir: %_DEST%\inc%_EXT%\oox\drawingml
+mkdir: %_DEST%\inc%_EXT%\oox\drawingml\chart
+mkdir: %_DEST%\inc%_EXT%\oox\drawingml\table
+mkdir: %_DEST%\inc%_EXT%\oox\helper
+mkdir: %_DEST%\inc%_EXT%\oox\ole
+mkdir: %_DEST%\inc%_EXT%\oox\token
+mkdir: %_DEST%\inc%_EXT%\oox\vml
+mkdir: %_DEST%\inc%_EXT%\oox\xls
+
+..\%__SRC%\misc\*.map %_DEST%\bin%_EXT%\*.map
+..\%__SRC%\lib\ixo.lib %_DEST%\lib%_EXT%\ixo.lib
+..\%__SRC%\lib\xol.lib %_DEST%\lib%_EXT%\xol.lib
+..\%__SRC%\lib\libxol.a %_DEST%\lib%_EXT%\libxol.a
+..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*.dll
+..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%\lib*.so
+..\%__SRC%\lib\i*.lib %_DEST%\lib%_EXT%\i*.lib
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+
+..\%__SRC%\inc\oox\token\tokens.hxx %_DEST%\inc%_EXT%\oox\token\tokens.hxx
+..\%__SRC%\misc\namespaces.txt %_DEST%\inc%_EXT%\oox\namespaces.txt
+
+..\source\token\tokens.txt %_DEST%\inc%_EXT%\oox\token.txt
+..\inc\oox\dllapi.h %_DEST%\inc%_EXT%\oox\dllapi.h
+..\inc\oox\helper\binarystreambase.hxx %_DEST%\inc%_EXT%\oox\helper\binarystreambase.hxx
+..\inc\oox\helper\helper.hxx %_DEST%\inc%_EXT%\oox\helper\helper.hxx
+..\inc\oox\helper\refmap.hxx %_DEST%\inc%_EXT%\oox\helper\refmap.hxx
+..\inc\oox\helper\refvector.hxx %_DEST%\inc%_EXT%\oox\helper\refvector.hxx
+..\inc\oox\helper\storagebase.hxx %_DEST%\inc%_EXT%\oox\helper\storagebase.hxx
+..\inc\oox\helper\zipstorage.hxx %_DEST%\inc%_EXT%\oox\helper\zipstorage.hxx
+..\inc\oox\core\filterbase.hxx %_DEST%\inc%_EXT%\oox\core\filterbase.hxx
+..\inc\oox\core\filterdetect.hxx %_DEST%\inc%_EXT%\oox\core\filterdetect.hxx
+..\inc\oox\core\relations.hxx %_DEST%\inc%_EXT%\oox\core\relations.hxx
+..\inc\oox\core\xmlfilterbase.hxx %_DEST%\inc%_EXT%\oox\core\xmlfilterbase.hxx
+..\inc\oox\drawingml\chart\chartconverter.hxx %_DEST%\inc%_EXT%\oox\drawingml\chart\chartconverter.hxx
+..\inc\oox\drawingml\table\tablestylelist.hxx %_DEST%\inc%_EXT%\oox\drawingml\table\tablestylelist.hxx
+..\inc\oox\ole\vbaproject.hxx %_DEST%\inc%_EXT%\oox\ole\vbaproject.hxx
+..\inc\oox\vml\vmldrawing.hxx %_DEST%\inc%_EXT%\oox\vml\vmldrawing.hxx
+..\inc\oox\vml\vmlshape.hxx %_DEST%\inc%_EXT%\oox\vml\vmlshape.hxx
+..\inc\oox\xls\excelvbaproject.hxx %_DEST%\inc%_EXT%\oox\xls\excelvbaproject.hxx
+
+dos: sh -c "if test %OS% = MACOSX; then create-bundle %_DEST%\lib%_EXT%\*.dylib; fi"
+
+..\xml\components.xml %_DEST%\xml%_EXT%\components.xml
+..\%__SRC%\misc\oox.component %_DEST%\xml%_EXT%\oox.component
diff --git a/oox/source/core/binarycodec.cxx b/oox/source/core/binarycodec.cxx
new file mode 100644
index 000000000000..3f406ba1af08
--- /dev/null
+++ b/oox/source/core/binarycodec.cxx
@@ -0,0 +1,427 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/binarycodec.hxx"
+
+#include <algorithm>
+#include <string.h>
+#include "oox/helper/attributelist.hxx"
+
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/docpasswordhelper.hxx>
+
+using namespace ::com::sun::star;
+
+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
+
+// ============================================================================
+
+/*static*/ sal_uInt16 CodecHelper::getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement )
+{
+ sal_Int32 nPasswordHash = rAttribs.getIntegerHex( nElement, 0 );
+ OSL_ENSURE( (0 <= nPasswordHash) && (nPasswordHash <= SAL_MAX_UINT16), "CodecHelper::getPasswordHash - invalid password hash" );
+ return static_cast< sal_uInt16 >( ((0 <= nPasswordHash) && (nPasswordHash <= SAL_MAX_UINT16)) ? nPasswordHash : 0 );
+}
+
+// ============================================================================
+
+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::initCodec( const uno::Sequence< beans::NamedValue >& aData )
+{
+ bool bResult = sal_False;
+
+ ::comphelper::SequenceAsHashMap aHashData( aData );
+ uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
+
+ if ( aKey.getLength() == 16 )
+ {
+ (void)memcpy( mpnKey, aKey.getConstArray(), 16 );
+ bResult = sal_True;
+
+ mnBaseKey = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ), (sal_Int16)0 );
+ mnHash = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ), (sal_Int16)0 );
+ }
+ else
+ OSL_ENSURE( sal_False, "Unexpected key size!\n" );
+
+ return bResult;
+}
+
+uno::Sequence< beans::NamedValue > BinaryCodec_XOR::getEncryptionData()
+{
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ) ] <<= uno::Sequence<sal_Int8>( (sal_Int8*)mpnKey, 16 );
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ) ] <<= (sal_Int16)mnBaseKey;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ) ] <<= (sal_Int16)mnHash;
+
+ return aHashData.getAsConstNamedValueList();
+}
+
+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;
+}
+
+// ============================================================================
+
+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 ) );
+ (void)memset (mpnUnique, 0, sizeof(mpnUnique));
+}
+
+BinaryCodec_RCF::~BinaryCodec_RCF()
+{
+ (void)memset( mpnDigestValue, 0, sizeof( mpnDigestValue ) );
+ (void)memset (mpnUnique, 0, sizeof(mpnUnique));
+ rtl_digest_destroy( mhDigest );
+ rtl_cipher_destroy( mhCipher );
+}
+
+bool BinaryCodec_RCF::initCodec( const uno::Sequence< beans::NamedValue >& aData )
+{
+ bool bResult = sal_False;
+
+ ::comphelper::SequenceAsHashMap aHashData( aData );
+ uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
+
+ if ( aKey.getLength() == RTL_DIGEST_LENGTH_MD5 )
+ {
+ (void)memcpy( mpnDigestValue, aKey.getConstArray(), RTL_DIGEST_LENGTH_MD5 );
+ uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ), uno::Sequence< sal_Int8 >() );
+ if ( aUniqueID.getLength() == 16 )
+ {
+ (void)memcpy( mpnUnique, aUniqueID.getConstArray(), 16 );
+ bResult = sal_False;
+ }
+ else
+ OSL_ENSURE( sal_False, "Unexpected document ID!\n" );
+ }
+ else
+ OSL_ENSURE( sal_False, "Unexpected key size!\n" );
+
+ return bResult;
+}
+
+uno::Sequence< beans::NamedValue > BinaryCodec_RCF::getEncryptionData()
+{
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)mpnDigestValue, RTL_DIGEST_LENGTH_MD5 );
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)mpnUnique, 16 );
+
+ return aHashData.getAsConstNamedValueList();
+}
+
+void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnSalt[ 16 ] )
+{
+ uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pnPassData, uno::Sequence< sal_Int8 >( (sal_Int8*)pnSalt, 16 ) );
+ // Fill raw digest of above updates into DigestValue.
+
+ if ( aKey.getLength() == sizeof(mpnDigestValue) )
+ (void)memcpy ( mpnDigestValue, (const sal_uInt8*)aKey.getConstArray(), sizeof(mpnDigestValue) );
+ else
+ memset( mpnDigestValue, 0, sizeof(mpnDigestValue) );
+
+ (void)memcpy( mpnUnique, pnSalt, 16 );
+}
+
+bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnVerifier[ 16 ], const sal_uInt8 pnVerifierHash[ 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, pnVerifier, 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, pnVerifierHash, 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..9bebedb9c96b
--- /dev/null
+++ b/oox/source/core/binaryfilterbase.cxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/binaryfilterbase.hxx"
+
+#include "oox/ole/olestorage.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+BinaryFilterBase::BinaryFilterBase( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ FilterBase( rxContext )
+{
+}
+
+BinaryFilterBase::~BinaryFilterBase()
+{
+}
+
+// private --------------------------------------------------------------------
+
+StorageRef BinaryFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
+{
+ return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxInStream, true ) );
+}
+
+StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
+{
+ return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxOutStream, true ) );
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/contexthandler.cxx b/oox/source/core/contexthandler.cxx
new file mode 100644
index 000000000000..8bf2c4eadfeb
--- /dev/null
+++ b/oox/source/core/contexthandler.cxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/contexthandler.hxx"
+
+#include "oox/core/fragmenthandler.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+ContextHandler::ContextHandler( ContextHandler& rParent ) :
+ ContextHandlerImplBase(),
+ mxBaseData( rParent.mxBaseData )
+{
+}
+
+ContextHandler::ContextHandler( const FragmentBaseDataRef& rxBaseData ) :
+ mxBaseData( rxBaseData )
+{
+}
+
+ContextHandler::~ContextHandler()
+{
+}
+
+XmlFilterBase& ContextHandler::getFilter() const
+{
+ return mxBaseData->mrFilter;
+}
+
+const Relations& ContextHandler::getRelations() const
+{
+ return *mxBaseData->mxRelations;
+}
+
+const OUString& ContextHandler::getFragmentPath() const
+{
+ return mxBaseData->maFragmentPath;
+}
+
+OUString ContextHandler::getFragmentPathFromRelation( const Relation& rRelation ) const
+{
+ return mxBaseData->mxRelations->getFragmentPathFromRelation( rRelation );
+}
+
+OUString ContextHandler::getFragmentPathFromRelId( const OUString& rRelId ) const
+{
+ return mxBaseData->mxRelations->getFragmentPathFromRelId( rRelId );
+}
+
+OUString ContextHandler::getFragmentPathFromFirstType( const OUString& rType ) const
+{
+ return mxBaseData->mxRelations->getFragmentPathFromFirstType( rType );
+}
+
+void ContextHandler::implSetLocator( const Reference< XLocator >& rxLocator )
+{
+ mxBaseData->mxLocator = rxLocator;
+}
+
+// com.sun.star.xml.sax.XFastContextHandler interface -------------------------
+
+void ContextHandler::startFastElement( sal_Int32, const Reference< XFastAttributeList >& ) throw( SAXException, RuntimeException )
+{
+}
+
+void ContextHandler::startUnknownElement( const OUString&, const OUString&, const Reference< XFastAttributeList >& ) throw( SAXException, RuntimeException )
+{
+}
+
+void ContextHandler::endFastElement( sal_Int32 ) throw( SAXException, RuntimeException )
+{
+}
+
+void ContextHandler::endUnknownElement( const OUString&, const OUString& ) throw( SAXException, RuntimeException )
+{
+}
+
+Reference< XFastContextHandler > ContextHandler::createFastChildContext( sal_Int32, const Reference< XFastAttributeList >& ) throw( SAXException, RuntimeException )
+{
+ return 0;
+}
+
+Reference< XFastContextHandler > ContextHandler::createUnknownChildContext( const OUString&, const OUString&, const Reference< XFastAttributeList >& ) throw( SAXException, RuntimeException )
+{
+ return 0;
+}
+
+void ContextHandler::characters( const OUString& ) throw( SAXException, RuntimeException )
+{
+}
+
+void ContextHandler::ignorableWhitespace( const OUString& ) throw( SAXException, RuntimeException )
+{
+}
+
+void ContextHandler::processingInstruction( const OUString&, const OUString& ) throw( SAXException, RuntimeException )
+{
+}
+
+// record context interface ---------------------------------------------------
+
+ContextHandlerRef ContextHandler::createRecordContext( sal_Int32, SequenceInputStream& )
+{
+ return 0;
+}
+
+void ContextHandler::startRecord( sal_Int32, SequenceInputStream& )
+{
+}
+
+void ContextHandler::endRecord( sal_Int32 )
+{
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/contexthandler2.cxx b/oox/source/core/contexthandler2.cxx
new file mode 100644
index 000000000000..48f5718f9149
--- /dev/null
+++ b/oox/source/core/contexthandler2.cxx
@@ -0,0 +1,268 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/contexthandler2.hxx"
+#include <rtl/ustrbuf.hxx>
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+/** Information about a processed element. */
+struct ElementInfo
+{
+ OUStringBuffer maChars; /// Collected element characters.
+ sal_Int32 mnElement; /// The element identifier.
+ bool mbTrimSpaces; /// True = trims leading/trailing spaces from text data.
+
+ inline explicit ElementInfo() : mnElement( XML_TOKEN_INVALID ), mbTrimSpaces( false ) {}
+};
+
+// ============================================================================
+
+ContextHandler2Helper::ContextHandler2Helper( bool bEnableTrimSpace ) :
+ mxContextStack( new ContextStack ),
+ mnRootStackSize( 0 ),
+ mbEnableTrimSpace( bEnableTrimSpace )
+{
+ pushElementInfo( XML_ROOT_CONTEXT );
+}
+
+ContextHandler2Helper::ContextHandler2Helper( const ContextHandler2Helper& rParent ) :
+ mxContextStack( rParent.mxContextStack ),
+ mnRootStackSize( rParent.mxContextStack->size() ),
+ mbEnableTrimSpace( rParent.mbEnableTrimSpace )
+{
+}
+
+ContextHandler2Helper::~ContextHandler2Helper()
+{
+}
+
+sal_Int32 ContextHandler2Helper::getCurrentElement() const
+{
+ return mxContextStack->empty() ? XML_ROOT_CONTEXT : mxContextStack->back().mnElement;
+}
+
+sal_Int32 ContextHandler2Helper::getParentElement( sal_Int32 nCountBack ) const
+{
+ if( (nCountBack < 0) || (mxContextStack->size() < static_cast< size_t >( nCountBack )) )
+ return XML_TOKEN_INVALID;
+ return (mxContextStack->size() == static_cast< size_t >( nCountBack )) ?
+ XML_ROOT_CONTEXT : (*mxContextStack)[ mxContextStack->size() - nCountBack - 1 ].mnElement;
+}
+
+bool ContextHandler2Helper::isRootElement() const
+{
+ return mxContextStack->size() == mnRootStackSize + 1;
+}
+
+Reference< XFastContextHandler > ContextHandler2Helper::implCreateChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
+{
+ // #i76091# process collected characters (calls onCharacters() if needed)
+ processCollectedChars();
+ ContextHandlerRef xContext = onCreateContext( nElement, AttributeList( rxAttribs ) );
+ return Reference< XFastContextHandler >( xContext.get() );
+}
+
+void ContextHandler2Helper::implStartElement( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
+{
+ AttributeList aAttribs( rxAttribs );
+ pushElementInfo( nElement ).mbTrimSpaces = aAttribs.getToken( XML_TOKEN( space ), XML_TOKEN_INVALID ) != XML_preserve;
+ onStartElement( aAttribs );
+}
+
+void ContextHandler2Helper::implCharacters( const OUString& rChars )
+{
+ // #i76091# collect characters until new element starts or this element ends
+ if( !mxContextStack->empty() )
+ mxContextStack->back().maChars.append( rChars );
+}
+
+void ContextHandler2Helper::implEndElement( sal_Int32 nElement )
+{
+ (void)nElement; // prevent "unused parameter" warning in product build
+ OSL_ENSURE( getCurrentElement() == nElement, "ContextHandler2Helper::implEndElement - context stack broken" );
+ if( !mxContextStack->empty() )
+ {
+ // #i76091# process collected characters (calls onCharacters() if needed)
+ processCollectedChars();
+ onEndElement();
+ popElementInfo();
+ }
+}
+
+ContextHandlerRef ContextHandler2Helper::implCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ return onCreateRecordContext( nRecId, rStrm );
+}
+
+void ContextHandler2Helper::implStartRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ pushElementInfo( nRecId );
+ onStartRecord( rStrm );
+}
+
+void ContextHandler2Helper::implEndRecord( sal_Int32 nRecId )
+{
+ (void)nRecId; // prevent "unused parameter" warning in product build
+ OSL_ENSURE( getCurrentElement() == nRecId, "ContextHandler2Helper::implEndRecord - context stack broken" );
+ if( !mxContextStack->empty() )
+ {
+ onEndRecord();
+ popElementInfo();
+ }
+}
+
+ElementInfo& ContextHandler2Helper::pushElementInfo( sal_Int32 nElement )
+{
+ mxContextStack->resize( mxContextStack->size() + 1 );
+ ElementInfo& rInfo = mxContextStack->back();
+ rInfo.mnElement = nElement;
+ return rInfo;
+}
+
+void ContextHandler2Helper::popElementInfo()
+{
+ OSL_ENSURE( !mxContextStack->empty(), "ContextHandler2Helper::popElementInfo - context stack broken" );
+ if( !mxContextStack->empty() )
+ mxContextStack->pop_back();
+}
+
+void ContextHandler2Helper::processCollectedChars()
+{
+ OSL_ENSURE( !mxContextStack->empty(), "ContextHandler2Helper::processCollectedChars - no context info" );
+ ElementInfo& rInfo = mxContextStack->back();
+ if( rInfo.maChars.getLength() > 0 )
+ {
+ OUString aChars = rInfo.maChars.makeStringAndClear();
+ if( mbEnableTrimSpace && rInfo.mbTrimSpaces )
+ aChars = aChars.trim();
+ if( aChars.getLength() > 0 )
+ onCharacters( aChars );
+ }
+}
+
+// ============================================================================
+
+ContextHandler2::ContextHandler2( ContextHandler2Helper& rParent ) :
+ ContextHandler( dynamic_cast< ContextHandler& >( rParent ) ),
+ ContextHandler2Helper( rParent )
+{
+}
+
+ContextHandler2::~ContextHandler2()
+{
+}
+
+// com.sun.star.xml.sax.XFastContextHandler interface -------------------------
+
+Reference< XFastContextHandler > SAL_CALL ContextHandler2::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException )
+{
+ return implCreateChildContext( nElement, rxAttribs );
+}
+
+void SAL_CALL ContextHandler2::startFastElement(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException )
+{
+ implStartElement( nElement, rxAttribs );
+}
+
+void SAL_CALL ContextHandler2::characters( const OUString& rChars ) throw( SAXException, RuntimeException )
+{
+ implCharacters( rChars );
+}
+
+void SAL_CALL ContextHandler2::endFastElement( sal_Int32 nElement ) throw( SAXException, RuntimeException )
+{
+ implEndElement( nElement );
+}
+
+// oox.core.RecordContext interface -------------------------------------------
+
+ContextHandlerRef ContextHandler2::createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ return implCreateRecordContext( nRecId, rStrm );
+}
+
+void ContextHandler2::startRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ implStartRecord( nRecId, rStrm );
+}
+
+void ContextHandler2::endRecord( sal_Int32 nRecId )
+{
+ implEndRecord( nRecId );
+}
+
+// oox.core.ContextHandler2Helper interface -----------------------------------
+
+ContextHandlerRef ContextHandler2::onCreateContext( sal_Int32, const AttributeList& )
+{
+ return 0;
+}
+
+void ContextHandler2::onStartElement( const AttributeList& )
+{
+}
+
+void ContextHandler2::onCharacters( const OUString& )
+{
+}
+
+void ContextHandler2::onEndElement()
+{
+}
+
+ContextHandlerRef ContextHandler2::onCreateRecordContext( sal_Int32, SequenceInputStream& )
+{
+ return 0;
+}
+
+void ContextHandler2::onStartRecord( SequenceInputStream& )
+{
+}
+
+void ContextHandler2::onEndRecord()
+{
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/fastparser.cxx b/oox/source/core/fastparser.cxx
new file mode 100755
index 000000000000..eaf8c428b92c
--- /dev/null
+++ b/oox/source/core/fastparser.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/fastparser.hxx"
+
+#include "oox/core/fasttokenhandler.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/helper.hxx"
+#include "oox/helper/storagebase.hxx"
+#include "oox/token/namespacemap.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+class InputStreamCloseGuard
+{
+public:
+ explicit InputStreamCloseGuard( const Reference< XInputStream >& rxInStream, bool bCloseStream );
+ ~InputStreamCloseGuard();
+private:
+ Reference< XInputStream > mxInStream;
+ bool mbCloseStream;
+};
+
+InputStreamCloseGuard::InputStreamCloseGuard( const Reference< XInputStream >& rxInStream, bool bCloseStream ) :
+ mxInStream( rxInStream ),
+ mbCloseStream( bCloseStream )
+{
+}
+
+InputStreamCloseGuard::~InputStreamCloseGuard()
+{
+ if( mxInStream.is() && mbCloseStream ) try { mxInStream->closeInput(); } catch( Exception& ) {}
+}
+
+} // namespace
+
+// ============================================================================
+
+FastParser::FastParser( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ mrNamespaceMap( StaticNamespaceMap::get() )
+{
+ // create a fast parser instance
+ Reference< XMultiComponentFactory > xFactory( rxContext->getServiceManager(), UNO_SET_THROW );
+ mxParser.set( xFactory->createInstanceWithContext( CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ), rxContext ), UNO_QUERY_THROW );
+
+ // create the fast token handler based on the OOXML token list
+ mxParser->setTokenHandler( new FastTokenHandler );
+}
+
+FastParser::~FastParser()
+{
+}
+
+void FastParser::registerNamespace( sal_Int32 nNamespaceId ) throw( IllegalArgumentException, RuntimeException )
+{
+ if( !mxParser.is() )
+ throw RuntimeException();
+
+ const OUString* pNamespaceUrl = ContainerHelper::getMapElement( mrNamespaceMap, nNamespaceId );
+ if( !pNamespaceUrl )
+ throw IllegalArgumentException();
+
+ mxParser->registerNamespace( *pNamespaceUrl, nNamespaceId );
+}
+
+void FastParser::setDocumentHandler( const Reference< XFastDocumentHandler >& rxDocHandler ) throw( RuntimeException )
+{
+ if( !mxParser.is() )
+ throw RuntimeException();
+ mxParser->setFastDocumentHandler( rxDocHandler );
+}
+
+void FastParser::parseStream( const InputSource& rInputSource, bool bCloseStream ) throw( SAXException, IOException, RuntimeException )
+{
+ // guard closing the input stream also when exceptions are thrown
+ InputStreamCloseGuard aGuard( rInputSource.aInputStream, bCloseStream );
+ if( !mxParser.is() )
+ throw RuntimeException();
+ mxParser->parseStream( rInputSource );
+}
+
+void FastParser::parseStream( const Reference< XInputStream >& rxInStream, const OUString& rStreamName, bool bCloseStream ) throw( SAXException, IOException, RuntimeException )
+{
+ InputSource aInputSource;
+ aInputSource.sSystemId = rStreamName;
+ aInputSource.aInputStream = rxInStream;
+ parseStream( aInputSource, bCloseStream );
+}
+
+void FastParser::parseStream( StorageBase& rStorage, const OUString& rStreamName, bool bCloseStream ) throw( SAXException, IOException, RuntimeException )
+{
+ parseStream( rStorage.openInputStream( rStreamName ), rStreamName, bCloseStream );
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/fasttokenhandler.cxx b/oox/source/core/fasttokenhandler.cxx
new file mode 100644
index 000000000000..e09687cc5470
--- /dev/null
+++ b/oox/source/core/fasttokenhandler.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/fasttokenhandler.hxx"
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include "oox/helper/helper.hxx"
+#include "oox/token/tokenmap.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+OUString SAL_CALL FastTokenHandler_getImplementationName()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.core.FastTokenHandler" );
+}
+
+Sequence< OUString > SAL_CALL FastTokenHandler_getSupportedServiceNames()
+{
+ Sequence< OUString > aServiceNames( 1 );
+ aServiceNames[ 0 ] = CREATE_OUSTRING( "com.sun.star.xml.sax.FastTokenHandler" );
+ return aServiceNames;
+}
+
+Reference< XInterface > SAL_CALL FastTokenHandler_createInstance( const Reference< XComponentContext >& /*rxContext*/ ) throw (Exception)
+{
+ return static_cast< ::cppu::OWeakObject* >( new FastTokenHandler );
+}
+
+// ============================================================================
+
+FastTokenHandler::FastTokenHandler() :
+ mrTokenMap( StaticTokenMap::get() )
+{
+}
+
+FastTokenHandler::~FastTokenHandler()
+{
+}
+
+// XServiceInfo
+
+OUString SAL_CALL FastTokenHandler::getImplementationName() throw (RuntimeException)
+{
+ return FastTokenHandler_getImplementationName();
+}
+
+sal_Bool SAL_CALL FastTokenHandler::supportsService( const OUString& rServiceName ) throw (RuntimeException)
+{
+ Sequence< OUString > aServiceNames = FastTokenHandler_getSupportedServiceNames();
+ for( sal_Int32 nIndex = 0, nLength = aServiceNames.getLength(); nIndex < nLength; ++nIndex )
+ if( aServiceNames[ nIndex ] == rServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+Sequence< OUString > SAL_CALL FastTokenHandler::getSupportedServiceNames() throw (RuntimeException)
+{
+ return FastTokenHandler_getSupportedServiceNames();
+}
+
+// XFastTokenHandler
+
+sal_Int32 FastTokenHandler::getToken( const OUString& rIdentifier ) throw( RuntimeException )
+{
+ return mrTokenMap.getTokenFromUnicode( rIdentifier );
+}
+
+OUString FastTokenHandler::getIdentifier( sal_Int32 nToken ) throw( RuntimeException )
+{
+ return mrTokenMap.getUnicodeTokenName( nToken );
+}
+
+Sequence< sal_Int8 > FastTokenHandler::getUTF8Identifier( sal_Int32 nToken ) throw( RuntimeException )
+{
+ return mrTokenMap.getUtf8TokenName( nToken );
+}
+
+sal_Int32 FastTokenHandler::getTokenFromUTF8( const Sequence< sal_Int8 >& rIdentifier ) throw( RuntimeException )
+{
+ return mrTokenMap.getTokenFromUtf8( rIdentifier );
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx
new file mode 100644
index 000000000000..b215150acb88
--- /dev/null
+++ b/oox/source/core/filterbase.cxx
@@ -0,0 +1,583 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/filterbase.hxx"
+
+#include <set>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <comphelper/docpasswordhelper.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/instance.hxx>
+#include <rtl/uri.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/modelobjecthelper.hxx"
+#include "oox/ole/oleobjecthelper.hxx"
+#include "oox/ole/vbaproject.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::uno;
+
+using ::comphelper::MediaDescriptor;
+using ::comphelper::SequenceAsHashMap;
+using ::oox::ole::OleObjectHelper;
+using ::oox::ole::VbaProject;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+struct UrlPool
+{
+ ::osl::Mutex maMutex;
+ ::std::set< OUString > maUrls;
+};
+
+struct StaticUrlPool : public ::rtl::Static< UrlPool, StaticUrlPool > {};
+
+// ----------------------------------------------------------------------------
+
+/** This guard prevents recursive loading/saving of the same document. */
+class DocumentOpenedGuard
+{
+public:
+ explicit DocumentOpenedGuard( const OUString& rUrl );
+ ~DocumentOpenedGuard();
+
+ inline bool isValid() const { return mbValid; }
+
+private:
+ DocumentOpenedGuard( const DocumentOpenedGuard& );
+ DocumentOpenedGuard& operator=( const DocumentOpenedGuard& );
+
+ OUString maUrl;
+ bool mbValid;
+};
+
+DocumentOpenedGuard::DocumentOpenedGuard( const OUString& rUrl )
+{
+ UrlPool& rUrlPool = StaticUrlPool::get();
+ ::osl::MutexGuard aGuard( rUrlPool.maMutex );
+ mbValid = (rUrl.getLength() == 0) || (rUrlPool.maUrls.count( rUrl ) == 0);
+ if( mbValid && (rUrl.getLength() > 0) )
+ {
+ rUrlPool.maUrls.insert( rUrl );
+ maUrl = rUrl;
+ }
+}
+
+DocumentOpenedGuard::~DocumentOpenedGuard()
+{
+ UrlPool& rUrlPool = StaticUrlPool::get();
+ ::osl::MutexGuard aGuard( rUrlPool.maMutex );
+ if( maUrl.getLength() > 0 )
+ rUrlPool.maUrls.erase( maUrl );
+}
+
+} // namespace
+
+// ============================================================================
+
+/** Specifies whether this filter is an import or export filter. */
+enum FilterDirection
+{
+ FILTERDIRECTION_UNKNOWN,
+ FILTERDIRECTION_IMPORT,
+ FILTERDIRECTION_EXPORT
+};
+
+// ----------------------------------------------------------------------------
+
+struct FilterBaseImpl
+{
+ typedef ::boost::shared_ptr< GraphicHelper > GraphicHelperRef;
+ typedef ::boost::shared_ptr< ModelObjectHelper > ModelObjHelperRef;
+ typedef ::boost::shared_ptr< OleObjectHelper > OleObjHelperRef;
+ typedef ::boost::shared_ptr< VbaProject > VbaProjectRef;
+
+ FilterDirection meDirection;
+ SequenceAsHashMap maArguments;
+ MediaDescriptor maMediaDesc;
+ OUString maFileUrl;
+ StorageRef mxStorage;
+
+ GraphicHelperRef mxGraphicHelper; /// Graphic and graphic object handling.
+ ModelObjHelperRef mxModelObjHelper; /// Tables to create new named drawing objects.
+ OleObjHelperRef mxOleObjHelper; /// OLE object handling.
+ VbaProjectRef mxVbaProject; /// VBA project manager.
+
+ Reference< XComponentContext > mxComponentContext;
+ Reference< XMultiComponentFactory > mxComponentFactory;
+ Reference< XMultiServiceFactory > mxServiceFactory;
+ Reference< XModel > mxModel;
+ Reference< XMultiServiceFactory > mxModelFactory;
+ Reference< XFrame > mxTargetFrame;
+ Reference< XInputStream > mxInStream;
+ Reference< XStream > mxOutStream;
+ Reference< XStatusIndicator > mxStatusIndicator;
+ Reference< XInteractionHandler > mxInteractionHandler;
+
+ explicit FilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
+
+ void setDocumentModel( const Reference< XComponent >& rxComponent ) throw( IllegalArgumentException );
+
+ void initializeFilter();
+ void finalizeFilter();
+};
+
+// ----------------------------------------------------------------------------
+
+FilterBaseImpl::FilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ meDirection( FILTERDIRECTION_UNKNOWN ),
+ mxComponentContext( rxContext, UNO_SET_THROW ),
+ mxComponentFactory( rxContext->getServiceManager(), UNO_SET_THROW ),
+ mxServiceFactory( rxContext->getServiceManager(), UNO_QUERY_THROW )
+{
+}
+
+void FilterBaseImpl::setDocumentModel( const Reference< XComponent >& rxComponent ) throw( IllegalArgumentException )
+{
+ try
+ {
+ mxModel.set( rxComponent, UNO_QUERY_THROW );
+ mxModelFactory.set( rxComponent, UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ throw IllegalArgumentException();
+ }
+}
+
+void FilterBaseImpl::initializeFilter()
+{
+ try
+ {
+ // lock the model controllers
+ mxModel->lockControllers();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void FilterBaseImpl::finalizeFilter()
+{
+ try
+ {
+ // write the descriptor back to the document model (adds the passwords)
+ mxModel->attachResource( maFileUrl, maMediaDesc.getAsConstPropertyValueList() );
+ // unlock the model controllers
+ mxModel->unlockControllers();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+FilterBase::FilterBase( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ mxImpl( new FilterBaseImpl( rxContext ) )
+{
+}
+
+FilterBase::~FilterBase()
+{
+}
+
+bool FilterBase::isImportFilter() const
+{
+ return mxImpl->meDirection == FILTERDIRECTION_IMPORT;
+}
+
+bool FilterBase::isExportFilter() const
+{
+ return mxImpl->meDirection == FILTERDIRECTION_EXPORT;
+}
+
+// ----------------------------------------------------------------------------
+
+Any FilterBase::getArgument( const OUString& rArgName ) const
+{
+ SequenceAsHashMap::const_iterator aIt = mxImpl->maArguments.find( rArgName );
+ return (aIt == mxImpl->maArguments.end()) ? Any() : aIt->second;
+}
+
+const Reference< XComponentContext >& FilterBase::getComponentContext() const
+{
+ return mxImpl->mxComponentContext;
+}
+
+const Reference< XMultiComponentFactory >& FilterBase::getComponentFactory() const
+{
+ return mxImpl->mxComponentFactory;
+}
+
+const Reference< XMultiServiceFactory >& FilterBase::getServiceFactory() const
+{
+ return mxImpl->mxServiceFactory;
+}
+
+const Reference< XModel >& FilterBase::getModel() const
+{
+ return mxImpl->mxModel;
+}
+
+const Reference< XMultiServiceFactory >& FilterBase::getModelFactory() const
+{
+ return mxImpl->mxModelFactory;
+}
+
+const Reference< XFrame >& FilterBase::getTargetFrame() const
+{
+ return mxImpl->mxTargetFrame;
+}
+
+const Reference< XStatusIndicator >& FilterBase::getStatusIndicator() const
+{
+ return mxImpl->mxStatusIndicator;
+}
+
+const Reference< XInteractionHandler >& FilterBase::getInteractionHandler() const
+{
+ return mxImpl->mxInteractionHandler;
+}
+
+MediaDescriptor& FilterBase::getMediaDescriptor() const
+{
+ return mxImpl->maMediaDesc;
+}
+
+const OUString& FilterBase::getFileUrl() const
+{
+ return mxImpl->maFileUrl;
+}
+
+namespace {
+
+inline bool lclIsDosDrive( const OUString& rUrl, sal_Int32 nPos = 0 )
+{
+ return
+ (rUrl.getLength() >= nPos + 3) &&
+ ((('A' <= rUrl[ nPos ]) && (rUrl[ nPos ] <= 'Z')) || (('a' <= rUrl[ nPos ]) && (rUrl[ nPos ] <= 'z'))) &&
+ (rUrl[ nPos + 1 ] == ':') &&
+ (rUrl[ nPos + 2 ] == '/');
+}
+
+} // namespace
+
+OUString FilterBase::getAbsoluteUrl( const OUString& rUrl ) const
+{
+ // handle some special cases before calling ::rtl::Uri::convertRelToAbs()
+
+ const OUString aFileSchema = CREATE_OUSTRING( "file:" );
+ const OUString aFilePrefix = CREATE_OUSTRING( "file:///" );
+ const sal_Int32 nFilePrefixLen = aFilePrefix.getLength();
+ const OUString aUncPrefix = CREATE_OUSTRING( "//" );
+
+ /* (1) convert all backslashes to slashes, and check that passed URL is
+ not empty. */
+ OUString aUrl = rUrl.replace( '\\', '/' );
+ if( aUrl.getLength() == 0 )
+ return aUrl;
+
+ /* (2) add 'file:///' to absolute Windows paths, e.g. convert
+ 'C:/path/file' to 'file:///c:/path/file'. */
+ if( lclIsDosDrive( aUrl ) )
+ return aFilePrefix + aUrl;
+
+ /* (3) add 'file:' to UNC paths, e.g. convert '//server/path/file' to
+ 'file://server/path/file'. */
+ if( aUrl.match( aUncPrefix ) )
+ return aFileSchema + aUrl;
+
+ /* (4) remove additional slashes from UNC paths, e.g. convert
+ 'file://///server/path/file' to 'file://server/path/file'. */
+ if( (aUrl.getLength() >= nFilePrefixLen + 2) &&
+ aUrl.match( aFilePrefix ) &&
+ aUrl.match( aUncPrefix, nFilePrefixLen ) )
+ {
+ return aFileSchema + aUrl.copy( nFilePrefixLen );
+ }
+
+ /* (5) handle URLs relative to current drive, e.g. the URL '/path1/file1'
+ relative to the base URL 'file:///C:/path2/file2' does not result in
+ the expected 'file:///C:/path1/file1', but in 'file:///path1/file1'. */
+ if( (aUrl.getLength() >= 1) && (aUrl[ 0 ] == '/') &&
+ mxImpl->maFileUrl.match( aFilePrefix ) &&
+ lclIsDosDrive( mxImpl->maFileUrl, nFilePrefixLen ) )
+ {
+ return mxImpl->maFileUrl.copy( 0, nFilePrefixLen + 3 ) + aUrl.copy( 1 );
+ }
+
+ try
+ {
+ return ::rtl::Uri::convertRelToAbs( mxImpl->maFileUrl, aUrl );
+ }
+ catch( ::rtl::MalformedUriException& )
+ {
+ }
+ return aUrl;
+}
+
+StorageRef FilterBase::getStorage() const
+{
+ return mxImpl->mxStorage;
+}
+
+StorageRef FilterBase::openSubStorage( const OUString& rStorageName, bool bCreateMissing ) const
+{
+ return mxImpl->mxStorage->openSubStorage( rStorageName, bCreateMissing );
+}
+
+Reference< XInputStream > FilterBase::openInputStream( const OUString& rStreamName ) const
+{
+ return mxImpl->mxStorage->openInputStream( rStreamName );
+}
+
+Reference< XOutputStream > FilterBase::openOutputStream( const OUString& rStreamName ) const
+{
+ return mxImpl->mxStorage->openOutputStream( rStreamName );
+}
+
+void FilterBase::commitStorage() const
+{
+ mxImpl->mxStorage->commit();
+}
+
+// helpers --------------------------------------------------------------------
+
+GraphicHelper& FilterBase::getGraphicHelper() const
+{
+ if( !mxImpl->mxGraphicHelper )
+ mxImpl->mxGraphicHelper.reset( implCreateGraphicHelper() );
+ return *mxImpl->mxGraphicHelper;
+}
+
+ModelObjectHelper& FilterBase::getModelObjectHelper() const
+{
+ if( !mxImpl->mxModelObjHelper )
+ mxImpl->mxModelObjHelper.reset( new ModelObjectHelper( mxImpl->mxModelFactory ) );
+ return *mxImpl->mxModelObjHelper;
+}
+
+OleObjectHelper& FilterBase::getOleObjectHelper() const
+{
+ if( !mxImpl->mxOleObjHelper )
+ mxImpl->mxOleObjHelper.reset( new OleObjectHelper( mxImpl->mxModelFactory ) );
+ return *mxImpl->mxOleObjHelper;
+}
+
+VbaProject& FilterBase::getVbaProject() const
+{
+ if( !mxImpl->mxVbaProject )
+ mxImpl->mxVbaProject.reset( implCreateVbaProject() );
+ return *mxImpl->mxVbaProject;
+}
+
+Sequence< NamedValue > FilterBase::requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const
+{
+ ::std::vector< OUString > aDefaultPasswords;
+ aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
+ return ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+ rVerifier, mxImpl->maMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
+}
+
+bool FilterBase::importBinaryData( StreamDataSequence& orDataSeq, const OUString& rStreamName )
+{
+ OSL_ENSURE( rStreamName.getLength() > 0, "FilterBase::importBinaryData - empty stream name" );
+ if( rStreamName.getLength() == 0 )
+ return false;
+
+ // try to open the stream (this may fail - do not assert)
+ BinaryXInputStream aInStrm( openInputStream( rStreamName ), true );
+ if( aInStrm.isEof() )
+ return false;
+
+ // copy the entire stream to the passed sequence
+ SequenceOutputStream aOutStrm( orDataSeq );
+ aInStrm.copyToStream( aOutStrm );
+ return true;
+}
+
+// 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 )
+{
+ if( rArgs.getLength() >= 2 ) try
+ {
+ mxImpl->maArguments << rArgs[ 1 ];
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// com.sun.star.document.XImporter interface ----------------------------------
+
+void SAL_CALL FilterBase::setTargetDocument( const Reference< XComponent >& rxDocument ) throw( IllegalArgumentException, RuntimeException )
+{
+ mxImpl->setDocumentModel( rxDocument );
+ mxImpl->meDirection = FILTERDIRECTION_IMPORT;
+}
+
+// com.sun.star.document.XExporter interface ----------------------------------
+
+void SAL_CALL FilterBase::setSourceDocument( const Reference< XComponent >& rxDocument ) throw( IllegalArgumentException, RuntimeException )
+{
+ mxImpl->setDocumentModel( rxDocument );
+ mxImpl->meDirection = FILTERDIRECTION_EXPORT;
+}
+
+// com.sun.star.document.XFilter interface ------------------------------------
+
+sal_Bool SAL_CALL FilterBase::filter( const Sequence< PropertyValue >& rMediaDescSeq ) throw( RuntimeException )
+{
+ if( !mxImpl->mxModel.is() || !mxImpl->mxModelFactory.is() || (mxImpl->meDirection == FILTERDIRECTION_UNKNOWN) )
+ throw RuntimeException();
+
+ sal_Bool bRet = sal_False;
+ setMediaDescriptor( rMediaDescSeq );
+ DocumentOpenedGuard aOpenedGuard( mxImpl->maFileUrl );
+ if( aOpenedGuard.isValid() || !mxImpl->maFileUrl.getLength() )
+ {
+ mxImpl->initializeFilter();
+ switch( mxImpl->meDirection )
+ {
+ case FILTERDIRECTION_UNKNOWN:
+ break;
+ case FILTERDIRECTION_IMPORT:
+ if( mxImpl->mxInStream.is() )
+ {
+ mxImpl->mxStorage = implCreateStorage( mxImpl->mxInStream );
+ bRet = mxImpl->mxStorage.get() && importDocument();
+ }
+ break;
+ case FILTERDIRECTION_EXPORT:
+ if( mxImpl->mxOutStream.is() )
+ {
+ mxImpl->mxStorage = implCreateStorage( mxImpl->mxOutStream );
+ bRet = mxImpl->mxStorage.get() && exportDocument();
+ }
+ break;
+ }
+ mxImpl->finalizeFilter();
+ }
+ return bRet;
+}
+
+void SAL_CALL FilterBase::cancel() throw( RuntimeException )
+{
+}
+
+// protected ------------------------------------------------------------------
+
+Reference< XInputStream > FilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const
+{
+ return rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_INPUTSTREAM(), Reference< XInputStream >() );
+}
+
+Reference< XStream > FilterBase::implGetOutputStream( MediaDescriptor& rMediaDesc ) const
+{
+ return rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_STREAMFOROUTPUT(), Reference< XStream >() );
+}
+
+// private --------------------------------------------------------------------
+
+void FilterBase::setMediaDescriptor( const Sequence< PropertyValue >& rMediaDescSeq )
+{
+ mxImpl->maMediaDesc << rMediaDescSeq;
+
+ switch( mxImpl->meDirection )
+ {
+ case FILTERDIRECTION_UNKNOWN:
+ OSL_ENSURE( false, "FilterBase::setMediaDescriptor - invalid filter direction" );
+ break;
+ case FILTERDIRECTION_IMPORT:
+ mxImpl->maMediaDesc.addInputStream();
+ mxImpl->mxInStream = implGetInputStream( mxImpl->maMediaDesc );
+ OSL_ENSURE( mxImpl->mxInStream.is(), "FilterBase::setMediaDescriptor - missing input stream" );
+ break;
+ case FILTERDIRECTION_EXPORT:
+ mxImpl->mxOutStream = implGetOutputStream( mxImpl->maMediaDesc );
+ OSL_ENSURE( mxImpl->mxOutStream.is(), "FilterBase::setMediaDescriptor - missing output stream" );
+ break;
+ }
+
+ mxImpl->maFileUrl = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), OUString() );
+ mxImpl->mxTargetFrame = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_FRAME(), Reference< XFrame >() );
+ mxImpl->mxStatusIndicator = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_STATUSINDICATOR(), Reference< XStatusIndicator >() );
+ mxImpl->mxInteractionHandler = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_INTERACTIONHANDLER(), Reference< XInteractionHandler >() );
+}
+
+GraphicHelper* FilterBase::implCreateGraphicHelper() const
+{
+ // default: return base implementation without any special behaviour
+ return new GraphicHelper( mxImpl->mxComponentContext, mxImpl->mxTargetFrame, mxImpl->mxStorage );
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
new file mode 100644
index 000000000000..cdab111e9898
--- /dev/null
+++ b/oox/source/core/filterdetect.cxx
@@ -0,0 +1,681 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/filterdetect.hxx"
+
+#include <com/sun/star/io/XStream.hpp>
+#include <comphelper/docpasswordhelper.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <openssl/evp.h>
+#include <rtl/digest.h>
+#include "oox/core/fastparser.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/helper/zipstorage.hxx"
+#include "oox/ole/olestorage.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::comphelper::MediaDescriptor;
+using ::comphelper::SequenceAsHashMap;
+using ::rtl::OUString;
+
+// ============================================================================
+
+FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilterName ) :
+ mrFilterName( rFilterName )
+{
+ 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 PR_TOKEN( Relationships ):
+ break;
+ case PR_TOKEN( Relationship ):
+ if( !maContextStack.empty() && (maContextStack.back() == PR_TOKEN( Relationships )) )
+ parseRelationship( aAttribs );
+ break;
+
+ // cases for [Content_Types].xml
+ case PC_TOKEN( Types ):
+ break;
+ case PC_TOKEN( Default ):
+ if( !maContextStack.empty() && (maContextStack.back() == PC_TOKEN( Types )) )
+ parseContentTypesDefault( aAttribs );
+ break;
+ case PC_TOKEN( Override ):
+ if( !maContextStack.empty() && (maContextStack.back() == PC_TOKEN( 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, OUString() );
+ if( aType.equalsAscii( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) )
+ maTargetPath = OUString( sal_Unicode( '/' ) ) + rAttribs.getString( XML_Target, OUString() );
+}
+
+OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType ) const
+{
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" ) ||
+ rContentType.equalsAscii( "application/vnd.ms-word.document.macroEnabled.main+xml" ) )
+ return CREATE_OUSTRING( "writer_MS_Word_2007" );
+
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml" ) ||
+ rContentType.equalsAscii( "application/vnd.ms-word.template.macroEnabledTemplate.main+xml" ) )
+ return CREATE_OUSTRING( "writer_MS_Word_2007_Template" );
+
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" ) ||
+ rContentType.equalsAscii( "application/vnd.ms-excel.sheet.macroEnabled.main+xml" ) )
+ return CREATE_OUSTRING( "MS Excel 2007 XML" );
+
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml" ) ||
+ rContentType.equalsAscii( "application/vnd.ms-excel.template.macroEnabled.main+xml" ) )
+ return CREATE_OUSTRING( "MS Excel 2007 XML Template" );
+
+ if( rContentType.equalsAscii( "application/vnd.ms-excel.sheet.binary.macroEnabled.main" ) )
+ return CREATE_OUSTRING( "MS Excel 2007 Binary" );
+
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml" ) ||
+ rContentType.equalsAscii( "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml" ) )
+ return CREATE_OUSTRING( "MS PowerPoint 2007 XML" );
+
+ if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml" ) ||
+ rContentType.equalsAscii( "application/vnd.ms-powerpoint.template.macroEnabled.main+xml" ) )
+ return CREATE_OUSTRING( "MS PowerPoint 2007 XML Template" );
+
+ return OUString();
+}
+
+void FilterDetectDocHandler::parseContentTypesDefault( const AttributeList& rAttribs )
+{
+ // only if no overridden part name found
+ if( mrFilterName.getLength() == 0 )
+ {
+ // check if target path ends with extension
+ OUString aExtension = rAttribs.getString( XML_Extension, OUString() );
+ sal_Int32 nExtPos = maTargetPath.getLength() - aExtension.getLength();
+ if( (nExtPos > 0) && (maTargetPath[ nExtPos - 1 ] == '.') && maTargetPath.match( aExtension, nExtPos ) )
+ mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
+ }
+}
+
+void FilterDetectDocHandler::parseContentTypesOverride( const AttributeList& rAttribs )
+{
+ if( rAttribs.getString( XML_PartName, OUString() ).equals( maTargetPath ) )
+ mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
+}
+
+// ============================================================================
+
+/* 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< XComponentContext >& rxContext ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new FilterDetect( rxContext ) );
+}
+
+// ----------------------------------------------------------------------------
+
+FilterDetect::FilterDetect( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ mxContext( rxContext, UNO_SET_THROW )
+{
+}
+
+FilterDetect::~FilterDetect()
+{
+}
+
+/* =========================================================================== */
+/* Kudos to Caolan McNamara who provided the core decryption implementations. */
+/* =========================================================================== */
+
+namespace {
+
+const sal_uInt32 ENCRYPTINFO_CRYPTOAPI = 0x00000004;
+const sal_uInt32 ENCRYPTINFO_DOCPROPS = 0x00000008;
+const sal_uInt32 ENCRYPTINFO_EXTERNAL = 0x00000010;
+const sal_uInt32 ENCRYPTINFO_AES = 0x00000020;
+
+const sal_uInt32 ENCRYPT_ALGO_AES128 = 0x0000660E;
+const sal_uInt32 ENCRYPT_ALGO_AES192 = 0x0000660F;
+const sal_uInt32 ENCRYPT_ALGO_AES256 = 0x00006610;
+const sal_uInt32 ENCRYPT_ALGO_RC4 = 0x00006801;
+
+const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004;
+
+// ----------------------------------------------------------------------------
+
+bool lclIsZipPackage( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm )
+{
+ ZipStorage aZipStorage( rxFactory, rxInStrm );
+ return aZipStorage.isStorage();
+}
+
+// ----------------------------------------------------------------------------
+
+struct PackageEncryptionInfo
+{
+ sal_uInt8 mpnSalt[ 16 ];
+ sal_uInt8 mpnEncrVerifier[ 16 ];
+ sal_uInt8 mpnEncrVerifierHash[ 32 ];
+ sal_uInt32 mnFlags;
+ sal_uInt32 mnAlgorithmId;
+ sal_uInt32 mnAlgorithmIdHash;
+ sal_uInt32 mnKeySize;
+ sal_uInt32 mnSaltSize;
+ sal_uInt32 mnVerifierHashSize;
+};
+
+bool lclReadEncryptionInfo( PackageEncryptionInfo& rEncrInfo, BinaryInputStream& rStrm )
+{
+ rStrm.skip( 4 );
+ rStrm >> rEncrInfo.mnFlags;
+ if( getFlag( rEncrInfo.mnFlags, ENCRYPTINFO_EXTERNAL ) )
+ return false;
+
+ sal_uInt32 nHeaderSize, nRepeatedFlags;
+ rStrm >> nHeaderSize >> nRepeatedFlags;
+ if( (nHeaderSize < 20) || (nRepeatedFlags != rEncrInfo.mnFlags) )
+ return false;
+
+ rStrm.skip( 4 );
+ rStrm >> rEncrInfo.mnAlgorithmId >> rEncrInfo.mnAlgorithmIdHash >> rEncrInfo.mnKeySize;
+ rStrm.skip( nHeaderSize - 20 );
+ rStrm >> rEncrInfo.mnSaltSize;
+ if( rEncrInfo.mnSaltSize != 16 )
+ return false;
+
+ rStrm.readMemory( rEncrInfo.mpnSalt, 16 );
+ rStrm.readMemory( rEncrInfo.mpnEncrVerifier, 16 );
+ rStrm >> rEncrInfo.mnVerifierHashSize;
+ rStrm.readMemory( rEncrInfo.mpnEncrVerifierHash, 32 );
+ return !rStrm.isEof();
+}
+
+// ----------------------------------------------------------------------------
+
+void lclDeriveKey( const sal_uInt8* pnHash, sal_uInt32 nHashLen, sal_uInt8* pnKeyDerived, sal_uInt32 nRequiredKeyLen )
+{
+ sal_uInt8 pnBuffer[ 64 ];
+ memset( pnBuffer, 0x36, sizeof( pnBuffer ) );
+ for( sal_uInt32 i = 0; i < nHashLen; ++i )
+ pnBuffer[ i ] ^= pnHash[ i ];
+
+ rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) );
+ sal_uInt8 pnX1[ RTL_DIGEST_LENGTH_SHA1 ];
+ aError = rtl_digest_get( aDigest, pnX1, RTL_DIGEST_LENGTH_SHA1 );
+ rtl_digest_destroy( aDigest );
+
+ memset( pnBuffer, 0x5C, sizeof( pnBuffer ) );
+ for( sal_uInt32 i = 0; i < nHashLen; ++i )
+ pnBuffer[ i ] ^= pnHash[ i ];
+
+ aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) );
+ sal_uInt8 pnX2[ RTL_DIGEST_LENGTH_SHA1 ];
+ aError = rtl_digest_get( aDigest, pnX2, RTL_DIGEST_LENGTH_SHA1 );
+ rtl_digest_destroy( aDigest );
+
+ if( nRequiredKeyLen > RTL_DIGEST_LENGTH_SHA1 )
+ {
+ memcpy( pnKeyDerived + RTL_DIGEST_LENGTH_SHA1, pnX2, nRequiredKeyLen - RTL_DIGEST_LENGTH_SHA1 );
+ nRequiredKeyLen = RTL_DIGEST_LENGTH_SHA1;
+ }
+ memcpy( pnKeyDerived, pnX1, nRequiredKeyLen );
+}
+
+// ----------------------------------------------------------------------------
+
+bool lclCheckEncryptionData( const sal_uInt8* pnKey, sal_uInt32 nKeySize, const sal_uInt8* pnVerifier, sal_uInt32 nVerifierSize, const sal_uInt8* pnVerifierHash, sal_uInt32 nVerifierHashSize )
+{
+ bool bResult = false;
+
+ // the only currently supported algorithm needs key size 128
+ if ( nKeySize == 16 && nVerifierSize == 16 && nVerifierHashSize == 32 )
+ {
+ // check password
+ EVP_CIPHER_CTX aes_ctx;
+ EVP_CIPHER_CTX_init( &aes_ctx );
+ EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
+ EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+ int nOutLen = 0;
+ sal_uInt8 pnTmpVerifier[ 16 ];
+ (void) memset( pnTmpVerifier, 0, sizeof(pnTmpVerifier) );
+
+ /*int*/ EVP_DecryptUpdate( &aes_ctx, pnTmpVerifier, &nOutLen, pnVerifier, nVerifierSize );
+ EVP_CIPHER_CTX_cleanup( &aes_ctx );
+
+ EVP_CIPHER_CTX_init( &aes_ctx );
+ EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
+ EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+ sal_uInt8 pnTmpVerifierHash[ 32 ];
+ (void) memset( pnTmpVerifierHash, 0, sizeof(pnTmpVerifierHash) );
+
+ /*int*/ EVP_DecryptUpdate( &aes_ctx, pnTmpVerifierHash, &nOutLen, pnVerifierHash, nVerifierHashSize );
+ EVP_CIPHER_CTX_cleanup( &aes_ctx );
+
+ rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ rtlDigestError aError = rtl_digest_update( aDigest, pnTmpVerifier, sizeof( pnTmpVerifier ) );
+ sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ];
+ aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 );
+ rtl_digest_destroy( aDigest );
+
+ bResult = ( memcmp( pnSha1Hash, pnTmpVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0 );
+ }
+
+ return bResult;
+}
+
+// ----------------------------------------------------------------------------
+
+Sequence< NamedValue > lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen )
+{
+ size_t nBufferSize = rEncrInfo.mnSaltSize + 2 * rPassword.getLength();
+ sal_uInt8* pnBuffer = new sal_uInt8[ nBufferSize ];
+ memcpy( pnBuffer, rEncrInfo.mpnSalt, rEncrInfo.mnSaltSize );
+
+ sal_uInt8* pnPasswordLoc = pnBuffer + rEncrInfo.mnSaltSize;
+ const sal_Unicode* pStr = rPassword.getStr();
+ for( sal_Int32 i = 0, nLen = rPassword.getLength(); i < nLen; ++i, ++pStr, pnPasswordLoc += 2 )
+ ByteOrderConverter::writeLittleEndian( pnPasswordLoc, static_cast< sal_uInt16 >( *pStr ) );
+
+ rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, nBufferSize );
+ delete[] pnBuffer;
+
+ size_t nHashSize = RTL_DIGEST_LENGTH_SHA1 + 4;
+ sal_uInt8* pnHash = new sal_uInt8[ nHashSize ];
+ aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 );
+ rtl_digest_destroy( aDigest );
+
+ for( sal_uInt32 i = 0; i < 50000; ++i )
+ {
+ ByteOrderConverter::writeLittleEndian( pnHash, i );
+ aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ aError = rtl_digest_update( aDigest, pnHash, nHashSize );
+ aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 );
+ rtl_digest_destroy( aDigest );
+ }
+
+ memmove( pnHash, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 );
+ memset( pnHash + RTL_DIGEST_LENGTH_SHA1, 0, 4 );
+ aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ aError = rtl_digest_update( aDigest, pnHash, nHashSize );
+ aError = rtl_digest_get( aDigest, pnHash, RTL_DIGEST_LENGTH_SHA1 );
+ rtl_digest_destroy( aDigest );
+
+ lclDeriveKey( pnHash, RTL_DIGEST_LENGTH_SHA1, pnKey, nRequiredKeyLen );
+ delete[] pnHash;
+
+ Sequence< NamedValue > aResult;
+ if( lclCheckEncryptionData( pnKey, nRequiredKeyLen, rEncrInfo.mpnEncrVerifier, sizeof( rEncrInfo.mpnEncrVerifier ), rEncrInfo.mpnEncrVerifierHash, sizeof( rEncrInfo.mpnEncrVerifierHash ) ) )
+ {
+ SequenceAsHashMap aEncryptionData;
+ aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionKey" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pnKey ), nRequiredKeyLen );
+ aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionSalt" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnSalt ), rEncrInfo.mnSaltSize );
+ aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionVerifier" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnEncrVerifier ), sizeof( rEncrInfo.mpnEncrVerifier ) );
+ aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionVerifierHash" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnEncrVerifierHash ), sizeof( rEncrInfo.mpnEncrVerifierHash ) );
+ aResult = aEncryptionData.getAsConstNamedValueList();
+ }
+
+ return aResult;
+}
+
+// the password verifier ------------------------------------------------------
+
+class PasswordVerifier : public ::comphelper::IDocPasswordVerifier
+{
+public:
+ explicit PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo );
+
+ virtual ::comphelper::DocPasswordVerifierResult
+ verifyPassword( const OUString& rPassword, Sequence< NamedValue >& o_rEncryptionData );
+ virtual ::comphelper::DocPasswordVerifierResult
+ verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData );
+
+ inline const sal_uInt8* getKey() const { return &maKey.front(); }
+
+private:
+ const PackageEncryptionInfo& mrEncryptInfo;
+ ::std::vector< sal_uInt8 > maKey;
+};
+
+PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) :
+ mrEncryptInfo( rEncryptInfo ),
+ maKey( static_cast< size_t >( rEncryptInfo.mnKeySize / 8 ), 0 )
+{
+}
+
+::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword, Sequence< NamedValue >& o_rEncryptionData )
+{
+ // verifies the password and writes the related decryption key into maKey
+ o_rEncryptionData = lclGenerateEncryptionKey( mrEncryptInfo, rPassword, &maKey.front(), maKey.size() );
+ return o_rEncryptionData.hasElements() ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData )
+{
+ SequenceAsHashMap aHashData( rEncryptionData );
+ Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionKey" ), Sequence< sal_Int8 >() );
+ Sequence< sal_Int8 > aVerifier = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionVerifier" ), Sequence< sal_Int8 >() );
+ Sequence< sal_Int8 > aVerifierHash = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionVerifierHash" ), Sequence< sal_Int8 >() );
+
+ bool bResult = lclCheckEncryptionData(
+ reinterpret_cast< const sal_uInt8* >( aKey.getConstArray() ), aKey.getLength(),
+ reinterpret_cast< const sal_uInt8* >( aVerifier.getConstArray() ), aVerifier.getLength(),
+ reinterpret_cast< const sal_uInt8* >( aVerifierHash.getConstArray() ), aVerifierHash.getLength() );
+
+ return bResult ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescriptor& rMediaDesc ) const
+{
+ Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY );
+ if( xFactory.is() )
+ {
+ // try the plain input stream
+ Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY );
+ if( !xInStrm.is() || lclIsZipPackage( xFactory, xInStrm ) )
+ return xInStrm;
+
+ // check if a temporary file is passed in the 'ComponentData' property
+ Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY );
+ if( xDecrypted.is() )
+ {
+ Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream();
+ if( lclIsZipPackage( xFactory, xDecrInStrm ) )
+ return xDecrInStrm;
+ }
+
+ // try to decrypt an encrypted OLE package
+ ::oox::ole::OleStorage aOleStorage( xFactory, xInStrm, false );
+ if( aOleStorage.isStorage() ) try
+ {
+ // open the required input streams in the encrypted package
+ Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW );
+ Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW );
+
+ // read the encryption info stream
+ PackageEncryptionInfo aEncryptInfo;
+ BinaryXInputStream aInfoStrm( xEncryptionInfo, true );
+ bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm );
+
+ // check flags and agorithm IDs, requiered are AES128 and SHA-1
+ bool bImplemented = bValidInfo &&
+ getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) &&
+ getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) &&
+ // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set
+ ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) &&
+ // hash algorithm ID 0 defaults to SHA-1 too
+ ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) &&
+ (aEncryptInfo.mnVerifierHashSize == 20);
+
+ if( bImplemented )
+ {
+ /* "VelvetSweatshop" is the built-in default encryption
+ password used by MS Excel for the "workbook protection"
+ feature with password. Try this first before prompting the
+ user for a password. */
+ ::std::vector< OUString > aDefaultPasswords;
+ aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
+
+ /* Use the comphelper password helper to request a password.
+ This helper returns either with the correct password
+ (according to the verifier), or with an empty string if
+ user has cancelled the password input dialog. */
+ PasswordVerifier aVerifier( aEncryptInfo );
+ Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+ aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
+
+ if( aEncryptionData.getLength() == 0 )
+ {
+ rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true;
+ }
+ else
+ {
+ // create temporary file for unencrypted package
+ Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
+ Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW );
+ BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true );
+ BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true );
+
+ EVP_CIPHER_CTX aes_ctx;
+ EVP_CIPHER_CTX_init( &aes_ctx );
+ EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 );
+ EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+
+ sal_uInt8 pnInBuffer[ 1024 ];
+ sal_uInt8 pnOutBuffer[ 1024 ];
+ sal_Int32 nInLen;
+ int nOutLen;
+ aEncryptedPackage.skip( 8 ); // decrypted size
+ while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 )
+ {
+ EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen );
+ aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen );
+ }
+ EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen );
+ aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen );
+
+ EVP_CIPHER_CTX_cleanup( &aes_ctx );
+ xDecryptedPackage->flush();
+ aDecryptedPackage.seekToStart();
+
+ // store temp file in media descriptor to keep it alive
+ rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) );
+
+ Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream();
+ if( lclIsZipPackage( xFactory, xDecrInStrm ) )
+ return xDecrInStrm;
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ return Reference< XInputStream >();
+}
+
+// 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();
+}
+
+// com.sun.star.document.XExtendedFilterDetection interface -------------------
+
+OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq ) throw( RuntimeException )
+{
+ OUString aFilterName;
+ MediaDescriptor aMediaDesc( rMediaDescSeq );
+ Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
+
+ /* Check that the user has not choosen to abort detection, e.g. by hitting
+ 'Cancel' in the password input dialog. This may happen because this
+ filter detection is used by different filters. */
+ bool bAborted = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_ABORTED(), false );
+ if( !bAborted ) try
+ {
+ aMediaDesc.addInputStream();
+
+ /* Get the unencrypted input stream. This may include creation of a
+ temporary file that contains the decrypted package. This temporary
+ file will be stored in the 'ComponentData' property of the media
+ descriptor. */
+ Reference< XInputStream > xInStrm( extractUnencryptedPackage( aMediaDesc ), UNO_SET_THROW );
+
+ // stream must be a ZIP package
+ ZipStorage aZipStorage( xFactory, xInStrm );
+ if( aZipStorage.isStorage() )
+ {
+ // create the fast parser, register the XML namespaces, set document handler
+ FastParser aParser( mxContext );
+ aParser.registerNamespace( NMSP_packageRel );
+ aParser.registerNamespace( NMSP_officeRel );
+ aParser.registerNamespace( NMSP_packageContentTypes );
+ aParser.setDocumentHandler( new FilterDetectDocHandler( aFilterName ) );
+
+ /* Parse '_rels/.rels' to get the target path and '[Content_Types].xml'
+ to determine the content type of the part at the target path. */
+ aParser.parseStream( aZipStorage, CREATE_OUSTRING( "_rels/.rels" ) );
+ aParser.parseStream( aZipStorage, CREATE_OUSTRING( "[Content_Types].xml" ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ // write back changed media descriptor members
+ aMediaDesc >> rMediaDescSeq;
+ return aFilterName;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/fragmenthandler.cxx b/oox/source/core/fragmenthandler.cxx
new file mode 100644
index 000000000000..a1c42e56c155
--- /dev/null
+++ b/oox/source/core/fragmenthandler.cxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/fragmenthandler.hxx"
+
+#include "oox/core/xmlfilterbase.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+FragmentBaseData::FragmentBaseData( XmlFilterBase& rFilter, const OUString& rFragmentPath, RelationsRef xRelations ) :
+ mrFilter( rFilter ),
+ maFragmentPath( rFragmentPath ),
+ mxRelations( xRelations )
+{
+}
+
+// ============================================================================
+
+FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) :
+ FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, rFilter.importRelations( rFragmentPath ) ) ) )
+{
+}
+
+FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath, RelationsRef xRelations ) :
+ FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, xRelations ) ) )
+{
+}
+
+FragmentHandler::~FragmentHandler()
+{
+}
+
+// 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 >& rxLocator ) throw( SAXException, RuntimeException )
+{
+ implSetLocator( rxLocator );
+}
+
+// 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 0;
+}
+
+Reference< XFastContextHandler > FragmentHandler::createUnknownChildContext( const OUString&, const OUString&, const Reference< XFastAttributeList >& ) throw( SAXException, RuntimeException )
+{
+ return 0;
+}
+
+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 )
+{
+}
+
+// XML stream handling --------------------------------------------------------
+
+Reference< XInputStream > FragmentHandler::openFragmentStream() const
+{
+ return getFilter().openInputStream( getFragmentPath() );
+}
+
+// binary records -------------------------------------------------------------
+
+const RecordInfo* FragmentHandler::getRecordInfos() const
+{
+ // default: no support for binary records
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/fragmenthandler2.cxx b/oox/source/core/fragmenthandler2.cxx
new file mode 100644
index 000000000000..7771b89747b9
--- /dev/null
+++ b/oox/source/core/fragmenthandler2.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/fragmenthandler2.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+FragmentHandler2::FragmentHandler2( XmlFilterBase& rFilter, const OUString& rFragmentPath, bool bEnableTrimSpace ) :
+ FragmentHandler( rFilter, rFragmentPath ),
+ ContextHandler2Helper( bEnableTrimSpace )
+{
+}
+
+FragmentHandler2::~FragmentHandler2()
+{
+}
+
+// com.sun.star.xml.sax.XFastDocumentHandler interface --------------------
+
+void SAL_CALL FragmentHandler2::startDocument() throw( SAXException, RuntimeException )
+{
+ initializeImport();
+}
+
+void SAL_CALL FragmentHandler2::endDocument() throw( SAXException, RuntimeException )
+{
+ finalizeImport();
+}
+
+// com.sun.star.xml.sax.XFastContextHandler interface -------------------------
+
+Reference< XFastContextHandler > SAL_CALL FragmentHandler2::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException )
+{
+ return implCreateChildContext( nElement, rxAttribs );
+}
+
+void SAL_CALL FragmentHandler2::startFastElement(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException )
+{
+ implStartElement( nElement, rxAttribs );
+}
+
+void SAL_CALL FragmentHandler2::characters( const OUString& rChars ) throw( SAXException, RuntimeException )
+{
+ implCharacters( rChars );
+}
+
+void SAL_CALL FragmentHandler2::endFastElement( sal_Int32 nElement ) throw( SAXException, RuntimeException )
+{
+ implEndElement( nElement );
+}
+
+// oox.core.ContextHandler interface ------------------------------------------
+
+ContextHandlerRef FragmentHandler2::createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ return implCreateRecordContext( nRecId, rStrm );
+}
+
+void FragmentHandler2::startRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ implStartRecord( nRecId, rStrm );
+}
+
+void FragmentHandler2::endRecord( sal_Int32 nRecId )
+{
+ implEndRecord( nRecId );
+}
+
+// oox.core.ContextHandler2Helper interface -----------------------------------
+
+ContextHandlerRef FragmentHandler2::onCreateContext( sal_Int32, const AttributeList& )
+{
+ return 0;
+}
+
+void FragmentHandler2::onStartElement( const AttributeList& )
+{
+}
+
+void FragmentHandler2::onCharacters( const OUString& )
+{
+}
+
+void FragmentHandler2::onEndElement()
+{
+}
+
+ContextHandlerRef FragmentHandler2::onCreateRecordContext( sal_Int32, SequenceInputStream& )
+{
+ return 0;
+}
+
+void FragmentHandler2::onStartRecord( SequenceInputStream& )
+{
+}
+
+void FragmentHandler2::onEndRecord()
+{
+}
+
+// oox.core.FragmentHandler2 interface ----------------------------------------
+
+void FragmentHandler2::initializeImport()
+{
+}
+
+void FragmentHandler2::finalizeImport()
+{
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk
new file mode 100644
index 000000000000..2b58b95777df
--- /dev/null
+++ b/oox/source/core/makefile.mk
@@ -0,0 +1,66 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=core
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+.IF "$(SYSTEM_OPENSSL)" == "YES"
+CFLAGS+= $(OPENSSL_CFLAGS)
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/binarycodec.obj \
+ $(SLO)$/binaryfilterbase.obj \
+ $(SLO)$/contexthandler.obj \
+ $(SLO)$/contexthandler2.obj \
+ $(SLO)$/fastparser.obj \
+ $(SLO)$/fasttokenhandler.obj \
+ $(SLO)$/filterbase.obj \
+ $(SLO)$/filterdetect.obj \
+ $(SLO)$/fragmenthandler.obj \
+ $(SLO)$/fragmenthandler2.obj \
+ $(SLO)$/recordparser.obj \
+ $(SLO)$/relations.obj \
+ $(SLO)$/relationshandler.obj \
+ $(SLO)$/services.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..aef73ceed86c
--- /dev/null
+++ b/oox/source/core/recordparser.cxx
@@ -0,0 +1,350 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/recordparser.hxx"
+
+#include <vector>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/xml/sax/XLocator.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include "oox/core/fragmenthandler.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+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;
+ ContextHandlerRef getCurrentContext() const;
+
+ void pushContext( const RecordInfo& rRec, const ContextHandlerRef& rxContext );
+ void popContext();
+
+private:
+ typedef ::std::pair< RecordInfo, ContextHandlerRef > 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);
+}
+
+ContextHandlerRef ContextStack::getCurrentContext() const
+{
+ if( !maStack.empty() )
+ return maStack.back().second;
+ return mxHandler.get();
+}
+
+void ContextStack::pushContext( const RecordInfo& rRecInfo, const ContextHandlerRef& 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.readMemory( &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, StreamDataSequence& orData, BinaryInputStream& rStrm )
+{
+ sal_Int32 nRecSize = 0;
+ bool bValid = lclReadRecordHeader( ornRecId, nRecSize, rStrm );
+ if( bValid )
+ {
+ orData.realloc( nRecSize );
+ bValid = (nRecSize == 0) || (rStrm.readData( 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;
+
+ // build record infos
+ maStartMap.clear();
+ maEndMap.clear();
+ const RecordInfo* pRecs = mxHandler.is() ? mxHandler->getRecordInfos() : 0;
+ OSL_ENSURE( pRecs, "RecordInfoProvider::RecordInfoProvider - missing record list" );
+ for( ; pRecs && pRecs->mnStartRecId >= 0; ++pRecs )
+ {
+ maStartMap[ pRecs->mnStartRecId ] = *pRecs;
+ if( pRecs->mnEndRecId >= 0 )
+ maEndMap[ pRecs->mnEndRecId ] = *pRecs;
+ }
+}
+
+void RecordParser::parseStream( const RecordInputSource& rInputSource ) throw( SAXException, IOException, RuntimeException )
+{
+ maSource = rInputSource;
+
+ if( !maSource.mxInStream || maSource.mxInStream->isEof() )
+ throw IOException();
+ if( !mxHandler.is() )
+ throw SAXException();
+
+ // 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;
+ StreamDataSequence aRecData;
+ while( lclReadNextRecord( nRecId, aRecData, *maSource.mxInStream ) )
+ {
+ // create record stream object from imported record data
+ SequenceInputStream aRecStrm( aRecData );
+ // try to leave a context, there may be other incomplete contexts on the stack
+ if( const RecordInfo* pEndRecInfo = getEndRecordInfo( nRecId ) )
+ {
+ // 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
+ ContextHandlerRef xCurrContext = mxStack->getCurrentContext();
+ if( xCurrContext.is() )
+ {
+ // context end record may contain some data, handle it as simple record
+ aRecStrm.seekToStart();
+ 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
+ ContextHandlerRef xCurrContext = mxStack->getCurrentContext();
+ if( xCurrContext.is() )
+ {
+ aRecStrm.seekToStart();
+ xCurrContext = xCurrContext->createRecordContext( nRecId, aRecStrm );
+ }
+ // track all context identifiers on the stack (do not push simple records)
+ const RecordInfo* pStartRecInfo = getStartRecordInfo( nRecId );
+ if( pStartRecInfo )
+ mxStack->pushContext( *pStartRecInfo, xCurrContext );
+ // import the record
+ if( xCurrContext.is() )
+ {
+ // import the record
+ aRecStrm.seekToStart();
+ 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();
+}
+
+const RecordInfo* RecordParser::getStartRecordInfo( sal_Int32 nRecId ) const
+{
+ RecordInfoMap::const_iterator aIt = maStartMap.find( nRecId );
+ return (aIt == maStartMap.end()) ? 0 : &aIt->second;
+}
+
+const RecordInfo* RecordParser::getEndRecordInfo( sal_Int32 nRecId ) const
+{
+ RecordInfoMap::const_iterator aIt = maEndMap.find( nRecId );
+ return (aIt == maEndMap.end()) ? 0 : &aIt->second;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/relations.cxx b/oox/source/core/relations.cxx
new file mode 100644
index 000000000000..f6cade391a0f
--- /dev/null
+++ b/oox/source/core/relations.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/relations.hxx"
+
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+OUString lclRemoveFileName( const OUString& rPath )
+{
+ return rPath.copy( 0, ::std::max< sal_Int32 >( rPath.lastIndexOf( '/' ), 0 ) );
+}
+
+OUString lclAppendFileName( const OUString& rPath, const OUString& rFileName )
+{
+ return (rPath.getLength() == 0) ? rFileName :
+ OUStringBuffer( rPath ).append( sal_Unicode( '/' ) ).append( rFileName ).makeStringAndClear();
+}
+
+} // namespace
+
+// ============================================================================
+
+Relations::Relations( const OUString& rFragmentPath ) :
+ maFragmentPath( rFragmentPath )
+{
+}
+
+const Relation* Relations::getRelationFromRelId( const OUString& rId ) const
+{
+ const_iterator aIt = find( rId );
+ return (aIt == end()) ? 0 : &aIt->second;
+}
+
+const Relation* Relations::getRelationFromFirstType( const OUString& rType ) const
+{
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ if( aIt->second.maType.equalsIgnoreAsciiCase( rType ) )
+ return &aIt->second;
+ return 0;
+}
+
+RelationsRef Relations::getRelationsFromType( const OUString& rType ) const
+{
+ RelationsRef xRelations( new Relations( maFragmentPath ) );
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ if( aIt->second.maType.equalsIgnoreAsciiCase( rType ) )
+ (*xRelations)[ aIt->first ] = aIt->second;
+ return xRelations;
+}
+
+OUString Relations::getExternalTargetFromRelId( const OUString& rRelId ) const
+{
+ const Relation* pRelation = getRelationFromRelId( rRelId );
+ return (pRelation && pRelation->mbExternal) ? pRelation->maTarget : OUString();
+}
+
+OUString Relations::getExternalTargetFromFirstType( const OUString& rType ) const
+{
+ const Relation* pRelation = getRelationFromFirstType( rType );
+ return (pRelation && pRelation->mbExternal) ? pRelation->maTarget : OUString();
+}
+
+OUString Relations::getFragmentPathFromRelation( const Relation& rRelation ) const
+{
+ // no target, no fragment path
+ if( rRelation.mbExternal || (rRelation.maTarget.getLength() == 0) )
+ return OUString();
+
+ // absolute target: return it without leading slash (#i100978)
+ if( rRelation.maTarget[ 0 ] == '/' )
+ return rRelation.maTarget.copy( 1 );
+
+ // empty fragment path: return target
+ if( maFragmentPath.getLength() == 0 )
+ return rRelation.maTarget;
+
+ // resolve relative target path according to base path
+ OUString aPath = lclRemoveFileName( maFragmentPath );
+ sal_Int32 nStartPos = 0;
+ while( nStartPos < rRelation.maTarget.getLength() )
+ {
+ sal_Int32 nSepPos = rRelation.maTarget.indexOf( '/', nStartPos );
+ if( nSepPos < 0 ) nSepPos = rRelation.maTarget.getLength();
+ // append next directory name from aTarget to aPath, or remove last directory on '../'
+ if( (nStartPos + 2 == nSepPos) && (rRelation.maTarget[ nStartPos ] == '.') && (rRelation.maTarget[ nStartPos + 1 ] == '.') )
+ aPath = lclRemoveFileName( aPath );
+ else
+ aPath = lclAppendFileName( aPath, rRelation.maTarget.copy( nStartPos, nSepPos - nStartPos ) );
+ // move nStartPos to next directory name
+ nStartPos = nSepPos + 1;
+ }
+
+ return aPath;
+}
+
+OUString Relations::getFragmentPathFromRelId( const OUString& rRelId ) const
+{
+ const Relation* pRelation = getRelationFromRelId( rRelId );
+ return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
+}
+
+OUString Relations::getFragmentPathFromFirstType( const OUString& rType ) const
+{
+ const Relation* pRelation = getRelationFromFirstType( rType );
+ return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString();
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/relationshandler.cxx b/oox/source/core/relationshandler.cxx
new file mode 100644
index 000000000000..6812a4acada6
--- /dev/null
+++ b/oox/source/core/relationshandler.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/relationshandler.hxx"
+
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/attributelist.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+/* Build path to relations file from passed fragment 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
+
+// ============================================================================
+
+RelationsFragment::RelationsFragment( XmlFilterBase& rFilter, RelationsRef xRelations ) :
+ FragmentHandler( rFilter, lclGetRelationsPath( xRelations->getFragmentPath() ), xRelations ),
+ mxRelations( xRelations )
+{
+}
+
+Reference< XFastContextHandler > RelationsFragment::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ AttributeList aAttribs( rxAttribs );
+ switch( nElement )
+ {
+ case PR_TOKEN( Relationship ):
+ {
+ Relation aRelation;
+ aRelation.maId = aAttribs.getString( XML_Id, OUString() );
+ aRelation.maType = aAttribs.getString( XML_Type, OUString() );
+ aRelation.maTarget = aAttribs.getString( XML_Target, OUString() );
+ if( (aRelation.maId.getLength() > 0) && (aRelation.maType.getLength() > 0) && (aRelation.maTarget.getLength() > 0) )
+ {
+ sal_Int32 nTargetMode = aAttribs.getToken( XML_TargetMode, XML_Internal );
+ OSL_ENSURE( (nTargetMode == XML_Internal) || (nTargetMode == XML_External),
+ "RelationsFragment::createFastChildContext - unexpected target mode, assuming external" );
+ aRelation.mbExternal = nTargetMode != XML_Internal;
+
+ OSL_ENSURE( mxRelations->count( aRelation.maId ) == 0,
+ "RelationsFragment::createFastChildContext - relation identifier exists already" );
+ mxRelations->insert( Relations::value_type( aRelation.maId, aRelation ) );
+ }
+ }
+ break;
+ case PR_TOKEN( Relationships ):
+ xRet = getFastContextHandler();
+ break;
+ }
+ return xRet;
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/core/services.cxx b/oox/source/core/services.cxx
new file mode 100644
index 000000000000..f05524f4d046
--- /dev/null
+++ b/oox/source/core/services.cxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <cppuhelper/implementationentry.hxx>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star::uno;
+
+// Declare static functions providing service information =====================
+
+#define DECLARE_FUNCTIONS( className ) \
+extern OUString SAL_CALL className##_getImplementationName() throw(); \
+extern Sequence< OUString > SAL_CALL className##_getSupportedServiceNames() throw(); \
+extern Reference< XInterface > SAL_CALL className##_createInstance( \
+ const Reference< XComponentContext >& rxContext ) throw (Exception)
+
+namespace oox {
+ namespace core { DECLARE_FUNCTIONS( FastTokenHandler ); }
+ namespace core { DECLARE_FUNCTIONS( FilterDetect ); }
+ namespace docprop { DECLARE_FUNCTIONS( DocumentPropertiesImport ); }
+ namespace ole { DECLARE_FUNCTIONS( WordVbaProjectFilter ); }
+ namespace ppt { DECLARE_FUNCTIONS( PowerPointImport ); }
+ namespace shape { DECLARE_FUNCTIONS( ShapeContextHandler ); }
+ namespace xls { DECLARE_FUNCTIONS( BiffDetector ); }
+ namespace xls { DECLARE_FUNCTIONS( ExcelFilter ); }
+ namespace xls { DECLARE_FUNCTIONS( ExcelBiffFilter ); }
+ namespace xls { DECLARE_FUNCTIONS( ExcelVbaProjectFilter ); }
+ namespace xls { DECLARE_FUNCTIONS( OOXMLFormulaParser ); }
+}
+
+#undef DECLARE_FUNCTIONS
+
+// ============================================================================
+
+namespace {
+
+#define IMPLEMENTATION_ENTRY( className ) \
+ { &className##_createInstance, &className##_getImplementationName, &className##_getSupportedServiceNames, ::cppu::createSingleComponentFactory, 0, 0 }
+
+static ::cppu::ImplementationEntry const spServices[] =
+{
+ IMPLEMENTATION_ENTRY( ::oox::core::FastTokenHandler ),
+ IMPLEMENTATION_ENTRY( ::oox::core::FilterDetect ),
+ IMPLEMENTATION_ENTRY( ::oox::docprop::DocumentPropertiesImport ),
+ IMPLEMENTATION_ENTRY( ::oox::ole::WordVbaProjectFilter ),
+ IMPLEMENTATION_ENTRY( ::oox::ppt::PowerPointImport ),
+ IMPLEMENTATION_ENTRY( ::oox::shape::ShapeContextHandler ),
+ IMPLEMENTATION_ENTRY( ::oox::xls::BiffDetector ),
+ IMPLEMENTATION_ENTRY( ::oox::xls::ExcelFilter ),
+ IMPLEMENTATION_ENTRY( ::oox::xls::ExcelBiffFilter ),
+ IMPLEMENTATION_ENTRY( ::oox::xls::ExcelVbaProjectFilter ),
+ IMPLEMENTATION_ENTRY( ::oox::xls::OOXMLFormulaParser ),
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+#undef IMPLEMENTATION_ENTRY
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName, uno_Environment** /*ppEnvironment*/ )
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const char* pImplName, void* pServiceManager, void* pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, spServices );
+}
+
+// ============================================================================
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
new file mode 100644
index 000000000000..fe13d9322346
--- /dev/null
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -0,0 +1,510 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/xmlfilterbase.hxx"
+
+#include <cstdio>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/embed/XRelationshipAccess.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include <sax/fshelper.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/fastparser.hxx"
+#include "oox/core/filterdetect.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/core/recordparser.hxx"
+#include "oox/core/relationshandler.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/zipstorage.hxx"
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::xml::sax;
+
+using ::comphelper::MediaDescriptor;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::sax_fastparser::FSHelperPtr;
+using ::sax_fastparser::FastSerializerHelper;
+
+// ============================================================================
+
+namespace {
+
+bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix )
+{
+ sal_Int32 nSuffixPos = rFragmentPath.getLength() - rSuffix.getLength();
+ return (nSuffixPos >= 0) && rFragmentPath.match( rSuffix, nSuffixPos );
+}
+
+} // namespace
+
+// ============================================================================
+
+struct XmlFilterBaseImpl
+{
+ typedef RefMap< OUString, Relations > RelationsMap;
+
+ FastParser maFastParser;
+ const OUString maBinSuffix;
+ const OUString maVmlSuffix;
+ RelationsMap maRelationsMap;
+ TextFieldStack maTextFieldStack;
+
+ explicit XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
+};
+
+// ----------------------------------------------------------------------------
+
+XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ maFastParser( rxContext ),
+ maBinSuffix( CREATE_OUSTRING( ".bin" ) ),
+ maVmlSuffix( CREATE_OUSTRING( ".vml" ) )
+{
+ // register XML namespaces
+ maFastParser.registerNamespace( NMSP_xml );
+ maFastParser.registerNamespace( NMSP_packageRel );
+ maFastParser.registerNamespace( NMSP_officeRel );
+
+ maFastParser.registerNamespace( NMSP_dml );
+ maFastParser.registerNamespace( NMSP_dmlDiagram );
+ maFastParser.registerNamespace( NMSP_dmlChart );
+ maFastParser.registerNamespace( NMSP_dmlChartDr );
+ maFastParser.registerNamespace( NMSP_dmlSpreadDr );
+
+ maFastParser.registerNamespace( NMSP_vml );
+ maFastParser.registerNamespace( NMSP_vmlOffice );
+ maFastParser.registerNamespace( NMSP_vmlWord );
+ maFastParser.registerNamespace( NMSP_vmlExcel );
+ maFastParser.registerNamespace( NMSP_vmlPowerpoint );
+
+ maFastParser.registerNamespace( NMSP_xls );
+ maFastParser.registerNamespace( NMSP_ppt );
+
+ maFastParser.registerNamespace( NMSP_ax );
+ maFastParser.registerNamespace( NMSP_xm );
+}
+
+// ============================================================================
+
+XmlFilterBase::XmlFilterBase( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ FilterBase( rxContext ),
+ mxImpl( new XmlFilterBaseImpl( rxContext ) ),
+ mnRelId( 1 ),
+ mnMaxDocId( 0 )
+{
+}
+
+XmlFilterBase::~XmlFilterBase()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OUString XmlFilterBase::getFragmentPathFromFirstType( const OUString& rType )
+{
+ // importRelations() caches the relations map for subsequence calls
+ return importRelations( OUString() )->getFragmentPathFromFirstType( 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 import binary streams (fragment extension must be '.bin')
+ if( lclHasSuffix( aFragmentPath, mxImpl->maBinSuffix ) )
+ {
+ try
+ {
+ // try to open the fragment stream (this may fail - do not assert)
+ Reference< XInputStream > xInStrm( openInputStream( aFragmentPath ), UNO_SET_THROW );
+
+ // create the record parser
+ RecordParser aParser;
+ aParser.setFragmentHandler( rxHandler );
+
+ // create the input source and parse the stream
+ RecordInputSource aSource;
+ aSource.mxInStream.reset( new BinaryXInputStream( 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
+ {
+ /* Try to open the fragment stream (may fail, do not throw/assert).
+ Using the virtual function openFragmentStream() allows a document
+ handler to create specialized input streams, e.g. VML streams that
+ have to preprocess the raw input data. */
+ Reference< XInputStream > xInStrm = rxHandler->openFragmentStream();
+
+ // own try/catch block for showing parser failure assertion with fragment path
+ if( xInStrm.is() ) try
+ {
+ mxImpl->maFastParser.setDocumentHandler( xDocHandler );
+ mxImpl->maFastParser.parseStream( xInStrm, aFragmentPath );
+ return true;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, OStringBuffer( "XmlFilterBase::importFragment - XML parser failed in fragment '" ).
+ append( OUStringToOString( aFragmentPath, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ 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( rFragmentPath ) );
+ importFragment( new RelationsFragment( *this, rxRelations ) );
+ }
+ return rxRelations;
+}
+
+Reference< XOutputStream > XmlFilterBase::openFragmentStream( const OUString& rStreamName, const OUString& rMediaType )
+{
+ Reference< XOutputStream > xOutputStream = openOutputStream( rStreamName );
+ PropertySet aPropSet( xOutputStream );
+ aPropSet.setProperty( PROP_MediaType, rMediaType );
+ return xOutputStream;
+}
+
+FSHelperPtr XmlFilterBase::openFragmentStreamWithSerializer( const OUString& rStreamName, const OUString& rMediaType )
+{
+ return FSHelperPtr( new FastSerializerHelper( openFragmentStream( rStreamName, rMediaType ) ) );
+}
+
+TextFieldStack& XmlFilterBase::getTextFieldStack() const
+{
+ return mxImpl->maTextFieldStack;
+}
+
+namespace {
+
+OUString lclAddRelation( const Reference< XRelationshipAccess > xRelations, sal_Int32 nId, const OUString& rType, const OUString& rTarget, bool bExternal )
+{
+ OUString sId = OUStringBuffer().appendAscii( "rId" ).append( nId ).makeStringAndClear();
+
+ Sequence< StringPair > aEntry( bExternal ? 3 : 2 );
+ aEntry[0].First = CREATE_OUSTRING( "Type" );
+ aEntry[0].Second = rType;
+ aEntry[1].First = CREATE_OUSTRING( "Target" );
+ aEntry[1].Second = rTarget;
+ if( bExternal )
+ {
+ aEntry[2].First = CREATE_OUSTRING( "TargetMode" );
+ aEntry[2].Second = CREATE_OUSTRING( "External" );
+ }
+ xRelations->insertRelationshipByID( sId, aEntry, sal_True );
+
+ return sId;
+}
+
+} // namespace
+
+OUString XmlFilterBase::addRelation( const OUString& rType, const OUString& rTarget, bool bExternal )
+{
+ Reference< XRelationshipAccess > xRelations( getStorage()->getXStorage(), UNO_QUERY );
+ if( xRelations.is() )
+ return lclAddRelation( xRelations, mnRelId ++, rType, rTarget, bExternal );
+
+ return OUString();
+}
+
+OUString XmlFilterBase::addRelation( const Reference< XOutputStream > xOutputStream, const OUString& rType, const OUString& rTarget, bool bExternal )
+{
+ sal_Int32 nId = 0;
+
+ PropertySet aPropSet( xOutputStream );
+ if( aPropSet.is() )
+ aPropSet.getProperty( nId, PROP_RelId );
+ else
+ nId = mnRelId++;
+
+ Reference< XRelationshipAccess > xRelations( xOutputStream, UNO_QUERY );
+ if( xRelations.is() )
+ return lclAddRelation( xRelations, nId, rType, rTarget, bExternal );
+
+ return OUString();
+}
+
+static void
+writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const OUString& sValue )
+{
+ if( sValue.getLength() == 0 )
+ return;
+ pDoc->startElement( nXmlElement, FSEND );
+ pDoc->write( sValue );
+ pDoc->endElement( nXmlElement );
+}
+
+static void
+writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const sal_Int32 nValue )
+{
+ pDoc->startElement( nXmlElement, FSEND );
+ pDoc->write( OUString::valueOf( nValue ) );
+ pDoc->endElement( nXmlElement );
+}
+
+static void
+writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const DateTime& rTime )
+{
+ if( rTime.Year == 0 )
+ return;
+
+ if ( ( nXmlElement >> 16 ) != XML_dcterms )
+ pDoc->startElement( nXmlElement, FSEND );
+ else
+ pDoc->startElement( nXmlElement,
+ FSNS( XML_xsi, XML_type ), "dcterms:W3CDTF",
+ FSEND );
+
+ char pStr[200];
+ snprintf( pStr, sizeof( pStr ), "%d-%02d-%02dT%02d:%02d:%02d.%02dZ",
+ rTime.Year, rTime.Month, rTime.Day,
+ rTime.Hours, rTime.Minutes, rTime.Seconds,
+ rTime.HundredthSeconds );
+
+ pDoc->write( pStr );
+
+ pDoc->endElement( nXmlElement );
+}
+
+static void
+writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, Sequence< rtl::OUString > aItems )
+{
+ if( aItems.getLength() == 0 )
+ return;
+
+ OUStringBuffer sRep;
+ sRep.append( aItems[ 0 ] );
+
+ for( sal_Int32 i = 1, end = aItems.getLength(); i < end; ++i )
+ {
+ sRep.appendAscii( " " ).append( aItems[ i ] );
+ }
+
+ writeElement( pDoc, nXmlElement, sRep.makeStringAndClear() );
+}
+
+static void
+writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const Locale& rLocale )
+{
+ // TODO: what to do with .Country and .Variant
+ writeElement( pDoc, nXmlElement, rLocale.Language );
+}
+
+static void
+writeCoreProperties( XmlFilterBase& rSelf, Reference< XDocumentProperties > xProperties )
+{
+ rSelf.addRelation(
+ CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" ),
+ CREATE_OUSTRING( "docProps/core.xml" ) );
+ FSHelperPtr pCoreProps = rSelf.openFragmentStreamWithSerializer(
+ CREATE_OUSTRING( "docProps/core.xml" ),
+ CREATE_OUSTRING( "application/vnd.openxmlformats-package.core-properties+xml" ) );
+ pCoreProps->startElementNS( XML_cp, XML_coreProperties,
+ FSNS( XML_xmlns, XML_cp ), "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
+ FSNS( XML_xmlns, XML_dc ), "http://purl.org/dc/elements/1.1/",
+ FSNS( XML_xmlns, XML_dcterms ), "http://purl.org/dc/terms/",
+ FSNS( XML_xmlns, XML_dcmitype ), "http://purl.org/dc/dcmitype/",
+ FSNS( XML_xmlns, XML_xsi ), "http://www.w3.org/2001/XMLSchema-instance",
+ FSEND );
+
+#if OOXTODO
+ writeElement( pCoreProps, FSNS( XML_cp, XML_category ), "category" );
+ writeElement( pCoreProps, FSNS( XML_cp, XML_contentStatus ), "status" );
+ writeElement( pCoreProps, FSNS( XML_cp, XML_contentType ), "contentType" );
+#endif /* def OOXTODO */
+ writeElement( pCoreProps, FSNS( XML_dcterms, XML_created ), xProperties->getCreationDate() );
+ writeElement( pCoreProps, FSNS( XML_dc, XML_creator ), xProperties->getAuthor() );
+ writeElement( pCoreProps, FSNS( XML_dc, XML_description ), xProperties->getDescription() );
+#if OOXTODO
+ writeElement( pCoreProps, FSNS( XML_dc, XML_identifier ), "ident" );
+#endif /* def OOXTODO */
+ writeElement( pCoreProps, FSNS( XML_cp, XML_keywords ), xProperties->getKeywords() );
+ writeElement( pCoreProps, FSNS( XML_dc, XML_language ), xProperties->getLanguage() );
+ writeElement( pCoreProps, FSNS( XML_cp, XML_lastModifiedBy ), xProperties->getModifiedBy() );
+ writeElement( pCoreProps, FSNS( XML_cp, XML_lastPrinted ), xProperties->getPrintDate() );
+ writeElement( pCoreProps, FSNS( XML_dcterms, XML_modified ), xProperties->getModificationDate() );
+ writeElement( pCoreProps, FSNS( XML_cp, XML_revision ), xProperties->getEditingCycles() );
+ writeElement( pCoreProps, FSNS( XML_dc, XML_subject ), xProperties->getSubject() );
+ writeElement( pCoreProps, FSNS( XML_dc, XML_title ), xProperties->getTitle() );
+#if OOXTODO
+ writeElement( pCoreProps, FSNS( XML_cp, XML_version ), "version" );
+#endif /* def OOXTODO */
+
+ pCoreProps->endElementNS( XML_cp, XML_coreProperties );
+}
+
+static void
+writeAppProperties( XmlFilterBase& rSelf, Reference< XDocumentProperties > xProperties )
+{
+ rSelf.addRelation(
+ CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" ),
+ CREATE_OUSTRING( "docProps/app.xml" ) );
+ FSHelperPtr pAppProps = rSelf.openFragmentStreamWithSerializer(
+ CREATE_OUSTRING( "docProps/app.xml" ),
+ CREATE_OUSTRING( "application/vnd.openxmlformats-officedocument.extended-properties+xml" ) );
+ pAppProps->startElement( XML_Properties,
+ XML_xmlns, "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
+ FSNS( XML_xmlns, XML_vt ), "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",
+ FSEND );
+
+ writeElement( pAppProps, XML_Template, xProperties->getTemplateName() );
+#if OOXTODO
+ writeElement( pAppProps, XML_Manager, "manager" );
+ writeElement( pAppProps, XML_Company, "company" );
+ writeElement( pAppProps, XML_Pages, "pages" );
+ writeElement( pAppProps, XML_Words, "words" );
+ writeElement( pAppProps, XML_Characters, "characters" );
+ writeElement( pAppProps, XML_PresentationFormat, "presentation format" );
+ writeElement( pAppProps, XML_Lines, "lines" );
+ writeElement( pAppProps, XML_Paragraphs, "paragraphs" );
+ writeElement( pAppProps, XML_Slides, "slides" );
+ writeElement( pAppProps, XML_Notes, "notes" );
+#endif /* def OOXTODO */
+ writeElement( pAppProps, XML_TotalTime, xProperties->getEditingDuration() );
+#if OOXTODO
+ writeElement( pAppProps, XML_HiddenSlides, "hidden slides" );
+ writeElement( pAppProps, XML_MMClips, "mm clips" );
+ writeElement( pAppProps, XML_ScaleCrop, "scale crop" );
+ writeElement( pAppProps, XML_HeadingPairs, "heading pairs" );
+ writeElement( pAppProps, XML_TitlesOfParts, "titles of parts" );
+ writeElement( pAppProps, XML_LinksUpToDate, "links up-to-date" );
+ writeElement( pAppProps, XML_CharactersWithSpaces, "characters with spaces" );
+ writeElement( pAppProps, XML_SharedDoc, "shared doc" );
+ writeElement( pAppProps, XML_HyperlinkBase, "hyperlink base" );
+ writeElement( pAppProps, XML_HLinks, "hlinks" );
+ writeElement( pAppProps, XML_HyperlinksChanged, "hyperlinks changed" );
+ writeElement( pAppProps, XML_DigSig, "digital signature" );
+#endif /* def OOXTODO */
+ writeElement( pAppProps, XML_Application, xProperties->getGenerator() );
+#if OOXTODO
+ writeElement( pAppProps, XML_AppVersion, "app version" );
+ writeElement( pAppProps, XML_DocSecurity, "doc security" );
+#endif /* def OOXTODO */
+ pAppProps->endElement( XML_Properties );
+}
+
+XmlFilterBase& XmlFilterBase::exportDocumentProperties( Reference< XDocumentProperties > xProperties )
+{
+ if( xProperties.is() )
+ {
+ writeCoreProperties( *this, xProperties );
+ writeAppProperties( *this, xProperties );
+ Sequence< ::com::sun::star::beans::NamedValue > aStats = xProperties->getDocumentStatistics();
+ printf( "# Document Statistics:\n" );
+ for( sal_Int32 i = 0, end = aStats.getLength(); i < end; ++i )
+ {
+ ::com::sun::star::uno::Any aValue = aStats[ i ].Value;
+ ::rtl::OUString sValue;
+ bool bHaveString = aValue >>= sValue;
+ printf ("#\t%s=%s [%s]\n",
+ OUStringToOString( aStats[ i ].Name, RTL_TEXTENCODING_UTF8 ).getStr(),
+ bHaveString
+ ? OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr()
+ : "<unconvertable>",
+ OUStringToOString( aValue.getValueTypeName(), RTL_TEXTENCODING_UTF8 ).getStr());
+ }
+ }
+ return *this;
+}
+
+// protected ------------------------------------------------------------------
+
+Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const
+{
+ /* Get the input stream directly from the media descriptor, or decrypt the
+ package again. The latter is needed e.g. when the document is reloaded.
+ All this is implemented in the detector service. */
+ FilterDetect aDetector( getComponentContext() );
+ return aDetector.extractUnencryptedPackage( rMediaDesc );
+}
+
+// private --------------------------------------------------------------------
+
+StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
+{
+ return StorageRef( new ZipStorage( getServiceFactory(), rxInStream ) );
+}
+
+StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
+{
+ return StorageRef( new ZipStorage( getServiceFactory(), rxOutStream ) );
+}
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
diff --git a/oox/source/docprop/docprophandler.cxx b/oox/source/docprop/docprophandler.cxx
new file mode 100644
index 000000000000..560fcf141c19
--- /dev/null
+++ b/oox/source/docprop/docprophandler.cxx
@@ -0,0 +1,691 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "docprophandler.hxx"
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyExistException.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include <osl/time.h>
+
+#include "oox/helper/attributelist.hxx"
+
+using namespace ::com::sun::star;
+
+namespace oox {
+namespace docprop {
+
+// ------------------------------------------------
+OOXMLDocPropHandler::OOXMLDocPropHandler( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< document::XDocumentProperties > xDocProp )
+: m_xContext( xContext )
+, m_xDocProp( xDocProp )
+, m_nState( 0 )
+, m_nBlock( 0 )
+, m_nType( 0 )
+, m_nInBlock( 0 )
+{
+ if ( !xContext.is() || !xDocProp.is() )
+ throw uno::RuntimeException();
+}
+
+// ------------------------------------------------
+OOXMLDocPropHandler::~OOXMLDocPropHandler()
+{
+}
+
+// ------------------------------------------------
+void OOXMLDocPropHandler::InitNew()
+{
+ m_nState = 0;
+ m_nBlock = 0;
+ m_aCustomPropertyName = ::rtl::OUString();
+ m_nType = 0;
+ m_nInBlock = 0;
+}
+
+// ------------------------------------------------
+void OOXMLDocPropHandler::AddCustomProperty( const uno::Any& aAny )
+{
+ if ( m_aCustomPropertyName.getLength() )
+ {
+ const uno::Reference< beans::XPropertyContainer > xUserProps =
+ m_xDocProp->getUserDefinedProperties();
+ if ( !xUserProps.is() )
+ throw uno::RuntimeException();
+
+ try
+ {
+ xUserProps->addProperty( m_aCustomPropertyName,
+ beans::PropertyAttribute::REMOVEABLE, aAny );
+ }
+ catch( beans::PropertyExistException& )
+ {
+ // conflicts with core and extended properties are possible
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ASSERT( "Can not add custom property!" );
+ }
+ }
+}
+
+// ------------------------------------------------
+util::DateTime OOXMLDocPropHandler::GetDateTimeFromW3CDTF( const ::rtl::OUString& aChars )
+{
+ oslDateTime aOslDTime = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ sal_Int32 nLen = aChars.getLength();
+ if ( nLen >= 4 )
+ {
+ aOslDTime.Year = (sal_uInt16)aChars.copy( 0, 4 ).toInt32();
+
+ if ( nLen >= 7 && aChars.getStr()[4] == (sal_Unicode)'-' )
+ {
+ aOslDTime.Month = (sal_uInt16)aChars.copy( 5, 2 ).toInt32();
+
+ if ( nLen >= 10 && aChars.getStr()[7] == (sal_Unicode)'-' )
+ {
+ aOslDTime.Day = (sal_uInt16)aChars.copy( 8, 2 ).toInt32();
+
+ if ( nLen >= 16 && aChars.getStr()[10] == (sal_Unicode)'T' && aChars.getStr()[13] == (sal_Unicode)':' )
+ {
+ aOslDTime.Hours = (sal_uInt16)aChars.copy( 11, 2 ).toInt32();
+ aOslDTime.Minutes = (sal_uInt16)aChars.copy( 14, 2 ).toInt32();
+
+ sal_Int32 nOptTime = 0;
+ if ( nLen >= 19 && aChars.getStr()[16] == (sal_Unicode)':' )
+ {
+ aOslDTime.Seconds = (sal_uInt16)aChars.copy( 17, 2 ).toInt32();
+ nOptTime += 3;
+ if ( nLen >= 21 && aChars.getStr()[19] == (sal_Unicode)'.' )
+ {
+ aOslDTime.NanoSeconds = (sal_uInt32)(aChars.copy( 20, 1 ).toInt32() * 10e8);
+ nOptTime += 2;
+ }
+ }
+
+ sal_Int32 nModif = 0;
+ if ( nLen >= 16 + nOptTime + 6 )
+ {
+ if ( ( aChars.getStr()[16 + nOptTime] == (sal_Unicode)'+' || aChars.getStr()[16 + nOptTime] == (sal_Unicode)'-' )
+ && aChars.getStr()[16 + nOptTime + 3] == (sal_Unicode)':' )
+
+ {
+ nModif = aChars.copy( 16 + nOptTime + 1, 2 ).toInt32() * 3600;
+ nModif += aChars.copy( 16 + nOptTime + 4, 2 ).toInt32() * 60;
+ if ( aChars.getStr()[16 + nOptTime] == (sal_Unicode)'-' )
+ nModif *= -1;
+ }
+ }
+
+ if ( nModif )
+ {
+ // convert to UTC time
+ TimeValue aTmp;
+ if ( osl_getTimeValueFromDateTime( &aOslDTime, &aTmp ) )
+ {
+ aTmp.Seconds += nModif;
+ osl_getDateTimeFromTimeValue( &aTmp, &aOslDTime );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return util::DateTime( (sal_uInt16)( aOslDTime.NanoSeconds / 1e7 ), aOslDTime.Seconds, aOslDTime.Minutes, aOslDTime.Hours, aOslDTime.Day, aOslDTime.Month, aOslDTime.Year );
+}
+
+// ------------------------------------------------
+uno::Sequence< ::rtl::OUString > OOXMLDocPropHandler::GetKeywordsSet( const ::rtl::OUString& aChars )
+{
+ if ( aChars.getLength() )
+ {
+ uno::Sequence< ::rtl::OUString > aResult( 20 );
+ sal_Int32 nCounter = 0;
+
+ const sal_Unicode* pStr = aChars.getStr();
+ for( sal_Int32 nInd = 0; nInd < aChars.getLength() && pStr[nInd] != 0; nInd++ )
+ {
+ switch( pStr[nInd] )
+ {
+ case (sal_Unicode)' ':
+ case (sal_Unicode)',':
+ case (sal_Unicode)';':
+ case (sal_Unicode)':':
+ case (sal_Unicode)'\t':
+ // this is a delimiter
+ // unfortunately I did not find any specification for the possible delimiters
+ if ( aResult[nCounter].getLength() )
+ {
+ if ( nCounter >= aResult.getLength() )
+ aResult.realloc( nCounter + 10 );
+ nCounter++;
+ }
+ break;
+
+ default:
+ // this should be a part of keyword
+ aResult[nCounter] += ::rtl::OUString( (sal_Unicode)pStr[nInd] );
+ }
+ }
+
+ aResult.realloc( nCounter + 1 );
+ return aResult;
+ }
+
+ return uno::Sequence< ::rtl::OUString >();
+}
+// ------------------------------------------------
+lang::Locale OOXMLDocPropHandler::GetLanguage( const ::rtl::OUString& aChars )
+{
+ lang::Locale aResult;
+ if ( aChars.getLength() >= 2 )
+ {
+ aResult.Language = aChars.copy( 0, 2 );
+ if ( aChars.getLength() >= 5 && aChars.getStr()[2] == (sal_Unicode)'-' )
+ aResult.Country = aChars.copy( 3, 2 );
+
+ // TODO/LATER: the variant could be also detected
+ }
+
+ return aResult;
+}
+
+// ------------------------------------------------
+void OOXMLDocPropHandler::UpdateDocStatistic( const ::rtl::OUString& aChars )
+{
+ uno::Sequence< beans::NamedValue > aSet = m_xDocProp->getDocumentStatistics();
+ ::rtl::OUString aName;
+
+ switch( m_nBlock )
+ {
+ case EXTPR_TOKEN( Characters ):
+ aName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharacterCount" ) );
+ break;
+
+ case EXTPR_TOKEN( Pages ):
+ aName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageCount" ) );
+ break;
+
+ case EXTPR_TOKEN( Words ):
+ aName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WordCount" ) );
+ break;
+
+ case EXTPR_TOKEN( Paragraphs ):
+ aName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParagraphCount" ) );
+ break;
+
+ default:
+ OSL_ASSERT( "Unexpected statistic!" );
+ break;
+ }
+
+ if ( aName.getLength() )
+ {
+ sal_Bool bFound = sal_False;
+ sal_Int32 nLen = aSet.getLength();
+ for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
+ if ( aSet[nInd].Name.equals( aName ) )
+ {
+ aSet[nInd].Value = uno::makeAny( aChars.toInt32() );
+ bFound = sal_True;
+ break;
+ }
+
+ if ( !bFound )
+ {
+ aSet.realloc( nLen + 1 );
+ aSet[nLen].Name = aName;
+ aSet[nLen].Value = uno::makeAny( aChars.toInt32() );
+ }
+
+ m_xDocProp->setDocumentStatistics( aSet );
+ }
+}
+
+// ------------------------------------------------
+// com.sun.star.xml.sax.XFastDocumentHandler
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::startDocument()
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::endDocument()
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ InitNew();
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+
+// com.sun.star.xml.sax.XFastContextHandler
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::startFastElement( ::sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ if ( !m_nInBlock && !m_nState )
+ {
+ if ( nElement == COREPR_TOKEN( coreProperties )
+ || nElement == EXTPR_TOKEN( Properties )
+ || nElement == CUSTPR_TOKEN( Properties ) )
+ {
+ m_nState = nElement;
+ }
+ else
+ {
+ OSL_ASSERT( "Unexpected file format!" );
+ }
+ }
+ else if ( m_nState && m_nInBlock == 1 ) // that tag should contain the property name
+ {
+ // Currently the attributes are ignored for the core properties since the only
+ // known attribute is xsi:type that can only be used with dcterms:created and
+ // dcterms:modified, and this element is allowed currently to have only one value dcterms:W3CDTF
+ m_nBlock = nElement;
+
+ if ( xAttribs.is() && xAttribs->hasAttribute( XML_name ) )
+ m_aCustomPropertyName = xAttribs->getValue( XML_name );
+ }
+ else if ( m_nState && m_nInBlock && m_nInBlock == 2 && getNamespace( nElement ) == NMSP_officeDocPropsVT )
+ {
+ m_nType = nElement;
+ }
+ else
+ {
+ OSL_ASSERT( "For now unexpected tags are ignored!" );
+ }
+
+ if ( m_nInBlock == SAL_MAX_INT32 )
+ throw uno::RuntimeException();
+
+ m_nInBlock++;
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::startUnknownElement( const ::rtl::OUString& aNamespace, const ::rtl::OUString& aName, const uno::Reference< xml::sax::XFastAttributeList >& )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ ::rtl::OUString aUnknown = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown element" ) );
+ aUnknown += aNamespace;
+ aUnknown += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":" ) );
+ aUnknown += aName;
+ OSL_ASSERT( ::rtl::OUStringToOString( aUnknown, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ if ( m_nInBlock == SAL_MAX_INT32 )
+ throw uno::RuntimeException();
+
+ m_nInBlock++;
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::endFastElement( ::sal_Int32 )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ if ( m_nInBlock )
+ {
+ m_nInBlock--;
+
+ if ( !m_nInBlock )
+ m_nState = 0;
+ else if ( m_nInBlock == 1 )
+ {
+ m_nBlock = 0;
+ m_aCustomPropertyName = ::rtl::OUString();
+ }
+ else if ( m_nInBlock == 2 )
+ m_nType = 0;
+ }
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::endUnknownElement( const ::rtl::OUString&, const ::rtl::OUString& )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ if ( m_nInBlock )
+ m_nInBlock--;
+}
+
+// ------------------------------------------------
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL OOXMLDocPropHandler::createFastChildContext( ::sal_Int32, const uno::Reference< xml::sax::XFastAttributeList >& )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ // Should the arguments be parsed?
+ return uno::Reference< xml::sax::XFastContextHandler >( static_cast< xml::sax::XFastContextHandler* >( this ) );
+}
+
+// ------------------------------------------------
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL OOXMLDocPropHandler::createUnknownChildContext( const ::rtl::OUString&, const ::rtl::OUString&, const uno::Reference< xml::sax::XFastAttributeList >& )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ return uno::Reference< xml::sax::XFastContextHandler >( static_cast< xml::sax::XFastContextHandler* >( this ) );
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::characters( const ::rtl::OUString& aChars )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+ try
+ {
+ if ( (m_nInBlock == 2) || ((m_nInBlock == 3) && m_nType) )
+ {
+ if ( m_nState == COREPR_TOKEN( coreProperties ) )
+ {
+ switch( m_nBlock )
+ {
+ case COREPR_TOKEN( category ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "category" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case COREPR_TOKEN( contentStatus ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "contentStatus" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case COREPR_TOKEN( contentType ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "contentType" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case COREPR_TOKEN( identifier ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "identifier" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case COREPR_TOKEN( version ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "version" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case DCT_TOKEN( created ):
+ if ( aChars.getLength() >= 4 )
+ m_xDocProp->setCreationDate( GetDateTimeFromW3CDTF( aChars ) );
+ break;
+
+ case DC_TOKEN( creator ):
+ m_xDocProp->setAuthor( aChars );
+ break;
+
+ case DC_TOKEN( description ):
+ m_xDocProp->setDescription( aChars );
+ break;
+
+ case COREPR_TOKEN( keywords ):
+ m_xDocProp->setKeywords( GetKeywordsSet( aChars ) );
+ break;
+
+ case DC_TOKEN( language ):
+ if ( aChars.getLength() >= 2 )
+ m_xDocProp->setLanguage( GetLanguage( aChars ) );
+ break;
+
+ case COREPR_TOKEN( lastModifiedBy ):
+ m_xDocProp->setModifiedBy( aChars );
+ break;
+
+ case COREPR_TOKEN( lastPrinted ):
+ if ( aChars.getLength() >= 4 )
+ m_xDocProp->setPrintDate( GetDateTimeFromW3CDTF( aChars ) );
+ break;
+
+ case DCT_TOKEN( modified ):
+ if ( aChars.getLength() >= 4 )
+ m_xDocProp->setModificationDate( GetDateTimeFromW3CDTF( aChars ) );
+ break;
+
+ case COREPR_TOKEN( revision ):
+ try
+ {
+ m_xDocProp->setEditingCycles(
+ static_cast<sal_Int16>(aChars.toInt32()) );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ // ignore
+ }
+ break;
+
+ case DC_TOKEN( subject ):
+ m_xDocProp->setSubject( aChars );
+ break;
+
+ case DC_TOKEN( title ):
+ m_xDocProp->setTitle( aChars );
+ break;
+
+ default:
+ OSL_ASSERT( "Unexpected core property!" );
+ }
+ }
+ else if ( m_nState == EXTPR_TOKEN( Properties ) )
+ {
+ switch( m_nBlock )
+ {
+ case EXTPR_TOKEN( Application ):
+ m_xDocProp->setGenerator( aChars );
+ break;
+
+ case EXTPR_TOKEN( Template ):
+ m_xDocProp->setTemplateName( aChars );
+ break;
+
+ case EXTPR_TOKEN( TotalTime ):
+ try
+ {
+ m_xDocProp->setEditingDuration( aChars.toInt32() );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ // ignore
+ }
+ break;
+
+ case EXTPR_TOKEN( Characters ):
+ case EXTPR_TOKEN( Pages ):
+ case EXTPR_TOKEN( Words ):
+ case EXTPR_TOKEN( Paragraphs ):
+ UpdateDocStatistic( aChars );
+ break;
+
+ case EXTPR_TOKEN( HyperlinksChanged ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HyperlinksChanged" ) );
+ AddCustomProperty( uno::makeAny( aChars.toBoolean() ) ); // the property has boolean type
+ break;
+
+ case EXTPR_TOKEN( LinksUpToDate ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LinksUpToDate" ) );
+ AddCustomProperty( uno::makeAny( aChars.toBoolean() ) ); // the property has boolean type
+ break;
+
+ case EXTPR_TOKEN( ScaleCrop ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScaleCrop" ) );
+ AddCustomProperty( uno::makeAny( aChars.toBoolean() ) ); // the property has boolean type
+ break;
+
+ case EXTPR_TOKEN( SharedDoc ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ShareDoc" ) );
+ AddCustomProperty( uno::makeAny( aChars.toBoolean() ) ); // the property has boolean type
+ break;
+
+ case EXTPR_TOKEN( DocSecurity ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocSecurity" ) );
+ AddCustomProperty( uno::makeAny( aChars.toInt32() ) ); // the property has sal_Int32 type
+ break;
+
+ case EXTPR_TOKEN( HiddenSlides ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HiddenSlides" ) );
+ AddCustomProperty( uno::makeAny( aChars.toInt32() ) ); // the property has sal_Int32 type
+ break;
+
+ case EXTPR_TOKEN( MMClips ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MMClips" ) );
+ AddCustomProperty( uno::makeAny( aChars.toInt32() ) ); // the property has sal_Int32 type
+ break;
+
+ case EXTPR_TOKEN( Notes ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Notes" ) );
+ AddCustomProperty( uno::makeAny( aChars.toInt32() ) ); // the property has sal_Int32 type
+ break;
+
+ case EXTPR_TOKEN( Slides ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Slides" ) );
+ AddCustomProperty( uno::makeAny( aChars.toInt32() ) ); // the property has sal_Int32 type
+ break;
+
+ case EXTPR_TOKEN( AppVersion ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AppVersion" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case EXTPR_TOKEN( Company ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Company" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case EXTPR_TOKEN( HyperlinkBase ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HyperlinkBase" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case EXTPR_TOKEN( Manager ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Manager" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case EXTPR_TOKEN( PresentationFormat ):
+ m_aCustomPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PresentationFormat" ) );
+ AddCustomProperty( uno::makeAny( aChars ) ); // the property has string type
+ break;
+
+ case EXTPR_TOKEN( CharactersWithSpaces ):
+ case EXTPR_TOKEN( Lines ):
+ case EXTPR_TOKEN( DigSig ):
+ case EXTPR_TOKEN( HeadingPairs ):
+ case EXTPR_TOKEN( HLinks ):
+ case EXTPR_TOKEN( TitlesOfParts ):
+ // ignored during the import currently
+ break;
+
+ default:
+ OSL_ASSERT( "Unexpected extended property!" );
+ }
+ }
+ else if ( m_nState == CUSTPR_TOKEN( Properties ) )
+ {
+ if ( m_nBlock == CUSTPR_TOKEN( property ) )
+ {
+ // this is a custom property
+ switch( m_nType )
+ {
+ case VT_TOKEN( bool ):
+ AddCustomProperty( uno::makeAny( aChars.toBoolean() ) );
+ break;
+
+ case VT_TOKEN( bstr ):
+ case VT_TOKEN( lpstr ):
+ case VT_TOKEN( lpwstr ):
+ AddCustomProperty( uno::makeAny( AttributeConversion::decodeXString( aChars ) ) ); // the property has string type
+ break;
+
+ case VT_TOKEN( date ):
+ case VT_TOKEN( filetime ):
+ AddCustomProperty( uno::makeAny( GetDateTimeFromW3CDTF( aChars ) ) );
+
+ case VT_TOKEN( i1 ):
+ case VT_TOKEN( i2 ):
+ AddCustomProperty( uno::makeAny( (sal_Int16)aChars.toInt32() ) );
+ break;
+
+ case VT_TOKEN( i4 ):
+ case VT_TOKEN( int ):
+ AddCustomProperty( uno::makeAny( aChars.toInt32() ) );
+ break;
+
+ case VT_TOKEN( i8 ):
+ AddCustomProperty( uno::makeAny( aChars.toInt64() ) );
+ break;
+
+ case VT_TOKEN( r4 ):
+ AddCustomProperty( uno::makeAny( aChars.toFloat() ) );
+ break;
+
+ case VT_TOKEN( r8 ):
+ AddCustomProperty( uno::makeAny( aChars.toDouble() ) );
+ break;
+
+ default:
+ // all the other types are ignored;
+ break;
+ }
+ }
+ else
+ {
+ OSL_ASSERT( "Unexpected tag in custom property!" );
+ }
+ }
+ }
+ }
+ catch( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch( xml::sax::SAXException& )
+ {
+ throw;
+ }
+ catch( uno::Exception& e )
+ {
+ throw xml::sax::SAXException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Error while setting document property!" ) ),
+ uno::Reference< uno::XInterface >(),
+ uno::makeAny( e ) );
+ }
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::ignorableWhitespace( const ::rtl::OUString& )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+// ------------------------------------------------
+void SAL_CALL OOXMLDocPropHandler::processingInstruction( const ::rtl::OUString&, const ::rtl::OUString& )
+ throw (xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+} // namespace docprop
+} // namespace oox
+
diff --git a/oox/source/docprop/docprophandler.hxx b/oox/source/docprop/docprophandler.hxx
new file mode 100644
index 000000000000..13e6e47b025e
--- /dev/null
+++ b/oox/source/docprop/docprophandler.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DOCPROP_DOCPROPHANDLER_HXX
+#define OOX_DOCPROP_DOCPROPHANDLER_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+#include "oox/token/namespaces.hxx"
+#include "oox/token/tokens.hxx"
+
+namespace oox {
+namespace docprop {
+
+#define COREPR_TOKEN( token ) (::oox::NMSP_packageMetaCorePr | XML_##token)
+#define CUSTPR_TOKEN( token ) (::oox::NMSP_officeCustomPr | XML_##token)
+#define EXTPR_TOKEN( token ) (::oox::NMSP_officeExtPr | XML_##token)
+#define VT_TOKEN( token ) (::oox::NMSP_officeDocPropsVT | XML_##token)
+#define DC_TOKEN( token ) (::oox::NMSP_dc | XML_##token)
+#define DCT_TOKEN( token ) (::oox::NMSP_dcTerms | XML_##token)
+
+class OOXMLDocPropHandler : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastDocumentHandler >
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties > m_xDocProp;
+
+ sal_Int32 m_nState;
+ sal_Int32 m_nBlock;
+ sal_Int32 m_nType;
+
+ sal_Int32 m_nInBlock;
+
+ ::rtl::OUString m_aCustomPropertyName;
+
+public:
+ explicit OOXMLDocPropHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext, const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties > xDocProp );
+
+ virtual ~OOXMLDocPropHandler();
+
+ void InitNew();
+ void AddCustomProperty( const ::com::sun::star::uno::Any& aAny );
+
+ ::com::sun::star::util::DateTime GetDateTimeFromW3CDTF( const ::rtl::OUString& aChars );
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > GetKeywordsSet( const ::rtl::OUString& aChars );
+ ::com::sun::star::lang::Locale GetLanguage( const ::rtl::OUString& aChars );
+ void UpdateDocStatistic( const ::rtl::OUString& aChars );
+
+ // com.sun.star.xml.sax.XFastDocumentHandler
+
+ virtual void SAL_CALL startDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& rxLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+ // com.sun.star.xml.sax.XFastContextHandler
+
+ virtual void SAL_CALL startFastElement( ::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);
+ virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) 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);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, 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);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/docprop/makefile.mk b/oox/source/docprop/makefile.mk
new file mode 100644
index 000000000000..5687178da9e0
--- /dev/null
+++ b/oox/source/docprop/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=docprop
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/ooxmldocpropimport.obj \
+ $(SLO)$/docprophandler.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/docprop/ooxmldocpropimport.cxx b/oox/source/docprop/ooxmldocpropimport.cxx
new file mode 100644
index 000000000000..7f3a08859302
--- /dev/null
+++ b/oox/source/docprop/ooxmldocpropimport.cxx
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "ooxmldocpropimport.hxx"
+
+#include <vector>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
+#include <com/sun/star/embed/XRelationshipAccess.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include "oox/core/fastparser.hxx"
+#include "oox/core/relations.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/helper.hxx"
+#include "docprophandler.hxx"
+
+namespace oox {
+namespace docprop {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+OUString SAL_CALL DocumentPropertiesImport_getImplementationName()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.docprop.DocumentPropertiesImporter" );
+}
+
+Sequence< OUString > SAL_CALL DocumentPropertiesImport_getSupportedServiceNames()
+{
+ Sequence< OUString > aServices( 1 );
+ aServices[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.OOXMLDocumentPropertiesImporter" );
+ return aServices;
+}
+
+Reference< XInterface > SAL_CALL DocumentPropertiesImport_createInstance( const Reference< XComponentContext >& rxContext ) SAL_THROW((Exception))
+{
+ return static_cast< ::cppu::OWeakObject* >( new DocumentPropertiesImport( rxContext ) );
+}
+
+// ============================================================================
+
+namespace {
+
+Sequence< InputSource > lclGetRelatedStreams( const Reference< XStorage >& rxStorage, const OUString& rStreamType ) throw (RuntimeException)
+{
+ Reference< XRelationshipAccess > xRelation( rxStorage, UNO_QUERY_THROW );
+ Reference< XHierarchicalStorageAccess > xHierarchy( rxStorage, UNO_QUERY_THROW );
+
+ Sequence< Sequence< StringPair > > aPropsInfo = xRelation->getRelationshipsByType( rStreamType );
+
+ ::std::vector< InputSource > aResult;
+
+ for( sal_Int32 nIndex = 0, nLength = aPropsInfo.getLength(); nIndex < nLength; ++nIndex )
+ {
+ const Sequence< StringPair >& rEntries = aPropsInfo[ nIndex ];
+ for( sal_Int32 nEntryIndex = 0, nEntryLength = rEntries.getLength(); nEntryIndex < nEntryLength; ++nEntryIndex )
+ {
+ const StringPair& rEntry = rEntries[ nEntryIndex ];
+ if( rEntry.First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
+ {
+ Reference< XExtendedStorageStream > xExtStream(
+ xHierarchy->openStreamElementByHierarchicalName( rEntry.Second, ElementModes::READ ), UNO_QUERY_THROW );
+ Reference< XInputStream > xInStream = xExtStream->getInputStream();
+ if( xInStream.is() )
+ {
+ aResult.resize( aResult.size() + 1 );
+ aResult.back().sSystemId = rEntry.Second;
+ aResult.back().aInputStream = xExtStream->getInputStream();
+ }
+ break;
+ }
+ }
+ }
+
+ return ContainerHelper::vectorToSequence( aResult );
+}
+
+} // namespace
+
+// ============================================================================
+
+DocumentPropertiesImport::DocumentPropertiesImport( const Reference< XComponentContext >& rxContext ) :
+ mxContext( rxContext )
+{
+}
+
+// XServiceInfo
+
+OUString SAL_CALL DocumentPropertiesImport::getImplementationName() throw (RuntimeException)
+{
+ return DocumentPropertiesImport_getImplementationName();
+}
+
+sal_Bool SAL_CALL DocumentPropertiesImport::supportsService( const OUString& rServiceName ) throw (RuntimeException)
+{
+ Sequence< OUString > aServiceNames = DocumentPropertiesImport_getSupportedServiceNames();
+ for( sal_Int32 nIndex = 0, nLength = aServiceNames.getLength(); nIndex < nLength; ++nIndex )
+ if( aServiceNames[ nIndex ] == rServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+Sequence< OUString > SAL_CALL DocumentPropertiesImport::getSupportedServiceNames() throw (RuntimeException)
+{
+ return DocumentPropertiesImport_getSupportedServiceNames();
+}
+
+// XOOXMLDocumentPropertiesImporter
+
+void SAL_CALL DocumentPropertiesImport::importProperties(
+ const Reference< XStorage >& rxSource, const Reference< XDocumentProperties >& rxDocumentProperties )
+ throw (RuntimeException, IllegalArgumentException, SAXException, Exception)
+{
+ if( !mxContext.is() )
+ throw RuntimeException();
+
+ if( !rxSource.is() || !rxDocumentProperties.is() )
+ throw IllegalArgumentException();
+
+ Sequence< InputSource > aCoreStreams = lclGetRelatedStreams( rxSource, CREATE_OFFICEDOC_RELATION_TYPE( "metadata/core-properties" ) );
+ // MS Office seems to have a bug, so we have to do similar handling
+ if( !aCoreStreams.hasElements() )
+ aCoreStreams = lclGetRelatedStreams( rxSource, CREATE_PACKAGE_RELATION_TYPE( "metadata/core-properties" ) );
+
+ Sequence< InputSource > aExtStreams = lclGetRelatedStreams( rxSource, CREATE_OFFICEDOC_RELATION_TYPE( "extended-properties" ) );
+ Sequence< InputSource > aCustomStreams = lclGetRelatedStreams( rxSource, CREATE_OFFICEDOC_RELATION_TYPE( "custom-properties" ) );
+
+ if( aCoreStreams.hasElements() || aExtStreams.hasElements() || aCustomStreams.hasElements() )
+ {
+ if( aCoreStreams.getLength() > 1 )
+ throw IOException( CREATE_OUSTRING( "Unexpected core properties stream!" ), Reference< XInterface >() );
+
+ ::oox::core::FastParser aParser( mxContext );
+ aParser.registerNamespace( NMSP_packageMetaCorePr );
+ aParser.registerNamespace( NMSP_dc );
+ aParser.registerNamespace( NMSP_dcTerms );
+ aParser.registerNamespace( NMSP_officeExtPr );
+ aParser.registerNamespace( NMSP_officeCustomPr );
+ aParser.registerNamespace( NMSP_officeDocPropsVT );
+ aParser.setDocumentHandler( new OOXMLDocPropHandler( mxContext, rxDocumentProperties ) );
+
+ if( aCoreStreams.hasElements() )
+ aParser.parseStream( aCoreStreams[ 0 ], true );
+ for( sal_Int32 nIndex = 0; nIndex < aExtStreams.getLength(); ++nIndex )
+ aParser.parseStream( aExtStreams[ nIndex ], true );
+ for( sal_Int32 nIndex = 0; nIndex < aCustomStreams.getLength(); ++nIndex )
+ aParser.parseStream( aCustomStreams[ nIndex ], true );
+ }
+}
+
+// ============================================================================
+
+} // namespace docprop
+} // namespace oox
diff --git a/oox/source/docprop/ooxmldocpropimport.hxx b/oox/source/docprop/ooxmldocpropimport.hxx
new file mode 100644
index 000000000000..79f4d1f7e60b
--- /dev/null
+++ b/oox/source/docprop/ooxmldocpropimport.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DOCPROP_OOXMLDOCPROPIMPORT_HXX
+#define OOX_DOCPROP_OOXMLDOCPROPIMPORT_HXX
+
+#include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+namespace oox {
+namespace docprop {
+
+// ============================================================================
+
+class DocumentPropertiesImport :
+ public ::cppu::WeakImplHelper2<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::document::XOOXMLDocumentPropertiesImporter >
+{
+public:
+ explicit DocumentPropertiesImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext );
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException);
+
+ // XOOXMLDocumentPropertiesImporter
+ virtual void SAL_CALL importProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxSource,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties >& rxDocumentProperties )
+ throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::Exception);
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxContext;
+};
+
+// ============================================================================
+
+} // namespace docprop
+} // namespace oox
+
+#endif
diff --git a/oox/source/drawingml/chart/axiscontext.cxx b/oox/source/drawingml/chart/axiscontext.cxx
new file mode 100644
index 000000000000..e590bf1c64cb
--- /dev/null
+++ b/oox/source/drawingml/chart/axiscontext.cxx
@@ -0,0 +1,320 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/axiscontext.hxx"
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/chart/axismodel.hxx"
+#include "oox/drawingml/chart/titlecontext.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::oox::core::ContextHandlerRef;
+using ::oox::core::ContextHandler2Helper;
+using ::rtl::OUString;
+
+// ============================================================================
+
+AxisDispUnitsContext::AxisDispUnitsContext( ContextHandler2Helper& rParent, AxisDispUnitsModel& rModel ) :
+ ContextBase< AxisDispUnitsModel >( rParent, rModel )
+{
+}
+
+AxisDispUnitsContext::~AxisDispUnitsContext()
+{
+}
+
+ContextHandlerRef AxisDispUnitsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( dispUnits ):
+ switch( nElement )
+ {
+ case C_TOKEN( builtInUnit ):
+ mrModel.mnBuiltInUnit = rAttribs.getToken( XML_val, XML_thousands );
+ return 0;
+ case C_TOKEN( custUnit ):
+ mrModel.mfCustomUnit = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( dispUnitsLbl ):
+ return this;
+ }
+ break;
+
+ case C_TOKEN( dispUnitsLbl ):
+ switch( nElement )
+ {
+ case C_TOKEN( layout ):
+ return new LayoutContext( *this, mrModel.mxLayout.create() );
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ case C_TOKEN( tx ):
+ return new TextContext( *this, mrModel.mxText.create() );
+ case C_TOKEN( txPr ):
+ return new TextBodyContext( *this, mrModel.mxTextProp.create() );
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+AxisContextBase::AxisContextBase( ContextHandler2Helper& rParent, AxisModel& rModel ) :
+ ContextBase< AxisModel >( rParent, rModel )
+{
+}
+
+AxisContextBase::~AxisContextBase()
+{
+}
+
+ContextHandlerRef AxisContextBase::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( catAx ):
+ case C_TOKEN( dateAx ):
+ case C_TOKEN( serAx ):
+ case C_TOKEN( valAx ):
+ switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.mnAxisId = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( crossAx ):
+ mrModel.mnCrossAxisId = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( crosses ):
+ mrModel.mnCrossMode = rAttribs.getToken( XML_val, XML_autoZero );
+ return 0;
+ case C_TOKEN( crossesAt ):
+ mrModel.mofCrossesAt = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( delete ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbDeleted = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( majorGridlines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxMajorGridLines.create() );
+ case C_TOKEN( majorTickMark ):
+ // default is 'out', not 'cross' as specified
+ mrModel.mnMajorTickMark = rAttribs.getToken( XML_val, XML_out );
+ return 0;
+ case C_TOKEN( minorGridlines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxMinorGridLines.create() );
+ case C_TOKEN( minorTickMark ):
+ // default is 'none', not 'cross' as specified
+ mrModel.mnMinorTickMark = rAttribs.getToken( XML_val, XML_none );
+ return 0;
+ case C_TOKEN( numFmt ):
+ mrModel.maNumberFormat.setAttributes( rAttribs );
+ return 0;
+ case C_TOKEN( scaling ):
+ return this;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ case C_TOKEN( tickLblPos ):
+ mrModel.mnTickLabelPos = rAttribs.getToken( XML_val, XML_nextTo );
+ return 0;
+ case C_TOKEN( title ):
+ return new TitleContext( *this, mrModel.mxTitle.create() );
+ case C_TOKEN( txPr ):
+ return new TextBodyContext( *this, mrModel.mxTextProp.create() );
+ }
+ break;
+
+ case C_TOKEN( scaling ):
+ switch( nElement )
+ {
+ case C_TOKEN( logBase ):
+ mrModel.mofLogBase = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( max ):
+ mrModel.mofMax = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( min ):
+ mrModel.mofMin = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( orientation ):
+ mrModel.mnOrientation = rAttribs.getToken( XML_val, XML_minMax );
+ return 0;
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+CatAxisContext::CatAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
+ AxisContextBase( rParent, rModel )
+{
+}
+
+CatAxisContext::~CatAxisContext()
+{
+}
+
+ContextHandlerRef CatAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( auto ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbAuto = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( axPos ):
+ mrModel.mnAxisPos = rAttribs.getToken( XML_val, XML_TOKEN_INVALID );
+ return 0;
+ case C_TOKEN( lblAlgn ):
+ mrModel.mnLabelAlign = rAttribs.getToken( XML_val, XML_ctr );
+ return 0;
+ case C_TOKEN( lblOffset ):
+ mrModel.mnLabelOffset = rAttribs.getInteger( XML_val, 100 );
+ return 0;
+ case C_TOKEN( noMultiLvlLbl ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbNoMultiLevel = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( tickLblSkip ):
+ mrModel.mnTickLabelSkip = rAttribs.getInteger( XML_val, 0 );
+ return 0;
+ case C_TOKEN( tickMarkSkip ):
+ mrModel.mnTickMarkSkip = rAttribs.getInteger( XML_val, 0 );
+ return 0;
+ }
+ return AxisContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+DateAxisContext::DateAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
+ AxisContextBase( rParent, rModel )
+{
+}
+
+DateAxisContext::~DateAxisContext()
+{
+}
+
+ContextHandlerRef DateAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( auto ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbAuto = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( baseTimeUnit ):
+ mrModel.monBaseTimeUnit = rAttribs.getToken( XML_val, XML_days );
+ return 0;
+ case C_TOKEN( lblOffset ):
+ mrModel.mnLabelOffset = rAttribs.getInteger( XML_val, 100 );
+ return 0;
+ case C_TOKEN( majorTimeUnit ):
+ mrModel.mnMajorTimeUnit = rAttribs.getToken( XML_val, XML_days );
+ return 0;
+ case C_TOKEN( majorUnit ):
+ mrModel.mofMajorUnit = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( minorTimeUnit ):
+ mrModel.mnMinorTimeUnit = rAttribs.getToken( XML_val, XML_days );
+ return 0;
+ case C_TOKEN( minorUnit ):
+ mrModel.mofMinorUnit = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ }
+ return AxisContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+SerAxisContext::SerAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
+ AxisContextBase( rParent, rModel )
+{
+}
+
+SerAxisContext::~SerAxisContext()
+{
+}
+
+ContextHandlerRef SerAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( tickLblSkip ):
+ mrModel.mnTickLabelSkip = rAttribs.getInteger( XML_val, 0 );
+ return 0;
+ case C_TOKEN( tickMarkSkip ):
+ mrModel.mnTickMarkSkip = rAttribs.getInteger( XML_val, 0 );
+ return 0;
+ }
+ return AxisContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+ValAxisContext::ValAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
+ AxisContextBase( rParent, rModel )
+{
+}
+
+ValAxisContext::~ValAxisContext()
+{
+}
+
+ContextHandlerRef ValAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( crossBetween ):
+ mrModel.mnCrossBetween = rAttribs.getToken( XML_val, XML_between );
+ return 0;
+ case C_TOKEN( dispUnits ):
+ return new AxisDispUnitsContext( *this, mrModel.mxDispUnits.create() );
+ case C_TOKEN( majorUnit ):
+ mrModel.mofMajorUnit = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( minorUnit ):
+ mrModel.mofMinorUnit = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ }
+ return AxisContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/axisconverter.cxx b/oox/source/drawingml/chart/axisconverter.cxx
new file mode 100644
index 000000000000..18dc00b9d866
--- /dev/null
+++ b/oox/source/drawingml/chart/axisconverter.cxx
@@ -0,0 +1,365 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/axisconverter.hxx"
+
+#include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
+#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
+#include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
+#include <com/sun/star/chart/ChartAxisPosition.hpp>
+#include <com/sun/star/chart/TimeInterval.hpp>
+#include <com/sun/star/chart/TimeUnit.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/TickmarkStyle.hpp>
+#include <com/sun/star/chart2/XAxis.hpp>
+#include <com/sun/star/chart2/XCoordinateSystem.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include "oox/drawingml/chart/axismodel.hxx"
+#include "oox/drawingml/chart/titleconverter.hxx"
+#include "oox/drawingml/chart/typegroupconverter.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+inline void lclSetValueOrClearAny( Any& orAny, const OptValue< double >& rofValue )
+{
+ if( rofValue.has() ) orAny <<= rofValue.get(); else orAny.clear();
+}
+
+bool lclIsLogarithmicScale( const AxisModel& rAxisModel )
+{
+ return rAxisModel.mofLogBase.has() && (2.0 <= rAxisModel.mofLogBase.get()) && (rAxisModel.mofLogBase.get() <= 1000.0);
+}
+
+sal_Int32 lclGetApiTimeUnit( sal_Int32 nTimeUnit )
+{
+ using namespace ::com::sun::star::chart;
+ switch( nTimeUnit )
+ {
+ case XML_days: return TimeUnit::DAY;
+ case XML_months: return TimeUnit::MONTH;
+ case XML_years: return TimeUnit::YEAR;
+ default: OSL_ENSURE( false, "lclGetApiTimeUnit - unexpected time unit" );
+ }
+ return TimeUnit::DAY;
+}
+
+void lclConvertTimeInterval( Any& orInterval, const OptValue< double >& rofUnit, sal_Int32 nTimeUnit )
+{
+ if( rofUnit.has() && (1.0 <= rofUnit.get()) && (rofUnit.get() <= SAL_MAX_INT32) )
+ orInterval <<= ::com::sun::star::chart::TimeInterval( static_cast< sal_Int32 >( rofUnit.get() ), lclGetApiTimeUnit( nTimeUnit ) );
+ else
+ orInterval.clear();
+}
+
+::com::sun::star::chart::ChartAxisLabelPosition lclGetLabelPosition( sal_Int32 nToken )
+{
+ using namespace ::com::sun::star::chart;
+ switch( nToken )
+ {
+ case XML_high: return ChartAxisLabelPosition_OUTSIDE_END;
+ case XML_low: return ChartAxisLabelPosition_OUTSIDE_START;
+ case XML_nextTo: return ChartAxisLabelPosition_NEAR_AXIS;
+ }
+ return ChartAxisLabelPosition_NEAR_AXIS;
+}
+
+sal_Int32 lclGetTickMark( sal_Int32 nToken )
+{
+ using namespace ::com::sun::star::chart2::TickmarkStyle;
+ switch( nToken )
+ {
+ case XML_in: return INNER;
+ case XML_out: return OUTER;
+ case XML_cross: return INNER | OUTER;
+ }
+ return NONE;
+}
+
+} // namespace
+
+// ============================================================================
+
+AxisConverter::AxisConverter( const ConverterRoot& rParent, AxisModel& rModel ) :
+ ConverterBase< AxisModel >( rParent, rModel )
+{
+}
+
+AxisConverter::~AxisConverter()
+{
+}
+
+void AxisConverter::convertFromModel( const Reference< XCoordinateSystem >& rxCoordSystem,
+ TypeGroupConverter& rTypeGroup, const AxisModel* pCrossingAxis, sal_Int32 nAxesSetIdx, sal_Int32 nAxisIdx )
+{
+ Reference< XAxis > xAxis;
+ try
+ {
+ namespace cssc = ::com::sun::star::chart;
+ namespace cssc2 = ::com::sun::star::chart2;
+
+ const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
+ ObjectFormatter& rFormatter = getFormatter();
+
+ // create the axis object (always)
+ xAxis.set( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Axis" ) ), UNO_QUERY_THROW );
+ PropertySet aAxisProp( xAxis );
+ // #i58688# axis enabled
+ aAxisProp.setProperty( PROP_Show, !mrModel.mbDeleted );
+
+ // axis line, tick, and gridline properties ---------------------------
+
+ // show axis labels
+ aAxisProp.setProperty( PROP_DisplayLabels, mrModel.mnTickLabelPos != XML_none );
+ aAxisProp.setProperty( PROP_LabelPosition, lclGetLabelPosition( mrModel.mnTickLabelPos ) );
+ // no X axis line in radar charts
+ if( (nAxisIdx == API_X_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_RADAR) )
+ mrModel.mxShapeProp.getOrCreate().getLineProperties().maLineFill.moFillType = XML_noFill;
+ // axis line and tick label formatting
+ rFormatter.convertFormatting( aAxisProp, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_AXIS );
+ // tick label rotation
+ rFormatter.convertTextRotation( aAxisProp, mrModel.mxTextProp, true );
+
+ // tick mark style
+ aAxisProp.setProperty( PROP_MajorTickmarks, lclGetTickMark( mrModel.mnMajorTickMark ) );
+ aAxisProp.setProperty( PROP_MinorTickmarks, lclGetTickMark( mrModel.mnMinorTickMark ) );
+ aAxisProp.setProperty( PROP_MarkPosition, cssc::ChartAxisMarkPosition_AT_AXIS );
+
+ // main grid
+ PropertySet aGridProp( xAxis->getGridProperties() );
+ aGridProp.setProperty( PROP_Show, mrModel.mxMajorGridLines.is() );
+ if( mrModel.mxMajorGridLines.is() )
+ rFormatter.convertFrameFormatting( aGridProp, mrModel.mxMajorGridLines, OBJECTTYPE_MAJORGRIDLINE );
+
+ // sub grid
+ Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
+ if( aSubGridPropSeq.hasElements() )
+ {
+ PropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
+ aSubGridProp.setProperty( PROP_Show, mrModel.mxMinorGridLines.is() );
+ if( mrModel.mxMinorGridLines.is() )
+ rFormatter.convertFrameFormatting( aSubGridProp, mrModel.mxMinorGridLines, OBJECTTYPE_MINORGRIDLINE );
+ }
+
+ // axis type and X axis categories ------------------------------------
+
+ ScaleData aScaleData = xAxis->getScaleData();
+ // set axis type
+ switch( nAxisIdx )
+ {
+ case API_X_AXIS:
+ if( rTypeInfo.mbCategoryAxis )
+ {
+ OSL_ENSURE( (mrModel.mnTypeId == C_TOKEN( catAx )) || (mrModel.mnTypeId == C_TOKEN( dateAx )),
+ "AxisConverter::convertFromModel - unexpected axis model type (must: c:catAx or c:dateAx)" );
+ bool bDateAxis = mrModel.mnTypeId == C_TOKEN( dateAx );
+ /* Chart2 requires axis type CATEGORY for automatic
+ category/date axis (even if it is a date axis
+ currently). */
+ aScaleData.AxisType = (bDateAxis && !mrModel.mbAuto) ? cssc2::AxisType::DATE : cssc2::AxisType::CATEGORY;
+ aScaleData.AutoDateAxis = mrModel.mbAuto;
+ aScaleData.Categories = rTypeGroup.createCategorySequence();
+ }
+ else
+ {
+ OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( valAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:valAx)" );
+ aScaleData.AxisType = cssc2::AxisType::REALNUMBER;
+ }
+ break;
+ case API_Y_AXIS:
+ OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( valAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:valAx)" );
+ aScaleData.AxisType = rTypeGroup.isPercent() ? cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER;
+ break;
+ case API_Z_AXIS:
+ OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( serAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:serAx)" );
+ OSL_ENSURE( rTypeGroup.isDeep3dChart(), "AxisConverter::convertFromModel - series axis not supported by this chart type" );
+ aScaleData.AxisType = cssc2::AxisType::SERIES;
+ break;
+ }
+
+ // axis scaling and increment -----------------------------------------
+
+ switch( aScaleData.AxisType )
+ {
+ case cssc2::AxisType::CATEGORY:
+ case cssc2::AxisType::SERIES:
+ case cssc2::AxisType::DATE:
+ {
+ /* Determine date axis type from XML type identifier, and not
+ via aScaleData.AxisType, as this value sticks to CATEGORY
+ for automatic category/date axes). */
+ if( mrModel.mnTypeId == C_TOKEN( dateAx ) )
+ {
+ // scaling algorithm
+ aScaleData.Scaling.set( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.LinearScaling" ) ), UNO_QUERY );
+ // min/max
+ lclSetValueOrClearAny( aScaleData.Minimum, mrModel.mofMin );
+ lclSetValueOrClearAny( aScaleData.Maximum, mrModel.mofMax );
+ // major/minor increment
+ lclConvertTimeInterval( aScaleData.TimeIncrement.MajorTimeInterval, mrModel.mofMajorUnit, mrModel.mnMajorTimeUnit );
+ lclConvertTimeInterval( aScaleData.TimeIncrement.MinorTimeInterval, mrModel.mofMinorUnit, mrModel.mnMinorTimeUnit );
+ // base time unit
+ if( mrModel.monBaseTimeUnit.has() )
+ aScaleData.TimeIncrement.TimeResolution <<= lclGetApiTimeUnit( mrModel.monBaseTimeUnit.get() );
+ else
+ aScaleData.TimeIncrement.TimeResolution.clear();
+ }
+ else
+ {
+ // do not overlap text unless all labels are visible
+ aAxisProp.setProperty( PROP_TextOverlap, mrModel.mnTickLabelSkip == 1 );
+ // do not break text into several lines
+ aAxisProp.setProperty( PROP_TextBreak, false );
+ // do not stagger labels in two lines
+ aAxisProp.setProperty( PROP_ArrangeOrder, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
+ //! TODO #i58731# show n-th category
+ }
+ }
+ break;
+ case cssc2::AxisType::REALNUMBER:
+ case cssc2::AxisType::PERCENT:
+ {
+ // scaling algorithm
+ bool bLogScale = lclIsLogarithmicScale( mrModel );
+ OUString aScalingService = bLogScale ?
+ CREATE_OUSTRING( "com.sun.star.chart2.LogarithmicScaling" ) :
+ CREATE_OUSTRING( "com.sun.star.chart2.LinearScaling" );
+ aScaleData.Scaling.set( createInstance( aScalingService ), UNO_QUERY );
+ // min/max
+ lclSetValueOrClearAny( aScaleData.Minimum, mrModel.mofMin );
+ lclSetValueOrClearAny( aScaleData.Maximum, mrModel.mofMax );
+ // major increment
+ IncrementData& rIncrementData = aScaleData.IncrementData;
+ if( mrModel.mofMajorUnit.has() && aScaleData.Scaling.is() )
+ rIncrementData.Distance <<= aScaleData.Scaling->doScaling( mrModel.mofMajorUnit.get() );
+ else
+ lclSetValueOrClearAny( rIncrementData.Distance, mrModel.mofMajorUnit );
+ // minor increment
+ Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
+ rSubIncrementSeq.realloc( 1 );
+ Any& rIntervalCount = rSubIncrementSeq[ 0 ].IntervalCount;
+ rIntervalCount.clear();
+ if( bLogScale )
+ {
+ if( mrModel.mofMinorUnit.has() )
+ rIntervalCount <<= sal_Int32( 9 );
+ }
+ else if( mrModel.mofMajorUnit.has() && mrModel.mofMinorUnit.has() && (0.0 < mrModel.mofMinorUnit.get()) && (mrModel.mofMinorUnit.get() <= mrModel.mofMajorUnit.get()) )
+ {
+ double fCount = mrModel.mofMajorUnit.get() / mrModel.mofMinorUnit.get() + 0.5;
+ if( (1.0 <= fCount) && (fCount < 1001.0) )
+ rIntervalCount <<= static_cast< sal_Int32 >( fCount );
+ }
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "AxisConverter::convertFromModel - unknown axis type" );
+ }
+
+ /* Do not set a value to the Origin member anymore (already done via
+ new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
+ aScaleData.Origin.clear();
+
+ // axis orientation ---------------------------------------------------
+
+ // #i85167# pie/donut charts need opposite direction at Y axis
+ // #i87747# radar charts need opposite direction at X axis
+ bool bMirrorDirection =
+ ((nAxisIdx == API_Y_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_PIE)) ||
+ ((nAxisIdx == API_X_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_RADAR));
+ bool bReverse = (mrModel.mnOrientation == XML_maxMin) != bMirrorDirection;
+ aScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
+
+ // write back scaling data
+ xAxis->setScaleData( aScaleData );
+
+ // number format ------------------------------------------------------
+
+ if( (aScaleData.AxisType == cssc2::AxisType::REALNUMBER) || (aScaleData.AxisType == cssc2::AxisType::PERCENT) )
+ getFormatter().convertNumberFormat( aAxisProp, mrModel.maNumberFormat );
+
+ // position of crossing axis ------------------------------------------
+
+ bool bManualCrossing = mrModel.mofCrossesAt.has();
+ cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
+ if( !bManualCrossing ) switch( mrModel.mnCrossMode )
+ {
+ case XML_min: eAxisPos = cssc::ChartAxisPosition_START; break;
+ case XML_max: eAxisPos = cssc::ChartAxisPosition_END; break;
+ case XML_autoZero: eAxisPos = cssc::ChartAxisPosition_VALUE; break;
+ }
+ aAxisProp.setProperty( PROP_CrossoverPosition, eAxisPos );
+
+ // calculate automatic origin depending on scaling mode of crossing axis
+ bool bCrossingLogScale = pCrossingAxis && lclIsLogarithmicScale( *pCrossingAxis );
+ double fCrossingPos = bManualCrossing ? mrModel.mofCrossesAt.get() : (bCrossingLogScale ? 1.0 : 0.0);
+ aAxisProp.setProperty( PROP_CrossoverValue, fCrossingPos );
+
+ // axis title ---------------------------------------------------------
+
+ // in radar charts, title objects may exist, but are not shown
+ if( mrModel.mxTitle.is() && (rTypeGroup.getTypeInfo().meTypeCategory != TYPECATEGORY_RADAR) )
+ {
+ Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
+ TitleConverter aTitleConv( *this, *mrModel.mxTitle );
+ aTitleConv.convertFromModel( xTitled, CREATE_OUSTRING( "Axis Title" ), OBJECTTYPE_AXISTITLE, nAxesSetIdx, nAxisIdx );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( xAxis.is() && rxCoordSystem.is() ) try
+ {
+ // insert axis into coordinate system
+ rxCoordSystem->setAxisByDimension( nAxisIdx, xAxis, nAxesSetIdx );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "AxisConverter::convertFromModel - cannot insert axis into coordinate system" );
+ }
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/axismodel.cxx b/oox/source/drawingml/chart/axismodel.cxx
new file mode 100644
index 000000000000..c1bec6c1e1be
--- /dev/null
+++ b/oox/source/drawingml/chart/axismodel.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/axismodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+AxisDispUnitsModel::AxisDispUnitsModel() :
+ mfCustomUnit( 0.0 ),
+ mnBuiltInUnit( XML_TOKEN_INVALID )
+{
+}
+
+AxisDispUnitsModel::~AxisDispUnitsModel()
+{
+}
+
+// ============================================================================
+
+AxisModel::AxisModel( sal_Int32 nTypeId ) :
+ mnAxisId( -1 ),
+ mnAxisPos( XML_TOKEN_INVALID ),
+ mnCrossAxisId( -1 ),
+ mnCrossBetween( XML_between ),
+ mnCrossMode( XML_autoZero ),
+ mnLabelAlign( XML_ctr ),
+ mnLabelOffset( 100 ),
+ mnMajorTickMark( XML_out ),
+ mnMajorTimeUnit( XML_days ),
+ mnMinorTickMark( XML_none ),
+ mnMinorTimeUnit( XML_days ),
+ mnOrientation( XML_minMax ),
+ mnTickLabelPos( XML_nextTo ),
+ mnTickLabelSkip( 0 ),
+ mnTickMarkSkip( 0 ),
+ mnTypeId( nTypeId ),
+ mbAuto( false ),
+ mbDeleted( false ),
+ mbNoMultiLevel( false )
+{
+}
+
+AxisModel::~AxisModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/chartcontextbase.cxx b/oox/source/drawingml/chart/chartcontextbase.cxx
new file mode 100644
index 000000000000..69c1f2622b46
--- /dev/null
+++ b/oox/source/drawingml/chart/chartcontextbase.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/chartcontextbase.hxx"
+
+#include "oox/drawingml/chart/modelbase.hxx"
+#include "oox/drawingml/shapepropertiescontext.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+
+// ============================================================================
+
+ShapePrWrapperContext::ShapePrWrapperContext( ContextHandler2Helper& rParent, Shape& rModel ) :
+ ContextBase< Shape >( rParent, rModel )
+{
+}
+
+ShapePrWrapperContext::~ShapePrWrapperContext()
+{
+}
+
+ContextHandlerRef ShapePrWrapperContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ return (isRootElement() && (nElement == C_TOKEN( spPr ))) ? new ShapePropertiesContext( *this, mrModel ) : 0;
+}
+
+// ============================================================================
+
+LayoutContext::LayoutContext( ContextHandler2Helper& rParent, LayoutModel& rModel ) :
+ ContextBase< LayoutModel >( rParent, rModel )
+{
+}
+
+LayoutContext::~LayoutContext()
+{
+}
+
+ContextHandlerRef LayoutContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( layout ):
+ switch( nElement )
+ {
+ case C_TOKEN( manualLayout ):
+ mrModel.mbAutoLayout = false;
+ return this;
+ }
+ break;
+
+ case C_TOKEN( manualLayout ):
+ switch( nElement )
+ {
+ case C_TOKEN( x ):
+ mrModel.mfX = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( y ):
+ mrModel.mfY = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( w ):
+ mrModel.mfW = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( h ):
+ mrModel.mfH = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( xMode ):
+ mrModel.mnXMode = rAttribs.getToken( XML_val, XML_factor );
+ return 0;
+ case C_TOKEN( yMode ):
+ mrModel.mnYMode = rAttribs.getToken( XML_val, XML_factor );
+ return 0;
+ case C_TOKEN( wMode ):
+ mrModel.mnWMode = rAttribs.getToken( XML_val, XML_factor );
+ return 0;
+ case C_TOKEN( hMode ):
+ mrModel.mnHMode = rAttribs.getToken( XML_val, XML_factor );
+ return 0;
+ case C_TOKEN( layoutTarget ):
+ mrModel.mnTarget = rAttribs.getToken( XML_val, XML_outer );
+ return 0;
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/chartconverter.cxx b/oox/source/drawingml/chart/chartconverter.cxx
new file mode 100644
index 000000000000..02672088c763
--- /dev/null
+++ b/oox/source/drawingml/chart/chartconverter.cxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/chartconverter.hxx"
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include "oox/drawingml/chart/chartspaceconverter.hxx"
+#include "oox/drawingml/chart/chartspacemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::chart2::data;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::XmlFilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
+ChartConverter::ChartConverter()
+{
+}
+
+ChartConverter::~ChartConverter()
+{
+}
+
+void ChartConverter::convertFromModel( XmlFilterBase& rFilter,
+ ChartSpaceModel& rChartModel, const Reference< XChartDocument >& rxChartDoc,
+ const Reference< XShapes >& rxExternalPage, const Point& rChartPos, const Size& rChartSize )
+{
+ OSL_ENSURE( rxChartDoc.is(), "ChartConverter::convertFromModel - missing chart document" );
+ if( rxChartDoc.is() )
+ {
+ ConverterRoot aConvBase( rFilter, *this, rChartModel, rxChartDoc, rChartSize );
+ ChartSpaceConverter aSpaceConv( aConvBase, rChartModel );
+ aSpaceConv.convertFromModel( rxExternalPage, rChartPos );
+ }
+}
+
+void ChartConverter::createDataProvider( const Reference< XChartDocument >& rxChartDoc )
+{
+ try
+ {
+ if( !rxChartDoc->hasInternalDataProvider() )
+ rxChartDoc->createInternalDataProvider( sal_False );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+Reference< XDataSequence > ChartConverter::createDataSequence( const Reference< XDataProvider >&, const DataSequenceModel& )
+{
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/chartdrawingfragment.cxx b/oox/source/drawingml/chart/chartdrawingfragment.cxx
new file mode 100644
index 000000000000..03c634453e8b
--- /dev/null
+++ b/oox/source/drawingml/chart/chartdrawingfragment.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/chartdrawingfragment.hxx"
+
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/connectorshapecontext.hxx"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/drawingml/shapecontext.hxx"
+#include "oox/drawingml/shapegroupcontext.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+ShapeAnchor::ShapeAnchor( bool bRelSize ) :
+ mbRelSize( bRelSize )
+{
+}
+
+void ShapeAnchor::importExt( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( !mbRelSize, "ShapeAnchor::importExt - unexpected 'cdr:ext' element" );
+ maSize.Width = rAttribs.getHyper( XML_cx, 0 );
+ maSize.Height = rAttribs.getHyper( XML_cy, 0 );
+}
+
+void ShapeAnchor::setPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue )
+{
+ AnchorPosModel* pAnchorPos = 0;
+ switch( nParentContext )
+ {
+ case CDR_TOKEN( from ):
+ pAnchorPos = &maFrom;
+ break;
+ case CDR_TOKEN( to ):
+ OSL_ENSURE( mbRelSize, "ShapeAnchor::setPos - unexpected 'cdr:to' element" );
+ pAnchorPos = &maTo;
+ break;
+ default:
+ OSL_ENSURE( false, "ShapeAnchor::setPos - unexpected parent element" );
+ }
+ if( pAnchorPos ) switch( nElement )
+ {
+ case CDR_TOKEN( x ): pAnchorPos->mfX = rValue.toDouble(); break;
+ case CDR_TOKEN( y ): pAnchorPos->mfY = rValue.toDouble(); break;
+ default: OSL_ENSURE( false, "ShapeAnchor::setPos - unexpected element" );
+ }
+}
+
+Rectangle ShapeAnchor::calcEmuLocation( const EmuRectangle& rEmuChartRect ) const
+{
+ Rectangle aLoc( -1, -1, -1, -1 );
+
+ OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcEmuLocation - invalid from position" );
+ OSL_ENSURE( mbRelSize ? maTo.isValid() : maSize.isValid(), "ShapeAnchor::calcEmuLocation - invalid to/size" );
+ if( maFrom.isValid() && (mbRelSize ? maTo.isValid() : maSize.isValid()) )
+ {
+ // calculate shape position
+ aLoc.X = getLimitedValue< sal_Int32, double >( maFrom.mfX * rEmuChartRect.Width, 0, SAL_MAX_INT32 );
+ aLoc.Y = getLimitedValue< sal_Int32, double >( maFrom.mfY * rEmuChartRect.Height, 0, SAL_MAX_INT32 );
+
+ // calculate shape size
+ if( mbRelSize )
+ {
+ aLoc.Width = getLimitedValue< sal_Int32, double >( maTo.mfX * rEmuChartRect.Width, 0, SAL_MAX_INT32 ) - aLoc.X;
+ if( aLoc.Width < 0 )
+ {
+ aLoc.X += aLoc.Width;
+ aLoc.Width *= -1;
+ }
+ aLoc.Height = getLimitedValue< sal_Int32, double >( maTo.mfY * rEmuChartRect.Height, 0, SAL_MAX_INT32 ) - aLoc.Y;
+ if( aLoc.Height < 0 )
+ {
+ aLoc.Y += aLoc.Height;
+ aLoc.Height *= -1;
+ }
+ }
+ else
+ {
+ aLoc.Width = getLimitedValue< sal_Int32, sal_Int64 >( maSize.Width, 0, SAL_MAX_INT32 );
+ aLoc.Height = getLimitedValue< sal_Int32, sal_Int64 >( maSize.Height, 0, SAL_MAX_INT32 );
+ }
+ }
+
+ return aLoc;
+}
+// ============================================================================
+
+ChartDrawingFragment::ChartDrawingFragment( XmlFilterBase& rFilter,
+ const OUString& rFragmentPath, const Reference< XShapes >& rxDrawPage,
+ const Size& rChartSize, const Point& rShapesOffset, bool bOleSupport ) :
+ FragmentHandler2( rFilter, rFragmentPath ),
+ mxDrawPage( rxDrawPage ),
+ mbOleSupport( bOleSupport )
+{
+ maEmuChartRect.X = static_cast< sal_Int64 >( rShapesOffset.X ) * 360;
+ maEmuChartRect.Y = static_cast< sal_Int64 >( rShapesOffset.Y ) * 360;
+ maEmuChartRect.Width = static_cast< sal_Int64 >( rChartSize.Width ) * 360;
+ maEmuChartRect.Height = static_cast< sal_Int64 >( rChartSize.Height ) * 360;
+}
+
+ChartDrawingFragment::~ChartDrawingFragment()
+{
+}
+
+ContextHandlerRef ChartDrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == C_TOKEN( userShapes ) ) return this;
+ break;
+
+ case C_TOKEN( userShapes ):
+ switch( nElement )
+ {
+ case CDR_TOKEN( absSizeAnchor ):
+ mxAnchor.reset( new ShapeAnchor( false ) );
+ return this;
+ case CDR_TOKEN( relSizeAnchor ):
+ mxAnchor.reset( new ShapeAnchor( true ) );
+ return this;
+ }
+ break;
+
+ case CDR_TOKEN( absSizeAnchor ):
+ case CDR_TOKEN( relSizeAnchor ):
+ switch( nElement )
+ {
+ case CDR_TOKEN( sp ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.CustomShape" ) );
+ return new ShapeContext( *this, ShapePtr(), mxShape );
+ case CDR_TOKEN( cxnSp ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.ConnectorShape" ) );
+ return new ConnectorShapeContext( *this, ShapePtr(), mxShape );
+ case CDR_TOKEN( pic ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) );
+ return new GraphicShapeContext( *this, ShapePtr(), mxShape );
+ case CDR_TOKEN( graphicFrame ):
+ if( !mbOleSupport )
+ return 0;
+ mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) );
+ return new GraphicalObjectFrameContext( *this, ShapePtr(), mxShape, true );
+ case CDR_TOKEN( grpSp ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.GroupShape" ) );
+ return new ShapeGroupContext( *this, ShapePtr(), mxShape );
+
+ case CDR_TOKEN( from ):
+ case CDR_TOKEN( to ):
+ return this;
+
+ case CDR_TOKEN( ext ):
+ if( mxAnchor.get() ) mxAnchor->importExt( rAttribs );
+ return 0;
+ }
+ break;
+
+ case CDR_TOKEN( from ):
+ case CDR_TOKEN( to ):
+ switch( nElement )
+ {
+ case CDR_TOKEN( x ):
+ case CDR_TOKEN( y ):
+ return this; // collect value in onEndElement()
+ }
+ break;
+ }
+ return 0;
+}
+
+void ChartDrawingFragment::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( CDR_TOKEN( x ), CDR_TOKEN( y ) ) && mxAnchor.get() )
+ mxAnchor->setPos( getCurrentElement(), getParentElement(), rChars );
+}
+
+void ChartDrawingFragment::onEndElement()
+{
+ if( isCurrentElement( CDR_TOKEN( absSizeAnchor ), CDR_TOKEN( relSizeAnchor ) ) )
+ {
+ if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() )
+ {
+ Rectangle aLoc = mxAnchor->calcEmuLocation( maEmuChartRect );
+ if( (aLoc.X >= 0) && (aLoc.Y >= 0) && (aLoc.Width >= 0) && (aLoc.Height >= 0) )
+ mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aLoc );
+ }
+ mxShape.reset();
+ mxAnchor.reset();
+ }
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/chartspaceconverter.cxx b/oox/source/drawingml/chart/chartspaceconverter.cxx
new file mode 100644
index 000000000000..bfcad1b43d04
--- /dev/null
+++ b/oox/source/drawingml/chart/chartspaceconverter.cxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/chartspaceconverter.hxx"
+
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/chart/chartconverter.hxx"
+#include "oox/drawingml/chart/chartdrawingfragment.hxx"
+#include "oox/drawingml/chart/chartspacemodel.hxx"
+#include "oox/drawingml/chart/plotareaconverter.hxx"
+#include "oox/drawingml/chart/titleconverter.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::awt::Point;
+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::uno::makeAny;
+using ::com::sun::star::util::XNumberFormatsSupplier;
+using ::com::sun::star::drawing::XDrawPageSupplier;
+using ::com::sun::star::drawing::XShapes;
+using ::com::sun::star::chart2::XDiagram;
+using ::com::sun::star::chart2::XTitled;
+using ::com::sun::star::chart2::data::XDataReceiver;
+using ::com::sun::star::beans::XPropertySet;
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::chart2::data;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+ChartSpaceConverter::ChartSpaceConverter( const ConverterRoot& rParent, ChartSpaceModel& rModel ) :
+ ConverterBase< ChartSpaceModel >( rParent, rModel )
+{
+}
+
+ChartSpaceConverter::~ChartSpaceConverter()
+{
+}
+
+void ChartSpaceConverter::convertFromModel( const Reference< XShapes >& rxExternalPage, const Point& rChartPos )
+{
+ /* create data provider (virtual function in the ChartConverter class,
+ derived converters may create an external data provider) */
+ getChartConverter().createDataProvider( getChartDocument() );
+
+ // attach number formatter of container document to data receiver
+ try
+ {
+ Reference< XDataReceiver > xDataRec( getChartDocument(), UNO_QUERY_THROW );
+ Reference< XNumberFormatsSupplier > xNumFmtSupp( getFilter().getModel(), UNO_QUERY_THROW );
+ xDataRec->attachNumberFormatsSupplier( xNumFmtSupp );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // formatting of the chart background
+ PropertySet aBackPropSet( getChartDocument()->getPageBackground() );
+ getFormatter().convertFrameFormatting( aBackPropSet, mrModel.mxShapeProp, OBJECTTYPE_CHARTSPACE );
+
+ // convert plot area (container of all chart type groups)
+ PlotAreaConverter aPlotAreaConv( *this, mrModel.mxPlotArea.getOrCreate() );
+ aPlotAreaConv.convertFromModel( mrModel.mxView3D.getOrCreate() );
+
+ // plot area converter has created the diagram object
+ Reference< XDiagram > xDiagram = getChartDocument()->getFirstDiagram();
+
+ // convert wall and floor formatting in 3D charts
+ if( xDiagram.is() && aPlotAreaConv.isWall3dChart() )
+ {
+ WallFloorConverter aFloorConv( *this, mrModel.mxFloor.getOrCreate() );
+ aFloorConv.convertFromModel( xDiagram, OBJECTTYPE_FLOOR );
+
+ WallFloorConverter aWallConv( *this, mrModel.mxBackWall.getOrCreate() );
+ aWallConv.convertFromModel( xDiagram, OBJECTTYPE_WALL );
+ }
+
+ // chart title
+ if( !mrModel.mbAutoTitleDel ) try
+ {
+ /* If the title model is missing, but the chart shows exactly one
+ series, the series title is shown as chart title. */
+ OUString aAutoTitle = aPlotAreaConv.getAutomaticTitle();
+ if( mrModel.mxTitle.is() || (aAutoTitle.getLength() > 0) )
+ {
+ if( aAutoTitle.getLength() == 0 )
+ aAutoTitle = CREATE_OUSTRING( "Chart Title" );
+ Reference< XTitled > xTitled( getChartDocument(), UNO_QUERY_THROW );
+ TitleConverter aTitleConv( *this, mrModel.mxTitle.getOrCreate() );
+ aTitleConv.convertFromModel( xTitled, aAutoTitle, OBJECTTYPE_CHARTTITLE );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ // legend
+ if( xDiagram.is() && mrModel.mxLegend.is() )
+ {
+ LegendConverter aLegendConv( *this, *mrModel.mxLegend );
+ aLegendConv.convertFromModel( xDiagram );
+ }
+
+ // treatment of missing values
+ if( xDiagram.is() )
+ {
+ using namespace ::com::sun::star::chart::MissingValueTreatment;
+ sal_Int32 nMissingValues = LEAVE_GAP;
+ switch( mrModel.mnDispBlanksAs )
+ {
+ case XML_gap: nMissingValues = LEAVE_GAP; break;
+ case XML_zero: nMissingValues = USE_ZERO; break;
+ case XML_span: nMissingValues = CONTINUE; break;
+ }
+ PropertySet aDiaProp( xDiagram );
+ aDiaProp.setProperty( PROP_MissingValueTreatment, nMissingValues );
+ }
+
+ /* Following all conversions needing the old Chart1 API that involves full
+ initialization of the chart view. */
+ namespace cssc = ::com::sun::star::chart;
+ Reference< cssc::XChartDocument > xChart1Doc( getChartDocument(), UNO_QUERY );
+ if( xChart1Doc.is() )
+ {
+ /* Set the IncludeHiddenCells property via the old API as only this
+ ensures that the data provider and all created sequences get this
+ flag correctly. */
+ PropertySet aDiaProp( xChart1Doc->getDiagram() );
+ aDiaProp.setProperty( PROP_IncludeHiddenCells, !mrModel.mbPlotVisOnly );
+
+ // plot area position and size
+ aPlotAreaConv.convertPositionFromModel();
+
+ // positions of main title and all axis titles
+ convertTitlePositions();
+ }
+
+ // embedded drawing shapes
+ if( mrModel.maDrawingPath.getLength() > 0 ) try
+ {
+ /* Get the internal draw page of the chart document, if no external
+ drawing page has been passed. */
+ Reference< XShapes > xShapes;
+ Point aShapesOffset( 0, 0 );
+ if( rxExternalPage.is() )
+ {
+ xShapes = rxExternalPage;
+ // offset for embedded shapes to move them inside the chart area
+ aShapesOffset = rChartPos;
+ }
+ else
+ {
+ Reference< XDrawPageSupplier > xDrawPageSupp( getChartDocument(), UNO_QUERY_THROW );
+ xShapes.set( xDrawPageSupp->getDrawPage(), UNO_QUERY_THROW );
+ }
+
+ /* If an external drawing page is passed, all embedded shapes will be
+ inserted there (used e.g. with 'chart sheets' in spreadsheet
+ documents). In this case, all types of shapes including OLE objects
+ are supported. If the shapes are inserted into the internal chart
+ drawing page instead, it is not possible to embed OLE objects. */
+ bool bOleSupport = rxExternalPage.is();
+
+ // now, xShapes is not null anymore
+ getFilter().importFragment( new ChartDrawingFragment(
+ getFilter(), mrModel.maDrawingPath, xShapes, getChartSize(), aShapesOffset, bOleSupport ) );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // pivot chart
+ if ( mrModel.mbPivotChart )
+ {
+ PropertySet aProps( getChartDocument() );
+ aProps.setProperty( PROP_DisableDataTableDialog , true );
+ aProps.setProperty( PROP_DisableComplexChartTypes , true );
+ }
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/chartspacefragment.cxx b/oox/source/drawingml/chart/chartspacefragment.cxx
new file mode 100644
index 000000000000..06da27c02d01
--- /dev/null
+++ b/oox/source/drawingml/chart/chartspacefragment.cxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/chartspacefragment.hxx"
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/chart/chartspacemodel.hxx"
+#include "oox/drawingml/chart/plotareacontext.hxx"
+#include "oox/drawingml/chart/titlecontext.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+ChartSpaceFragment::ChartSpaceFragment( XmlFilterBase& rFilter, const OUString& rFragmentPath, ChartSpaceModel& rModel ) :
+ FragmentBase< ChartSpaceModel >( rFilter, rFragmentPath, rModel )
+{
+}
+
+ChartSpaceFragment::~ChartSpaceFragment()
+{
+}
+
+ContextHandlerRef ChartSpaceFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ switch( nElement )
+ {
+ case C_TOKEN( chartSpace ):
+ return this;
+ }
+ break;
+
+ case C_TOKEN( chartSpace ):
+ switch( nElement )
+ {
+ case C_TOKEN( chart ):
+ return this;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ case C_TOKEN( style ):
+ mrModel.mnStyle = rAttribs.getInteger( XML_val, 2 );
+ return 0;
+ case C_TOKEN( txPr ):
+ return new TextBodyContext( *this, mrModel.mxTextProp.create() );
+ case C_TOKEN( userShapes ):
+ mrModel.maDrawingPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ return 0;
+ case C_TOKEN( pivotSource ):
+ mrModel.mbPivotChart = true;
+ return 0;
+ }
+ break;
+
+ case C_TOKEN( chart ):
+ switch( nElement )
+ {
+ case C_TOKEN( autoTitleDeleted ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbAutoTitleDel = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( backWall ):
+ return new WallFloorContext( *this, mrModel.mxBackWall.create() );
+ case C_TOKEN( dispBlanksAs ):
+ mrModel.mnDispBlanksAs = rAttribs.getToken( XML_val, XML_zero );
+ return 0;
+ case C_TOKEN( floor ):
+ return new WallFloorContext( *this, mrModel.mxFloor.create() );
+ case C_TOKEN( legend ):
+ return new LegendContext( *this, mrModel.mxLegend.create() );
+ case C_TOKEN( plotArea ):
+ return new PlotAreaContext( *this, mrModel.mxPlotArea.create() );
+ case C_TOKEN( plotVisOnly ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbPlotVisOnly = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( showDLblsOverMax ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbShowLabelsOverMax = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( sideWall ):
+ return new WallFloorContext( *this, mrModel.mxSideWall.create() );
+ case C_TOKEN( title ):
+ return new TitleContext( *this, mrModel.mxTitle.create() );
+ case C_TOKEN( view3D ):
+ return new View3DContext( *this, mrModel.mxView3D.create() );
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/chartspacemodel.cxx b/oox/source/drawingml/chart/chartspacemodel.cxx
new file mode 100644
index 000000000000..7f86448c8d08
--- /dev/null
+++ b/oox/source/drawingml/chart/chartspacemodel.cxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/chartspacemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+ChartSpaceModel::ChartSpaceModel() :
+ mnDispBlanksAs( XML_gap ), // not zero as specified
+ mnStyle( 2 ),
+ mbAutoTitleDel( false ),
+ mbPlotVisOnly( false ),
+ mbShowLabelsOverMax( false ),
+ mbPivotChart( false )
+{
+}
+
+ChartSpaceModel::~ChartSpaceModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/converterbase.cxx b/oox/source/drawingml/chart/converterbase.cxx
new file mode 100644
index 000000000000..7e601ff016af
--- /dev/null
+++ b/oox/source/drawingml/chart/converterbase.cxx
@@ -0,0 +1,439 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/converterbase.hxx"
+
+#include <com/sun/star/chart/XAxisXSupplier.hpp>
+#include <com/sun/star/chart/XAxisYSupplier.hpp>
+#include <com/sun/star/chart/XAxisZSupplier.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart2/RelativeSize.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <tools/solar.h> // for F_PI180
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/theme.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+namespace cssc = ::com::sun::star::chart;
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::XmlFilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+struct TitleKey : public ::std::pair< ObjectType, ::std::pair< sal_Int32, sal_Int32 > >
+{
+ inline explicit TitleKey( ObjectType eObjType, sal_Int32 nMainIdx = -1, sal_Int32 nSubIdx = -1 )
+ { first = eObjType; second.first = nMainIdx; second.second = nSubIdx; }
+};
+
+// ----------------------------------------------------------------------------
+
+/** A helper structure to store all data related to title objects. Needed for
+ the conversion of manual title positions that needs the old Chart1 API.
+ */
+struct TitleLayoutInfo
+{
+ typedef Reference< XShape > (*GetShapeFunc)( const Reference< cssc::XChartDocument >& );
+
+ Reference< XTitle > mxTitle; /// The API title object.
+ ModelRef< LayoutModel > mxLayout; /// The layout model, if existing.
+ GetShapeFunc mpGetShape; /// Helper function to receive the title shape.
+
+ inline explicit TitleLayoutInfo() : mpGetShape( 0 ) {}
+
+ void convertTitlePos(
+ ConverterRoot& rRoot,
+ const Reference< cssc::XChartDocument >& rxChart1Doc );
+};
+
+void TitleLayoutInfo::convertTitlePos( ConverterRoot& rRoot, const Reference< cssc::XChartDocument >& rxChart1Doc )
+{
+ if( mxTitle.is() && mpGetShape ) try
+ {
+ // try to get the title shape
+ Reference< XShape > xTitleShape( mpGetShape( rxChart1Doc ), UNO_SET_THROW );
+ // get title rotation angle, needed for correction of position of top-left edge
+ double fAngle = 0.0;
+ PropertySet aTitleProp( mxTitle );
+ aTitleProp.getProperty( fAngle, PROP_TextRotation );
+ // convert the position
+ LayoutModel& rLayout = mxLayout.getOrCreate();
+ LayoutConverter aLayoutConv( rRoot, rLayout );
+ aLayoutConv.convertFromModel( xTitleShape, fAngle );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+/* The following local functions implement getting the XShape interface of all
+ supported title objects (chart and axes). This needs some effort due to the
+ design of the old Chart1 API used to access these objects. */
+
+/** A code fragment that returns a shape object from the passed shape supplier
+ using the specified interface function. Checks a boolean property first. */
+#define OOX_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
+ PropertySet aPropSet( shape_supplier ); \
+ if( shape_supplier.is() && aPropSet.getBoolProperty( PROP_##property_name ) ) \
+ return shape_supplier->supplier_func(); \
+ return Reference< XShape >(); \
+
+/** Implements a function returning the drawing shape of an axis title, if
+ existing, using the specified API interface and its function. */
+#define OOX_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
+Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
+{ \
+ Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
+ OOX_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
+}
+
+/** Returns the drawing shape of the main title, if existing. */
+Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc )
+{
+ OOX_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
+}
+
+OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
+OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
+OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
+OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
+OOX_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
+
+#undef OOX_DEFINEFUNC_GETAXISTITLESHAPE
+#undef OOX_IMPLEMENT_GETTITLESHAPE
+
+} // namespace
+
+// ============================================================================
+
+struct ConverterData
+{
+ typedef ::std::map< TitleKey, TitleLayoutInfo > TitleMap;
+
+ ObjectFormatter maFormatter;
+ TitleMap maTitles;
+ XmlFilterBase& mrFilter;
+ ChartConverter& mrConverter;
+ Reference< XChartDocument > mxDoc;
+ Size maSize;
+
+ explicit ConverterData(
+ XmlFilterBase& rFilter,
+ ChartConverter& rChartConverter,
+ const ChartSpaceModel& rChartModel,
+ const Reference< XChartDocument >& rxChartDoc,
+ const Size& rChartSize );
+ ~ConverterData();
+};
+
+// ----------------------------------------------------------------------------
+
+ConverterData::ConverterData(
+ XmlFilterBase& rFilter,
+ ChartConverter& rChartConverter,
+ const ChartSpaceModel& rChartModel,
+ const Reference< XChartDocument >& rxChartDoc,
+ const Size& rChartSize ) :
+ maFormatter( rFilter, rxChartDoc, rChartModel ),
+ mrFilter( rFilter ),
+ mrConverter( rChartConverter ),
+ mxDoc( rxChartDoc ),
+ maSize( rChartSize )
+{
+ OSL_ENSURE( mxDoc.is(), "ConverterData::ConverterData - missing chart document" );
+ // lock the model to suppress internal updates during conversion
+ try
+ {
+ Reference< XModel > xModel( mxDoc, UNO_QUERY_THROW );
+ xModel->lockControllers();
+ }
+ catch( Exception& )
+ {
+ }
+
+ // prepare conversion of title positions
+ maTitles[ TitleKey( OBJECTTYPE_CHARTTITLE ) ].mpGetShape = lclGetMainTitleShape;
+ maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_PRIM_AXESSET, API_X_AXIS ) ].mpGetShape = lclGetXAxisTitleShape;
+ maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_PRIM_AXESSET, API_Y_AXIS ) ].mpGetShape = lclGetYAxisTitleShape;
+ maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_PRIM_AXESSET, API_Z_AXIS ) ].mpGetShape = lclGetZAxisTitleShape;
+ maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_SECN_AXESSET, API_X_AXIS ) ].mpGetShape = lclGetSecXAxisTitleShape;
+ maTitles[ TitleKey( OBJECTTYPE_AXISTITLE, API_SECN_AXESSET, API_Y_AXIS ) ].mpGetShape = lclGetSecYAxisTitleShape;
+}
+
+ConverterData::~ConverterData()
+{
+ // unlock the model
+ try
+ {
+ Reference< XModel > xModel( mxDoc, UNO_QUERY_THROW );
+ xModel->unlockControllers();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+ConverterRoot::ConverterRoot(
+ XmlFilterBase& rFilter,
+ ChartConverter& rChartConverter,
+ const ChartSpaceModel& rChartModel,
+ const Reference< XChartDocument >& rxChartDoc,
+ const Size& rChartSize ) :
+ mxData( new ConverterData( rFilter, rChartConverter, rChartModel, rxChartDoc, rChartSize ) )
+{
+}
+
+ConverterRoot::~ConverterRoot()
+{
+}
+
+Reference< XInterface > ConverterRoot::createInstance( const OUString& rServiceName ) const
+{
+ Reference< XInterface > xInt;
+ try
+ {
+ xInt = mxData->mrFilter.getServiceFactory()->createInstance( rServiceName );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xInt.is(), "ConverterRoot::createInstance - cannot create instance" );
+ return xInt;
+}
+
+XmlFilterBase& ConverterRoot::getFilter() const
+{
+ return mxData->mrFilter;
+}
+
+ChartConverter& ConverterRoot::getChartConverter() const
+{
+ return mxData->mrConverter;
+}
+
+Reference< XChartDocument > ConverterRoot::getChartDocument() const
+{
+ return mxData->mxDoc;
+}
+
+const Size& ConverterRoot::getChartSize() const
+{
+ return mxData->maSize;
+}
+
+ObjectFormatter& ConverterRoot::getFormatter() const
+{
+ return mxData->maFormatter;
+}
+
+void ConverterRoot::registerTitleLayout( const Reference< XTitle >& rxTitle,
+ const ModelRef< LayoutModel >& rxLayout, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx )
+{
+ OSL_ENSURE( rxTitle.is(), "ConverterRoot::registerTitleLayout - missing title object" );
+ TitleLayoutInfo& rTitleInfo = mxData->maTitles[ TitleKey( eObjType, nMainIdx, nSubIdx ) ];
+ OSL_ENSURE( rTitleInfo.mpGetShape, "ConverterRoot::registerTitleLayout - invalid title key" );
+ rTitleInfo.mxTitle = rxTitle;
+ rTitleInfo.mxLayout = rxLayout;
+}
+
+void ConverterRoot::convertTitlePositions()
+{
+ try
+ {
+ Reference< cssc::XChartDocument > xChart1Doc( mxData->mxDoc, UNO_QUERY_THROW );
+ for( ConverterData::TitleMap::iterator aIt = mxData->maTitles.begin(), aEnd = mxData->maTitles.end(); aIt != aEnd; ++aIt )
+ aIt->second.convertTitlePos( *this, xChart1Doc );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+namespace {
+
+/** Returns a position value in the chart area in 1/100 mm. */
+sal_Int32 lclCalcPosition( sal_Int32 nChartSize, double fPos, sal_Int32 nPosMode )
+{
+ switch( nPosMode )
+ {
+ case XML_edge: // absolute start position as factor of chart size
+ return getLimitedValue< sal_Int32, double >( nChartSize * fPos + 0.5, 0, nChartSize );
+ case XML_factor: // position relative to object default position
+ OSL_ENSURE( false, "lclCalcPosition - relative positioning not supported" );
+ return -1;
+ };
+
+ OSL_ENSURE( false, "lclCalcPosition - unknown positioning mode" );
+ return -1;
+}
+
+/** Returns a size value in the chart area in 1/100 mm. */
+sal_Int32 lclCalcSize( sal_Int32 nPos, sal_Int32 nChartSize, double fSize, sal_Int32 nSizeMode )
+{
+ sal_Int32 nValue = getLimitedValue< sal_Int32, double >( nChartSize * fSize + 0.5, 0, nChartSize );
+ switch( nSizeMode )
+ {
+ case XML_factor: // passed value is width/height
+ return nValue;
+ case XML_edge: // passed value is right/bottom position
+ return nValue - nPos + 1;
+ };
+
+ OSL_ENSURE( false, "lclCalcSize - unknown size mode" );
+ return -1;
+}
+
+/** Returns a relative size value in the chart area. */
+double lclCalcRelSize( double fPos, double fSize, sal_Int32 nSizeMode )
+{
+ switch( nSizeMode )
+ {
+ case XML_factor: // passed value is width/height
+ break;
+ case XML_edge: // passed value is right/bottom position
+ fSize -= fPos;
+ break;
+ default:
+ OSL_ENSURE( false, "lclCalcRelSize - unknown size mode" );
+ fSize = 0.0;
+ };
+ return getLimitedValue< double, double >( fSize, 0.0, 1.0 - fPos );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+LayoutConverter::LayoutConverter( const ConverterRoot& rParent, LayoutModel& rModel ) :
+ ConverterBase< LayoutModel >( rParent, rModel )
+{
+}
+
+LayoutConverter::~LayoutConverter()
+{
+}
+
+bool LayoutConverter::calcAbsRectangle( Rectangle& orRect ) const
+{
+ if( !mrModel.mbAutoLayout )
+ {
+ const Size& rChartSize = getChartSize();
+ orRect.X = lclCalcPosition( rChartSize.Width, mrModel.mfX, mrModel.mnXMode );
+ orRect.Y = lclCalcPosition( rChartSize.Height, mrModel.mfY, mrModel.mnYMode );
+ if( (orRect.X >= 0) && (orRect.Y >= 0) )
+ {
+ orRect.Width = lclCalcSize( orRect.X, rChartSize.Width, mrModel.mfW, mrModel.mnWMode );
+ orRect.Height = lclCalcSize( orRect.Y, rChartSize.Height, mrModel.mfH, mrModel.mnHMode );
+ return (orRect.Width > 0) && (orRect.Height > 0);
+ }
+ }
+ return false;
+}
+
+bool LayoutConverter::convertFromModel( PropertySet& rPropSet )
+{
+ if( !mrModel.mbAutoLayout &&
+ (mrModel.mnXMode == XML_edge) && (mrModel.mfX >= 0.0) &&
+ (mrModel.mnYMode == XML_edge) && (mrModel.mfY >= 0.0) )
+ {
+ RelativePosition aPos(
+ getLimitedValue< double, double >( mrModel.mfX, 0.0, 1.0 ),
+ getLimitedValue< double, double >( mrModel.mfY, 0.0, 1.0 ),
+ Alignment_TOP_LEFT );
+ rPropSet.setProperty( PROP_RelativePosition, aPos );
+
+ RelativeSize aSize(
+ lclCalcRelSize( aPos.Primary, mrModel.mfW, mrModel.mnWMode ),
+ lclCalcRelSize( aPos.Secondary, mrModel.mfH, mrModel.mnHMode ) );
+ if( (aSize.Primary > 0.0) && (aSize.Secondary > 0.0) )
+ {
+ rPropSet.setProperty( PROP_RelativeSize, aSize );
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LayoutConverter::convertFromModel( const Reference< XShape >& rxShape, double fRotationAngle )
+{
+ if( !mrModel.mbAutoLayout )
+ {
+ const Size& rChartSize = getChartSize();
+ Point aShapePos(
+ lclCalcPosition( rChartSize.Width, mrModel.mfX, mrModel.mnXMode ),
+ lclCalcPosition( rChartSize.Height, mrModel.mfY, mrModel.mnYMode ) );
+ if( (aShapePos.X >= 0) && (aShapePos.Y >= 0) )
+ {
+ // the call to XShape.getSize() may recalc the chart view
+ Size aShapeSize = rxShape->getSize();
+ // rotated shapes need special handling...
+ double fSin = fabs( sin( fRotationAngle * F_PI180 ) );
+ // add part of height to X direction, if title is rotated down
+ if( fRotationAngle > 180.0 )
+ aShapePos.X += static_cast< sal_Int32 >( fSin * aShapeSize.Height + 0.5 );
+ // add part of width to Y direction, if title is rotated up
+ else if( fRotationAngle > 0.0 )
+ aShapePos.Y += static_cast< sal_Int32 >( fSin * aShapeSize.Width + 0.5 );
+ // set the resulting position at the shape
+ rxShape->setPosition( aShapePos );
+ return true;
+ }
+ }
+ return false;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/datasourcecontext.cxx b/oox/source/drawingml/chart/datasourcecontext.cxx
new file mode 100644
index 000000000000..a044dd67018d
--- /dev/null
+++ b/oox/source/drawingml/chart/datasourcecontext.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/datasourcecontext.hxx"
+
+#include "oox/drawingml/chart/datasourcemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+DoubleSequenceContext::DoubleSequenceContext( ContextHandler2Helper& rParent, DataSequenceModel& rModel ) :
+ DataSequenceContextBase( rParent, rModel ),
+ mnPtIndex( -1 )
+{
+}
+
+DoubleSequenceContext::~DoubleSequenceContext()
+{
+}
+
+ContextHandlerRef DoubleSequenceContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( numRef ):
+ switch( nElement )
+ {
+ case C_TOKEN( f ):
+ case C_TOKEN( numCache ):
+ return this;
+ }
+ break;
+
+ case C_TOKEN( numCache ):
+ case C_TOKEN( numLit ):
+ switch( nElement )
+ {
+ case C_TOKEN( formatCode ):
+ return this;
+ case C_TOKEN( ptCount ):
+ mrModel.mnPointCount = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( pt ):
+ mnPtIndex = rAttribs.getInteger( XML_idx, -1 );
+ return this;
+ }
+ break;
+
+ case C_TOKEN( pt ):
+ switch( nElement )
+ {
+ case C_TOKEN( v ):
+ return this;
+ }
+ break;
+ }
+ return 0;
+}
+
+void DoubleSequenceContext::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( f ):
+ mrModel.maFormula = rChars;
+ break;
+ case C_TOKEN( formatCode ):
+ mrModel.maFormatCode = rChars;
+ break;
+ case C_TOKEN( v ):
+ if( mnPtIndex >= 0 )
+ mrModel.maData[ mnPtIndex ] <<= rChars.toDouble();
+ break;
+ }
+}
+
+// ============================================================================
+
+StringSequenceContext::StringSequenceContext( ContextHandler2Helper& rParent, DataSequenceModel& rModel ) :
+ DataSequenceContextBase( rParent, rModel )
+{
+}
+
+StringSequenceContext::~StringSequenceContext()
+{
+}
+
+ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( multiLvlStrRef ):
+ switch( nElement )
+ {
+ case C_TOKEN( f ):
+ return this;
+ }
+ break;
+
+ case C_TOKEN( strRef ):
+ switch( nElement )
+ {
+ case C_TOKEN( f ):
+ case C_TOKEN( strCache ):
+ return this;
+ }
+ break;
+
+ case C_TOKEN( strCache ):
+ case C_TOKEN( strLit ):
+ switch( nElement )
+ {
+ case C_TOKEN( ptCount ):
+ mrModel.mnPointCount = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( pt ):
+ mnPtIndex = rAttribs.getInteger( XML_idx, -1 );
+ return this;
+ }
+ break;
+
+ case C_TOKEN( pt ):
+ switch( nElement )
+ {
+ case C_TOKEN( v ):
+ return this;
+ }
+ break;
+ }
+ return 0;
+}
+
+void StringSequenceContext::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( f ):
+ mrModel.maFormula = rChars;
+ break;
+ case C_TOKEN( v ):
+ if( mnPtIndex >= 0 )
+ mrModel.maData[ mnPtIndex ] <<= rChars;
+ break;
+ }
+}
+
+// ============================================================================
+
+DataSourceContext::DataSourceContext( ContextHandler2Helper& rParent, DataSourceModel& rModel ) :
+ ContextBase< DataSourceModel >( rParent, rModel )
+{
+}
+
+DataSourceContext::~DataSourceContext()
+{
+}
+
+ContextHandlerRef DataSourceContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( cat ):
+ case C_TOKEN( xVal ):
+ switch( nElement )
+ {
+ case C_TOKEN( multiLvlStrRef ):
+ case C_TOKEN( strLit ):
+ case C_TOKEN( strRef ):
+ OSL_ENSURE( !mrModel.mxDataSeq, "DataSourceContext::onCreateContext - multiple data sequences" );
+ return new StringSequenceContext( *this, mrModel.mxDataSeq.create() );
+
+ case C_TOKEN( numLit ):
+ case C_TOKEN( numRef ):
+ OSL_ENSURE( !mrModel.mxDataSeq, "DataSourceContext::onCreateContext - multiple data sequences" );
+ return new DoubleSequenceContext( *this, mrModel.mxDataSeq.create() );
+ }
+ break;
+
+ case C_TOKEN( plus ):
+ case C_TOKEN( minus ):
+ case C_TOKEN( val ):
+ case C_TOKEN( yVal ):
+ case C_TOKEN( bubbleSize ):
+ switch( nElement )
+ {
+ case C_TOKEN( numLit ):
+ case C_TOKEN( numRef ):
+ OSL_ENSURE( !mrModel.mxDataSeq, "DataSourceContext::onCreateContext - multiple data sequences" );
+ return new DoubleSequenceContext( *this, mrModel.mxDataSeq.create() );
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/datasourceconverter.cxx b/oox/source/drawingml/chart/datasourceconverter.cxx
new file mode 100644
index 000000000000..c68a6cbe4adf
--- /dev/null
+++ b/oox/source/drawingml/chart/datasourceconverter.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/datasourceconverter.hxx"
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include "oox/drawingml/chart/chartconverter.hxx"
+#include "oox/drawingml/chart/datasourcemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::chart2::data;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+DataSequenceConverter::DataSequenceConverter( const ConverterRoot& rParent, DataSequenceModel& rModel ) :
+ ConverterBase< DataSequenceModel >( rParent, rModel )
+{
+}
+
+DataSequenceConverter::~DataSequenceConverter()
+{
+}
+
+Reference< XDataSequence > DataSequenceConverter::createDataSequence( const OUString& rRole )
+{
+ // create data sequence from data source model (virtual call at chart converter)
+ Reference< XDataSequence > xDataSeq = getChartConverter().createDataSequence( getChartDocument()->getDataProvider(), mrModel );
+
+ // set sequence role
+ PropertySet aSeqProp( xDataSeq );
+ aSeqProp.setProperty( PROP_Role, rRole );
+
+ return xDataSeq;
+}
+
+// ============================================================================
+
+DataSourceConverter::DataSourceConverter( const ConverterRoot& rParent, DataSourceModel& rModel ) :
+ ConverterBase< DataSourceModel >( rParent, rModel )
+{
+}
+
+DataSourceConverter::~DataSourceConverter()
+{
+}
+
+Reference< XDataSequence > DataSourceConverter::createDataSequence( const OUString& rRole )
+{
+ Reference< XDataSequence > xDataSeq;
+ if( mrModel.mxDataSeq.is() )
+ {
+ DataSequenceConverter aDataSeqConv( *this, *mrModel.mxDataSeq );
+ xDataSeq = aDataSeqConv.createDataSequence( rRole );
+ }
+ return xDataSeq;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/datasourcemodel.cxx b/oox/source/drawingml/chart/datasourcemodel.cxx
new file mode 100644
index 000000000000..aad5a1bff959
--- /dev/null
+++ b/oox/source/drawingml/chart/datasourcemodel.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/datasourcemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+DataSequenceModel::DataSequenceModel() :
+ mnPointCount( -1 )
+{
+}
+
+DataSequenceModel::~DataSequenceModel()
+{
+}
+
+// ============================================================================
+
+DataSourceModel::DataSourceModel()
+{
+}
+
+DataSourceModel::~DataSourceModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/makefile.mk b/oox/source/drawingml/chart/makefile.mk
new file mode 100644
index 000000000000..84762e6a2540
--- /dev/null
+++ b/oox/source/drawingml/chart/makefile.mk
@@ -0,0 +1,74 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=oox
+TARGET=chart
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/axiscontext.obj \
+ $(SLO)$/axisconverter.obj \
+ $(SLO)$/axismodel.obj \
+ $(SLO)$/chartcontextbase.obj \
+ $(SLO)$/chartconverter.obj \
+ $(SLO)$/chartdrawingfragment.obj \
+ $(SLO)$/chartspaceconverter.obj \
+ $(SLO)$/chartspacefragment.obj \
+ $(SLO)$/chartspacemodel.obj \
+ $(SLO)$/converterbase.obj \
+ $(SLO)$/datasourcecontext.obj \
+ $(SLO)$/datasourceconverter.obj \
+ $(SLO)$/datasourcemodel.obj \
+ $(SLO)$/modelbase.obj \
+ $(SLO)$/objectformatter.obj \
+ $(SLO)$/plotareacontext.obj \
+ $(SLO)$/plotareaconverter.obj \
+ $(SLO)$/plotareamodel.obj \
+ $(SLO)$/seriescontext.obj \
+ $(SLO)$/seriesconverter.obj \
+ $(SLO)$/seriesmodel.obj \
+ $(SLO)$/titlecontext.obj \
+ $(SLO)$/titleconverter.obj \
+ $(SLO)$/titlemodel.obj \
+ $(SLO)$/typegroupcontext.obj \
+ $(SLO)$/typegroupconverter.obj \
+ $(SLO)$/typegroupmodel.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/drawingml/chart/modelbase.cxx b/oox/source/drawingml/chart/modelbase.cxx
new file mode 100644
index 000000000000..f32a118c5589
--- /dev/null
+++ b/oox/source/drawingml/chart/modelbase.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/modelbase.hxx"
+
+#include "oox/helper/attributelist.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+NumberFormat::NumberFormat() :
+ mbSourceLinked( true )
+{
+}
+
+void NumberFormat::setAttributes( const AttributeList& rAttribs )
+{
+ maFormatCode = rAttribs.getString( XML_formatCode, OUString() );
+ // default is 'false', not 'true' as specified
+ mbSourceLinked = rAttribs.getBool( XML_sourceLinked, false );
+}
+
+// ============================================================================
+
+LayoutModel::LayoutModel() :
+ mfX( 0.0 ),
+ mfY( 0.0 ),
+ mfW( 0.0 ),
+ mfH( 0.0 ),
+ mnXMode( XML_factor ),
+ mnYMode( XML_factor ),
+ mnWMode( XML_factor ),
+ mnHMode( XML_factor ),
+ mnTarget( XML_outer ),
+ mbAutoLayout( true )
+{
+}
+
+LayoutModel::~LayoutModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx
new file mode 100644
index 000000000000..f6d441ded650
--- /dev/null
+++ b/oox/source/drawingml/chart/objectformatter.cxx
@@ -0,0 +1,1208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/objectformatter.hxx"
+
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <osl/thread.h>
+#include <rtl/strbuf.hxx>
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/textbody.hxx"
+#include "oox/drawingml/textparagraph.hxx"
+#include "oox/drawingml/theme.hxx"
+#include "oox/drawingml/chart/chartspacemodel.hxx"
+#include "oox/helper/modelobjecthelper.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::oox::core::XmlFilterBase;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringToOString;
+
+// ============================================================================
+
+namespace {
+
+struct AutoFormatPatternEntry
+{
+ sal_Int32 mnColorToken; /// Theme color token.
+ sal_Int32 mnModToken; /// Color modification token.
+ sal_Int32 mnModValue; /// Color modification value.
+};
+
+#define AUTOFORMAT_PATTERN_COLOR( color_token ) \
+ { color_token, XML_TOKEN_INVALID, 0 }
+
+#define AUTOFORMAT_PATTERN_COLORMOD( color_token, mod_token, mod_value ) \
+ { color_token, mod_token, mod_value }
+
+#define AUTOFORMAT_PATTERN_END() \
+ AUTOFORMAT_PATTERN_COLOR( XML_TOKEN_INVALID )
+
+static const AutoFormatPatternEntry spAutoFormatPattern1[] =
+{
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 88500 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 92500 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
+ AUTOFORMAT_PATTERN_END()
+};
+
+static const AutoFormatPatternEntry spAutoFormatPattern2[] =
+{
+ AUTOFORMAT_PATTERN_COLOR( XML_accent1 ),
+ AUTOFORMAT_PATTERN_COLOR( XML_accent2 ),
+ AUTOFORMAT_PATTERN_COLOR( XML_accent3 ),
+ AUTOFORMAT_PATTERN_COLOR( XML_accent4 ),
+ AUTOFORMAT_PATTERN_COLOR( XML_accent5 ),
+ AUTOFORMAT_PATTERN_COLOR( XML_accent6 ),
+ AUTOFORMAT_PATTERN_END()
+};
+
+static const AutoFormatPatternEntry spAutoFormatPattern3[] =
+{
+ AUTOFORMAT_PATTERN_COLORMOD( XML_accent1, XML_shade, 50000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_accent2, XML_shade, 50000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_accent3, XML_shade, 50000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_accent4, XML_shade, 50000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_accent5, XML_shade, 50000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_accent6, XML_shade, 50000 ),
+ AUTOFORMAT_PATTERN_END()
+};
+
+static const AutoFormatPatternEntry spAutoFormatPattern4[] =
+{
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 5000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 15000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
+ AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
+ AUTOFORMAT_PATTERN_END()
+};
+
+#undef AUTOFORMAT_PATTERN_COLOR
+#undef AUTOFORMAT_PATTERN_COLORMOD
+#undef AUTOFORMAT_PATTERN_END
+
+// ----------------------------------------------------------------------------
+
+struct AutoFormatEntry
+{
+ sal_Int32 mnFirstStyleIdx; /// First chart style index.
+ sal_Int32 mnLastStyleIdx; /// Last chart style index.
+ sal_Int32 mnThemedIdx; /// Themed style index.
+ sal_Int32 mnColorToken; /// Theme color token.
+ sal_Int32 mnModToken; /// Color modification token.
+ sal_Int32 mnModValue; /// Color modification value.
+ sal_Int32 mnRelLineWidth; /// Relative line width (percent).
+ const AutoFormatPatternEntry* mpPattern;/// Color cycling pattern for data series.
+ bool mbFadedColor; /// True = Faded color for data series.
+};
+
+#define AUTOFORMAT_COLOR( first, last, themed_style, color_token ) \
+ { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, 100, 0, false }
+
+#define AUTOFORMAT_ACCENTS( first, themed_style ) \
+ AUTOFORMAT_COLOR( first, first, themed_style, XML_accent1 ), \
+ AUTOFORMAT_COLOR( first + 1, first + 1, themed_style, XML_accent2 ), \
+ AUTOFORMAT_COLOR( first + 2, first + 2, themed_style, XML_accent3 ), \
+ AUTOFORMAT_COLOR( first + 3, first + 3, themed_style, XML_accent4 ), \
+ AUTOFORMAT_COLOR( first + 4, first + 4, themed_style, XML_accent5 ), \
+ AUTOFORMAT_COLOR( first + 5, first + 5, themed_style, XML_accent6 )
+
+#define AUTOFORMAT_COLORMOD( first, last, themed_style, color_token, mod_token, mod_value ) \
+ { first, last, themed_style, color_token, mod_token, mod_value, 100, 0, false }
+
+#define AUTOFORMAT_ACCENTSMOD( first, themed_style, mod_token, mod_value ) \
+ AUTOFORMAT_COLORMOD( first, first, themed_style, XML_accent1, mod_token, mod_value ), \
+ AUTOFORMAT_COLORMOD( first + 1, first + 1, themed_style, XML_accent2, mod_token, mod_value ), \
+ AUTOFORMAT_COLORMOD( first + 2, first + 2, themed_style, XML_accent3, mod_token, mod_value ), \
+ AUTOFORMAT_COLORMOD( first + 3, first + 3, themed_style, XML_accent4, mod_token, mod_value ), \
+ AUTOFORMAT_COLORMOD( first + 4, first + 4, themed_style, XML_accent5, mod_token, mod_value ), \
+ AUTOFORMAT_COLORMOD( first + 5, first + 5, themed_style, XML_accent6, mod_token, mod_value )
+
+#define AUTOFORMAT_PATTERN( first, last, themed_style, line_width, pattern ) \
+ { first, last, themed_style, XML_TOKEN_INVALID, XML_TOKEN_INVALID, 0, line_width, pattern, false }
+
+#define AUTOFORMAT_FADED( first, last, themed_style, color_token, line_width ) \
+ { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, line_width, 0, true }
+
+#define AUTOFORMAT_FADEDACCENTS( first, themed_style, line_width ) \
+ AUTOFORMAT_FADED( first, first, themed_style, XML_accent1, line_width ), \
+ AUTOFORMAT_FADED( first + 1, first + 1, themed_style, XML_accent2, line_width ), \
+ AUTOFORMAT_FADED( first + 2, first + 2, themed_style, XML_accent3, line_width ), \
+ AUTOFORMAT_FADED( first + 3, first + 3, themed_style, XML_accent4, line_width ), \
+ AUTOFORMAT_FADED( first + 4, first + 4, themed_style, XML_accent5, line_width ), \
+ AUTOFORMAT_FADED( first + 5, first + 5, themed_style, XML_accent6, line_width )
+
+#define AUTOFORMAT_INVISIBLE( first, last ) \
+ AUTOFORMAT_COLOR( first, last, -1, XML_TOKEN_INVALID )
+
+#define AUTOFORMAT_END() \
+ AUTOFORMAT_INVISIBLE( -1, -1 )
+
+static const AutoFormatEntry spNoFormats[] =
+{
+ AUTOFORMAT_INVISIBLE( 1, 48 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spChartSpaceLines[] =
+{
+ AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
+ AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
+ // 41...48: no line, same as Chart2
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spChartSpaceFills[] =
+{
+ AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
+ AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
+ AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spPlotArea2dFills[] =
+{
+ AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
+ AUTOFORMAT_COLORMOD( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
+ AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_tint, 20000 ), // tint not documented!?
+ AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spFloorLines[] =
+{
+ AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
+ AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
+ // 41...48: no line, same as Chart2
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spWallFloorFills[] =
+{
+ AUTOFORMAT_INVISIBLE( 1, 32 ),
+ AUTOFORMAT_COLORMOD( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
+ AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_tint, 20000 ), // tint not documented!?
+ AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spAxisLines[] =
+{
+ AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ), // tint not documented!?
+ AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ), // tint not documented!?
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spMajorGridLines[] =
+{
+ AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ), // tint not documented!?
+ AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ), // tint not documented!?
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spMinorGridLines[] =
+{
+ AUTOFORMAT_COLORMOD( 1, 40, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 50000 ),
+ AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 90000 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spOtherLines[] =
+{
+ AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1 ),
+ AUTOFORMAT_COLOR( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
+ AUTOFORMAT_COLORMOD( 35, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 25000 ),
+ AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_lt1 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spLinearSeriesLines[] =
+{
+ AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 300 ),
+ AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 500 ),
+ AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_SUBTLE, 500 ),
+ AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_SUBTLE, 700 ),
+ AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 500 ),
+ AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern4 ),
+ AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_SUBTLE, 500 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spFilledSeriesLines[] =
+{
+ AUTOFORMAT_INVISIBLE( 1, 8 ),
+ AUTOFORMAT_COLOR( 9, 16, THEMED_STYLE_SUBTLE, XML_lt1 ),
+ AUTOFORMAT_INVISIBLE( 17, 32 ),
+ AUTOFORMAT_COLORMOD( 33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 50000 ),
+ AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern3 ),
+ AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 50000 ),
+ AUTOFORMAT_INVISIBLE( 41, 48 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spFilledSeries2dFills[] =
+{
+ AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_INTENSE, 100 ),
+ AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_INTENSE, 100 ),
+ AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern4 ),
+ AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_INTENSE, 100 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spFilledSeries3dFills[] =
+{
+ AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
+ AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern4 ),
+ AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
+ AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_SUBTLE, 100 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spFilledSeriesEffects[] =
+{
+ // 1...8: no effect, same as Chart2
+ AUTOFORMAT_COLOR( 9, 16, THEMED_STYLE_SUBTLE, XML_dk1 ),
+ AUTOFORMAT_COLOR( 17, 24, THEMED_STYLE_MODERATE, XML_dk1 ),
+ AUTOFORMAT_COLOR( 25, 32, THEMED_STYLE_INTENSE, XML_dk1 ),
+ // 33...40: no effect, same as Chart2
+ AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_INTENSE, XML_dk1 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spUpDownBarLines[] =
+{
+ AUTOFORMAT_COLOR( 1, 16, THEMED_STYLE_SUBTLE, XML_tx1 ),
+ AUTOFORMAT_INVISIBLE( 17, 32 ),
+ AUTOFORMAT_COLOR( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
+ AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
+ AUTOFORMAT_INVISIBLE( 41, 48 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spUpBarFills[] =
+{
+ AUTOFORMAT_COLORMOD( 1, 1, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 25000 ),
+ AUTOFORMAT_COLORMOD( 2, 2, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 5000 ),
+ AUTOFORMAT_ACCENTSMOD( 3, THEMED_STYLE_SUBTLE, XML_tint, 25000 ),
+ AUTOFORMAT_COLORMOD( 9, 9, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 25000 ),
+ AUTOFORMAT_COLORMOD( 10, 10, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 5000 ),
+ AUTOFORMAT_ACCENTSMOD( 11, THEMED_STYLE_SUBTLE, XML_tint, 25000 ),
+ AUTOFORMAT_COLORMOD( 17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
+ AUTOFORMAT_COLORMOD( 18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 5000 ),
+ AUTOFORMAT_ACCENTSMOD( 19, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
+ AUTOFORMAT_COLORMOD( 25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
+ AUTOFORMAT_COLORMOD( 26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 5000 ),
+ AUTOFORMAT_ACCENTSMOD( 27, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
+ AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
+ AUTOFORMAT_COLORMOD( 41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
+ AUTOFORMAT_COLOR( 42, 42, THEMED_STYLE_INTENSE, XML_lt1 ),
+ AUTOFORMAT_ACCENTSMOD( 43, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spDownBarFills[] =
+{
+ AUTOFORMAT_COLORMOD( 1, 1, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
+ AUTOFORMAT_COLORMOD( 2, 2, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
+ AUTOFORMAT_ACCENTSMOD( 3, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
+ AUTOFORMAT_COLORMOD( 9, 9, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
+ AUTOFORMAT_COLORMOD( 10, 10, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
+ AUTOFORMAT_ACCENTSMOD( 11, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
+ AUTOFORMAT_COLORMOD( 17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
+ AUTOFORMAT_COLORMOD( 18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 95000 ),
+ AUTOFORMAT_ACCENTSMOD( 19, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
+ AUTOFORMAT_COLORMOD( 25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
+ AUTOFORMAT_COLORMOD( 26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 95000 ),
+ AUTOFORMAT_ACCENTSMOD( 27, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
+ AUTOFORMAT_COLORMOD( 33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
+ AUTOFORMAT_COLORMOD( 34, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
+ AUTOFORMAT_ACCENTSMOD( 27, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
+ AUTOFORMAT_COLORMOD( 41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
+ AUTOFORMAT_COLOR( 42, 42, THEMED_STYLE_INTENSE, XML_dk1 ),
+ AUTOFORMAT_ACCENTSMOD( 43, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
+ AUTOFORMAT_END()
+};
+
+static const AutoFormatEntry spUpDownBarEffects[] =
+{
+ // 1...8: no effect, same as Chart2
+ AUTOFORMAT_COLOR( 9, 16, THEMED_STYLE_SUBTLE, XML_dk1 ),
+ AUTOFORMAT_COLOR( 17, 24, THEMED_STYLE_MODERATE, XML_dk1 ),
+ AUTOFORMAT_COLOR( 25, 32, THEMED_STYLE_INTENSE, XML_dk1 ),
+ // 33...40: no effect, same as Chart2
+ AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_INTENSE, XML_dk1 ),
+ AUTOFORMAT_END()
+};
+
+#undef AUTOFORMAT_COLOR
+#undef AUTOFORMAT_ACCENTS
+#undef AUTOFORMAT_COLORMOD
+#undef AUTOFORMAT_ACCENTSMOD
+#undef AUTOFORMAT_PATTERN
+#undef AUTOFORMAT_FADED
+#undef AUTOFORMAT_FADEDACCENTS
+#undef AUTOFORMAT_INVISIBLE
+#undef AUTOFORMAT_END
+
+const AutoFormatEntry* lclGetAutoFormatEntry( const AutoFormatEntry* pEntries, sal_Int32 nStyle )
+{
+ for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
+ if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
+ return pEntries;
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+struct AutoTextEntry
+{
+ sal_Int32 mnFirstStyleIdx; /// First chart style index.
+ sal_Int32 mnLastStyleIdx; /// Last chart style index.
+ sal_Int32 mnThemedFont; /// Themed font (minor/major).
+ sal_Int32 mnColorToken; /// Theme color token.
+ sal_Int32 mnDefFontSize; /// Default font size (1/100 points).
+ sal_Int32 mnRelFontSize; /// Font size relative to chart global font (percent).
+ bool mbBold; /// True = bold font.
+};
+
+#define AUTOTEXT_COLOR( first, last, themed_font, color_token, def_font_size, rel_font_size, bold ) \
+ { first, last, themed_font, color_token, def_font_size, rel_font_size, bold }
+
+#define AUTOTEXT_END() \
+ AUTOTEXT_COLOR( -1, -1, XML_none, XML_TOKEN_INVALID, 1000, 100, false )
+
+static const AutoTextEntry spChartTitleTexts[] =
+{
+ AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1800, 120, true ),
+ AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1800, 120, true ),
+ AUTOTEXT_END()
+};
+
+static const AutoTextEntry spAxisTitleTexts[] =
+{
+ AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1000, 100, true ),
+ AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, true ),
+ AUTOTEXT_END()
+};
+
+static const AutoTextEntry spOtherTexts[] =
+{
+ AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1000, 100, false ),
+ AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, false ),
+ AUTOTEXT_END()
+};
+
+#undef AUTOTEXT_COLOR
+#undef AUTOTEXT_END
+
+const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int32 nStyle )
+{
+ for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
+ if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
+ return pEntries;
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Enumerates different sets of property names for chart object formatting. */
+enum PropertyType
+{
+ PROPERTYTYPE_COMMON, /// Common objects, no special handling.
+ PROPERTYTYPE_LINEARSERIES, /// Specific to linear data series.
+ PROPERTYTYPE_FILLEDSERIES /// Specific to filled data series.
+};
+
+/** Contains information about formatting of a specific chart object type. */
+struct ObjectTypeFormatEntry
+{
+ ObjectType meObjType; /// Object type for automatic format.
+ PropertyType mePropType; /// Property type for property names.
+ const AutoFormatEntry* mpAutoLines; /// Automatic line formatting for all chart styles.
+ const AutoFormatEntry* mpAutoFills; /// Automatic fill formatting for all chart styles.
+ const AutoFormatEntry* mpAutoEffects; /// Automatic effect formatting for all chart styles.
+ const AutoTextEntry* mpAutoTexts; /// Automatic text attributes for all chart styles.
+ bool mbIsFrame; /// True = object is a frame, false = object is a line.
+};
+
+#define TYPEFORMAT_FRAME( obj_type, prop_type, auto_texts, auto_lines, auto_fills, auto_effects ) \
+ { obj_type, prop_type, auto_lines, auto_fills, auto_effects, auto_texts, true }
+
+#define TYPEFORMAT_LINE( obj_type, prop_type, auto_texts, auto_lines ) \
+ { obj_type, prop_type, auto_lines, 0, 0, auto_texts, false }
+
+static const ObjectTypeFormatEntry spObjTypeFormatEntries[] =
+{
+ // object type property type auto text auto line auto fill auto effect
+ TYPEFORMAT_FRAME( OBJECTTYPE_CHARTSPACE, PROPERTYTYPE_COMMON, 0, spChartSpaceLines, spChartSpaceFills, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_CHARTTITLE, PROPERTYTYPE_COMMON, spChartTitleTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_LEGEND, PROPERTYTYPE_COMMON, spOtherTexts, spNoFormats, spNoFormats, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA2D, PROPERTYTYPE_COMMON, 0, 0 /* eq to Ch2 */, spPlotArea2dFills, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA3D, PROPERTYTYPE_COMMON, 0, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_WALL, PROPERTYTYPE_COMMON, 0, 0 /* eq to Ch2 */, spWallFloorFills, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_FLOOR, PROPERTYTYPE_COMMON, 0, spFloorLines, spWallFloorFills, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_LINE( OBJECTTYPE_AXIS, PROPERTYTYPE_COMMON, spOtherTexts, spAxisLines ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_AXISTITLE, PROPERTYTYPE_COMMON, spAxisTitleTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_AXISUNIT, PROPERTYTYPE_COMMON, spAxisTitleTexts, 0 /* eq in Ch2 */, 0 /* eq in Ch2 */, 0 /* eq in Ch2 */ ),
+ TYPEFORMAT_LINE( OBJECTTYPE_MAJORGRIDLINE, PROPERTYTYPE_COMMON, 0, spMajorGridLines ),
+ TYPEFORMAT_LINE( OBJECTTYPE_MINORGRIDLINE, PROPERTYTYPE_COMMON, 0, spMinorGridLines ),
+ TYPEFORMAT_LINE( OBJECTTYPE_LINEARSERIES2D, PROPERTYTYPE_LINEARSERIES, 0, spLinearSeriesLines ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES2D, PROPERTYTYPE_FILLEDSERIES, 0, spFilledSeriesLines, spFilledSeries2dFills, spFilledSeriesEffects ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES3D, PROPERTYTYPE_FILLEDSERIES, 0, spFilledSeriesLines, spFilledSeries3dFills, spFilledSeriesEffects ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_DATALABEL, PROPERTYTYPE_COMMON, spOtherTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_LINE( OBJECTTYPE_TRENDLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_TRENDLINELABEL, PROPERTYTYPE_COMMON, spOtherTexts, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */, 0 /* eq to Ch2 */ ),
+ TYPEFORMAT_LINE( OBJECTTYPE_ERRORBAR, PROPERTYTYPE_COMMON, 0, spOtherLines ),
+ TYPEFORMAT_LINE( OBJECTTYPE_SERLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ),
+ TYPEFORMAT_LINE( OBJECTTYPE_LEADERLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ),
+ TYPEFORMAT_LINE( OBJECTTYPE_DROPLINE, PROPERTYTYPE_COMMON, 0, spOtherLines ),
+ TYPEFORMAT_LINE( OBJECTTYPE_HILOLINE, PROPERTYTYPE_LINEARSERIES, 0, spOtherLines ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_UPBAR, PROPERTYTYPE_COMMON, 0, spUpDownBarLines, spUpBarFills, spUpDownBarEffects ),
+ TYPEFORMAT_FRAME( OBJECTTYPE_DOWNBAR, PROPERTYTYPE_COMMON, 0, spUpDownBarLines, spDownBarFills, spUpDownBarEffects ),
+ TYPEFORMAT_LINE( OBJECTTYPE_DATATABLE, PROPERTYTYPE_COMMON, spOtherTexts, spChartSpaceLines )
+};
+
+#undef TYPEFORMAT_FRAME
+#undef TYPEFORMAT_LINE
+// ----------------------------------------------------------------------------
+
+void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptionsModel& rPicOptions )
+{
+ bool bStacked = (rPicOptions.mnPictureFormat == XML_stack) || (rPicOptions.mnPictureFormat == XML_stackScale);
+ orFillProps.maBlipProps.moBitmapMode = bStacked ? XML_tile : XML_stretch;
+}
+
+// ----------------------------------------------------------------------------
+
+const sal_Int32 spnCommonLineIds[ LineId_END ] = { PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID };
+const sal_Int32 spnLinearLineIds[ LineId_END ] = { PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID };
+const sal_Int32 spnFilledLineIds[ LineId_END ] = { PROP_BorderStyle, PROP_BorderWidth, PROP_BorderColor, PROP_BorderTransparency, PROP_BorderDashName, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID };
+
+const sal_Int32 spnCommonFillIds[ FillId_END ] = { PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillGradientName, PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint };
+const sal_Int32 spnFilledFillIds[ FillId_END ] = { PROP_FillStyle, PROP_Color, PROP_Transparency, PROP_GradientName, PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint };
+
+} // namespace
+
+// ============================================================================
+
+struct ObjectFormatterData;
+
+// ----------------------------------------------------------------------------
+
+class DetailFormatterBase
+{
+public:
+ explicit DetailFormatterBase(
+ ObjectFormatterData& rData,
+ const AutoFormatEntry* pAutoFormatEntry );
+ explicit DetailFormatterBase(
+ ObjectFormatterData& rData,
+ const AutoTextEntry* pAutoTextEntry );
+
+protected:
+ /** Returns the placeholder color which may depend on the passed series index. */
+ sal_Int32 getPhColor( sal_Int32 nSeriesIdx ) const;
+
+private:
+ /** Resolves and returns the scheme color with the passed transformation. */
+ sal_Int32 getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const;
+
+protected:
+ typedef ::std::vector< sal_Int32 > ColorPatternVec;
+
+ ObjectFormatterData& mrData; /// Shared formatter data.
+ sal_Int32 mnPhClr; /// RGB placeholder color for themed style.
+ ColorPatternVec maColorPattern; /// Different cycling colors for data series.
+};
+
+// ----------------------------------------------------------------------------
+
+class LineFormatter : public DetailFormatterBase
+{
+public:
+ explicit LineFormatter(
+ ObjectFormatterData& rData,
+ const AutoFormatEntry* pAutoFormatEntry,
+ PropertyType ePropType );
+
+ /** Converts line formatting to the passed property set. */
+ void convertFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ sal_Int32 nSeriesIdx );
+
+private:
+ LinePropertiesPtr mxAutoLine; /// Automatic line properties.
+ LinePropertyIds& mrLinePropIds; /// Property identifiers for border/line formatting.
+};
+
+// ----------------------------------------------------------------------------
+
+class FillFormatter : public DetailFormatterBase
+{
+public:
+ explicit FillFormatter(
+ ObjectFormatterData& rData,
+ const AutoFormatEntry* pAutoFormatEntry,
+ PropertyType ePropType );
+
+ /** Converts area formatting to the passed property set. */
+ void convertFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ const PictureOptionsModel* pPicOptions,
+ sal_Int32 nSeriesIdx );
+
+private:
+ FillPropertiesPtr mxAutoFill; /// Automatic fill properties.
+ FillPropertyIds& mrFillPropIds; /// Property identifiers for fill formatting.
+};
+
+// ----------------------------------------------------------------------------
+
+class EffectFormatter : public DetailFormatterBase
+{
+public:
+ explicit EffectFormatter(
+ ObjectFormatterData& rData,
+ const AutoFormatEntry* pAutoFormatEntry,
+ PropertyType ePropType );
+
+ /** Converts effect formatting to the passed property set. */
+ void convertFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ sal_Int32 nSeriesIdx );
+};
+
+// ----------------------------------------------------------------------------
+
+class TextFormatter : public DetailFormatterBase
+{
+public:
+ explicit TextFormatter(
+ ObjectFormatterData& rData,
+ const AutoTextEntry* pAutoTextEntry,
+ const ModelRef< TextBody >& rxGlobalTextProp );
+
+ /** Converts text formatting to the passed property set. */
+ void convertFormatting(
+ PropertySet& rPropSet,
+ const TextCharacterProperties* pTextProps );
+ /** Converts text formatting to the passed property set. */
+ void convertFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< TextBody >& rxTextProp );
+
+private:
+ TextCharacterPropertiesPtr mxAutoText; /// Automatic text properties.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Formatter for a specific object type. */
+class ObjectTypeFormatter
+{
+public:
+ explicit ObjectTypeFormatter(
+ ObjectFormatterData& rData,
+ const ObjectTypeFormatEntry& rEntry,
+ const ChartSpaceModel& rChartSpace );
+
+ /** Sets frame formatting properties to the passed property set. */
+ void convertFrameFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ const PictureOptionsModel* pPicOptions,
+ sal_Int32 nSeriesIdx );
+
+ /** Sets text formatting properties to the passed property set. */
+ void convertTextFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< TextBody >& rxTextProp );
+
+ /** Sets frame/text formatting properties to the passed property set. */
+ void convertFormatting(
+ PropertySet& rPropSet,
+ const ModelRef< Shape >& rxShapeProp,
+ const ModelRef< TextBody >& rxTextProp );
+
+ /** Sets text formatting properties to the passed property set. */
+ void convertTextFormatting(
+ PropertySet& rPropSet,
+ const TextCharacterProperties& rTextProps );
+
+ /** Sets automatic line properties to the passed property set. */
+ void convertAutomaticLine(
+ PropertySet& rPropSet,
+ sal_Int32 nSeriesIdx );
+
+ /** Sets automatic fill properties to the passed property set. */
+ void convertAutomaticFill(
+ PropertySet& rPropSet,
+ sal_Int32 nSeriesIdx );
+
+private:
+ LineFormatter maLineFormatter; /// Converter for line formatting.
+ FillFormatter maFillFormatter; /// Converter for fill formatting.
+ EffectFormatter maEffectFormatter; /// Converter for effect formatting.
+ TextFormatter maTextFormatter; /// Converter for text formatting.
+ const ObjectTypeFormatEntry& mrEntry; /// Additional settings.
+};
+
+// ----------------------------------------------------------------------------
+
+struct ObjectFormatterData
+{
+ typedef RefMap< ObjectType, ObjectTypeFormatter > ObjectTypeFormatterMap;
+
+ const XmlFilterBase& mrFilter; /// Base filter object.
+ ObjectTypeFormatterMap maTypeFormatters; /// Formatters for all types of objects in a chart.
+ ModelObjectHelper maModelObjHelper; /// Helper for named drawing formatting (dashes, gradients, bitmaps).
+ LinePropertyIds maCommonLineIds; /// Property identifiers for common border formatting.
+ LinePropertyIds maLinearLineIds; /// Property identifiers for line formatting of linear series.
+ LinePropertyIds maFilledLineIds; /// Property identifiers for line formatting of filled series.
+ FillPropertyIds maCommonFillIds; /// Property identifiers for common area fill.
+ FillPropertyIds maFilledFillIds; /// Property identifiers for area fill of filled series.
+ Reference< XNumberFormats > mxNumFmts; /// Number formats collection of container document.
+ Reference< XNumberFormatTypes > mxNumTypes; /// Number format types collection of container document.
+ Locale maEnUsLocale; /// Locale struct containing en-US.
+ Locale maFromLocale; /// Empty locale struct.
+ sal_Int32 mnMaxSeriesIdx; /// Maximum series index used for color cycling/fading.
+
+ explicit ObjectFormatterData(
+ const XmlFilterBase& rFilter,
+ const Reference< XChartDocument >& rxChartDoc,
+ const ChartSpaceModel& rChartSpace );
+
+ ObjectTypeFormatter* getTypeFormatter( ObjectType eObjType );
+
+ LinePropertyIds& getLinePropertyIds( PropertyType ePropType );
+ FillPropertyIds& getFillPropertyIds( PropertyType ePropType );
+};
+
+// ============================================================================
+
+DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
+ mrData( rData ),
+ mnPhClr( -1 )
+{
+ if( pAutoFormatEntry )
+ {
+ if( pAutoFormatEntry->mpPattern )
+ {
+ // prepare multi-color pattern
+ for( const AutoFormatPatternEntry* pPatternEntry = pAutoFormatEntry->mpPattern; pPatternEntry->mnColorToken != XML_TOKEN_INVALID; ++pPatternEntry )
+ maColorPattern.push_back( getSchemeColor( pPatternEntry->mnColorToken, pPatternEntry->mnModToken, pPatternEntry->mnModValue ) );
+ }
+ else if( pAutoFormatEntry->mnColorToken != XML_TOKEN_INVALID )
+ {
+ // prepare color or single-color pattern (color fading)
+ mnPhClr = getSchemeColor( pAutoFormatEntry->mnColorToken, pAutoFormatEntry->mnModToken, pAutoFormatEntry->mnModValue );
+ if( pAutoFormatEntry->mbFadedColor )
+ maColorPattern.push_back( mnPhClr );
+ }
+ }
+}
+
+DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry ) :
+ mrData( rData ),
+ mnPhClr( -1 )
+{
+ if( pAutoTextEntry && (pAutoTextEntry->mnColorToken != XML_TOKEN_INVALID) )
+ mnPhClr = getSchemeColor( pAutoTextEntry->mnColorToken, XML_TOKEN_INVALID, 0 );
+}
+
+sal_Int32 DetailFormatterBase::getPhColor( sal_Int32 nSeriesIdx ) const
+{
+ if( maColorPattern.empty() || (mrData.mnMaxSeriesIdx < 0) || (nSeriesIdx < 0) )
+ return mnPhClr;
+
+ /* Apply tint/shade depending on the cycle index. The colors of leading
+ series are darkened (color shade), the colors of trailing series are
+ lightened (color tint). Shade/tint is applied in an exclusive range of
+ -70% to 70%.
+
+ Example 1: 3 data series using single-color shading with accent color 1
+ (e.g. automatic chart style #3). Shade/tint is applied per series.
+ Shade/tint changes in steps of 140%/(<series_count+1) = 140%/4 = 35%,
+ starting at -70%:
+ Step 1: -70% -> Not used.
+ Step 2: -35% -> Series 1 has 35% shade of accent color 1.
+ Step 3: 0% -> Series 2 has pure accent color 1.
+ Step 4: 35% -> Series 3 has 35% tint of accent color 1.
+ Step 5: 70% -> Not used.
+
+ Example 2: 20 data series using accent color pattern (e.g. automatic
+ chart style #2). Each color cycle has a size of 6 series (accent colors
+ 1 to 6). Shade/tint is applied per color cycle.
+ Cycle #1: Series 1...6 are based on accent colors 1 to 6.
+ Cycle #2: Series 7...12 are based on accent colors 1 to 6.
+ Cycle #3: Series 13...18 are based on accent colors 1 to 6.
+ Cycle #4: Series 19...20 are based on accent colors 1 to 2.
+ Shade/tint changes in steps of 140%/(cycle_count+1) = 140%/5 = 28%,
+ starting at -70%:
+ Step 1: -70% -> Not used.
+ Step 2: -42% -> Cycle #1 has 42% shade of accent colors 1...6
+ step 3: -14% -> Cycle #2 has 14% shade of accent colors 1...6
+ step 4: 14% -> Cycle #3 has 14% tint of accent colors 1...6
+ step 5: 42% -> Cycle #4 has 42% tint of accent colors 1...6
+ step 6: 70% -> Not used.
+ */
+ sal_Int32 nPhClr = maColorPattern[ static_cast< size_t >( nSeriesIdx % maColorPattern.size() ) ];
+ size_t nCycleIdx = static_cast< size_t >( nSeriesIdx / maColorPattern.size() );
+ size_t nMaxCycleIdx = static_cast< size_t >( mrData.mnMaxSeriesIdx / maColorPattern.size() );
+ double fShadeTint = static_cast< double >( nCycleIdx + 1 ) / (nMaxCycleIdx + 2) * 1.4 - 0.7;
+ if( fShadeTint != 0.0 )
+ {
+ Color aColor;
+ aColor.setSrgbClr( nPhClr );
+ aColor.addChartTintTransformation( fShadeTint );
+ nPhClr = aColor.getColor( mrData.mrFilter.getGraphicHelper() );
+ }
+
+ return nPhClr;
+}
+
+sal_Int32 DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const
+{
+ Color aColor;
+ aColor.setSchemeClr( nColorToken );
+ if( nModToken != XML_TOKEN_INVALID )
+ aColor.addTransformation( nModToken, nModValue );
+ return aColor.getColor( mrData.mrFilter.getGraphicHelper() );
+}
+
+// ============================================================================
+
+LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, PropertyType ePropType ) :
+ DetailFormatterBase( rData, pAutoFormatEntry ),
+ mrLinePropIds( rData.getLinePropertyIds( ePropType ) )
+{
+ if( pAutoFormatEntry )
+ {
+ mxAutoLine.reset( new LineProperties );
+ mxAutoLine->maLineFill.moFillType = XML_noFill;
+ if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
+ if( const LineProperties* pLineProps = pTheme->getLineStyle( pAutoFormatEntry->mnThemedIdx ) )
+ *mxAutoLine = *pLineProps;
+ // change line width according to chart auto style
+ if( mxAutoLine->moLineWidth.has() )
+ mxAutoLine->moLineWidth = mxAutoLine->moLineWidth.get() * pAutoFormatEntry->mnRelLineWidth / 100;
+ }
+}
+
+void LineFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx )
+{
+ LineProperties aLineProps;
+ if( mxAutoLine.get() )
+ aLineProps.assignUsed( *mxAutoLine );
+ if( rxShapeProp.is() )
+ aLineProps.assignUsed( rxShapeProp->getLineProperties() );
+ aLineProps.pushToPropSet( rPropSet, mrData.maModelObjHelper, mrData.mrFilter.getGraphicHelper(), mrLinePropIds, getPhColor( nSeriesIdx ) );
+}
+
+// ============================================================================
+
+FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, PropertyType ePropType ) :
+ DetailFormatterBase( rData, pAutoFormatEntry ),
+ mrFillPropIds( rData.getFillPropertyIds( ePropType ) )
+{
+ if( pAutoFormatEntry )
+ {
+ mxAutoFill.reset( new FillProperties );
+ mxAutoFill->moFillType = XML_noFill;
+ if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
+ if( const FillProperties* pFillProps = pTheme->getFillStyle( pAutoFormatEntry->mnThemedIdx ) )
+ *mxAutoFill = *pFillProps;
+ }
+}
+
+void FillFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
+{
+ FillProperties aFillProps;
+ if( mxAutoFill.get() )
+ aFillProps.assignUsed( *mxAutoFill );
+ if( rxShapeProp.is() )
+ aFillProps.assignUsed( rxShapeProp->getFillProperties() );
+ if( pPicOptions )
+ lclConvertPictureOptions( aFillProps, *pPicOptions );
+ aFillProps.pushToPropSet( rPropSet, mrData.maModelObjHelper, mrData.mrFilter.getGraphicHelper(), mrFillPropIds, 0, getPhColor( nSeriesIdx ) );
+}
+
+// ============================================================================
+
+EffectFormatter::EffectFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, PropertyType /*ePropType*/ ) :
+ DetailFormatterBase( rData, pAutoFormatEntry )
+{
+}
+
+void EffectFormatter::convertFormatting( PropertySet& /*rPropSet*/, const ModelRef< Shape >& /*rxShapeProp*/, sal_Int32 /*nSeriesIdx*/ )
+{
+}
+
+// ============================================================================
+
+namespace {
+
+const TextCharacterProperties* lclGetTextProperties( const ModelRef< TextBody >& rxTextProp )
+{
+ return (rxTextProp.is() && !rxTextProp->getParagraphs().empty()) ?
+ &rxTextProp->getParagraphs().front()->getProperties().getTextCharacterProperties() : 0;
+}
+
+} // namespace
+
+TextFormatter::TextFormatter( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry, const ModelRef< TextBody >& rxGlobalTextProp ) :
+ DetailFormatterBase( rData, pAutoTextEntry )
+{
+ if( pAutoTextEntry )
+ {
+ mxAutoText.reset( new TextCharacterProperties );
+ if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
+ if( const TextCharacterProperties* pTextProps = pTheme->getFontStyle( pAutoTextEntry->mnThemedFont ) )
+ *mxAutoText = *pTextProps;
+ sal_Int32 nTextColor = getPhColor( -1 );
+ if( nTextColor >= 0 )
+ mxAutoText->maCharColor.setSrgbClr( nTextColor );
+ mxAutoText->moHeight = pAutoTextEntry->mnDefFontSize;
+ mxAutoText->moBold = pAutoTextEntry->mbBold;
+
+ if( const TextCharacterProperties* pTextProps = lclGetTextProperties( rxGlobalTextProp ) )
+ {
+ mxAutoText->assignUsed( *pTextProps );
+ if( pTextProps->moHeight.has() )
+ mxAutoText->moHeight = pTextProps->moHeight.get() * pAutoTextEntry->mnRelFontSize / 100;
+ }
+ }
+}
+
+void TextFormatter::convertFormatting( PropertySet& rPropSet, const TextCharacterProperties* pTextProps )
+{
+ TextCharacterProperties aTextProps;
+ if( mxAutoText.get() )
+ aTextProps.assignUsed( *mxAutoText );
+ if( pTextProps )
+ aTextProps.assignUsed( *pTextProps );
+ aTextProps.pushToPropSet( rPropSet, mrData.mrFilter );
+}
+
+void TextFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
+{
+ convertFormatting( rPropSet, lclGetTextProperties( rxTextProp ) );
+}
+
+// ============================================================================
+
+ObjectTypeFormatter::ObjectTypeFormatter( ObjectFormatterData& rData, const ObjectTypeFormatEntry& rEntry, const ChartSpaceModel& rChartSpace ) :
+ maLineFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoLines, rChartSpace.mnStyle ), rEntry.mePropType ),
+ maFillFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoFills, rChartSpace.mnStyle ), rEntry.mePropType ),
+ maEffectFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoEffects, rChartSpace.mnStyle ), rEntry.mePropType ),
+ maTextFormatter( rData, lclGetAutoTextEntry( rEntry.mpAutoTexts, rChartSpace.mnStyle ), rChartSpace.mxTextProp ),
+ mrEntry( rEntry )
+{
+}
+
+void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
+{
+ maLineFormatter.convertFormatting( rPropSet, rxShapeProp, nSeriesIdx );
+ if( mrEntry.mbIsFrame )
+ maFillFormatter.convertFormatting( rPropSet, rxShapeProp, pPicOptions, nSeriesIdx );
+ maEffectFormatter.convertFormatting( rPropSet, rxShapeProp, nSeriesIdx );
+}
+
+void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
+{
+ maTextFormatter.convertFormatting( rPropSet, rxTextProp );
+}
+
+void ObjectTypeFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp )
+{
+ convertFrameFormatting( rPropSet, rxShapeProp, 0, -1 );
+ convertTextFormatting( rPropSet, rxTextProp );
+}
+
+void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps )
+{
+ maTextFormatter.convertFormatting( rPropSet, &rTextProps );
+}
+
+void ObjectTypeFormatter::convertAutomaticLine( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
+{
+ ModelRef< Shape > xShapeProp;
+ maLineFormatter.convertFormatting( rPropSet, xShapeProp, nSeriesIdx );
+ maEffectFormatter.convertFormatting( rPropSet, xShapeProp, nSeriesIdx );
+}
+
+void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
+{
+ ModelRef< Shape > xShapeProp;
+ maFillFormatter.convertFormatting( rPropSet, xShapeProp, 0, nSeriesIdx );
+ maEffectFormatter.convertFormatting( rPropSet, xShapeProp, nSeriesIdx );
+}
+
+// ============================================================================
+
+ObjectFormatterData::ObjectFormatterData( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
+ mrFilter( rFilter ),
+ maModelObjHelper( Reference< XMultiServiceFactory >( rxChartDoc, UNO_QUERY ) ),
+ maCommonLineIds( spnCommonLineIds, true, false ),
+ maLinearLineIds( spnLinearLineIds, true, false ),
+ maFilledLineIds( spnFilledLineIds, true, false ),
+ maCommonFillIds( spnCommonFillIds, true, true ),
+ maFilledFillIds( spnFilledFillIds, true, true ),
+ maEnUsLocale( CREATE_OUSTRING( "en" ), CREATE_OUSTRING( "US" ), OUString() ),
+ mnMaxSeriesIdx( -1 )
+{
+ const ObjectTypeFormatEntry* pEntryEnd = STATIC_ARRAY_END( spObjTypeFormatEntries );
+ for( const ObjectTypeFormatEntry* pEntry = spObjTypeFormatEntries; pEntry != pEntryEnd; ++pEntry )
+ maTypeFormatters[ pEntry->meObjType ].reset( new ObjectTypeFormatter( *this, *pEntry, rChartSpace ) );
+
+ try
+ {
+ Reference< XNumberFormatsSupplier > xNumFmtsSupp( mrFilter.getModel(), UNO_QUERY_THROW );
+ mxNumFmts = xNumFmtsSupp->getNumberFormats();
+ mxNumTypes.set( mxNumFmts, UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( mxNumFmts.is() && mxNumTypes.is(), "ObjectFormatterData::ObjectFormatterData - cannot get number formats" );
+}
+
+ObjectTypeFormatter* ObjectFormatterData::getTypeFormatter( ObjectType eObjType )
+{
+ OSL_ENSURE( maTypeFormatters.has( eObjType ), "ObjectFormatterData::getTypeFormatter - unknown object type" );
+ return maTypeFormatters.get( eObjType ).get();
+}
+
+LinePropertyIds& ObjectFormatterData::getLinePropertyIds( PropertyType ePropType )
+{
+ switch( ePropType )
+ {
+ case PROPERTYTYPE_COMMON: return maCommonLineIds;
+ case PROPERTYTYPE_LINEARSERIES: return maLinearLineIds;
+ case PROPERTYTYPE_FILLEDSERIES: return maFilledLineIds;
+ }
+ return maCommonLineIds;
+}
+
+FillPropertyIds& ObjectFormatterData::getFillPropertyIds( PropertyType ePropType )
+{
+ switch( ePropType )
+ {
+ case PROPERTYTYPE_COMMON: return maCommonFillIds;
+ case PROPERTYTYPE_LINEARSERIES: return maCommonFillIds;
+ case PROPERTYTYPE_FILLEDSERIES: return maFilledFillIds;
+ }
+ return maCommonFillIds;
+}
+
+// ============================================================================
+
+ObjectFormatter::ObjectFormatter( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
+ mxData( new ObjectFormatterData( rFilter, rxChartDoc, rChartSpace ) )
+{
+}
+
+ObjectFormatter::~ObjectFormatter()
+{
+}
+
+void ObjectFormatter::setMaxSeriesIndex( sal_Int32 nMaxSeriesIdx )
+{
+ mxData->mnMaxSeriesIdx = nMaxSeriesIdx;
+}
+
+sal_Int32 ObjectFormatter::getMaxSeriesIndex() const
+{
+ return mxData->mnMaxSeriesIdx;
+}
+
+void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx )
+{
+ if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
+ pFormat->convertFrameFormatting( rPropSet, rxShapeProp, 0, nSeriesIdx );
+}
+
+void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel& rPicOptions, ObjectType eObjType, sal_Int32 nSeriesIdx )
+{
+ if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
+ pFormat->convertFrameFormatting( rPropSet, rxShapeProp, &rPicOptions, nSeriesIdx );
+}
+
+void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
+{
+ if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
+ pFormat->convertTextFormatting( rPropSet, rxTextProp );
+}
+
+void ObjectFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
+{
+ if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
+ pFormat->convertFormatting( rPropSet, rxShapeProp, rxTextProp );
+}
+
+void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps, ObjectType eObjType )
+{
+ if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
+ pFormat->convertTextFormatting( rPropSet, rTextProps );
+}
+
+void ObjectFormatter::convertTextRotation( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, bool bSupportsStacked )
+{
+ if( rxTextProp.is() )
+ {
+ bool bStacked = false;
+ if( bSupportsStacked )
+ {
+ sal_Int32 nVert = rxTextProp->getTextProperties().moVert.get( XML_horz );
+ bStacked = (nVert == XML_wordArtVert) || (nVert == XML_wordArtVertRtl);
+ rPropSet.setProperty( PROP_StackCharacters, bStacked );
+ }
+
+ /* Chart2 expects rotation angle as double value in range of [0,360).
+ OOXML counts clockwise, Chart2 counts counterclockwise. */
+ double fAngle = static_cast< double >( bStacked ? 0 : rxTextProp->getTextProperties().moRotation.get( 0 ) );
+ fAngle = getDoubleIntervalValue< double >( -fAngle / 60000.0, 0.0, 360.0 );
+ rPropSet.setProperty( PROP_TextRotation, fAngle );
+ }
+}
+
+void ObjectFormatter::convertNumberFormat( PropertySet& rPropSet, const NumberFormat& rNumberFormat, bool bPercentFormat )
+{
+ if( mxData->mxNumFmts.is() )
+ {
+ sal_Int32 nPropId = bPercentFormat ? PROP_PercentageNumberFormat : PROP_NumberFormat;
+ if( rNumberFormat.mbSourceLinked || (rNumberFormat.maFormatCode.getLength() == 0) )
+ {
+ rPropSet.setProperty( nPropId, Any() );
+ }
+ else try
+ {
+ sal_Int32 nIndex = rNumberFormat.maFormatCode.equalsIgnoreAsciiCaseAscii( "general" ) ?
+ mxData->mxNumTypes->getStandardIndex( mxData->maFromLocale ) :
+ mxData->mxNumFmts->addNewConverted( rNumberFormat.maFormatCode, mxData->maEnUsLocale, mxData->maFromLocale );
+ if( nIndex >= 0 )
+ rPropSet.setProperty( nPropId, nIndex );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false,
+ OStringBuffer( "ObjectFormatter::convertNumberFormat - cannot create number format '" ).
+ append( OUStringToOString( rNumberFormat.maFormatCode, osl_getThreadTextEncoding() ) ).append( '\'' ).getStr() );
+ }
+ }
+}
+
+void ObjectFormatter::convertAutomaticLine( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
+{
+ if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
+ pFormat->convertAutomaticLine( rPropSet, nSeriesIdx );
+}
+
+void ObjectFormatter::convertAutomaticFill( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
+{
+ if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
+ pFormat->convertAutomaticFill( rPropSet, nSeriesIdx );
+}
+
+/*static*/ bool ObjectFormatter::isAutomaticLine( const ModelRef< Shape >& rxShapeProp )
+{
+ return !rxShapeProp || !rxShapeProp->getLineProperties().maLineFill.moFillType.has();
+}
+
+/*static*/ bool ObjectFormatter::isAutomaticFill( const ModelRef< Shape >& rxShapeProp )
+{
+ return !rxShapeProp || !rxShapeProp->getFillProperties().moFillType.has();
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/plotareacontext.cxx b/oox/source/drawingml/chart/plotareacontext.cxx
new file mode 100644
index 000000000000..17c6487b59b4
--- /dev/null
+++ b/oox/source/drawingml/chart/plotareacontext.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/plotareacontext.hxx"
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/chart/axiscontext.hxx"
+#include "oox/drawingml/chart/plotareamodel.hxx"
+#include "oox/drawingml/chart/seriescontext.hxx"
+#include "oox/drawingml/chart/titlecontext.hxx"
+#include "oox/drawingml/chart/typegroupcontext.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+
+// ============================================================================
+
+View3DContext::View3DContext( ContextHandler2Helper& rParent, View3DModel& rModel ) :
+ ContextBase< View3DModel >( rParent, rModel )
+{
+}
+
+View3DContext::~View3DContext()
+{
+}
+
+ContextHandlerRef View3DContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( view3D ):
+ switch( nElement )
+ {
+ case C_TOKEN( depthPercent ):
+ mrModel.mnDepthPercent = rAttribs.getInteger( XML_val, 100 );
+ return 0;
+ case C_TOKEN( hPercent ):
+ mrModel.monHeightPercent = rAttribs.getInteger( XML_val, 100 );
+ return 0;
+ case C_TOKEN( perspective ):
+ mrModel.mnPerspective = rAttribs.getInteger( XML_val, 30 );
+ return 0;
+ case C_TOKEN( rAngAx ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbRightAngled = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( rotX ):
+ // default value dependent on chart type
+ mrModel.monRotationX = rAttribs.getInteger( XML_val );
+ return 0;
+ case C_TOKEN( rotY ):
+ // default value dependent on chart type
+ mrModel.monRotationY = rAttribs.getInteger( XML_val );
+ return 0;
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+WallFloorContext::WallFloorContext( ContextHandler2Helper& rParent, WallFloorModel& rModel ) :
+ ContextBase< WallFloorModel >( rParent, rModel )
+{
+}
+
+WallFloorContext::~WallFloorContext()
+{
+}
+
+ContextHandlerRef WallFloorContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( backWall ):
+ case C_TOKEN( floor ):
+ case C_TOKEN( sideWall ):
+ switch( nElement )
+ {
+ case C_TOKEN( pictureOptions ):
+ return new PictureOptionsContext( *this, mrModel.mxPicOptions.create() );
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+PlotAreaContext::PlotAreaContext( ContextHandler2Helper& rParent, PlotAreaModel& rModel ) :
+ ContextBase< PlotAreaModel >( rParent, rModel )
+{
+}
+
+PlotAreaContext::~PlotAreaContext()
+{
+}
+
+ContextHandlerRef PlotAreaContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( plotArea ):
+ switch( nElement )
+ {
+ case C_TOKEN( area3DChart ):
+ case C_TOKEN( areaChart ):
+ return new AreaTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+ case C_TOKEN( bar3DChart ):
+ case C_TOKEN( barChart ):
+ return new BarTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+ case C_TOKEN( bubbleChart ):
+ return new BubbleTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+ case C_TOKEN( line3DChart ):
+ case C_TOKEN( lineChart ):
+ case C_TOKEN( stockChart ):
+ return new LineTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+ case C_TOKEN( doughnutChart ):
+ case C_TOKEN( ofPieChart ):
+ case C_TOKEN( pie3DChart ):
+ case C_TOKEN( pieChart ):
+ return new PieTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+ case C_TOKEN( radarChart ):
+ return new RadarTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+ case C_TOKEN( scatterChart ):
+ return new ScatterTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+ case C_TOKEN( surface3DChart ):
+ case C_TOKEN( surfaceChart ):
+ return new SurfaceTypeGroupContext( *this, mrModel.maTypeGroups.create( nElement ) );
+
+ case C_TOKEN( catAx ):
+ return new CatAxisContext( *this, mrModel.maAxes.create( nElement ) );
+ case C_TOKEN( dateAx ):
+ return new DateAxisContext( *this, mrModel.maAxes.create( nElement ) );
+ case C_TOKEN( serAx ):
+ return new SerAxisContext( *this, mrModel.maAxes.create( nElement ) );
+ case C_TOKEN( valAx ):
+ return new ValAxisContext( *this, mrModel.maAxes.create( nElement ) );
+
+ case C_TOKEN( layout ):
+ return new LayoutContext( *this, mrModel.mxLayout.create() );
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/plotareaconverter.cxx b/oox/source/drawingml/chart/plotareaconverter.cxx
new file mode 100644
index 000000000000..78379ae855bd
--- /dev/null
+++ b/oox/source/drawingml/chart/plotareaconverter.cxx
@@ -0,0 +1,452 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/plotareaconverter.hxx"
+
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XDiagramPositioning.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XDiagram.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include "oox/drawingml/chart/axisconverter.hxx"
+#include "oox/drawingml/chart/plotareamodel.hxx"
+#include "oox/drawingml/chart/typegroupconverter.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+/** Axes set model. This is a helper for the plot area converter collecting all
+ type groups and axes of the primary or secondary axes set. */
+struct AxesSetModel
+{
+ typedef ModelVector< TypeGroupModel > TypeGroupVector;
+ typedef ModelMap< sal_Int32, AxisModel > AxisMap;
+
+ TypeGroupVector maTypeGroups; /// All type groups containing data series.
+ AxisMap maAxes; /// All axes mapped by API axis type.
+
+ inline explicit AxesSetModel() {}
+ inline ~AxesSetModel() {}
+};
+
+// ============================================================================
+
+/** Axes set converter. This is a helper class for the plot area converter. */
+class AxesSetConverter : public ConverterBase< AxesSetModel >
+{
+public:
+ explicit AxesSetConverter( const ConverterRoot& rParent, AxesSetModel& rModel );
+ virtual ~AxesSetConverter();
+
+ /** Converts the axes set model to a chart2 diagram. Returns an automatic
+ chart title from a single series title, if possible. */
+ void convertFromModel(
+ const Reference< XDiagram >& rxDiagram,
+ View3DModel& rView3DModel,
+ sal_Int32 nAxesSetIdx,
+ bool bSupportsVaryColorsByPoint );
+
+ /** Returns the automatic chart title if the axes set contains only one series. */
+ inline const ::rtl::OUString& getAutomaticTitle() const { return maAutoTitle; }
+ /** Returns true, if the chart is three-dimensional. */
+ inline bool is3dChart() const { return mb3dChart; }
+ /** Returns true, if chart type supports wall and floor format in 3D mode. */
+ inline bool isWall3dChart() const { return mbWall3dChart; }
+ /** Returns true, if chart is a pie chart or doughnut chart. */
+ inline bool isPieChart() const { return mbPieChart; }
+
+private:
+ ::rtl::OUString maAutoTitle;
+ bool mb3dChart;
+ bool mbWall3dChart;
+ bool mbPieChart;
+};
+
+// ----------------------------------------------------------------------------
+
+AxesSetConverter::AxesSetConverter( const ConverterRoot& rParent, AxesSetModel& rModel ) :
+ ConverterBase< AxesSetModel >( rParent, rModel ),
+ mb3dChart( false ),
+ mbWall3dChart( false ),
+ mbPieChart( false )
+{
+}
+
+AxesSetConverter::~AxesSetConverter()
+{
+}
+
+ModelRef< AxisModel > lclGetOrCreateAxis( const AxesSetModel::AxisMap& rFromAxes, sal_Int32 nAxisIdx, sal_Int32 nDefTypeId )
+{
+ ModelRef< AxisModel > xAxis = rFromAxes.get( nAxisIdx );
+ if( !xAxis )
+ xAxis.create( nDefTypeId ).mbDeleted = true; // missing axis is invisible
+ return xAxis;
+}
+
+void AxesSetConverter::convertFromModel( const Reference< XDiagram >& rxDiagram,
+ View3DModel& rView3DModel, sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint )
+{
+ // create type group converter objects for all type groups
+ typedef RefVector< TypeGroupConverter > TypeGroupConvVector;
+ TypeGroupConvVector aTypeGroups;
+ for( AxesSetModel::TypeGroupVector::iterator aIt = mrModel.maTypeGroups.begin(), aEnd = mrModel.maTypeGroups.end(); aIt != aEnd; ++aIt )
+ aTypeGroups.push_back( TypeGroupConvVector::value_type( new TypeGroupConverter( *this, **aIt ) ) );
+
+ OSL_ENSURE( !aTypeGroups.empty(), "AxesSetConverter::convertFromModel - no type groups in axes set" );
+ if( !aTypeGroups.empty() ) try
+ {
+ // first type group needed for coordinate system and axis conversion
+ TypeGroupConverter& rFirstTypeGroup = *aTypeGroups.front();
+
+ // get automatic chart title, if there is only one type group
+ if( aTypeGroups.size() == 1 )
+ maAutoTitle = rFirstTypeGroup.getSingleSeriesTitle();
+
+ /* Create a coordinate system. For now, all type groups from all axes sets
+ have to be inserted into one coordinate system. Later, chart2 should
+ support using one coordinate system for each axes set. */
+ Reference< XCoordinateSystem > xCoordSystem;
+ Reference< XCoordinateSystemContainer > xCoordSystemCont( rxDiagram, UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
+ if( aCoordSystems.hasElements() )
+ {
+ OSL_ENSURE( aCoordSystems.getLength() == 1, "AxesSetConverter::convertFromModel - too many coordinate systems" );
+ xCoordSystem = aCoordSystems[ 0 ];
+ OSL_ENSURE( xCoordSystem.is(), "AxesSetConverter::convertFromModel - invalid coordinate system" );
+ }
+ else
+ {
+ xCoordSystem = rFirstTypeGroup.createCoordinateSystem();
+ if( xCoordSystem.is() )
+ xCoordSystemCont->addCoordinateSystem( xCoordSystem );
+ }
+
+ // 3D view settings
+ mb3dChart = rFirstTypeGroup.is3dChart();
+ mbWall3dChart = rFirstTypeGroup.isWall3dChart();
+ mbPieChart = rFirstTypeGroup.getTypeInfo().meTypeCategory == TYPECATEGORY_PIE;
+ if( mb3dChart )
+ {
+ View3DConverter aView3DConv( *this, rView3DModel );
+ aView3DConv.convertFromModel( rxDiagram, rFirstTypeGroup );
+ }
+
+ /* Convert all chart type groups. Each type group will add its series
+ to the data provider attached to the chart document. */
+ if( xCoordSystem.is() )
+ {
+ // convert all axes (create missing axis models)
+ ModelRef< AxisModel > xXAxis = lclGetOrCreateAxis( mrModel.maAxes, API_X_AXIS, rFirstTypeGroup.getTypeInfo().mbCategoryAxis ? C_TOKEN( catAx ) : C_TOKEN( valAx ) );
+ ModelRef< AxisModel > xYAxis = lclGetOrCreateAxis( mrModel.maAxes, API_Y_AXIS, C_TOKEN( valAx ) );
+
+ AxisConverter aXAxisConv( *this, *xXAxis );
+ aXAxisConv.convertFromModel( xCoordSystem, rFirstTypeGroup, xYAxis.get(), nAxesSetIdx, API_X_AXIS );
+ AxisConverter aYAxisConv( *this, *xYAxis );
+ aYAxisConv.convertFromModel( xCoordSystem, rFirstTypeGroup, xXAxis.get(), nAxesSetIdx, API_Y_AXIS );
+
+ if( rFirstTypeGroup.isDeep3dChart() )
+ {
+ ModelRef< AxisModel > xZAxis = lclGetOrCreateAxis( mrModel.maAxes, API_Z_AXIS, C_TOKEN( serAx ) );
+ AxisConverter aZAxisConv( *this, *xZAxis );
+ aZAxisConv.convertFromModel( xCoordSystem, rFirstTypeGroup, 0, nAxesSetIdx, API_Z_AXIS );
+ }
+
+ // convert all chart type groups, this converts all series data and formatting
+ for( TypeGroupConvVector::iterator aTIt = aTypeGroups.begin(), aTEnd = aTypeGroups.end(); aTIt != aTEnd; ++aTIt )
+ (*aTIt)->convertFromModel( rxDiagram, xCoordSystem, nAxesSetIdx, bSupportsVaryColorsByPoint );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+View3DConverter::View3DConverter( const ConverterRoot& rParent, View3DModel& rModel ) :
+ ConverterBase< View3DModel >( rParent, rModel )
+{
+}
+
+View3DConverter::~View3DConverter()
+{
+}
+
+void View3DConverter::convertFromModel( const Reference< XDiagram >& rxDiagram, TypeGroupConverter& rTypeGroup )
+{
+ namespace cssd = ::com::sun::star::drawing;
+ PropertySet aPropSet( rxDiagram );
+
+ sal_Int32 nRotationY = 0;
+ sal_Int32 nRotationX = 0;
+ bool bRightAngled = false;
+ sal_Int32 nAmbientColor = 0;
+ sal_Int32 nLightColor = 0;
+
+ if( rTypeGroup.getTypeInfo().meTypeCategory == TYPECATEGORY_PIE )
+ {
+ // Y rotation used as 'first pie slice angle' in 3D pie charts
+ rTypeGroup.convertPieRotation( aPropSet, mrModel.monRotationY.get( 0 ) );
+ // X rotation a.k.a. elevation (map OOXML [0..90] to Chart2 [-90,0])
+ nRotationX = getLimitedValue< sal_Int32, sal_Int32 >( mrModel.monRotationX.get( 15 ), 0, 90 ) - 90;
+ // no right-angled axes in pie charts
+ bRightAngled = false;
+ // ambient color (Gray 30%)
+ nAmbientColor = 0xB3B3B3;
+ // light color (Gray 70%)
+ nLightColor = 0x4C4C4C;
+ }
+ else // 3D bar/area/line charts
+ {
+ // Y rotation (OOXML [0..359], Chart2 [-179,180])
+ nRotationY = mrModel.monRotationY.get( 20 );
+ // X rotation a.k.a. elevation (OOXML [-90..90], Chart2 [-179,180])
+ nRotationX = getLimitedValue< sal_Int32, sal_Int32 >( mrModel.monRotationX.get( 15 ), -90, 90 );
+ // right-angled axes
+ bRightAngled = mrModel.mbRightAngled;
+ // ambient color (Gray 20%)
+ nAmbientColor = 0xCCCCCC;
+ // light color (Gray 60%)
+ nLightColor = 0x666666;
+ }
+
+ // Y rotation (map OOXML [0..359] to Chart2 [-179,180])
+ nRotationY %= 360;
+ if( nRotationY > 180 ) nRotationY -= 360;
+ /* Perspective (map OOXML [0..200] to Chart2 [0,100]). Seems that MSO 2007 is
+ buggy here, the XML plugin of MSO 2003 writes the correct perspective in
+ the range from 0 to 100. We will emulate the wrong behaviour of MSO 2007. */
+ sal_Int32 nPerspective = getLimitedValue< sal_Int32, sal_Int32 >( mrModel.mnPerspective / 2, 0, 100 );
+ // projection mode (parallel axes, if right-angled, #i90360# or if perspective is at 0%)
+ bool bParallel = bRightAngled || (nPerspective == 0);
+ cssd::ProjectionMode eProjMode = bParallel ? cssd::ProjectionMode_PARALLEL : cssd::ProjectionMode_PERSPECTIVE;
+
+ // set rotation properties
+ aPropSet.setProperty( PROP_RotationVertical, nRotationY );
+ aPropSet.setProperty( PROP_RotationHorizontal, nRotationX );
+ aPropSet.setProperty( PROP_Perspective, nPerspective );
+ aPropSet.setProperty( PROP_RightAngledAxes, bRightAngled );
+ aPropSet.setProperty( PROP_D3DScenePerspective, eProjMode );
+
+ // set light settings
+ aPropSet.setProperty( PROP_D3DSceneShadeMode, cssd::ShadeMode_FLAT );
+ aPropSet.setProperty( PROP_D3DSceneAmbientColor, nAmbientColor );
+ aPropSet.setProperty( PROP_D3DSceneLightOn1, false );
+ aPropSet.setProperty( PROP_D3DSceneLightOn2, true );
+ aPropSet.setProperty( PROP_D3DSceneLightColor2, nLightColor );
+ aPropSet.setProperty( PROP_D3DSceneLightDirection2, cssd::Direction3D( 0.2, 0.4, 1.0 ) );
+}
+
+// ============================================================================
+
+WallFloorConverter::WallFloorConverter( const ConverterRoot& rParent, WallFloorModel& rModel ) :
+ ConverterBase< WallFloorModel >( rParent, rModel )
+{
+}
+
+WallFloorConverter::~WallFloorConverter()
+{
+}
+
+void WallFloorConverter::convertFromModel( const Reference< XDiagram >& rxDiagram, ObjectType eObjType )
+{
+ if( rxDiagram.is() )
+ {
+ PropertySet aPropSet;
+ switch( eObjType )
+ {
+ case OBJECTTYPE_FLOOR: aPropSet.set( rxDiagram->getFloor() ); break;
+ case OBJECTTYPE_WALL: aPropSet.set( rxDiagram->getWall() ); break;
+ default: OSL_ENSURE( false, "WallFloorConverter::convertFromModel - invalid object type" );
+ }
+ if( aPropSet.is() )
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxPicOptions.getOrCreate(), eObjType );
+ }
+}
+
+// ============================================================================
+
+PlotAreaConverter::PlotAreaConverter( const ConverterRoot& rParent, PlotAreaModel& rModel ) :
+ ConverterBase< PlotAreaModel >( rParent, rModel ),
+ mb3dChart( false ),
+ mbWall3dChart( false ),
+ mbPieChart( false )
+{
+}
+
+PlotAreaConverter::~PlotAreaConverter()
+{
+}
+
+void PlotAreaConverter::convertFromModel( View3DModel& rView3DModel )
+{
+ /* Create the diagram object and attach it to the chart document. One
+ diagram is used to carry all coordinate systems and data series. */
+ Reference< XDiagram > xDiagram;
+ try
+ {
+ xDiagram.set( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Diagram" ) ), UNO_QUERY_THROW );
+ getChartDocument()->setFirstDiagram( xDiagram );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // store all axis models in a map, keyed by axis identifier
+ typedef ModelMap< sal_Int32, AxisModel > AxisMap;
+ AxisMap aAxisMap;
+ for( PlotAreaModel::AxisVector::iterator aAIt = mrModel.maAxes.begin(), aAEnd = mrModel.maAxes.end(); aAIt != aAEnd; ++aAIt )
+ {
+ PlotAreaModel::AxisVector::value_type xAxis = *aAIt;
+ OSL_ENSURE( xAxis->mnAxisId >= 0, "PlotAreaConverter::convertFromModel - invalid axis identifier" );
+ OSL_ENSURE( !aAxisMap.has( xAxis->mnAxisId ), "PlotAreaConverter::convertFromModel - axis identifiers not unique" );
+ if( xAxis->mnAxisId >= 0 )
+ aAxisMap[ xAxis->mnAxisId ] = xAxis;
+ }
+
+ // group the type group models into different axes sets
+ typedef ModelVector< AxesSetModel > AxesSetVector;
+ AxesSetVector aAxesSets;
+ sal_Int32 nMaxSeriesIdx = -1;
+ for( PlotAreaModel::TypeGroupVector::iterator aTIt = mrModel.maTypeGroups.begin(), aTEnd = mrModel.maTypeGroups.end(); aTIt != aTEnd; ++aTIt )
+ {
+ PlotAreaModel::TypeGroupVector::value_type xTypeGroup = *aTIt;
+ if( !xTypeGroup->maSeries.empty() )
+ {
+ // try to find a compatible axes set for the type group
+ AxesSetModel* pAxesSet = 0;
+ for( AxesSetVector::iterator aASIt = aAxesSets.begin(), aASEnd = aAxesSets.end(); !pAxesSet && (aASIt != aASEnd); ++aASIt )
+ if( (*aASIt)->maTypeGroups.front()->maAxisIds == xTypeGroup->maAxisIds )
+ pAxesSet = aASIt->get();
+
+ // not possible to insert into an existing axes set -> start a new axes set
+ if( !pAxesSet )
+ {
+ pAxesSet = &aAxesSets.create();
+ // find axis models used by the type group
+ const TypeGroupModel::AxisIdVector& rAxisIds = xTypeGroup->maAxisIds;
+ if( rAxisIds.size() >= 1 )
+ pAxesSet->maAxes[ API_X_AXIS ] = aAxisMap.get( rAxisIds[ 0 ] );
+ if( rAxisIds.size() >= 2 )
+ pAxesSet->maAxes[ API_Y_AXIS ] = aAxisMap.get( rAxisIds[ 1 ] );
+ if( rAxisIds.size() >= 3 )
+ pAxesSet->maAxes[ API_Z_AXIS ] = aAxisMap.get( rAxisIds[ 2 ] );
+ }
+
+ // insert the type group model
+ pAxesSet->maTypeGroups.push_back( xTypeGroup );
+
+ // collect the maximum series index for automatic series formatting
+ for( TypeGroupModel::SeriesVector::iterator aSIt = xTypeGroup->maSeries.begin(), aSEnd = xTypeGroup->maSeries.end(); aSIt != aSEnd; ++aSIt )
+ nMaxSeriesIdx = ::std::max( nMaxSeriesIdx, (*aSIt)->mnIndex );
+ }
+ }
+ getFormatter().setMaxSeriesIndex( nMaxSeriesIdx );
+
+ // varying point colors only for single series in single chart type
+ bool bSupportsVaryColorsByPoint = mrModel.maTypeGroups.size() == 1;
+
+ // convert all axes sets
+ for( AxesSetVector::iterator aASBeg = aAxesSets.begin(), aASIt = aASBeg, aASEnd = aAxesSets.end(); aASIt != aASEnd; ++aASIt )
+ {
+ AxesSetConverter aAxesSetConv( *this, **aASIt );
+ sal_Int32 nAxesSetIdx = static_cast< sal_Int32 >( aASIt - aASBeg );
+ aAxesSetConv.convertFromModel( xDiagram, rView3DModel, nAxesSetIdx, bSupportsVaryColorsByPoint );
+ if( nAxesSetIdx == 0 )
+ {
+ maAutoTitle = aAxesSetConv.getAutomaticTitle();
+ mb3dChart = aAxesSetConv.is3dChart();
+ mbWall3dChart = aAxesSetConv.isWall3dChart();
+ mbPieChart = aAxesSetConv.isPieChart();
+ }
+ else
+ {
+ maAutoTitle = OUString();
+ }
+ }
+
+ // plot area formatting
+ if( xDiagram.is() && !mb3dChart )
+ {
+ PropertySet aPropSet( xDiagram->getWall() );
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, OBJECTTYPE_PLOTAREA2D );
+ }
+}
+
+void PlotAreaConverter::convertPositionFromModel()
+{
+ LayoutModel& rLayout = mrModel.mxLayout.getOrCreate();
+ LayoutConverter aLayoutConv( *this, rLayout );
+ Rectangle aDiagramRect;
+ if( aLayoutConv.calcAbsRectangle( aDiagramRect ) ) try
+ {
+ namespace cssc = ::com::sun::star::chart;
+ Reference< cssc::XChartDocument > xChart1Doc( getChartDocument(), UNO_QUERY_THROW );
+ Reference< cssc::XDiagramPositioning > xPositioning( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
+ // for pie charts, always set inner plot area size to exclude the data labels as Excel does
+ sal_Int32 nTarget = (mbPieChart && (rLayout.mnTarget == XML_outer)) ? XML_inner : rLayout.mnTarget;
+ switch( nTarget )
+ {
+ case XML_inner:
+ xPositioning->setDiagramPositionExcludingAxes( aDiagramRect );
+ break;
+ case XML_outer:
+ xPositioning->setDiagramPositionIncludingAxes( aDiagramRect );
+ break;
+ default:
+ OSL_ENSURE( false, "PlotAreaConverter::convertPositionFromModel - unknown positioning target" );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/plotareamodel.cxx b/oox/source/drawingml/chart/plotareamodel.cxx
new file mode 100644
index 000000000000..324186526cc6
--- /dev/null
+++ b/oox/source/drawingml/chart/plotareamodel.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/plotareamodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+View3DModel::View3DModel() :
+ mnDepthPercent( 100 ),
+ mnPerspective( 30 ),
+ mbRightAngled( false )
+{
+}
+
+View3DModel::~View3DModel()
+{
+}
+
+// ============================================================================
+
+WallFloorModel::WallFloorModel()
+{
+}
+
+WallFloorModel::~WallFloorModel()
+{
+}
+
+// ============================================================================
+
+PlotAreaModel::PlotAreaModel()
+{
+}
+
+PlotAreaModel::~PlotAreaModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/chart/seriescontext.cxx b/oox/source/drawingml/chart/seriescontext.cxx
new file mode 100644
index 000000000000..014ca51e869d
--- /dev/null
+++ b/oox/source/drawingml/chart/seriescontext.cxx
@@ -0,0 +1,754 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/seriescontext.hxx"
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/chart/datasourcecontext.hxx"
+#include "oox/drawingml/chart/seriesmodel.hxx"
+#include "oox/drawingml/chart/titlecontext.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::oox::core::ContextHandler2;
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+ContextHandlerRef lclDataLabelSharedCreateContext( ContextHandler2& rContext,
+ sal_Int32 nElement, const AttributeList& rAttribs, DataLabelModelBase& orModel )
+{
+ if( rContext.isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( delete ):
+ // default is 'false', not 'true' as specified
+ orModel.mbDeleted = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( dLblPos ):
+ orModel.monLabelPos = rAttribs.getToken( XML_val, XML_TOKEN_INVALID );
+ return 0;
+ case C_TOKEN( numFmt ):
+ orModel.maNumberFormat.setAttributes( rAttribs );
+ return 0;
+ case C_TOKEN( showBubbleSize ):
+ orModel.mobShowBubbleSize = rAttribs.getBool( XML_val );
+ return 0;
+ case C_TOKEN( showCatName ):
+ orModel.mobShowCatName = rAttribs.getBool( XML_val );
+ return 0;
+ case C_TOKEN( showLegendKey ):
+ orModel.mobShowLegendKey = rAttribs.getBool( XML_val );
+ return 0;
+ case C_TOKEN( showPercent ):
+ orModel.mobShowPercent = rAttribs.getBool( XML_val );
+ return 0;
+ case C_TOKEN( showSerName ):
+ orModel.mobShowSerName = rAttribs.getBool( XML_val );
+ return 0;
+ case C_TOKEN( showVal ):
+ orModel.mobShowVal = rAttribs.getBool( XML_val );
+ return 0;
+ case C_TOKEN( separator ):
+ // collect separator text in onCharacters()
+ return &rContext;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( rContext, orModel.mxShapeProp.create() );
+ case C_TOKEN( txPr ):
+ return new TextBodyContext( rContext, orModel.mxTextProp.create() );
+ }
+ return 0;
+}
+
+void lclDataLabelSharedCharacters( ContextHandler2& rContext, const OUString& rChars, DataLabelModelBase& orModel )
+{
+ if( rContext.isCurrentElement( C_TOKEN( separator ) ) )
+ orModel.moaSeparator = rChars;
+}
+
+} // namespace
+
+// ============================================================================
+
+DataLabelContext::DataLabelContext( ContextHandler2Helper& rParent, DataLabelModel& rModel ) :
+ ContextBase< DataLabelModel >( rParent, rModel )
+{
+}
+
+DataLabelContext::~DataLabelContext()
+{
+}
+
+ContextHandlerRef DataLabelContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( idx ):
+ mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( layout ):
+ return new LayoutContext( *this, mrModel.mxLayout.create() );
+ case C_TOKEN( tx ):
+ return new TextContext( *this, mrModel.mxText.create() );
+ }
+ return lclDataLabelSharedCreateContext( *this, nElement, rAttribs, mrModel );
+}
+
+void DataLabelContext::onCharacters( const OUString& rChars )
+{
+ lclDataLabelSharedCharacters( *this, rChars, mrModel );
+}
+
+// ============================================================================
+
+DataLabelsContext::DataLabelsContext( ContextHandler2Helper& rParent, DataLabelsModel& rModel ) :
+ ContextBase< DataLabelsModel >( rParent, rModel )
+{
+}
+
+DataLabelsContext::~DataLabelsContext()
+{
+}
+
+ContextHandlerRef DataLabelsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( dLbl ):
+ return new DataLabelContext( *this, mrModel.maPointLabels.create() );
+ case C_TOKEN( leaderLines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxLeaderLines.create() );
+ case C_TOKEN( showLeaderLines ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbShowLeaderLines = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return lclDataLabelSharedCreateContext( *this, nElement, rAttribs, mrModel );
+}
+
+void DataLabelsContext::onCharacters( const OUString& rChars )
+{
+ lclDataLabelSharedCharacters( *this, rChars, mrModel );
+}
+
+// ============================================================================
+
+PictureOptionsContext::PictureOptionsContext( ContextHandler2Helper& rParent, PictureOptionsModel& rModel ) :
+ ContextBase< PictureOptionsModel >( rParent, rModel )
+{
+}
+
+PictureOptionsContext::~PictureOptionsContext()
+{
+}
+
+ContextHandlerRef PictureOptionsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( applyToEnd ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbApplyToEnd = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( applyToFront ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbApplyToFront = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( applyToSides ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbApplyToSides = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( pictureFormat ):
+ mrModel.mnPictureFormat = rAttribs.getToken( XML_val, XML_stretch );
+ return 0;
+ case C_TOKEN( pictureStackUnit ):
+ mrModel.mfStackUnit = rAttribs.getDouble( XML_val, 1.0 );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ErrorBarContext::ErrorBarContext( ContextHandler2Helper& rParent, ErrorBarModel& rModel ) :
+ ContextBase< ErrorBarModel >( rParent, rModel )
+{
+}
+
+ErrorBarContext::~ErrorBarContext()
+{
+}
+
+ContextHandlerRef ErrorBarContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( errBarType ):
+ mrModel.mnTypeId = rAttribs.getToken( XML_val, XML_both );
+ return 0;
+ case C_TOKEN( errDir ):
+ mrModel.mnDirection = rAttribs.getToken( XML_val, XML_TOKEN_INVALID );
+ return 0;
+ case C_TOKEN( errValType ):
+ mrModel.mnValueType = rAttribs.getToken( XML_val, XML_fixedVal );
+ return 0;
+ case C_TOKEN( minus ):
+ return new DataSourceContext( *this, mrModel.maSources.create( ErrorBarModel::MINUS ) );
+ case C_TOKEN( noEndCap ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbNoEndCap = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( plus ):
+ return new DataSourceContext( *this, mrModel.maSources.create( ErrorBarModel::PLUS ) );
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ case C_TOKEN( val ):
+ mrModel.mfValue = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+TrendlineLabelContext::TrendlineLabelContext( ContextHandler2Helper& rParent, TrendlineLabelModel& rModel ) :
+ ContextBase< TrendlineLabelModel >( rParent, rModel )
+{
+}
+
+TrendlineLabelContext::~TrendlineLabelContext()
+{
+}
+
+ContextHandlerRef TrendlineLabelContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( layout ):
+ return new LayoutContext( *this, mrModel.mxLayout.create() );
+ case C_TOKEN( numFmt ):
+ mrModel.maNumberFormat.setAttributes( rAttribs );
+ return 0;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ case C_TOKEN( tx ):
+ return new TextContext( *this, mrModel.mxText.create() );
+ case C_TOKEN( txPr ):
+ return new TextBodyContext( *this, mrModel.mxTextProp.create() );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+TrendlineContext::TrendlineContext( ContextHandler2Helper& rParent, TrendlineModel& rModel ) :
+ ContextBase< TrendlineModel >( rParent, rModel )
+{
+}
+
+TrendlineContext::~TrendlineContext()
+{
+}
+
+ContextHandlerRef TrendlineContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( backward ):
+ mrModel.mfBackward = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( dispEq ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbDispEquation = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( dispRSqr ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbDispRSquared = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( forward ):
+ mrModel.mfForward = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( intercept ):
+ mrModel.mfIntercept = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( name ):
+ return this; // collect name in onCharacters()
+ case C_TOKEN( order ):
+ mrModel.mnOrder = rAttribs.getInteger( XML_val, 2 );
+ return 0;
+ case C_TOKEN( period ):
+ mrModel.mnPeriod = rAttribs.getInteger( XML_val, 2 );
+ return 0;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ case C_TOKEN( trendlineLbl ):
+ return new TrendlineLabelContext( *this, mrModel.mxLabel.create() );
+ case C_TOKEN( trendlineType ):
+ mrModel.mnTypeId = rAttribs.getToken( XML_val, XML_linear );
+ return 0;
+ }
+ return 0;
+}
+
+void TrendlineContext::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( C_TOKEN( name ) ) )
+ mrModel.maName = rChars;
+}
+
+// ============================================================================
+
+DataPointContext::DataPointContext( ContextHandler2Helper& rParent, DataPointModel& rModel ) :
+ ContextBase< DataPointModel >( rParent, rModel )
+{
+}
+
+DataPointContext::~DataPointContext()
+{
+}
+
+ContextHandlerRef DataPointContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( dPt ):
+ switch( nElement )
+ {
+ case C_TOKEN( bubble3D ):
+ mrModel.mobBubble3d = rAttribs.getBool( XML_val );
+ return 0;
+ case C_TOKEN( explosion ):
+ // if the 'val' attribute is missing, series explosion remains unchanged
+ mrModel.monExplosion = rAttribs.getInteger( XML_val );
+ return 0;
+ case C_TOKEN( idx ):
+ mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( invertIfNegative ):
+ // default is 'false', not 'true' as specified (value not derived from series!)
+ mrModel.mbInvertNeg = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( marker ):
+ return this;
+ case C_TOKEN( pictureOptions ):
+ return new PictureOptionsContext( *this, mrModel.mxPicOptions.create() );
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ }
+ break;
+
+ case C_TOKEN( marker ):
+ switch( nElement )
+ {
+ case C_TOKEN( size ):
+ mrModel.monMarkerSize = rAttribs.getInteger( XML_val, 5 );
+ return 0;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxMarkerProp.create() );
+ case C_TOKEN( symbol ):
+ mrModel.monMarkerSymbol = rAttribs.getToken( XML_val, XML_none );
+ return 0;
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+SeriesContextBase::SeriesContextBase( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ ContextBase< SeriesModel >( rParent, rModel )
+{
+}
+
+SeriesContextBase::~SeriesContextBase()
+{
+}
+
+ContextHandlerRef SeriesContextBase::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( idx ):
+ mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( order ):
+ mrModel.mnOrder = rAttribs.getInteger( XML_val, -1 );
+ return 0;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+ case C_TOKEN( tx ):
+ return new TextContext( *this, mrModel.mxText.create() );
+ }
+ break;
+
+ case C_TOKEN( marker ):
+ switch( nElement )
+ {
+ case C_TOKEN( size ):
+ mrModel.mnMarkerSize = rAttribs.getInteger( XML_val, 5 );
+ return 0;
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxMarkerProp.create() );
+ case C_TOKEN( symbol ):
+ mrModel.mnMarkerSymbol = rAttribs.getToken( XML_val, XML_none );
+ return 0;
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+AreaSeriesContext::AreaSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+AreaSeriesContext::~AreaSeriesContext()
+{
+}
+
+ContextHandlerRef AreaSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( cat ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( errBars ):
+ return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dPt ):
+ return new DataPointContext( *this, mrModel.maPoints.create() );
+ case C_TOKEN( trendline ):
+ return new TrendlineContext( *this, mrModel.maTrendlines.create() );
+ case C_TOKEN( val ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+BarSeriesContext::BarSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+BarSeriesContext::~BarSeriesContext()
+{
+}
+
+ContextHandlerRef BarSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( cat ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dPt ):
+ return new DataPointContext( *this, mrModel.maPoints.create() );
+ case C_TOKEN( errBars ):
+ return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
+ case C_TOKEN( invertIfNegative ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbInvertNeg = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( pictureOptions ):
+ return new PictureOptionsContext( *this, mrModel.mxPicOptions.create() );
+ case C_TOKEN( shape ):
+ // missing attribute does not change shape type to 'box' as specified
+ mrModel.monShape = rAttribs.getToken( XML_val );
+ return 0;
+ case C_TOKEN( trendline ):
+ return new TrendlineContext( *this, mrModel.maTrendlines.create() );
+ case C_TOKEN( val ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+BubbleSeriesContext::BubbleSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+BubbleSeriesContext::~BubbleSeriesContext()
+{
+}
+
+ContextHandlerRef BubbleSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( bubble3D ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbBubble3d = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( bubbleSize ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::POINTS ) );
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dPt ):
+ return new DataPointContext( *this, mrModel.maPoints.create() );
+ case C_TOKEN( errBars ):
+ return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
+ case C_TOKEN( invertIfNegative ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbInvertNeg = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( trendline ):
+ return new TrendlineContext( *this, mrModel.maTrendlines.create() );
+ case C_TOKEN( xVal ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( yVal ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+LineSeriesContext::LineSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+LineSeriesContext::~LineSeriesContext()
+{
+}
+
+ContextHandlerRef LineSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( cat ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dPt ):
+ return new DataPointContext( *this, mrModel.maPoints.create() );
+ case C_TOKEN( errBars ):
+ return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
+ case C_TOKEN( marker ):
+ return this;
+ case C_TOKEN( smooth ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbSmooth = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( trendline ):
+ return new TrendlineContext( *this, mrModel.maTrendlines.create() );
+ case C_TOKEN( val ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+PieSeriesContext::PieSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+PieSeriesContext::~PieSeriesContext()
+{
+}
+
+ContextHandlerRef PieSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( cat ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dPt ):
+ return new DataPointContext( *this, mrModel.maPoints.create() );
+ case C_TOKEN( explosion ):
+ mrModel.mnExplosion = rAttribs.getInteger( XML_val, 0 );
+ return 0;
+ case C_TOKEN( val ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+RadarSeriesContext::RadarSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+RadarSeriesContext::~RadarSeriesContext()
+{
+}
+
+ContextHandlerRef RadarSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( cat ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dPt ):
+ return new DataPointContext( *this, mrModel.maPoints.create() );
+ case C_TOKEN( marker ):
+ return this;
+ case C_TOKEN( smooth ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbSmooth = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( val ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+ScatterSeriesContext::ScatterSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+ScatterSeriesContext::~ScatterSeriesContext()
+{
+}
+
+ContextHandlerRef ScatterSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dPt ):
+ return new DataPointContext( *this, mrModel.maPoints.create() );
+ case C_TOKEN( errBars ):
+ return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
+ case C_TOKEN( marker ):
+ return this;
+ case C_TOKEN( smooth ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbSmooth = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( trendline ):
+ return new TrendlineContext( *this, mrModel.maTrendlines.create() );
+ case C_TOKEN( xVal ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( yVal ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+SurfaceSeriesContext::SurfaceSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
+ SeriesContextBase( rParent, rModel )
+{
+}
+
+SurfaceSeriesContext::~SurfaceSeriesContext()
+{
+}
+
+ContextHandlerRef SurfaceSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( ser ):
+ switch( nElement )
+ {
+ case C_TOKEN( cat ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
+ case C_TOKEN( val ):
+ return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
+ }
+ break;
+ }
+ return SeriesContextBase::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx
new file mode 100644
index 000000000000..b9eaee5c01be
--- /dev/null
+++ b/oox/source/drawingml/chart/seriesconverter.cxx
@@ -0,0 +1,619 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/seriesconverter.hxx"
+
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/XDataSeries.hpp>
+#include <com/sun/star/chart2/XRegressionCurve.hpp>
+#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+#include <com/sun/star/chart2/data/XDataSink.hpp>
+#include "oox/drawingml/chart/datasourceconverter.hxx"
+#include "oox/drawingml/chart/seriesmodel.hxx"
+#include "oox/drawingml/chart/titleconverter.hxx"
+#include "oox/drawingml/chart/typegroupconverter.hxx"
+#include "oox/drawingml/chart/typegroupmodel.hxx"
+#include "oox/helper/containerhelper.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::chart2::data;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
+ const ConverterRoot& rParent,
+ DataSourceModel* pValues, const OUString& rRole,
+ TextModel* pTitle = 0 )
+{
+ // create data sequence for values
+ Reference< XDataSequence > xValueSeq;
+ if( pValues )
+ {
+ DataSourceConverter aSourceConv( rParent, *pValues );
+ xValueSeq = aSourceConv.createDataSequence( rRole );
+ }
+
+ // create data sequence for title
+ Reference< XDataSequence > xTitleSeq;
+ if( pTitle )
+ {
+ TextConverter aTextConv( rParent, *pTitle );
+ xTitleSeq = aTextConv.createDataSequence( CREATE_OUSTRING( "label" ) );
+ }
+
+ // create the labeled data sequence, if values or title are present
+ Reference< XLabeledDataSequence > xLabeledSeq;
+ if( xValueSeq.is() || xTitleSeq.is() )
+ {
+ xLabeledSeq.set( rParent.createInstance( CREATE_OUSTRING( "com.sun.star.chart2.data.LabeledDataSequence" ) ), UNO_QUERY );
+ if( xLabeledSeq.is() )
+ {
+ xLabeledSeq->setValues( xValueSeq );
+ xLabeledSeq->setLabel( xTitleSeq );
+ }
+ }
+ return xLabeledSeq;
+}
+
+void lclConvertLabelFormatting( PropertySet& rPropSet, ObjectFormatter& rFormatter,
+ const DataLabelModelBase& rDataLabel, const TypeGroupConverter& rTypeGroup, bool bDataSeriesLabel )
+{
+ const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
+
+ /* Excel 2007 does not change the series setting for a single data point,
+ if none of some specific elements occur. But only one existing element
+ in a data point will reset most other of these elements from the series
+ (e.g.: series has <c:showVal>, data point has <c:showCatName>, this
+ will reset <c:showVal> for this point, unless <c:showVal> is repeated
+ in the data point). The elements <c:layout>, <c:numberFormat>,
+ <c:spPr>, <c:tx>, and <c:txPr> are not affected at all. */
+ bool bHasAnyElement =
+ rDataLabel.moaSeparator.has() || rDataLabel.monLabelPos.has() ||
+ rDataLabel.mobShowCatName.has() || rDataLabel.mobShowLegendKey.has() ||
+ rDataLabel.mobShowPercent.has() || rDataLabel.mobShowSerName.has() ||
+ rDataLabel.mobShowVal.has();
+
+ bool bShowValue = !rDataLabel.mbDeleted && rDataLabel.mobShowVal.get( false );
+ bool bShowPercent = !rDataLabel.mbDeleted && rDataLabel.mobShowPercent.get( false ) && (rTypeInfo.meTypeCategory == TYPECATEGORY_PIE);
+ bool bShowCateg = !rDataLabel.mbDeleted && rDataLabel.mobShowCatName.get( false );
+ bool bShowSymbol = !rDataLabel.mbDeleted && rDataLabel.mobShowLegendKey.get( false );
+
+ // type of attached label
+ if( bHasAnyElement || rDataLabel.mbDeleted )
+ {
+ DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
+ rPropSet.setProperty( PROP_Label, aPointLabel );
+ }
+
+ if( !rDataLabel.mbDeleted )
+ {
+ // data label number format (percentage format wins over value format)
+ rFormatter.convertNumberFormat( rPropSet, rDataLabel.maNumberFormat, bShowPercent );
+
+ // data label text formatting (frame formatting not supported by Chart2)
+ rFormatter.convertTextFormatting( rPropSet, rDataLabel.mxTextProp, OBJECTTYPE_DATALABEL );
+ rFormatter.convertTextRotation( rPropSet, rDataLabel.mxTextProp, false );
+
+ // data label separator (do not overwrite series separator, if no explicit point separator is present)
+ if( bDataSeriesLabel || rDataLabel.moaSeparator.has() )
+ rPropSet.setProperty( PROP_LabelSeparator, rDataLabel.moaSeparator.get( CREATE_OUSTRING( "; " ) ) );
+
+ // data label placement (do not overwrite series placement, if no explicit point placement is present)
+ if( bDataSeriesLabel || rDataLabel.monLabelPos.has() )
+ {
+ namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
+ sal_Int32 nPlacement = rTypeInfo.mnDefLabelPos;
+ switch( rDataLabel.monLabelPos.get( XML_TOKEN_INVALID ) )
+ {
+ case XML_outEnd: nPlacement = csscd::OUTSIDE; break;
+ case XML_inEnd: nPlacement = csscd::INSIDE; break;
+ case XML_ctr: nPlacement = csscd::CENTER; break;
+ case XML_inBase: nPlacement = csscd::NEAR_ORIGIN; break;
+ case XML_t: nPlacement = csscd::TOP; break;
+ case XML_b: nPlacement = csscd::BOTTOM; break;
+ case XML_l: nPlacement = csscd::LEFT; break;
+ case XML_r: nPlacement = csscd::RIGHT; break;
+ case XML_bestFit: nPlacement = csscd::AVOID_OVERLAP; break;
+ }
+ rPropSet.setProperty( PROP_LabelPlacement, nPlacement );
+ }
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+DataLabelConverter::DataLabelConverter( const ConverterRoot& rParent, DataLabelModel& rModel ) :
+ ConverterBase< DataLabelModel >( rParent, rModel )
+{
+}
+
+DataLabelConverter::~DataLabelConverter()
+{
+}
+
+void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries, const TypeGroupConverter& rTypeGroup )
+{
+ if( rxDataSeries.is() ) try
+ {
+ PropertySet aPropSet( rxDataSeries->getDataPointByIndex( mrModel.mnIndex ) );
+ lclConvertLabelFormatting( aPropSet, getFormatter(), mrModel, rTypeGroup, false );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+DataLabelsConverter::DataLabelsConverter( const ConverterRoot& rParent, DataLabelsModel& rModel ) :
+ ConverterBase< DataLabelsModel >( rParent, rModel )
+{
+}
+
+DataLabelsConverter::~DataLabelsConverter()
+{
+}
+
+void DataLabelsConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries, const TypeGroupConverter& rTypeGroup )
+{
+ if( !mrModel.mbDeleted )
+ {
+ PropertySet aPropSet( rxDataSeries );
+ lclConvertLabelFormatting( aPropSet, getFormatter(), mrModel, rTypeGroup, true );
+ }
+
+ // data point label settings
+ for( DataLabelsModel::DataLabelVector::iterator aIt = mrModel.maPointLabels.begin(), aEnd = mrModel.maPointLabels.end(); aIt != aEnd; ++aIt )
+ {
+ DataLabelConverter aLabelConv( *this, **aIt );
+ aLabelConv.convertFromModel( rxDataSeries, rTypeGroup );
+ }
+}
+
+// ============================================================================
+
+ErrorBarConverter::ErrorBarConverter( const ConverterRoot& rParent, ErrorBarModel& rModel ) :
+ ConverterBase< ErrorBarModel >( rParent, rModel )
+{
+}
+
+ErrorBarConverter::~ErrorBarConverter()
+{
+}
+
+void ErrorBarConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries )
+{
+ bool bShowPos = (mrModel.mnTypeId == XML_plus) || (mrModel.mnTypeId == XML_both);
+ bool bShowNeg = (mrModel.mnTypeId == XML_minus) || (mrModel.mnTypeId == XML_both);
+ if( bShowPos || bShowNeg ) try
+ {
+ Reference< XPropertySet > xErrorBar( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.ErrorBar" ) ), UNO_QUERY_THROW );
+ PropertySet aBarProp( xErrorBar );
+
+ // plus/minus bars
+ aBarProp.setProperty( PROP_ShowPositiveError, bShowPos );
+ aBarProp.setProperty( PROP_ShowNegativeError, bShowNeg );
+
+ // type of displayed error
+ namespace cssc = ::com::sun::star::chart;
+ switch( mrModel.mnValueType )
+ {
+ case XML_cust:
+ {
+ // #i87806# manual error bars
+ aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::FROM_DATA );
+ // attach data sequences to erorr bar
+ Reference< XDataSink > xDataSink( xErrorBar, UNO_QUERY );
+ if( xDataSink.is() )
+ {
+ // create vector of all value sequences
+ ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
+ // add positive values
+ if( bShowPos )
+ {
+ Reference< XLabeledDataSequence > xValueSeq = createLabeledDataSequence( ErrorBarModel::PLUS );
+ if( xValueSeq.is() )
+ aLabeledSeqVec.push_back( xValueSeq );
+ }
+ // add negative values
+ if( bShowNeg )
+ {
+ Reference< XLabeledDataSequence > xValueSeq = createLabeledDataSequence( ErrorBarModel::MINUS );
+ if( xValueSeq.is() )
+ aLabeledSeqVec.push_back( xValueSeq );
+ }
+ // attach labeled data sequences to series
+ if( aLabeledSeqVec.empty() )
+ xErrorBar.clear();
+ else
+ xDataSink->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec ) );
+ }
+ }
+ break;
+ case XML_fixedVal:
+ aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::ABSOLUTE );
+ aBarProp.setProperty( PROP_PositiveError, mrModel.mfValue );
+ aBarProp.setProperty( PROP_NegativeError, mrModel.mfValue );
+ break;
+ case XML_percentage:
+ aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::RELATIVE );
+ aBarProp.setProperty( PROP_PositiveError, mrModel.mfValue );
+ aBarProp.setProperty( PROP_NegativeError, mrModel.mfValue );
+ break;
+ case XML_stdDev:
+ aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::STANDARD_DEVIATION );
+ aBarProp.setProperty( PROP_Weight, mrModel.mfValue );
+ break;
+ case XML_stdErr:
+ aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::STANDARD_ERROR );
+ break;
+ default:
+ OSL_ENSURE( false, "ErrorBarConverter::convertFromModel - unknown error bar type" );
+ xErrorBar.clear();
+ }
+
+ // error bar formatting
+ getFormatter().convertFrameFormatting( aBarProp, mrModel.mxShapeProp, OBJECTTYPE_ERRORBAR );
+
+ if( xErrorBar.is() )
+ {
+ PropertySet aSeriesProp( rxDataSeries );
+ switch( mrModel.mnDirection )
+ {
+ case XML_x: aSeriesProp.setProperty( PROP_ErrorBarX, xErrorBar ); break;
+ case XML_y: aSeriesProp.setProperty( PROP_ErrorBarY, xErrorBar ); break;
+ default: OSL_ENSURE( false, "ErrorBarConverter::convertFromModel - invalid error bar direction" );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "ErrorBarConverter::convertFromModel - error while creating error bars" );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+Reference< XLabeledDataSequence > ErrorBarConverter::createLabeledDataSequence( ErrorBarModel::SourceType eSourceType )
+{
+ OUString aRole;
+ switch( eSourceType )
+ {
+ case ErrorBarModel::PLUS:
+ switch( mrModel.mnDirection )
+ {
+ case XML_x: aRole = CREATE_OUSTRING( "error-bars-x-positive" ); break;
+ case XML_y: aRole = CREATE_OUSTRING( "error-bars-y-positive" ); break;
+ }
+ break;
+ case ErrorBarModel::MINUS:
+ switch( mrModel.mnDirection )
+ {
+ case XML_x: aRole = CREATE_OUSTRING( "error-bars-x-negative" ); break;
+ case XML_y: aRole = CREATE_OUSTRING( "error-bars-y-negative" ); break;
+ }
+ break;
+ }
+ OSL_ENSURE( aRole.getLength() > 0, "ErrorBarConverter::createLabeledDataSequence - invalid error bar direction" );
+ return lclCreateLabeledDataSequence( *this, mrModel.maSources.get( eSourceType ).get(), aRole );
+}
+
+// ============================================================================
+
+TrendlineLabelConverter::TrendlineLabelConverter( const ConverterRoot& rParent, TrendlineLabelModel& rModel ) :
+ ConverterBase< TrendlineLabelModel >( rParent, rModel )
+{
+}
+
+TrendlineLabelConverter::~TrendlineLabelConverter()
+{
+}
+
+void TrendlineLabelConverter::convertFromModel( PropertySet& rPropSet )
+{
+ // formatting
+ getFormatter().convertFormatting( rPropSet, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_TRENDLINELABEL );
+}
+
+// ============================================================================
+
+TrendlineConverter::TrendlineConverter( const ConverterRoot& rParent, TrendlineModel& rModel ) :
+ ConverterBase< TrendlineModel >( rParent, rModel )
+{
+}
+
+TrendlineConverter::~TrendlineConverter()
+{
+}
+
+void TrendlineConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries )
+{
+ try
+ {
+ // trend line type
+ OUString aServiceName;
+ switch( mrModel.mnTypeId )
+ {
+ case XML_exp: aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.ExponentialRegressionCurve" ); break;
+ case XML_linear: aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.LinearRegressionCurve" ); break;
+ case XML_log: aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.LogarithmicRegressionCurve" ); break;
+ case XML_movingAvg: /* #i66819# moving average trendlines not supported */ break;
+ case XML_poly: /* #i20819# polynomial trendlines not supported */ break;
+ case XML_power: aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.PotentialRegressionCurve" ); break;
+ default: OSL_ENSURE( false, "TrendlineConverter::convertFromModel - unknown trendline type" );
+ }
+ if( aServiceName.getLength() > 0 )
+ {
+ Reference< XRegressionCurve > xRegCurve( createInstance( aServiceName ), UNO_QUERY_THROW );
+ PropertySet aPropSet( xRegCurve );
+
+ // trendline formatting
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, OBJECTTYPE_TRENDLINE );
+
+ // #i83100# show equation and correlation coefficient
+ PropertySet aLabelProp( xRegCurve->getEquationProperties() );
+ aLabelProp.setProperty( PROP_ShowEquation, mrModel.mbDispEquation );
+ aLabelProp.setProperty( PROP_ShowCorrelationCoefficient, mrModel.mbDispRSquared );
+
+ // #i83100# formatting of the equation text box
+ if( mrModel.mbDispEquation || mrModel.mbDispRSquared )
+ {
+ TrendlineLabelConverter aLabelConv( *this, mrModel.mxLabel.getOrCreate() );
+ aLabelConv.convertFromModel( aLabelProp );
+ }
+
+ // unsupported: #i5085# manual trendline size
+ // unsupported: #i34093# manual crossing point
+
+ Reference< XRegressionCurveContainer > xRegCurveCont( rxDataSeries, UNO_QUERY_THROW );
+ xRegCurveCont->addRegressionCurve( xRegCurve );
+ }
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "TrendlineConverter::convertFromModel - error while creating trendline" );
+ }
+}
+
+// ============================================================================
+
+DataPointConverter::DataPointConverter( const ConverterRoot& rParent, DataPointModel& rModel ) :
+ ConverterBase< DataPointModel >( rParent, rModel )
+{
+}
+
+DataPointConverter::~DataPointConverter()
+{
+}
+
+void DataPointConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries,
+ const TypeGroupConverter& rTypeGroup, const SeriesModel& rSeries )
+{
+ try
+ {
+ PropertySet aPropSet( rxDataSeries->getDataPointByIndex( mrModel.mnIndex ) );
+
+ // data point marker
+ if( mrModel.monMarkerSymbol.differsFrom( rSeries.mnMarkerSymbol ) || mrModel.monMarkerSize.differsFrom( rSeries.mnMarkerSize ) )
+ rTypeGroup.convertMarker( aPropSet, mrModel.monMarkerSymbol.get( rSeries.mnMarkerSymbol ), mrModel.monMarkerSize.get( rSeries.mnMarkerSize ) );
+
+ // data point pie explosion
+ if( mrModel.monExplosion.differsFrom( rSeries.mnExplosion ) )
+ rTypeGroup.convertPieExplosion( aPropSet, mrModel.monExplosion.get() );
+
+ // point formatting
+ if( mrModel.mxShapeProp.is() )
+ {
+ if( rTypeGroup.getTypeInfo().mbPictureOptions )
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxPicOptions.getOrCreate(), rTypeGroup.getSeriesObjectType(), rSeries.mnIndex );
+ else
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, rTypeGroup.getSeriesObjectType(), rSeries.mnIndex );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+SeriesConverter::SeriesConverter( const ConverterRoot& rParent, SeriesModel& rModel ) :
+ ConverterBase< SeriesModel >( rParent, rModel )
+{
+}
+
+SeriesConverter::~SeriesConverter()
+{
+}
+
+Reference< XLabeledDataSequence > SeriesConverter::createCategorySequence( const OUString& rRole )
+{
+ return createLabeledDataSequence( SeriesModel::CATEGORIES, rRole, false );
+}
+
+Reference< XLabeledDataSequence > SeriesConverter::createValueSequence( const OUString& rRole )
+{
+ return createLabeledDataSequence( SeriesModel::VALUES, rRole, true );
+}
+
+Reference< XDataSeries > SeriesConverter::createDataSeries( const TypeGroupConverter& rTypeGroup, bool bVaryColorsByPoint )
+{
+ const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
+
+ // create the data series object
+ Reference< XDataSeries > xDataSeries( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.DataSeries" ) ), UNO_QUERY );
+ PropertySet aSeriesProp( xDataSeries );
+
+ // attach data and title sequences to series
+ sal_Int32 nDataPointCount = 0;
+ Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
+ if( xDataSink.is() )
+ {
+ // create vector of all value sequences
+ ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
+ // add Y values
+ Reference< XLabeledDataSequence > xYValueSeq = createValueSequence( CREATE_OUSTRING( "values-y" ) );
+ if( xYValueSeq.is() )
+ {
+ aLabeledSeqVec.push_back( xYValueSeq );
+ Reference< XDataSequence > xValues = xYValueSeq->getValues();
+ if( xValues.is() )
+ nDataPointCount = xValues->getData().getLength();
+ }
+ // add X values of scatter and bubble charts
+ if( !rTypeInfo.mbCategoryAxis )
+ {
+ Reference< XLabeledDataSequence > xXValueSeq = createCategorySequence( CREATE_OUSTRING( "values-x" ) );
+ if( xXValueSeq.is() )
+ aLabeledSeqVec.push_back( xXValueSeq );
+ // add size values of bubble charts
+ if( rTypeInfo.meTypeId == TYPEID_BUBBLE )
+ {
+ Reference< XLabeledDataSequence > xSizeValueSeq = createLabeledDataSequence( SeriesModel::POINTS, CREATE_OUSTRING( "values-size" ), true );
+ if( xSizeValueSeq.is() )
+ aLabeledSeqVec.push_back( xSizeValueSeq );
+ }
+ }
+ // attach labeled data sequences to series
+ if( !aLabeledSeqVec.empty() )
+ xDataSink->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec ) );
+ }
+
+ // error bars
+ for( SeriesModel::ErrorBarVector::iterator aIt = mrModel.maErrorBars.begin(), aEnd = mrModel.maErrorBars.end(); aIt != aEnd; ++aIt )
+ {
+ ErrorBarConverter aErrorBarConv( *this, **aIt );
+ aErrorBarConv.convertFromModel( xDataSeries );
+ }
+
+ // trendlines
+ for( SeriesModel::TrendlineVector::iterator aIt = mrModel.maTrendlines.begin(), aEnd = mrModel.maTrendlines.end(); aIt != aEnd; ++aIt )
+ {
+ TrendlineConverter aTrendlineConv( *this, **aIt );
+ aTrendlineConv.convertFromModel( xDataSeries );
+ }
+
+ // data point markers
+ rTypeGroup.convertMarker( aSeriesProp, mrModel.mnMarkerSymbol, mrModel.mnMarkerSize );
+#if OOX_CHART_SMOOTHED_PER_SERIES
+ // #i66858# smoothed series lines
+ rTypeGroup.convertLineSmooth( aSeriesProp, mrModel.mbSmooth );
+#endif
+ // 3D bar style (not possible to set at chart type -> set at all series)
+ rTypeGroup.convertBarGeometry( aSeriesProp, mrModel.monShape.get( rTypeGroup.getModel().mnShape ) );
+ // pie explosion (restricted to [0%,100%] in Chart2)
+ rTypeGroup.convertPieExplosion( aSeriesProp, mrModel.mnExplosion );
+
+ // series formatting
+ ObjectFormatter& rFormatter = getFormatter();
+ ObjectType eObjType = rTypeGroup.getSeriesObjectType();
+ if( rTypeInfo.mbPictureOptions )
+ rFormatter.convertFrameFormatting( aSeriesProp, mrModel.mxShapeProp, mrModel.mxPicOptions.getOrCreate(), eObjType, mrModel.mnIndex );
+ else
+ rFormatter.convertFrameFormatting( aSeriesProp, mrModel.mxShapeProp, eObjType, mrModel.mnIndex );
+
+ // set the (unused) property default value used by the Chart2 templates (true for pie/doughnut charts)
+ bool bIsPie = rTypeInfo.meTypeCategory == TYPECATEGORY_PIE;
+ aSeriesProp.setProperty( PROP_VaryColorsByPoint, bIsPie );
+
+ // own area formatting for every data point (TODO: varying line color not supported)
+ // #i91271# always set area formatting for every point in pie/doughnut charts to override their automatic point formatting
+ if( bIsPie || (bVaryColorsByPoint && rTypeGroup.isSeriesFrameFormat() && ObjectFormatter::isAutomaticFill( mrModel.mxShapeProp )) )
+ {
+ /* Set the series point number as color cycle size at the object
+ formatter to get correct start-shade/end-tint. TODO: in doughnut
+ charts, the sizes of the series may vary, need to use the maximum
+ point count of all series. */
+ sal_Int32 nOldMax = rFormatter.getMaxSeriesIndex();
+ if( bVaryColorsByPoint )
+ rFormatter.setMaxSeriesIndex( nDataPointCount - 1 );
+ for( sal_Int32 nIndex = 0; nIndex < nDataPointCount; ++nIndex )
+ {
+ try
+ {
+ PropertySet aPointProp( xDataSeries->getDataPointByIndex( nIndex ) );
+ rFormatter.convertAutomaticFill( aPointProp, eObjType, bVaryColorsByPoint ? nIndex : mrModel.mnIndex );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ rFormatter.setMaxSeriesIndex( nOldMax );
+ }
+
+ // data point settings
+ for( SeriesModel::DataPointVector::iterator aIt = mrModel.maPoints.begin(), aEnd = mrModel.maPoints.end(); aIt != aEnd; ++aIt )
+ {
+ DataPointConverter aPointConv( *this, **aIt );
+ aPointConv.convertFromModel( xDataSeries, rTypeGroup, mrModel );
+ }
+
+ /* Series data label settings. If and only if the series does not contain
+ a c:dLbls element, then the c:dLbls element of the parent chart type is
+ used (data label settings of the parent chart type are *not* merged
+ into own existing data label settings). */
+ ModelRef< DataLabelsModel > xLabels = mrModel.mxLabels.is() ? mrModel.mxLabels : rTypeGroup.getModel().mxLabels;
+ if( xLabels.is() )
+ {
+ DataLabelsConverter aLabelsConv( *this, *xLabels );
+ aLabelsConv.convertFromModel( xDataSeries, rTypeGroup );
+ }
+
+ return xDataSeries;
+}
+
+// private --------------------------------------------------------------------
+
+Reference< XLabeledDataSequence > SeriesConverter::createLabeledDataSequence(
+ SeriesModel::SourceType eSourceType, const OUString& rRole, bool bUseTextLabel )
+{
+ DataSourceModel* pValues = mrModel.maSources.get( eSourceType ).get();
+ TextModel* pTitle = bUseTextLabel ? mrModel.mxText.get() : 0;
+ return lclCreateLabeledDataSequence( *this, pValues, rRole, pTitle );
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/seriesmodel.cxx b/oox/source/drawingml/chart/seriesmodel.cxx
new file mode 100644
index 000000000000..417d250caf77
--- /dev/null
+++ b/oox/source/drawingml/chart/seriesmodel.cxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/seriesmodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+DataLabelModelBase::DataLabelModelBase() :
+ mbDeleted( false )
+{
+}
+
+DataLabelModelBase::~DataLabelModelBase()
+{
+}
+
+// ============================================================================
+
+DataLabelModel::DataLabelModel() :
+ mnIndex( -1 )
+{
+}
+
+DataLabelModel::~DataLabelModel()
+{
+}
+
+// ============================================================================
+
+DataLabelsModel::DataLabelsModel() :
+ mbShowLeaderLines( false )
+{
+}
+
+DataLabelsModel::~DataLabelsModel()
+{
+}
+
+// ============================================================================
+
+PictureOptionsModel::PictureOptionsModel() :
+ mfStackUnit( 1.0 ),
+ mnPictureFormat( XML_stretch ),
+ mbApplyToFront( false ),
+ mbApplyToSides( false ),
+ mbApplyToEnd( false )
+{
+}
+
+PictureOptionsModel::~PictureOptionsModel()
+{
+}
+
+// ============================================================================
+
+ErrorBarModel::ErrorBarModel() :
+ mfValue( 0.0 ),
+ mnDirection( XML_y ),
+ mnTypeId( XML_both ),
+ mnValueType( XML_fixedVal ),
+ mbNoEndCap( false )
+{
+}
+
+ErrorBarModel::~ErrorBarModel()
+{
+}
+
+// ============================================================================
+
+TrendlineLabelModel::TrendlineLabelModel()
+{
+}
+
+TrendlineLabelModel::~TrendlineLabelModel()
+{
+}
+
+// ============================================================================
+
+TrendlineModel::TrendlineModel() :
+ mnOrder( 2 ),
+ mnPeriod( 2 ),
+ mnTypeId( XML_linear ),
+ mbDispEquation( false ),
+ mbDispRSquared( false )
+{
+}
+
+TrendlineModel::~TrendlineModel()
+{
+}
+
+// ============================================================================
+
+DataPointModel::DataPointModel() :
+ mnIndex( -1 ),
+ mbInvertNeg( false )
+{
+}
+
+DataPointModel::~DataPointModel()
+{
+}
+
+// ============================================================================
+
+SeriesModel::SeriesModel() :
+ mnExplosion( 0 ),
+ mnIndex( -1 ),
+ mnMarkerSize( 5 ),
+ mnMarkerSymbol( XML_auto ),
+ mnOrder( -1 ),
+ mbBubble3d( false ),
+ mbInvertNeg( false ),
+ mbSmooth( false )
+{
+}
+
+SeriesModel::~SeriesModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/titlecontext.cxx b/oox/source/drawingml/chart/titlecontext.cxx
new file mode 100644
index 000000000000..cc2b7ace0e72
--- /dev/null
+++ b/oox/source/drawingml/chart/titlecontext.cxx
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/titlecontext.hxx"
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/chart/datasourcecontext.hxx"
+#include "oox/drawingml/chart/titlemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+TextContext::TextContext( ContextHandler2Helper& rParent, TextModel& rModel ) :
+ ContextBase< TextModel >( rParent, rModel )
+{
+}
+
+TextContext::~TextContext()
+{
+}
+
+ContextHandlerRef TextContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ // this context handler is used for <c:tx> and embedded <c:v> elements
+ if( isCurrentElement( C_TOKEN( tx ) ) ) switch( nElement )
+ {
+ case C_TOKEN( rich ):
+ return new TextBodyContext( *this, mrModel.mxTextBody.create() );
+
+ case C_TOKEN( strRef ):
+ OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" );
+ return new StringSequenceContext( *this, mrModel.mxDataSeq.create() );
+
+ case C_TOKEN( v ):
+ OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" );
+ return this; // collect value in onCharacters()
+ }
+ return 0;
+}
+
+void TextContext::onCharacters( const OUString& rChars )
+{
+ // store as single string sequence element
+ if( isCurrentElement( C_TOKEN( v ) ) )
+ mrModel.mxDataSeq.create().maData[ 0 ] <<= rChars;
+}
+
+// ============================================================================
+
+TitleContext::TitleContext( ContextHandler2Helper& rParent, TitleModel& rModel ) :
+ ContextBase< TitleModel >( rParent, rModel )
+{
+}
+
+TitleContext::~TitleContext()
+{
+}
+
+ContextHandlerRef TitleContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ // this context handler is used for <c:title> only
+ switch( nElement )
+ {
+ case C_TOKEN( layout ):
+ return new LayoutContext( *this, mrModel.mxLayout.create() );
+
+ case C_TOKEN( overlay ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbOverlay = rAttribs.getBool( XML_val, false );
+ return 0;
+
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+
+ case C_TOKEN( tx ):
+ return new TextContext( *this, mrModel.mxText.create() );
+
+ case C_TOKEN( txPr ):
+ return new TextBodyContext( *this, mrModel.mxTextProp.create() );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+LegendContext::LegendContext( ContextHandler2Helper& rParent, LegendModel& rModel ) :
+ ContextBase< LegendModel >( rParent, rModel )
+{
+}
+
+LegendContext::~LegendContext()
+{
+}
+
+ContextHandlerRef LegendContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ // this context handler is used for <c:legend> only
+ switch( nElement )
+ {
+ case C_TOKEN( layout ):
+ return new LayoutContext( *this, mrModel.mxLayout.create() );
+
+ case C_TOKEN( legendPos ):
+ mrModel.mnPosition = rAttribs.getToken( XML_val, XML_r );
+ return 0;
+
+ case C_TOKEN( overlay ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbOverlay = rAttribs.getBool( XML_val, false );
+ return 0;
+
+ case C_TOKEN( spPr ):
+ return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
+
+ case C_TOKEN( txPr ):
+ return new TextBodyContext( *this, mrModel.mxTextProp.create() );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/titleconverter.cxx b/oox/source/drawingml/chart/titleconverter.cxx
new file mode 100644
index 000000000000..8163241e5a31
--- /dev/null
+++ b/oox/source/drawingml/chart/titleconverter.cxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/titleconverter.hxx"
+
+#include <com/sun/star/chart/ChartLegendExpansion.hpp>
+#include <com/sun/star/chart2/LegendPosition.hpp>
+#include <com/sun/star/chart2/XDiagram.hpp>
+#include <com/sun/star/chart2/XFormattedString.hpp>
+#include <com/sun/star/chart2/XLegend.hpp>
+#include <com/sun/star/chart2/XTitle.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include "oox/drawingml/textbody.hxx"
+#include "oox/drawingml/textparagraph.hxx"
+#include "oox/drawingml/chart/datasourceconverter.hxx"
+#include "oox/drawingml/chart/titlemodel.hxx"
+#include "oox/helper/containerhelper.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::chart2::data;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::XmlFilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
+TextConverter::TextConverter( const ConverterRoot& rParent, TextModel& rModel ) :
+ ConverterBase< TextModel >( rParent, rModel )
+{
+}
+
+TextConverter::~TextConverter()
+{
+}
+
+Reference< XDataSequence > TextConverter::createDataSequence( const OUString& rRole )
+{
+ Reference< XDataSequence > xDataSeq;
+ if( mrModel.mxDataSeq.is() )
+ {
+ DataSequenceConverter aDataSeqConv( *this, *mrModel.mxDataSeq );
+ xDataSeq = aDataSeqConv.createDataSequence( rRole );
+ }
+ return xDataSeq;
+}
+
+Sequence< Reference< XFormattedString > > TextConverter::createStringSequence(
+ const OUString& rDefaultText, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
+{
+ OSL_ENSURE( !mrModel.mxDataSeq || !mrModel.mxTextBody, "TextConverter::createStringSequence - linked string and rich text found" );
+ ::std::vector< Reference< XFormattedString > > aStringVec;
+ if( mrModel.mxTextBody.is() )
+ {
+ // rich-formatted text objects can be created, but currently Chart2 is not able to show them
+ const TextParagraphVector& rTextParas = mrModel.mxTextBody->getParagraphs();
+ for( TextParagraphVector::const_iterator aPIt = rTextParas.begin(), aPEnd = rTextParas.end(); aPIt != aPEnd; ++aPIt )
+ {
+ const TextParagraph& rTextPara = **aPIt;
+ const TextCharacterProperties& rParaProps = rTextPara.getProperties().getTextCharacterProperties();
+ for( TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt )
+ {
+ const TextRun& rTextRun = **aRIt;
+ bool bAddNewLine = (aRIt + 1 == aREnd) && (aPIt + 1 != aPEnd);
+ Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, rTextRun.getText(), bAddNewLine );
+ PropertySet aPropSet( xFmtStr );
+ TextCharacterProperties aRunProps( rParaProps );
+ aRunProps.assignUsed( rTextRun.getTextCharacterProperties() );
+ getFormatter().convertTextFormatting( aPropSet, aRunProps, eObjType );
+ }
+ }
+ }
+ else
+ {
+ OUString aString;
+ // try to create string from linked data
+ if( mrModel.mxDataSeq.is() && !mrModel.mxDataSeq->maData.empty() )
+ mrModel.mxDataSeq->maData.begin()->second >>= aString;
+ // no linked string -> fall back to default string
+ if( aString.getLength() == 0 )
+ aString = rDefaultText;
+
+ // create formatted string object
+ if( aString.getLength() > 0 )
+ {
+ Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, aString, false );
+ PropertySet aPropSet( xFmtStr );
+ getFormatter().convertTextFormatting( aPropSet, rxTextProp, eObjType );
+ }
+ }
+
+ return ContainerHelper::vectorToSequence( aStringVec );
+}
+
+Reference< XFormattedString > TextConverter::appendFormattedString(
+ ::std::vector< Reference< XFormattedString > >& orStringVec, const OUString& rString, bool bAddNewLine ) const
+{
+ Reference< XFormattedString > xFmtStr;
+ try
+ {
+ xFmtStr.set( ConverterRoot::createInstance( CREATE_OUSTRING( "com.sun.star.chart2.FormattedString" ) ), UNO_QUERY_THROW );
+ xFmtStr->setString( bAddNewLine ? (rString + OUString( sal_Unicode( '\n' ) )) : rString );
+ orStringVec.push_back( xFmtStr );
+ }
+ catch( Exception& )
+ {
+ }
+ return xFmtStr;
+}
+
+// ============================================================================
+
+TitleConverter::TitleConverter( const ConverterRoot& rParent, TitleModel& rModel ) :
+ ConverterBase< TitleModel >( rParent, rModel )
+{
+}
+
+TitleConverter::~TitleConverter()
+{
+}
+
+void TitleConverter::convertFromModel( const Reference< XTitled >& rxTitled, const OUString& rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx )
+{
+ if( rxTitled.is() )
+ {
+ // create the formatted strings
+ TextModel& rText = mrModel.mxText.getOrCreate();
+ TextConverter aTextConv( *this, rText );
+ Sequence< Reference< XFormattedString > > aStringSeq = aTextConv.createStringSequence( rAutoTitle, mrModel.mxTextProp, eObjType );
+ if( aStringSeq.hasElements() ) try
+ {
+ // create the title object and set the string data
+ Reference< XTitle > xTitle( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Title" ) ), UNO_QUERY_THROW );
+ xTitle->setText( aStringSeq );
+ rxTitled->setTitleObject( xTitle );
+
+ // frame formatting (text formatting already done in TextConverter::createStringSequence())
+ PropertySet aPropSet( xTitle );
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, eObjType );
+
+ // frame rotation
+ OSL_ENSURE( !mrModel.mxTextProp || !rText.mxTextBody, "TitleConverter::convertFromModel - multiple text properties" );
+ ModelRef< TextBody > xTextProp = mrModel.mxTextProp.is() ? mrModel.mxTextProp : rText.mxTextBody;
+ getFormatter().convertTextRotation( aPropSet, xTextProp, true );
+
+ // register the title and layout data for conversion of position
+ registerTitleLayout( xTitle, mrModel.mxLayout, eObjType, nMainIdx, nSubIdx );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+// ============================================================================
+
+LegendConverter::LegendConverter( const ConverterRoot& rParent, LegendModel& rModel ) :
+ ConverterBase< LegendModel >( rParent, rModel )
+{
+}
+
+LegendConverter::~LegendConverter()
+{
+}
+
+void LegendConverter::convertFromModel( const Reference< XDiagram >& rxDiagram )
+{
+ if( rxDiagram.is() ) try
+ {
+ namespace cssc = ::com::sun::star::chart;
+ namespace cssc2 = ::com::sun::star::chart2;
+
+ // create the legend
+ Reference< XLegend > xLegend( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Legend" ) ), UNO_QUERY_THROW );
+ rxDiagram->setLegend( xLegend );
+ PropertySet aPropSet( xLegend );
+ aPropSet.setProperty( PROP_Show, true );
+
+ // legend formatting
+ getFormatter().convertFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_LEGEND );
+
+ // predefined legend position and expansion
+ cssc2::LegendPosition eLegendPos = cssc2::LegendPosition_CUSTOM;
+ cssc::ChartLegendExpansion eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
+ switch( mrModel.mnPosition )
+ {
+ case XML_l:
+ eLegendPos = cssc2::LegendPosition_LINE_START;
+ eLegendExpand = cssc::ChartLegendExpansion_HIGH;
+ break;
+ case XML_r:
+ case XML_tr: // top-right not supported
+ eLegendPos = cssc2::LegendPosition_LINE_END;
+ eLegendExpand = cssc::ChartLegendExpansion_HIGH;
+ break;
+ case XML_t:
+ eLegendPos = cssc2::LegendPosition_PAGE_START;
+ eLegendExpand = cssc::ChartLegendExpansion_WIDE;
+ break;
+ case XML_b:
+ eLegendPos = cssc2::LegendPosition_PAGE_END;
+ eLegendExpand = cssc::ChartLegendExpansion_WIDE;
+ break;
+ }
+
+ // manual positioning and size
+ if( mrModel.mxLayout.get() )
+ {
+ LayoutConverter aLayoutConv( *this, *mrModel.mxLayout );
+ // manual size needs ChartLegendExpansion_CUSTOM
+ if( aLayoutConv.convertFromModel( aPropSet ) )
+ eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
+ }
+
+ // set position and expansion properties
+ aPropSet.setProperty( PROP_AnchorPosition, eLegendPos );
+ aPropSet.setProperty( PROP_Expansion, eLegendExpand );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/titlemodel.cxx b/oox/source/drawingml/chart/titlemodel.cxx
new file mode 100644
index 000000000000..d1dc2c664e8f
--- /dev/null
+++ b/oox/source/drawingml/chart/titlemodel.cxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/titlemodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+TextModel::TextModel()
+{
+}
+
+TextModel::~TextModel()
+{
+}
+
+// ============================================================================
+
+TitleModel::TitleModel() :
+ mbOverlay( false )
+{
+}
+
+TitleModel::~TitleModel()
+{
+}
+
+// ============================================================================
+
+LegendModel::LegendModel() :
+ mnPosition( XML_r ),
+ mbOverlay( false )
+{
+}
+
+LegendModel::~LegendModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/typegroupcontext.cxx b/oox/source/drawingml/chart/typegroupcontext.cxx
new file mode 100644
index 000000000000..781b2665d6f1
--- /dev/null
+++ b/oox/source/drawingml/chart/typegroupcontext.cxx
@@ -0,0 +1,404 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/typegroupcontext.hxx"
+
+#include "oox/drawingml/chart/seriescontext.hxx"
+#include "oox/drawingml/chart/typegroupmodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+
+// ============================================================================
+
+UpDownBarsContext::UpDownBarsContext( ContextHandler2Helper& rParent, UpDownBarsModel& rModel ) :
+ ContextBase< UpDownBarsModel >( rParent, rModel )
+{
+}
+
+UpDownBarsContext::~UpDownBarsContext()
+{
+}
+
+ContextHandlerRef UpDownBarsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( upDownBars ):
+ switch( nElement )
+ {
+ case C_TOKEN( downBars ):
+ return new ShapePrWrapperContext( *this, mrModel.mxDownBars.create() );
+ case C_TOKEN( gapWidth ):
+ mrModel.mnGapWidth = rAttribs.getInteger( XML_val, 150 );
+ return 0;
+ case C_TOKEN( upBars ):
+ return new ShapePrWrapperContext( *this, mrModel.mxUpBars.create() );
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+AreaTypeGroupContext::AreaTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+AreaTypeGroupContext::~AreaTypeGroupContext()
+{
+}
+
+ContextHandlerRef AreaTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.maAxisIds.push_back( rAttribs.getInteger( XML_val, -1 ) );
+ return 0;
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dropLines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxDropLines.create() );
+ case C_TOKEN( gapDepth ):
+ mrModel.mnGapDepth = rAttribs.getInteger( XML_val, 150 );
+ return 0;
+ case C_TOKEN( grouping ):
+ mrModel.mnGrouping = rAttribs.getToken( XML_val, XML_standard );
+ return 0;
+ case C_TOKEN( ser ):
+ return new AreaSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( varyColors ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbVaryColors = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+BarTypeGroupContext::BarTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+BarTypeGroupContext::~BarTypeGroupContext()
+{
+}
+
+ContextHandlerRef BarTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.maAxisIds.push_back( rAttribs.getInteger( XML_val, -1 ) );
+ return 0;
+ case C_TOKEN( barDir ):
+ mrModel.mnBarDir = rAttribs.getToken( XML_val, XML_col );
+ return 0;
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( gapDepth ):
+ mrModel.mnGapDepth = rAttribs.getInteger( XML_val, 150 );
+ return 0;
+ case C_TOKEN( gapWidth ):
+ mrModel.mnGapWidth = rAttribs.getInteger( XML_val, 150 );
+ return 0;
+ case C_TOKEN( grouping ):
+ // default is 'standard', not 'clustered' as specified
+ mrModel.mnGrouping = rAttribs.getToken( XML_val, XML_standard );
+ return 0;
+ case C_TOKEN( overlap ):
+ mrModel.mnOverlap = rAttribs.getInteger( XML_val, 0 );
+ return 0;
+ case C_TOKEN( ser ):
+ return new BarSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( serLines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxSerLines.create() );
+ case C_TOKEN( shape ):
+ mrModel.mnShape = rAttribs.getToken( XML_val, XML_box );
+ return 0;
+ case C_TOKEN( varyColors ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbVaryColors = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+BubbleTypeGroupContext::BubbleTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+BubbleTypeGroupContext::~BubbleTypeGroupContext()
+{
+}
+
+ContextHandlerRef BubbleTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.maAxisIds.push_back( rAttribs.getInteger( XML_val, -1 ) );
+ return 0;
+ case C_TOKEN( bubble3D ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbBubble3d = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( bubbleScale ):
+ mrModel.mnBubbleScale = rAttribs.getInteger( XML_val, 100 );
+ return 0;
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( ser ):
+ return new BubbleSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( showNegBubbles ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbShowNegBubbles = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( sizeRepresents ):
+ mrModel.mnSizeRepresents = rAttribs.getToken( XML_val, XML_area );
+ return 0;
+ case C_TOKEN( varyColors ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbVaryColors = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+LineTypeGroupContext::LineTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+LineTypeGroupContext::~LineTypeGroupContext()
+{
+}
+
+ContextHandlerRef LineTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.maAxisIds.push_back( rAttribs.getInteger( XML_val, -1 ) );
+ return 0;
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( dropLines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxDropLines.create() );
+ case C_TOKEN( gapDepth ):
+ mrModel.mnGapDepth = rAttribs.getInteger( XML_val, 150 );
+ return 0;
+ case C_TOKEN( grouping ):
+ mrModel.mnGrouping = rAttribs.getToken( XML_val, XML_standard );
+ return 0;
+ case C_TOKEN( hiLowLines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxHiLowLines.create() );
+ case C_TOKEN( marker ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbShowMarker = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( ser ):
+ return new LineSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( smooth ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbSmooth = rAttribs.getBool( XML_val, false );
+ return 0;
+ case C_TOKEN( upDownBars ):
+ return new UpDownBarsContext( *this, mrModel.mxUpDownBars.create() );
+ case C_TOKEN( varyColors ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbVaryColors = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+PieTypeGroupContext::PieTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+PieTypeGroupContext::~PieTypeGroupContext()
+{
+}
+
+ContextHandlerRef PieTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( firstSliceAng ):
+ mrModel.mnFirstAngle = rAttribs.getInteger( XML_val, 0 );
+ return 0;
+ case C_TOKEN( gapWidth ):
+ mrModel.mnGapWidth = rAttribs.getInteger( XML_val, 150 );
+ return 0;
+ case C_TOKEN( holeSize ):
+ mrModel.mnHoleSize = rAttribs.getInteger( XML_val, 10 );
+ return 0;
+ case C_TOKEN( ofPieType ):
+ mrModel.mnOfPieType = rAttribs.getToken( XML_val, XML_pie );
+ return 0;
+ case C_TOKEN( secondPieSize ):
+ mrModel.mnSecondPieSize = rAttribs.getInteger( XML_val, 75 );
+ return 0;
+ case C_TOKEN( ser ):
+ return new PieSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( serLines ):
+ return new ShapePrWrapperContext( *this, mrModel.mxSerLines.create() );
+ case C_TOKEN( splitPos ):
+ mrModel.mfSplitPos = rAttribs.getDouble( XML_val, 0.0 );
+ return 0;
+ case C_TOKEN( splitType ):
+ mrModel.mnSplitType = rAttribs.getToken( XML_val, XML_auto );
+ return 0;
+ case C_TOKEN( varyColors ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbVaryColors = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+RadarTypeGroupContext::RadarTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+RadarTypeGroupContext::~RadarTypeGroupContext()
+{
+}
+
+ContextHandlerRef RadarTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.maAxisIds.push_back( rAttribs.getInteger( XML_val, -1 ) );
+ return 0;
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( radarStyle ):
+ mrModel.mnRadarStyle = rAttribs.getToken( XML_val, XML_standard );
+ return 0;
+ case C_TOKEN( ser ):
+ return new RadarSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( varyColors ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbVaryColors = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ScatterTypeGroupContext::ScatterTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+ScatterTypeGroupContext::~ScatterTypeGroupContext()
+{
+}
+
+ContextHandlerRef ScatterTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.maAxisIds.push_back( rAttribs.getInteger( XML_val, -1 ) );
+ return 0;
+ case C_TOKEN( dLbls ):
+ return new DataLabelsContext( *this, mrModel.mxLabels.create() );
+ case C_TOKEN( scatterStyle ):
+ mrModel.mnScatterStyle = rAttribs.getInteger( XML_val, XML_marker );
+ return 0;
+ case C_TOKEN( ser ):
+ return new ScatterSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( varyColors ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbVaryColors = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+SurfaceTypeGroupContext::SurfaceTypeGroupContext( ContextHandler2Helper& rParent, TypeGroupModel& rModel ) :
+ TypeGroupContextBase( rParent, rModel )
+{
+}
+
+SurfaceTypeGroupContext::~SurfaceTypeGroupContext()
+{
+}
+
+ContextHandlerRef SurfaceTypeGroupContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case C_TOKEN( axId ):
+ mrModel.maAxisIds.push_back( rAttribs.getInteger( XML_val, -1 ) );
+ return 0;
+ case C_TOKEN( ser ):
+ return new SurfaceSeriesContext( *this, mrModel.maSeries.create() );
+ case C_TOKEN( wireframe ):
+ // default is 'false', not 'true' as specified
+ mrModel.mbWireframe = rAttribs.getBool( XML_val, false );
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/typegroupconverter.cxx b/oox/source/drawingml/chart/typegroupconverter.cxx
new file mode 100644
index 000000000000..6c0d3660a670
--- /dev/null
+++ b/oox/source/drawingml/chart/typegroupconverter.cxx
@@ -0,0 +1,566 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/typegroupconverter.hxx"
+
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart2/CurveStyle.hpp>
+#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
+#include <com/sun/star/chart2/StackingDirection.hpp>
+#include <com/sun/star/chart2/Symbol.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XCoordinateSystem.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/data/XDataSink.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/chart/seriesconverter.hxx"
+#include "oox/drawingml/chart/typegroupmodel.hxx"
+#include "oox/helper/containerhelper.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::chart2::data;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+// chart type service names
+const sal_Char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
+const sal_Char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
+const sal_Char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
+const sal_Char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
+const sal_Char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
+const sal_Char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType";
+const sal_Char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
+const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
+const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
+const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
+
+namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
+
+static const TypeGroupInfo spTypeInfos[] =
+{
+ // type-id type-category service varied-point-color default label pos comb2d supp3d polar area2d 1stvis xcateg swap stack revers betw picopt
+ { TYPEID_BAR, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, true, true, false, true, false, true, false, true, false, true, true },
+ { TYPEID_HORBAR, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, false, true, false, true, false, true, true, true, false, true, true },
+ { TYPEID_LINE, TYPECATEGORY_LINE, SERVICE_CHART2_LINE, VARPOINTMODE_SINGLE, csscd::RIGHT, true, true, false, false, false, true, false, true, false, true, false },
+ { TYPEID_AREA, TYPECATEGORY_LINE, SERVICE_CHART2_AREA, VARPOINTMODE_NONE, csscd::CENTER, true, true, false, true, false, true, false, true, true, false, false },
+ { TYPEID_STOCK, TYPECATEGORY_LINE, SERVICE_CHART2_CANDLE, VARPOINTMODE_NONE, csscd::RIGHT, true, false, false, false, false, true, false, true, false, true, false },
+ { TYPEID_RADARLINE, TYPECATEGORY_RADAR, SERVICE_CHART2_NET, VARPOINTMODE_SINGLE, csscd::TOP, false, false, true, false, false, true, false, false, false, false, false },
+ { TYPEID_RADARAREA, TYPECATEGORY_RADAR, SERVICE_CHART2_FILLEDNET, VARPOINTMODE_NONE, csscd::TOP, false, false, true, true, false, true, false, false, true, false, false },
+ { TYPEID_PIE, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, true, false, false, false, false, false },
+ { TYPEID_DOUGHNUT, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, false, true, false, false, false, false, false },
+ { TYPEID_OFPIE, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, true, false, false, false, false, false },
+ { TYPEID_SCATTER, TYPECATEGORY_SCATTER, SERVICE_CHART2_SCATTER, VARPOINTMODE_SINGLE, csscd::RIGHT, true, true, false, false, false, false, false, false, false, false, false },
+ { TYPEID_BUBBLE, TYPECATEGORY_SCATTER, SERVICE_CHART2_BUBBLE, VARPOINTMODE_SINGLE, csscd::RIGHT, false, false, false, true, false, false, false, false, false, false, false },
+ { TYPEID_SURFACE, TYPECATEGORY_SURFACE, SERVICE_CHART2_SURFACE, VARPOINTMODE_NONE, csscd::RIGHT, false, true, false, true, false, true, false, false, false, false, false }
+};
+
+static const TypeGroupInfo saUnknownTypeInfo =
+ { TYPEID_UNKNOWN, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, true, true, false, true, false, true, false, true, false, true, true };
+
+const TypeGroupInfo& lclGetTypeInfoFromTypeId( TypeId eTypeId )
+{
+ const TypeGroupInfo* pEnd = STATIC_ARRAY_END( spTypeInfos );
+ for( const TypeGroupInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
+ if( pIt->meTypeId == eTypeId )
+ return *pIt;
+ OSL_ENSURE( eTypeId == TYPEID_UNKNOWN, "lclGetTypeInfoFromTypeId - unexpected chart type identifier" );
+ return saUnknownTypeInfo;
+}
+
+} // namespace
+
+// ============================================================================
+
+UpDownBarsConverter::UpDownBarsConverter( const ConverterRoot& rParent, UpDownBarsModel& rModel ) :
+ ConverterBase< UpDownBarsModel >( rParent, rModel )
+{
+}
+
+UpDownBarsConverter::~UpDownBarsConverter()
+{
+}
+
+void UpDownBarsConverter::convertFromModel( const Reference< XChartType >& rxChartType )
+{
+ PropertySet aTypeProp( rxChartType );
+
+ // upbar format
+ Reference< XPropertySet > xWhitePropSet;
+ if( aTypeProp.getProperty( xWhitePropSet, PROP_WhiteDay ) )
+ {
+ PropertySet aPropSet( xWhitePropSet );
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxUpBars, OBJECTTYPE_UPBAR );
+ }
+
+ // downbar format
+ Reference< XPropertySet > xBlackPropSet;
+ if( aTypeProp.getProperty( xBlackPropSet, PROP_BlackDay ) )
+ {
+ PropertySet aPropSet( xBlackPropSet );
+ getFormatter().convertFrameFormatting( aPropSet, mrModel.mxDownBars, OBJECTTYPE_DOWNBAR );
+ }
+}
+
+// ============================================================================
+
+TypeGroupConverter::TypeGroupConverter( const ConverterRoot& rParent, TypeGroupModel& rModel ) :
+ ConverterBase< TypeGroupModel >( rParent, rModel ),
+ mb3dChart( false )
+{
+ TypeId eTypeId = TYPEID_UNKNOWN;
+ switch( mrModel.mnTypeId )
+ {
+#define ENSURE_AXESCOUNT( min, max ) OSL_ENSURE( (min <= (int)mrModel.maAxisIds.size()) && ((int)mrModel.maAxisIds.size() <= max), "TypeGroupConverter::TypeGroupConverter - invalid axes count" )
+ case C_TOKEN( area3DChart ): ENSURE_AXESCOUNT( 2, 3 ); eTypeId = TYPEID_AREA; mb3dChart = true; break;
+ case C_TOKEN( areaChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_AREA; mb3dChart = false; break;
+ case C_TOKEN( bar3DChart ): ENSURE_AXESCOUNT( 2, 3 ); eTypeId = TYPEID_BAR; mb3dChart = true; break;
+ case C_TOKEN( barChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_BAR; mb3dChart = false; break;
+ case C_TOKEN( bubbleChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_BUBBLE; mb3dChart = false; break;
+ case C_TOKEN( doughnutChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_DOUGHNUT; mb3dChart = false; break;
+ case C_TOKEN( line3DChart ): ENSURE_AXESCOUNT( 3, 3 ); eTypeId = TYPEID_LINE; mb3dChart = true; break;
+ case C_TOKEN( lineChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_LINE; mb3dChart = false; break;
+ case C_TOKEN( ofPieChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_OFPIE; mb3dChart = false; break;
+ case C_TOKEN( pie3DChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_PIE; mb3dChart = true; break;
+ case C_TOKEN( pieChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_PIE; mb3dChart = false; break;
+ case C_TOKEN( radarChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_RADARLINE; mb3dChart = false; break;
+ case C_TOKEN( scatterChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_SCATTER; mb3dChart = false; break;
+ case C_TOKEN( stockChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_STOCK; mb3dChart = false; break;
+ case C_TOKEN( surface3DChart ): ENSURE_AXESCOUNT( 3, 3 ); eTypeId = TYPEID_SURFACE; mb3dChart = true; break;
+ case C_TOKEN( surfaceChart ): ENSURE_AXESCOUNT( 2, 3 ); eTypeId = TYPEID_SURFACE; mb3dChart = true; break; // 3D bar chart from all surface charts
+ default: OSL_ENSURE( false, "TypeGroupConverter::TypeGroupConverter - unknown chart type" );
+#undef ENSURE_AXESCOUNT
+ }
+
+ // special handling for some chart types
+ switch( eTypeId )
+ {
+ case TYPEID_BAR:
+ if( mrModel.mnBarDir == XML_bar )
+ eTypeId = TYPEID_HORBAR;
+ break;
+ case TYPEID_RADARLINE:
+ if( mrModel.mnRadarStyle == XML_filled )
+ eTypeId = TYPEID_RADARAREA;
+ break;
+ case TYPEID_SURFACE:
+ // create a deep 3D bar chart from surface charts
+ mrModel.mnGrouping = XML_standard;
+ break;
+ default:;
+ }
+
+ // set the chart type info struct for the current chart type
+ maTypeInfo = lclGetTypeInfoFromTypeId( eTypeId );
+}
+
+TypeGroupConverter::~TypeGroupConverter()
+{
+}
+
+bool TypeGroupConverter::isStacked() const
+{
+ return maTypeInfo.mbSupportsStacking && (mrModel.mnGrouping == XML_stacked);
+}
+
+bool TypeGroupConverter::isPercent() const
+{
+ return maTypeInfo.mbSupportsStacking && (mrModel.mnGrouping == XML_percentStacked);
+}
+
+bool TypeGroupConverter::is3dChart() const
+{
+ return mb3dChart;
+}
+
+bool TypeGroupConverter::isWall3dChart() const
+{
+ return mb3dChart && (maTypeInfo.meTypeCategory != TYPECATEGORY_PIE);
+}
+
+bool TypeGroupConverter::isDeep3dChart() const
+{
+ return isWall3dChart() && (mrModel.mnGrouping == XML_standard);
+}
+
+bool TypeGroupConverter::isSeriesFrameFormat() const
+{
+ return mb3dChart || maTypeInfo.mbSeriesIsFrame2d;
+}
+
+ObjectType TypeGroupConverter::getSeriesObjectType() const
+{
+ return mb3dChart ? OBJECTTYPE_FILLEDSERIES3D :
+ (maTypeInfo.mbSeriesIsFrame2d ? OBJECTTYPE_FILLEDSERIES2D : OBJECTTYPE_LINEARSERIES2D);
+}
+
+bool TypeGroupConverter::isReverseSeries() const
+{
+ return maTypeInfo.mbReverseSeries && !mb3dChart && !isStacked() && !isPercent();
+}
+
+OUString TypeGroupConverter::getSingleSeriesTitle() const
+{
+ OUString aSeriesTitle;
+ if( !mrModel.maSeries.empty() && (maTypeInfo.mbSingleSeriesVis || (mrModel.maSeries.size() == 1)) )
+ if( const TextModel* pText = mrModel.maSeries.front()->mxText.get() )
+ if( const DataSequenceModel* pDataSeq = pText->mxDataSeq.get() )
+ if( !pDataSeq->maData.empty() )
+ pDataSeq->maData.begin()->second >>= aSeriesTitle;
+ return aSeriesTitle;
+}
+
+Reference< XCoordinateSystem > TypeGroupConverter::createCoordinateSystem()
+{
+ // find service name for coordinate system
+ OUString aServiceName;
+ if( maTypeInfo.mbPolarCoordSystem )
+ {
+ if( mb3dChart )
+ aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.PolarCoordinateSystem3d" );
+ else
+ aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.PolarCoordinateSystem2d" );
+ }
+ else
+ {
+ if( mb3dChart )
+ aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.CartesianCoordinateSystem3d" );
+ else
+ aServiceName = CREATE_OUSTRING( "com.sun.star.chart2.CartesianCoordinateSystem2d" );
+ }
+
+ // create the coordinate system object
+ Reference< XCoordinateSystem > xCoordSystem( createInstance( aServiceName ), UNO_QUERY );
+
+ // swap X and Y axis
+ if( maTypeInfo.mbSwappedAxesSet )
+ {
+ PropertySet aPropSet( xCoordSystem );
+ aPropSet.setProperty( PROP_SwapXAndYAxis, true );
+ }
+
+ return xCoordSystem;
+}
+
+Reference< XLabeledDataSequence > TypeGroupConverter::createCategorySequence()
+{
+ Reference< XLabeledDataSequence > xLabeledSeq;
+ /* Find first existing category sequence. The bahaviour of Excel 2007 is
+ different to Excel 2003, which always used the category sequence of the
+ first series, even if it was empty. */
+ for( TypeGroupModel::SeriesVector::iterator aIt = mrModel.maSeries.begin(), aEnd = mrModel.maSeries.end(); !xLabeledSeq.is() && (aIt != aEnd); ++aIt )
+ {
+ if( (*aIt)->maSources.has( SeriesModel::CATEGORIES ) )
+ {
+ SeriesConverter aSeriesConv( *this, **aIt );
+ xLabeledSeq = aSeriesConv.createCategorySequence( CREATE_OUSTRING( "categories" ) );
+ }
+ }
+ return xLabeledSeq;
+}
+
+void TypeGroupConverter::convertFromModel( const Reference< XDiagram >& rxDiagram,
+ const Reference< XCoordinateSystem >& rxCoordSystem,
+ sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint )
+{
+ try
+ {
+ // create the chart type object
+ OUString aService = OUString::createFromAscii( maTypeInfo.mpcServiceName );
+ Reference< XChartType > xChartType( createInstance( aService ), UNO_QUERY_THROW );
+
+ // additional properties
+ PropertySet aDiaProp( rxDiagram );
+ PropertySet aTypeProp( xChartType );
+ switch( maTypeInfo.meTypeCategory )
+ {
+ case TYPECATEGORY_BAR:
+ {
+ Sequence< sal_Int32 > aInt32Seq( 2 );
+ aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = mrModel.mnOverlap;
+ aTypeProp.setProperty( PROP_OverlapSequence, aInt32Seq );
+ aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = mrModel.mnGapWidth;
+ aTypeProp.setProperty( PROP_GapwidthSequence, aInt32Seq );
+ }
+ break;
+ case TYPECATEGORY_PIE:
+ {
+ aTypeProp.setProperty( PROP_UseRings, maTypeInfo.meTypeId == TYPEID_DOUGHNUT );
+ /* #i85166# starting angle of first pie slice. 3D pie charts
+ use Y rotation setting in view3D element. Of-pie charts do
+ not support pie rotation. */
+ if( !is3dChart() && (maTypeInfo.meTypeId != TYPEID_OFPIE) )
+ convertPieRotation( aDiaProp, mrModel.mnFirstAngle );
+ }
+ break;
+ default:;
+ }
+
+ // create converter objects for all series models
+ typedef RefVector< SeriesConverter > SeriesConvVector;
+ SeriesConvVector aSeries;
+ for( TypeGroupModel::SeriesVector::iterator aIt = mrModel.maSeries.begin(), aEnd = mrModel.maSeries.end(); aIt != aEnd; ++aIt )
+ aSeries.push_back( SeriesConvVector::value_type( new SeriesConverter( *this, **aIt ) ) );
+
+ // reverse series order for some unstacked 2D chart types
+ if( isReverseSeries() )
+ ::std::reverse( aSeries.begin(), aSeries.end() );
+
+ // decide whether to use varying colors for each data point
+ bool bVaryColorsByPoint = bSupportsVaryColorsByPoint && mrModel.mbVaryColors;
+ switch( maTypeInfo.meVarPointMode )
+ {
+ case VARPOINTMODE_NONE: bVaryColorsByPoint = false; break;
+ case VARPOINTMODE_SINGLE: bVaryColorsByPoint &= (mrModel.maSeries.size() == 1); break;
+ case VARPOINTMODE_MULTI: break;
+ }
+
+ /* Stock chart needs special processing. Create one 'big' series with
+ data sequences of different roles. */
+ if( maTypeInfo.meTypeId == TYPEID_STOCK )
+ {
+ // create the data series object
+ Reference< XDataSeries > xDataSeries( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.DataSeries" ) ), UNO_QUERY );
+ Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
+ if( xDataSink.is() )
+ {
+ // create a list of data sequences from all series
+ ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
+ OSL_ENSURE( aSeries.size() >= 3, "TypeGroupConverter::convertFromModel - too few stock chart series" );
+ int nRoleIdx = (aSeries.size() == 3) ? 1 : 0;
+ for( SeriesConvVector::iterator aIt = aSeries.begin(), aEnd = aSeries.end(); (nRoleIdx < 4) && (aIt != aEnd); ++nRoleIdx, ++aIt )
+ {
+ // create a data sequence with a specific role
+ OUString aRole;
+ switch( nRoleIdx )
+ {
+ case 0: aRole = CREATE_OUSTRING( "values-first" ); break;
+ case 1: aRole = CREATE_OUSTRING( "values-max" ); break;
+ case 2: aRole = CREATE_OUSTRING( "values-min" ); break;
+ case 3: aRole = CREATE_OUSTRING( "values-last" ); break;
+ }
+ Reference< XLabeledDataSequence > xDataSeq = (*aIt)->createValueSequence( aRole );
+ if( xDataSeq.is() )
+ aLabeledSeqVec.push_back( xDataSeq );
+ }
+
+ // attach labeled data sequences to series and insert series into chart type
+ xDataSink->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec ) );
+
+ // formatting of high/low lines
+ aTypeProp.setProperty( PROP_ShowHighLow, true );
+ PropertySet aSeriesProp( xDataSeries );
+ if( mrModel.mxHiLowLines.is() )
+ getFormatter().convertFrameFormatting( aSeriesProp, mrModel.mxHiLowLines, OBJECTTYPE_HILOLINE );
+ else
+ // hi/low-lines cannot be switched off via "ShowHighLow" property (?)
+ aSeriesProp.setProperty( PROP_LineStyle, ::com::sun::star::drawing::LineStyle_NONE );
+
+ // formatting of up/down bars
+ bool bUpDownBars = mrModel.mxUpDownBars.is();
+ aTypeProp.setProperty( PROP_Japanese, bUpDownBars );
+ aTypeProp.setProperty( PROP_ShowFirst, bUpDownBars );
+ if( bUpDownBars )
+ {
+ UpDownBarsConverter aUpDownConv( *this, *mrModel.mxUpDownBars );
+ aUpDownConv.convertFromModel( xChartType );
+ }
+
+ // insert the series into the chart type object
+ insertDataSeries( xChartType, xDataSeries, nAxesSetIdx );
+ }
+ }
+ else
+ {
+ for( SeriesConvVector::iterator aIt = aSeries.begin(), aEnd = aSeries.end(); aIt != aEnd; ++aIt )
+ {
+ SeriesConverter& rSeriesConv = **aIt;
+ Reference< XDataSeries > xDataSeries = rSeriesConv.createDataSeries( *this, bVaryColorsByPoint );
+ insertDataSeries( xChartType, xDataSeries, nAxesSetIdx );
+
+ /* Excel does not use the value of the c:smooth element of the
+ chart type to set a default line smoothing for the data
+ series. Line smoothing is always controlled by the c:smooth
+ element of the respective data series. If the element in the
+ data series is missing, line smoothing is off, regardless of
+ the c:smooth element of the chart type. */
+#if !OOX_CHART_SMOOTHED_PER_SERIES
+ if( rSeriesConv.getModel().mbSmooth )
+ convertLineSmooth( aTypeProp, true );
+#endif
+ }
+ }
+
+ // add chart type object to coordinate system
+ Reference< XChartTypeContainer > xChartTypeCont( rxCoordSystem, UNO_QUERY_THROW );
+ xChartTypeCont->addChartType( xChartType );
+
+ // set existence of bar connector lines at diagram (only in stacked 2D bar charts)
+ if( mrModel.mxSerLines.is() && !mb3dChart && (maTypeInfo.meTypeCategory == TYPECATEGORY_BAR) && (isStacked() || isPercent()) )
+ aDiaProp.setProperty( PROP_ConnectBars, true );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "TypeGroupConverter::convertFromModel - cannot add chart type" );
+ }
+}
+
+void TypeGroupConverter::convertMarker( PropertySet& rPropSet, sal_Int32 nOoxSymbol, sal_Int32 nOoxSize ) const
+{
+ if( !isSeriesFrameFormat() )
+ {
+ namespace cssc = ::com::sun::star::chart2;
+
+ // symbol style
+ cssc::Symbol aSymbol;
+ aSymbol.Style = cssc::SymbolStyle_STANDARD;
+ switch( nOoxSymbol )
+ {
+ case XML_auto: aSymbol.Style = cssc::SymbolStyle_AUTO; break;
+ case XML_none: aSymbol.Style = cssc::SymbolStyle_NONE; break;
+ case XML_square: aSymbol.StandardSymbol = 0; break; // square
+ case XML_diamond: aSymbol.StandardSymbol = 1; break; // diamond
+ case XML_triangle: aSymbol.StandardSymbol = 3; break; // arrow up
+ case XML_x: aSymbol.StandardSymbol = 6; break; // bow tie
+ case XML_star: aSymbol.StandardSymbol = 7; break; // sand glass
+ case XML_dot: aSymbol.StandardSymbol = 4; break; // arrow right
+ case XML_dash: aSymbol.StandardSymbol = 2; break; // arrow down
+ case XML_circle: aSymbol.StandardSymbol = 4; break; // arrow right
+ case XML_plus: aSymbol.StandardSymbol = 5; break; // arrow left
+ }
+
+ // symbol size (points in OOXML, 1/100 mm in Chart2)
+ sal_Int32 nSize = static_cast< sal_Int32 >( nOoxSize * (2540.0 / 72.0) + 0.5 );
+ aSymbol.Size.Width = aSymbol.Size.Height = nSize;
+
+ // set the property
+ rPropSet.setProperty( PROP_Symbol, aSymbol );
+ }
+}
+
+void TypeGroupConverter::convertLineSmooth( PropertySet& rPropSet, bool bOoxSmooth ) const
+{
+ if( !isSeriesFrameFormat() && (maTypeInfo.meTypeCategory != TYPECATEGORY_RADAR) )
+ {
+ namespace cssc = ::com::sun::star::chart2;
+ cssc::CurveStyle eCurveStyle = bOoxSmooth ? cssc::CurveStyle_CUBIC_SPLINES : cssc::CurveStyle_LINES;
+ rPropSet.setProperty( PROP_CurveStyle, eCurveStyle );
+ }
+}
+
+void TypeGroupConverter::convertBarGeometry( PropertySet& rPropSet, sal_Int32 nOoxShape ) const
+{
+ if( mb3dChart && (maTypeInfo.meTypeCategory == TYPECATEGORY_BAR) )
+ {
+ namespace cssc = ::com::sun::star::chart2;
+
+ sal_Int32 nGeom3d = cssc::DataPointGeometry3D::CUBOID;
+ switch( nOoxShape )
+ {
+ case XML_box: nGeom3d = cssc::DataPointGeometry3D::CUBOID; break;
+ case XML_cone: nGeom3d = cssc::DataPointGeometry3D::CONE; break;
+ case XML_coneToMax: nGeom3d = cssc::DataPointGeometry3D::CONE; break;
+ case XML_cylinder: nGeom3d = cssc::DataPointGeometry3D::CYLINDER; break;
+ case XML_pyramid: nGeom3d = cssc::DataPointGeometry3D::PYRAMID; break;
+ case XML_pyramidToMax: nGeom3d = cssc::DataPointGeometry3D::PYRAMID; break;
+ default: OSL_ENSURE( false, "TypeGroupConverter::convertBarGeometry - unknown 3D bar shape type" );
+ }
+ rPropSet.setProperty( PROP_Geometry3D, nGeom3d );
+ }
+}
+
+void TypeGroupConverter::convertPieRotation( PropertySet& rPropSet, sal_Int32 nOoxAngle ) const
+{
+ if( maTypeInfo.meTypeCategory == TYPECATEGORY_PIE )
+ {
+ // map OOXML [0,360] clockwise (0deg top) to Chart2 counterclockwise (0deg left)
+ sal_Int32 nAngle = (450 - nOoxAngle) % 360;
+ rPropSet.setProperty( PROP_StartingAngle, nAngle );
+ }
+}
+
+void TypeGroupConverter::convertPieExplosion( PropertySet& rPropSet, sal_Int32 nOoxExplosion ) const
+{
+ if( maTypeInfo.meTypeCategory == TYPECATEGORY_PIE )
+ {
+ // pie explosion restricted to 100% in Chart2, set as double in range [0,1]
+ double fOffset = getLimitedValue< double >( nOoxExplosion / 100.0, 0.0, 1.0 );
+ rPropSet.setProperty( PROP_Offset, fOffset );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void TypeGroupConverter::insertDataSeries( const Reference< XChartType >& rxChartType, const Reference< XDataSeries >& rxSeries, sal_Int32 nAxesSetIdx )
+{
+ if( rxSeries.is() )
+ {
+ PropertySet aSeriesProp( rxSeries );
+
+ // series stacking mode
+ namespace cssc = ::com::sun::star::chart2;
+ cssc::StackingDirection eStacking = cssc::StackingDirection_NO_STACKING;
+ // stacked overrides deep-3d
+ if( isStacked() || isPercent() )
+ eStacking = cssc::StackingDirection_Y_STACKING;
+ else if( isDeep3dChart() )
+ eStacking = cssc::StackingDirection_Z_STACKING;
+ aSeriesProp.setProperty( PROP_StackingDirection, eStacking );
+
+ // additional series properties
+ aSeriesProp.setProperty( PROP_AttachedAxisIndex, nAxesSetIdx );
+
+ // insert series into container
+ try
+ {
+ Reference< XDataSeriesContainer > xSeriesCont( rxChartType, UNO_QUERY_THROW );
+ xSeriesCont->addDataSeries( rxSeries );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "TypeGroupConverter::insertDataSeries - cannot add data series" );
+ }
+ }
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/chart/typegroupmodel.cxx b/oox/source/drawingml/chart/typegroupmodel.cxx
new file mode 100644
index 000000000000..ee5eefc4d163
--- /dev/null
+++ b/oox/source/drawingml/chart/typegroupmodel.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/chart/typegroupmodel.hxx"
+
+namespace oox {
+namespace drawingml {
+namespace chart {
+
+// ============================================================================
+
+UpDownBarsModel::UpDownBarsModel() :
+ mnGapWidth( 150 )
+{
+}
+
+UpDownBarsModel::~UpDownBarsModel()
+{
+}
+
+// ============================================================================
+
+TypeGroupModel::TypeGroupModel( sal_Int32 nTypeId ) :
+ mfSplitPos( 0.0 ),
+ mnBarDir( XML_col ),
+ mnBubbleScale( 100 ),
+ mnFirstAngle( 0 ),
+ mnGapDepth( 150 ),
+ mnGapWidth( 150 ),
+ mnGrouping( XML_standard ),
+ mnHoleSize( 10 ),
+ mnOfPieType( XML_pie ),
+ mnOverlap( 0 ),
+ mnRadarStyle( XML_standard ),
+ mnScatterStyle( XML_marker ),
+ mnSecondPieSize( 75 ),
+ mnShape( XML_box ),
+ mnSizeRepresents( XML_area ),
+ mnSplitType( XML_auto ),
+ mnTypeId( nTypeId ),
+ mbBubble3d( false ),
+ mbShowMarker( false ),
+ mbShowNegBubbles( false ),
+ mbSmooth( false ),
+ mbVaryColors( false ),
+ mbWireframe( false )
+{
+}
+
+TypeGroupModel::~TypeGroupModel()
+{
+}
+
+// ============================================================================
+
+} // namespace chart
+} // namespace drawingml
+} // namespace oox
diff --git a/oox/source/drawingml/clrscheme.cxx b/oox/source/drawingml/clrscheme.cxx
new file mode 100644
index 000000000000..b011cd27b147
--- /dev/null
+++ b/oox/source/drawingml/clrscheme.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/clrscheme.hxx"
+#include "oox/token/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_lt1; break;
+ case XML_bg2 : nSchemeClrToken = XML_lt2; break;
+ case XML_tx1 : nSchemeClrToken = XML_dk1; break;
+ case XML_tx2 : nSchemeClrToken = XML_dk2; 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;
+}
+
+} }
diff --git a/oox/source/drawingml/clrschemecontext.cxx b/oox/source/drawingml/clrschemecontext.cxx
new file mode 100644
index 000000000000..fad92dd35c3c
--- /dev/null
+++ b/oox/source/drawingml/clrschemecontext.cxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/clrschemecontext.hxx"
+#include "oox/core/xmlfilterbase.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,
+ ClrMap& rClrMap, sal_Int32 nToken )
+{
+ if ( xAttributes->hasAttribute( nToken ) )
+ {
+ sal_Int32 nMappedToken = xAttributes->getOptionalValueToken( nToken, 0 );
+ rClrMap.setColorMap( nToken, nMappedToken );
+ }
+}
+
+clrMapContext::clrMapContext( ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttributes, ClrMap& rClrMap )
+: ContextHandler( rParent )
+{
+ 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 );
+}
+
+clrSchemeColorContext::clrSchemeColorContext( ContextHandler& rParent, ClrScheme& rClrScheme, sal_Int32 nColorToken ) :
+ ColorContext( rParent, *this ),
+ mrClrScheme( rClrScheme ),
+ mnColorToken( nColorToken )
+{
+}
+
+clrSchemeColorContext::~clrSchemeColorContext()
+{
+ mrClrScheme.setColor( mnColorToken, getColor( getFilter().getGraphicHelper() ) );
+}
+
+clrSchemeContext::clrSchemeContext( ContextHandler& rParent, ClrScheme& rClrScheme ) :
+ ContextHandler( rParent ),
+ mrClrScheme( rClrScheme )
+{
+}
+
+Reference< XFastContextHandler > clrSchemeContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( dk1 ):
+ case A_TOKEN( lt1 ):
+ case A_TOKEN( dk2 ):
+ case A_TOKEN( lt2 ):
+ case A_TOKEN( accent1 ):
+ case A_TOKEN( accent2 ):
+ case A_TOKEN( accent3 ):
+ case A_TOKEN( accent4 ):
+ case A_TOKEN( accent5 ):
+ case A_TOKEN( accent6 ):
+ case A_TOKEN( hlink ):
+ case A_TOKEN( folHlink ):
+ return new clrSchemeColorContext( *this, mrClrScheme, getBaseToken( nElement ) );
+ }
+ return 0;
+}
+
+} }
diff --git a/oox/source/drawingml/color.cxx b/oox/source/drawingml/color.cxx
new file mode 100644
index 000000000000..4ff19a4bf987
--- /dev/null
+++ b/oox/source/drawingml/color.cxx
@@ -0,0 +1,670 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/color.hxx"
+#include <algorithm>
+#include <math.h>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/token/namespaces.hxx"
+#include "oox/token/tokens.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+namespace {
+
+/** Global storage for predefined color values used in OOXML file formats. */
+struct PresetColorsPool
+{
+ typedef ::std::vector< sal_Int32 > ColorVector;
+
+ ColorVector maDmlColors; /// Predefined colors in DrawingML, indexed by XML token.
+ ColorVector maVmlColors; /// Predefined colors in VML, indexed by XML token.
+
+ explicit PresetColorsPool();
+};
+
+// ----------------------------------------------------------------------------
+
+PresetColorsPool::PresetColorsPool() :
+ maDmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ),
+ maVmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT )
+{
+ // predefined colors in DrawingML (map XML token identifiers to RGB values)
+ static const sal_Int32 spnDmlColors[] =
+ {
+ XML_aliceBlue, 0xF0F8FF, XML_antiqueWhite, 0xFAEBD7,
+ XML_aqua, 0x00FFFF, XML_aquamarine, 0x7FFFD4,
+ XML_azure, 0xF0FFFF, XML_beige, 0xF5F5DC,
+ XML_bisque, 0xFFE4C4, XML_black, 0x000000,
+ XML_blanchedAlmond, 0xFFEBCD, XML_blue, 0x0000FF,
+ XML_blueViolet, 0x8A2BE2, XML_brown, 0xA52A2A,
+ XML_burlyWood, 0xDEB887, XML_cadetBlue, 0x5F9EA0,
+ XML_chartreuse, 0x7FFF00, XML_chocolate, 0xD2691E,
+ XML_coral, 0xFF7F50, XML_cornflowerBlue, 0x6495ED,
+ XML_cornsilk, 0xFFF8DC, XML_crimson, 0xDC143C,
+ XML_cyan, 0x00FFFF, XML_deepPink, 0xFF1493,
+ XML_deepSkyBlue, 0x00BFFF, XML_dimGray, 0x696969,
+ XML_dkBlue, 0x00008B, XML_dkCyan, 0x008B8B,
+ XML_dkGoldenrod, 0xB8860B, XML_dkGray, 0xA9A9A9,
+ XML_dkGreen, 0x006400, XML_dkKhaki, 0xBDB76B,
+ XML_dkMagenta, 0x8B008B, XML_dkOliveGreen, 0x556B2F,
+ XML_dkOrange, 0xFF8C00, XML_dkOrchid, 0x9932CC,
+ XML_dkRed, 0x8B0000, XML_dkSalmon, 0xE9967A,
+ XML_dkSeaGreen, 0x8FBC8B, XML_dkSlateBlue, 0x483D8B,
+ XML_dkSlateGray, 0x2F4F4F, XML_dkTurquoise, 0x00CED1,
+ XML_dkViolet, 0x9400D3, XML_dodgerBlue, 0x1E90FF,
+ XML_firebrick, 0xB22222, XML_floralWhite, 0xFFFAF0,
+ XML_forestGreen, 0x228B22, XML_fuchsia, 0xFF00FF,
+ XML_gainsboro, 0xDCDCDC, XML_ghostWhite, 0xF8F8FF,
+ XML_gold, 0xFFD700, XML_goldenrod, 0xDAA520,
+ XML_gray, 0x808080, XML_green, 0x008000,
+ XML_greenYellow, 0xADFF2F, XML_honeydew, 0xF0FFF0,
+ XML_hotPink, 0xFF69B4, XML_indianRed, 0xCD5C5C,
+ XML_indigo, 0x4B0082, XML_ivory, 0xFFFFF0,
+ XML_khaki, 0xF0E68C, XML_lavender, 0xE6E6FA,
+ XML_lavenderBlush, 0xFFF0F5, XML_lawnGreen, 0x7CFC00,
+ XML_lemonChiffon, 0xFFFACD, XML_lime, 0x00FF00,
+ XML_limeGreen, 0x32CD32, XML_linen, 0xFAF0E6,
+ XML_ltBlue, 0xADD8E6, XML_ltCoral, 0xF08080,
+ XML_ltCyan, 0xE0FFFF, XML_ltGoldenrodYellow, 0xFAFA78,
+ XML_ltGray, 0xD3D3D3, XML_ltGreen, 0x90EE90,
+ XML_ltPink, 0xFFB6C1, XML_ltSalmon, 0xFFA07A,
+ XML_ltSeaGreen, 0x20B2AA, XML_ltSkyBlue, 0x87CEFA,
+ XML_ltSlateGray, 0x778899, XML_ltSteelBlue, 0xB0C4DE,
+ XML_ltYellow, 0xFFFFE0, XML_magenta, 0xFF00FF,
+ XML_maroon, 0x800000, XML_medAquamarine, 0x66CDAA,
+ XML_medBlue, 0x0000CD, XML_medOrchid, 0xBA55D3,
+ XML_medPurple, 0x9370DB, XML_medSeaGreen, 0x3CB371,
+ XML_medSlateBlue, 0x7B68EE, XML_medSpringGreen, 0x00FA9A,
+ XML_medTurquoise, 0x48D1CC, XML_medVioletRed, 0xC71585,
+ XML_midnightBlue, 0x191970, XML_mintCream, 0xF5FFFA,
+ XML_mistyRose, 0xFFE4E1, XML_moccasin, 0xFFE4B5,
+ XML_navajoWhite, 0xFFDEAD, XML_navy, 0x000080,
+ XML_oldLace, 0xFDF5E6, XML_olive, 0x808000,
+ XML_oliveDrab, 0x6B8E23, XML_orange, 0xFFA500,
+ XML_orangeRed, 0xFF4500, XML_orchid, 0xDA70D6,
+ XML_paleGoldenrod, 0xEEE8AA, XML_paleGreen, 0x98FB98,
+ XML_paleTurquoise, 0xAFEEEE, XML_paleVioletRed, 0xDB7093,
+ XML_papayaWhip, 0xFFEFD5, XML_peachPuff, 0xFFDAB9,
+ XML_peru, 0xCD853F, XML_pink, 0xFFC0CB,
+ XML_plum, 0xDDA0DD, XML_powderBlue, 0xB0E0E6,
+ XML_purple, 0x800080, XML_red, 0xFF0000,
+ XML_rosyBrown, 0xBC8F8F, XML_royalBlue, 0x4169E1,
+ XML_saddleBrown, 0x8B4513, XML_salmon, 0xFA8072,
+ XML_sandyBrown, 0xF4A460, XML_seaGreen, 0x2E8B57,
+ XML_seaShell, 0xFFF5EE, XML_sienna, 0xA0522D,
+ XML_silver, 0xC0C0C0, XML_skyBlue, 0x87CEEB,
+ XML_slateBlue, 0x6A5ACD, XML_slateGray, 0x708090,
+ XML_snow, 0xFFFAFA, XML_springGreen, 0x00FF7F,
+ XML_steelBlue, 0x4682B4, XML_tan, 0xD2B48C,
+ XML_teal, 0x008080, XML_thistle, 0xD8BFD8,
+ XML_tomato, 0xFF6347, XML_turquoise, 0x40E0D0,
+ XML_violet, 0xEE82EE, XML_wheat, 0xF5DEB3,
+ XML_white, 0xFFFFFF, XML_whiteSmoke, 0xF5F5F5,
+ XML_yellow, 0xFFFF00, XML_yellowGreen, 0x9ACD32
+ };
+ for( const sal_Int32* pnEntry = spnDmlColors; pnEntry < STATIC_ARRAY_END( spnDmlColors ); pnEntry += 2 )
+ maDmlColors[ static_cast< size_t >( pnEntry[ 0 ] ) ] = pnEntry[ 1 ];
+
+ // predefined colors in VML (map XML token identifiers to RGB values)
+ static const sal_Int32 spnVmlColors[] =
+ {
+ XML_aqua, 0x00FFFF, XML_black, 0x000000,
+ XML_blue, 0x0000FF, XML_fuchsia, 0xFF00FF,
+ XML_gray, 0x808080, XML_green, 0x008000,
+ XML_lime, 0x00FF00, XML_maroon, 0x800000,
+ XML_navy, 0x000080, XML_olive, 0x808000,
+ XML_purple, 0x800080, XML_red, 0xFF0000,
+ XML_silver, 0xC0C0C0, XML_teal, 0x008080,
+ XML_white, 0xFFFFFF, XML_yellow, 0xFFFF00
+ };
+ for( const sal_Int32* pnEntry = spnVmlColors; pnEntry < STATIC_ARRAY_END( spnVmlColors ); pnEntry += 2 )
+ maVmlColors[ static_cast< size_t >( pnEntry[ 0 ] ) ] = pnEntry[ 1 ];
+}
+
+// ----------------------------------------------------------------------------
+
+struct StaticPresetColorsPool : public ::rtl::Static< PresetColorsPool, StaticPresetColorsPool > {};
+
+// ----------------------------------------------------------------------------
+
+const double DEC_GAMMA = 2.3;
+const double INC_GAMMA = 1.0 / DEC_GAMMA;
+
+// ----------------------------------------------------------------------------
+
+inline void lclRgbToRgbComponents( sal_Int32& ornR, sal_Int32& ornG, sal_Int32& ornB, sal_Int32 nRgb )
+{
+ ornR = (nRgb >> 16) & 0xFF;
+ ornG = (nRgb >> 8) & 0xFF;
+ ornB = nRgb & 0xFF;
+}
+
+inline sal_Int32 lclRgbComponentsToRgb( sal_Int32 nR, sal_Int32 nG, sal_Int32 nB )
+{
+ return static_cast< sal_Int32 >( (nR << 16) | (nG << 8) | nB );
+}
+
+inline sal_Int32 lclRgbCompToCrgbComp( sal_Int32 nRgbComp )
+{
+ return static_cast< sal_Int32 >( nRgbComp * MAX_PERCENT / 255 );
+}
+
+inline sal_Int32 lclCrgbCompToRgbComp( sal_Int32 nCrgbComp )
+{
+ return static_cast< sal_Int32 >( nCrgbComp * 255 / MAX_PERCENT );
+}
+
+inline sal_Int32 lclGamma( sal_Int32 nComp, double fGamma )
+{
+ return static_cast< sal_Int32 >( pow( static_cast< double >( nComp ) / MAX_PERCENT, fGamma ) * MAX_PERCENT + 0.5 );
+}
+
+void lclSetValue( sal_Int32& ornValue, sal_Int32 nNew, sal_Int32 nMax = MAX_PERCENT )
+{
+ OSL_ENSURE( (0 <= nNew) && (nNew <= nMax), "lclSetValue - invalid value" );
+ if( (0 <= nNew) && (nNew <= nMax) )
+ ornValue = nNew;
+}
+
+void lclModValue( sal_Int32& ornValue, sal_Int32 nMod, sal_Int32 nMax = MAX_PERCENT )
+{
+ OSL_ENSURE( (0 <= nMod), "lclModValue - invalid modificator" );
+ ornValue = getLimitedValue< sal_Int32, double >( static_cast< double >( ornValue ) * nMod / MAX_PERCENT, 0, nMax );
+}
+
+void lclOffValue( sal_Int32& ornValue, sal_Int32 nOff, sal_Int32 nMax = MAX_PERCENT )
+{
+ OSL_ENSURE( (-nMax <= nOff) && (nOff <= nMax), "lclOffValue - invalid offset" );
+ ornValue = getLimitedValue< sal_Int32, sal_Int32 >( ornValue + nOff, 0, nMax );
+}
+
+} // namespace
+
+// ============================================================================
+
+Color::Color() :
+ meMode( COLOR_UNUSED ),
+ mnC1( 0 ),
+ mnC2( 0 ),
+ mnC3( 0 ),
+ mnAlpha( MAX_PERCENT )
+{
+}
+
+Color::~Color()
+{
+}
+
+/*static*/ sal_Int32 Color::getDmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb )
+{
+ /* Do not pass nDefaultRgb to ContainerHelper::getVectorElement(), to be
+ able to catch the existing vector entries without corresponding XML
+ token identifier. */
+ sal_Int32 nRgbValue = ContainerHelper::getVectorElement( StaticPresetColorsPool::get().maDmlColors, nToken, API_RGB_TRANSPARENT );
+ return (nRgbValue >= 0) ? nRgbValue : nDefaultRgb;
+}
+
+/*static*/ sal_Int32 Color::getVmlPresetColor( sal_Int32 nToken, sal_Int32 nDefaultRgb )
+{
+ /* Do not pass nDefaultRgb to ContainerHelper::getVectorElement(), to be
+ able to catch the existing vector entries without corresponding XML
+ token identifier. */
+ sal_Int32 nRgbValue = ContainerHelper::getVectorElement( StaticPresetColorsPool::get().maVmlColors, nToken, API_RGB_TRANSPARENT );
+ return (nRgbValue >= 0) ? nRgbValue : nDefaultRgb;
+}
+
+void Color::setUnused()
+{
+ meMode = COLOR_UNUSED;
+}
+
+void Color::setSrgbClr( sal_Int32 nRgb )
+{
+ OSL_ENSURE( (0 <= nRgb) && (nRgb <= 0xFFFFFF), "Color::setSrgbClr - invalid RGB value" );
+ meMode = COLOR_RGB;
+ lclRgbToRgbComponents( mnC1, mnC2, mnC3, nRgb );
+}
+
+void Color::setScrgbClr( sal_Int32 nR, sal_Int32 nG, sal_Int32 nB )
+{
+ OSL_ENSURE( (0 <= nR) && (nR <= MAX_PERCENT), "Color::setScrgbClr - invalid red value" );
+ OSL_ENSURE( (0 <= nG) && (nG <= MAX_PERCENT), "Color::setScrgbClr - invalid green value" );
+ OSL_ENSURE( (0 <= nB) && (nB <= MAX_PERCENT), "Color::setScrgbClr - invalid blue value" );
+ meMode = COLOR_CRGB;
+ mnC1 = getLimitedValue< sal_Int32, sal_Int32 >( nR, 0, MAX_PERCENT );
+ mnC2 = getLimitedValue< sal_Int32, sal_Int32 >( nG, 0, MAX_PERCENT );
+ mnC3 = getLimitedValue< sal_Int32, sal_Int32 >( nB, 0, MAX_PERCENT );
+}
+
+void Color::setHslClr( sal_Int32 nHue, sal_Int32 nSat, sal_Int32 nLum )
+{
+ OSL_ENSURE( (0 <= nHue) && (nHue <= MAX_DEGREE), "Color::setHslClr - invalid hue value" );
+ OSL_ENSURE( (0 <= nSat) && (nSat <= MAX_PERCENT), "Color::setHslClr - invalid saturation value" );
+ OSL_ENSURE( (0 <= nLum) && (nLum <= MAX_PERCENT), "Color::setHslClr - invalid luminance value" );
+ meMode = COLOR_HSL;
+ mnC1 = getLimitedValue< sal_Int32, sal_Int32 >( nHue, 0, MAX_DEGREE );
+ mnC2 = getLimitedValue< sal_Int32, sal_Int32 >( nSat, 0, MAX_PERCENT );
+ mnC3 = getLimitedValue< sal_Int32, sal_Int32 >( nLum, 0, MAX_PERCENT );
+}
+
+void Color::setPrstClr( sal_Int32 nToken )
+{
+ sal_Int32 nRgbValue = getDmlPresetColor( nToken, API_RGB_TRANSPARENT );
+ OSL_ENSURE( nRgbValue >= 0, "Color::setPrstClr - invalid preset color token" );
+ if( nRgbValue >= 0 )
+ setSrgbClr( nRgbValue );
+}
+
+void Color::setSchemeClr( sal_Int32 nToken )
+{
+ OSL_ENSURE( nToken != XML_TOKEN_INVALID, "Color::setSchemeClr - invalid color token" );
+ meMode = (nToken == XML_phClr) ? COLOR_PH : COLOR_SCHEME;
+ mnC1 = nToken;
+}
+
+void Color::setPaletteClr( sal_Int32 nPaletteIdx )
+{
+ OSL_ENSURE( nPaletteIdx >= 0, "Color::setPaletteClr - invalid palette index" );
+ meMode = COLOR_PALETTE;
+ mnC1 = nPaletteIdx;
+}
+
+void Color::setSysClr( sal_Int32 nToken, sal_Int32 nLastRgb )
+{
+ OSL_ENSURE( (-1 <= nLastRgb) && (nLastRgb <= 0xFFFFFF), "Color::setSysClr - invalid RGB value" );
+ meMode = COLOR_SYSTEM;
+ mnC1 = nToken;
+ mnC2 = nLastRgb;
+}
+
+void Color::addTransformation( sal_Int32 nElement, sal_Int32 nValue )
+{
+ /* Execute alpha transformations directly, store other transformations in
+ a vector, they may depend on a scheme base color which will be resolved
+ in Color::getColor(). */
+ sal_Int32 nToken = getBaseToken( nElement );
+ switch( nToken )
+ {
+ case XML_alpha: lclSetValue( mnAlpha, nValue ); break;
+ case XML_alphaMod: lclModValue( mnAlpha, nValue ); break;
+ case XML_alphaOff: lclOffValue( mnAlpha, nValue ); break;
+ default: maTransforms.push_back( Transformation( nToken, nValue ) );
+ }
+}
+
+void Color::addChartTintTransformation( double fTint )
+{
+ sal_Int32 nValue = getLimitedValue< sal_Int32, double >( fTint * MAX_PERCENT + 0.5, -MAX_PERCENT, MAX_PERCENT );
+ if( nValue < 0 )
+ maTransforms.push_back( Transformation( XML_shade, nValue + MAX_PERCENT ) );
+ else if( nValue > 0 )
+ maTransforms.push_back( Transformation( XML_tint, MAX_PERCENT - nValue ) );
+}
+
+void Color::addExcelTintTransformation( double fTint )
+{
+ sal_Int32 nValue = getLimitedValue< sal_Int32, double >( fTint * MAX_PERCENT + 0.5, -MAX_PERCENT, MAX_PERCENT );
+ maTransforms.push_back( Transformation( XLS_TOKEN( tint ), nValue ) );
+}
+
+void Color::clearTransformations()
+{
+ maTransforms.clear();
+ clearTransparence();
+}
+
+void Color::clearTransparence()
+{
+ mnAlpha = MAX_PERCENT;
+}
+
+sal_Int32 Color::getColor( const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr ) const
+{
+ /* Special handling for theme style list placeholder colors (state
+ COLOR_PH), Color::getColor() may be called with different placeholder
+ colors in the nPhClr parameter. Therefore, the resolved color will not
+ be stored in this object, thus the state COLOR_FINAL will not be
+ reached and the transformation container will not be cleared, but the
+ original COLOR_PH state will be restored instead. */
+ bool bIsPh = false;
+
+ switch( meMode )
+ {
+ case COLOR_UNUSED: mnC1 = API_RGB_TRANSPARENT; break;
+
+ case COLOR_RGB: break; // nothing to do
+ case COLOR_CRGB: break; // nothing to do
+ case COLOR_HSL: break; // nothing to do
+
+ case COLOR_SCHEME: setResolvedRgb( rGraphicHelper.getSchemeColor( mnC1 ) ); break;
+ case COLOR_PALETTE: setResolvedRgb( rGraphicHelper.getPaletteColor( mnC1 ) ); break;
+ case COLOR_SYSTEM: setResolvedRgb( rGraphicHelper.getSystemColor( mnC1, mnC2 ) ); break;
+ case COLOR_PH: setResolvedRgb( nPhClr ); bIsPh = true; break;
+
+ case COLOR_FINAL: return mnC1;
+ }
+
+ // if color is UNUSED or turns to UNUSED in setResolvedRgb, do not perform transformations
+ if( meMode != COLOR_UNUSED )
+ {
+ for( TransformVec::const_iterator aIt = maTransforms.begin(), aEnd = maTransforms.end(); aIt != aEnd; ++aIt )
+ {
+ switch( aIt->mnToken )
+ {
+ case XML_red: toCrgb(); lclSetValue( mnC1, aIt->mnValue ); break;
+ case XML_redMod: toCrgb(); lclModValue( mnC1, aIt->mnValue ); break;
+ case XML_redOff: toCrgb(); lclOffValue( mnC1, aIt->mnValue ); break;
+ case XML_green: toCrgb(); lclSetValue( mnC2, aIt->mnValue ); break;
+ case XML_greenMod: toCrgb(); lclModValue( mnC2, aIt->mnValue ); break;
+ case XML_greenOff: toCrgb(); lclOffValue( mnC2, aIt->mnValue ); break;
+ case XML_blue: toCrgb(); lclSetValue( mnC3, aIt->mnValue ); break;
+ case XML_blueMod: toCrgb(); lclModValue( mnC3, aIt->mnValue ); break;
+ case XML_blueOff: toCrgb(); lclOffValue( mnC3, aIt->mnValue ); break;
+
+ case XML_hue: toHsl(); lclSetValue( mnC1, aIt->mnValue, MAX_DEGREE ); break;
+ case XML_hueMod: toHsl(); lclModValue( mnC1, aIt->mnValue, MAX_DEGREE ); break;
+ case XML_hueOff: toHsl(); lclOffValue( mnC1, aIt->mnValue, MAX_DEGREE ); break;
+ case XML_sat: toHsl(); lclSetValue( mnC2, aIt->mnValue ); break;
+ case XML_satMod: toHsl(); lclModValue( mnC2, aIt->mnValue ); break;
+ case XML_satOff: toHsl(); lclOffValue( mnC2, aIt->mnValue ); break;
+
+ case XML_lum:
+ toHsl();
+ lclSetValue( mnC3, aIt->mnValue );
+ // if color changes to black or white, it will stay gray if luminance changes again
+ if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0;
+ break;
+ case XML_lumMod:
+ toHsl();
+ lclModValue( mnC3, aIt->mnValue );
+ // if color changes to black or white, it will stay gray if luminance changes again
+ if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0;
+ break;
+ case XML_lumOff:
+ toHsl();
+ lclOffValue( mnC3, aIt->mnValue );
+ // if color changes to black or white, it will stay gray if luminance changes again
+ if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) mnC2 = 0;
+ break;
+
+ case XML_shade:
+ // shade: 0% = black, 100% = original color
+ toCrgb();
+ OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid shade value" );
+ if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) )
+ {
+ double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT;
+ mnC1 = static_cast< sal_Int32 >( mnC1 * fFactor );
+ mnC2 = static_cast< sal_Int32 >( mnC2 * fFactor );
+ mnC3 = static_cast< sal_Int32 >( mnC3 * fFactor );
+ }
+ break;
+ case XML_tint:
+ // tint: 0% = white, 100% = original color
+ toCrgb();
+ OSL_ENSURE( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" );
+ if( (0 <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) )
+ {
+ double fFactor = static_cast< double >( aIt->mnValue ) / MAX_PERCENT;
+ mnC1 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC1) * fFactor );
+ mnC2 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC2) * fFactor );
+ mnC3 = static_cast< sal_Int32 >( MAX_PERCENT - (MAX_PERCENT - mnC3) * fFactor );
+ }
+ break;
+ case XLS_TOKEN( tint ):
+ // Excel tint: move luminance relative to current value
+ toHsl();
+ OSL_ENSURE( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT), "Color::getColor - invalid tint value" );
+ if( (-MAX_PERCENT <= aIt->mnValue) && (aIt->mnValue < 0) )
+ {
+ // negative: luminance towards 0% (black)
+ lclModValue( mnC3, aIt->mnValue + MAX_PERCENT );
+ }
+ else if( (0 < aIt->mnValue) && (aIt->mnValue <= MAX_PERCENT) )
+ {
+ // positive: luminance towards 100% (white)
+ mnC3 = MAX_PERCENT - mnC3;
+ lclModValue( mnC3, MAX_PERCENT - aIt->mnValue );
+ mnC3 = MAX_PERCENT - mnC3;
+ }
+ break;
+
+ case XML_gray:
+ // change color to gray, weighted RGB: 22% red, 72% green, 6% blue
+ toRgb();
+ mnC1 = mnC2 = mnC3 = (mnC1 * 22 + mnC2 * 72 + mnC3 * 6) / 100;
+ break;
+
+ case XML_comp:
+ // comp: rotate hue by 180 degrees, do not change lum/sat
+ toHsl();
+ (mnC1 += 180 * PER_DEGREE) %= MAX_DEGREE;
+ break;
+ case XML_inv:
+ // invert percentual RGB values
+ toCrgb();
+ mnC1 = MAX_PERCENT - mnC1;
+ mnC2 = MAX_PERCENT - mnC2;
+ mnC3 = MAX_PERCENT - mnC3;
+ break;
+
+ case XML_gamma:
+ // increase gamma of color
+ toCrgb();
+ mnC1 = lclGamma( mnC1, INC_GAMMA );
+ mnC2 = lclGamma( mnC2, INC_GAMMA );
+ mnC3 = lclGamma( mnC3, INC_GAMMA );
+ break;
+ case XML_invGamma:
+ // decrease gamma of color
+ toCrgb();
+ mnC1 = lclGamma( mnC1, DEC_GAMMA );
+ mnC2 = lclGamma( mnC2, DEC_GAMMA );
+ mnC3 = lclGamma( mnC3, DEC_GAMMA );
+ break;
+ }
+ }
+
+ // store resulting RGB value in mnC1
+ toRgb();
+ mnC1 = lclRgbComponentsToRgb( mnC1, mnC2, mnC3 );
+ }
+ else // if( meMode != COLOR_UNUSED )
+ {
+ mnC1 = API_RGB_TRANSPARENT;
+ }
+
+ meMode = bIsPh ? COLOR_PH : COLOR_FINAL;
+ if( meMode == COLOR_FINAL )
+ maTransforms.clear();
+ return mnC1;
+}
+
+bool Color::hasTransparence() const
+{
+ return mnAlpha < MAX_PERCENT;
+}
+
+sal_Int16 Color::getTransparence() const
+{
+ return static_cast< sal_Int16 >( (MAX_PERCENT - mnAlpha) / PER_PERCENT );
+}
+
+// private --------------------------------------------------------------------
+
+void Color::setResolvedRgb( sal_Int32 nRgb ) const
+{
+ meMode = (nRgb < 0) ? COLOR_UNUSED : COLOR_RGB;
+ lclRgbToRgbComponents( mnC1, mnC2, mnC3, nRgb );
+}
+
+void Color::toRgb() const
+{
+ switch( meMode )
+ {
+ case COLOR_RGB:
+ // nothing to do
+ break;
+ case COLOR_CRGB:
+ meMode = COLOR_RGB;
+ mnC1 = lclCrgbCompToRgbComp( lclGamma( mnC1, INC_GAMMA ) );
+ mnC2 = lclCrgbCompToRgbComp( lclGamma( mnC2, INC_GAMMA ) );
+ mnC3 = lclCrgbCompToRgbComp( lclGamma( mnC3, INC_GAMMA ) );
+ break;
+ case COLOR_HSL:
+ {
+ meMode = COLOR_RGB;
+ double fR = 0.0, fG = 0.0, fB = 0.0;
+ if( (mnC2 == 0) || (mnC3 == MAX_PERCENT) )
+ {
+ fR = fG = fB = static_cast< double >( mnC3 ) / MAX_PERCENT;
+ }
+ else if( mnC3 > 0 )
+ {
+ // base color from hue
+ double fHue = static_cast< double >( mnC1 ) / MAX_DEGREE * 6.0; // interval [0.0, 6.0)
+ if( fHue <= 1.0 ) { fR = 1.0; fG = fHue; } // red...yellow
+ else if( fHue <= 2.0 ) { fR = 2.0 - fHue; fG = 1.0; } // yellow...green
+ else if( fHue <= 3.0 ) { fG = 1.0; fB = fHue - 2.0; } // green...cyan
+ else if( fHue <= 4.0 ) { fG = 4.0 - fHue; fB = 1.0; } // cyan...blue
+ else if( fHue <= 5.0 ) { fR = fHue - 4.0; fB = 1.0; } // blue...magenta
+ else { fR = 1.0; fB = 6.0 - fHue; } // magenta...red
+
+ // apply saturation
+ double fSat = static_cast< double >( mnC2 ) / MAX_PERCENT;
+ fR = (fR - 0.5) * fSat + 0.5;
+ fG = (fG - 0.5) * fSat + 0.5;
+ fB = (fB - 0.5) * fSat + 0.5;
+
+ // apply luminance
+ double fLum = 2.0 * static_cast< double >( mnC3 ) / MAX_PERCENT - 1.0; // interval [-1.0, 1.0]
+ if( fLum < 0.0 )
+ {
+ double fShade = fLum + 1.0; // interval [0.0, 1.0] (black...full color)
+ fR *= fShade;
+ fG *= fShade;
+ fB *= fShade;
+ }
+ else if( fLum > 0.0 )
+ {
+ double fTint = 1.0 - fLum; // interval [0.0, 1.0] (white...full color)
+ fR = 1.0 - ((1.0 - fR) * fTint);
+ fG = 1.0 - ((1.0 - fG) * fTint);
+ fB = 1.0 - ((1.0 - fB) * fTint);
+ }
+ }
+ mnC1 = static_cast< sal_Int32 >( fR * 255.0 + 0.5 );
+ mnC2 = static_cast< sal_Int32 >( fG * 255.0 + 0.5 );
+ mnC3 = static_cast< sal_Int32 >( fB * 255.0 + 0.5 );
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "Color::toRgb - unexpected color mode" );
+ }
+}
+
+void Color::toCrgb() const
+{
+ switch( meMode )
+ {
+ case COLOR_HSL:
+ toRgb();
+ // run through!
+ case COLOR_RGB:
+ meMode = COLOR_CRGB;
+ mnC1 = lclGamma( lclRgbCompToCrgbComp( mnC1 ), DEC_GAMMA );
+ mnC2 = lclGamma( lclRgbCompToCrgbComp( mnC2 ), DEC_GAMMA );
+ mnC3 = lclGamma( lclRgbCompToCrgbComp( mnC3 ), DEC_GAMMA );
+ break;
+ case COLOR_CRGB:
+ // nothing to do
+ break;
+ default:
+ OSL_ENSURE( false, "Color::toCrgb - unexpected color mode" );
+ }
+}
+
+void Color::toHsl() const
+{
+ switch( meMode )
+ {
+ case COLOR_CRGB:
+ toRgb();
+ // run through!
+ case COLOR_RGB:
+ {
+ meMode = COLOR_HSL;
+ double fR = static_cast< double >( mnC1 ) / 255.0; // red [0.0, 1.0]
+ double fG = static_cast< double >( mnC2 ) / 255.0; // green [0.0, 1.0]
+ double fB = static_cast< double >( mnC3 ) / 255.0; // blue [0.0, 1.0]
+ double fMin = ::std::min( ::std::min( fR, fG ), fB );
+ double fMax = ::std::max( ::std::max( fR, fG ), fB );
+ double fD = fMax - fMin;
+
+ // hue: 0deg = red, 120deg = green, 240deg = blue
+ if( fD == 0.0 ) // black/gray/white
+ mnC1 = 0;
+ else if( fMax == fR ) // magenta...red...yellow
+ mnC1 = static_cast< sal_Int32 >( ((fG - fB) / fD * 60.0 + 360.0) * PER_DEGREE + 0.5 ) % MAX_DEGREE;
+ else if( fMax == fG ) // yellow...green...cyan
+ mnC1 = static_cast< sal_Int32 >( ((fB - fR) / fD * 60.0 + 120.0) * PER_DEGREE + 0.5 );
+ else // cyan...blue...magenta
+ mnC1 = static_cast< sal_Int32 >( ((fR - fG) / fD * 60.0 + 240.0) * PER_DEGREE + 0.5 );
+
+ // luminance: 0% = black, 50% = full color, 100% = white
+ mnC3 = static_cast< sal_Int32 >( (fMin + fMax) / 2.0 * MAX_PERCENT + 0.5 );
+
+ // saturation: 0% = gray, 100% = full color
+ if( (mnC3 == 0) || (mnC3 == MAX_PERCENT) ) // black/white
+ mnC2 = 0;
+ else if( mnC3 <= 50 * PER_PERCENT ) // dark...full color
+ mnC2 = static_cast< sal_Int32 >( fD / (fMin + fMax) * MAX_PERCENT + 0.5 );
+ else // full color...light
+ mnC2 = static_cast< sal_Int32 >( fD / (2.0 - fMax - fMin) * MAX_PERCENT + 0.5 );
+ }
+ break;
+ case COLOR_HSL:
+ // nothing to do
+ break;
+ default:
+ OSL_ENSURE( false, "Color::toHsl - unexpected color mode" );
+ }
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/colorchoicecontext.cxx b/oox/source/drawingml/colorchoicecontext.cxx
new file mode 100644
index 000000000000..a909f2f68d0c
--- /dev/null
+++ b/oox/source/drawingml/colorchoicecontext.cxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/drawingml/color.hxx"
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::xml::sax::SAXException;
+using ::com::sun::star::xml::sax::XFastAttributeList;
+using ::com::sun::star::xml::sax::XFastContextHandler;
+using ::oox::core::ContextHandler;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+ColorValueContext::ColorValueContext( ContextHandler& rParent, Color& rColor ) :
+ ContextHandler( rParent ),
+ mrColor( rColor )
+{
+}
+
+void ColorValueContext::startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
+ throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( rxAttribs );
+ switch( nElement )
+ {
+ case A_TOKEN( scrgbClr ):
+ mrColor.setScrgbClr(
+ aAttribs.getInteger( XML_r, 0 ),
+ aAttribs.getInteger( XML_g, 0 ),
+ aAttribs.getInteger( XML_b, 0 ) );
+ break;
+
+ case A_TOKEN( srgbClr ):
+ mrColor.setSrgbClr( aAttribs.getIntegerHex( XML_val, 0 ) );
+ break;
+
+ case A_TOKEN( hslClr ):
+ mrColor.setHslClr(
+ aAttribs.getInteger( XML_hue, 0 ),
+ aAttribs.getInteger( XML_sat, 0 ),
+ aAttribs.getInteger( XML_lum, 0 ) );
+ break;
+
+ case A_TOKEN( sysClr ):
+ mrColor.setSysClr(
+ aAttribs.getToken( XML_val, XML_TOKEN_INVALID ),
+ aAttribs.getIntegerHex( XML_lastClr, -1 ) );
+ break;
+
+ case A_TOKEN( schemeClr ):
+ mrColor.setSchemeClr( aAttribs.getToken( XML_val, XML_TOKEN_INVALID ) );
+ break;
+
+ case A_TOKEN( prstClr ):
+ mrColor.setPrstClr( aAttribs.getToken( XML_val, XML_TOKEN_INVALID ) );
+ break;
+ }
+}
+
+Reference< XFastContextHandler > ColorValueContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( rxAttribs );
+ switch( nElement )
+ {
+ case A_TOKEN( alpha ):
+ case A_TOKEN( alphaMod ):
+ case A_TOKEN( alphaOff ):
+ case A_TOKEN( blue ):
+ case A_TOKEN( blueMod ):
+ case A_TOKEN( blueOff ):
+ case A_TOKEN( hue ):
+ case A_TOKEN( hueMod ):
+ case A_TOKEN( hueOff ):
+ case A_TOKEN( lum ):
+ case A_TOKEN( lumMod ):
+ case A_TOKEN( lumOff ):
+ case A_TOKEN( green ):
+ case A_TOKEN( greenMod ):
+ case A_TOKEN( greenOff ):
+ case A_TOKEN( red ):
+ case A_TOKEN( redMod ):
+ case A_TOKEN( redOff ):
+ case A_TOKEN( sat ):
+ case A_TOKEN( satMod ):
+ case A_TOKEN( satOff ):
+ case A_TOKEN( shade ):
+ case A_TOKEN( tint ):
+ mrColor.addTransformation( nElement, aAttribs.getInteger( XML_val, 0 ) );
+ break;
+ case A_TOKEN( comp ):
+ case A_TOKEN( gamma ):
+ case A_TOKEN( gray ):
+ case A_TOKEN( inv ):
+ case A_TOKEN( invGamma ):
+ mrColor.addTransformation( nElement );
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ColorContext::ColorContext( ContextHandler& rParent, Color& rColor ) :
+ ContextHandler( rParent ),
+ mrColor( rColor )
+{
+}
+
+Reference< XFastContextHandler > ColorContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( scrgbClr ):
+ case A_TOKEN( srgbClr ):
+ case A_TOKEN( hslClr ):
+ case A_TOKEN( sysClr ):
+ case A_TOKEN( schemeClr ):
+ case A_TOKEN( prstClr ):
+ return new ColorValueContext( *this, mrColor );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/connectorshapecontext.cxx b/oox/source/drawingml/connectorshapecontext.cxx
new file mode 100644
index 000000000000..f2840a8d82fa
--- /dev/null
+++ b/oox/source/drawingml/connectorshapecontext.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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"
+
+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( ContextHandler& rParent,
+ ShapePtr pMasterShapePtr, ShapePtr pGroupShapePtr )
+: ShapeContext( rParent, pMasterShapePtr, pGroupShapePtr )
+{
+}
+
+ConnectorShapeContext::~ConnectorShapeContext()
+{
+}
+
+Reference< XFastContextHandler > ConnectorShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( getBaseToken( aElementToken ) )
+ {
+ 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..d0c5c6a2dde2
--- /dev/null
+++ b/oox/source/drawingml/customshapegeometry.cxx
@@ -0,0 +1,2065 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/customshapegeometry.hxx"
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <comphelper/stl_types.hxx>
+#include <hash_map>
+#include "oox/helper/helper.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertymap.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::drawing;
+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;
+
+//
+rtl::OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
+{
+ rtl::OUString aRet;
+ switch( rParameter.Type )
+ {
+ case EnhancedCustomShapeParameterType::NORMAL :
+ {
+ if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
+ {
+ double fValue = 0.0;
+ if ( rParameter.Value >>= fValue )
+ aRet = rtl::OUString::valueOf( fValue );
+ }
+ else
+ {
+ sal_Int32 nValue = 0;
+ if ( rParameter.Value >>= nValue )
+ aRet = rtl::OUString::valueOf( nValue );
+ }
+ }
+ break;
+ case EnhancedCustomShapeParameterType::EQUATION :
+ {
+ if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
+ {
+ sal_Int32 nFormulaIndex;
+ if ( rParameter.Value >>= nFormulaIndex )
+ {
+ aRet = CREATE_OUSTRING( "?" )
+ + rtl::OUString::valueOf( nFormulaIndex )
+ + CREATE_OUSTRING( " " );
+ }
+ }
+ else
+ {
+ // ups... we should have an index here and not the formula name
+ }
+ }
+ break;
+ case EnhancedCustomShapeParameterType::ADJUSTMENT :
+ {
+ if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
+ {
+ sal_Int32 nAdjustmentIndex;
+ if ( rParameter.Value >>= nAdjustmentIndex )
+ {
+ aRet = CREATE_OUSTRING( "$" )
+ + rtl::OUString::valueOf( nAdjustmentIndex )
+ + CREATE_OUSTRING( " " );
+ }
+ }
+ else
+ {
+ // ups... we should have an index here and not the formula name
+ }
+ }
+ break;
+ case EnhancedCustomShapeParameterType::LEFT :
+ {
+ const rtl::OUString sLeft( CREATE_OUSTRING( "left" ) );
+ aRet = sLeft;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::TOP :
+ {
+ const rtl::OUString sTop( CREATE_OUSTRING( "top" ) );
+ aRet = sTop;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::RIGHT :
+ {
+ const rtl::OUString sRight( CREATE_OUSTRING( "right" ) );
+ aRet = sRight;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::BOTTOM :
+ {
+ const rtl::OUString sBottom( CREATE_OUSTRING( "bottom" ) );
+ aRet = sBottom;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::XSTRETCH :
+ {
+ const rtl::OUString sXStretch( CREATE_OUSTRING( "xstretch" ) );
+ aRet = sXStretch;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::YSTRETCH :
+ {
+ const rtl::OUString sYStretch( CREATE_OUSTRING( "ystretch" ) );
+ aRet = sYStretch;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::HASSTROKE :
+ {
+ const rtl::OUString sHasStroke( CREATE_OUSTRING( "hasstroke" ) );
+ aRet = sHasStroke;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::HASFILL :
+ {
+ const rtl::OUString sHasFill( CREATE_OUSTRING( "hasfill" ) );
+ aRet = sHasFill;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::WIDTH :
+ {
+ const rtl::OUString sWidth( CREATE_OUSTRING( "width" ) );
+ aRet = sWidth;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::HEIGHT :
+ {
+ const rtl::OUString sHeight( CREATE_OUSTRING( "height" ) );
+ aRet = sHeight;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::LOGWIDTH :
+ {
+ const rtl::OUString sLogWidth( CREATE_OUSTRING( "logwidth" ) );
+ aRet = sLogWidth;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::LOGHEIGHT :
+ {
+ const rtl::OUString sLogHeight( CREATE_OUSTRING( "logheight" ) );
+ aRet = sLogHeight;
+ }
+ break;
+ }
+ return aRet;
+}
+
+// ---------------------------------------------------------------------
+
+static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const::rtl::OUString& rValue, sal_Bool bNoSymbols )
+{
+ com::sun::star::drawing::EnhancedCustomShapeParameter aRet;
+ if ( rValue.getLength() )
+ {
+ sal_Bool bConstant = sal_True;
+ sal_Int32 nConstant = 0;
+ sal_Char nVal = 0;
+
+ // first check if its a constant value
+ switch( AttributeConversion::decodeToken( rValue ) )
+ {
+ case XML_3cd4 : nConstant = 270 * 60000; break;
+ case XML_3cd8 : nConstant = 135 * 60000; break;
+ case XML_5cd8 : nConstant = 225 * 60000; break;
+ case XML_7cd8 : nConstant = 315 * 60000; break;
+ case XML_cd2 : nConstant = 180 * 60000; break;
+ case XML_cd4 : nConstant = 90 * 60000; break;
+ case XML_cd8 : nConstant = 45 * 60000; break;
+
+ case XML_b : // variable height of the shape defined in spPr
+ case XML_h :
+ {
+ if ( bNoSymbols )
+ {
+ CustomShapeGuide aGuide;
+ aGuide.maName = rValue;
+ aGuide.maFormula = CREATE_OUSTRING( "height" );
+
+ aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ else
+ aRet.Type = EnhancedCustomShapeParameterType::HEIGHT; // TODO: HEIGHT needs to be implemented
+ }
+ break;
+
+
+ case XML_hd8 : // !!PASSTHROUGH INTENDED
+ nVal += 2; // */ h 1.0 8.0
+ case XML_hd6 : // */ h 1.0 6.0
+ nVal++;
+ case XML_hd5 : // */ h 1.0 5.0
+ nVal++;
+ case XML_hd4 : // */ h 1.0 4.0
+ nVal += 2;
+ case XML_hd2 : // */ h 1.0 2.0
+ case XML_vc : // */ h 1.0 2.0
+ {
+ nVal += '2';
+
+ CustomShapeGuide aGuide;
+ aGuide.maName = rValue;
+ aGuide.maFormula = CREATE_OUSTRING( "height/" ) + rtl::OUString( nVal );
+
+ aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ break;
+
+ case XML_t :
+ case XML_l :
+ {
+ nConstant = 0;
+ aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
+ }
+ break;
+
+ case XML_ls : // longest side: max w h
+ {
+ CustomShapeGuide aGuide;
+ aGuide.maName = rValue;
+ aGuide.maFormula = CREATE_OUSTRING( "max(width,height)" );
+
+ aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ break;
+ case XML_ss : // shortest side: min w h
+ {
+ CustomShapeGuide aGuide;
+ aGuide.maName = rValue;
+ aGuide.maFormula = CREATE_OUSTRING( "min(width,height)" );
+
+ aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ break;
+ case XML_ssd8 : // */ ss 1.0 8.0
+ nVal += 2;
+ case XML_ssd6 : // */ ss 1.0 6.0
+ nVal += 2;
+ case XML_ssd4 : // */ ss 1.0 4.0
+ nVal += 2;
+ case XML_ssd2 : // */ ss 1.0 2.0
+ {
+ nVal += '2';
+
+ CustomShapeGuide aGuide;
+ aGuide.maName = rValue;
+ aGuide.maFormula = CREATE_OUSTRING( "min(width,height)/" ) + rtl::OUString( nVal );
+
+ aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ break;
+
+ case XML_r : // variable width of the shape defined in spPr
+ case XML_w :
+ {
+ if ( bNoSymbols )
+ {
+ CustomShapeGuide aGuide;
+ aGuide.maName = rValue;
+ aGuide.maFormula = CREATE_OUSTRING( "width" );
+
+ aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ else
+ aRet.Type = EnhancedCustomShapeParameterType::WIDTH;
+ }
+ break;
+
+ case XML_wd10 : // */ w 1.0 10.0
+ nVal += 2;
+ case XML_wd8 : // */ w 1.0 8.0
+ nVal += 2;
+ case XML_wd6 : // */ w 1.0 6.0
+ nVal++;
+ case XML_wd5 : // */ w 1.0 5.0
+ nVal++;
+ case XML_wd4 : // */ w 1.0 4.0
+ nVal += 2;
+ case XML_hc : // */ w 1.0 2.0
+ case XML_wd2 : // */ w 1.0 2.0
+ {
+ nVal += '2';
+
+ CustomShapeGuide aGuide;
+ aGuide.maName = rValue;
+ aGuide.maFormula = CREATE_OUSTRING( "width/" ) + rtl::OUString( nVal );
+
+ aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ break;
+
+ default:
+ bConstant = sal_False;
+ break;
+ }
+ if ( bConstant )
+ {
+ if ( nConstant )
+ {
+ aRet.Value = Any( nConstant );
+ aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
+ }
+ }
+ else
+ {
+ sal_Unicode n = rValue[ 0 ];
+ if ( ( n == '+' ) || ( n == '-' ) )
+ {
+ if ( rValue.getLength() > 0 )
+ n = rValue[ 1 ];
+ }
+ if ( ( n >= '0' ) && ( n <= '9' ) )
+ { // seems to be a ST_Coordinate
+ aRet.Value = Any( rValue.toInt32() );
+ aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
+ }
+ else
+ {
+ sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
+ if ( nGuideIndex >= 0 )
+ {
+ aRet.Value = Any( nGuideIndex );
+ aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
+ }
+ else
+ {
+ nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
+ if ( nGuideIndex >= 0 )
+ {
+ aRet.Value = Any( nGuideIndex );
+ aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ else
+ aRet.Value = Any( rValue );
+ }
+ }
+ }
+ }
+ return aRet;
+}
+
+static EnhancedCustomShapeParameter GetAdjAngle( CustomShapeProperties& rCustomShapeProperties, const ::rtl::OUString& rValue )
+{
+ EnhancedCustomShapeParameter aAngle( GetAdjCoordinate( rCustomShapeProperties, rValue, sal_True ) );
+ if ( aAngle.Type == EnhancedCustomShapeParameterType::NORMAL )
+ {
+ sal_Int32 nValue = 0;
+ aAngle.Value >>= nValue;
+ double fValue = ( static_cast< double >( nValue ) / 60000.0 ) * 360.0;
+ aAngle.Value <<= fValue;
+ }
+ return aAngle;
+}
+
+// ---------------------------------------------------------------------
+// CT_GeomGuideList
+class GeomGuideListContext : public ContextHandler
+{
+public:
+ GeomGuideListContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList );
+ 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:
+ std::vector< CustomShapeGuide >& mrGuideList;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+GeomGuideListContext::GeomGuideListContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
+: ContextHandler( rParent )
+, mrGuideList( rGuideList )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+static rtl::OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, 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() )
+ {
+ sal_Int32 i, nParameters = aTokens.size() - 1;
+ if ( nParameters > 3 )
+ nParameters = 3;
+
+ rtl::OUString sParameters[ 3 ];
+
+ for ( i = 0; i < nParameters; i++ )
+ sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], sal_False ) );
+
+ const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
+ if ( aIter != pCommandHashMap->end() )
+ {
+ switch( aIter->second )
+ {
+ case FC_MULDIV :
+ {
+ if ( nParameters == 3 )
+ aEquation = sParameters[ 0 ] + CREATE_OUSTRING( "*" ) + sParameters[ 1 ]
+ + CREATE_OUSTRING( "/" ) + sParameters[ 2 ];
+ }
+ break;
+ case FC_PLUSMINUS :
+ {
+ if ( nParameters == 3 )
+ aEquation = sParameters[ 0 ] + CREATE_OUSTRING( "+" ) + sParameters[ 1 ]
+ + CREATE_OUSTRING( "-" ) + sParameters[ 2 ];
+ }
+ break;
+ case FC_PLUSDIV :
+ {
+ if ( nParameters == 3 )
+ aEquation = CREATE_OUSTRING( "(" ) + sParameters[ 0 ] + CREATE_OUSTRING( "+" )
+ + sParameters[ 1 ] + CREATE_OUSTRING( ")/" ) + sParameters[ 2 ];
+ }
+ break;
+ case FC_IFELSE :
+ {
+ if ( nParameters == 3 )
+ aEquation = CREATE_OUSTRING( "if(" ) + sParameters[ 0 ] + CREATE_OUSTRING( "," )
+ + sParameters[ 1 ] + CREATE_OUSTRING( "," ) + sParameters[ 2 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_ABS :
+ {
+ if ( nParameters == 1 )
+ aEquation = CREATE_OUSTRING( "abs(" ) + sParameters[ 0 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_AT2 :
+ {
+ if ( nParameters == 2 )
+ aEquation = CREATE_OUSTRING( "atan2(" ) + sParameters[ 0 ] + CREATE_OUSTRING( "," )
+ + sParameters[ 1 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_CAT2 :
+ {
+ if ( nParameters == 3 )
+ aEquation = sParameters[ 0 ] + CREATE_OUSTRING( "*(cos(arctan(" ) +
+ sParameters[ 1 ] + CREATE_OUSTRING( "," ) + sParameters[ 2 ] + CREATE_OUSTRING( ")))" );
+ }
+ break;
+ case FC_COS :
+ {
+ if ( nParameters == 2 )
+ aEquation = sParameters[ 0 ] + CREATE_OUSTRING( "*cos(" ) +
+ sParameters[ 1 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_MAX :
+ {
+ if ( nParameters == 2 )
+ aEquation = CREATE_OUSTRING( "max(" ) + sParameters[ 0 ] + CREATE_OUSTRING( "," ) +
+ sParameters[ 1 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_MIN :
+ {
+ if ( nParameters == 2 )
+ aEquation = CREATE_OUSTRING( "min(" ) + sParameters[ 0 ] + CREATE_OUSTRING( "," ) +
+ sParameters[ 1 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_MOD :
+ {
+ if ( nParameters == 3 )
+ aEquation = CREATE_OUSTRING( "sqrt(" )
+ + sParameters[ 0 ] + CREATE_OUSTRING( "*" ) + sParameters[ 0 ] + CREATE_OUSTRING( "+" )
+ + sParameters[ 1 ] + CREATE_OUSTRING( "*" ) + sParameters[ 1 ] + CREATE_OUSTRING( "+" )
+ + sParameters[ 2 ] + CREATE_OUSTRING( "*" ) + sParameters[ 2 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_PIN :
+ {
+ if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
+ aEquation = CREATE_OUSTRING( "if(" ) + sParameters[ 0 ] + CREATE_OUSTRING( "-" ) + sParameters[ 1 ]
+ + CREATE_OUSTRING( "," ) + sParameters[ 0 ] + CREATE_OUSTRING( ",if(" ) + sParameters[ 2 ]
+ + CREATE_OUSTRING( "-" ) + sParameters[ 1 ] + CREATE_OUSTRING( "," ) + sParameters[ 1 ]
+ + CREATE_OUSTRING( "," ) + sParameters[ 2 ] + CREATE_OUSTRING( "))" );
+ }
+ break;
+ case FC_SAT2 :
+ {
+ if ( nParameters == 3 )
+ aEquation = sParameters[ 0 ] + CREATE_OUSTRING( "*(sin(arctan(" ) +
+ sParameters[ 1 ] + CREATE_OUSTRING( "," ) + sParameters[ 2 ] + CREATE_OUSTRING( ")))" );
+ }
+ break;
+ case FC_SIN :
+ {
+ if ( nParameters == 2 )
+ aEquation = sParameters[ 0 ] + CREATE_OUSTRING( "*sin(" ) +
+ sParameters[ 1 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_SQRT :
+ {
+ if ( nParameters == 1 )
+ aEquation = CREATE_OUSTRING( "sqrt(" ) + sParameters[ 0 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_TAN :
+ {
+ if ( nParameters == 2 )
+ aEquation = sParameters[ 0 ] + CREATE_OUSTRING( "*tan(" ) +
+ sParameters[ 1 ] + CREATE_OUSTRING( ")" );
+ }
+ break;
+ case FC_VAL :
+ {
+ if ( nParameters == 1 )
+ aEquation = sParameters[ 0 ];
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ }
+ return aEquation;
+}
+
+Reference< XFastContextHandler > GeomGuideListContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ if ( aElementToken == A_TOKEN( gd ) ) // CT_GeomGuide
+ {
+ CustomShapeGuide aGuide;
+ aGuide.maName = xAttribs->getOptionalValue( XML_name );
+ aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_fmla ) );
+ mrGuideList.push_back( aGuide );
+ }
+ return this;
+}
+
+// ---------------------------------------------------------------------
+
+static const rtl::OUString GetGeomGuideName( const ::rtl::OUString& rValue )
+{
+ return rValue;
+}
+
+// ---------------------------------------------------------------------
+// CT_AdjPoint2D
+class AdjPoint2DContext : public ContextHandler
+{
+public:
+ AdjPoint2DContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
+};
+
+AdjPoint2DContext::AdjPoint2DContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
+: ContextHandler( rParent )
+{
+ rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, xAttribs->getOptionalValue( XML_x ), sal_True );
+ rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, xAttribs->getOptionalValue( XML_y ), sal_True );
+}
+
+// ---------------------------------------------------------------------
+// CT_XYAdjustHandle
+class XYAdjustHandleContext : public ContextHandler
+{
+public:
+ XYAdjustHandleContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
+ 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:
+ AdjustHandle& mrAdjustHandle;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
+: ContextHandler( rParent )
+, mrAdjustHandle( rAdjustHandle )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+ const rtl::OUString aEmptyDefault;
+ AttributeList aAttribs( xAttribs );
+ if ( aAttribs.hasAttribute( XML_gdRefX ) )
+ {
+ mrAdjustHandle.gdRef1 = GetGeomGuideName( aAttribs.getString( XML_gdRefX, aEmptyDefault ) );
+ }
+ if ( aAttribs.hasAttribute( XML_minX ) )
+ {
+ mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, aAttribs.getString( XML_minX, aEmptyDefault ), sal_True );
+ }
+ if ( aAttribs.hasAttribute( XML_maxX ) )
+ {
+ mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, aAttribs.getString( XML_maxX, aEmptyDefault ), sal_True );
+ }
+ if ( aAttribs.hasAttribute( XML_gdRefY ) )
+ {
+ mrAdjustHandle.gdRef2 = GetGeomGuideName( aAttribs.getString( XML_gdRefY, aEmptyDefault ) );
+ }
+ if ( aAttribs.hasAttribute( XML_minY ) )
+ {
+ mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, aAttribs.getString( XML_minY, aEmptyDefault ), sal_True );
+ }
+ if ( aAttribs.hasAttribute( XML_maxY ) )
+ {
+ mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, aAttribs.getString( XML_maxY, aEmptyDefault ), sal_True );
+ }
+}
+
+Reference< XFastContextHandler > XYAdjustHandleContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( pos ) )
+ xContext = new AdjPoint2DContext( *this, xAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_PolarAdjustHandle
+class PolarAdjustHandleContext : public ContextHandler
+{
+public:
+ PolarAdjustHandleContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
+ 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:
+ AdjustHandle& mrAdjustHandle;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
+: ContextHandler( rParent )
+, mrAdjustHandle( rAdjustHandle )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+ const rtl::OUString aEmptyDefault;
+ AttributeList aAttribs( xAttribs );
+ if ( aAttribs.hasAttribute( XML_gdRefR ) )
+ {
+ mrAdjustHandle.gdRef1 = GetGeomGuideName( aAttribs.getString( XML_gdRefR, aEmptyDefault ) );
+ }
+ if ( aAttribs.hasAttribute( XML_minR ) )
+ {
+ mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, aAttribs.getString( XML_minR, aEmptyDefault ), sal_True );
+ }
+ if ( aAttribs.hasAttribute( XML_maxR ) )
+ {
+ mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, aAttribs.getString( XML_maxR, aEmptyDefault ), sal_True );
+ }
+ if ( aAttribs.hasAttribute( XML_gdRefAng ) )
+ {
+ mrAdjustHandle.gdRef2 = GetGeomGuideName( aAttribs.getString( XML_gdRefAng, aEmptyDefault ) );
+ }
+ if ( aAttribs.hasAttribute( XML_minAng ) )
+ {
+ mrAdjustHandle.min2 = GetAdjAngle( mrCustomShapeProperties, aAttribs.getString( XML_minAng, aEmptyDefault ) );
+ }
+ if ( aAttribs.hasAttribute( XML_maxAng ) )
+ {
+ mrAdjustHandle.max2 = GetAdjAngle( mrCustomShapeProperties, aAttribs.getString( XML_maxAng, aEmptyDefault ) );
+ }
+}
+
+Reference< XFastContextHandler > PolarAdjustHandleContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( pos ) )
+ xContext = new AdjPoint2DContext( *this, xAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_AdjustHandleList
+class AdjustHandleListContext : public ContextHandler
+{
+public:
+ AdjustHandleListContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList );
+ 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:
+ std::vector< AdjustHandle >& mrAdjustHandleList;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+AdjustHandleListContext::AdjustHandleListContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
+: ContextHandler( rParent )
+, mrAdjustHandleList( rAdjustHandleList )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+Reference< XFastContextHandler > AdjustHandleListContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( ahXY ) ) // CT_XYAdjustHandle
+ {
+ AdjustHandle aAdjustHandle( sal_False );
+ mrAdjustHandleList.push_back( aAdjustHandle );
+ xContext = new XYAdjustHandleContext( *this, xAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
+ }
+ else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
+ {
+ AdjustHandle aAdjustHandle( sal_True );
+ mrAdjustHandleList.push_back( aAdjustHandle );
+ xContext = new PolarAdjustHandleContext( *this, xAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
+ }
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_ConnectionSite
+class ConnectionSiteContext : public ContextHandler
+{
+public:
+ ConnectionSiteContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite );
+ 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:
+ ConnectionSite& mrConnectionSite;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+ConnectionSiteContext::ConnectionSiteContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
+: ContextHandler( rParent )
+, mrConnectionSite( rConnectionSite )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+ mrConnectionSite.ang = GetAdjAngle( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_ang ) );
+}
+
+Reference< XFastContextHandler > ConnectionSiteContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( pos ) )
+ xContext = new AdjPoint2DContext( *this, xAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_Path2DMoveTo
+class Path2DMoveToContext : public ContextHandler
+{
+public:
+ Path2DMoveToContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
+ 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:
+ EnhancedCustomShapeParameterPair& mrAdjPoint2D;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+Path2DMoveToContext::Path2DMoveToContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
+: ContextHandler( rParent )
+, mrAdjPoint2D( rAdjPoint2D )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+Reference< XFastContextHandler > Path2DMoveToContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( pt ) )
+ xContext = new AdjPoint2DContext( *this, xAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_Path2DLineTo
+class Path2DLineToContext : public ContextHandler
+{
+public:
+ Path2DLineToContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
+ 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:
+ EnhancedCustomShapeParameterPair& mrAdjPoint2D;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+Path2DLineToContext::Path2DLineToContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
+: ContextHandler( rParent )
+, mrAdjPoint2D( rAdjPoint2D )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+Reference< XFastContextHandler > Path2DLineToContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( pt ) )
+ xContext = new AdjPoint2DContext( *this, xAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_Path2DQuadBezierTo
+class Path2DQuadBezierToContext : public ContextHandler
+{
+public:
+ Path2DQuadBezierToContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rPt1, EnhancedCustomShapeParameterPair& rPt2 );
+ 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:
+ EnhancedCustomShapeParameterPair& mrPt1;
+ EnhancedCustomShapeParameterPair& mrPt2;
+ int nCount;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler& rParent,
+ CustomShapeProperties& rCustomShapeProperties,
+ EnhancedCustomShapeParameterPair& rPt1,
+ EnhancedCustomShapeParameterPair& rPt2 )
+: ContextHandler( rParent )
+, mrPt1( rPt1 )
+, mrPt2( rPt2 )
+, nCount( 0 )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+Reference< XFastContextHandler > Path2DQuadBezierToContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( pt ) )
+ xContext = new AdjPoint2DContext( *this, xAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_Path2DCubicBezierTo
+class Path2DCubicBezierToContext : public ContextHandler
+{
+public:
+ Path2DCubicBezierToContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties,
+ EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair& );
+ 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:
+ CustomShapeProperties& mrCustomShapeProperties;
+ EnhancedCustomShapeParameterPair& mrControlPt1;
+ EnhancedCustomShapeParameterPair& mrControlPt2;
+ EnhancedCustomShapeParameterPair& mrEndPt;
+ int nCount;
+};
+
+Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties,
+ EnhancedCustomShapeParameterPair& rControlPt1,
+ EnhancedCustomShapeParameterPair& rControlPt2,
+ EnhancedCustomShapeParameterPair& rEndPt )
+: ContextHandler( rParent )
+, mrCustomShapeProperties( rCustomShapeProperties )
+, mrControlPt1( rControlPt1 )
+, mrControlPt2( rControlPt2 )
+, mrEndPt( rEndPt )
+, nCount( 0 )
+{
+}
+
+Reference< XFastContextHandler > Path2DCubicBezierToContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( pt ) )
+ xContext = new AdjPoint2DContext( *this, xAttribs, mrCustomShapeProperties,
+ nCount++ ? nCount == 2 ? mrControlPt2 : mrEndPt : mrControlPt1 ); // CT_AdjPoint2D
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_Path2DContext
+class Path2DContext : public ContextHandler
+{
+public:
+ Path2DContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D );
+ virtual ~Path2DContext();
+ 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:
+ Path2D& mrPath2D;
+ std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& mrSegments;
+ CustomShapeProperties& mrCustomShapeProperties;
+};
+
+Path2DContext::Path2DContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D )
+: ContextHandler( rParent )
+, mrPath2D( rPath2D )
+, mrSegments( rSegments )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+ const rtl::OUString aEmptyString;
+
+ AttributeList aAttribs( xAttribs );
+ rPath2D.w = aAttribs.getString( XML_w, aEmptyString ).toInt64();
+ rPath2D.h = aAttribs.getString( XML_h, aEmptyString ).toInt64();
+ rPath2D.fill = aAttribs.getToken( XML_fill, XML_norm );
+ rPath2D.stroke = aAttribs.getBool( XML_stroke, sal_True );
+ rPath2D.extrusionOk = aAttribs.getBool( XML_extrusionOk, sal_True );
+}
+
+Path2DContext::~Path2DContext()
+{
+ EnhancedCustomShapeSegment aNewSegment;
+ if ( mrPath2D.fill == XML_none )
+ {
+ aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
+ aNewSegment.Count = 0;
+ mrSegments.push_back( aNewSegment );
+ }
+ aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
+ aNewSegment.Count = 0;
+ mrSegments.push_back( aNewSegment );
+}
+
+Reference< XFastContextHandler > Path2DContext::createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
+{
+ Reference< XFastContextHandler > xContext;
+ switch( aElementToken )
+ {
+ case A_TOKEN( close ) :
+ {
+ EnhancedCustomShapeSegment aNewSegment;
+ aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
+ aNewSegment.Count = 0;
+ mrSegments.push_back( aNewSegment );
+ }
+ break;
+ case A_TOKEN( moveTo ) :
+ {
+ EnhancedCustomShapeSegment aNewSegment;
+ aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
+ aNewSegment.Count = 1;
+ mrSegments.push_back( aNewSegment );
+
+ EnhancedCustomShapeParameterPair aAdjPoint2D;
+ mrPath2D.parameter.push_back( aAdjPoint2D );
+ xContext = new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
+ }
+ break;
+ case A_TOKEN( lnTo ) :
+ {
+
+ if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
+ mrSegments.back().Count++;
+ else
+ {
+ EnhancedCustomShapeSegment aSegment;
+ aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
+ aSegment.Count = 1;
+ mrSegments.push_back( aSegment );
+ }
+ EnhancedCustomShapeParameterPair aAdjPoint2D;
+ mrPath2D.parameter.push_back( aAdjPoint2D );
+ xContext = new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
+ }
+ break;
+ case A_TOKEN( arcTo ) : // CT_Path2DArcTo
+ {
+ if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCTO ) )
+ mrSegments.back().Count++;
+ else
+ {
+ EnhancedCustomShapeSegment aSegment;
+ aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
+ aSegment.Count = 1;
+ mrSegments.push_back( aSegment );
+ }
+ EnhancedCustomShapeParameter aWidth = GetAdjCoordinate( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_wR ), sal_True );
+ EnhancedCustomShapeParameter aHeight = GetAdjCoordinate( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_hR ), sal_True );
+ EnhancedCustomShapeParameter aStartAngle = GetAdjAngle( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_stAng ) );
+ EnhancedCustomShapeParameter swAngle = GetAdjAngle( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_swAng ) );
+
+ EnhancedCustomShapeParameterPair aPt1; // TODO: conversion from (wr hr stAng swAng)
+ EnhancedCustomShapeParameterPair aPt2; // to (x1 y1 x2 y2 x3 y3 x y) needed
+ EnhancedCustomShapeParameterPair aPt3;
+ EnhancedCustomShapeParameterPair aPt;
+ mrPath2D.parameter.push_back( aPt1 );
+ mrPath2D.parameter.push_back( aPt2 );
+ mrPath2D.parameter.push_back( aPt3 );
+ mrPath2D.parameter.push_back( aPt );
+ }
+ break;
+ case A_TOKEN( quadBezTo ) :
+ {
+ if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
+ mrSegments.back().Count++;
+ else
+ {
+ EnhancedCustomShapeSegment aSegment;
+ aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
+ aSegment.Count = 1;
+ mrSegments.push_back( aSegment );
+ }
+ EnhancedCustomShapeParameterPair aPt1;
+ EnhancedCustomShapeParameterPair aPt2;
+ mrPath2D.parameter.push_back( aPt1 );
+ mrPath2D.parameter.push_back( aPt2 );
+ xContext = new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
+ mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
+ mrPath2D.parameter.back() );
+ }
+ break;
+ case A_TOKEN( cubicBezTo ) :
+ {
+ if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
+ mrSegments.back().Count++;
+ else
+ {
+ EnhancedCustomShapeSegment aSegment;
+ aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
+ aSegment.Count = 1;
+ mrSegments.push_back( aSegment );
+ }
+ EnhancedCustomShapeParameterPair aControlPt1;
+ EnhancedCustomShapeParameterPair aControlPt2;
+ EnhancedCustomShapeParameterPair aEndPt;
+ mrPath2D.parameter.push_back( aControlPt1 );
+ mrPath2D.parameter.push_back( aControlPt2 );
+ mrPath2D.parameter.push_back( aEndPt );
+ xContext = new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
+ mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
+ mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
+ mrPath2D.parameter.back() );
+ }
+ break;
+ }
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_Path2DList
+class Path2DListContext : public ContextHandler
+{
+public:
+ Path2DListContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
+ std::vector< Path2D >& rPath2DList );
+
+ 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:
+
+ CustomShapeProperties& mrCustomShapeProperties;
+ std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& mrSegments;
+ std::vector< Path2D >& mrPath2DList;
+};
+
+Path2DListContext::Path2DListContext( ContextHandler& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
+ std::vector< Path2D >& rPath2DList )
+: ContextHandler( rParent )
+, mrCustomShapeProperties( rCustomShapeProperties )
+, mrSegments( rSegments )
+, mrPath2DList( rPath2DList )
+{
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL Path2DListContext::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)
+{
+ Reference< XFastContextHandler > xContext;
+ if ( aElementToken == A_TOKEN( path ) )
+ {
+ Path2D aPath2D;
+ mrPath2DList.push_back( aPath2D );
+ xContext = new Path2DContext( *this, xAttribs, mrCustomShapeProperties, mrSegments, mrPath2DList.back() );
+ }
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+
+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( ContextHandler& rParent, const Reference< XFastAttributeList >& /* xAttribs */, CustomShapeProperties& rCustomShapeProperties )
+: ContextHandler( rParent )
+, mrCustomShapeProperties( rCustomShapeProperties )
+{
+}
+
+Reference< XFastContextHandler > CustomShapeGeometryContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xContext;
+ switch( aElementToken )
+ {
+ case A_TOKEN( avLst ): // CT_GeomGuideList adjust value list
+ xContext = new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
+ break;
+ case A_TOKEN( gdLst ): // CT_GeomGuideList guide list
+ xContext = new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
+ break;
+ case A_TOKEN( ahLst ): // CT_AdjustHandleList adjust handle list
+ xContext = new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
+ break;
+ case A_TOKEN( cxnLst ): // CT_ConnectionSiteList connection site list
+ xContext = this;
+ break;
+ case A_TOKEN( rect ): // CT_GeomRectList geometry rect list
+ {
+ GeomRect aGeomRect;
+ aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_l ), sal_True );
+ aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_t ), sal_True );
+ aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_r ), sal_True );
+ aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, xAttribs->getOptionalValue( XML_b ), sal_True );
+ mrCustomShapeProperties.getTextRect() = aGeomRect;
+ }
+ break;
+ case A_TOKEN( pathLst ): // CT_Path2DList 2d path list
+ xContext = new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
+ break;
+
+ // from cxnLst:
+ case A_TOKEN( cxn ): // CT_ConnectionSite
+ {
+ ConnectionSite aConnectionSite;
+ mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
+ xContext = new ConnectionSiteContext( *this, xAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
+ }
+ break;
+ }
+ return xContext;
+}
+
+// ---------------------------------------------------------------------
+// CT_PresetGeometry2D
+PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties )
+: ContextHandler( rParent )
+, 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 == A_TOKEN( avLst ) )
+ return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
+ else
+ return this;
+}
+
+// ---------------------------------------------------------------------
+// CT_PresetTextShape
+PresetTextShapeContext::PresetTextShapeContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, CustomShapeProperties& rCustomShapeProperties )
+: ContextHandler( rParent )
+, 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)
+{
+ if ( aElementToken == A_TOKEN( avLst ) )
+ return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
+ else
+ return this;
+}
+
+} }
diff --git a/oox/source/drawingml/customshapeproperties.cxx b/oox/source/drawingml/customshapeproperties.cxx
new file mode 100644
index 000000000000..052fdc5e1dfc
--- /dev/null
+++ b/oox/source/drawingml/customshapeproperties.cxx
@@ -0,0 +1,268 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/customshapeproperties.hxx"
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XGraphicTransformer.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.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;
+using namespace ::com::sun::star::drawing;
+
+namespace oox { namespace drawingml {
+
+CustomShapeProperties::CustomShapeProperties()
+: mbMirroredX ( sal_False )
+, mbMirroredY ( sal_False )
+{
+}
+CustomShapeProperties::~CustomShapeProperties()
+{
+}
+
+sal_Int32 CustomShapeProperties::SetCustomShapeGuideValue( std::vector< CustomShapeGuide >& rGuideList, const CustomShapeGuide& rGuide )
+{
+ sal_uInt32 nIndex = 0;
+ for( ; nIndex < rGuideList.size(); nIndex++ )
+ {
+ if ( rGuideList[ nIndex ].maName == rGuide.maName )
+ break;
+ }
+ if ( nIndex == rGuideList.size() )
+ rGuideList.push_back( rGuide );
+ return static_cast< sal_Int32 >( nIndex );
+}
+
+// returns the index into the guidelist for a given formula name,
+// if the return value is < 0 then the guide value could not be found
+sal_Int32 CustomShapeProperties::GetCustomShapeGuideValue( const std::vector< CustomShapeGuide >& rGuideList, const rtl::OUString& rFormulaName )
+{
+ sal_Int32 nIndex = 0;
+ for( ; nIndex < static_cast< sal_Int32 >( rGuideList.size() ); nIndex++ )
+ {
+ if ( rGuideList[ nIndex ].maName == rFormulaName )
+ break;
+ }
+ if ( nIndex == static_cast< sal_Int32 >( rGuideList.size() ) )
+ nIndex = -1;
+ return nIndex;
+}
+
+void CustomShapeProperties::apply( const CustomShapePropertiesPtr& /* rSourceCustomShapeProperties */ )
+{
+ // not sure if this needs to be implemented
+}
+
+void CustomShapeProperties::pushToPropSet( const ::oox::core::FilterBase& /* rFilterBase */,
+ const Reference < XPropertySet >& xPropSet, const Reference < XShape > & xShape ) const
+{
+ if ( maShapePresetType.getLength() )
+ {
+ //const uno::Reference < drawing::XShape > xShape( xPropSet, UNO_QUERY );
+ Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY );
+ if( xDefaulter.is() )
+ xDefaulter->createCustomShapeDefaults( maShapePresetType );
+
+ if ( maAdjustmentGuideList.size() )
+ {
+ const OUString sType = CREATE_OUSTRING( "Type" );
+ const 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 )
+ {
+ std::vector< CustomShapeGuide >::const_iterator aIter( maAdjustmentGuideList.begin() );
+ while( aIter != maAdjustmentGuideList.end() )
+ {
+ if ( (*aIter).maName.getLength() > 3 )
+ {
+ sal_Int32 nAdjustmentIndex = (*aIter).maName.copy( 3 ).toInt32() - 1;
+ if ( ( nAdjustmentIndex >= 0 ) && ( nAdjustmentIndex < aAdjustmentSeq.getLength() ) )
+ {
+ EnhancedCustomShapeAdjustmentValue aAdjustmentVal;
+ aAdjustmentVal.Value <<= (*aIter).maFormula.toInt32();
+ aAdjustmentVal.State = PropertyState_DIRECT_VALUE;
+ aAdjustmentSeq[ nAdjustmentIndex ] = aAdjustmentVal;
+ }
+ }
+ aIter++;
+ }
+ aGeoPropSeq[ i ].Value <<= aAdjustmentSeq;
+ xPropSet->setPropertyValue( sCustomShapeGeometry, Any( aGeoPropSeq ) );
+ }
+ }
+ else if ( aGeoPropSeq[ i ].Name.equals( sType ) )
+ {
+ aGeoPropSeq[ i ].Value <<= maShapePresetType;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ sal_uInt32 i;
+ PropertyMap aPropertyMap;
+ aPropertyMap[ PROP_Type ] <<= CREATE_OUSTRING( "non-primitive" );
+ aPropertyMap[ PROP_MirroredX ] <<= Any( mbMirroredX );
+ aPropertyMap[ PROP_MirroredY ] <<= Any( mbMirroredY );
+ awt::Size aSize( xShape->getSize() );
+ awt::Rectangle aViewBox( 0, 0, aSize.Width * 360, aSize.Height * 360 );
+ if ( maPath2DList.size() )
+ { // TODO: each polygon may have its own size, but I think it is rather been used
+ // so we are only taking care of the first
+ if ( maPath2DList[ 0 ].w )
+ aViewBox.Width = static_cast< sal_Int32 >( maPath2DList[ 0 ].w );
+ if ( maPath2DList[ 0 ].h )
+ aViewBox.Height = static_cast< sal_Int32 >( maPath2DList[ 0 ].h );
+ }
+ aPropertyMap[ PROP_ViewBox ] <<= aViewBox;
+
+ Sequence< EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( maAdjustmentGuideList.size() );
+ for ( i = 0; i < maAdjustmentGuideList.size(); i++ )
+ {
+ EnhancedCustomShapeAdjustmentValue aAdjustmentVal;
+ aAdjustmentVal.Value <<= maAdjustmentGuideList[ i ].maFormula.toInt32();
+ aAdjustmentVal.State = PropertyState_DIRECT_VALUE;
+ aAdjustmentValues[ i ] = aAdjustmentVal;
+ }
+ aPropertyMap[ PROP_AdjustmentValues ] <<= aAdjustmentValues;
+
+ Sequence< rtl::OUString > aEquations( maGuideList.size() );
+ for ( i = 0; i < maGuideList.size(); i++ )
+ aEquations[ i ] = maGuideList[ i ].maFormula;
+ aPropertyMap[ PROP_Equations ] <<= aEquations;
+
+ PropertyMap aPath;
+ Sequence< EnhancedCustomShapeSegment > aSegments( maSegments.size() );
+ for ( i = 0; i < maSegments.size(); i++ )
+ aSegments[ i ] = maSegments[ i ];
+ aPath[ PROP_Segments ] <<= aSegments;
+ sal_uInt32 j, k, nParameterPairs = 0;
+ for ( i = 0; i < maPath2DList.size(); i++ )
+ nParameterPairs += maPath2DList[ i ].parameter.size();
+ Sequence< EnhancedCustomShapeParameterPair > aParameterPairs( nParameterPairs );
+ for ( i = 0, k = 0; i < maPath2DList.size(); i++ )
+ for ( j = 0; j < maPath2DList[ i ].parameter.size(); j++ )
+ aParameterPairs[ k++ ] = maPath2DList[ i ].parameter[ j ];
+ aPath[ PROP_Coordinates ] <<= aParameterPairs;
+ Sequence< PropertyValue > aPathSequence = aPath.makePropertyValueSequence();
+ aPropertyMap[ PROP_Path ] <<= aPathSequence;
+
+ Sequence< PropertyValues > aHandles( maAdjustHandleList.size() );
+ for ( i = 0; i < maAdjustHandleList.size(); i++ )
+ {
+ PropertyMap aHandle;
+ // maAdjustmentHandle[ i ].gdRef1 ... maAdjustmentHandle[ i ].gdRef2 ... :(
+ // gdRef1 && gdRef2 -> we do not offer such reference, so it is difficult
+ // to determine the correct adjustment handle that should be updated with the adjustment
+ // position. here is the solution: the adjustment value that is used within the position
+ // has to be updated, in case the position is a formula the first usage of a
+ // adjument value is decisive
+ if ( maAdjustHandleList[ i ].polar )
+ {
+ aHandle[ PROP_Position ] <<= maAdjustHandleList[ i ].pos;
+ if ( maAdjustHandleList[ i ].min1.has() )
+ aHandle[ PROP_RadiusRangeMinimum ] <<= maAdjustHandleList[ i ].min1.get();
+ if ( maAdjustHandleList[ i ].max1.has() )
+ aHandle[ PROP_RadiusRangeMaximum ] <<= maAdjustHandleList[ i ].max1.get();
+
+ /* TODO: AngleMin & AngleMax
+ if ( maAdjustHandleList[ i ].min2.has() )
+ aHandle[ PROP_ ] = maAdjustHandleList[ i ].min2.get();
+ if ( maAdjustHandleList[ i ].max2.has() )
+ aHandle[ PROP_ ] = maAdjustHandleList[ i ].max2.get();
+ */
+ }
+ else
+ {
+ aHandle[ PROP_Position ] <<= maAdjustHandleList[ i ].pos;
+ if ( maAdjustHandleList[ i ].gdRef1.has() )
+ {
+ // TODO: PROP_RefX and PROP_RefY are not yet part of our file format,
+ // so the handles will not work after save/reload
+ sal_Int32 nIndex = GetCustomShapeGuideValue( maAdjustmentGuideList, maAdjustHandleList[ i ].gdRef1.get() );
+ if ( nIndex >= 0 )
+ aHandle[ PROP_RefX ] <<= nIndex;
+ }
+ if ( maAdjustHandleList[ i ].gdRef2.has() )
+ {
+ sal_Int32 nIndex = GetCustomShapeGuideValue( maAdjustmentGuideList, maAdjustHandleList[ i ].gdRef2.get() );
+ if ( nIndex >= 0 )
+ aHandle[ PROP_RefY ] <<= nIndex;
+ }
+ if ( maAdjustHandleList[ i ].min1.has() )
+ aHandle[ PROP_RangeXMinimum ] <<= maAdjustHandleList[ i ].min1.get();
+ if ( maAdjustHandleList[ i ].max1.has() )
+ aHandle[ PROP_RangeXMaximum ] <<= maAdjustHandleList[ i ].max1.get();
+ if ( maAdjustHandleList[ i ].min2.has() )
+ aHandle[ PROP_RangeYMinimum ] <<= maAdjustHandleList[ i ].min2.get();
+ if ( maAdjustHandleList[ i ].max2.has() )
+ aHandle[ PROP_RangeYMaximum ] <<= maAdjustHandleList[ i ].max2.get();
+ }
+ aHandles[ i ] = aHandle.makePropertyValueSequence();
+ }
+ aPropertyMap[ PROP_Handles ] <<= aHandles;
+
+ // converting the vector to a sequence
+ Sequence< PropertyValue > aSeq = aPropertyMap.makePropertyValueSequence();
+ PropertySet aPropSet( xPropSet );
+ aPropSet.setProperty( PROP_CustomShapeGeometry, 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..8d81c800b2df
--- /dev/null
+++ b/oox/source/drawingml/diagram/datamodelcontext.cxx
@@ -0,0 +1,334 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/diagram/datamodelcontext.hxx"
+#include "oox/helper/attributelist.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 ContextHandler
+{
+public:
+ CxnContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ const dgm::ConnectionPtr & pConnection )
+ : ContextHandler( rParent )
+ , mpConnection( pConnection )
+ {
+ sal_Int32 nType = xAttribs->getOptionalValueToken( XML_type, XML_parOf );
+ pConnection->mnType = nType;
+ 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 DGM_TOKEN( extLst ):
+ return xRet;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+private:
+ dgm::ConnectionPtr mpConnection;
+};
+
+
+// CT_CxnList
+class CxnListContext
+ : public ContextHandler
+{
+public:
+ CxnListContext( ContextHandler& rParent, dgm::Connections & aConnections )
+ : ContextHandler( rParent )
+ , maConnections( aConnections )
+ {
+ }
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case DGM_TOKEN( cxn ):
+ {
+ dgm::ConnectionPtr pConnection( new dgm::Connection() );
+ maConnections.push_back( pConnection );
+ xRet.set( new CxnContext( *this, xAttribs, pConnection ) );
+ break;
+ }
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+private:
+ dgm::Connections & maConnections;
+};
+
+
+
+// CL_Pt
+class PtContext
+ : public ContextHandler
+{
+public:
+ PtContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ const dgm::PointPtr & pPoint)
+ : ContextHandler( rParent )
+ , mpPoint( pPoint )
+ {
+ mpPoint->setModelId( xAttribs->getOptionalValue( XML_modelId ) );
+ //
+ // the default type is XML_node
+ sal_Int32 nType = xAttribs->getOptionalValueToken( XML_type, XML_node );
+ mpPoint->setType( nType );
+
+ // ignore the cxnId unless it is this type. See 5.15.3.1.3 in Primer
+ if( ( nType == XML_parTrans ) || ( nType == XML_sibTrans ) )
+ {
+ mpPoint->setCnxId( xAttribs->getOptionalValue( XML_cxnId ) );
+ }
+ }
+
+
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& /*xAttribs*/ )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case DGM_TOKEN( extLst ):
+ return xRet;
+ case DGM_TOKEN( prSet ):
+ // TODO
+ // CT_ElemPropSet
+ break;
+ case DGM_TOKEN( spPr ):
+ OSL_TRACE( "shape props for point");
+ xRet = new ShapePropertiesContext( *this, *mpPoint->getShape() );
+ break;
+ case DGM_TOKEN( t ):
+ {
+ OSL_TRACE( "shape text body for point");
+ TextBodyPtr xTextBody( new TextBody );
+ mpPoint->getShape()->setTextBody( xTextBody );
+ xRet = new TextBodyContext( *this, *xTextBody );
+ break;
+ }
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+private:
+ dgm::PointPtr mpPoint;
+};
+
+
+
+// CT_PtList
+class PtListContext
+ : public ContextHandler
+{
+public:
+ PtListContext( ContextHandler& rParent, dgm::Points & aPoints)
+ : ContextHandler( rParent )
+ , maPoints( aPoints )
+ {
+ }
+ virtual Reference< XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 aElementToken,
+ const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+ {
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case DGM_TOKEN( pt ):
+ {
+ // CT_Pt
+ dgm::PointPtr pPoint( new dgm::Point() );
+ maPoints.push_back( pPoint );
+ xRet.set( new PtContext( *this, xAttribs, pPoint ) );
+ break;
+ }
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+private:
+ dgm::Points & maPoints;
+};
+
+// CT_BackgroundFormatting
+class BackgroundFormattingContext
+ : public ContextHandler
+{
+public:
+ BackgroundFormattingContext( ContextHandler& rParent, DiagramDataPtr & pModel )
+ : ContextHandler( rParent )
+ , 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 A_TOKEN( blipFill ):
+ case A_TOKEN( gradFill ):
+ case A_TOKEN( grpFill ):
+ case A_TOKEN( noFill ):
+ case A_TOKEN( pattFill ):
+ case A_TOKEN( solidFill ):
+ // EG_FillProperties
+ xRet.set( FillPropertiesContext::createFillContext(
+ *this, aElementToken, xAttribs, *mpDataModel->getFillProperties() ) );
+ break;
+ case A_TOKEN( effectDag ):
+ case A_TOKEN( effectLst ):
+ // TODO
+ // EG_EffectProperties
+ break;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+private:
+ DiagramDataPtr mpDataModel;
+};
+
+
+
+DataModelContext::DataModelContext( ContextHandler& rParent,
+ const DiagramDataPtr & pDataModel )
+ : ContextHandler( rParent )
+ , 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 DGM_TOKEN( cxnLst ):
+ // CT_CxnList
+ xRet.set( new CxnListContext( *this, mpDataModel->getConnections() ) );
+ break;
+ case DGM_TOKEN( ptLst ):
+ // CT_PtList
+ xRet.set( new PtListContext( *this, mpDataModel->getPoints() ) );
+ break;
+ case DGM_TOKEN( bg ):
+ // CT_BackgroundFormatting
+ xRet.set( new BackgroundFormattingContext( *this, mpDataModel ) );
+ break;
+ case DGM_TOKEN( whole ):
+ // CT_WholeE2oFormatting
+ // TODO
+ return xRet;
+ case DGM_TOKEN( extLst ):
+ return xRet;
+ 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..cebb730af103
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -0,0 +1,297 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include <functional>
+#include <boost/bind.hpp>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include "oox/drawingml/diagram/diagram.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+
+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.GraphicObjectShape" ) )
+ , mnType( 0 )
+{
+}
+
+void Point::dump()
+{
+ OSL_TRACE( "dgm: pt cnxId %s, modelId %s",
+ OUSTRING_TO_CSTR( msCnxId ),
+ OUSTRING_TO_CSTR( msModelId ) );
+}
+
+void Point::setModelId( const ::rtl::OUString & sModelId )
+{
+ msModelId = sModelId;
+ mpShape->setName( msModelId );
+}
+
+
+bool PointsTree::addChild( const PointsTreePtr & pChild )
+{
+ bool added = false;
+
+ OSL_ENSURE( pChild->mpParent.expired(), "can't add, has already a parent" );
+ OSL_ENSURE( mpNode, "has no node" );
+ if( mpNode && pChild->mpParent.expired() )
+ {
+ pChild->mpParent = shared_from_this();
+ maChildrens.push_back( pChild );
+ added = true;
+ }
+
+ return added;
+}
+
+PointsTreePtr PointsTree::getParent() const
+{
+ if( !mpParent.expired() )
+ {
+ return mpParent.lock() ;
+ }
+ return PointsTreePtr();
+}
+
+
+} // dgm namespace
+
+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 ) );
+}
+
+static void setPosition( const dgm::PointPtr & pPoint, const awt::Point & pt )
+{
+ ShapePtr pShape = pPoint->getShape();
+ awt::Size sz;
+ sz.Width = 50;
+ sz.Height = 50;
+ pShape->setPosition( pt );
+ pShape->setSize( sz );
+}
+
+void DiagramLayout::layout( const dgm::PointsTreePtr & pTree, const awt::Point & pt )
+{
+ setPosition( pTree->getPoint(), pt );
+ awt::Point nextPt = pt;
+ nextPt.Y += 50;
+ dgm::PointsTree::Childrens::const_iterator iter;
+ for( iter = pTree->beginChild(); iter != pTree->endChild(); iter++ )
+ {
+ layout( *iter, nextPt );
+ nextPt.X += 50;
+ }
+}
+
+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::build( )
+{
+ OSL_TRACE( "building diagram" );
+ typedef std::map< OUString, dgm::PointPtr > PointsMap;
+ PointsMap aPointsMap;
+ dgm::Points::iterator aPointsIter( mpData->getPoints( ).begin() );
+ for( ; aPointsIter != mpData->getPoints( ).end() ; aPointsIter++ )
+ {
+ const OUString & sName((*aPointsIter)->getModelId());
+ if( sName.getLength() > 0 )
+ {
+ aPointsMap[ sName ] = *aPointsIter;
+ }
+ }
+
+ typedef std::map< OUString, dgm::PointsTreePtr > PointsTreeMap;
+ PointsTreeMap aTreeMap;
+ PointsTreeMap aRoots;
+
+ dgm::Connections & aConnections(mpData->getConnections( ) );
+ dgm::Connections::iterator aCnxIter;
+ for( aCnxIter = aConnections.begin(); aCnxIter != aConnections.end(); ++aCnxIter )
+ {
+ OSL_ENSURE( *aCnxIter, "NULL connection found" );
+ if( (*aCnxIter)->mnType != XML_parOf )
+ {
+// OSL_TRACE( "ignoring relation %s", OUSTRING_TO_CSTR( (*aCnxIter)->msModelId ) );
+ continue;
+ }
+ dgm::PointPtr pDest;
+ dgm::PointsTreePtr pSource;
+ PointsMap::iterator iterP;
+ OUString & srcId( (*aCnxIter)->msSourceId );
+ OUString & dstId( (*aCnxIter)->msDestId );
+ OSL_TRACE( "connexion %s -> %s", OUSTRING_TO_CSTR( srcId ),
+ OUSTRING_TO_CSTR( dstId ) );
+
+ PointsTreeMap::iterator iterT = aTreeMap.find( srcId );
+ if( iterT != aTreeMap.end() )
+ {
+ pSource = iterT->second;
+ }
+ else
+ {
+ // this tree node is not found. create it with the source
+ // and make it the root node.
+ iterP = aPointsMap.find( srcId );
+ if( iterP != aPointsMap.end() )
+ {
+ pSource.reset( new dgm::PointsTree( iterP->second ) );
+ aRoots[ srcId ] = pSource;
+ aTreeMap[ srcId ] = pSource;
+ }
+ else
+ {
+ OSL_TRACE("parent node not found !");
+ }
+ }
+ iterP = aPointsMap.find( dstId );
+ if( iterP != aPointsMap.end() )
+ {
+ pDest = iterP->second;
+ }
+ OSL_ENSURE( pDest, "destination not found" );
+ OSL_ENSURE( pSource, "source not found" );
+ if(pDest && pSource)
+ {
+ dgm::PointsTreePtr pNode( new dgm::PointsTree( pDest ) );
+ bool added = pSource->addChild( pNode );
+ (void)added;
+ aRoots.erase( dstId );
+ OSL_ENSURE( added, "add child failed" );
+ aTreeMap[ dstId ] = pNode;
+ }
+ }
+ // check bounds
+ OSL_ENSURE( aRoots.size() == 1, "more than one root" );
+ // #i92239# roots may be empty
+ if( !aRoots.empty() )
+ {
+ mpRoot = aRoots.begin()->second;
+ OSL_TRACE( "root is %s", OUSTRING_TO_CSTR( mpRoot->getPoint()->getModelId() ) );
+ for( PointsTreeMap::iterator iter = aTreeMap.begin();
+ iter != aTreeMap.end(); iter++ )
+ {
+ if(! iter->second->getParent() )
+ {
+ OSL_TRACE("node without parent %s", OUSTRING_TO_CSTR( iter->first ) );
+ }
+ }
+ }
+}
+
+
+void Diagram::addTo( const ShapePtr & pParentShape )
+{
+ dgm::Points & aPoints( mpData->getPoints( ) );
+ dgm::Points::iterator aPointsIter;
+ build( );
+ if( mpRoot.get() )
+ mpLayout->layout( mpRoot, awt::Point( 0, 0 ) );
+
+ for( aPointsIter = aPoints.begin(); aPointsIter != aPoints.end(); ++aPointsIter )
+ {
+ if( ( *aPointsIter )->getType() != XML_node )
+ {
+ continue;
+ }
+ ShapePtr pShape = ( *aPointsIter )->getShape( );
+ if( pShape->getName( ).getLength() > 0 )
+ {
+ maShapeMap[ pShape->getName( ) ] = pShape;
+ OSL_TRACE( "Dgm: added shape %s to map", OUSTRING_TO_CSTR( pShape->getName() ) );
+ }
+ pParentShape->addChild( pShape );
+ }
+
+ OSL_TRACE( "Dgm: addTo() # of childs %d", pParentShape->getChildren().size() );
+ for( std::vector< ShapePtr >::iterator iter = pParentShape->getChildren().begin();
+ iter != pParentShape->getChildren().end(); ++iter)
+ {
+ OSL_TRACE( "Dgm: shape name %s", OUSTRING_TO_CSTR( (*iter)->getName() ) );
+ }
+}
+
+OUString Diagram::getLayoutId() const
+{
+ OUString sLayoutId;
+ if( mpLayout )
+ {
+ sLayoutId = mpLayout->getUniqueId();
+ }
+ return sLayoutId;
+}
+
+
+} }
diff --git a/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx
new file mode 100644
index 000000000000..ac98bfb18c38
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "diagramdefinitioncontext.hxx"
+#include "oox/helper/helper.hxx"
+#include "layoutnodecontext.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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttributes,
+ const DiagramLayoutPtr &pLayout )
+ : ContextHandler( rParent )
+ , 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 DGM_TOKEN( title ):
+ mpLayout->setTitle( xAttribs->getOptionalValue( XML_val ) );
+ break;
+ case DGM_TOKEN( desc ):
+ mpLayout->setDesc( xAttribs->getOptionalValue( XML_val ) );
+ break;
+ case DGM_TOKEN( layoutNode ):
+ mpLayout->getNode().reset( new LayoutNode() );
+ xRet.set( new LayoutNodeContext( *this, xAttribs, mpLayout->getNode() ) );
+ break;
+ case DGM_TOKEN( clrData ):
+ // TODO, does not matter for the UI. skip.
+ return xRet;
+ case DGM_TOKEN( sampData ):
+ mpLayout->getSampData().reset( new DiagramData );
+ xRet.set( new DataModelContext( *this, mpLayout->getSampData() ) );
+ break;
+ case DGM_TOKEN( styleData ):
+ mpLayout->getStyleData().reset( new DiagramData );
+ xRet.set( new DataModelContext( *this, mpLayout->getStyleData() ) );
+ break;
+ case DGM_TOKEN( cat ):
+ case DGM_TOKEN( 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..99407aed80d3
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_DIAGRAMDEFINITIONCONTEXT_HXX
+#define OOX_DRAWINGML_DIAGRAMDEFINITIONCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+
+namespace oox { namespace drawingml {
+
+class DiagramDefinitionContext : public ::oox::core::ContextHandler
+{
+public:
+ DiagramDefinitionContext( ::oox::core::ContextHandler& rParent, 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..644e84771b3e
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/diagram/diagramfragmenthandler.hxx"
+#include "oox/drawingml/diagram/datamodelcontext.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( XmlFilterBase& rFilter,
+ const OUString& rFragmentPath,
+ const DiagramDataPtr pDataPtr )
+ throw( )
+ : FragmentHandler( rFilter, 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 DGM_TOKEN( dataModel ):
+ xRet.set( new DataModelContext( *this, mpDataPtr ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet = getFastContextHandler();
+
+ return xRet;
+}
+
+///////////////////
+
+DiagramLayoutFragmentHandler::DiagramLayoutFragmentHandler( XmlFilterBase& rFilter,
+ const OUString& rFragmentPath,
+ const DiagramLayoutPtr pDataPtr )
+ throw( )
+ : FragmentHandler( rFilter, 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 DGM_TOKEN( layoutDef ):
+ xRet.set( new DiagramDefinitionContext( *this, xAttribs, mpDataPtr ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet = getFastContextHandler();
+
+ return xRet;
+}
+
+///////////////////////
+
+DiagramQStylesFragmentHandler::DiagramQStylesFragmentHandler( XmlFilterBase& rFilter,
+ const OUString& rFragmentPath,
+ const DiagramQStylesPtr pDataPtr )
+ throw( )
+ : FragmentHandler( rFilter, 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 DGM_TOKEN( styleDef ):
+ // TODO
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet = getFastContextHandler();
+
+ return xRet;
+}
+
+/////////////////////
+
+DiagramColorsFragmentHandler::DiagramColorsFragmentHandler( XmlFilterBase& rFilter,
+ const OUString& rFragmentPath,
+ const DiagramColorsPtr pDataPtr )
+ throw( )
+ : FragmentHandler( rFilter, 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 DGM_TOKEN( colorsDef ):
+ // TODO
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet = getFastContextHandler();
+
+ return xRet;
+}
+
+
+
+
+} }
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
new file mode 100644
index 000000000000..a351189f3067
--- /dev/null
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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..0815843dd424
--- /dev/null
+++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx
@@ -0,0 +1,356 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "layoutnodecontext.hxx"
+
+#include "oox/helper/attributelist.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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ const LayoutAtomPtr & pNode )
+ : LayoutNodeContext( rParent, 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 ContextHandler
+{
+public:
+ AlgorithmContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
+ : ContextHandler( rParent )
+ , 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 ContextHandler
+{
+public:
+ ChooseContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
+ : ContextHandler( rParent )
+ , 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( *this, xAttribs, pAtom ) );
+ break;
+ }
+ case XML_else:
+ // CT_Otherwise
+ if( !mbHasElse )
+ {
+ LayoutAtomPtr pAtom( new ConditionAtom( true ) );
+ mpNode->addChild( pAtom );
+ xRet.set( new IfContext( *this, 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( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, const LayoutAtomPtr & pNode )
+ : LayoutNodeContext( rParent, 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 ContextHandler
+{
+public:
+ LayoutVariablePropertySetContext( ContextHandler& rParent, LayoutNode::VarMap & aVar )
+ : ContextHandler( rParent )
+ , 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( getBaseToken( aElement ) );
+ 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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ const LayoutAtomPtr &pNode )
+ : ContextHandler( rParent )
+ , 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 DGM_TOKEN( animLvl ):
+ nIdx = LayoutNode::VAR_animLvl;
+ break;
+ case DGM_TOKEN( animOne ):
+ nIdx = LayoutNode::VAR_animOne;
+ break;
+ case DGM_TOKEN( bulletEnabled ):
+ nIdx = LayoutNode::VAR_bulletEnabled;
+ break;
+ case DGM_TOKEN( chMax ):
+ nIdx = LayoutNode::VAR_chMax;
+ break;
+ case DGM_TOKEN( chPref ):
+ nIdx = LayoutNode::VAR_chPref;
+ break;
+ case DGM_TOKEN( dir ):
+ nIdx = LayoutNode::VAR_dir;
+ break;
+ case DGM_TOKEN( hierBranch ):
+ nIdx = LayoutNode::VAR_hierBranch;
+ break;
+ case DGM_TOKEN( orgChart ):
+ nIdx = LayoutNode::VAR_orgChart;
+ break;
+ case DGM_TOKEN( 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 DGM_TOKEN( layoutNode ):
+ {
+ LayoutNodePtr pNode( new LayoutNode() );
+ mpNode->addChild( pNode );
+ xRet.set( new LayoutNodeContext( *this, xAttribs, pNode ) );
+ break;
+ }
+ case DGM_TOKEN( shape ):
+ {
+ ShapePtr pShape( new Shape() );
+ xRet.set( new ShapeContext( *this, ShapePtr(), pShape ) );
+ break;
+ }
+ case DGM_TOKEN( extLst ):
+ return xRet;
+ case DGM_TOKEN( alg ):
+ {
+ // CT_Algorithm
+ LayoutAtomPtr pAtom( new AlgAtom );
+ mpNode->addChild( pAtom );
+ xRet.set( new AlgorithmContext( *this, xAttribs, pAtom ) );
+ break;
+ }
+ case DGM_TOKEN( choose ):
+ {
+ // CT_Choose
+ LayoutAtomPtr pAtom( new ChooseAtom );
+ mpNode->addChild( pAtom );
+ xRet.set( new ChooseContext( *this, xAttribs, pAtom ) );
+ break;
+ }
+ case DGM_TOKEN( forEach ):
+ {
+ // CT_ForEach
+ LayoutAtomPtr pAtom( new ForEachAtom );
+ mpNode->addChild( pAtom );
+ xRet.set( new ForEachContext( *this, xAttribs, pAtom ) );
+ break;
+ }
+ case DGM_TOKEN( constrLst ):
+ // CT_Constraints
+ // TODO
+ break;
+ case DGM_TOKEN( 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 DGM_TOKEN( ruleLst ):
+ // CT_Rules
+ // TODO
+ break;
+ case DGM_TOKEN( varLst ):
+ {
+ LayoutNodePtr pNode( boost::dynamic_pointer_cast< LayoutNode >( mpNode ) );
+ if( pNode )
+ {
+ xRet.set( new LayoutVariablePropertySetContext( *this, 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..19cb19aa602d
--- /dev/null
+++ b/oox/source/drawingml/diagram/layoutnodecontext.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_LAYOUTNODECONTEXT_HXX
+#define OOX_DRAWINGML_LAYOUTNODECONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/diagram/diagram.hxx"
+
+namespace oox { namespace drawingml {
+
+class LayoutNodeContext : public ::oox::core::ContextHandler
+{
+public:
+ LayoutNodeContext( ContextHandler& rParent, 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..9d526ed3d3fb
--- /dev/null
+++ b/oox/source/drawingml/diagram/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+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..f99fdc21ab55
--- /dev/null
+++ b/oox/source/drawingml/drawingmltypes.cxx
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/drawingmltypes.hxx"
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/style/CaseMap.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <sax/tools/converter.hxx>
+#include "oox/token/tokens.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XFastAttributeList;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::geometry;
+using namespace ::com::sun::star::style;
+
+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 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 EMUs into 1/100th mmm */
+sal_Int32 GetCoordinate( sal_Int32 nValue )
+{
+ return (nValue + 180) / 360;
+}
+
+/** converts an emu string into 1/100th mmm */
+sal_Int32 GetCoordinate( const OUString& sValue )
+{
+ sal_Int32 nRet = 0;
+ if( !::sax::Converter::convertNumber( nRet, sValue ) )
+ nRet = 0;
+ return GetCoordinate( nRet );
+}
+
+/** converts a ST_Percentage % string into 1/1000th of % */
+sal_Int32 GetPercent( const OUString& sValue )
+{
+ sal_Int32 nRet = 0;
+ if( !::sax::Converter::convertNumber( nRet, sValue ) )
+ nRet = 0;
+
+ return nRet;
+}
+
+double GetPositiveFixedPercentage( const OUString& sValue )
+{
+ double fPercent = sValue.toFloat() / 100000.;
+ return fPercent;
+}
+
+// --------------------------------------------------------------------
+
+/** converts the attributes from an CT_Point2D into an awt Point with 1/100thmm */
+Point GetPoint2D( const Reference< XFastAttributeList >& xAttribs )
+{
+ return 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% */
+Point GetPointPercent( const Reference< XFastAttributeList >& xAttribs )
+{
+ return Point( GetPercent( xAttribs->getOptionalValue( XML_x ) ), GetCoordinate( xAttribs->getOptionalValue( XML_y ) ) );
+}
+
+// --------------------------------------------------------------------
+
+/** converts the ST_TextFontSize to point */
+float GetTextSize( const 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 OUString& sValue )
+{
+ sal_Int32 nRet;
+ if( ::sax::Converter::convertNumber( nRet, sValue ) )
+ nRet = GetTextSpacingPoint( nRet );
+ return nRet;
+}
+
+sal_Int32 GetTextSpacingPoint( const sal_Int32 nValue )
+{
+ return ( nValue * 254 + 360 ) / 720;
+}
+
+TextVerticalAdjust GetTextVerticalAdjust( sal_Int32 nToken )
+{
+ TextVerticalAdjust rVal = TextVerticalAdjust_TOP;
+
+ switch( nToken ) {
+ case XML_b:
+ rVal = TextVerticalAdjust_BOTTOM;
+ break;
+ case XML_ctr:
+ rVal = TextVerticalAdjust_CENTER;
+ break;
+ }
+
+ return rVal;
+}
+
+float GetFontHeight( sal_Int32 nHeight )
+{
+ // convert 1/100 points to points
+ return static_cast< float >( nHeight / 100.0 );
+}
+
+sal_Int16 GetFontUnderline( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_none: return FontUnderline::NONE;
+ case XML_dash: return FontUnderline::DASH;
+ case XML_dashHeavy: return FontUnderline::BOLDDASH;
+ case XML_dashLong: return FontUnderline::LONGDASH;
+ case XML_dashLongHeavy: return FontUnderline::BOLDLONGDASH;
+ case XML_dbl: return FontUnderline::DOUBLE;
+ case XML_dotDash: return FontUnderline::DASHDOT;
+ case XML_dotDashHeavy: return FontUnderline::BOLDDASHDOT;
+ case XML_dotDotDash: return FontUnderline::DASHDOTDOT;
+ case XML_dotDotDashHeavy: return FontUnderline::BOLDDASHDOTDOT;
+ case XML_dotted: return FontUnderline::DOTTED;
+ case XML_dottedHeavy: return FontUnderline::BOLDDOTTED;
+ case XML_heavy: return FontUnderline::BOLD;
+ case XML_sng: return FontUnderline::SINGLE;
+ case XML_wavy: return FontUnderline::WAVE;
+ case XML_wavyDbl: return FontUnderline::DOUBLEWAVE;
+ case XML_wavyHeavy: return FontUnderline::BOLDWAVE;
+// case XML_words: // TODO
+ }
+ return FontUnderline::DONTKNOW;
+}
+
+sal_Int16 GetFontStrikeout( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_dblStrike: return FontStrikeout::DOUBLE;
+ case XML_noStrike: return FontStrikeout::NONE;
+ case XML_sngStrike: return FontStrikeout::SINGLE;
+ }
+ return FontStrikeout::DONTKNOW;
+}
+
+sal_Int16 GetCaseMap( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_all: return CaseMap::UPPERCASE;
+ case XML_small: return CaseMap::SMALLCAPS;
+ }
+ return CaseMap::NONE;
+}
+
+/** 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 */
+IntegerRectangle2D GetRelativeRect( const Reference< XFastAttributeList >& xAttribs )
+{
+ 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 */
+Size GetSize2D( const Reference< XFastAttributeList >& xAttribs )
+{
+ return 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;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/embeddedwavaudiofile.cxx b/oox/source/drawingml/embeddedwavaudiofile.cxx
new file mode 100644
index 000000000000..5c9484894109
--- /dev/null
+++ b/oox/source/drawingml/embeddedwavaudiofile.cxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/embeddedwavaudiofile.hxx"
+#include "oox/helper/attributelist.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 Relations& rRelations,
+ const Reference< XFastAttributeList >& xAttribs, EmbeddedWAVAudioFile & aAudio )
+ {
+ AttributeList attribs(xAttribs);
+
+ OUString sId = xAttribs->getOptionalValue( R_TOKEN( embed ) );
+ aAudio.msEmbed = rRelations.getFragmentPathFromRelId( 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..19700cd8199c
--- /dev/null
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/fillproperties.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/text/GraphicCrop.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/ColorMode.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/RectanglePoint.hpp>
+#include <com/sun/star/graphic/XGraphicTransformer.hpp>
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/modelobjecthelper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/token/tokens.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::graphic;
+
+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::geometry::IntegerRectangle2D;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+namespace {
+
+static const sal_Int32 spnDefaultFillIds[ FillId_END ] =
+{
+ PROP_FillStyle,
+ PROP_FillColor,
+ PROP_FillTransparence,
+ PROP_FillGradient,
+ PROP_FillBitmapURL,
+ PROP_FillBitmapMode,
+ PROP_FillBitmapSizeX,
+ PROP_FillBitmapSizeY,
+ PROP_FillBitmapPositionOffsetX,
+ PROP_FillBitmapPositionOffsetY,
+ PROP_FillBitmapRectanglePoint
+};
+
+BitmapMode lclGetBitmapMode( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_tile: return BitmapMode_REPEAT;
+ case XML_stretch: return BitmapMode_STRETCH;
+ }
+ return BitmapMode_NO_REPEAT;
+}
+
+RectanglePoint lclGetRectanglePoint( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_tl: return RectanglePoint_LEFT_TOP;
+ case XML_t: return RectanglePoint_MIDDLE_TOP;
+ case XML_tr: return RectanglePoint_RIGHT_TOP;
+ case XML_l: return RectanglePoint_LEFT_MIDDLE;
+ case XML_ctr: return RectanglePoint_MIDDLE_MIDDLE;
+ case XML_r: return RectanglePoint_RIGHT_MIDDLE;
+ case XML_bl: return RectanglePoint_LEFT_BOTTOM;
+ case XML_b: return RectanglePoint_MIDDLE_BOTTOM;
+ case XML_br: return RectanglePoint_RIGHT_BOTTOM;
+ }
+ return RectanglePoint_LEFT_TOP;
+}
+
+const awt::Size lclGetOriginalSize( const GraphicHelper& rGraphicHelper, const Reference< XGraphic >& rxGraphic )
+{
+ awt::Size aSizeHmm( 0, 0 );
+ try
+ {
+ Reference< beans::XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
+ if( xGraphicPropertySet->getPropertyValue( CREATE_OUSTRING( "Size100thMM" ) ) >>= aSizeHmm )
+ {
+ if( !aSizeHmm.Width && !aSizeHmm.Height )
+ { // MAPMODE_PIXEL USED :-(
+ awt::Size aSourceSizePixel( 0, 0 );
+ if( xGraphicPropertySet->getPropertyValue( CREATE_OUSTRING( "SizePixel" ) ) >>= aSourceSizePixel )
+ aSizeHmm = rGraphicHelper.convertScreenPixelToHmm( aSourceSizePixel );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ return aSizeHmm;
+}
+
+} // namespace
+
+// ============================================================================
+
+FillPropertyIds::FillPropertyIds( const sal_Int32* pnPropertyIds, bool bNamedFillGradient, bool bNamedFillBitmap ) :
+ mpnPropertyIds( pnPropertyIds ),
+ mbNamedFillGradient( bNamedFillGradient ),
+ mbNamedFillBitmap( bNamedFillBitmap )
+{
+ OSL_ENSURE( mpnPropertyIds != 0, "FillPropertyIds::FillPropertyIds - missing property identifiers" );
+}
+
+// ============================================================================
+
+void GradientFillProperties::assignUsed( const GradientFillProperties& rSourceProps )
+{
+ if( !rSourceProps.maGradientStops.empty() )
+ maGradientStops = rSourceProps.maGradientStops;
+ moFillToRect.assignIfUsed( rSourceProps.moFillToRect );
+ moTileRect.assignIfUsed( rSourceProps.moTileRect );
+ moGradientPath.assignIfUsed( rSourceProps.moGradientPath );
+ moShadeAngle.assignIfUsed( rSourceProps.moShadeAngle );
+ moShadeFlip.assignIfUsed( rSourceProps.moShadeFlip );
+ moShadeScaled.assignIfUsed( rSourceProps.moShadeScaled );
+ moRotateWithShape.assignIfUsed( rSourceProps.moRotateWithShape );
+}
+
+// ============================================================================
+
+void PatternFillProperties::assignUsed( const PatternFillProperties& rSourceProps )
+{
+ maPattFgColor.assignIfUsed( rSourceProps.maPattFgColor );
+ maPattBgColor.assignIfUsed( rSourceProps.maPattBgColor );
+ moPattPreset.assignIfUsed( rSourceProps.moPattPreset );
+}
+
+// ============================================================================
+
+void BlipFillProperties::assignUsed( const BlipFillProperties& rSourceProps )
+{
+ if( rSourceProps.mxGraphic.is() )
+ mxGraphic = rSourceProps.mxGraphic;
+ moBitmapMode.assignIfUsed( rSourceProps.moBitmapMode );
+ moFillRect.assignIfUsed( rSourceProps.moFillRect );
+ moTileOffsetX.assignIfUsed( rSourceProps.moTileOffsetX );
+ moTileOffsetY.assignIfUsed( rSourceProps.moTileOffsetY );
+ moTileScaleX.assignIfUsed( rSourceProps.moTileScaleX );
+ moTileScaleY.assignIfUsed( rSourceProps.moTileScaleY );
+ moTileAlign.assignIfUsed( rSourceProps.moTileAlign );
+ moTileFlip.assignIfUsed( rSourceProps.moTileFlip );
+ moRotateWithShape.assignIfUsed( rSourceProps.moRotateWithShape );
+ moColorEffect.assignIfUsed( rSourceProps.moColorEffect );
+ moBrightness.assignIfUsed( rSourceProps.moBrightness );
+ moContrast.assignIfUsed( rSourceProps.moContrast );
+ maColorChangeFrom.assignIfUsed( rSourceProps.maColorChangeFrom );
+ maColorChangeTo.assignIfUsed( rSourceProps.maColorChangeTo );
+}
+
+// ============================================================================
+
+FillPropertyIds FillProperties::DEFAULT_IDS( spnDefaultFillIds, false, false );
+
+void FillProperties::assignUsed( const FillProperties& rSourceProps )
+{
+ moFillType.assignIfUsed( rSourceProps.moFillType );
+ maFillColor.assignIfUsed( rSourceProps.maFillColor );
+ maGradientProps.assignUsed( rSourceProps.maGradientProps );
+ maPatternProps.assignUsed( rSourceProps.maPatternProps );
+ maBlipProps.assignUsed( rSourceProps.maBlipProps );
+}
+
+Color FillProperties::getBestSolidColor() const
+{
+ Color aSolidColor;
+ if( moFillType.has() ) switch( moFillType.get() )
+ {
+ case XML_solidFill:
+ aSolidColor = maFillColor;
+ break;
+ case XML_gradFill:
+ if( !maGradientProps.maGradientStops.empty() )
+ aSolidColor = maGradientProps.maGradientStops.begin()->second;
+ break;
+ case XML_pattFill:
+ aSolidColor = maPatternProps.maPattBgColor.isUsed() ? maPatternProps.maPattBgColor : maPatternProps.maPattFgColor;
+ break;
+ }
+ return aSolidColor;
+}
+
+void FillProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper, const FillPropertyIds& rPropIds,
+ sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const
+{
+ if( moFillType.has() )
+ {
+ FillStyle eFillStyle = FillStyle_NONE;
+ switch( moFillType.get() )
+ {
+ case XML_noFill:
+ eFillStyle = FillStyle_NONE;
+ break;
+
+ case XML_solidFill:
+ if( maFillColor.isUsed() )
+ {
+ rPropMap.setProperty( rPropIds[ FillColorId ], maFillColor.getColor( rGraphicHelper, nPhClr ) );
+ if( maFillColor.hasTransparence() )
+ rPropMap.setProperty( rPropIds[ FillTransparenceId ], maFillColor.getTransparence() );
+ eFillStyle = FillStyle_SOLID;
+ }
+ break;
+
+ case XML_gradFill:
+ // do not create gradient struct if property is not supported...
+ if( rPropIds.has( FillGradientId ) )
+ {
+ awt::Gradient aGradient;
+ aGradient.Angle = 900;
+ aGradient.StartIntensity = 100;
+ aGradient.EndIntensity = 100;
+
+ size_t nColorCount = maGradientProps.maGradientStops.size();
+ if( nColorCount > 1 )
+ {
+ aGradient.StartColor = maGradientProps.maGradientStops.begin()->second.getColor( rGraphicHelper, nPhClr );
+ aGradient.EndColor = maGradientProps.maGradientStops.rbegin()->second.getColor( rGraphicHelper, nPhClr );
+ }
+
+ // "rotate with shape" not set, or set to false -> do not rotate
+ if ( !maGradientProps.moRotateWithShape.get( false ) )
+ nShapeRotation = 0;
+
+ sal_Int32 nDmlAngle = 0;
+ if( maGradientProps.moGradientPath.has() )
+ {
+ aGradient.Style = (maGradientProps.moGradientPath.get() == XML_circle) ? awt::GradientStyle_ELLIPTICAL : awt::GradientStyle_RECT;
+ // position of gradient center (limited to [30%;70%], otherwise gradient is too hidden)
+ IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.get( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) );
+ sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2;
+ aGradient.XOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterX / PER_PERCENT, 30, 70 );
+ sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2;
+ aGradient.YOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterY / PER_PERCENT, 30, 70 );
+ ::std::swap( aGradient.StartColor, aGradient.EndColor );
+ nDmlAngle = nShapeRotation;
+ }
+ else
+ {
+ /* Try to detect a VML axial gradient. This type of
+ gradient is simulated by a 3-point linear gradient
+ with equal start and end color. */
+ bool bAxial = (nColorCount == 3) && (aGradient.StartColor == aGradient.EndColor);
+ aGradient.Style = bAxial ? awt::GradientStyle_AXIAL : awt::GradientStyle_LINEAR;
+ if( bAxial )
+ {
+ GradientFillProperties::GradientStopMap::const_iterator aIt = maGradientProps.maGradientStops.begin();
+ // API StartColor is inner color in axial gradient
+ aGradient.StartColor = (++aIt)->second.getColor( rGraphicHelper, nPhClr );
+ }
+ nDmlAngle = maGradientProps.moShadeAngle.get( 0 ) - nShapeRotation;
+ }
+ // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees)
+ aGradient.Angle = static_cast< sal_Int16 >( (4500 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 );
+
+ // push gradient or named gradient to property map
+ if( rPropIds.mbNamedFillGradient )
+ {
+ OUString aGradientName = rModelObjHelper.insertFillGradient( aGradient );
+ if( aGradientName.getLength() > 0 )
+ {
+ rPropMap.setProperty( rPropIds[ FillGradientId ], aGradientName );
+ eFillStyle = FillStyle_GRADIENT;
+ }
+ }
+ else
+ {
+ rPropMap.setProperty( rPropIds[ FillGradientId ], aGradient );
+ eFillStyle = FillStyle_GRADIENT;
+ }
+ }
+ break;
+
+ case XML_blipFill:
+ // do not start complex graphic transformation if property is not supported...
+ if( maBlipProps.mxGraphic.is() && rPropIds.has( FillBitmapUrlId ) )
+ {
+ // TODO: "rotate with shape" is not possible with our current core
+
+ OUString aGraphicUrl = rGraphicHelper.createGraphicObject( maBlipProps.mxGraphic );
+ if( aGraphicUrl.getLength() > 0 )
+ {
+ // push bitmap or named bitmap to property map
+ if( rPropIds.mbNamedFillBitmap )
+ {
+ OUString aBitmapName = rModelObjHelper.insertFillBitmap( aGraphicUrl );
+ if( aBitmapName.getLength() > 0 )
+ {
+ rPropMap.setProperty( rPropIds[ FillBitmapUrlId ], aBitmapName );
+ eFillStyle = FillStyle_BITMAP;
+ }
+ }
+ else
+ {
+ rPropMap.setProperty( rPropIds[ FillBitmapUrlId ], aGraphicUrl );
+ eFillStyle = FillStyle_BITMAP;
+ }
+ }
+
+ // set other bitmap properties, if bitmap has been inserted into the map
+ if( eFillStyle == FillStyle_BITMAP )
+ {
+ // bitmap mode (single, repeat, stretch)
+ BitmapMode eBitmapMode = lclGetBitmapMode( maBlipProps.moBitmapMode.get( XML_TOKEN_INVALID ) );
+ rPropMap.setProperty( rPropIds[ FillBitmapModeId ], eBitmapMode );
+
+ // additional settings for repeated bitmap
+ if( eBitmapMode == BitmapMode_REPEAT )
+ {
+ // anchor position inside bitmap
+ RectanglePoint eRectPoint = lclGetRectanglePoint( maBlipProps.moTileAlign.get( XML_tl ) );
+ rPropMap.setProperty( rPropIds[ FillBitmapRectanglePointId ], eRectPoint );
+
+ awt::Size aOriginalSize = lclGetOriginalSize( rGraphicHelper, maBlipProps.mxGraphic );
+ if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) )
+ {
+ // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm
+ double fScaleX = maBlipProps.moTileScaleX.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
+ sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 );
+ rPropMap.setProperty( rPropIds[ FillBitmapSizeXId ], nFillBmpSizeX );
+ double fScaleY = maBlipProps.moTileScaleY.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
+ sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 );
+ rPropMap.setProperty( rPropIds[ FillBitmapSizeYId ], nFillBmpSizeY );
+
+ // offset of the first bitmap tile (given as EMUs), convert to percent
+ sal_Int16 nTileOffsetX = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetX.get( 0 ) / 3.6 / aOriginalSize.Width, 0, 100 );
+ rPropMap.setProperty( rPropIds[ FillBitmapOffsetXId ], nTileOffsetX );
+ sal_Int16 nTileOffsetY = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetY.get( 0 ) / 3.6 / aOriginalSize.Height, 0, 100 );
+ rPropMap.setProperty( rPropIds[ FillBitmapOffsetYId ], nTileOffsetY );
+ }
+ }
+ }
+ }
+ break;
+
+ case XML_pattFill:
+ {
+ // todo
+ Color aColor = getBestSolidColor();
+ if( aColor.isUsed() )
+ {
+ rPropMap.setProperty( rPropIds[ FillColorId ], aColor.getColor( rGraphicHelper, nPhClr ) );
+ if( aColor.hasTransparence() )
+ rPropMap.setProperty( rPropIds[ FillTransparenceId ], aColor.getTransparence() );
+ eFillStyle = FillStyle_SOLID;
+ }
+ }
+ break;
+
+ case XML_grpFill:
+ // todo
+ eFillStyle = FillStyle_NONE;
+ break;
+ }
+
+ // set final fill style property
+ rPropMap.setProperty( rPropIds[ FillStyleId ], eFillStyle );
+ }
+}
+
+void FillProperties::pushToPropSet( PropertySet& rPropSet, ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper, const FillPropertyIds& rPropIds,
+ sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const
+{
+ PropertyMap aPropMap;
+ pushToPropMap( aPropMap, rModelObjHelper, rGraphicHelper, rPropIds, nShapeRotation, nPhClr );
+ rPropSet.setProperties( aPropMap );
+}
+
+// ============================================================================
+
+void GraphicProperties::assignUsed( const GraphicProperties& rSourceProps )
+{
+ maBlipProps.assignUsed( rSourceProps.maBlipProps );
+}
+
+void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr ) const
+{
+ if( maBlipProps.mxGraphic.is() )
+ {
+ // created transformed graphic
+ Reference< XGraphic > xGraphic = maBlipProps.mxGraphic;
+ if( maBlipProps.maColorChangeFrom.isUsed() && maBlipProps.maColorChangeTo.isUsed() )
+ {
+ sal_Int32 nFromColor = maBlipProps.maColorChangeFrom.getColor( rGraphicHelper, nPhClr );
+ sal_Int32 nToColor = maBlipProps.maColorChangeTo.getColor( rGraphicHelper, nPhClr );
+ if ( (nFromColor != nToColor) || maBlipProps.maColorChangeTo.hasTransparence() ) try
+ {
+ sal_Int16 nToTransparence = maBlipProps.maColorChangeTo.getTransparence();
+ sal_Int8 nToAlpha = static_cast< sal_Int8 >( (100 - nToTransparence) / 39.062 ); // ?!? correct ?!?
+ Reference< XGraphicTransformer > xTransformer( maBlipProps.mxGraphic, UNO_QUERY_THROW );
+ xGraphic = xTransformer->colorChange( maBlipProps.mxGraphic, nFromColor, 9, nToColor, nToAlpha );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ OUString aGraphicUrl = rGraphicHelper.createGraphicObject( xGraphic );
+ if( aGraphicUrl.getLength() > 0 )
+ rPropMap[ PROP_GraphicURL ] <<= aGraphicUrl;
+
+ // cropping
+ if ( maBlipProps.moClipRect.has() )
+ {
+ geometry::IntegerRectangle2D oClipRect( maBlipProps.moClipRect.get() );
+ awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
+ if ( aOriginalSize.Width && aOriginalSize.Height )
+ {
+ text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
+ if ( oClipRect.X1 )
+ aGraphCrop.Left = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X1 ) / 100000 );
+ if ( oClipRect.Y1 )
+ aGraphCrop.Top = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y1 ) / 100000 );
+ if ( oClipRect.X2 )
+ aGraphCrop.Right = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X2 ) / 100000 );
+ if ( oClipRect.Y2 )
+ aGraphCrop.Bottom = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y2 ) / 100000 );
+ rPropMap[ PROP_GraphicCrop ] <<= aGraphCrop;
+ }
+ }
+ }
+
+ // color effect
+ ColorMode eColorMode = ColorMode_STANDARD;
+ switch( maBlipProps.moColorEffect.get( XML_TOKEN_INVALID ) )
+ {
+ case XML_biLevel: eColorMode = ColorMode_MONO; break;
+ case XML_grayscl: eColorMode = ColorMode_GREYS; break;
+ }
+ rPropMap[ PROP_GraphicColorMode ] <<= eColorMode;
+
+ // brightness and contrast
+ sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.get( 0 ) / PER_PERCENT, -100, 100 );
+ if( nBrightness != 0 )
+ rPropMap[ PROP_AdjustLuminance ] <<= nBrightness;
+ sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.get( 0 ) / PER_PERCENT, -100, 100 );
+ if( nContrast != 0 )
+ rPropMap[ PROP_AdjustContrast ] <<= nContrast;
+}
+
+void GraphicProperties::pushToPropSet( PropertySet& rPropSet, const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr ) const
+{
+ PropertyMap aPropMap;
+ pushToPropMap( aPropMap, rGraphicHelper, nPhClr );
+ rPropSet.setProperties( aPropMap );
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/fillpropertiesgroupcontext.cxx b/oox/source/drawingml/fillpropertiesgroupcontext.cxx
new file mode 100644
index 000000000000..15b1ef0f2404
--- /dev/null
+++ b/oox/source/drawingml/fillpropertiesgroupcontext.cxx
@@ -0,0 +1,308 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::oox::core::ContextHandler;
+using ::oox::core::XmlFilterBase;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+SolidFillContext::SolidFillContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >&, FillProperties& rFillProps ) :
+ ColorContext( rParent, rFillProps.maFillColor )
+{
+}
+
+// ============================================================================
+
+GradientFillContext::GradientFillContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rxAttribs, GradientFillProperties& rGradientProps ) :
+ ContextHandler( rParent ),
+ mrGradientProps( rGradientProps )
+{
+ AttributeList aAttribs( rxAttribs );
+ mrGradientProps.moShadeFlip = aAttribs.getToken( XML_flip );
+ mrGradientProps.moRotateWithShape = aAttribs.getBool( XML_rotWithShape );
+}
+
+Reference< XFastContextHandler > GradientFillContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( rxAttribs );
+ switch( nElement )
+ {
+ case A_TOKEN( gsLst ):
+ return this; // for gs elements
+
+ case A_TOKEN( gs ):
+ if( aAttribs.hasAttribute( XML_pos ) )
+ {
+ double fPosition = getLimitedValue< double >( aAttribs.getDouble( XML_pos, 0.0 ) / 100000.0, 0.0, 1.0 );
+ return new ColorContext( *this, mrGradientProps.maGradientStops[ fPosition ] );
+ }
+ break;
+
+ case A_TOKEN( lin ):
+ mrGradientProps.moShadeAngle = aAttribs.getInteger( XML_ang );
+ mrGradientProps.moShadeScaled = aAttribs.getBool( XML_scaled );
+ break;
+
+ case A_TOKEN( path ):
+ // always set a path type, this disables linear gradient in conversion
+ mrGradientProps.moGradientPath = aAttribs.getToken( XML_path, XML_rect );
+ return this; // for fillToRect element
+
+ case A_TOKEN( fillToRect ):
+ mrGradientProps.moFillToRect = GetRelativeRect( rxAttribs );
+ break;
+
+ case A_TOKEN( tileRect ):
+ mrGradientProps.moTileRect = GetRelativeRect( rxAttribs );
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+PatternFillContext::PatternFillContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rxAttribs, PatternFillProperties& rPatternProps ) :
+ ContextHandler( rParent ),
+ mrPatternProps( rPatternProps )
+{
+ AttributeList aAttribs( rxAttribs );
+ mrPatternProps.moPattPreset = aAttribs.getToken( XML_prst );
+}
+
+Reference< XFastContextHandler > PatternFillContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( bgClr ):
+ return new ColorContext( *this, mrPatternProps.maPattBgColor );
+ case A_TOKEN( fgClr ):
+ return new ColorContext( *this, mrPatternProps.maPattFgColor );
+ }
+ return 0;
+}
+
+// ============================================================================
+// ============================================================================
+
+ColorChangeContext::ColorChangeContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rxAttribs, BlipFillProperties& rBlipProps ) :
+ ContextHandler( rParent ),
+ mrBlipProps( rBlipProps )
+{
+ mrBlipProps.maColorChangeFrom.setUnused();
+ mrBlipProps.maColorChangeTo.setUnused();
+ AttributeList aAttribs( rxAttribs );
+ mbUseAlpha = aAttribs.getBool( XML_useA, true );
+}
+
+ColorChangeContext::~ColorChangeContext()
+{
+ if( !mbUseAlpha )
+ mrBlipProps.maColorChangeTo.clearTransparence();
+}
+
+Reference< XFastContextHandler > ColorChangeContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( clrFrom ):
+ return new ColorContext( *this, mrBlipProps.maColorChangeFrom );
+ case A_TOKEN( clrTo ):
+ return new ColorContext( *this, mrBlipProps.maColorChangeTo );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+BlipContext::BlipContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rxAttribs, BlipFillProperties& rBlipProps ) :
+ ContextHandler( rParent ),
+ mrBlipProps( rBlipProps )
+{
+ AttributeList aAttribs( rxAttribs );
+ if( aAttribs.hasAttribute( R_TOKEN( embed ) ) )
+ {
+ // internal picture URL
+ OUString aFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( embed ), OUString() ) );
+ if( aFragmentPath.getLength() > 0 )
+ mrBlipProps.mxGraphic = getFilter().getGraphicHelper().importEmbeddedGraphic( aFragmentPath );
+ }
+ else if( aAttribs.hasAttribute( R_TOKEN( link ) ) )
+ {
+ // external URL
+ OUString aRelId = aAttribs.getString( R_TOKEN( link ), OUString() );
+ OUString aTargetLink = getFilter().getAbsoluteUrl( getRelations().getExternalTargetFromRelId( aRelId ) );
+ // TODO: load external picture
+ }
+}
+
+Reference< XFastContextHandler > BlipContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( rxAttribs );
+ switch( nElement )
+ {
+ case A_TOKEN( biLevel ):
+ case A_TOKEN( grayscl ):
+ mrBlipProps.moColorEffect = getBaseToken( nElement );
+ break;
+
+ case A_TOKEN( clrChange ):
+ return new ColorChangeContext( *this, rxAttribs, mrBlipProps );
+
+ case A_TOKEN( lum ):
+ mrBlipProps.moBrightness = aAttribs.getInteger( XML_bright );
+ mrBlipProps.moContrast = aAttribs.getInteger( XML_contrast );
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+BlipFillContext::BlipFillContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rxAttribs, BlipFillProperties& rBlipProps ) :
+ ContextHandler( rParent ),
+ mrBlipProps( rBlipProps )
+{
+ AttributeList aAttribs( rxAttribs );
+ mrBlipProps.moRotateWithShape = aAttribs.getBool( XML_rotWithShape );
+}
+
+Reference< XFastContextHandler > BlipFillContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( rxAttribs );
+ switch( nElement )
+ {
+ case A_TOKEN( blip ):
+ return new BlipContext( *this, rxAttribs, mrBlipProps );
+
+ case A_TOKEN( srcRect ):
+ {
+ rtl::OUString aDefault( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "0" ) ) );
+ ::com::sun::star::geometry::IntegerRectangle2D aClipRect;
+ aClipRect.X1 = GetPercent( aAttribs.getString( XML_l, aDefault ) );
+ aClipRect.Y1 = GetPercent( aAttribs.getString( XML_t, aDefault ) );
+ aClipRect.X2 = GetPercent( aAttribs.getString( XML_r, aDefault ) );
+ aClipRect.Y2 = GetPercent( aAttribs.getString( XML_b, aDefault ) );
+ mrBlipProps.moClipRect = aClipRect;
+ }
+ break;
+
+ case A_TOKEN( tile ):
+ mrBlipProps.moBitmapMode = getBaseToken( nElement );
+ mrBlipProps.moTileOffsetX = aAttribs.getInteger( XML_tx );
+ mrBlipProps.moTileOffsetY = aAttribs.getInteger( XML_ty );
+ mrBlipProps.moTileScaleX = aAttribs.getInteger( XML_sx );
+ mrBlipProps.moTileScaleY = aAttribs.getInteger( XML_sy );
+ mrBlipProps.moTileAlign = aAttribs.getToken( XML_algn );
+ mrBlipProps.moTileFlip = aAttribs.getToken( XML_flip );
+ break;
+
+ case A_TOKEN( stretch ):
+ mrBlipProps.moBitmapMode = getBaseToken( nElement );
+ return this; // for fillRect element
+
+ case A_TOKEN( fillRect ):
+ mrBlipProps.moFillRect = GetRelativeRect( rxAttribs );
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+// ============================================================================
+
+FillPropertiesContext::FillPropertiesContext( ContextHandler& rParent, FillProperties& rFillProps ) :
+ ContextHandler( rParent ),
+ mrFillProps( rFillProps )
+{
+}
+
+Reference< XFastContextHandler > FillPropertiesContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
+ throw ( SAXException, RuntimeException )
+{
+ return createFillContext( *this, nElement, rxAttribs, mrFillProps );
+}
+
+/*static*/ Reference< XFastContextHandler > FillPropertiesContext::createFillContext(
+ ContextHandler& rParent, sal_Int32 nElement,
+ const Reference< XFastAttributeList >& rxAttribs, FillProperties& rFillProps )
+{
+ switch( nElement )
+ {
+ case A_TOKEN( noFill ): { rFillProps.moFillType = getBaseToken( nElement ); return 0; };
+ case A_TOKEN( solidFill ): { rFillProps.moFillType = getBaseToken( nElement ); return new SolidFillContext( rParent, rxAttribs, rFillProps ); };
+ case A_TOKEN( gradFill ): { rFillProps.moFillType = getBaseToken( nElement ); return new GradientFillContext( rParent, rxAttribs, rFillProps.maGradientProps ); };
+ case A_TOKEN( pattFill ): { rFillProps.moFillType = getBaseToken( nElement ); return new PatternFillContext( rParent, rxAttribs, rFillProps.maPatternProps ); };
+ case A_TOKEN( blipFill ): { rFillProps.moFillType = getBaseToken( nElement ); return new BlipFillContext( rParent, rxAttribs, rFillProps.maBlipProps ); };
+ case A_TOKEN( grpFill ): { rFillProps.moFillType = getBaseToken( nElement ); return 0; }; // TODO
+ }
+ return 0;
+}
+
+// ============================================================================
+
+SimpleFillPropertiesContext::SimpleFillPropertiesContext( ContextHandler& rParent, Color& rColor ) :
+ FillPropertiesContext( rParent, *this ),
+ mrColor( rColor )
+{
+}
+
+SimpleFillPropertiesContext::~SimpleFillPropertiesContext()
+{
+ mrColor = getBestSolidColor();
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx
new file mode 100644
index 000000000000..646017aa22ea
--- /dev/null
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -0,0 +1,317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/customshapeproperties.hxx"
+#include "oox/drawingml/diagram/diagramfragmenthandler.hxx"
+#include "oox/drawingml/table/tablecontext.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/drawingml/transform2dcontext.hxx"
+
+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 ::com::sun::star::xml::sax;
+using namespace ::oox::core;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+// CT_Picture
+
+GraphicShapeContext::GraphicShapeContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
+: ShapeContext( rParent, pMasterShapePtr, pShapePtr )
+{
+}
+
+Reference< XFastContextHandler > GraphicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( getBaseToken( aElementToken ) )
+ {
+ // CT_ShapeProperties
+ case XML_xfrm:
+ xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
+ break;
+ case XML_blipFill:
+ xRet.set( new BlipFillContext( *this, xAttribs, mpShapePtr->getGraphicProperties().maBlipProps ) );
+ break;
+ }
+
+ if ((getNamespace( aElementToken ) == NMSP_vml) && mpShapePtr)
+ {
+ mpShapePtr->setServiceName("com.sun.star.drawing.CustomShape");
+ CustomShapePropertiesPtr pCstmShpProps
+ (mpShapePtr->getCustomShapeProperties());
+
+ sal_uInt32 nType = getBaseToken( aElementToken );
+ OUString sType(GetShapeType(nType));
+
+ if (sType.getLength() > 0)
+ pCstmShpProps->setShapePresetType(sType);
+ }
+
+ if( !xRet.is() )
+ xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
+
+ return xRet;
+}
+
+// ============================================================================
+// CT_GraphicalObjectFrameContext
+
+GraphicalObjectFrameContext::GraphicalObjectFrameContext( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr, bool bEmbedShapesInChart ) :
+ ShapeContext( rParent, pMasterShapePtr, pShapePtr ),
+ mbEmbedShapesInChart( bEmbedShapesInChart )
+{
+}
+
+Reference< XFastContextHandler > GraphicalObjectFrameContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( getBaseToken( aElementToken ) )
+ {
+ // CT_ShapeProperties
+ case XML_nvGraphicFramePr: // CT_GraphicalObjectFrameNonVisual
+ break;
+ case XML_xfrm: // CT_Transform2D
+ xRet.set( new Transform2DContext( *this, xAttribs, *mpShapePtr ) );
+ break;
+ case XML_graphic: // CT_GraphicalObject
+ xRet.set( this );
+ break;
+
+ case XML_graphicData : // CT_GraphicalObjectData
+ {
+ OUString sUri( xAttribs->getOptionalValue( XML_uri ) );
+ if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/presentationml/2006/ole" ) )
+ xRet.set( new OleObjectGraphicDataContext( *this, mpShapePtr ) );
+ else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ) )
+ xRet.set( new DiagramGraphicDataContext( *this, mpShapePtr ) );
+ else if ( sUri.equalsAscii( "http://schemas.openxmlformats.org/drawingml/2006/chart" ) )
+ xRet.set( new ChartGraphicDataContext( *this, mpShapePtr, mbEmbedShapesInChart ) );
+ else if ( sUri.compareToAscii( "http://schemas.openxmlformats.org/drawingml/2006/table" ) == 0 )
+ xRet.set( new table::TableContext( *this, mpShapePtr ) );
+ 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;
+}
+
+// ============================================================================
+
+OleObjectGraphicDataContext::OleObjectGraphicDataContext( ContextHandler& rParent, ShapePtr xShape ) :
+ ShapeContext( rParent, ShapePtr(), xShape ),
+ mrOleObjectInfo( xShape->setOleObjectType() )
+{
+}
+
+OleObjectGraphicDataContext::~OleObjectGraphicDataContext()
+{
+ /* Register the OLE shape at the VML drawing, this prevents that the
+ related VML shape converts the OLE object by itself. */
+ if( mrOleObjectInfo.maShapeId.getLength() > 0 )
+ if( ::oox::vml::Drawing* pVmlDrawing = getFilter().getVmlDrawing() )
+ pVmlDrawing->registerOleObject( mrOleObjectInfo );
+}
+
+Reference< XFastContextHandler > OleObjectGraphicDataContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ AttributeList aAttribs( xAttribs );
+
+ switch( nElement )
+ {
+ case PPT_TOKEN( oleObj ):
+ {
+ mrOleObjectInfo.maShapeId = aAttribs.getXString( XML_spid, OUString() );
+ const Relation* pRelation = getRelations().getRelationFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
+ OSL_ENSURE( pRelation, "OleObjectGraphicDataContext::createFastChildContext - missing relation for OLE object" );
+ if( pRelation )
+ {
+ mrOleObjectInfo.mbLinked = pRelation->mbExternal;
+ if( pRelation->mbExternal )
+ {
+ mrOleObjectInfo.maTargetLink = getFilter().getAbsoluteUrl( pRelation->maTarget );
+ }
+ else
+ {
+ OUString aFragmentPath = getFragmentPathFromRelation( *pRelation );
+ if( aFragmentPath.getLength() > 0 )
+ getFilter().importBinaryData( mrOleObjectInfo.maEmbeddedData, aFragmentPath );
+ }
+ }
+ mrOleObjectInfo.maName = aAttribs.getXString( XML_name, OUString() );
+ mrOleObjectInfo.maProgId = aAttribs.getXString( XML_progId, OUString() );
+ mrOleObjectInfo.mbShowAsIcon = aAttribs.getBool( XML_showAsIcon, false );
+ xRet.set( this );
+ }
+ break;
+
+ case PPT_TOKEN( embed ):
+ OSL_ENSURE( !mrOleObjectInfo.mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
+ break;
+
+ case PPT_TOKEN( link ):
+ OSL_ENSURE( mrOleObjectInfo.mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" );
+ mrOleObjectInfo.mbAutoUpdate = aAttribs.getBool( XML_updateAutomatic, false );
+ break;
+ }
+ return xRet;
+}
+
+// ============================================================================
+
+DiagramGraphicDataContext::DiagramGraphicDataContext( ContextHandler& rParent, ShapePtr pShapePtr )
+: ShapeContext( rParent, ShapePtr(), pShapePtr )
+{
+ pShapePtr->setDiagramType();
+}
+
+DiagramGraphicDataContext::~DiagramGraphicDataContext()
+{
+}
+
+DiagramPtr DiagramGraphicDataContext::loadDiagram()
+{
+ DiagramPtr pDiagram( new Diagram() );
+ XmlFilterBase& rFilter = getFilter();
+
+ // data
+ OUString sDmPath = getFragmentPathFromRelId( msDm );
+ if( sDmPath.getLength() > 0 )
+ {
+ DiagramDataPtr pData( new DiagramData() );
+ pDiagram->setData( pData );
+ rFilter.importFragment( new DiagramDataFragmentHandler( rFilter, sDmPath, pData ) );
+ }
+ // layout
+ OUString sLoPath = getFragmentPathFromRelId( msLo );
+ if( sLoPath.getLength() > 0 )
+ {
+ DiagramLayoutPtr pLayout( new DiagramLayout() );
+ pDiagram->setLayout( pLayout );
+ rFilter.importFragment( new DiagramLayoutFragmentHandler( rFilter, sLoPath, pLayout ) );
+ }
+ // style
+ OUString sQsPath = getFragmentPathFromRelId( msQs );
+ if( sQsPath.getLength() > 0 )
+ {
+ DiagramQStylesPtr pStyles( new DiagramQStyles() );
+ pDiagram->setQStyles( pStyles );
+ rFilter.importFragment( new DiagramQStylesFragmentHandler( rFilter, sQsPath, pStyles ) );
+ }
+ // colors
+ OUString sCsPath = getFragmentPathFromRelId( msCs );
+ if( sCsPath.getLength() > 0 )
+ {
+ DiagramColorsPtr pColors( new DiagramColors() );
+ pDiagram->setColors( pColors );
+ rFilter.importFragment( new DiagramColorsFragmentHandler( rFilter, sCsPath, pColors ) ) ;
+ }
+
+ return pDiagram;
+}
+
+
+Reference< XFastContextHandler > DiagramGraphicDataContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case DGM_TOKEN( relIds ):
+ {
+ msDm = xAttribs->getOptionalValue( R_TOKEN( dm ) );
+ msLo = xAttribs->getOptionalValue( R_TOKEN( lo ) );
+ msQs = xAttribs->getOptionalValue( R_TOKEN( qs ) );
+ msCs = xAttribs->getOptionalValue( R_TOKEN( cs ) );
+ DiagramPtr pDiagram = loadDiagram();
+ pDiagram->addTo( mpShapePtr );
+ OSL_TRACE("diagram added shape %s of type %s", OUSTRING_TO_CSTR( mpShapePtr->getName() ),
+ OUSTRING_TO_CSTR( mpShapePtr->getServiceName() ) );
+ break;
+ }
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( ShapeContext::createFastChildContext( aElementToken, xAttribs ) );
+
+ return xRet;
+}
+
+// ============================================================================
+
+ChartGraphicDataContext::ChartGraphicDataContext( ContextHandler& rParent, const ShapePtr& rxShape, bool bEmbedShapes ) :
+ ShapeContext( rParent, ShapePtr(), rxShape ),
+ mrChartShapeInfo( rxShape->setChartType( bEmbedShapes ) )
+{
+}
+
+Reference< XFastContextHandler > ChartGraphicDataContext::createFastChildContext( ::sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
+ throw (SAXException, RuntimeException)
+{
+ if( nElement == C_TOKEN( chart ) )
+ {
+ AttributeList aAttribs( rxAttribs );
+ mrChartShapeInfo.maFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/guidcontext.cxx b/oox/source/drawingml/guidcontext.cxx
new file mode 100644
index 000000000000..d5fbc10783ac
--- /dev/null
+++ b/oox/source/drawingml/guidcontext.cxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/guidcontext.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 {
+
+GuidContext::GuidContext( ContextHandler& rParent, rtl::OUString& rGuidId )
+: ContextHandler( rParent )
+, mrGuidId( rGuidId )
+{
+}
+void GuidContext::characters( const OUString& aChars ) throw ( SAXException, RuntimeException )
+{
+ mrGuidId += aChars;
+}
+
+} }
diff --git a/oox/source/drawingml/hyperlinkcontext.cxx b/oox/source/drawingml/hyperlinkcontext.cxx
new file mode 100644
index 000000000000..2b2b1ee1cef6
--- /dev/null
+++ b/oox/source/drawingml/hyperlinkcontext.cxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "hyperlinkcontext.hxx"
+
+#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
+
+#include "oox/helper/propertymap.hxx"
+#include "oox/core/relations.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/embeddedwavaudiofile.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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttributes, PropertyMap& aProperties )
+ : ContextHandler( rParent )
+ , maProperties(aProperties)
+{
+ OUString sURL, sHref;
+ OUString aRelId = xAttributes->getOptionalValue( R_TOKEN( id ) );
+ if ( aRelId.getLength() )
+ {
+ OSL_TRACE("OOX: URI rId %s", ::rtl::OUStringToOString (aRelId, RTL_TEXTENCODING_UTF8).pData->buffer);
+ sHref = getRelations().getExternalTargetFromRelId( aRelId );
+ if( sHref.getLength() > 0 )
+ {
+ OSL_TRACE("OOX: URI href %s", ::rtl::OUStringToOString (sHref, RTL_TEXTENCODING_UTF8).pData->buffer);
+ sURL = getFilter().getAbsoluteUrl( sHref );
+ }
+ }
+ OUString sTooltip = xAttributes->getOptionalValue( R_TOKEN( tooltip ) );
+ if ( sTooltip.getLength() )
+ maProperties[ PROP_Representation ] <<= sTooltip;
+ OUString sFrame = xAttributes->getOptionalValue( R_TOKEN( tgtFrame ) );
+ if( sFrame.getLength() )
+ maProperties[ PROP_TargetFrame ] <<= sFrame;
+ OUString aAction = xAttributes->getOptionalValue( XML_action );
+ if ( aAction.getLength() )
+ {
+ // reserved values of the unrestricted string aAction:
+ // ppaction://customshow?id=SHOW_ID // custom presentation
+ // ppaction://hlinkfile // external file via r:id
+ // ppaction://hlinkpres?slideindex=SLIDE_NUM // external presentation via r:id
+ // ppaction://hlinkshowjump?jump=endshow
+ // ppaction://hlinkshowjump?jump=firstslide
+ // ppaction://hlinkshowjump?jump=lastslide
+ // ppaction://hlinkshowjump?jump=lastslideviewed
+ // ppaction://hlinkshowjump?jump=nextslide
+ // ppaction://hlinkshowjump?jump=previousslide
+ // ppaction://hlinksldjump
+ // ppaction://macro?name=MACRO_NAME
+ // ppaction://program
+
+ const OUString sPPAction( CREATE_OUSTRING( "ppaction://" ) );
+ if ( aAction.matchIgnoreAsciiCase( sPPAction, 0 ) )
+ {
+ OUString aPPAct( aAction.copy( sPPAction.getLength() ) );
+ sal_Int32 nIndex = aPPAct.indexOf( '?', 0 );
+ OUString aPPAction( nIndex > 0 ? aPPAct.copy( 0, nIndex ) : aPPAct );
+
+ const OUString sHlinkshowjump( CREATE_OUSTRING( "hlinkshowjump" ) );
+ const OUString sHlinksldjump( CREATE_OUSTRING( "hlinksldjump" ) );
+ if ( aPPAction.match( sHlinkshowjump ) )
+ {
+ const OUString sJump( CREATE_OUSTRING( "jump=" ) );
+ if ( aPPAct.match( sJump, nIndex + 1 ) )
+ {
+ OUString aDestination( aPPAct.copy( nIndex + 1 + sJump.getLength() ) );
+ sURL = sURL.concat( CREATE_OUSTRING( "#action?jump=" ) );
+ sURL = sURL.concat( aDestination );
+ }
+ }
+ else if ( aPPAction.match( sHlinksldjump ) )
+ {
+ sURL = OUString();
+
+ sal_Int32 nIndex2 = 0;
+ while ( nIndex2 < sHref.getLength() )
+ {
+ sal_Unicode nChar = sHref[ nIndex2 ];
+ if ( ( nChar >= '0' ) && ( nChar <= '9' ) )
+ break;
+ nIndex2++;
+ }
+ if ( nIndex2 && ( nIndex2 != sHref.getLength() ) )
+ {
+ sal_Int32 nLength = 1;
+ while( ( nIndex2 + nLength ) < sHref.getLength() )
+ {
+ sal_Unicode nChar = sHref[ nIndex2 + nLength ];
+ if ( ( nChar < '0' ) || ( nChar > '9' ) )
+ break;
+ nLength++;
+ }
+ sal_Int32 nPageNumber = sHref.copy( nIndex2, nLength ).toInt32();
+ if ( nPageNumber )
+ {
+ const OUString sSlide( CREATE_OUSTRING( "slide" ) );
+ const OUString sNotesSlide( CREATE_OUSTRING( "notesSlide" ) );
+ const OUString aSlideType( sHref.copy( 0, nIndex2 ) );
+ if ( aSlideType.match( sSlide ) )
+ sURL = CREATE_OUSTRING( "#Slide " ).concat( rtl::OUString::valueOf( nPageNumber ) );
+ else if ( aSlideType.match( sNotesSlide ) )
+ sURL = CREATE_OUSTRING( "#Notes " ).concat( rtl::OUString::valueOf( nPageNumber ) );
+// else: todo for other types such as notesMaster or slideMaster as they can't be referenced easily
+ }
+ }
+ }
+ }
+ }
+ if ( sURL.getLength() )
+ maProperties[ PROP_URL ] <<= sURL;
+
+ // TODO unhandled
+ // XML_invalidUrl
+ // XML_history
+ // XML_highlightClick
+ // XML_endSnd
+}
+
+HyperLinkContext::~HyperLinkContext()
+{
+}
+
+Reference< XFastContextHandler > HyperLinkContext::createFastChildContext(
+ ::sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElement )
+ {
+ case A_TOKEN( extLst ):
+ return xRet;
+ case A_TOKEN( snd ):
+ EmbeddedWAVAudioFile aAudio;
+ getEmbeddedWAVAudioFile( getRelations(), xAttribs, aAudio );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/hyperlinkcontext.hxx b/oox/source/drawingml/hyperlinkcontext.hxx
new file mode 100644
index 000000000000..aa5b5f0a19ec
--- /dev/null
+++ b/oox/source/drawingml/hyperlinkcontext.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_HYPERLINKCONTEXT_HXX
+#define OOX_DRAWINGML_HYPERLINKCONTEXT_HXX
+
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { class PropertyMap; }
+
+namespace oox {
+namespace drawingml {
+
+class HyperLinkContext : public ::oox::core::ContextHandler
+{
+public:
+ HyperLinkContext(
+ ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
+ PropertyMap& aProperties );
+ virtual ~HyperLinkContext();
+
+ 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;
+};
+
+} // namespace drawingml
+} // namespace oox
+
+#endif
+
diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx
new file mode 100644
index 000000000000..2eb1ef8b4cdf
--- /dev/null
+++ b/oox/source/drawingml/lineproperties.cxx
@@ -0,0 +1,477 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/lineproperties.hxx"
+#include <vector>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/drawing/FlagSequence.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/modelobjecthelper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/token/tokens.hxx"
+
+using namespace ::com::sun::star::drawing;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::awt::Point;
+using ::com::sun::star::container::XNameContainer;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+namespace {
+
+static const sal_Int32 spnDefaultLineIds[ LineId_END ] =
+{
+ PROP_LineStyle,
+ PROP_LineWidth,
+ PROP_LineColor,
+ PROP_LineTransparence,
+ PROP_LineDash,
+ PROP_LineJoint,
+ PROP_LineStartName,
+ PROP_LineStartWidth,
+ PROP_LineStartCenter,
+ PROP_LineEndName,
+ PROP_LineEndWidth,
+ PROP_LineEndCenter
+};
+
+// ----------------------------------------------------------------------------
+
+void lclSetDashData( LineDash& orLineDash, sal_Int16 nDots, sal_Int32 nDotLen,
+ sal_Int16 nDashes, sal_Int32 nDashLen, sal_Int32 nDistance )
+{
+ orLineDash.Dots = nDots;
+ orLineDash.DotLen = nDotLen;
+ orLineDash.Dashes = nDashes;
+ orLineDash.DashLen = nDashLen;
+ orLineDash.Distance = nDistance;
+}
+
+/** Converts the specified preset dash to API dash.
+
+ Line length and dot length are set relative to line width and have to be
+ multiplied by the actual line width after this function.
+ */
+void lclConvertPresetDash( LineDash& orLineDash, sal_Int32 nPresetDash )
+{
+ switch( nPresetDash )
+ {
+ case XML_dot: lclSetDashData( orLineDash, 1, 1, 0, 0, 3 ); break;
+ case XML_dash: lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); break;
+ case XML_dashDot: lclSetDashData( orLineDash, 1, 1, 1, 4, 3 ); break;
+
+ case XML_lgDash: lclSetDashData( orLineDash, 0, 0, 1, 8, 3 ); break;
+ case XML_lgDashDot: lclSetDashData( orLineDash, 1, 1, 1, 8, 3 ); break;
+ case XML_lgDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 8, 3 ); break;
+
+ case XML_sysDot: lclSetDashData( orLineDash, 1, 1, 0, 0, 1 ); break;
+ case XML_sysDash: lclSetDashData( orLineDash, 0, 0, 1, 3, 1 ); break;
+ case XML_sysDashDot: lclSetDashData( orLineDash, 1, 1, 1, 3, 1 ); break;
+ case XML_sysDashDotDot: lclSetDashData( orLineDash, 2, 1, 1, 3, 1 ); break;
+
+ default:
+ OSL_ENSURE( false, "lclConvertPresetDash - unsupported preset dash" );
+ lclSetDashData( orLineDash, 0, 0, 1, 4, 3 );
+ }
+}
+
+/** Converts the passed custom dash to API dash.
+
+ Line length and dot length are set relative to line width and have to be
+ multiplied by the actual line width after this function.
+ */
+void lclConvertCustomDash( LineDash& orLineDash, const LineProperties::DashStopVector& rCustomDash )
+{
+ if( rCustomDash.empty() )
+ {
+ OSL_ENSURE( false, "lclConvertCustomDash - unexpected empty custom dash" );
+ lclSetDashData( orLineDash, 0, 0, 1, 4, 3 );
+ return;
+ }
+
+ // count dashes and dots (stops equal or less than 2 are assumed to be dots)
+ sal_Int16 nDots = 0;
+ sal_Int32 nDotLen = 0;
+ sal_Int16 nDashes = 0;
+ sal_Int32 nDashLen = 0;
+ sal_Int32 nDistance = 0;
+ for( LineProperties::DashStopVector::const_iterator aIt = rCustomDash.begin(), aEnd = rCustomDash.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->first <= 2 )
+ {
+ ++nDots;
+ nDotLen += aIt->first;
+ }
+ else
+ {
+ ++nDashes;
+ nDashLen += aIt->first;
+ }
+ nDistance += aIt->second;
+ }
+ orLineDash.DotLen = (nDots > 0) ? ::std::max< sal_Int32 >( nDotLen / nDots, 1 ) : 0;
+ orLineDash.Dots = nDots;
+ orLineDash.DashLen = (nDashes > 0) ? ::std::max< sal_Int32 >( nDashLen / nDashes, 1 ) : 0;
+ orLineDash.Dashes = nDashes;
+ orLineDash.Distance = ::std::max< sal_Int32 >( nDistance / rCustomDash.size(), 1 );
+}
+
+DashStyle lclGetDashStyle( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_rnd: return DashStyle_ROUNDRELATIVE;
+ case XML_sq: return DashStyle_RECTRELATIVE;
+ case XML_flat: return DashStyle_RECT;
+ }
+ return DashStyle_ROUNDRELATIVE;
+}
+
+LineJoint lclGetLineJoint( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_round: return LineJoint_ROUND;
+ case XML_bevel: return LineJoint_BEVEL;
+ case XML_miter: return LineJoint_MITER;
+ }
+ return LineJoint_ROUND;
+}
+
+const sal_Int32 OOX_ARROWSIZE_SMALL = 0;
+const sal_Int32 OOX_ARROWSIZE_MEDIUM = 1;
+const sal_Int32 OOX_ARROWSIZE_LARGE = 2;
+
+sal_Int32 lclGetArrowSize( sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_sm: return OOX_ARROWSIZE_SMALL;
+ case XML_med: return OOX_ARROWSIZE_MEDIUM;
+ case XML_lg: return OOX_ARROWSIZE_LARGE;
+ }
+ return OOX_ARROWSIZE_MEDIUM;
+}
+
+// ----------------------------------------------------------------------------
+
+void lclPushMarkerProperties( PropertyMap& rPropMap, const LineArrowProperties& rArrowProps,
+ ModelObjectHelper& rModelObjHelper, const LinePropertyIds& rPropIds, sal_Int32 nLineWidth, bool bLineEnd )
+{
+ PolyPolygonBezierCoords aMarker;
+ OUString aMarkerName;
+ sal_Int32 nMarkerWidth = 0;
+ bool bMarkerCenter = false;
+
+ OUStringBuffer aBuffer;
+ sal_Int32 nArrowType = rArrowProps.moArrowType.get( XML_none );
+ switch( nArrowType )
+ {
+ case XML_triangle:
+ aBuffer.append( CREATE_OUSTRING( "msArrowEnd" ) );
+ break;
+ case XML_arrow:
+ aBuffer.append( CREATE_OUSTRING( "msArrowOpenEnd" ) );
+ break;
+ case XML_stealth:
+ aBuffer.append( CREATE_OUSTRING( "msArrowStealthEnd" ) );
+ break;
+ case XML_diamond:
+ aBuffer.append( CREATE_OUSTRING( "msArrowDiamondEnd" ) );
+ bMarkerCenter = true;
+ break;
+ case XML_oval:
+ aBuffer.append( CREATE_OUSTRING( "msArrowOvalEnd" ) );
+ bMarkerCenter = true;
+ break;
+ }
+
+ if( aBuffer.getLength() > 0 )
+ {
+ sal_Int32 nLength = lclGetArrowSize( rArrowProps.moArrowLength.get( XML_med ) );
+ sal_Int32 nWidth = lclGetArrowSize( rArrowProps.moArrowWidth.get( XML_med ) );
+
+ sal_Int32 nNameIndex = nWidth * 3 + nLength + 1;
+ aBuffer.append( sal_Unicode( ' ' ) ).append( nNameIndex );
+ aMarkerName = aBuffer.makeStringAndClear();
+
+ bool bIsArrow = nArrowType == XML_arrow;
+ double fArrowLength = 1.0;
+ switch( nLength )
+ {
+ case OOX_ARROWSIZE_SMALL: fArrowLength = (bIsArrow ? 3.5 : 2.0); break;
+ case OOX_ARROWSIZE_MEDIUM: fArrowLength = (bIsArrow ? 4.5 : 3.0); break;
+ case OOX_ARROWSIZE_LARGE: fArrowLength = (bIsArrow ? 6.0 : 5.0); break;
+ }
+ double fArrowWidth = 1.0;
+ switch( nWidth )
+ {
+ case OOX_ARROWSIZE_SMALL: fArrowWidth = (bIsArrow ? 3.5 : 2.0); break;
+ case OOX_ARROWSIZE_MEDIUM: fArrowWidth = (bIsArrow ? 4.5 : 3.0); break;
+ case OOX_ARROWSIZE_LARGE: fArrowWidth = (bIsArrow ? 6.0 : 5.0); break;
+ }
+ // set arrow width relative to line width (convert line width from EMUs to 1/100 mm)
+ sal_Int32 nApiLineWidth = ::std::max< sal_Int32 >( GetCoordinate( nLineWidth ), 70 );
+ nMarkerWidth = static_cast< sal_Int32 >( fArrowWidth * nApiLineWidth );
+
+ // test if the arrow already exists, do not create it again in this case
+ if( !rPropIds.mbNamedLineMarker || !rModelObjHelper.hasLineMarker( aMarkerName ) )
+ {
+// pass X and Y as percentage to OOX_ARROW_POINT
+#define OOX_ARROW_POINT( x, y ) Point( static_cast< sal_Int32 >( fArrowWidth * x ), static_cast< sal_Int32 >( fArrowLength * y ) )
+
+ ::std::vector< Point > aPoints;
+ switch( rArrowProps.moArrowType.get() )
+ {
+ case XML_triangle:
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 100, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 0, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ break;
+ case XML_arrow:
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 100, 91 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 85, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 36 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 15, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 0, 91 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ break;
+ case XML_stealth:
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 100, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 60 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 0, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ break;
+ case XML_diamond:
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 100, 50 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 0, 50 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ break;
+ case XML_oval:
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 75, 7 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 93, 25 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 100, 50 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 93, 75 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 75, 93 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 100 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 25, 93 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 7, 75 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 0, 50 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 7, 25 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 25, 7 ) );
+ aPoints.push_back( OOX_ARROW_POINT( 50, 0 ) );
+ break;
+ }
+#undef OOX_ARROW_POINT
+
+ OSL_ENSURE( !aPoints.empty(), "ApiLineMarkerProperties::ApiLineMarkerProperties - missing arrow coordinates" );
+ if( !aPoints.empty() )
+ {
+ aMarker.Coordinates.realloc( 1 );
+ aMarker.Coordinates[ 0 ] = ContainerHelper::vectorToSequence( aPoints );
+
+ ::std::vector< PolygonFlags > aFlags( aPoints.size(), PolygonFlags_NORMAL );
+ aMarker.Flags.realloc( 1 );
+ aMarker.Flags[ 0 ] = ContainerHelper::vectorToSequence( aFlags );
+
+ if( rPropIds.mbNamedLineMarker && !rModelObjHelper.insertLineMarker( aMarkerName, aMarker ) )
+ aMarkerName = OUString();
+ }
+ else
+ {
+ aMarkerName = OUString();
+ }
+ }
+ }
+
+ // push the properties (filled aMarkerName indicates valid marker)
+ if( aMarkerName.getLength() > 0 )
+ {
+ if( bLineEnd )
+ {
+ if( rPropIds.mbNamedLineMarker )
+ rPropMap.setProperty( rPropIds[ LineEndId ], aMarkerName );
+ else
+ rPropMap.setProperty( rPropIds[ LineEndId ], aMarker );
+ rPropMap.setProperty( rPropIds[ LineEndWidthId ], nMarkerWidth );
+ rPropMap.setProperty( rPropIds[ LineEndCenterId ], bMarkerCenter );
+ }
+ else
+ {
+ if( rPropIds.mbNamedLineMarker )
+ rPropMap.setProperty( rPropIds[ LineStartId ], aMarkerName );
+ else
+ rPropMap.setProperty( rPropIds[ LineStartId ], aMarker );
+ rPropMap.setProperty( rPropIds[ LineStartWidthId ], nMarkerWidth );
+ rPropMap.setProperty( rPropIds[ LineStartCenterId ], bMarkerCenter );
+ }
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+LinePropertyIds::LinePropertyIds( const sal_Int32* pnPropertyIds, bool bNamedLineDash, bool bNamedLineMarker ) :
+ mpnPropertyIds( pnPropertyIds ),
+ mbNamedLineDash( bNamedLineDash ),
+ mbNamedLineMarker( bNamedLineMarker )
+{
+ OSL_ENSURE( mpnPropertyIds != 0, "LinePropertyIds::LinePropertyIds - missing property identifiers" );
+}
+
+// ============================================================================
+
+void LineArrowProperties::assignUsed( const LineArrowProperties& rSourceProps )
+{
+ moArrowType.assignIfUsed( rSourceProps.moArrowType );
+ moArrowWidth.assignIfUsed( rSourceProps.moArrowWidth );
+ moArrowLength.assignIfUsed( rSourceProps.moArrowLength );
+}
+
+// ============================================================================
+
+LinePropertyIds LineProperties::DEFAULT_IDS( spnDefaultLineIds, false, true );
+
+void LineProperties::assignUsed( const LineProperties& rSourceProps )
+{
+ maStartArrow.assignUsed( rSourceProps.maStartArrow );
+ maEndArrow.assignUsed( rSourceProps.maEndArrow );
+ maLineFill.assignUsed( rSourceProps.maLineFill );
+ if( !rSourceProps.maCustomDash.empty() )
+ maCustomDash = rSourceProps.maCustomDash;
+ moLineWidth.assignIfUsed( rSourceProps.moLineWidth );
+ moPresetDash.assignIfUsed( rSourceProps.moPresetDash );
+ moLineCompound.assignIfUsed( rSourceProps.moLineCompound );
+ moLineCap.assignIfUsed( rSourceProps.moLineCap );
+ moLineJoint.assignIfUsed( rSourceProps.moLineJoint );
+}
+
+void LineProperties::pushToPropMap( PropertyMap& rPropMap, ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const
+{
+ // line fill type must exist, otherwise ignore other properties
+ if( maLineFill.moFillType.has() )
+ {
+ // line style (our core only supports none and solid)
+ LineStyle eLineStyle = (maLineFill.moFillType.get() == XML_noFill) ? LineStyle_NONE : LineStyle_SOLID;
+
+ // create line dash from preset dash token (not for invisible line)
+ if( (eLineStyle != LineStyle_NONE) && (moPresetDash.differsFrom( XML_solid ) || (!moPresetDash && !maCustomDash.empty())) )
+ {
+ LineDash aLineDash;
+ aLineDash.Style = lclGetDashStyle( moLineCap.get( XML_rnd ) );
+
+ // convert preset dash or custom dash
+ if( moPresetDash.has() )
+ lclConvertPresetDash( aLineDash, moPresetDash.get() );
+ else
+ lclConvertCustomDash( aLineDash, maCustomDash );
+
+ // convert relative dash/dot length to absolute length
+ sal_Int32 nLineWidth = GetCoordinate( moLineWidth.get( 103500 ) );
+ aLineDash.DotLen *= nLineWidth;
+ aLineDash.DashLen *= nLineWidth;
+ aLineDash.Distance *= nLineWidth;
+
+ if( rPropIds.mbNamedLineDash )
+ {
+ OUString aDashName = rModelObjHelper.insertLineDash( aLineDash );
+ if( aDashName.getLength() > 0 )
+ {
+ rPropMap.setProperty( rPropIds[ LineDashId ], aDashName );
+ eLineStyle = LineStyle_DASH;
+ }
+ }
+ else
+ {
+ rPropMap.setProperty( rPropIds[ LineDashId ], aLineDash );
+ eLineStyle = LineStyle_DASH;
+ }
+ }
+
+ // set final line style property
+ rPropMap.setProperty( rPropIds[ LineStyleId ], eLineStyle );
+
+ // line joint type
+ if( moLineJoint.has() )
+ rPropMap.setProperty( rPropIds[ LineJointId ], lclGetLineJoint( moLineJoint.get() ) );
+
+ // convert line width from EMUs to 1/100 mm
+ if( moLineWidth.has() )
+ rPropMap.setProperty( rPropIds[ LineWidthId ], GetCoordinate( moLineWidth.get() ) );
+
+ // line color and transparence
+ Color aLineColor = maLineFill.getBestSolidColor();
+ if( aLineColor.isUsed() )
+ {
+ rPropMap.setProperty( rPropIds[ LineColorId ], aLineColor.getColor( rGraphicHelper, nPhClr ) );
+ if( aLineColor.hasTransparence() )
+ rPropMap.setProperty( rPropIds[ LineTransparenceId ], aLineColor.getTransparence() );
+ }
+
+ // line markers
+ lclPushMarkerProperties( rPropMap, maStartArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), false );
+ lclPushMarkerProperties( rPropMap, maEndArrow, rModelObjHelper, rPropIds, moLineWidth.get( 0 ), true );
+ }
+}
+
+void LineProperties::pushToPropSet( PropertySet& rPropSet, ModelObjectHelper& rModelObjHelper,
+ const GraphicHelper& rGraphicHelper, const LinePropertyIds& rPropIds, sal_Int32 nPhClr ) const
+{
+ PropertyMap aPropMap;
+ pushToPropMap( aPropMap, rModelObjHelper, rGraphicHelper, rPropIds, nPhClr );
+ rPropSet.setProperties( aPropMap );
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/linepropertiescontext.cxx b/oox/source/drawingml/linepropertiescontext.cxx
new file mode 100644
index 000000000000..a200b60f9e4b
--- /dev/null
+++ b/oox/source/drawingml/linepropertiescontext.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/linepropertiescontext.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+// CT_LineProperties
+
+namespace oox { namespace drawingml {
+// ---------------------------------------------------------------------
+
+LinePropertiesContext::LinePropertiesContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs,
+ LineProperties& rLineProperties ) throw()
+: ContextHandler( rParent )
+, mrLineProperties( rLineProperties )
+{
+ AttributeList aAttribs( xAttribs );
+ mrLineProperties.moLineWidth = aAttribs.getInteger( XML_w );
+ mrLineProperties.moLineCompound = aAttribs.getToken( XML_cmpd );
+ mrLineProperties.moLineCap = aAttribs.getToken( XML_cap );
+}
+
+LinePropertiesContext::~LinePropertiesContext()
+{
+}
+
+Reference< XFastContextHandler > LinePropertiesContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ AttributeList aAttribs( xAttribs );
+ switch( nElement )
+ {
+ // LineFillPropertiesGroup
+ case A_TOKEN( noFill ):
+ case A_TOKEN( solidFill ):
+ case A_TOKEN( gradFill ):
+ case A_TOKEN( pattFill ):
+ xRet = FillPropertiesContext::createFillContext( *this, nElement, xAttribs, mrLineProperties.maLineFill );
+ break;
+
+ // LineDashPropertiesGroup
+ case A_TOKEN( prstDash ): // CT_PresetLineDashProperties
+ mrLineProperties.moPresetDash = aAttribs.getToken( XML_val );
+ break;
+ case A_TOKEN( custDash ): // CT_DashStopList
+ xRet = this;
+ break;
+ case A_TOKEN( ds ):
+ mrLineProperties.maCustomDash.push_back( LineProperties::DashStop(
+ aAttribs.getInteger( XML_d, 0 ), aAttribs.getInteger( XML_sp, 0 ) ) );
+ break;
+
+ // LineJoinPropertiesGroup
+ case A_TOKEN( round ):
+ case A_TOKEN( bevel ):
+ case A_TOKEN( miter ):
+ mrLineProperties.moLineJoint = getBaseToken( nElement );
+ break;
+
+ case A_TOKEN( headEnd ): // CT_LineEndProperties
+ case A_TOKEN( tailEnd ): // CT_LineEndProperties
+ { // ST_LineEndType
+ bool bTailEnd = nElement == A_TOKEN( tailEnd );
+ LineArrowProperties& rArrowProps = bTailEnd ? mrLineProperties.maEndArrow : mrLineProperties.maStartArrow;
+ rArrowProps.moArrowType = aAttribs.getToken( XML_type );
+ rArrowProps.moArrowWidth = aAttribs.getToken( XML_w );
+ rArrowProps.moArrowLength = aAttribs.getToken( XML_len );
+ }
+ break;
+ }
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/makefile.mk b/oox/source/drawingml/makefile.mk
new file mode 100644
index 000000000000..e2d4ea6b8f3d
--- /dev/null
+++ b/oox/source/drawingml/makefile.mk
@@ -0,0 +1,91 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=drawingml
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/clrscheme.obj\
+ $(SLO)$/clrschemecontext.obj\
+ $(SLO)$/color.obj\
+ $(SLO)$/colorchoicecontext.obj\
+ $(SLO)$/connectorshapecontext.obj\
+ $(SLO)$/customshapegeometry.obj\
+ $(SLO)$/customshapeproperties.obj\
+ $(SLO)$/drawingmltypes.obj\
+ $(SLO)$/embeddedwavaudiofile.obj\
+ $(SLO)$/fillproperties.obj\
+ $(SLO)$/fillpropertiesgroupcontext.obj\
+ $(SLO)$/graphicshapecontext.obj\
+ $(SLO)$/guidcontext.obj\
+ $(SLO)$/hyperlinkcontext.obj\
+ $(SLO)$/lineproperties.obj\
+ $(SLO)$/linepropertiescontext.obj\
+ $(SLO)$/objectdefaultcontext.obj\
+ $(SLO)$/shape.obj\
+ $(SLO)$/shapecontext.obj\
+ $(SLO)$/shapegroupcontext.obj\
+ $(SLO)$/shapepropertiescontext.obj\
+ $(SLO)$/shapestylecontext.obj\
+ $(SLO)$/spdefcontext.obj\
+ $(SLO)$/textbody.obj\
+ $(SLO)$/textbodycontext.obj\
+ $(SLO)$/textbodyproperties.obj\
+ $(SLO)$/textbodypropertiescontext.obj\
+ $(SLO)$/textcharacterproperties.obj\
+ $(SLO)$/textcharacterpropertiescontext.obj\
+ $(SLO)$/textfield.obj\
+ $(SLO)$/textfieldcontext.obj\
+ $(SLO)$/textfont.obj\
+ $(SLO)$/textliststyle.obj \
+ $(SLO)$/textliststylecontext.obj\
+ $(SLO)$/textparagraph.obj\
+ $(SLO)$/textparagraphproperties.obj\
+ $(SLO)$/textparagraphpropertiescontext.obj\
+ $(SLO)$/textrun.obj\
+ $(SLO)$/textspacingcontext.obj\
+ $(SLO)$/texttabstoplistcontext.obj\
+ $(SLO)$/theme.obj\
+ $(SLO)$/themeelementscontext.obj\
+ $(SLO)$/themefragmenthandler.obj\
+ $(SLO)$/transform2dcontext.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..d233379f9b02
--- /dev/null
+++ b/oox/source/drawingml/objectdefaultcontext.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/objectdefaultcontext.hxx"
+#include "oox/drawingml/spdefcontext.hxx"
+#include "oox/drawingml/theme.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( ContextHandler& rParent, Theme& rTheme )
+: ContextHandler( rParent )
+, mrTheme( rTheme )
+{
+}
+
+Reference< XFastContextHandler > objectDefaultContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& /* xAttribs */ ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ case A_TOKEN( spDef ):
+ return new spDefContext( *this, mrTheme.getSpDef() );
+ case A_TOKEN( lnDef ):
+ return new spDefContext( *this, mrTheme.getLnDef() );
+ case A_TOKEN( txDef ):
+ return new spDefContext( *this, mrTheme.getTxDef() );
+ }
+ return 0;
+}
+
+} }
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
new file mode 100644
index 000000000000..61956c068deb
--- /dev/null
+++ b/oox/source/drawingml/shape.cxx
@@ -0,0 +1,624 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/shape.hxx"
+#include "oox/drawingml/customshapeproperties.hxx"
+#include "oox/drawingml/theme.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/textbody.hxx"
+#include "oox/drawingml/table/tableproperties.hxx"
+#include "oox/drawingml/chart/chartconverter.hxx"
+#include "oox/drawingml/chart/chartspacefragment.hxx"
+#include "oox/drawingml/chart/chartspacemodel.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/propertyset.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 <com/sun/star/chart2/XChartDocument.hpp>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <com/sun/star/document/XActionLockable.hpp>
+
+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 )
+, mpGraphicPropertiesPtr( new GraphicProperties )
+, mpCustomShapePropertiesPtr( new CustomShapeProperties )
+, mpMasterTextListStyle( new TextListStyle )
+, mnSubType( 0 )
+, mnSubTypeIndex( -1 )
+, meFrameType( FRAMETYPE_GENERIC )
+, mnRotation( 0 )
+, mbFlipH( false )
+, mbFlipV( false )
+, mbHidden( false )
+{
+ if ( pServiceName )
+ msServiceName = OUString::createFromAscii( pServiceName );
+ setDefaults();
+}
+
+Shape::~Shape()
+{
+}
+
+table::TablePropertiesPtr Shape::getTableProperties()
+{
+ if ( !mpTablePropertiesPtr.get() )
+ mpTablePropertiesPtr.reset( new table::TableProperties() );
+ return mpTablePropertiesPtr;
+}
+
+void Shape::setDefaults()
+{
+ maShapeProperties[ PROP_TextAutoGrowHeight ] <<= false;
+ maShapeProperties[ PROP_TextWordWrap ] <<= true;
+ maShapeProperties[ PROP_TextLeftDistance ] <<= static_cast< sal_Int32 >( 250 );
+ maShapeProperties[ PROP_TextUpperDistance ] <<= static_cast< sal_Int32 >( 125 );
+ maShapeProperties[ PROP_TextRightDistance ] <<= static_cast< sal_Int32 >( 250 );
+ maShapeProperties[ PROP_TextLowerDistance ] <<= static_cast< sal_Int32 >( 125 );
+ maShapeProperties[ PROP_CharHeight ] <<= static_cast< float >( 18.0 );
+}
+
+::oox::vml::OleObjectInfo& Shape::setOleObjectType()
+{
+ OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" );
+ meFrameType = FRAMETYPE_OLEOBJECT;
+ mxOleObjectInfo.reset( new ::oox::vml::OleObjectInfo( true ) );
+ return *mxOleObjectInfo;
+}
+
+ChartShapeInfo& Shape::setChartType( bool bEmbedShapes )
+{
+ OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" );
+ meFrameType = FRAMETYPE_CHART;
+ msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" );
+ mxChartShapeInfo.reset( new ChartShapeInfo( bEmbedShapes ) );
+ return *mxChartShapeInfo;
+}
+
+void Shape::setDiagramType()
+{
+ OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" );
+ meFrameType = FRAMETYPE_DIAGRAM;
+ msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" );
+ mnSubType = 0;
+}
+
+void Shape::setTableType()
+{
+ OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" );
+ meFrameType = FRAMETYPE_TABLE;
+ msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.TableShape" );
+ mnSubType = 0;
+}
+
+void Shape::setServiceName( const sal_Char* pServiceName )
+{
+ if ( pServiceName )
+ msServiceName = OUString::createFromAscii( pServiceName );
+}
+
+
+const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const
+{
+ ShapeStyleRefMap::const_iterator aIt = maShapeStyleRefs.find( nRefType );
+ return (aIt == maShapeStyleRefs.end()) ? 0 : &aIt->second;
+}
+
+void Shape::addShape(
+ ::oox::core::XmlFilterBase& rFilterBase,
+ const Theme* pTheme,
+ const Reference< XShapes >& rxShapes,
+ const awt::Rectangle* pShapeRect,
+ ShapeIdMap* pShapeMap )
+{
+ try
+ {
+ rtl::OUString sServiceName( msServiceName );
+ if( sServiceName.getLength() )
+ {
+ Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, sal_False ) );
+
+ if( pShapeMap && msId.getLength() )
+ {
+ (*pShapeMap)[ 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() )
+ addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap );
+ }
+ Reference< document::XActionLockable > xLockable( mxShape, UNO_QUERY );
+ if( xLockable.is() )
+ xLockable->removeActionLock();
+ }
+ catch( const Exception& )
+ {
+ }
+}
+
+void Shape::applyShapeReference( const 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() ) );
+ mpTablePropertiesPtr = table::TablePropertiesPtr( rReferencedShape.mpTablePropertiesPtr.get() ? new table::TableProperties( *rReferencedShape.mpTablePropertiesPtr.get() ) : NULL );
+ mpMasterTextListStyle = TextListStylePtr( new TextListStyle( *rReferencedShape.mpMasterTextListStyle.get() ) );
+ maShapeStyleRefs = rReferencedShape.maShapeStyleRefs;
+ maSize = rReferencedShape.maSize;
+ maPosition = rReferencedShape.maPosition;
+ mnRotation = rReferencedShape.mnRotation;
+ mbFlipH = rReferencedShape.mbFlipH;
+ mbFlipV = rReferencedShape.mbFlipV;
+ mbHidden = rReferencedShape.mbHidden;
+}
+
+// for group shapes, the following method is also adding each child
+void Shape::addChildren(
+ XmlFilterBase& rFilterBase,
+ Shape& rMaster,
+ const Theme* pTheme,
+ const Reference< XShapes >& rxShapes,
+ const awt::Rectangle& rClientRect,
+ ShapeIdMap* pShapeMap )
+{
+ // 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.maChildren.begin() );
+ while( aIter != rMaster.maChildren.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.maChildren.begin();
+ while( aIter != rMaster.maChildren.end() )
+ {
+ awt::Rectangle aShapeRect;
+ awt::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, pTheme, rxShapes, pShapeRect, pShapeMap );
+ }
+}
+
+Reference< XShape > Shape::createAndInsert(
+ ::oox::core::XmlFilterBase& rFilterBase,
+ const rtl::OUString& rServiceName,
+ const Theme* pTheme,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const awt::Rectangle* pShapeRect,
+ sal_Bool bClearText )
+{
+ awt::Size aSize( pShapeRect ? awt::Size( pShapeRect->Width, pShapeRect->Height ) : maSize );
+ awt::Point aPosition( pShapeRect ? awt::Point( pShapeRect->X, pShapeRect->Y ) : maPosition );
+ awt::Rectangle aShapeRectHmm( aPosition.X / 360, aPosition.Y / 360, aSize.Width / 360, aSize.Height / 360 );
+
+ OUString aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm );
+ sal_Bool bIsCustomShape = aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShape" ) );
+
+ basegfx::B2DHomMatrix aTransformation;
+ 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( !bIsCustomShape && ( 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 ( aServiceName == 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;
+
+ maShapeProperties[ PROP_PolyPolygon ] <<= aPolyPolySequence;
+ }
+ else if ( aServiceName == 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() ) );
+
+ maShapeProperties[ PROP_StartPosition ] <<= aAWTStartPosition;
+ maShapeProperties[ PROP_EndPosition ] <<= 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);
+
+ maShapeProperties[ PROP_Transformation ] <<= aMatrix;
+ }
+ Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
+ if ( !mxShape.is() )
+ mxShape = Reference< drawing::XShape >( xServiceFact->createInstance( aServiceName ), UNO_QUERY_THROW );
+
+ Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
+ if( mxShape.is() && xSet.is() )
+ {
+ if( msName.getLength() )
+ {
+ Reference< container::XNamed > xNamed( mxShape, UNO_QUERY );
+ if( xNamed.is() )
+ xNamed->setName( msName );
+ }
+ rxShapes->add( mxShape );
+
+ if ( mbHidden )
+ {
+ const OUString sHidden( CREATE_OUSTRING( "Visible" ) );
+ xSet->setPropertyValue( sHidden, Any( !mbHidden ) );
+ }
+
+ Reference< document::XActionLockable > xLockable( mxShape, UNO_QUERY );
+ if( xLockable.is() )
+ xLockable->addActionLock();
+
+ // sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape
+ if ( bClearText )
+ {
+ uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
+ if ( xText.is() )
+ {
+ OUString aEmpty;
+ xText->setString( aEmpty );
+ }
+ }
+
+ ModelObjectHelper& rModelObjectHelper = rFilterBase.getModelObjectHelper();
+ const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper();
+
+ LineProperties aLineProperties;
+ aLineProperties.maLineFill.moFillType = XML_noFill;
+ sal_Int32 nLinePhClr = -1;
+ FillProperties aFillProperties;
+ aFillProperties.moFillType = XML_noFill;
+ sal_Int32 nFillPhClr = -1;
+
+ if( pTheme )
+ {
+ if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
+ {
+ if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
+ aLineProperties.assignUsed( *pLineProps );
+ nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper );
+ }
+ if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
+ {
+ if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) )
+ aFillProperties.assignUsed( *pFillProps );
+ nFillPhClr = pFillRef->maPhClr.getColor( rGraphicHelper );
+ }
+// if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_fillRef ) )
+// {
+// if( const EffectProperties* pEffectProps = pTheme->getEffectStyle( pEffectRef->mnThemedIdx ) )
+// aEffectProperties.assignUsed( *pEffectProps );
+// nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper );
+// }
+ }
+
+ aLineProperties.assignUsed( getLineProperties() );
+ aFillProperties.assignUsed( getFillProperties() );
+
+ PropertyMap aShapeProperties;
+ PropertyMap::const_iterator aShapePropIter;
+
+ // add properties from textbody to shape properties
+ if( mpTextBody.get() )
+ {
+ for ( aShapePropIter = mpTextBody->getTextProperties().maPropertyMap.begin();
+ aShapePropIter != mpTextBody->getTextProperties().maPropertyMap.end(); aShapePropIter++ )
+ aShapeProperties[ (*aShapePropIter).first ] = (*aShapePropIter).second;
+ }
+
+ aShapeProperties.insert( getShapeProperties().begin(), getShapeProperties().end() );
+ // applying properties
+ PropertySet aPropSet( xSet );
+ if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) )
+ mpGraphicPropertiesPtr->pushToPropSet( aPropSet, rGraphicHelper );
+ if ( mpTablePropertiesPtr.get() && ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.TableShape" ) ) )
+ mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle );
+ aFillProperties.pushToPropSet( aPropSet, rModelObjectHelper, rGraphicHelper, FillProperties::DEFAULT_IDS, mnRotation, nFillPhClr );
+ aLineProperties.pushToPropSet( aPropSet, rModelObjectHelper, rGraphicHelper, LineProperties::DEFAULT_IDS, nLinePhClr );
+
+ // 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() );
+ const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight );
+ if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) )
+ if( /*const Any* pAutoGrowHeight =*/ aShapeProperties.getProperty( PROP_TextAutoGrowHeight ) )
+ xSet->setPropertyValue( rPropName, Any( false ) );
+
+ // do not set properties at a group shape (this causes assertions from svx)
+ if( aServiceName != OUString::createFromAscii( "com.sun.star.drawing.GroupShape" ) )
+ aPropSet.setProperties( aShapeProperties );
+
+ if( bIsCustomShape )
+ {
+ if ( mbFlipH )
+ mpCustomShapePropertiesPtr->setMirroredX( sal_True );
+ if ( mbFlipV )
+ mpCustomShapePropertiesPtr->setMirroredY( sal_True );
+ mpCustomShapePropertiesPtr->pushToPropSet( rFilterBase, xSet, mxShape );
+ }
+
+ // in some cases, we don't have any text body.
+ if( getTextBody() )
+ {
+ Reference < XText > xText( mxShape, UNO_QUERY );
+ if ( xText.is() ) // not every shape is supporting an XText interface (e.g. GroupShape)
+ {
+ TextCharacterProperties aCharStyleProperties;
+ if( const ShapeStyleRef* pFontRef = getShapeStyleRef( XML_fontRef ) )
+ {
+ if( pTheme )
+ if( const TextCharacterProperties* pCharProps = pTheme->getFontStyle( pFontRef->mnThemedIdx ) )
+ aCharStyleProperties.assignUsed( *pCharProps );
+ aCharStyleProperties.maCharColor.assignIfUsed( pFontRef->maPhClr );
+ }
+
+ Reference < XTextCursor > xAt = xText->createTextCursor();
+ getTextBody()->insertAt( rFilterBase, xText, xAt, aCharStyleProperties, mpMasterTextListStyle );
+ }
+ }
+ if( xLockable.is() )
+ xLockable->removeActionLock();
+ }
+
+ if( mxShape.is() )
+ finalizeXShape( rFilterBase, rxShapes );
+
+ return mxShape;
+}
+
+// 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++;
+ }
+}
+
+void Shape::setTextBody(const TextBodyPtr & pTextBody)
+{
+ mpTextBody = pTextBody;
+}
+
+
+TextBodyPtr Shape::getTextBody()
+{
+ return mpTextBody;
+}
+
+void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle )
+{
+ mpMasterTextListStyle = pMasterTextListStyle;
+}
+
+OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const Rectangle& rShapeRect )
+{
+ OUString aServiceName = rServiceName;
+ switch( meFrameType )
+ {
+ case FRAMETYPE_OLEOBJECT:
+ {
+ Size aOleSize( rShapeRect.Width, rShapeRect.Height );
+ if( rFilter.getOleObjectHelper().importOleObject( maShapeProperties, *mxOleObjectInfo, aOleSize ) )
+ aServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" );
+
+ // get the path to the representation graphic
+ OUString aGraphicPath;
+ if( mxOleObjectInfo->maShapeId.getLength() > 0 )
+ if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() )
+ if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) )
+ aGraphicPath = pVmlShape->getGraphicPath();
+
+ // import and store the graphic
+ if( aGraphicPath.getLength() > 0 )
+ {
+ Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
+ if( xGraphic.is() )
+ maShapeProperties[ PROP_Graphic ] <<= xGraphic;
+ }
+ }
+ break;
+
+ default:;
+ }
+ return aServiceName;
+}
+
+void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
+{
+ switch( meFrameType )
+ {
+ case FRAMETYPE_CHART:
+ {
+ OSL_ENSURE( mxChartShapeInfo->maFragmentPath.getLength() > 0, "Shape::finalizeXShape - missing chart fragment" );
+ if( mxShape.is() && (mxChartShapeInfo->maFragmentPath.getLength() > 0) ) try
+ {
+ // set the chart2 OLE class ID at the OLE shape
+ PropertySet aShapeProp( mxShape );
+ aShapeProp.setProperty( PROP_CLSID, CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) );
+
+ // get the XModel interface of the embedded object from the OLE shape
+ Reference< frame::XModel > xDocModel;
+ aShapeProp.getProperty( xDocModel, PROP_Model );
+ Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
+
+ // load the chart data from the XML fragment
+ chart::ChartSpaceModel aModel;
+ rFilter.importFragment( new chart::ChartSpaceFragment( rFilter, mxChartShapeInfo->maFragmentPath, aModel ) );
+
+ // convert imported chart model to chart document
+ Reference< drawing::XShapes > xExternalPage;
+ if( !mxChartShapeInfo->mbEmbedShapes )
+ xExternalPage = rxShapes;
+ rFilter.getChartConverter().convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ break;
+
+ default:;
+ }
+}
+
+// ============================================================================
+
+} }
diff --git a/oox/source/drawingml/shapecontext.cxx b/oox/source/drawingml/shapecontext.cxx
new file mode 100644
index 000000000000..d4781fdaa436
--- /dev/null
+++ b/oox/source/drawingml/shapecontext.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/helper/attributelist.hxx"
+#include "oox/drawingml/shapecontext.hxx"
+#include "oox/drawingml/shapestylecontext.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"
+
+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( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pShapePtr )
+: ContextHandler( rParent )
+, 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( getBaseToken( aElementToken ) )
+ {
+ // nvSpPr CT_ShapeNonVisual begin
+// case XML_drElemPr:
+// break;
+ case XML_cNvPr:
+ {
+ AttributeList aAttribs( xAttribs );
+ mpShapePtr->setHidden( aAttribs.getBool( XML_hidden, false ) );
+ 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->setSubTypeIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
+ break;
+ // nvSpPr CT_ShapeNonVisual end
+
+ case XML_spPr:
+ xRet = new ShapePropertiesContext( *this, *mpShapePtr );
+ break;
+
+ case XML_style:
+ xRet = new ShapeStyleContext( *this, *mpShapePtr );
+ break;
+
+ case XML_txBody:
+ {
+ TextBodyPtr xTextBody( new TextBody );
+ mpShapePtr->setTextBody( xTextBody );
+ xRet = new TextBodyContext( *this, *xTextBody );
+ 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..183302667066
--- /dev/null
+++ b/oox/source/drawingml/shapegroupcontext.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/helper/attributelist.hxx"
+#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"
+
+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( ContextHandler& rParent, ShapePtr pMasterShapePtr, ShapePtr pGroupShapePtr )
+: ContextHandler( rParent )
+, 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( getBaseToken( aElementToken ) )
+ {
+ case XML_cNvPr:
+ {
+ AttributeList aAttribs( xAttribs );
+ mpGroupShapePtr->setHidden( aAttribs.getBool( XML_hidden, false ) );
+ 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->setSubTypeIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
+ break;
+ // nvSpPr CT_ShapeNonVisual end
+
+ case XML_grpSpPr:
+ xRet = new ShapePropertiesContext( *this, *mpGroupShapePtr );
+ break;
+ case XML_spPr:
+ xRet = new ShapePropertiesContext( *this, *mpGroupShapePtr );
+ break;
+/*
+ case XML_style:
+ xRet = new ShapeStyleContext( getParser() );
+ break;
+*/
+ case XML_cxnSp: // connector shape
+ xRet.set( new ConnectorShapeContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.ConnectorShape" ) ) ) );
+ break;
+ case XML_grpSp: // group shape
+ xRet.set( new ShapeGroupContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.GroupShape" ) ) ) );
+ break;
+ case XML_sp: // shape
+ xRet.set( new ShapeContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.CustomShape" ) ) ) );
+ break;
+ case XML_pic: // CT_Picture
+ xRet.set( new GraphicShapeContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ) ) );
+ break;
+ case XML_graphicFrame: // CT_GraphicalObjectFrame
+ xRet.set( new GraphicalObjectFrameContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ), true ) );
+ 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..13fd8c421784
--- /dev/null
+++ b/oox/source/drawingml/shapepropertiescontext.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/shapepropertiescontext.hxx"
+
+#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/linepropertiescontext.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/transform2dcontext.hxx"
+#include "oox/drawingml/customshapegeometry.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( ContextHandler& rParent, Shape& rShape )
+: ContextHandler( rParent )
+, mrShape( rShape )
+{
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > ShapePropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ // CT_Transform2D
+ case A_TOKEN( xfrm ):
+ xRet.set( new Transform2DContext( *this, xAttribs, mrShape ) );
+ break;
+
+ // GeometryGroup
+ case A_TOKEN( custGeom ): // custom geometry "CT_CustomGeometry2D"
+ xRet.set( new CustomShapeGeometryContext( *this, xAttribs, *(mrShape.getCustomShapeProperties()) ) );
+ break;
+
+
+ case A_TOKEN( 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( *this, xAttribs, *(mrShape.getCustomShapeProperties()) ) );
+ }
+ break;
+
+ case A_TOKEN( prstTxWarp ):
+ xRet.set( new PresetTextShapeContext( *this, xAttribs, *(mrShape.getCustomShapeProperties()) ) );
+ break;
+
+ // CT_LineProperties
+ case A_TOKEN( ln ):
+ xRet.set( new LinePropertiesContext( *this, xAttribs, mrShape.getLineProperties() ) );
+ break;
+
+ // EffectPropertiesGroup
+ // todo not supported by core
+ case A_TOKEN( effectLst ): // CT_EffectList
+ case A_TOKEN( effectDag ): // CT_EffectContainer
+ break;
+
+ // todo
+ case A_TOKEN( scene3d ): // CT_Scene3D
+ case A_TOKEN( sp3d ): // CT_Shape3D
+ break;
+ }
+
+ // FillPropertiesGroupContext
+ if( !xRet.is() )
+ xRet.set( FillPropertiesContext::createFillContext( *this, aElementToken, xAttribs, mrShape.getFillProperties() ) );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/shapestylecontext.cxx b/oox/source/drawingml/shapestylecontext.cxx
new file mode 100644
index 000000000000..a1ae5df43cda
--- /dev/null
+++ b/oox/source/drawingml/shapestylecontext.cxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/shapestylecontext.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/drawingml/colorchoicecontext.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_ShapeStyle
+// ---------------
+ShapeStyleContext::ShapeStyleContext( ContextHandler& rParent, Shape& rShape )
+: ContextHandler( rParent )
+, 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;
+ AttributeList aAttribs( rxAttributes );
+ switch( aElementToken )
+ {
+ case A_TOKEN( lnRef ) : // CT_StyleMatrixReference
+ case A_TOKEN( fillRef ) : // CT_StyleMatrixReference
+ case A_TOKEN( effectRef ) : // CT_StyleMatrixReference
+ case A_TOKEN( fontRef ) : // CT_FontReference
+ {
+ sal_Int32 nToken = getBaseToken( aElementToken );
+ ShapeStyleRef& rStyleRef = mrShape.getShapeStyleRefs()[ nToken ];
+ rStyleRef.mnThemedIdx = (nToken == XML_fontRef) ? aAttribs.getToken( XML_idx, XML_none ) : aAttribs.getInteger( XML_idx, 0 );
+ xRet.set( new ColorContext( *this, rStyleRef.maPhClr ) );
+ }
+ break;
+ }
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/spdefcontext.cxx b/oox/source/drawingml/spdefcontext.cxx
new file mode 100644
index 000000000000..da86e031ddec
--- /dev/null
+++ b/oox/source/drawingml/spdefcontext.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/spdefcontext.hxx"
+#include "oox/drawingml/shapepropertiescontext.hxx"
+#include "oox/drawingml/textbody.hxx"
+#include "oox/drawingml/textbodypropertiescontext.hxx"
+#include "oox/drawingml/textliststylecontext.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( ContextHandler& rParent, Shape& rDefaultObject )
+: ContextHandler( rParent )
+, mrDefaultObject( rDefaultObject )
+{
+}
+
+Reference< XFastContextHandler > spDefContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case A_TOKEN( spPr ):
+ {
+ xRet = new ShapePropertiesContext( *this, mrDefaultObject );
+ break;
+ }
+ case A_TOKEN( bodyPr ):
+ {
+ TextBodyPtr xTextBody( new TextBody );
+ mrDefaultObject.setTextBody( xTextBody );
+ xRet = new TextBodyPropertiesContext( *this, xAttribs, xTextBody->getTextProperties() );
+ break;
+ }
+ case A_TOKEN( lstStyle ):
+ xRet.set( new TextListStyleContext( *this, *mrDefaultObject.getMasterTextListStyle() ) );
+ break;
+ case A_TOKEN( style ):
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/drawingml/table/makefile.mk b/oox/source/drawingml/table/makefile.mk
new file mode 100644
index 000000000000..fa71971fc278
--- /dev/null
+++ b/oox/source/drawingml/table/makefile.mk
@@ -0,0 +1,62 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=oox
+TARGET=table
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/tablecontext.obj \
+ $(SLO)$/tableproperties.obj \
+ $(SLO)$/tablerow.obj \
+ $(SLO)$/tablerowcontext.obj \
+ $(SLO)$/tablecell.obj \
+ $(SLO)$/tablecellcontext.obj \
+ $(SLO)$/tablestylelist.obj \
+ $(SLO)$/tablestylelistfragmenthandler.obj \
+ $(SLO)$/tablestylecontext.obj \
+ $(SLO)$/tablestyle.obj \
+ $(SLO)$/tablebackgroundstylecontext.obj \
+ $(SLO)$/tablepartstylecontext.obj \
+ $(SLO)$/tablestyletextstylecontext.obj \
+ $(SLO)$/tablestylecellstylecontext.obj \
+ $(SLO)$/tablestylepart.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/drawingml/table/tablebackgroundstylecontext.cxx b/oox/source/drawingml/table/tablebackgroundstylecontext.cxx
new file mode 100644
index 000000000000..075e8ded9b31
--- /dev/null
+++ b/oox/source/drawingml/table/tablebackgroundstylecontext.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/table/tablebackgroundstylecontext.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableBackgroundStyleContext::TableBackgroundStyleContext( ContextHandler& rParent, TableStyle& rTableStyle )
+: ContextHandler( rParent )
+, mrTableStyle( rTableStyle )
+{
+}
+
+TableBackgroundStyleContext::~TableBackgroundStyleContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TableBackgroundStyleContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+
+ AttributeList aAttribs( xAttribs );
+ switch( aElementToken )
+ {
+ // EG_ThemeableFillStyle (choice)
+ case A_TOKEN( fill ): // CT_FillProperties
+ {
+ boost::shared_ptr< FillProperties >& rxFillProperties = mrTableStyle.getBackgroundFillProperties();
+ rxFillProperties.reset( new FillProperties );
+ xRet.set( new FillPropertiesContext( *this, *rxFillProperties ) );
+ }
+ break;
+ case A_TOKEN( fillRef ): // CT_StyleMatrixReference
+ {
+ ShapeStyleRef& rStyleRef = mrTableStyle.getBackgroundFillStyleRef();
+ rStyleRef.mnThemedIdx = aAttribs.getInteger( XML_idx, 0 );
+ xRet.set( new ColorContext( *this, rStyleRef.maPhClr ) );
+ }
+ break;
+
+ // EG_ThemeableEffectStyle (choice)
+ case A_TOKEN( effect ): // CT_EffectProperties
+ break;
+ case A_TOKEN( effectRef ): // CT_StyleMatrixReference
+ break;
+ }
+ if( !xRet.is() )
+ {
+ uno::Reference<XFastContextHandler> xTmp(this);
+ xRet.set( xTmp );
+ }
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx
new file mode 100644
index 000000000000..f381b20d5383
--- /dev/null
+++ b/oox/source/drawingml/table/tablecell.cxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/table/tablecell.hxx"
+#include "oox/drawingml/table/tableproperties.hxx"
+#include "oox/drawingml/textbody.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/propertyset.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/table/XTable.hpp>
+#include <com/sun/star/table/XMergeableCellRange.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/text/XText.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 ::com::sun::star::table::BorderLine;
+using ::com::sun::star::drawing::LineStyle;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableCell::TableCell()
+: mnRowSpan ( 1 )
+, mnGridSpan( 1 )
+, mbhMerge( sal_False )
+, mbvMerge( sal_False )
+, mnMarL( 91440 )
+, mnMarR( 91440 )
+, mnMarT( 45720 )
+, mnMarB( 45720 )
+, mnVertToken( XML_horz )
+, mnAnchorToken( XML_t )
+, mbAnchorCtr( sal_False )
+, mnHorzOverflowToken( XML_clip )
+{
+}
+TableCell::~TableCell()
+{
+}
+
+void applyLineAttributes( const ::oox::core::XmlFilterBase& rFilterBase,
+ Reference< XPropertySet >& rxPropSet, oox::drawingml::LineProperties& rLineProperties,
+ sal_Int32 nPropId )
+{
+ BorderLine aBorderLine( 0, 0, 0, 0 );
+ if( rLineProperties.maLineFill.moFillType.differsFrom( XML_noFill ) )
+ {
+ Color aColor = rLineProperties.maLineFill.getBestSolidColor();
+ aBorderLine.Color = aColor.getColor( rFilterBase.getGraphicHelper() );
+ aBorderLine.OuterLineWidth = static_cast< sal_Int16 >( GetCoordinate( rLineProperties.moLineWidth.get( 0 ) ) / 4 );
+ aBorderLine.InnerLineWidth = static_cast< sal_Int16 >( GetCoordinate( rLineProperties.moLineWidth.get( 0 ) ) / 4 );
+ aBorderLine.LineDistance = 0;
+ }
+
+ PropertySet aPropSet( rxPropSet );
+ aPropSet.setProperty( nPropId, aBorderLine );
+}
+
+void applyBorder( TableStylePart& rTableStylePart, sal_Int32 nLineType, oox::drawingml::LineProperties& rLineProperties )
+{
+ std::map < sal_Int32, ::oox::drawingml::LinePropertiesPtr >& rPartLineBorders( rTableStylePart.getLineBorders() );
+ std::map < sal_Int32, ::oox::drawingml::LinePropertiesPtr >::const_iterator aIter( rPartLineBorders.find( nLineType ) );
+ if ( ( aIter != rPartLineBorders.end() ) && aIter->second.get() )
+ rLineProperties.assignUsed( *aIter->second );
+}
+
+void applyTableStylePart( const ::oox::core::XmlFilterBase& rFilterBase, const Reference < ::com::sun::star::table::XCell >& rxCell, oox::drawingml::FillProperties& rFillProperties,
+ oox::drawingml::LineProperties& rLeftBorder,
+ oox::drawingml::LineProperties& rRightBorder,
+ oox::drawingml::LineProperties& rTopBorder,
+ oox::drawingml::LineProperties& rBottomBorder,
+ oox::drawingml::LineProperties& rTopLeftToBottomRightBorder,
+ oox::drawingml::LineProperties& rBottomLeftToTopRightBorder,
+ TableStylePart& rTableStylePart )
+{
+ boost::shared_ptr< ::oox::drawingml::FillProperties >& rPartFillPropertiesPtr( rTableStylePart.getFillProperties() );
+ if ( rPartFillPropertiesPtr.get() )
+ rFillProperties.assignUsed( *rPartFillPropertiesPtr );
+
+ applyBorder( rTableStylePart, XML_left, rLeftBorder );
+ applyBorder( rTableStylePart, XML_right, rRightBorder );
+ applyBorder( rTableStylePart, XML_top, rTopBorder );
+ applyBorder( rTableStylePart, XML_bottom, rBottomBorder );
+ applyBorder( rTableStylePart, XML_tl2br, rTopLeftToBottomRightBorder );
+ applyBorder( rTableStylePart, XML_tr2bl, rBottomLeftToTopRightBorder );
+
+ TextCharacterProperties aTextCharProps;
+ aTextCharProps.maLatinFont = rTableStylePart.getLatinFont();
+ aTextCharProps.maAsianFont = rTableStylePart.getAsianFont();
+ aTextCharProps.maComplexFont = rTableStylePart.getComplexFont();
+ aTextCharProps.maSymbolFont = rTableStylePart.getSymbolFont();
+ aTextCharProps.maCharColor = rTableStylePart.getTextColor();
+
+ PropertySet aPropSet( rxCell );
+ aTextCharProps.pushToPropSet( aPropSet, rFilterBase );
+}
+
+void applyTableCellProperties( const Reference < ::com::sun::star::table::XCell >& rxCell, const TableCell& rTableCell )
+{
+ static const rtl::OUString sTopBorder( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) );
+ static const rtl::OUString sBottomBorder( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) );
+ static const rtl::OUString sLeftBorder( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) );
+ static const rtl::OUString sRightBorder( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) );
+ static const rtl::OUString sVerticalAdjust( RTL_CONSTASCII_USTRINGPARAM( "TextVerticalAdjust" ) );
+
+ Reference< XPropertySet > xPropSet( rxCell, UNO_QUERY_THROW );
+ xPropSet->setPropertyValue( sTopBorder, Any( static_cast< sal_Int32 >( rTableCell.getTopMargin() / 360 ) ) );
+ xPropSet->setPropertyValue( sRightBorder, Any( static_cast< sal_Int32 >( rTableCell.getRightMargin() / 360 ) ) );
+ xPropSet->setPropertyValue( sLeftBorder, Any( static_cast< sal_Int32 >( rTableCell.getLeftMargin() / 360 ) ) );
+ xPropSet->setPropertyValue( sBottomBorder, Any( static_cast< sal_Int32 >( rTableCell.getBottomMargin() / 360 ) ) );
+
+ drawing::TextVerticalAdjust eVA;
+ switch( rTableCell.getAnchorToken() )
+ {
+ case XML_ctr: eVA = drawing::TextVerticalAdjust_CENTER; break;
+ case XML_b: eVA = drawing::TextVerticalAdjust_BOTTOM; break;
+ case XML_just:
+ case XML_dist:
+ default:
+ case XML_t: eVA = drawing::TextVerticalAdjust_TOP; break;
+ }
+ xPropSet->setPropertyValue( sVerticalAdjust, Any( eVA ) );
+}
+
+void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, ::oox::drawingml::TextListStylePtr pMasterTextListStyle,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::table::XCell >& rxCell, const TableProperties& rTableProperties,
+ const TableStyle& rTableStyle, sal_Int32 nColumn, sal_Int32 nMaxColumn, sal_Int32 nRow, sal_Int32 nMaxRow )
+{
+ TableStyle& rTable( const_cast< TableStyle& >( rTableStyle ) );
+ TableProperties& rProperties( const_cast< TableProperties& >( rTableProperties ) );
+
+ Reference< text::XText > xText( rxCell, UNO_QUERY_THROW );
+ Reference< text::XTextCursor > xAt = xText->createTextCursor();
+
+ applyTableCellProperties( rxCell, *this );
+ TextCharacterProperties aTextStyleProps;
+ getTextBody()->insertAt( rFilterBase, xText, xAt, aTextStyleProps, pMasterTextListStyle );
+
+ Reference< XPropertySet > xPropSet( rxCell, UNO_QUERY_THROW );
+ oox::drawingml::FillProperties aFillProperties;
+ oox::drawingml::LineProperties aLinePropertiesLeft;
+ oox::drawingml::LineProperties aLinePropertiesRight;
+ oox::drawingml::LineProperties aLinePropertiesTop;
+ oox::drawingml::LineProperties aLinePropertiesBottom;
+ oox::drawingml::LineProperties aLinePropertiesTopLeftToBottomRight;
+ oox::drawingml::LineProperties aLinePropertiesBottomLeftToTopRight;
+
+ boost::shared_ptr< ::oox::drawingml::FillProperties >& rBackgroundFillPropertiesPtr( rTable.getBackgroundFillProperties() );
+ if ( rBackgroundFillPropertiesPtr.get() )
+ aFillProperties.assignUsed( *rBackgroundFillPropertiesPtr );
+
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getWholeTbl() );
+
+ if ( rProperties.isFirstRow() && ( nRow == 0 ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getFirstRow() );
+ }
+ if ( rProperties.isLastRow() && ( nRow == nMaxRow ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getLastRow() );
+ }
+ if ( rProperties.isFirstCol() && ( nColumn == 0 ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getFirstCol() );
+ }
+ if ( rProperties.isLastCol() && ( nColumn == nMaxColumn ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getLastCol() );
+ }
+ if ( rProperties.isBandRow() )
+ {
+ if ( ( !rProperties.isFirstRow() || ( nRow != 0 ) ) &&
+ ( !rProperties.isLastRow() || ( nRow != nMaxRow ) ) )
+ {
+ sal_Int32 nBand = nRow;
+ if ( rProperties.isFirstRow() )
+ nBand++;
+ if ( nBand & 1 )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getBand2H() );
+ }
+ else
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getBand1H() );
+ }
+ }
+ }
+ if ( ( nRow == 0 ) && ( nColumn == 0 ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getNwCell() );
+ }
+ if ( ( nRow == nMaxRow ) && ( nColumn == 0 ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getSwCell() );
+ }
+ if ( ( nRow == 0 ) && ( nColumn == nMaxColumn ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getNeCell() );
+ }
+ if ( ( nRow == nMaxColumn ) && ( nColumn == nMaxColumn ) )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getSeCell() );
+ }
+ if ( rProperties.isBandCol() )
+ {
+ if ( ( !rProperties.isFirstCol() || ( nColumn != 0 ) ) &&
+ ( !rProperties.isLastCol() || ( nColumn != nMaxColumn ) ) )
+ {
+ sal_Int32 nBand = nColumn;
+ if ( rProperties.isFirstCol() )
+ nBand++;
+ if ( nBand & 1 )
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getBand2V() );
+ }
+ else
+ {
+ applyTableStylePart( rFilterBase, rxCell, aFillProperties,
+ aLinePropertiesLeft,
+ aLinePropertiesRight,
+ aLinePropertiesTop,
+ aLinePropertiesBottom,
+ aLinePropertiesTopLeftToBottomRight,
+ aLinePropertiesBottomLeftToTopRight,
+ rTable.getBand1V() );
+ }
+ }
+ }
+ aLinePropertiesLeft.assignUsed( maLinePropertiesLeft );
+ aLinePropertiesRight.assignUsed( maLinePropertiesRight );
+ aLinePropertiesTop.assignUsed( maLinePropertiesTop );
+ aLinePropertiesBottom.assignUsed( maLinePropertiesBottom );
+ aLinePropertiesTopLeftToBottomRight.assignUsed( maLinePropertiesTopLeftToBottomRight );
+ aLinePropertiesBottomLeftToTopRight.assignUsed( maLinePropertiesBottomLeftToTopRight );
+ applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesLeft, PROP_LeftBorder );
+ applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesRight, PROP_RightBorder );
+ applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesTop, PROP_TopBorder );
+ applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesBottom, PROP_BottomBorder );
+ applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesTopLeftToBottomRight, PROP_DiagonalTLBR );
+ applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesBottomLeftToTopRight, PROP_DiagonalBLTR );
+
+ aFillProperties.assignUsed( maFillProperties );
+ PropertySet aPropSet( xPropSet );
+ // TODO: phClr?
+ aFillProperties.pushToPropSet( aPropSet, rFilterBase.getModelObjectHelper(), rFilterBase.getGraphicHelper() );
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablecellcontext.cxx b/oox/source/drawingml/table/tablecellcontext.cxx
new file mode 100644
index 000000000000..844f134c3e85
--- /dev/null
+++ b/oox/source/drawingml/table/tablecellcontext.cxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/table/tablecellcontext.hxx"
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/linepropertiescontext.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableCellContext::TableCellContext( ContextHandler& rParent, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs, TableCell& rTableCell )
+: ContextHandler( rParent )
+, mrTableCell( rTableCell )
+{
+ if ( xAttribs->hasAttribute( XML_rowSpan ) )
+ mrTableCell.setRowSpan( xAttribs->getOptionalValue( XML_rowSpan ).toInt32() );
+ if ( xAttribs->hasAttribute( XML_gridSpan ) )
+ mrTableCell.setGridSpan( xAttribs->getOptionalValue( XML_gridSpan ).toInt32() );
+
+ AttributeList aAttribs( xAttribs );
+ mrTableCell.sethMerge( aAttribs.getBool( XML_hMerge, sal_False ) );
+ mrTableCell.setvMerge( aAttribs.getBool( XML_vMerge, sal_False ) );
+}
+
+TableCellContext::~TableCellContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TableCellContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( txBody ): // CT_TextBody
+ {
+ oox::drawingml::TextBodyPtr xTextBody( new oox::drawingml::TextBody );
+ mrTableCell.setTextBody( xTextBody );
+ xRet = new oox::drawingml::TextBodyContext( *this, *xTextBody );
+ }
+ break;
+
+ case A_TOKEN( tcPr ): // CT_TableCellProperties
+ {
+ AttributeList aAttribs( xAttribs );
+ mrTableCell.setLeftMargin( aAttribs.getInteger( XML_marL, 91440 ) );
+ mrTableCell.setRightMargin( aAttribs.getInteger( XML_marR, 91440 ) );
+ mrTableCell.setTopMargin( aAttribs.getInteger( XML_marT, 45720 ) );
+ mrTableCell.setBottomMargin( aAttribs.getInteger( XML_marB, 45720 ) );
+ mrTableCell.setVertToken( xAttribs->getOptionalValueToken( XML_vert, XML_horz ) ); // ST_TextVerticalType
+ mrTableCell.setAnchorToken( xAttribs->getOptionalValueToken( XML_anchor, XML_t ) ); // ST_TextAnchoringType
+ mrTableCell.setAnchorCtr( aAttribs.getBool( XML_anchorCtr, sal_False ) );
+ mrTableCell.setHorzOverflowToken( xAttribs->getOptionalValueToken( XML_horzOverflow, XML_clip ) ); // ST_TextHorzOverflowType
+ }
+ break;
+ case A_TOKEN( lnL ):
+ xRet.set( new oox::drawingml::LinePropertiesContext( *this, xAttribs, mrTableCell.maLinePropertiesLeft ) );
+ break;
+ case A_TOKEN( lnR ):
+ xRet.set( new oox::drawingml::LinePropertiesContext( *this, xAttribs, mrTableCell.maLinePropertiesRight ) );
+ break;
+ case A_TOKEN( lnT ):
+ xRet.set( new oox::drawingml::LinePropertiesContext( *this, xAttribs, mrTableCell.maLinePropertiesTop ) );
+ break;
+ case A_TOKEN( lnB ):
+ xRet.set( new oox::drawingml::LinePropertiesContext( *this, xAttribs, mrTableCell.maLinePropertiesBottom ) );
+ break;
+ case A_TOKEN( lnTlToBr ):
+ xRet.set( new oox::drawingml::LinePropertiesContext( *this, xAttribs, mrTableCell.maLinePropertiesTopLeftToBottomRight ) );
+ break;
+ case A_TOKEN( lnBlToTr ):
+ xRet.set( new oox::drawingml::LinePropertiesContext( *this, xAttribs, mrTableCell.maLinePropertiesBottomLeftToTopRight ) );
+ break;
+ case A_TOKEN( cell3D ): // CT_Cell3D
+ break;
+
+ case A_TOKEN( extLst ): // CT_OfficeArtExtensionList
+ break;
+
+ default:
+ xRet.set( FillPropertiesContext::createFillContext( *this, aElementToken, xAttribs, mrTableCell.maFillProperties ) );
+ break;
+
+ }
+ if ( !xRet.is() )
+ {
+ uno::Reference< XFastContextHandler > xTmp( this );
+ xRet.set( xTmp );
+ }
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablecontext.cxx b/oox/source/drawingml/table/tablecontext.cxx
new file mode 100644
index 000000000000..f7e7af620428
--- /dev/null
+++ b/oox/source/drawingml/table/tablecontext.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+#include "oox/helper/attributelist.hxx"
+#include "oox/drawingml/guidcontext.hxx"
+#include "oox/drawingml/table/tablecontext.hxx"
+#include "oox/drawingml/table/tableproperties.hxx"
+#include "oox/drawingml/table/tablestylecontext.hxx"
+#include "oox/drawingml/table/tablerowcontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableContext::TableContext( ContextHandler& rParent, ShapePtr pShapePtr )
+: ShapeContext( rParent, ShapePtr(), pShapePtr )
+, mrTableProperties( *pShapePtr->getTableProperties().get() )
+{
+ pShapePtr->setTableType();
+}
+
+TableContext::~TableContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TableContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( tblPr ): // CT_TableProperties
+ {
+ AttributeList aAttribs( xAttribs );
+ mrTableProperties.isRtl() = aAttribs.getBool( XML_rtl, sal_False );
+ mrTableProperties.isFirstRow() = aAttribs.getBool( XML_firstRow, sal_False );
+ mrTableProperties.isFirstCol() = aAttribs.getBool( XML_firstCol, sal_False );
+ mrTableProperties.isLastRow() = aAttribs.getBool( XML_lastRow, sal_False );
+ mrTableProperties.isLastCol() = aAttribs.getBool( XML_lastCol, sal_False );
+ mrTableProperties.isBandRow() = aAttribs.getBool( XML_bandRow, sal_False );
+ mrTableProperties.isBandCol() = aAttribs.getBool( XML_bandCol, sal_False );
+ }
+ break;
+ case A_TOKEN( tableStyle ): // CT_TableStyle
+ {
+ boost::shared_ptr< TableStyle >& rTableStyle = mrTableProperties.getTableStyle();
+ rTableStyle.reset( new TableStyle() );
+ xRet = new TableStyleContext( *this, xAttribs, *rTableStyle );
+ }
+ break;
+ case A_TOKEN( tableStyleId ): // ST_Guid
+ xRet.set( new oox::drawingml::GuidContext( *this, mrTableProperties.getStyleId() ) );
+ break;
+
+ case A_TOKEN( tblGrid ): // CT_TableGrid
+ break;
+ case A_TOKEN( gridCol ): // CT_TableCol
+ {
+ std::vector< sal_Int32 >& rvTableGrid( mrTableProperties.getTableGrid() );
+ rvTableGrid.push_back( xAttribs->getOptionalValue( XML_w ).toInt32() );
+ }
+ break;
+ case A_TOKEN( tr ): // CT_TableRow
+ {
+ std::vector< TableRow >& rvTableRows( mrTableProperties.getTableRows() );
+ rvTableRows.resize( rvTableRows.size() + 1 );
+ xRet.set( new TableRowContext( *this, xAttribs, rvTableRows.back() ) );
+ }
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablepartstylecontext.cxx b/oox/source/drawingml/table/tablepartstylecontext.cxx
new file mode 100644
index 000000000000..1d48cbcf2a18
--- /dev/null
+++ b/oox/source/drawingml/table/tablepartstylecontext.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/table/tablepartstylecontext.hxx"
+#include "oox/drawingml/table/tablestyletextstylecontext.hxx"
+#include "oox/drawingml/table/tablestylecellstylecontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TablePartStyleContext::TablePartStyleContext( ContextHandler& rParent, TableStylePart& rTableStylePart )
+: ContextHandler( rParent )
+, mrTableStylePart( rTableStylePart )
+{
+}
+
+TablePartStyleContext::~TablePartStyleContext()
+{
+}
+
+// CT_TablePartStyle
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TablePartStyleContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( tcTxStyle ): // CT_TableStyleTextStyle
+ xRet.set( new TableStyleTextStyleContext( *this, xAttribs, mrTableStylePart ) );
+ break;
+ case A_TOKEN( tcStyle ): // CT_TableStyleCellStyle
+ xRet.set( new TableStyleCellStyleContext( *this, mrTableStylePart ) );
+ break;
+ }
+ if( !xRet.is() )
+ {
+ uno::Reference<XFastContextHandler> xTmp(this);
+ xRet.set( xTmp );
+ }
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tableproperties.cxx b/oox/source/drawingml/table/tableproperties.cxx
new file mode 100644
index 000000000000..e0d0ac91c2ab
--- /dev/null
+++ b/oox/source/drawingml/table/tableproperties.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/table/tableproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include <com/sun/star/table/XTable.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/table/XMergeableCellRange.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/propertyset.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;
+using namespace ::com::sun::star::table;
+
+
+namespace oox { namespace drawingml { namespace table {
+
+TableProperties::TableProperties()
+: mbRtl( sal_False )
+, mbFirstRow( sal_False )
+, mbFirstCol( sal_False )
+, mbLastRow( sal_False )
+, mbLastCol( sal_False )
+, mbBandRow( sal_False )
+, mbBandCol( sal_False )
+{
+}
+TableProperties::~TableProperties()
+{
+}
+
+void TableProperties::apply( const TablePropertiesPtr& /* rSourceTableProperties */ )
+{
+}
+
+void CreateTableRows( uno::Reference< XTableRows > xTableRows, const std::vector< TableRow >& rvTableRows )
+{
+ if ( rvTableRows.size() > 1 )
+ xTableRows->insertByIndex( 0, rvTableRows.size() - 1 );
+ std::vector< TableRow >::const_iterator aTableRowIter( rvTableRows.begin() );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xTableRows, UNO_QUERY_THROW );
+ for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
+ {
+ static const rtl::OUString sHeight( RTL_CONSTASCII_USTRINGPARAM ( "Height" ) );
+ Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
+ xPropSet->setPropertyValue( sHeight, Any( static_cast< sal_Int32 >( aTableRowIter->getHeight() / 360 ) ) );
+ aTableRowIter++;
+ }
+}
+
+void CreateTableColumns( Reference< XTableColumns > xTableColumns, const std::vector< sal_Int32 >& rvTableGrid )
+{
+ if ( rvTableGrid.size() > 1 )
+ xTableColumns->insertByIndex( 0, rvTableGrid.size() - 1 );
+ std::vector< sal_Int32 >::const_iterator aTableGridIter( rvTableGrid.begin() );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xTableColumns, UNO_QUERY_THROW );
+ for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
+ {
+ static const rtl::OUString sWidth( RTL_CONSTASCII_USTRINGPARAM ( "Width" ) );
+ Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
+ xPropSet->setPropertyValue( sWidth, Any( static_cast< sal_Int32 >( *aTableGridIter++ / 360 ) ) );
+ }
+}
+
+void MergeCells( const uno::Reference< XTable >& xTable, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan )
+{
+ if( xTable.is() ) try
+ {
+ Reference< XMergeableCellRange > xRange( xTable->createCursorByRange( xTable->getCellRangeByPosition( nCol, nRow,nCol + nColSpan - 1, nRow + nRowSpan - 1 ) ), UNO_QUERY_THROW );
+ if( xRange->isMergeable() )
+ xRange->merge();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+static TableStyle* pDefaultTableStyle = new TableStyle();
+
+const TableStyle& TableProperties::getUsedTableStyle( const ::oox::core::XmlFilterBase& rFilterBase )
+{
+ ::oox::core::XmlFilterBase& rBase( const_cast< ::oox::core::XmlFilterBase& >( rFilterBase ) );
+
+ TableStyle* pTableStyle = NULL;
+ if ( mpTableStyle )
+ pTableStyle = &*mpTableStyle;
+ else if ( rBase.getTableStyles() )
+ {
+ const std::vector< TableStyle >& rTableStyles( rBase.getTableStyles()->getTableStyles() );
+ const rtl::OUString aStyleId( getStyleId().getLength() ? getStyleId() : rBase.getTableStyles()->getDefaultStyleId() );
+ std::vector< TableStyle >::const_iterator aIter( rTableStyles.begin() );
+ while( aIter != rTableStyles.end() )
+ {
+ if ( const_cast< TableStyle& >( *aIter ).getStyleId() == aStyleId )
+ {
+ pTableStyle = &const_cast< TableStyle& >( *aIter );
+ break; // we get the correct style
+ }
+ aIter++;
+ }
+ }
+ if ( !pTableStyle )
+ pTableStyle = pDefaultTableStyle;
+
+ return *pTableStyle;
+}
+
+void TableProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XPropertySet >& xPropSet, TextListStylePtr pMasterTextListStyle )
+{
+ TableStyleListPtr( const_cast< ::oox::core::XmlFilterBase& >( rFilterBase ).getTableStyles() );
+
+ uno::Reference< XColumnRowRange > xColumnRowRange(
+ xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) ), uno::UNO_QUERY_THROW );
+
+ CreateTableColumns( xColumnRowRange->getColumns(), mvTableGrid );
+ CreateTableRows( xColumnRowRange->getRows(), mvTableRows );
+
+ const TableStyle& rTableStyle( getUsedTableStyle( rFilterBase ) );
+ sal_Int32 nRow = 0;
+ std::vector< TableRow >::iterator aTableRowIter( mvTableRows.begin() );
+ while( aTableRowIter != mvTableRows.end() )
+ {
+ sal_Int32 nColumn = 0;
+ std::vector< TableCell >::iterator aTableCellIter( aTableRowIter->getTableCells().begin() );
+ while( aTableCellIter != aTableRowIter->getTableCells().end() )
+ {
+ TableCell& rTableCell( *aTableCellIter );
+ if ( !rTableCell.getvMerge() && !rTableCell.gethMerge() )
+ {
+ uno::Reference< XTable > xTable( xColumnRowRange, uno::UNO_QUERY_THROW );
+ if ( ( rTableCell.getRowSpan() > 1 ) || ( rTableCell.getGridSpan() > 1 ) )
+ MergeCells( xTable, nColumn, nRow, rTableCell.getGridSpan(), rTableCell.getRowSpan() );
+
+ Reference< XCellRange > xCellRange( xTable, UNO_QUERY_THROW );
+ rTableCell.pushToXCell( rFilterBase, pMasterTextListStyle, xCellRange->getCellByPosition( nColumn, nRow ), *this, rTableStyle,
+ nColumn, aTableRowIter->getTableCells().size(), nRow, mvTableRows.size() );
+ }
+ nColumn++;
+ aTableCellIter++;
+ }
+ nRow++;
+ aTableRowIter++;
+ }
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablerow.cxx b/oox/source/drawingml/table/tablerow.cxx
new file mode 100644
index 000000000000..3c4af56a5d42
--- /dev/null
+++ b/oox/source/drawingml/table/tablerow.cxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/table/tablerow.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include "oox/helper/propertyset.hxx"
+#include <com/sun/star/table/XTable.hpp>
+#include <com/sun/star/table/XMergeableCellRange.hpp>
+#include <com/sun/star/table/BorderLine.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 { namespace table {
+
+TableRow::TableRow()
+: mnHeight( 0 )
+{
+}
+TableRow::~TableRow()
+{
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablerowcontext.cxx b/oox/source/drawingml/table/tablerowcontext.cxx
new file mode 100644
index 000000000000..1a6c38167a8d
--- /dev/null
+++ b/oox/source/drawingml/table/tablerowcontext.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/table/tablerowcontext.hxx"
+#include "oox/drawingml/table/tablecellcontext.hxx"
+#include "oox/drawingml/table/tablerow.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableRowContext::TableRowContext( ContextHandler& rParent, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs, TableRow& rTableRow )
+: ContextHandler( rParent )
+, mrTableRow( rTableRow )
+{
+ rTableRow.setHeight( xAttribs->getOptionalValue( XML_h ).toInt32() );
+}
+
+TableRowContext::~TableRowContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TableRowContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( tc ): // CT_TableCell
+ {
+ std::vector< TableCell >& rvTableCells = mrTableRow.getTableCells();
+ rvTableCells.resize( rvTableCells.size() + 1 );
+ xRet.set( new TableCellContext( *this, xAttribs, rvTableCells.back() ) );
+ }
+ break;
+ case A_TOKEN( extLst ): // CT_OfficeArtExtensionList
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ {
+ uno::Reference< XFastContextHandler > xTmp( this );
+ xRet.set( xTmp );
+ }
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablestyle.cxx b/oox/source/drawingml/table/tablestyle.cxx
new file mode 100644
index 000000000000..78a110ebb8cb
--- /dev/null
+++ b/oox/source/drawingml/table/tablestyle.cxx
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/table/tablestyle.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+TableStyle::TableStyle()
+{
+}
+
+TableStyle::~TableStyle()
+{
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablestylecellstylecontext.cxx b/oox/source/drawingml/table/tablestylecellstylecontext.cxx
new file mode 100644
index 000000000000..56127b0c049c
--- /dev/null
+++ b/oox/source/drawingml/table/tablestylecellstylecontext.cxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/table/tablestylecellstylecontext.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/linepropertiescontext.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableStyleCellStyleContext::TableStyleCellStyleContext( ContextHandler& rParent, TableStylePart& rTableStylePart )
+: ContextHandler( rParent )
+, mrTableStylePart( rTableStylePart )
+, mnLineType( XML_none )
+{
+}
+
+TableStyleCellStyleContext::~TableStyleCellStyleContext()
+{
+}
+
+// CT_TableStyleCellStyle
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TableStyleCellStyleContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+ AttributeList aAttribs( xAttribs );
+ switch( aElementToken )
+ {
+ case A_TOKEN( tcBdr ): // CT_TableCellBorderStyle
+ break;
+ case A_TOKEN( left ): // CT_ThemeableLineStyle
+ case A_TOKEN( right ):
+ case A_TOKEN( top ):
+ case A_TOKEN( bottom ):
+ case A_TOKEN( insideH ):
+ case A_TOKEN( insideV ):
+ case A_TOKEN( tl2br ):
+ case A_TOKEN( tr2bl ):
+ mnLineType = getBaseToken( aElementToken );
+ break;
+
+ case A_TOKEN( ln ):
+ {
+ if ( mnLineType != XML_none )
+ {
+ std::map < sal_Int32, ::oox::drawingml::LinePropertiesPtr >& rLineBorders = mrTableStylePart.getLineBorders();
+ ::oox::drawingml::LinePropertiesPtr mpLineProperties( new oox::drawingml::LineProperties );
+ rLineBorders[ mnLineType ] = mpLineProperties;
+ xRet = new LinePropertiesContext( *this, xAttribs, *mpLineProperties );
+ }
+ }
+ break;
+ case A_TOKEN( lnRef ):
+ {
+ if ( mnLineType != XML_none )
+ {
+ ShapeStyleRef& rLineStyleRef = mrTableStylePart.getStyleRefs()[ mnLineType ];
+ rLineStyleRef.mnThemedIdx = aAttribs.getInteger( XML_idx, 0 );
+ xRet.set( new ColorContext( *this, rLineStyleRef.maPhClr ) );
+ }
+ }
+ break;
+
+ // EG_ThemeableFillStyle (choice)
+ case A_TOKEN( fill ): // CT_FillProperties
+ {
+ FillPropertiesPtr& rxFillProperties = mrTableStylePart.getFillProperties();
+ rxFillProperties.reset( new FillProperties );
+ xRet.set( new FillPropertiesContext( *this, *rxFillProperties ) );
+ }
+ break;
+ case A_TOKEN( fillRef ): // CT_StyleMatrixReference
+ {
+ ShapeStyleRef& rStyleRef = mrTableStylePart.getStyleRefs()[ XML_fillRef ];
+ rStyleRef.mnThemedIdx = aAttribs.getInteger( XML_idx, 0 );
+ xRet.set( new ColorContext( *this, rStyleRef.maPhClr ) );
+ }
+ break;
+
+ case A_TOKEN( cell3D ): // CT_Cell3D
+ break;
+ }
+ if( !xRet.is() )
+ {
+ uno::Reference<XFastContextHandler> xTmp(this);
+ xRet.set( xTmp );
+ }
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablestylecontext.cxx b/oox/source/drawingml/table/tablestylecontext.cxx
new file mode 100644
index 000000000000..aee23eaf9c7b
--- /dev/null
+++ b/oox/source/drawingml/table/tablestylecontext.cxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/table/tablestylecontext.hxx"
+#include "oox/drawingml/table/tablebackgroundstylecontext.hxx"
+#include "oox/drawingml/table/tablepartstylecontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableStyleContext::TableStyleContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs, TableStyle& rTableStyle )
+: ContextHandler( rParent )
+, mrTableStyle( rTableStyle )
+{
+ mrTableStyle.getStyleId() = xAttribs->getOptionalValue( XML_styleId );
+ mrTableStyle.getStyleName() = xAttribs->getOptionalValue( XML_styleName );
+}
+
+TableStyleContext::~TableStyleContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TableStyleContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& /* xAttribs */ )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( tblBg ): // CT_TableBackgroundStyle
+ xRet = new TableBackgroundStyleContext( *this, mrTableStyle );
+ break;
+ case A_TOKEN( wholeTbl ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getWholeTbl() );
+ break;
+ case A_TOKEN( band1H ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getBand1H() );
+ break;
+ case A_TOKEN( band2H ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getBand2H() );
+ break;
+ case A_TOKEN( band1V ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getBand1V() );
+ break;
+ case A_TOKEN( band2V ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getBand2V() );
+ break;
+ case A_TOKEN( lastCol ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getLastCol() );
+ break;
+ case A_TOKEN( firstCol ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getFirstCol() );
+ break;
+ case A_TOKEN( lastRow ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getLastRow() );
+ break;
+ case A_TOKEN( seCell ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getSeCell() );
+ break;
+ case A_TOKEN( swCell ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getSwCell() );
+ break;
+ case A_TOKEN( firstRow ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getFirstRow() );
+ break;
+ case A_TOKEN( neCell ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getNeCell() );
+ break;
+ case A_TOKEN( nwCell ): // CT_TablePartStyle
+ xRet = new TablePartStyleContext( *this, mrTableStyle.getNwCell() );
+ break;
+ case A_TOKEN( extLst ): // CT_OfficeArtExtensionList
+ break;
+ }
+ if( !xRet.is() )
+ {
+ uno::Reference<XFastContextHandler> xTmp(this);
+ xRet.set( xTmp );
+ }
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablestylelist.cxx b/oox/source/drawingml/table/tablestylelist.cxx
new file mode 100644
index 000000000000..36ebc56a84a3
--- /dev/null
+++ b/oox/source/drawingml/table/tablestylelist.cxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/table/tablestylelist.hxx"
+#include "oox/drawingml/table/tablestyle.hxx"
+
+namespace oox { namespace drawingml { namespace table {
+
+TableStyleList::TableStyleList()
+{
+}
+
+TableStyleList::~TableStyleList()
+{
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablestylelistfragmenthandler.cxx b/oox/source/drawingml/table/tablestylelistfragmenthandler.cxx
new file mode 100644
index 000000000000..7b837d27e826
--- /dev/null
+++ b/oox/source/drawingml/table/tablestylelistfragmenthandler.cxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/table/tablestylelistfragmenthandler.hxx"
+#include "oox/drawingml/table/tablestylecontext.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+
+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;
+
+namespace oox {
+namespace drawingml {
+namespace table {
+
+// ============================================================================
+
+TableStyleListFragmentHandler::TableStyleListFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath, TableStyleList& rTableStyleList ):
+FragmentHandler2( rFilter, rFragmentPath ),
+mrTableStyleList( rTableStyleList )
+{
+}
+
+TableStyleListFragmentHandler::~TableStyleListFragmentHandler()
+{
+}
+
+// CT_TableStyleList
+Reference< XFastContextHandler > TableStyleListFragmentHandler::createFastChildContext(
+ sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw ( SAXException, RuntimeException )
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case A_TOKEN( tblStyleLst ): // CT_TableStyleList
+ mrTableStyleList.getDefaultStyleId() = xAttribs->getOptionalValue( XML_def );
+ break;
+ case A_TOKEN( tblStyle ): // CT_TableStyle
+ std::vector< TableStyle >& rTableStyles = mrTableStyleList.getTableStyles();
+ rTableStyles.resize( rTableStyles.size() + 1 );
+ xRet = new TableStyleContext( *this, xAttribs, rTableStyles.back() );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet = getFastContextHandler();
+ return xRet;
+}
+
+// ============================================================================
+
+} // namespace table
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/table/tablestylepart.cxx b/oox/source/drawingml/table/tablestylepart.cxx
new file mode 100644
index 000000000000..b4a68fd488cd
--- /dev/null
+++ b/oox/source/drawingml/table/tablestylepart.cxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/table/tablestylepart.hxx"
+#include "oox/drawingml/drawingmltypes.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 { namespace table {
+
+TableStylePart::TableStylePart()
+{
+}
+
+TableStylePart::~TableStylePart()
+{
+}
+
+} } }
diff --git a/oox/source/drawingml/table/tablestyletextstylecontext.cxx b/oox/source/drawingml/table/tablestyletextstylecontext.cxx
new file mode 100644
index 000000000000..7c04e3293eb1
--- /dev/null
+++ b/oox/source/drawingml/table/tablestyletextstylecontext.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include "oox/drawingml/table/tablestyletextstylecontext.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using ::rtl::OUString;
+
+namespace oox { namespace drawingml { namespace table {
+
+TableStyleTextStyleContext::TableStyleTextStyleContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs, TableStylePart& rTableStylePart )
+: ContextHandler( rParent )
+, mrTableStylePart( rTableStylePart )
+{
+ sal_Int32 nB = xAttribs->getOptionalValueToken( XML_b, XML_def );
+ if ( nB == XML_on )
+ mrTableStylePart.getTextBoldStyle() = ::boost::optional< sal_Bool >( sal_True );
+ else if ( nB == XML_off )
+ mrTableStylePart.getTextBoldStyle() = ::boost::optional< sal_Bool >( sal_False );
+
+ sal_Int32 nI = xAttribs->getOptionalValueToken( XML_i, XML_def );
+ if ( nI == XML_on )
+ mrTableStylePart.getTextItalicStyle() = ::boost::optional< sal_Bool >( sal_True );
+ else if ( nI == XML_off )
+ mrTableStylePart.getTextItalicStyle() = ::boost::optional< sal_Bool >( sal_False );
+}
+
+TableStyleTextStyleContext::~TableStyleTextStyleContext()
+{
+}
+
+// CT_TableStyleTextStyle
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+TableStyleTextStyleContext::createFastChildContext( ::sal_Int32 aElementToken, const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
+ throw ( xml::sax::SAXException, uno::RuntimeException)
+{
+ uno::Reference< xml::sax::XFastContextHandler > xRet;
+ AttributeList aAttribs( xAttribs );
+
+ switch( aElementToken )
+ {
+ // EG_ThemeableFontStyles (choice)
+ case A_TOKEN( font ): // CT_FontCollection
+ xRet.set( this );
+ break;
+ case A_TOKEN( ea ): // CT_TextFont
+ mrTableStylePart.getAsianFont().setAttributes( aAttribs );
+ return 0;
+ case A_TOKEN( cs ): // CT_TextFont
+ mrTableStylePart.getComplexFont().setAttributes( aAttribs );
+ return 0;
+ case A_TOKEN( sym ): // CT_TextFont
+ mrTableStylePart.getSymbolFont().setAttributes( aAttribs );
+ return 0;
+ case A_TOKEN( latin ): // CT_TextFont
+ mrTableStylePart.getLatinFont().setAttributes( aAttribs );
+ return 0;
+
+ case A_TOKEN( fontRef ): // CT_FontReference
+ {
+ ShapeStyleRef& rFontStyle = mrTableStylePart.getStyleRefs()[ XML_fontRef ];
+ rFontStyle.mnThemedIdx = aAttribs.getToken( XML_idx, XML_none );
+ xRet.set( new ColorContext( *this, rFontStyle.maPhClr ) );
+ }
+ break;
+
+ case A_TOKEN( extLst ): // CT_OfficeArtExtensionList
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( new ColorValueContext( *this, mrTableStylePart.getTextColor() ) );
+
+ return xRet;
+}
+
+} } }
diff --git a/oox/source/drawingml/textbody.cxx b/oox/source/drawingml/textbody.cxx
new file mode 100644
index 000000000000..20c554ef3e64
--- /dev/null
+++ b/oox/source/drawingml/textbody.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textbody.hxx"
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include "oox/drawingml/textparagraph.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()
+{
+}
+
+TextBody::~TextBody()
+{
+}
+
+TextParagraph& TextBody::addParagraph()
+{
+ TextParagraphPtr xPara( new TextParagraph );
+ maParagraphs.push_back( xPara );
+ return *xPara;
+}
+
+void TextBody::insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XText > & xText,
+ const Reference < XTextCursor > & xAt,
+ const TextCharacterProperties& rTextStyleProperties,
+ const TextListStylePtr& pMasterTextListStylePtr ) const
+{
+ TextListStyle aCombinedTextStyle;
+ aCombinedTextStyle.apply( *pMasterTextListStylePtr );
+ aCombinedTextStyle.apply( maTextListStyle );
+
+ for( TextParagraphVector::const_iterator aBeg = maParagraphs.begin(), aIt = aBeg, aEnd = maParagraphs.end(); aIt != aEnd; ++aIt )
+ (*aIt)->insertAt( rFilterBase, xText, xAt, rTextStyleProperties, aCombinedTextStyle, aIt == aBeg );
+}
+
+
+} }
diff --git a/oox/source/drawingml/textbodycontext.cxx b/oox/source/drawingml/textbodycontext.cxx
new file mode 100644
index 000000000000..8d695e295fd4
--- /dev/null
+++ b/oox/source/drawingml/textbodycontext.cxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textbodycontext.hxx"
+#include "oox/drawingml/textbodypropertiescontext.hxx"
+#include "oox/drawingml/textparagraph.hxx"
+#include "oox/drawingml/textparagraphpropertiescontext.hxx"
+#include "oox/drawingml/textcharacterpropertiescontext.hxx"
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/drawingml/textfield.hxx"
+#include "oox/drawingml/textfieldcontext.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 ContextHandler
+{
+public:
+ TextParagraphContext( ContextHandler& rParent, 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( ContextHandler& rParent, TextParagraph& rPara )
+: ContextHandler( rParent )
+, mrParagraph( rPara )
+{
+}
+
+// --------------------------------------------------------------------
+void TextParagraphContext::endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException)
+{
+ if( aElementToken == (A_TOKEN( p )) )
+ {
+ }
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextParagraphContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ // EG_TextRun
+ switch( aElementToken )
+ {
+ case A_TOKEN( r ): // "CT_RegularTextRun" Regular Text Run.
+ {
+ TextRunPtr pRun( new TextRun );
+ mrParagraph.addRun( pRun );
+ xRet.set( new RegularTextRunContext( *this, pRun ) );
+ break;
+ }
+ case A_TOKEN( br ): // "CT_TextLineBreak" Soft return line break (vertical tab).
+ {
+ TextRunPtr pRun( new TextRun );
+ pRun->setLineBreak();
+ mrParagraph.addRun( pRun );
+ xRet.set( new RegularTextRunContext( *this, pRun ) );
+ break;
+ }
+ case A_TOKEN( fld ): // "CT_TextField" Text Field.
+ {
+ TextFieldPtr pField( new TextField );
+ mrParagraph.addRun( pField );
+ xRet.set( new TextFieldContext( *this, xAttribs, *pField ) );
+ break;
+ }
+ case A_TOKEN( pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, xAttribs, mrParagraph.getProperties() ) );
+ break;
+ case A_TOKEN( endParaRPr ):
+ xRet.set( new TextCharacterPropertiesContext( *this, xAttribs, mrParagraph.getEndProperties() ) );
+ break;
+ }
+
+ return xRet;
+}
+// --------------------------------------------------------------------
+
+RegularTextRunContext::RegularTextRunContext( ContextHandler& rParent, TextRunPtr pRunPtr )
+: ContextHandler( rParent )
+, mpRunPtr( pRunPtr )
+, mbIsInText( false )
+{
+}
+
+// --------------------------------------------------------------------
+
+void RegularTextRunContext::endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ case A_TOKEN( t ):
+ {
+ mbIsInText = false;
+ break;
+ }
+ case A_TOKEN( r ):
+ {
+ break;
+ }
+
+ }
+}
+
+// --------------------------------------------------------------------
+
+void RegularTextRunContext::characters( const OUString& aChars ) throw (SAXException, RuntimeException)
+{
+ if( mbIsInText )
+ {
+ mpRunPtr->getText() += aChars;
+ }
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > RegularTextRunContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet( this );
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( rPr ): // "CT_TextCharPropertyBag" The text char properties of this text run.
+ xRet.set( new TextCharacterPropertiesContext( *this, xAttribs, mpRunPtr->getTextCharacterProperties() ) );
+ break;
+ case A_TOKEN( t ): // "xsd:string" minOccurs="1" The actual text string.
+ mbIsInText = true;
+ break;
+ }
+
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+TextBodyContext::TextBodyContext( ContextHandler& rParent, TextBody& rTextBody )
+: ContextHandler( rParent )
+, mrTextBody( rTextBody )
+{
+}
+
+// --------------------------------------------------------------------
+
+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 A_TOKEN( bodyPr ): // CT_TextBodyPropertyBag
+ xRet.set( new TextBodyPropertiesContext( *this, xAttribs, mrTextBody.getTextProperties() ) );
+ break;
+ case A_TOKEN( lstStyle ): // CT_TextListStyle
+ xRet.set( new TextListStyleContext( *this, mrTextBody.getTextListStyle() ) );
+ break;
+ case A_TOKEN( p ): // CT_TextParagraph
+ xRet.set( new TextParagraphContext( *this, mrTextBody.addParagraph() ) );
+ break;
+ }
+
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+} }
+
diff --git a/oox/source/drawingml/textbodyproperties.cxx b/oox/source/drawingml/textbodyproperties.cxx
new file mode 100644
index 000000000000..4339c93aa0ae
--- /dev/null
+++ b/oox/source/drawingml/textbodyproperties.cxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textbodyproperties.hxx"
+#include <com/sun/star/text/WritingMode.hpp>
+#include "oox/token/tokens.hxx"
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+TextBodyProperties::TextBodyProperties()
+{
+}
+
+void TextBodyProperties::pushToPropMap( PropertyMap& rPropMap ) const
+{
+ rPropMap.insert( maPropertyMap.begin(), maPropertyMap.end() );
+
+ // #160799# fake different vertical text modes by top-bottom writing mode
+ if( moVert.get( XML_horz ) != XML_horz )
+ rPropMap[ PROP_TextWritingMode ] <<= ::com::sun::star::text::WritingMode_TB_RL;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/textbodypropertiescontext.cxx b/oox/source/drawingml/textbodypropertiescontext.cxx
new file mode 100644
index 000000000000..f22258075e16
--- /dev/null
+++ b/oox/source/drawingml/textbodypropertiescontext.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textbodypropertiescontext.hxx"
+
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include "oox/drawingml/textbodyproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertymap.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace drawingml {
+
+// --------------------------------------------------------------------
+
+// CT_TextBodyProperties
+TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttributes, TextBodyProperties& rTextBodyProp )
+: ContextHandler( rParent )
+, mrTextBodyProp( rTextBodyProp )
+{
+ AttributeList aAttribs( xAttributes );
+
+ // ST_TextWrappingType
+ sal_Int32 nWrappingType = aAttribs.getToken( XML_wrap, XML_square );
+ mrTextBodyProp.maPropertyMap[ PROP_TextWordWrap ] <<= static_cast< sal_Bool >( nWrappingType == XML_square );
+
+ // ST_Coordinate
+ OUString sValue;
+ sValue = xAttributes->getOptionalValue( XML_lIns );
+ if( sValue.getLength() ) {
+ sal_Int32 nLeftInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 91440 / 360 );
+ mrTextBodyProp.maPropertyMap[ PROP_TextLeftDistance ] <<= static_cast< sal_Int32 >( nLeftInset );
+ }
+ sValue = xAttributes->getOptionalValue( XML_tIns );
+ if( sValue.getLength() ) {
+ sal_Int32 nTopInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 91440 / 360 );
+ mrTextBodyProp.maPropertyMap[ PROP_TextUpperDistance ] <<= static_cast< sal_Int32 >( nTopInset );
+ }
+ sValue = xAttributes->getOptionalValue( XML_rIns );
+ if( sValue.getLength() ) {
+ sal_Int32 nRightInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 91440 / 360 );
+ mrTextBodyProp.maPropertyMap[ PROP_TextRightDistance ] <<= static_cast< sal_Int32 >( nRightInset );
+ }
+ sValue = xAttributes->getOptionalValue( XML_bIns );
+ if( sValue.getLength() ) {
+ sal_Int32 nBottonInset = ( sValue.getLength() != 0 ? GetCoordinate( sValue ) : 45720 / 360 );
+ mrTextBodyProp.maPropertyMap[ PROP_TextLowerDistance ] <<= static_cast< sal_Int32 >( nBottonInset );
+ }
+
+ // ST_TextAnchoringType
+ drawing::TextVerticalAdjust eVA( drawing::TextVerticalAdjust_TOP );
+ switch( xAttributes->getOptionalValueToken( XML_anchor, XML_t ) )
+ {
+ case XML_b : eVA = drawing::TextVerticalAdjust_BOTTOM; break;
+ case XML_dist :
+ case XML_just :
+ case XML_ctr : eVA = drawing::TextVerticalAdjust_CENTER; break;
+ default:
+ case XML_t : eVA = drawing::TextVerticalAdjust_TOP; break;
+ }
+ mrTextBodyProp.maPropertyMap[ PROP_TextVerticalAdjust ] <<= eVA;
+
+ bool bAnchorCenter = aAttribs.getBool( XML_anchorCtr, false );
+ if( bAnchorCenter )
+ mrTextBodyProp.maPropertyMap[ PROP_TextHorizontalAdjust ] <<=
+ TextHorizontalAdjust_CENTER;
+
+// bool bCompatLineSpacing = aAttribs.getBool( XML_compatLnSpc, false );
+// bool bForceAA = aAttribs.getBool( XML_forceAA, false );
+// bool bFromWordArt = aAttribs.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 = aAttribs.getInteger( XML_numCol, 1 );
+
+ // ST_Angle
+ mrTextBodyProp.moRotation = aAttribs.getInteger( XML_rot );
+
+// bool bRtlCol = aAttribs.getBool( XML_rtlCol, false );
+ // ST_PositiveCoordinate
+// sal_Int32 nSpcCol = aAttribs.getInteger( XML_spcCol, 0 );
+// bool bSpcFirstLastPara = aAttribs.getBool( XML_spcFirstLastPara, 0 );
+// bool bUpRight = aAttribs.getBool( XML_upright, 0 );
+
+ // ST_TextVerticalType
+ mrTextBodyProp.moVert = aAttribs.getToken( XML_vert );
+ bool bRtl = aAttribs.getBool( XML_rtl, false );
+ sal_Int32 tVert = mrTextBodyProp.moVert.get( XML_horz );
+ if( tVert == XML_vert || tVert == XML_eaVert || tVert == XML_vert270 || tVert == XML_mongolianVert ) {
+ mrTextBodyProp.maPropertyMap[ PROP_TextWritingMode ]
+ <<= WritingMode_TB_RL;
+ // workaround for TB_LR as using WritingMode2 doesn't work
+ if( !bAnchorCenter )
+ mrTextBodyProp.maPropertyMap[ PROP_TextHorizontalAdjust ] <<=
+ TextHorizontalAdjust_LEFT;
+ } else
+ mrTextBodyProp.maPropertyMap[ PROP_TextWritingMode ]
+ <<= ( bRtl ? WritingMode_RL_TB : WritingMode_LR_TB );
+}
+
+// --------------------------------------------------------------------
+
+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;
+ switch( aElementToken )
+ {
+ // Sequence
+ case A_TOKEN( prstTxWarp ): // CT_PresetTextShape
+ case A_TOKEN( prot ): // CT_TextProtectionProperty
+ break;
+
+ // EG_TextAutofit
+ case A_TOKEN( noAutofit ):
+ mrTextBodyProp.maPropertyMap[ PROP_TextAutoGrowHeight ] <<= false; // CT_TextNoAutofit
+ break;
+ case A_TOKEN( normAutofit ): // CT_TextNormalAutofit
+ mrTextBodyProp.maPropertyMap[ PROP_TextFitToSize ] <<= true;
+ mrTextBodyProp.maPropertyMap[ PROP_TextAutoGrowHeight ] <<= false;
+ break;
+ case A_TOKEN( spAutoFit ):
+ mrTextBodyProp.maPropertyMap[ PROP_TextAutoGrowHeight ] <<= true;
+ break;
+
+ case A_TOKEN( scene3d ): // CT_Scene3D
+
+ // EG_Text3D
+ case A_TOKEN( sp3d ): // CT_Shape3D
+ case A_TOKEN( 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..61333535c38f
--- /dev/null
+++ b/oox/source/drawingml/textcharacterproperties.cxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textcharacterproperties.hxx"
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/token/tokens.hxx"
+
+using ::rtl::OUString;
+using ::oox::core::XmlFilterBase;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+void TextCharacterProperties::assignUsed( const TextCharacterProperties& rSourceProps )
+{
+ // overwrite all properties exisiting in rSourceProps
+ maHyperlinkPropertyMap.insert( rSourceProps.maHyperlinkPropertyMap.begin(), rSourceProps.maHyperlinkPropertyMap.end() );
+ maLatinFont.assignIfUsed( rSourceProps.maLatinFont );
+ maAsianFont.assignIfUsed( rSourceProps.maAsianFont );
+ maComplexFont.assignIfUsed( rSourceProps.maComplexFont );
+ maSymbolFont.assignIfUsed( rSourceProps.maSymbolFont );
+ maCharColor.assignIfUsed( rSourceProps.maCharColor );
+ maHighlightColor.assignIfUsed( rSourceProps.maHighlightColor );
+ maUnderlineColor.assignIfUsed( rSourceProps.maUnderlineColor );
+ moHeight.assignIfUsed( rSourceProps.moHeight );
+ moSpacing.assignIfUsed( rSourceProps.moSpacing );
+ moUnderline.assignIfUsed( rSourceProps.moUnderline );
+ moStrikeout.assignIfUsed( rSourceProps.moStrikeout );
+ moCaseMap.assignIfUsed( rSourceProps.moCaseMap );
+ moBold.assignIfUsed( rSourceProps.moBold );
+ moItalic.assignIfUsed( rSourceProps.moItalic );
+ moUnderlineLineFollowText.assignIfUsed( rSourceProps.moUnderlineLineFollowText );
+ moUnderlineFillFollowText.assignIfUsed( rSourceProps.moUnderlineFillFollowText );
+}
+
+void TextCharacterProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFilterBase& rFilter ) const
+{
+ OUString aFontName;
+ sal_Int16 nFontPitch = 0;
+ sal_Int16 nFontFamily = 0;
+
+ if( maLatinFont.getFontData( aFontName, nFontPitch, nFontFamily, rFilter ) )
+ {
+ rPropMap[ PROP_CharFontName ] <<= aFontName;
+ rPropMap[ PROP_CharFontPitch ] <<= nFontPitch;
+ rPropMap[ PROP_CharFontFamily ] <<= nFontFamily;
+ }
+
+ if( maAsianFont.getFontData( aFontName, nFontPitch, nFontFamily, rFilter ) )
+ {
+ rPropMap[ PROP_CharFontNameAsian ] <<= aFontName;
+ rPropMap[ PROP_CharFontPitchAsian ] <<= nFontFamily;
+ rPropMap[ PROP_CharFontFamilyAsian ] <<= nFontPitch;
+ }
+
+ if( maComplexFont.getFontData( aFontName, nFontPitch, nFontFamily, rFilter ) )
+ {
+ rPropMap[ PROP_CharFontNameComplex ] <<= aFontName;
+ rPropMap[ PROP_CharFontPitchComplex ] <<= nFontPitch;
+ rPropMap[ PROP_CharFontFamilyComplex ] <<= nFontFamily;
+ }
+
+ // symbolfont, will now be ... textrun.cxx ... ausgewertet !!!i#113673
+
+ if( maCharColor.isUsed() )
+ rPropMap[ PROP_CharColor ] <<= maCharColor.getColor( rFilter.getGraphicHelper() );
+
+ if( moLang.has() && (moLang.get().getLength() > 0) )
+ {
+ lang::Locale aLocale;
+ sal_Int32 nSepPos = moLang.get().indexOf( sal_Unicode( '-' ), 0 );
+ if ( nSepPos >= 0 )
+ {
+ aLocale.Language = moLang.get().copy( 0, nSepPos );
+ aLocale.Country = moLang.get().copy( nSepPos + 1 );
+ }
+ else
+ {
+ aLocale.Language = moLang.get();
+ }
+ rPropMap[ PROP_CharLocale ] <<= aLocale;
+ rPropMap[ PROP_CharLocaleAsian ] <<= aLocale;
+ rPropMap[ PROP_CharLocaleComplex ] <<= aLocale;
+ }
+
+ if( moHeight.has() )
+ {
+ float fHeight = GetFontHeight( moHeight.get() );
+ rPropMap[ PROP_CharHeight ] <<= fHeight;
+ rPropMap[ PROP_CharHeightAsian ] <<= fHeight;
+ rPropMap[ PROP_CharHeightComplex ] <<= fHeight;
+ }
+
+ rPropMap[ PROP_CharKerning ] <<= (sal_Int16) GetTextSpacingPoint( moSpacing.get( 0 ) );
+
+ rPropMap[ PROP_CharUnderline ] <<= GetFontUnderline( moUnderline.get( XML_none ) );
+ rPropMap[ PROP_CharStrikeout ] <<= GetFontStrikeout( moStrikeout.get( XML_noStrike ) );
+ rPropMap[ PROP_CharCaseMap ] <<= GetCaseMap( moCaseMap.get( XML_none ) );
+
+ float fWeight = moBold.get( false ) ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL;
+ rPropMap[ PROP_CharWeight ] <<= fWeight;
+ rPropMap[ PROP_CharWeightAsian ] <<= fWeight;
+ rPropMap[ PROP_CharWeightComplex ] <<= fWeight;
+
+ awt::FontSlant eSlant = moItalic.get( false ) ? awt::FontSlant_ITALIC : awt::FontSlant_NONE;
+ rPropMap[ PROP_CharPosture ] <<= eSlant;
+ rPropMap[ PROP_CharPostureAsian ] <<= eSlant;
+ rPropMap[ PROP_CharPostureComplex ] <<= eSlant;
+
+ bool bUnderlineFillFollowText = moUnderlineFillFollowText.get( false );
+ if( moUnderline.has() && maUnderlineColor.isUsed() && !bUnderlineFillFollowText )
+ {
+ rPropMap[ PROP_CharUnderlineHasColor ] <<= true;
+ rPropMap[ PROP_CharUnderlineColor ] <<= maUnderlineColor.getColor( rFilter.getGraphicHelper() );
+ }
+}
+
+void TextCharacterProperties::pushToPropSet( PropertySet& rPropSet, const XmlFilterBase& rFilter ) const
+{
+ PropertyMap aPropMap;
+ pushToPropMap( aPropMap, rFilter );
+ rPropSet.setProperties( aPropMap );
+}
+
+float TextCharacterProperties::getCharHeightPoints( float fDefault ) const
+{
+ return moHeight.has() ? GetFontHeight( moHeight.get() ) : fDefault;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/textcharacterpropertiescontext.cxx b/oox/source/drawingml/textcharacterpropertiescontext.cxx
new file mode 100644
index 000000000000..f3be44773a39
--- /dev/null
+++ b/oox/source/drawingml/textcharacterpropertiescontext.cxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textcharacterpropertiescontext.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/textparagraphproperties.hxx"
+#include "oox/core/relations.hxx"
+#include "hyperlinkcontext.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(
+ ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rXAttributes,
+ TextCharacterProperties& rTextCharacterProperties )
+: ContextHandler( rParent )
+, mrTextCharacterProperties( rTextCharacterProperties )
+{
+ AttributeList aAttribs( rXAttributes );
+ if ( aAttribs.hasAttribute( XML_lang ) )
+ mrTextCharacterProperties.moLang = aAttribs.getString( XML_lang );
+ if ( aAttribs.hasAttribute( XML_sz ) )
+ mrTextCharacterProperties.moHeight = aAttribs.getInteger( XML_sz );
+ if ( aAttribs.hasAttribute( XML_u ) )
+ mrTextCharacterProperties.moUnderline = aAttribs.getToken( XML_u );
+ if ( aAttribs.hasAttribute( XML_strike ) )
+ mrTextCharacterProperties.moStrikeout = aAttribs.getToken( XML_strike );
+
+// mrTextCharacterProperties.moCaseMap = aAttribs.getToken( XML_cap );
+ if ( aAttribs.hasAttribute( XML_b ) )
+ mrTextCharacterProperties.moBold = aAttribs.getBool( XML_b );
+ if ( aAttribs.hasAttribute( XML_i ) )
+ mrTextCharacterProperties.moItalic = aAttribs.getBool( XML_i );
+
+// TODO
+/* todo: we need to be able to iterate over the XFastAttributes
+
+ // ST_TextNonNegativePoint
+ const OUString sCharKerning( CREATE_OUSTRING( "CharKerning" ) );
+ //case A_TOKEN( kern ):
+
+ // ST_TextLanguageID
+ OUString sAltLang = rXAttributes->getOptionalValue( XML_altLang );
+
+ case A_TOKEN( kumimoji ): // xsd:boolean
+ break;
+ case A_TOKEN( spc ): // ST_TextPoint
+ case A_TOKEN( normalizeH ): // xsd:boolean
+ case A_TOKEN( baseline ): // ST_Percentage
+ case A_TOKEN( noProof ): // xsd:boolean
+ case A_TOKEN( dirty ): // xsd:boolean
+ case A_TOKEN( err ): // xsd:boolean
+ case A_TOKEN( smtClean ): // xsd:boolean
+ case A_TOKEN( smtId ): // xsd:unsignedInt
+ break;
+*/
+
+}
+
+TextCharacterPropertiesContext::~TextCharacterPropertiesContext()
+{
+}
+
+// --------------------------------------------------------------------
+
+void TextCharacterPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextCharacterPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttributes ) throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( xAttributes );
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+// TODO unsupported yet
+// case A_TOKEN( ln ): // CT_LineProperties
+// xRet.set( new LinePropertiesContext( getHandler(), xAttributes, maTextOutlineProperties ) );
+// break;
+
+ case A_TOKEN( solidFill ): // EG_FillProperties
+ xRet.set( new ColorContext( *this, mrTextCharacterProperties.maCharColor ) );
+ break;
+
+ // EG_EffectProperties
+ case A_TOKEN( effectDag ): // CT_EffectContainer 5.1.10.25
+ case A_TOKEN( effectLst ): // CT_EffectList 5.1.10.26
+ break;
+
+ case A_TOKEN( highlight ): // CT_Color
+ xRet.set( new ColorContext( *this, mrTextCharacterProperties.maHighlightColor ) );
+ break;
+
+ // EG_TextUnderlineLine
+ case A_TOKEN( uLnTx ): // CT_TextUnderlineLineFollowText
+ mrTextCharacterProperties.moUnderlineLineFollowText = true;
+ break;
+// TODO unsupported yet
+// case A_TOKEN( uLn ): // CT_LineProperties
+// xRet.set( new LinePropertiesContext( getHandler(), xAttributes, maUnderlineProperties ) );
+// break;
+
+ // EG_TextUnderlineFill
+ case A_TOKEN( uFillTx ): // CT_TextUnderlineFillFollowText
+ mrTextCharacterProperties.moUnderlineFillFollowText = true;
+ break;
+ case A_TOKEN( uFill ): // CT_TextUnderlineFillGroupWrapper->EG_FillProperties (not supported)
+ xRet.set( new SimpleFillPropertiesContext( *this, mrTextCharacterProperties.maUnderlineColor ) );
+ break;
+
+ // CT_FontCollection
+ case A_TOKEN( latin ): // CT_TextFont
+ mrTextCharacterProperties.maLatinFont.setAttributes( aAttribs );
+ break;
+ case A_TOKEN( ea ): // CT_TextFont
+ mrTextCharacterProperties.maAsianFont.setAttributes( aAttribs );
+ break;
+ case A_TOKEN( cs ): // CT_TextFont
+ mrTextCharacterProperties.maComplexFont.setAttributes( aAttribs );
+ break;
+ case A_TOKEN( sym ): // CT_TextFont
+ mrTextCharacterProperties.maSymbolFont.setAttributes( aAttribs );
+ break;
+
+ case A_TOKEN( hlinkClick ): // CT_Hyperlink
+ case A_TOKEN( hlinkMouseOver ): // CT_Hyperlink
+ xRet.set( new HyperLinkContext( *this, xAttributes, mrTextCharacterProperties.maHyperlinkPropertyMap ) );
+ 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..c3049415c89a
--- /dev/null
+++ b/oox/source/drawingml/textfield.cxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/helper/propertyset.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/textparagraphproperties.hxx"
+#include "oox/drawingml/textcharacterproperties.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()
+{
+}
+
+namespace {
+
+/** 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.
+ */
+void lclCreateTextFields( 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
+ lclCreateTextFields( aFields, xModel, CREATE_OUSTRING( "datetime12" ) );
+ break;
+ case 9: // DateTime dd/mm/yy H:MM:SS PM
+ lclCreateTextFields( 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 ) );
+ }
+}
+
+} // namespace
+
+void TextField::insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XText > & xText,
+ const Reference < XTextCursor > &xAt,
+ const TextCharacterProperties& rTextCharacterStyle ) const
+{
+ try
+ {
+ PropertyMap aioBulletList;
+ Reference< XTextRange > xStart( xAt, UNO_QUERY );
+ Reference< XPropertySet > xProps( xStart, UNO_QUERY);
+ PropertySet aPropSet( xProps );
+
+ maTextParagraphProperties.pushToPropSet( rFilterBase, xProps, aioBulletList, NULL, sal_True, 18 );
+
+ TextCharacterProperties aTextCharacterProps( rTextCharacterStyle );
+ aTextCharacterProps.assignUsed( maTextParagraphProperties.getTextCharacterProperties() );
+ aTextCharacterProps.assignUsed( getTextCharacterProperties() );
+ aTextCharacterProps.pushToPropSet( aPropSet, rFilterBase );
+
+ std::list< Reference< XTextField > > fields;
+ lclCreateTextFields( fields, rFilterBase.getModel(), 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, getText(), 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..4e9f576a0ca9
--- /dev/null
+++ b/oox/source/drawingml/textfieldcontext.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textfieldcontext.hxx"
+#include "oox/drawingml/textparagraphpropertiescontext.hxx"
+#include "oox/drawingml/textcharacterpropertiescontext.hxx"
+#include "oox/drawingml/textfield.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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rXAttributes,
+ TextField& rTextField)
+ : ContextHandler( rParent )
+ , mrTextField( rTextField )
+ , mbIsInText( false )
+{
+ mrTextField.setUuid( rXAttributes->getOptionalValue( XML_id ) );
+ mrTextField.setType( rXAttributes->getOptionalValue( XML_type ) );
+}
+
+void TextFieldContext::endFastElement( sal_Int32 aElementToken ) throw (SAXException, RuntimeException)
+{
+ if( aElementToken == (A_TOKEN( t )) )
+ {
+ mbIsInText = false;
+ }
+}
+
+void TextFieldContext::characters( const OUString& aChars ) throw (SAXException, RuntimeException)
+{
+ if( mbIsInText )
+ {
+ mrTextField.getText() += aChars;
+ }
+}
+
+Reference< XFastContextHandler > TextFieldContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case A_TOKEN( rPr ):
+ xRet.set( new TextCharacterPropertiesContext( *this, xAttribs, mrTextField.getTextCharacterProperties() ) );
+ break;
+ case A_TOKEN( pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, xAttribs, mrTextField.getTextParagraphProperties() ) );
+ break;
+ case A_TOKEN( t ):
+ mbIsInText = true;
+ break;
+ }
+ if ( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+}
+
+
+} }
diff --git a/oox/source/drawingml/textfont.cxx b/oox/source/drawingml/textfont.cxx
new file mode 100644
index 000000000000..b4f9d359fb14
--- /dev/null
+++ b/oox/source/drawingml/textfont.cxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textfont.hxx"
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontPitch.hpp>
+#include "oox/drawingml/theme.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using ::rtl::OUString;
+using ::oox::core::XmlFilterBase;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+namespace {
+
+sal_Int16 lclGetFontPitch( sal_Int32 nOoxValue )
+{
+ using namespace ::com::sun::star::awt::FontPitch;
+ static const sal_Int16 spnFontPitch[] = { DONTKNOW, FIXED, VARIABLE };
+ return STATIC_ARRAY_SELECT( spnFontPitch, nOoxValue, DONTKNOW );
+}
+
+sal_Int16 lclGetFontFamily( sal_Int32 nOoxValue )
+{
+ using namespace ::com::sun::star::awt::FontFamily;
+ static const sal_Int16 spnFontFamily[] = { DONTKNOW, ROMAN, SWISS, MODERN, SCRIPT, DECORATIVE };
+ return STATIC_ARRAY_SELECT( spnFontFamily, nOoxValue, DONTKNOW );
+}
+
+} // namespace
+
+// ============================================================================
+
+TextFont::TextFont() :
+ mnPitch( 0 ),
+ mnCharset( WINDOWS_CHARSET_ANSI )
+{
+}
+
+void TextFont::setAttributes( const AttributeList& rAttribs )
+{
+ maTypeface = rAttribs.getString( XML_typeface, OUString() );
+ maPanose = rAttribs.getString( XML_panose, OUString() );
+ mnPitch = rAttribs.getInteger( XML_pitchFamily, 0 );
+ mnCharset = rAttribs.getInteger( XML_charset, WINDOWS_CHARSET_DEFAULT );
+}
+
+void TextFont::assignIfUsed( const TextFont& rTextFont )
+{
+ if( rTextFont.maTypeface.getLength() > 0 )
+ *this = rTextFont;
+}
+
+bool TextFont::getFontData( OUString& rFontName, sal_Int16 rnFontPitch, sal_Int16& rnFontFamily, const XmlFilterBase& rFilter ) const
+{
+ if( const Theme* pTheme = rFilter.getCurrentTheme() )
+ if( const TextFont* pFont = pTheme->resolveFont( maTypeface ) )
+ return pFont->implGetFontData( rFontName, rnFontPitch, rnFontFamily );
+ return implGetFontData( rFontName, rnFontPitch, rnFontFamily );
+}
+
+bool TextFont::implGetFontData( OUString& rFontName, sal_Int16 rnFontPitch, sal_Int16& rnFontFamily ) const
+{
+ rFontName = maTypeface;
+ rnFontPitch = lclGetFontPitch( extractValue< sal_Int16 >( mnPitch, 0, 4 ) );
+ rnFontFamily = lclGetFontFamily( extractValue< sal_Int16 >( mnPitch, 4, 4 ) );
+ return rFontName.getLength() > 0;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/textliststyle.cxx b/oox/source/drawingml/textliststyle.cxx
new file mode 100644
index 000000000000..8a491076909f
--- /dev/null
+++ b/oox/source/drawingml/textliststyle.cxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textliststyle.hxx"
+
+namespace oox { namespace drawingml {
+
+TextListStyle::TextListStyle()
+{
+ for ( int i = 0; i < 9; i++ )
+ {
+ maListStyle.push_back( TextParagraphPropertiesPtr( new TextParagraphProperties() ) );
+ maAggregationListStyle.push_back( TextParagraphPropertiesPtr( new TextParagraphProperties() ) );
+ }
+}
+
+TextListStyle::~TextListStyle()
+{
+}
+
+void applyStyleList( const TextParagraphPropertiesVector& rSourceListStyle, TextParagraphPropertiesVector& rDestListStyle )
+{
+ TextParagraphPropertiesVector::const_iterator aSourceListStyleIter( rSourceListStyle.begin() );
+ TextParagraphPropertiesVector::iterator aDestListStyleIter( rDestListStyle.begin() );
+ while( aSourceListStyleIter != rSourceListStyle.end() )
+ {
+ if ( aDestListStyleIter != rDestListStyle.end() )
+ {
+ (*aDestListStyleIter)->apply( **aSourceListStyleIter );
+ aDestListStyleIter++;
+ }
+ else
+ rDestListStyle.push_back( TextParagraphPropertiesPtr( new TextParagraphProperties( **aSourceListStyleIter ) ) );
+ aSourceListStyleIter++;
+ }
+}
+
+void TextListStyle::apply( const TextListStyle& rTextListStyle )
+{
+ applyStyleList( rTextListStyle.getAggregationListStyle(), getAggregationListStyle() );
+ applyStyleList( rTextListStyle.getListStyle(), getListStyle() );
+}
+
+} }
diff --git a/oox/source/drawingml/textliststylecontext.cxx b/oox/source/drawingml/textliststylecontext.cxx
new file mode 100644
index 000000000000..21afc698d730
--- /dev/null
+++ b/oox/source/drawingml/textliststylecontext.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/drawingml/textparagraphpropertiescontext.hxx"
+#include "oox/helper/attributelist.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( ContextHandler& rParent, TextListStyle& rTextListStyle )
+: ContextHandler( rParent )
+, 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 A_TOKEN( defPPr ): // CT_TextParagraphProperties
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 0 ] ) );
+ break;
+ case A_TOKEN( outline1pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getAggregationListStyle()[ 0 ] ) );
+ break;
+ case A_TOKEN( outline2pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getAggregationListStyle()[ 1 ] ) );
+ break;
+ case A_TOKEN( lvl1pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 0 ] ) );
+ break;
+ case A_TOKEN( lvl2pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 1 ] ) );
+ break;
+ case A_TOKEN( lvl3pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 2 ] ) );
+ break;
+ case A_TOKEN( lvl4pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 3 ] ) );
+ break;
+ case A_TOKEN( lvl5pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 4 ] ) );
+ break;
+ case A_TOKEN( lvl6pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 5 ] ) );
+ break;
+ case A_TOKEN( lvl7pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 6 ] ) );
+ break;
+ case A_TOKEN( lvl8pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 7 ] ) );
+ break;
+ case A_TOKEN( lvl9pPr ):
+ xRet.set( new TextParagraphPropertiesContext( *this, rxAttributes, *mrTextListStyle.getListStyle()[ 8 ] ) );
+ 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..a4bef1a5013c
--- /dev/null
+++ b/oox/source/drawingml/textparagraph.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textparagraph.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+
+#include <rtl/ustring.hxx>
+#include "oox/helper/propertyset.hxx"
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+
+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()
+{
+}
+
+TextParagraph::~TextParagraph()
+{
+}
+
+void TextParagraph::insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XText > &xText,
+ const Reference < XTextCursor > &xAt,
+ const TextCharacterProperties& rTextStyleProperties,
+ const TextListStyle& rTextListStyle, bool bFirst) const
+{
+ try {
+ sal_Int32 nParagraphSize = 0;
+ Reference< XTextRange > xStart( xAt, UNO_QUERY );
+
+ sal_Int16 nLevel = maProperties.getLevel();
+ const TextParagraphPropertiesVector& rListStyle = rTextListStyle.getListStyle();
+ if ( nLevel >= static_cast< sal_Int16 >( rListStyle.size() ) )
+ nLevel = 0;
+ TextParagraphPropertiesPtr pTextParagraphStyle;
+ if ( rListStyle.size() )
+ pTextParagraphStyle = rListStyle[ nLevel ];
+
+ TextCharacterProperties aTextCharacterStyle( rTextStyleProperties );
+ if ( pTextParagraphStyle.get() )
+ aTextCharacterStyle.assignUsed( pTextParagraphStyle->getTextCharacterProperties() );
+ aTextCharacterStyle.assignUsed( maProperties.getTextCharacterProperties() );
+
+ if( !bFirst )
+ {
+ xText->insertControlCharacter( xStart, ControlCharacter::APPEND_PARAGRAPH, sal_False );
+ xAt->gotoEnd( sal_True );
+ }
+ if ( maRuns.begin() == maRuns.end() )
+ {
+ PropertySet aPropSet( xStart );
+
+ TextCharacterProperties aTextCharacterProps( aTextCharacterStyle );
+ aTextCharacterProps.assignUsed( maEndProperties );
+ aTextCharacterProps.pushToPropSet( aPropSet, rFilterBase );
+ }
+ else
+ {
+ for( TextRunVector::const_iterator aIt = maRuns.begin(), aEnd = maRuns.end(); aIt != aEnd; ++aIt )
+ {
+ (*aIt)->insertAt( rFilterBase, xText, xAt, aTextCharacterStyle );
+ nParagraphSize += (*aIt)->getText().getLength();
+ }
+ }
+ xAt->gotoEnd( sal_True );
+
+ PropertyMap aioBulletList;
+ Reference< XPropertySet > xProps( xStart, UNO_QUERY);
+ float fCharacterSize = 18;
+ if ( pTextParagraphStyle.get() )
+ {
+ pTextParagraphStyle->pushToPropSet( rFilterBase, xProps, aioBulletList, NULL, sal_False, fCharacterSize );
+ fCharacterSize = pTextParagraphStyle->getCharHeightPoints( 18 );
+ }
+ maProperties.pushToPropSet( rFilterBase, xProps, aioBulletList, &pTextParagraphStyle->getBulletList(), sal_True, fCharacterSize );
+
+ // empty paragraphs do not have bullets in ppt
+ if ( !nParagraphSize )
+ {
+ const OUString sNumberingLevel( CREATE_OUSTRING( "NumberingLevel" ) );
+ xProps->setPropertyValue( sNumberingLevel, Any( static_cast< sal_Int16 >( -1 ) ) );
+ }
+
+// 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..cd969874513e
--- /dev/null
+++ b/oox/source/drawingml/textparagraphproperties.cxx
@@ -0,0 +1,423 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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 <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/drawingmltypes.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::setGraphic( ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic >& rXGraphic )
+{
+ mnNumberingType <<= NumberingType::BITMAP;
+ maGraphic <<= rXGraphic;
+}
+
+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;
+ maBulletFont.assignIfUsed( 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;
+ if ( rSource.maGraphic.hasValue() )
+ maGraphic = rSource.maGraphic;
+}
+
+void BulletList::pushToPropMap( const ::oox::core::XmlFilterBase& rFilterBase, PropertyMap& rPropMap ) const
+{
+ if( msNumberingPrefix.hasValue() )
+ rPropMap[ PROP_Prefix ] = msNumberingPrefix;
+ if( msNumberingSuffix.hasValue() )
+ rPropMap[ PROP_Suffix ] = msNumberingSuffix;
+ if( mnStartAt.hasValue() )
+ rPropMap[ PROP_StartWith ] = mnStartAt;
+ rPropMap[ PROP_Adjust ] <<= HoriOrientation::LEFT;
+
+ if( mnNumberingType.hasValue() )
+ rPropMap[ PROP_NumberingType ] = mnNumberingType;
+
+ OUString aBulletFontName;
+ sal_Int16 nBulletFontPitch = 0;
+ sal_Int16 nBulletFontFamily = 0;
+ if( maBulletFont.getFontData( aBulletFontName, nBulletFontPitch, nBulletFontFamily, rFilterBase ) )
+ {
+ FontDescriptor aFontDesc;
+ sal_Int16 nFontSize = 0;
+ if( mnFontSize >>= nFontSize )
+ aFontDesc.Height = nFontSize;
+
+ // TODO move the to the TextFont struct.
+ aFontDesc.Name = aBulletFontName;
+ aFontDesc.Pitch = nBulletFontPitch;
+ aFontDesc.Family = nBulletFontFamily;
+ rPropMap[ PROP_BulletFont ] <<= aFontDesc;
+ rPropMap[ PROP_BulletFontName ] <<= aBulletFontName;
+ }
+ if ( msBulletChar.hasValue() )
+ rPropMap[ PROP_BulletChar ] = msBulletChar;
+ if ( maGraphic.hasValue() )
+ {
+ Reference< com::sun::star::awt::XBitmap > xBitmap( maGraphic, UNO_QUERY );
+ if ( xBitmap.is() )
+ rPropMap[ PROP_Graphic ] <<= xBitmap;
+ }
+ if( mnSize.hasValue() )
+ rPropMap[ PROP_BulletRelSize ] = mnSize;
+ if ( maStyleName.hasValue() )
+ rPropMap[ PROP_CharStyleName ] <<= maStyleName;
+ if ( maBulletColorPtr->isUsed() )
+ rPropMap[ PROP_BulletColor ] <<= maBulletColorPtr->getColor( rFilterBase.getGraphicHelper() );
+}
+
+TextParagraphProperties::TextParagraphProperties()
+: mnLevel( 0 )
+{
+}
+
+TextParagraphProperties::~TextParagraphProperties()
+{
+}
+
+void TextParagraphProperties::apply( const TextParagraphProperties& rSourceProps )
+{
+ maTextParagraphPropertyMap.insert( rSourceProps.maTextParagraphPropertyMap.begin(), rSourceProps.maTextParagraphPropertyMap.end() );
+ maBulletList.apply( rSourceProps.maBulletList );
+ maTextCharacterProperties.assignUsed( rSourceProps.maTextCharacterProperties );
+ if ( rSourceProps.maParaTopMargin.bHasValue )
+ maParaTopMargin = rSourceProps.maParaTopMargin;
+ if ( rSourceProps.maParaBottomMargin.bHasValue )
+ maParaBottomMargin = rSourceProps.maParaBottomMargin;
+ if ( rSourceProps.moParaLeftMargin )
+ moParaLeftMargin = rSourceProps.moParaLeftMargin;
+ if ( rSourceProps.moFirstLineIndentation )
+ moFirstLineIndentation = rSourceProps.moFirstLineIndentation;
+}
+
+void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, const BulletList* pMasterBuList, sal_Bool bApplyBulletMap, float fCharacterSize ) const
+{
+ PropertySet aPropSet( xPropSet );
+ aPropSet.setProperties( maTextParagraphPropertyMap );
+
+ sal_Int32 nNumberingType = NumberingType::NUMBER_NONE;
+ if ( maBulletList.mnNumberingType.hasValue() )
+ maBulletList.mnNumberingType >>= nNumberingType;
+ else if ( pMasterBuList && pMasterBuList->mnNumberingType.hasValue() )
+ pMasterBuList->mnNumberingType >>= nNumberingType;
+ if ( nNumberingType == NumberingType::NUMBER_NONE )
+ aPropSet.setProperty< sal_Int16 >( PROP_NumberingLevel, -1 );
+
+ maBulletList.pushToPropMap( rFilterBase, rioBulletMap );
+
+ if ( maParaTopMargin.bHasValue )
+ aPropSet.setProperty( PROP_ParaTopMargin, maParaTopMargin.toMargin( getCharHeightPoints( 18.0 ) ) );
+ if ( maParaBottomMargin.bHasValue )
+ aPropSet.setProperty( PROP_ParaBottomMargin, maParaBottomMargin.toMargin( getCharHeightPoints( 18.0 ) ) );
+ if ( nNumberingType == NumberingType::BITMAP )
+ {
+ fCharacterSize = getCharHeightPoints( fCharacterSize );
+
+ com::sun::star::awt::Size aBulletSize;
+ aBulletSize.Width = aBulletSize.Height = static_cast< sal_Int32 >( ( fCharacterSize * ( 2540.0 / 72.0 ) * 0.8 ) );
+ rioBulletMap[ PROP_GraphicSize ] <<= aBulletSize;
+ }
+
+ boost::optional< sal_Int32 > noParaLeftMargin( moParaLeftMargin );
+ boost::optional< sal_Int32 > noFirstLineIndentation( moFirstLineIndentation );
+
+ if ( nNumberingType != NumberingType::NUMBER_NONE )
+ {
+ if ( noParaLeftMargin )
+ {
+ rioBulletMap[ PROP_LeftMargin ] <<= static_cast< sal_Int32 >( *noParaLeftMargin );
+ noParaLeftMargin = boost::optional< sal_Int32 >( 0 );
+ }
+ if ( noFirstLineIndentation )
+ {
+ rioBulletMap[ PROP_FirstLineOffset ] <<= static_cast< sal_Int32 >( *noFirstLineIndentation );
+ noFirstLineIndentation = boost::optional< sal_Int32 >( 0 );
+ }
+ }
+
+ if ( bApplyBulletMap )
+ {
+ Reference< XIndexReplace > xNumRule;
+ aPropSet.getProperty( xNumRule, PROP_NumberingRules );
+ OSL_ENSURE( xNumRule.is(), "can't get Numbering rules");
+
+ if( xNumRule.is() )
+ {
+ if( !rioBulletMap.empty() )
+ {
+ Sequence< PropertyValue > aBulletPropSeq = rioBulletMap.makePropertyValueSequence();
+ xNumRule->replaceByIndex( getLevel(), makeAny( aBulletPropSeq ) );
+ }
+
+ aPropSet.setProperty( PROP_NumberingRules, xNumRule );
+ }
+ }
+ if ( noParaLeftMargin )
+ aPropSet.setProperty( PROP_ParaLeftMargin, *noParaLeftMargin );
+ if ( noFirstLineIndentation )
+ aPropSet.setProperty( PROP_ParaFirstLineIndent, *noFirstLineIndentation );
+}
+
+float TextParagraphProperties::getCharHeightPoints( float fDefault ) const
+{
+ return maTextCharacterProperties.getCharHeightPoints( fDefault );
+}
+
+} }
diff --git a/oox/source/drawingml/textparagraphpropertiescontext.cxx b/oox/source/drawingml/textparagraphpropertiescontext.cxx
new file mode 100644
index 000000000000..eb888867556b
--- /dev/null
+++ b/oox/source/drawingml/textparagraphpropertiescontext.cxx
@@ -0,0 +1,283 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/fillproperties.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "textspacingcontext.hxx"
+#include "texttabstoplistcontext.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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ TextParagraphProperties& rTextParagraphProperties )
+: ContextHandler( rParent )
+, 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 );
+ rPropertyMap[ PROP_ParaAdjust ] <<= 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 );
+ rPropertyMap[ PROP_ParaIsHyphenation ] <<= 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 );
+ rPropertyMap[ PROP_ParaIsHangingPunctuation ] <<= bHangingPunct;
+ }
+
+ // ST_Coordinate
+ if ( xAttribs->hasAttribute( XML_indent ) )
+ {
+ sValue = xAttribs->getOptionalValue( XML_indent );
+ mrTextParagraphProperties.getFirstLineIndentation() = boost::optional< sal_Int32 >( 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 );
+ mrTextParagraphProperties.getParaLeftMargin() = boost::optional< sal_Int32 >( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
+ }
+
+ // ParaRightMargin
+ if ( xAttribs->hasAttribute( XML_marR ) )
+ {
+ sValue = xAttribs->getOptionalValue( XML_marR );
+ sal_Int32 nMarR = ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
+ rPropertyMap[ PROP_ParaRightMargin ] <<= nMarR;
+ }
+
+ if ( xAttribs->hasAttribute( XML_rtl ) )
+ {
+ bool bRtl = attribs.getBool( XML_rtl, false );
+ rPropertyMap[ PROP_TextWritingMode ] <<= ( bRtl ? WritingMode_RL_TB : WritingMode_LR_TB );
+ }
+}
+
+
+
+TextParagraphPropertiesContext::~TextParagraphPropertiesContext()
+{
+ PropertyMap& rPropertyMap( mrTextParagraphProperties.getTextParagraphPropertyMap() );
+ if ( maLineSpacing.bHasValue )
+ rPropertyMap[ PROP_ParaLineSpacing ] <<= 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 );
+ rPropertyMap[ PROP_ParaTabStops ] <<= aSeq;
+ }
+
+ if ( mxBlipProps.get() && mxBlipProps->mxGraphic.is() )
+ mrBulletList.setGraphic( mxBlipProps->mxGraphic );
+
+ if( mrBulletList.is() )
+ rPropertyMap[ PROP_IsNumbering ] <<= sal_True;
+ sal_Int16 nLevel = mrTextParagraphProperties.getLevel();
+ rPropertyMap[ PROP_NumberingLevel ] <<= nLevel;
+ rPropertyMap[ PROP_NumberingIsNumber ] <<= sal_True;
+}
+
+// --------------------------------------------------------------------
+
+void TextParagraphPropertiesContext::endFastElement( sal_Int32 ) throw (SAXException, RuntimeException)
+{
+}
+
+
+
+// --------------------------------------------------------------------
+
+Reference< XFastContextHandler > TextParagraphPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& rXAttributes ) throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( rXAttributes );
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case A_TOKEN( lnSpc ): // CT_TextSpacing
+ xRet.set( new TextSpacingContext( *this, maLineSpacing ) );
+ break;
+ case A_TOKEN( spcBef ): // CT_TextSpacing
+ xRet.set( new TextSpacingContext( *this, mrSpaceBefore ) );
+ break;
+ case A_TOKEN( spcAft ): // CT_TextSpacing
+ xRet.set( new TextSpacingContext( *this, mrSpaceAfter ) );
+ break;
+
+ // EG_TextBulletColor
+ case A_TOKEN( buClrTx ): // CT_TextBulletColorFollowText ???
+ mrBulletList.mbBulletColorFollowText <<= sal_True;
+ break;
+ case A_TOKEN( buClr ): // CT_Color
+ xRet.set( new ColorContext( *this, *mrBulletList.maBulletColorPtr ) );
+ break;
+
+ // EG_TextBulletSize
+ case A_TOKEN( buSzTx ): // CT_TextBulletSizeFollowText
+ mrBulletList.setBulletSize(100);
+ break;
+ case A_TOKEN( buSzPct ): // CT_TextBulletSizePercent
+ mrBulletList.setBulletSize( static_cast<sal_Int16>( GetPercent( rXAttributes->getOptionalValue( XML_val ) ) / 1000 ) );
+ break;
+ case A_TOKEN( buSzPts ): // CT_TextBulletSizePoint
+ mrBulletList.setBulletSize(0);
+ mrBulletList.setFontSize( static_cast<sal_Int16>(GetTextSize( rXAttributes->getOptionalValue( XML_val ) ) ) );
+ break;
+
+ // EG_TextBulletTypeface
+ case A_TOKEN( buFontTx ): // CT_TextBulletTypefaceFollowText
+ mrBulletList.mbBulletFontFollowText <<= sal_True;
+ break;
+ case A_TOKEN( buFont ): // CT_TextFont
+ mrBulletList.maBulletFont.setAttributes( aAttribs );
+ break;
+
+ // EG_TextBullet
+ case A_TOKEN( buNone ): // CT_TextNoBullet
+ mrBulletList.setNone();
+ break;
+ case A_TOKEN( 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 A_TOKEN( buChar ): // CT_TextCharBullet
+ try {
+ mrBulletList.setBulletChar( rXAttributes->getValue( XML_char ) );
+ }
+ catch(SAXException& /* e */)
+ {
+ OSL_TRACE("OOX: SAXException in XML_buChar");
+ }
+ break;
+ case A_TOKEN( buBlip ): // CT_TextBlipBullet
+ {
+ mxBlipProps.reset( new BlipFillProperties );
+ xRet.set( new BlipFillContext( *this, rXAttributes, *mxBlipProps ) );
+ }
+ break;
+
+ case A_TOKEN( tabLst ): // CT_TextTabStopList
+ xRet.set( new TextTabStopListContext( *this, maTabList ) );
+ break;
+ case A_TOKEN( defRPr ): // CT_TextCharacterProperties
+ xRet.set( new TextCharacterPropertiesContext( *this, rXAttributes, mrTextParagraphProperties.getTextCharacterProperties() ) );
+ 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..1e435defaa2d
--- /dev/null
+++ b/oox/source/drawingml/textrun.cxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textrun.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"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/xmlfilterbase.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 )
+{
+}
+
+TextRun::~TextRun()
+{
+}
+
+void TextRun::insertAt(
+ const ::oox::core::XmlFilterBase& rFilterBase,
+ const Reference < XText > & xText,
+ const Reference < XTextCursor > &xAt,
+ const TextCharacterProperties& rTextCharacterStyle ) const
+{
+ try {
+ Reference< XTextRange > xStart( xAt, UNO_QUERY );
+ PropertySet aPropSet( xStart );
+
+ TextCharacterProperties aTextCharacterProps( rTextCharacterStyle );
+ aTextCharacterProps.assignUsed( maTextCharacterProperties );
+ aTextCharacterProps.pushToPropSet( aPropSet, rFilterBase );
+
+ if( maTextCharacterProperties.maHyperlinkPropertyMap.empty() )
+ {
+ if( mbIsLineBreak )
+ {
+ OSL_TRACE( "OOX: TextRun::insertAt() insert line break" );
+ xText->insertControlCharacter( xStart, ControlCharacter::LINE_BREAK, sal_False );
+ }
+ else
+ {
+ OUString aLatinFontName, aSymbolFontName;
+ sal_Int16 nLatinFontPitch = 0, nSymbolFontPitch = 0;
+ sal_Int16 nLatinFontFamily = 0, nSymbolFontFamily = 0;
+
+ if ( !aTextCharacterProps.maSymbolFont.getFontData( aSymbolFontName, nSymbolFontPitch, nSymbolFontFamily, rFilterBase ) )
+ xText->insertString( xStart, getText(), sal_False );
+ else if ( getText().getLength() )
+ { // !!#i113673<<<
+ aTextCharacterProps.maLatinFont.getFontData( aLatinFontName, nLatinFontPitch, nLatinFontFamily, rFilterBase );
+
+ sal_Int32 nIndex = 0;
+ while ( sal_True )
+ {
+ sal_Int32 nCount = 0;
+ sal_Bool bSymbol = ( getText()[ nIndex ] & 0xff00 ) == 0xf000;
+ if ( bSymbol )
+ {
+ do
+ {
+ nCount++;
+ }
+ while( ( ( nCount + nIndex ) < getText().getLength() ) && ( ( getText()[ nCount + nIndex ] & 0xff00 ) == 0xf000 ) );
+ aPropSet.setAnyProperty( PROP_CharFontName, Any( aSymbolFontName ) );
+ aPropSet.setAnyProperty( PROP_CharFontPitch, Any( nSymbolFontPitch ) );
+ aPropSet.setAnyProperty( PROP_CharFontFamily, Any( nSymbolFontFamily ) );
+ }
+ else
+ {
+ do
+ {
+ nCount++;
+ }
+ while( ( ( nCount + nIndex ) < getText().getLength() ) && ( ( getText()[ nCount + nIndex ] & 0xff00 ) != 0xf000 ) );
+ aPropSet.setAnyProperty( PROP_CharFontName, Any( aLatinFontName ) );
+ aPropSet.setAnyProperty( PROP_CharFontPitch, Any( nLatinFontPitch ) );
+ aPropSet.setAnyProperty( PROP_CharFontFamily, Any( nLatinFontFamily ) );
+ }
+ rtl::OUString aSubString( getText().copy( nIndex, nCount ) );
+ xText->insertString( xStart, aSubString, sal_False );
+ nIndex += nCount;
+
+ if ( nIndex >= getText().getLength() )
+ break;
+
+ xStart = Reference< XTextRange >( xAt, UNO_QUERY );
+ aPropSet = PropertySet( xStart );
+ aTextCharacterProps.pushToPropSet( aPropSet, rFilterBase );
+ }
+ }
+ }
+ }
+ else
+ {
+ OSL_TRACE( "OOX: URL field" );
+ Reference< XMultiServiceFactory > xFactory( rFilterBase.getModel(), UNO_QUERY );
+ Reference< XTextField > xField( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ), UNO_QUERY );
+ if( xField.is() )
+ {
+ Reference< XTextCursor > xTextFieldCursor = xText->createTextCursor();
+ xTextFieldCursor->gotoEnd( sal_False );
+
+ PropertySet aFieldProps( xField );
+ aFieldProps.setProperties( maTextCharacterProperties.maHyperlinkPropertyMap );
+ aFieldProps.setProperty( PROP_Representation, getText() );
+ Reference< XTextContent > xContent( xField, UNO_QUERY);
+ xText->insertTextContent( xStart, xContent, sal_False );
+
+ xTextFieldCursor->gotoEnd( sal_True );
+ oox::core::TextField aTextField;
+ aTextField.xText = xText;
+ aTextField.xTextCursor = xTextFieldCursor;
+ aTextField.xTextField = xField;
+ rFilterBase.getTextFieldStack().push_back( aTextField );
+ }
+ else
+ {
+ OSL_TRACE( "OOX: URL field couldn't be created" );
+ xText->insertString( xStart, getText(), 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..5eb5f3d77f82
--- /dev/null
+++ b/oox/source/drawingml/textspacingcontext.cxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/textspacing.hxx"
+#include "textspacingcontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
+
+namespace oox { namespace drawingml {
+
+ TextSpacingContext::TextSpacingContext( ContextHandler& rParent, TextSpacing & aSpacing )
+ : ContextHandler( rParent )
+ , 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 A_TOKEN( spcPct ):
+ maSpacing.nUnit = TextSpacing::PERCENT;
+ maSpacing.nValue = GetPercent( xAttribs->getValue( XML_val ) );
+ break;
+ case A_TOKEN( 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..5b646c14d240
--- /dev/null
+++ b/oox/source/drawingml/textspacingcontext.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTSPACINGCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTSPACINGCONTEXT_HXX
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+class TextSpacing;
+
+class TextSpacingContext : public ::oox::core::ContextHandler
+{
+public:
+ TextSpacingContext( ::oox::core::ContextHandler& rParent, 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..78248fd0b6f7
--- /dev/null
+++ b/oox/source/drawingml/texttabstoplistcontext.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <list>
+#include <algorithm>
+
+#include <rtl/ustring.hxx>
+
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "texttabstoplistcontext.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( ContextHandler& rParent, std::list< TabStop > & aTabList )
+ : ContextHandler( rParent )
+ , 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 A_TOKEN( 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..5545e1231e3d
--- /dev/null
+++ b/oox/source/drawingml/texttabstoplistcontext.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_DRAWINGML_TEXTTABSTOPLISTCONTEXT_HXX
+#define OOX_DRAWINGML_TEXTTABSTOPLISTCONTEXT_HXX
+
+#include <list>
+
+#include <com/sun/star/style/TabStop.hpp>
+
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace drawingml {
+
+ class TextTabStopListContext : public ::oox::core::ContextHandler
+ {
+ public:
+ TextTabStopListContext( ::oox::core::ContextHandler& rParent,
+ ::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..b37ccdbaf13c
--- /dev/null
+++ b/oox/source/drawingml/theme.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/theme.hxx"
+
+using ::rtl::OUString;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+Theme::Theme()
+{
+}
+
+Theme::~Theme()
+{
+}
+
+namespace {
+
+template< typename Type >
+const Type* lclGetStyleElement( const RefVector< Type >& rVector, sal_Int32 nIndex )
+{
+ return (rVector.empty() || (nIndex < 1)) ? 0 :
+ rVector.get( ::std::min( static_cast< sal_Int32 >( nIndex - 1 ), static_cast< sal_Int32 >( rVector.size() - 1 ) ) ).get();
+}
+
+} // namespace
+
+const FillProperties* Theme::getFillStyle( sal_Int32 nIndex ) const
+{
+ return (nIndex >= 1000) ?
+ lclGetStyleElement( maBgFillStyleList, nIndex - 1000 ) :
+ lclGetStyleElement( maFillStyleList, nIndex );
+}
+
+const LineProperties* Theme::getLineStyle( sal_Int32 nIndex ) const
+{
+ return lclGetStyleElement( maLineStyleList, nIndex );
+}
+
+const PropertyMap* Theme::getEffectStyle( sal_Int32 nIndex ) const
+{
+ return lclGetStyleElement( maEffectStyleList, nIndex );
+}
+
+const TextCharacterProperties* Theme::getFontStyle( sal_Int32 nSchemeType ) const
+{
+ return maFontScheme.get( nSchemeType ).get();
+}
+
+const TextFont* Theme::resolveFont( const OUString& rName ) const
+{
+ /* Resolves the following names:
+ +mj-lt, +mj-ea, +mj-cs -- major Latin, Asian, Complex font
+ +mn-lt, +mn-ea, +mn-cs -- minor Latin, Asian, Complex font
+ */
+ if( (rName.getLength() == 6) && (rName[ 0 ] == '+') && (rName[ 3 ] == '-') )
+ {
+ const TextCharacterProperties* pCharProps = 0;
+ if( (rName[ 1 ] == 'm') && (rName[ 2 ] == 'j') )
+ pCharProps = maFontScheme.get( XML_major ).get();
+ else if( (rName[ 1 ] == 'm') && (rName[ 2 ] == 'n') )
+ pCharProps = maFontScheme.get( XML_minor ).get();
+ if( pCharProps )
+ {
+ if( (rName[ 4 ] == 'l') && (rName[ 5 ] == 't') )
+ return &pCharProps->maLatinFont;
+ if( (rName[ 4 ] == 'e') && (rName[ 5 ] == 'a') )
+ return &pCharProps->maAsianFont;
+ if( (rName[ 4 ] == 'c') && (rName[ 5 ] == 's') )
+ return &pCharProps->maComplexFont;
+ }
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/themeelementscontext.cxx b/oox/source/drawingml/themeelementscontext.cxx
new file mode 100644
index 000000000000..a27afdbc0ea3
--- /dev/null
+++ b/oox/source/drawingml/themeelementscontext.cxx
@@ -0,0 +1,241 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/themeelementscontext.hxx"
+#include "oox/drawingml/clrschemecontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/linepropertiescontext.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/theme.hxx"
+#include "oox/helper/attributelist.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 ContextHandler
+{
+public:
+ FillStyleListContext( ContextHandler& rParent, FillStyleList& rFillStyleList );
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+
+private:
+ FillStyleList& mrFillStyleList;
+};
+
+FillStyleListContext::FillStyleListContext( ContextHandler& rParent, FillStyleList& rFillStyleList ) :
+ ContextHandler( rParent ),
+ mrFillStyleList( rFillStyleList )
+{
+}
+
+Reference< XFastContextHandler > FillStyleListContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( noFill ):
+ case A_TOKEN( solidFill ):
+ case A_TOKEN( gradFill ):
+ case A_TOKEN( blipFill ):
+ case A_TOKEN( pattFill ):
+ case A_TOKEN( grpFill ):
+ mrFillStyleList.push_back( FillPropertiesPtr( new FillProperties ) );
+ return FillPropertiesContext::createFillContext( *this, nElement, xAttribs, *mrFillStyleList.back() );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+class LineStyleListContext : public ContextHandler
+{
+public:
+ LineStyleListContext( ContextHandler& rParent, LineStyleList& rLineStyleList );
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+
+private:
+ LineStyleList& mrLineStyleList;
+};
+
+LineStyleListContext::LineStyleListContext( ContextHandler& rParent, LineStyleList& rLineStyleList ) :
+ ContextHandler( rParent ),
+ mrLineStyleList( rLineStyleList )
+{
+}
+
+Reference< XFastContextHandler > LineStyleListContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( ln ):
+ mrLineStyleList.push_back( LinePropertiesPtr( new LineProperties ) );
+ return new LinePropertiesContext( *this, xAttribs, *mrLineStyleList.back() );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+class EffectStyleListContext : public ContextHandler
+{
+public:
+ EffectStyleListContext( ContextHandler& rParent, EffectStyleList& rEffectStyleList );
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+
+private:
+ EffectStyleList& mrEffectStyleList;
+};
+
+EffectStyleListContext::EffectStyleListContext( ContextHandler& rParent, EffectStyleList& rEffectStyleList ) :
+ ContextHandler( rParent ),
+ mrEffectStyleList( rEffectStyleList )
+{
+}
+
+Reference< XFastContextHandler > EffectStyleListContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& /*xAttribs*/ ) throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( effectStyle ):
+ mrEffectStyleList.push_back( EffectStyleList::value_type( new PropertyMap ) );
+ // TODO: import effect styles
+ return 0;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+class FontSchemeContext : public ContextHandler
+{
+public:
+ FontSchemeContext( ContextHandler& rParent, FontScheme& rFontScheme );
+ virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
+ virtual void SAL_CALL endFastElement( sal_Int32 nElement ) throw (SAXException, RuntimeException);
+
+private:
+ FontScheme& mrFontScheme;
+ TextCharacterPropertiesPtr mxCharProps;
+};
+
+FontSchemeContext::FontSchemeContext( ContextHandler& rParent, FontScheme& rFontScheme ) :
+ ContextHandler( rParent ),
+ mrFontScheme( rFontScheme )
+{
+}
+
+Reference< XFastContextHandler > FontSchemeContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
+ throw (SAXException, RuntimeException)
+{
+ AttributeList aAttribs( rxAttribs );
+ switch( nElement )
+ {
+ case A_TOKEN( majorFont ):
+ mxCharProps.reset( new TextCharacterProperties );
+ mrFontScheme[ XML_major ] = mxCharProps;
+ return this;
+ case A_TOKEN( minorFont ):
+ mxCharProps.reset( new TextCharacterProperties );
+ mrFontScheme[ XML_minor ] = mxCharProps;
+ return this;
+
+ case A_TOKEN( latin ):
+ if( mxCharProps.get() )
+ mxCharProps->maLatinFont.setAttributes( aAttribs );
+ break;
+ case A_TOKEN( ea ):
+ if( mxCharProps.get() )
+ mxCharProps->maAsianFont.setAttributes( aAttribs );
+ break;
+ case A_TOKEN( cs ):
+ if( mxCharProps.get() )
+ mxCharProps->maComplexFont.setAttributes( aAttribs );
+ break;
+ }
+ return 0;
+}
+
+void FontSchemeContext::endFastElement( sal_Int32 nElement ) throw (SAXException, RuntimeException)
+{
+ switch( nElement )
+ {
+ case A_TOKEN( majorFont ):
+ case A_TOKEN( minorFont ):
+ mxCharProps.reset();
+ break;
+ }
+}
+
+// ============================================================================
+
+ThemeElementsContext::ThemeElementsContext( ContextHandler& rParent, Theme& rTheme ) :
+ ContextHandler( rParent ),
+ mrTheme( rTheme )
+{
+}
+
+Reference< XFastContextHandler > ThemeElementsContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ // CT_BaseStyles
+ Reference< XFastContextHandler > xRet;
+ switch( nElement )
+ {
+ case A_TOKEN( clrScheme ): // CT_ColorScheme
+ return new clrSchemeContext( *this, mrTheme.getClrScheme() );
+ case A_TOKEN( fontScheme ): // CT_FontScheme
+ return new FontSchemeContext( *this, mrTheme.getFontScheme() );
+
+ case A_TOKEN( fmtScheme ): // CT_StyleMatrix
+ mrTheme.setStyleName( xAttribs->getOptionalValue( XML_name ) );
+ return this;
+
+ case A_TOKEN( fillStyleLst ): // CT_FillStyleList
+ return new FillStyleListContext( *this, mrTheme.getFillStyleList() );
+ case A_TOKEN( lnStyleLst ): // CT_LineStyleList
+ return new LineStyleListContext( *this, mrTheme.getLineStyleList() );
+ case A_TOKEN( effectStyleLst ): // CT_EffectStyleList
+ return new EffectStyleListContext( *this, mrTheme.getEffectStyleList() );
+ case A_TOKEN( bgFillStyleLst ): // CT_BackgroundFillStyleList
+ return new FillStyleListContext( *this, mrTheme.getBgFillStyleList() );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/themefragmenthandler.cxx b/oox/source/drawingml/themefragmenthandler.cxx
new file mode 100644
index 000000000000..3cae10e40b4f
--- /dev/null
+++ b/oox/source/drawingml/themefragmenthandler.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/themefragmenthandler.hxx"
+#include "oox/drawingml/objectdefaultcontext.hxx"
+#include "oox/drawingml/theme.hxx"
+#include "oox/drawingml/themeelementscontext.hxx"
+
+using ::rtl::OUString;
+using namespace ::oox::core;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+ThemeFragmentHandler::ThemeFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath, Theme& rTheme ) :
+ FragmentHandler2( rFilter, rFragmentPath ),
+ mrTheme( rTheme )
+{
+}
+
+ThemeFragmentHandler::~ThemeFragmentHandler()
+{
+}
+
+ContextHandlerRef ThemeFragmentHandler::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ // CT_OfficeStyleSheet
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ switch( nElement )
+ {
+ case A_TOKEN( theme ):
+ return this;
+ }
+ break;
+
+ case A_TOKEN( theme ):
+ switch( nElement )
+ {
+ case A_TOKEN( themeElements ): // CT_BaseStyles
+ return new ThemeElementsContext( *this, mrTheme );
+ case A_TOKEN( objectDefaults ): // CT_ObjectStyleDefaults
+ return new objectDefaultContext( *this, mrTheme );
+ case A_TOKEN( extraClrSchemeLst ): // CT_ColorSchemeList
+ return 0;
+ case A_TOKEN( custClrLst ): // CustomColorList
+ return 0;
+ case A_TOKEN( ext ): // CT_OfficeArtExtension
+ return 0;
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/drawingml/transform2dcontext.cxx b/oox/source/drawingml/transform2dcontext.cxx
new file mode 100644
index 000000000000..c686feed165c
--- /dev/null
+++ b/oox/source/drawingml/transform2dcontext.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/transform2dcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/drawingml/shape.hxx"
+
+using ::com::sun::star::awt::Point;
+using ::com::sun::star::awt::Size;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::xml::sax::SAXException;
+using ::com::sun::star::xml::sax::XFastAttributeList;
+using ::com::sun::star::xml::sax::XFastContextHandler;
+using ::oox::core::ContextHandler;
+
+namespace oox {
+namespace drawingml {
+
+// ============================================================================
+
+/** context to import a CT_Transform2D */
+Transform2DContext::Transform2DContext( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, Shape& rShape ) throw()
+: ContextHandler( rParent )
+, 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 ) );
+}
+
+Reference< XFastContextHandler > Transform2DContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ switch( aElementToken )
+ {
+ case A_TOKEN( off ): // horz/vert translation
+ mrShape.setPosition( Point( xAttribs->getOptionalValue( XML_x ).toInt32(), xAttribs->getOptionalValue( XML_y ).toInt32() ) );
+ break;
+ case A_TOKEN( ext ): // horz/vert size
+ mrShape.setSize( Size( xAttribs->getOptionalValue( XML_cx ).toInt32(), xAttribs->getOptionalValue( XML_cy ).toInt32() ) );
+ break;
+/* todo: what to do?
+ case A_TOKEN( chOff ): // horz/vert translation of children
+ case A_TOKEN( chExt ): // horz/vert size of children
+ break;
+*/
+ }
+
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace drawingml
+} // namespace oox
+
diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx
new file mode 100644
index 000000000000..546ad186e7ab
--- /dev/null
+++ b/oox/source/dump/biffdumper.cxx
@@ -0,0 +1,4554 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/dump/biffdumper.hxx"
+
+#include <osl/thread.h>
+#include <rtl/tencinfo.h>
+#include "oox/core/filterbase.hxx"
+#include "oox/dump/oledumper.hxx"
+#include "oox/ole/olestorage.hxx"
+#include "oox/xls/biffdetector.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/formulabase.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+namespace biff {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::oox::xls;
+
+using ::comphelper::MediaDescriptor;
+using ::oox::core::FilterBase;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+// constants ------------------------------------------------------------------
+
+const sal_uInt16 BIFF_FONTFLAG_BOLD = 0x0001;
+const sal_uInt16 BIFF_FONTFLAG_ITALIC = 0x0002;
+
+const sal_uInt16 BIFF_OBJTYPE_GROUP = 0;
+const sal_uInt16 BIFF_OBJTYPE_LINE = 1;
+const sal_uInt16 BIFF_OBJTYPE_RECTANGLE = 2;
+const sal_uInt16 BIFF_OBJTYPE_OVAL = 3;
+const sal_uInt16 BIFF_OBJTYPE_ARC = 4;
+const sal_uInt16 BIFF_OBJTYPE_CHART = 5;
+const sal_uInt16 BIFF_OBJTYPE_TEXT = 6;
+const sal_uInt16 BIFF_OBJTYPE_BUTTON = 7;
+const sal_uInt16 BIFF_OBJTYPE_PICTURE = 8;
+const sal_uInt16 BIFF_OBJTYPE_POLYGON = 9;
+const sal_uInt16 BIFF_OBJTYPE_CHECKBOX = 11;
+const sal_uInt16 BIFF_OBJTYPE_OPTIONBUTTON = 12;
+const sal_uInt16 BIFF_OBJTYPE_EDIT = 13;
+const sal_uInt16 BIFF_OBJTYPE_LABEL = 14;
+const sal_uInt16 BIFF_OBJTYPE_DIALOG = 15;
+const sal_uInt16 BIFF_OBJTYPE_SPIN = 16;
+const sal_uInt16 BIFF_OBJTYPE_SCROLLBAR = 17;
+const sal_uInt16 BIFF_OBJTYPE_LISTBOX = 18;
+const sal_uInt16 BIFF_OBJTYPE_GROUPBOX = 19;
+const sal_uInt16 BIFF_OBJTYPE_DROPDOWN = 20;
+const sal_uInt16 BIFF_OBJTYPE_NOTE = 25;
+const sal_uInt16 BIFF_OBJTYPE_DRAWING = 30;
+
+const sal_uInt16 BIFF_OBJFLAGS_CONTROL = 0x0010; /// Form control.
+const sal_uInt16 BIFF_OBJFLAGS_CTLSSTREAM = 0x0020; /// Data in Ctls stream.
+
+const sal_uInt16 BIFF_STYLE_BUILTIN = 0x8000;
+
+const sal_uInt16 BIFF_PT_NOSTRING = 0xFFFF;
+
+// ----------------------------------------------------------------------------
+
+void lclDumpDffClientPos( const OutputRef& rxOut, const BinaryInputStreamRef& rxStrm, const String& rName, sal_uInt16 nSubScale )
+{
+ MultiItemsGuard aMultiGuard( rxOut );
+ TableGuard aTabGuard( rxOut, 17 );
+ {
+ sal_uInt16 nPos = rxStrm->readuInt16();
+ ItemGuard aItem( rxOut, rName );
+ rxOut->writeDec( nPos );
+ }
+ {
+ sal_uInt16 nSubUnits = rxStrm->readuInt16();
+ ItemGuard aItem( rxOut, "sub-units" );
+ rxOut->writeDec( nSubUnits );
+ rxOut->writeChar( '/' );
+ rxOut->writeDec( nSubScale );
+ }
+}
+
+void lclDumpDffClientRect( const OutputRef& rxOut, const BinaryInputStreamRef& rxStrm )
+{
+ lclDumpDffClientPos( rxOut, rxStrm, "start-col", 1024 );
+ lclDumpDffClientPos( rxOut, rxStrm, "start-row", 256 );
+ lclDumpDffClientPos( rxOut, rxStrm, "end-col", 1024 );
+ lclDumpDffClientPos( rxOut, rxStrm, "end-row", 256 );
+}
+
+} // namespace
+
+// ============================================================================
+// ============================================================================
+
+BiffDffStreamObject::BiffDffStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
+{
+ DffStreamObject::construct( rParent, rxStrm );
+}
+
+void BiffDffStreamObject::implDumpClientAnchor()
+{
+ dumpHex< sal_uInt16 >( "flags", "DFF-CLIENTANCHOR-FLAGS" );
+ lclDumpDffClientRect( mxOut, mxStrm );
+}
+
+// ============================================================================
+
+BiffCtlsStreamObject::BiffCtlsStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
+{
+ InputObjectBase::construct( rParent, rxStrm );
+ mnStartPos = mnLength = 0;
+}
+
+void BiffCtlsStreamObject::dumpControl( sal_uInt32 nStartPos, sal_uInt32 nLength )
+{
+ mnStartPos = nStartPos;
+ mnLength = nLength;
+ dump();
+ mnStartPos = mnLength = 0;
+}
+
+void BiffCtlsStreamObject::implDump()
+{
+ if( mnLength > 0 )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "CTLS-START" );
+ {
+ IndentGuard aIndGuard( mxOut );
+ mxStrm->seek( mnStartPos );
+ RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) );
+ FormControlStreamObject( *this, xRelStrm ).dump();
+ }
+ writeEmptyItem( "CTLS-END" );
+ mxOut->emptyLine();
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+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() )
+{
+}
+
+void BiffSharedData::initializePerSheet()
+{
+ maFontEncs.clear();
+ maXfFontIds.clear();
+ meTextEnc = osl_getThreadTextEncoding();
+}
+
+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()
+{
+}
+
+void BiffObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, BiffType eBiff, const OUString& rSysFileName )
+{
+ if( rParent.isValid() && rxStrm.get() && (eBiff != BIFF_UNKNOWN) )
+ {
+ mxBiffData.reset( new BiffSharedData( eBiff ) );
+ mxBiffStrm.reset( new BiffInputStream( *rxStrm ) );
+ RecordObjectBase::construct( rParent, rxStrm, rSysFileName, mxBiffStrm, "RECORD-NAMES", "SIMPLE-RECORDS" );
+ if( RecordObjectBase::implIsValid() )
+ {
+ reconstructConfig( ConfigRef( new BiffConfig( cfg(), eBiff ) ) );
+ mxDffObj.reset( new BiffDffStreamObject( *this, mxBiffStrm ) );
+ if( StorageBase* pRootStrg = cfg().getRootStorage().get() )
+ {
+ BinaryInputStreamRef xCtlsStrm( new BinaryXInputStream( pRootStrg->openInputStream( CREATE_OUSTRING( "Ctls" ) ), true ) );
+ mxCtlsObj.reset( new BiffCtlsStreamObject( *this, xCtlsStrm ) );
+ }
+ const Config& rCfg = cfg();
+ mxErrCodes = rCfg.getNameList( "ERRORCODES" );
+ mxConstType = rCfg.getNameList( "CONSTVALUE-TYPE" );
+ mxResultType = rCfg.getNameList( "FORMULA-RESULTTYPE" );
+ mnLastRecId = BIFF_ID_UNKNOWN;
+ mbMergeContRec = rCfg.getBoolOption( "merge-continue-record", true );
+ }
+ }
+}
+
+void BiffObjectBase::construct( const BiffObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool BiffObjectBase::implIsValid() const
+{
+ return isValid( mxBiffData ) && mxBiffStrm.get() && isValid( mxDffObj ) && InputObjectBase::implIsValid();
+}
+
+bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ // previous record
+ mnLastRecId = mxBiffStrm->getRecId();
+ switch( mnLastRecId )
+ {
+ case BIFF_ID_CHBEGIN:
+ mxOut->incIndent();
+ break;
+ }
+
+ // start next record
+ bool bValid = mxBiffStrm->startNextRecord();
+ ornRecPos = mxBiffStrm->tellBase() - 4;
+ ornRecId = mxBiffStrm->getRecId();
+
+ // special CONTINUE handling
+ mxBiffStrm->resetRecord( mbMergeContRec );
+ if( mbMergeContRec ) switch( mxBiffStrm->getRecId() )
+ {
+ case BIFF_ID_OBJ:
+ case BIFF_ID_TXO:
+ case BIFF_ID_EOF:
+ case BIFF_ID_CONT:
+ mxBiffStrm->resetRecord( false );
+ break;
+ case BIFF_ID_MSODRAWINGGROUP:
+ case BIFF_ID_CHESCHERFORMAT:
+ mxBiffStrm->resetRecord( true, mxBiffStrm->getRecId() );
+ break;
+ }
+
+ // record specific settings
+ switch( mxBiffStrm->getRecId() )
+ {
+ case BIFF2_ID_BOF:
+ case BIFF3_ID_BOF:
+ case BIFF4_ID_BOF:
+ case BIFF5_ID_BOF:
+ case BIFF_ID_INTERFACEHDR:
+ mxBiffStrm->enableDecoder( false );
+ break;
+ case BIFF_ID_CHEND:
+ mxOut->decIndent();
+ break;
+ }
+
+ ornRecSize = mxBiffStrm->getLength();
+ return bValid;
+}
+
+OUString BiffObjectBase::getErrorName( sal_uInt8 nErrCode ) const
+{
+ return cfg().getName( mxErrCodes, nErrCode );
+}
+
+// ----------------------------------------------------------------------------
+
+sal_Int32 BiffObjectBase::readCol( bool bCol16Bit )
+{
+ return bCol16Bit ? mxBiffStrm->readuInt16() : mxBiffStrm->readuInt8();
+}
+
+sal_Int32 BiffObjectBase::readRow( bool bRow32Bit )
+{
+ return bRow32Bit ? mxBiffStrm->readInt32() : mxBiffStrm->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;
+ *mxBiffStrm >> nCount;
+ orRanges.resize( nCount );
+ for( RangeList::iterator aIt = orRanges.begin(), aEnd = orRanges.end(); !mxBiffStrm->isEof() && (aIt != aEnd); ++aIt )
+ readRange( *aIt, bCol16Bit, bRow32Bit );
+}
+
+// ----------------------------------------------------------------------------
+
+void BiffObjectBase::writeBooleanItem( const String& rName, sal_uInt8 nBool )
+{
+ writeDecItem( rName, nBool, "BOOLEAN" );
+}
+
+void BiffObjectBase::writeErrorCodeItem( const String& rName, sal_uInt8 nErrCode )
+{
+ writeHexItem( rName, nErrCode, mxErrCodes );
+}
+
+void BiffObjectBase::writeFontPortions( const FontPortionModelList& rPortions )
+{
+ if( !rPortions.empty() )
+ {
+ writeDecItem( "font-count", static_cast< sal_uInt32 >( rPortions.size() ) );
+ TableGuard aTabGuard( mxOut, 14 );
+ for( FontPortionModelList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeDecItem( "char-pos", aIt->mnPos );
+ writeDecItem( "font-idx", aIt->mnFontId, "FONTNAMES" );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+OUString BiffObjectBase::dumpByteString( const String& rName, 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 = mxBiffStrm->readByteString( !b8BitLength, true );
+ FontPortionModelList aPortions;
+ if( getFlag( nFlags, BIFF_STR_EXTRAFONTS ) )
+ aPortions.importPortions( *mxBiffStrm, 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(), FontPortionModel( 0, -1 ) );
+ if( aPortions.back().mnPos < nStrLen )
+ aPortions.push_back( FontPortionModel( 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( FontPortionModelList::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( rName( "text" ), aUniStr );
+ return aUniStr;
+}
+
+OUString BiffObjectBase::dumpUniString( const String& rName, 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 ? mxBiffStrm->readuInt8() : mxBiffStrm->readuInt16();
+ sal_uInt8 nFlagField = 0;
+ if( (nChars > 0) || !getFlag( nFlags, BIFF_STR_SMARTFLAGS ) )
+ *mxBiffStrm >> nFlagField;
+ bool b16Bit = getFlag( nFlagField, BIFF_STRF_16BIT );
+ bool bFonts = getFlag( nFlagField, BIFF_STRF_RICH );
+ bool bPhonetic = getFlag( nFlagField, BIFF_STRF_PHONETIC );
+ sal_uInt16 nFontCount = bFonts ? mxBiffStrm->readuInt16() : 0;
+ sal_uInt32 nPhoneticSize = bPhonetic ? mxBiffStrm->readuInt32() : 0;
+
+ // --- character array ---
+ OUString aString = mxBiffStrm->readUniStringChars( nChars, b16Bit, true );
+ writeStringItem( rName( "text" ), aString );
+
+ // --- formatting ---
+ // #122185# bRich flag may be set, but format runs may be missing
+ if( nFontCount > 0 )
+ {
+ IndentGuard aIndGuard( mxOut );
+ FontPortionModelList aPortions;
+ aPortions.importPortions( *mxBiffStrm, nFontCount, BIFF_FONTPORTION_16BIT );
+ writeFontPortions( aPortions );
+ }
+
+ // --- phonetic information ---
+ // #122185# bPhonetic flag may be set, but phonetic data may be missing
+ if( nPhoneticSize > 0 )
+ {
+ sal_Int64 nStrmPos = mxBiffStrm->tell();
+ IndentGuard aIndGuard( mxOut );
+ writeEmptyItem( "phonetic-data" );
+ dumpUnused( 2 );
+ dumpDec< sal_uInt16 >( "size" );
+ dumpDec< sal_uInt16 >( "font-idx", "FONTNAMES" );
+ dumpHex< sal_uInt16 >( "flags", "PHONETICPR-FLAGS" );
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "portion-count" );
+ sal_uInt16 nLen = dumpDec< sal_uInt16 >( "text-len" );
+ dumpUnicodeArray( "text", mxBiffStrm->readuInt16() );
+ if( nLen == 0 ) dumpUnused( 2 );
+ for( sal_uInt16 nPortion = 0; !mxBiffStrm->isEof() && (nPortion < nCount); ++nPortion )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ dumpDec< sal_uInt16 >( "first-portion-char" );
+ dumpDec< sal_uInt16 >( "first-main-char" );
+ dumpDec< sal_uInt16 >( "main-char-count" );
+ }
+ dumpRemainingTo( nStrmPos + nPhoneticSize );
+ }
+
+ return aString;
+}
+
+OUString BiffObjectBase::dumpString( const String& rName, BiffStringFlags nByteFlags, BiffStringFlags nUniFlags, rtl_TextEncoding eDefaultTextEnc )
+{
+ return (getBiff() == BIFF8) ? dumpUniString( rName, nUniFlags ) : dumpByteString( rName, nByteFlags, eDefaultTextEnc );
+}
+
+OUString BiffObjectBase::dumpSegmentedUniString( const String& rName )
+{
+ sal_Int32 nLength = mxBiffStrm->readInt32();
+ OUStringBuffer aBuffer;
+ while( !mxBiffStrm->isEof() && (aBuffer.getLength() < nLength) )
+ aBuffer.append( mxBiffStrm->readUniString() );
+ OUString aString = aBuffer.makeStringAndClear();
+ writeStringItem( rName, aString );
+ return aString;
+}
+
+void BiffObjectBase::dumpSegmentedUniStringArray( const String& rName )
+{
+ writeEmptyItem( rName );
+ IndentGuard aIndGuard( mxOut );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "count" ); !mxBiffStrm->isEof() && (nIndex < nCount); ++nIndex )
+ dumpSegmentedUniString( "#entry" );
+}
+
+sal_uInt8 BiffObjectBase::dumpBoolean( const String& rName )
+{
+ sal_uInt8 nBool;
+ *mxBiffStrm >> nBool;
+ writeBooleanItem( rName( "boolean" ), nBool );
+ return nBool;
+}
+
+sal_uInt8 BiffObjectBase::dumpErrorCode( const String& rName )
+{
+ sal_uInt8 nErrCode;
+ *mxBiffStrm >> nErrCode;
+ writeErrorCodeItem( rName( "error-code" ), nErrCode );
+ return nErrCode;
+}
+
+rtl_TextEncoding BiffObjectBase::dumpCodePage( const String& rName )
+{
+ sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( rName( "codepage" ), "CODEPAGES" );
+ return BiffHelper::calcTextEncodingFromCodePage( nCodePage );
+}
+
+void BiffObjectBase::dumpFormulaResult( const String& rName )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ sal_uInt8 pnResult[ 8 ];
+ mxBiffStrm->readMemory( pnResult, 8 );
+ writeArrayItem( rName( "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 String& rName, bool bCol16Bit )
+{
+ sal_Int32 nCol = readCol( bCol16Bit );
+ writeColIndexItem( rName( "col-idx" ), nCol );
+ return nCol;
+}
+
+sal_Int32 BiffObjectBase::dumpRowIndex( const String& rName, bool bRow32Bit )
+{
+ sal_Int32 nRow = readRow( bRow32Bit );
+ writeRowIndexItem( rName( "row-idx" ), nRow );
+ return nRow;
+}
+
+sal_Int32 BiffObjectBase::dumpColRange( const String& rName, bool bCol16Bit )
+{
+ sal_Int32 nCol1 = readCol( bCol16Bit );
+ sal_Int32 nCol2 = readCol( bCol16Bit );
+ writeColRangeItem( rName( "col-range" ), nCol1, nCol2 );
+ return nCol2 - nCol1 + 1;
+}
+
+sal_Int32 BiffObjectBase::dumpRowRange( const String& rName, bool bRow32Bit )
+{
+ sal_Int32 nRow1 = readRow( bRow32Bit );
+ sal_Int32 nRow2 = readRow( bRow32Bit );
+ writeRowRangeItem( rName( "row-range" ), nRow1, nRow2 );
+ return nRow2 - nRow1 + 1;
+}
+
+Address BiffObjectBase::dumpAddress( const String& rName, bool bCol16Bit, bool bRow32Bit )
+{
+ Address aPos;
+ readAddress( aPos, bCol16Bit, bRow32Bit );
+ writeAddressItem( rName( "addr" ), aPos );
+ return aPos;
+}
+
+Range BiffObjectBase::dumpRange( const String& rName, bool bCol16Bit, bool bRow32Bit )
+{
+ Range aRange;
+ readRange( aRange, bCol16Bit, bRow32Bit );
+ writeRangeItem( rName( "range" ), aRange );
+ return aRange;
+}
+
+void BiffObjectBase::dumpRangeList( const String& rName, bool bCol16Bit, bool bRow32Bit )
+{
+ RangeList aRanges;
+ readRangeList( aRanges, bCol16Bit, bRow32Bit );
+ writeRangeListItem( rName( "range-list" ), aRanges );
+}
+
+void BiffObjectBase::dumpConstArrayHeader( sal_uInt32& rnCols, sal_uInt32& rnRows )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ 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( mxOut, "size" );
+ mxOut->writeDec( rnCols );
+ mxOut->writeChar( 'x' );
+ mxOut->writeDec( rnRows );
+ aItem.cont();
+ mxOut->writeDec( rnCols * rnRows );
+}
+
+OUString BiffObjectBase::dumpConstValue( sal_Unicode cStrQuote )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ 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( mxOut->getLastItemValue() );
+ break;
+ case BIFF_DATATYPE_STRING:
+ aValue.append( dumpString( "value", BIFF_STR_8BITLENGTH ) );
+ StringHelper::enclose( aValue, cStrQuote );
+ break;
+ case BIFF_DATATYPE_BOOL:
+ dumpBoolean( "value" );
+ aValue.append( mxOut->getLastItemValue() );
+ dumpUnused( 7 );
+ break;
+ case BIFF_DATATYPE_ERROR:
+ dumpErrorCode( "value" );
+ aValue.append( mxOut->getLastItemValue() );
+ dumpUnused( 7 );
+ break;
+ }
+ return aValue.makeStringAndClear();
+}
+
+sal_uInt16 BiffObjectBase::dumpRepeatedRecId()
+{
+ return dumpHex< sal_uInt16 >( "repeated-rec-id", getRecNames() );
+}
+
+void BiffObjectBase::dumpFrHeader( bool bWithFlags, bool bWithRange )
+{
+ dumpHex< sal_uInt16 >( "fr-rec-id", getRecNames() );
+ sal_Int16 nFlags = bWithFlags ? dumpHex< sal_uInt16 >( "fr-flags", "FR-FLAGS" ) : 0x0001;
+ if( bWithRange )
+ {
+ if( getFlag< sal_uInt16 >( nFlags, 0x0001 ) )
+ dumpRange( "fr-range" );
+ else
+ dumpUnused( 8 );
+ }
+}
+
+void BiffObjectBase::dumpDffClientRect()
+{
+ lclDumpDffClientRect( mxOut, mxStrm );
+}
+
+void BiffObjectBase::dumpEmbeddedDff()
+{
+ mxOut->decIndent();
+ writeEmptyItem( "EMBEDDED-DFF-START" );
+ mxOut->incIndent();
+ mxDffObj->dump();
+ mxOut->emptyLine();
+ mxOut->decIndent();
+ writeEmptyItem( "EMBEDDED-DFF-END" );
+ mxOut->incIndent();
+}
+
+void BiffObjectBase::dumpControl()
+{
+ sal_uInt32 nStartPos = dumpHex< sal_uInt32 >( "ctls-stream-pos", "CONV-DEC" );
+ sal_uInt32 nLength = dumpHex< sal_uInt32 >( "ctls-stream-length", "CONV-DEC" );
+ if( isValid( mxCtlsObj ) )
+ mxCtlsObj->dumpControl( nStartPos, nLength );
+}
+
+// ============================================================================
+// ============================================================================
+
+FormulaObject::FormulaObject( const BiffObjectBase& rParent ) :
+ mnSize( 0 )
+{
+ BiffObjectBase::construct( rParent );
+ constructFmlaObj();
+}
+
+FormulaObject::~FormulaObject()
+{
+}
+
+sal_uInt16 FormulaObject::readFormulaSize()
+{
+ return (getBiff() == BIFF2) ? getBiffStream().readuInt8() : getBiffStream().readuInt16();
+}
+
+sal_uInt16 FormulaObject::dumpFormulaSize( const String& rName )
+{
+ sal_uInt16 nSize = readFormulaSize();
+ writeDecItem( rName( "formula-size" ), nSize );
+ return nSize;
+}
+
+void FormulaObject::dumpCellFormula( const String& rName, sal_uInt16 nSize )
+{
+ dumpFormula( rName, nSize, false );
+}
+
+void FormulaObject::dumpCellFormula( const String& rName )
+{
+ dumpFormula( rName, false );
+}
+
+void FormulaObject::dumpNameFormula( const String& rName, sal_uInt16 nSize )
+{
+ dumpFormula( rName, nSize, true );
+}
+
+void FormulaObject::dumpNameFormula( const String& rName )
+{
+ dumpFormula( rName, true );
+}
+
+void FormulaObject::implDump()
+{
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( maName );
+ writeDecItem( "formula-size", mnSize );
+ }
+ if( mnSize == 0 ) return;
+
+ sal_Int64 nStartPos = mxStrm->tell();
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() );
+
+ bool bValid = mxTokens.get();
+ mxStack.reset( new FormulaStack );
+ maAddData.clear();
+ IndentGuard aIndGuard( mxOut );
+ {
+ TableGuard aTabGuard( mxOut, 8, 18 );
+ while( bValid && !mxStrm->isEof() && (mxStrm->tell() < nEndPos) )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeHexItem( EMPTY_STRING, static_cast< sal_uInt16 >( mxStrm->tell() - nStartPos ) );
+ sal_uInt8 nTokenId = dumpHex< sal_uInt8 >( EMPTY_STRING, 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 == mxStrm->tell();
+ if( bValid )
+ {
+ dumpAddTokenData();
+ writeInfoItem( "formula", mxStack->getFormulaString() );
+ writeInfoItem( "classes", mxStack->getClassesString() );
+ }
+ else
+ dumpBinary( OOX_DUMP_ERRASCII( "formula-error" ), nEndPos - mxStrm->tell(), false );
+
+ mnSize = 0;
+}
+
+void FormulaObject::dumpFormula( const String& rName, sal_uInt16 nSize, bool bNameMode )
+{
+ maName = rName( "formula" );
+ mnSize = nSize;
+ mbNameMode = bNameMode;
+ dump();
+ mnSize = 0;
+}
+
+void FormulaObject::dumpFormula( const String& rName, bool bNameMode )
+{
+ dumpFormula( rName, readFormulaSize(), bNameMode );
+}
+
+// private --------------------------------------------------------------------
+
+void FormulaObject::constructFmlaObj()
+{
+ if( BiffObjectBase::implIsValid() )
+ {
+ mxFuncProv.reset( new FunctionProvider( FILTER_BIFF, 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) ? mxStrm->readuInt16() : mxStrm->readuInt8();
+}
+
+OUString FormulaObject::writeFuncIdItem( sal_uInt16 nFuncId, const FunctionInfo** oppFuncInfo )
+{
+ ItemGuard aItemGuard( mxOut, "func-id" );
+ writeHexItem( EMPTY_STRING, 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();
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+ mxOut->writeString( aFuncName );
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+ if( oppFuncInfo ) *oppFuncInfo = pFuncInfo;
+ return aFuncName;
+}
+
+sal_uInt16 FormulaObject::dumpTokenCol( const String& rName, bool& rbRelC, bool& rbRelR )
+{
+ sal_uInt16 nCol = 0;
+ if( getBiff() == BIFF8 )
+ {
+ nCol = dumpHex< sal_uInt16 >( rName, 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 >( rName );
+ return nCol;
+}
+
+sal_uInt16 FormulaObject::dumpTokenRow( const String& rName, bool& rbRelC, bool& rbRelR )
+{
+ sal_uInt16 nRow = 0;
+ if( getBiff() == BIFF8 )
+ nRow = dumpDec< sal_uInt16 >( rName );
+ else
+ {
+ nRow = dumpHex< sal_uInt16 >( rName, 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( mxOut->getLastItemValue() );
+}
+
+void FormulaObject::dumpDoubleToken()
+{
+ dumpDec< double >( "value" );
+ mxStack->pushOperand( mxOut->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( mxOut->getLastItemValue() );
+}
+
+void FormulaObject::dumpErrorToken()
+{
+ dumpErrorCode( "value" );
+ mxStack->pushOperand( mxOut->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( mxOut->getLastItemValue() ), rTokClass );
+}
+
+void FormulaObject::dumpAreaToken( const OUString& rTokClass, bool bNameMode )
+{
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRangeItem( "range", aRange, bNameMode );
+ mxStack->pushOperand( createRef( mxOut->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( mxOut->getLastItemValue(), rTokClass );
+}
+
+void FormulaObject::dumpArea3dToken( const OUString& rTokClass, bool bNameMode )
+{
+ OUString aRef = dumpTokenRefTabIdxs();
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRange3dItem( "range", aRef, aRange, bNameMode );
+ mxStack->pushOperand( mxOut->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 String& 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 );
+ StringHelper::appendIndex( aOp, mxOut->getLastItemValue() );
+ mxStack->pushOperand( aOp.makeStringAndClear() );
+}
+
+void FormulaObject::dumpUnaryOpToken( const String& rLOp, const String& rROp )
+{
+ mxStack->pushUnaryOp( rLOp, rROp );
+}
+
+void FormulaObject::dumpBinaryOpToken( const String& 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;
+ *mxStrm >> 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" );
+ mxOut->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 0: // in array formulas and defined names, the skip-bit may be 0
+ 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( mxOut->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( mxOut->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()
+{
+ mxOut->resetItemIndex();
+ for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); aIt != aEnd; ++aIt )
+ {
+ AddDataType eType = *aIt;
+
+ {
+ ItemGuard aItem( mxOut, "#add-data" );
+ switch( eType )
+ {
+ case ADDDATA_NLR: mxOut->writeAscii( "tNlr" ); break;
+ case ADDDATA_ARRAY: mxOut->writeAscii( "tArray" ); break;
+ case ADDDATA_MEMAREA: mxOut->writeAscii( "tMemArea" ); break;
+ }
+ }
+
+ size_t nIdx = aIt - maAddData.begin();
+ IndentGuard aIndGuard( mxOut );
+ 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( mxOut, 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_FMLASTRQUOTE ), 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( EMPTY_STRING, getBiff() == BIFF8 );
+}
+
+// ============================================================================
+// ============================================================================
+
+RecordStreamObject::~RecordStreamObject()
+{
+}
+
+void RecordStreamObject::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, BiffType eBiff, const OUString& rSysFileName )
+{
+ BiffObjectBase::construct( rParent, rxStrm, eBiff, rSysFileName );
+ if( BiffObjectBase::implIsValid() )
+ mxFmlaObj.reset( new FormulaObject( *this ) );
+}
+
+bool RecordStreamObject::implIsValid() const
+{
+ return isValid( mxFmlaObj ) && BiffObjectBase::implIsValid();
+}
+
+// ============================================================================
+
+WorkbookStreamObject::WorkbookStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ if( rxStrm.get() )
+ {
+ BiffType eBiff = BiffDetector::detectStreamBiffVersion( *rxStrm );
+ RecordStreamObject::construct( rParent, rxStrm, eBiff, rSysFileName );
+ if( RecordStreamObject::implIsValid() )
+ {
+ Config& rCfg = cfg();
+ mxColors = rCfg.getNameList( "COLORS" );
+ mxBorderStyles = rCfg.getNameList( "BORDERSTYLES" );
+ mxFillPatterns = rCfg.getNameList( "FILLPATTERNS" );
+ mnPTRowFields = 0;
+ mnPTColFields = 0;
+ mnPTRowColItemsIdx = 0;
+ mbHasDff = false;
+ initializePerSheet();
+ }
+ }
+}
+
+WorkbookStreamObject::~WorkbookStreamObject()
+{
+ if( WorkbookStreamObject::implIsValid() )
+ {
+ Config& rCfg = cfg();
+ rCfg.eraseNameList( "FONTNAMES" );
+ rCfg.eraseNameList( "FORMATS" );
+ }
+}
+
+void WorkbookStreamObject::implDumpRecordBody()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ sal_uInt16 nRecId = rStrm.getRecId();
+ sal_Int64 nRecSize = rStrm.getLength();
+ 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 ) dumpHex< sal_uInt32 >( "lowest-version", "BOF-LOWESTVERSION-FLAGS" );
+ if( (eBiff == BIFF4) && (getLastRecId() != BIFF_ID_OBJ) )
+ initializePerSheet();
+ break;
+
+ case BIFF_ID_BOOKEXT:
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt32 >( "rec-size" );
+ dumpHex< sal_uInt32 >( "flags-1", "BOOKEXT-FLAGS1" );
+ if( rStrm.getRemaining() > 0 ) dumpHex< sal_uInt8 >( "flags-2", "BOOKEXT-FLAGS2" );
+ if( rStrm.getRemaining() > 0 ) dumpHex< sal_uInt8 >( "flags-3", "BOOKEXT-FLAGS3" );
+ 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" );
+ dumpHex< sal_uInt16 >( "flags", "CFHEADER-FLAGS" );
+ 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" );
+ dumpCfRuleProp();
+ if( nFmla1Size > 0 ) getFormulaDumper().dumpNameFormula( "formula1", nFmla1Size );
+ if( nFmla2Size > 0 ) getFormulaDumper().dumpNameFormula( "formula2", nFmla2Size );
+ }
+ break;
+
+ case BIFF_ID_CFRULE12:
+ {
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt8 >( "type", "CFRULE12-TYPE" );
+ dumpDec< sal_uInt8 >( "operator", "CFRULE-OPERATOR" );
+ sal_uInt16 nFmla1Size = dumpDec< sal_uInt16 >( "formula1-size" );
+ sal_uInt16 nFmla2Size = dumpDec< sal_uInt16 >( "formula2-size" );
+ dumpDxf12Prop();
+ if( nFmla1Size > 0 ) getFormulaDumper().dumpNameFormula( "formula1", nFmla1Size );
+ if( nFmla2Size > 0 ) getFormulaDumper().dumpNameFormula( "formula2", nFmla2Size );
+ getFormulaDumper().dumpNameFormula( "active-formula" );
+ dumpHex< sal_uInt8 >( "flags", "CFRULE12-FLAGS" );
+ dumpDec< sal_uInt16 >( "priority" );
+ dumpCfRule12Param( dumpDec< sal_uInt16 >( "sub-type", "CFRULE12-SUBTYPE" ) );
+ }
+ break;
+
+ case BIFF_ID_CFRULEEXT:
+ dumpFrHeader( true, true );
+ dumpBool< sal_uInt32 >( "cfrule12-follows" );
+ dumpDec< sal_uInt16 >( "cfheader-id" );
+ if( rStrm.getRemaining() >= 25 )
+ {
+ dumpDec< sal_uInt16 >( "cfrule-idx" );
+ dumpDec< sal_uInt8 >( "operator", "CFRULE-OPERATOR" );
+ sal_uInt8 nSubType = dumpDec< sal_uInt8 >( "sub-type", "CFRULE12-SUBTYPE" );
+ dumpDec< sal_uInt16 >( "priority" );
+ dumpHex< sal_uInt8 >( "flags", "CFRULEEXT-FLAGS" );
+ if( dumpBoolean( "has-dxf-data" ) ) dumpDxf12Prop();
+ dumpCfRule12Param( nSubType );
+ }
+ break;
+
+ case BIFF_ID_CH3DDATAFORMAT:
+ dumpDec< sal_uInt8 >( "base", "CH3DDATAFORMAT-BASE" );
+ dumpDec< sal_uInt8 >( "top", "CH3DDATAFORMAT-TOP" );
+ break;
+
+ case BIFF_ID_CHAREAFORMAT:
+ dumpColorABGR( "fg-color" );
+ dumpColorABGR( "bg-color" );
+ 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 >( "inner-plotarea-pos", (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_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_CHDATERANGE:
+ dumpDec< sal_uInt16 >( "minimum-date" );
+ dumpDec< sal_uInt16 >( "maximum-date" );
+ dumpDec< sal_uInt16 >( "major-unit-value" );
+ dumpDec< sal_uInt16 >( "major-unit", "CHDATERANGE-UNIT" );
+ dumpDec< sal_uInt16 >( "minor-unit-value" );
+ dumpDec< sal_uInt16 >( "minor-unit", "CHDATERANGE-UNIT" );
+ dumpDec< sal_uInt16 >( "base-unit", "CHDATERANGE-UNIT" );
+ dumpDec< sal_uInt16 >( "axis-crossing-date" );
+ dumpHex< sal_uInt16 >( "flags", "CHDATERANGE-FLAGS" );
+ break;
+
+ case BIFF_ID_CHECKCOMPAT:
+ dumpFrHeader( true, true );
+ dumpBool< sal_uInt32 >( "check-compatibility" );
+ break;
+
+ case BIFF_ID_CHESCHERFORMAT:
+ dumpEmbeddedDff();
+ 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 >( "tl-mode", "CHFRAMEPOS-POSMODE" );
+ dumpDec< sal_uInt16 >( "br-mode", "CHFRAMEPOS-POSMODE" );
+ dumpRectWithGaps< sal_Int16 >( "position", 2 );
+ break;
+
+ case BIFF_ID_CHFRBLOCKBEGIN:
+ dumpFrHeader( true, false );
+ dumpDec< sal_uInt16 >( "type", "CHFRBLOCK-TYPE" );
+ dumpDec< sal_uInt16 >( "context" );
+ dumpDec< sal_uInt16 >( "value-1" );
+ dumpDec< sal_uInt16 >( "value-2" );
+ break;
+
+ case BIFF_ID_CHFRBLOCKEND:
+ dumpFrHeader( true, false );
+ dumpDec< sal_uInt16 >( "type", "CHFRBLOCK-TYPE" );
+ if( rStrm.getRemaining() >= 6 )
+ dumpUnused( 6 );
+ break;
+
+ case BIFF_ID_CHFRCATEGORYPROPS:
+ dumpFrHeader( true, false );
+ dumpDec< sal_uInt16 >( "label-offset", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "alignment", "CHFRCATEGORYPROPS-ALIGN" );
+ dumpHex< sal_uInt16 >( "flags", "CHFRCATEGORYPROPS-FLAGS" );
+ break;
+
+ case BIFF_ID_CHFREXTPROPS:
+ {
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt32 >( "data-size" );
+ dumpDec< sal_uInt8 >( "version" );
+ dumpUnused( 1 );
+ dumpDec< sal_uInt16 >( "parent", "CHFREXTPROPS-PARENT" );
+ dumpChFrExtProps();
+ dumpUnused( 4 );
+ }
+ break;
+
+ case BIFF_ID_CHFRINFO:
+ {
+ dumpFrHeader( true, false );
+ dumpDec< sal_uInt8 >( "creator", "CHFRINFO-APPVERSION" );
+ dumpDec< sal_uInt8 >( "writer", "CHFRINFO-APPVERSION" );
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "rec-range-count" );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ dumpHexPair< sal_uInt16 >( "#rec-range", '-' );
+ }
+ break;
+
+ case BIFF_ID_CHFRLABELPROPS:
+ dumpFrHeader( true, true );
+ dumpHex< sal_uInt16 >( "flags", "CHFRLABELPROPS-FLAGS" );
+ dumpUniString( "separator", BIFF_STR_SMARTFLAGS );
+ break;
+
+ case BIFF_ID_CHFRLAYOUT:
+ dumpFrHeader( true, true );
+ dumpHex< sal_uInt32 >( "checksum" );
+ dumpHex< sal_uInt16 >( "flags", "CHFRLAYOUT-FLAGS" );
+ dumpDec< sal_uInt16 >( "mode-x", "CHFRLAYOUT-MODE" );
+ dumpDec< sal_uInt16 >( "mode-y", "CHFRLAYOUT-MODE" );
+ dumpDec< sal_uInt16 >( "mode-w", "CHFRLAYOUT-MODE" );
+ dumpDec< sal_uInt16 >( "mode-h", "CHFRLAYOUT-MODE" );
+ dumpRect< double >( "position" );
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_CHFRPLOTAREALAYOUT:
+ dumpFrHeader( true, true );
+ dumpHex< sal_uInt32 >( "checksum" );
+ dumpHex< sal_uInt16 >( "flags", "CHFRPLOTAREALAYOUT-FLAGS" );
+ dumpRect< sal_Int16 >( "position" );
+ dumpDec< sal_uInt16 >( "mode-x", "CHFRLAYOUT-MODE" );
+ dumpDec< sal_uInt16 >( "mode-y", "CHFRLAYOUT-MODE" );
+ dumpDec< sal_uInt16 >( "mode-w", "CHFRLAYOUT-MODE" );
+ dumpDec< sal_uInt16 >( "mode-h", "CHFRLAYOUT-MODE" );
+ dumpRect< double >( "position" );
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_CHFRSHAPEPROPS:
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt16 >( "context" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt32 >( "checksum" );
+ dumpDec< sal_uInt32 >( "xml-size" );
+ break;
+
+ case BIFF_ID_CHFRTEXTPROPS:
+ dumpFrHeader( true, true );
+ dumpHex< sal_uInt32 >( "checksum" );
+ dumpDec< sal_uInt32 >( "xml-size" );
+ break;
+
+ case BIFF_ID_CHFRUNITPROPS:
+ dumpFrHeader( true, false );
+ dumpDec< sal_Int16 >( "preset", "CHFRUNITPROPS-PRESET" );
+ dumpDec< double >( "unit" );
+ dumpHex< sal_uInt16 >( "flags", "CHFRUNITPROPS-FLAGS" );
+ break;
+
+ case BIFF_ID_CHFRWRAPPER:
+ dumpFrHeader( true, false );
+ 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_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:
+ dumpColorABGR();
+ 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:
+ dumpColorABGR( "border-color" );
+ dumpColorABGR( "fill-color" );
+ 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_CHPIVOTFLAGS:
+ dumpRepeatedRecId();
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "flags", "CHPIVOTFLAGS-FLAGS" );
+ break;
+
+ case BIFF8_ID_CHPIVOTREF:
+ dumpRepeatedRecId();
+ dumpUnused( 4 );
+ dumpUniString( "ref", BIFF_STR_8BITLENGTH );
+ 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" );
+ dumpColorABGR();
+ dumpRect< sal_Int32 >( "position", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
+ dumpHex< sal_uInt16 >( "flags-1", "CHTEXT-FLAGS1" );
+ if( eBiff == BIFF8 ) dumpColorIdx();
+ if( eBiff == BIFF8 ) dumpHex< sal_uInt16 >( "flags-2", "CHTEXT-FLAGS2" );
+ 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" );
+ dumpColorABGR( "label-color" );
+ 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_CHTYPEGROUP:
+ dumpUnused( 16 );
+ dumpHex< sal_uInt16 >( "flags", "CHTYPEGROUP-FLAGS" );
+ if( eBiff >= BIFF5 ) dumpDec< sal_uInt16 >( "group-idx" );
+ 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_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:
+ mxOut->resetItemIndex();
+ for( sal_Int32 nCol = 0, nCount = dumpColRange(); nCol < nCount; ++nCol )
+ dumpXfIdx( "#xf-idx", true );
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_COLWIDTH:
+ dumpColRange( EMPTY_STRING, false );
+ dumpDec< sal_uInt16 >( "col-width", "CONV-COLWIDTH" );
+ break;
+
+ case BIFF_ID_COMPRESSPICS:
+ dumpFrHeader( true, true );
+ dumpBool< sal_uInt32 >( "recommend-compress-pics" );
+ break;
+
+ case BIFF_ID_CONNECTION:
+ {
+ dumpFrHeader( true, false );
+ sal_uInt16 nType = dumpDec< sal_uInt16 >( "data-source-type", "CONNECTION-SOURCETYPE" );
+ sal_uInt16 nFlags1 = dumpHex< sal_uInt16 >( "flags", "CONNECTION-FLAGS" );
+ dumpDec< sal_uInt16 >( "param-count" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "querytable-flags", "QUERYTABLESETTINGS-FLAGS" );
+ switch( nType )
+ {
+ case 4: dumpHex< sal_uInt16 >( "html-flags", "QUERYTABLESETTINGS-HTML-FLAGS" ); break;
+ case 5: dumpHex< sal_uInt16 >( "oledb-flags", "QUERYTABLESETTINGS-OLEDB-FLAGS" ); break;
+ case 7: dumpHex< sal_uInt16 >( "ado-flags", "QUERYTABLESETTINGS-ADO-FLAGS" ); break;
+ default: dumpUnused( 2 );
+ }
+ dumpDec< sal_uInt8 >( "edited-version" );
+ dumpDec< sal_uInt8 >( "refreshed-version" );
+ dumpDec< sal_uInt8 >( "min-refresh-version" );
+ dumpDec< sal_uInt16 >( "refresh-interval", "QUERYTABLESETTINGS-INTERVAL" );
+ dumpDec< sal_uInt16 >( "html-format", "QUERYTABLESETTINGS-HTMLFORMAT" );
+ dumpDec< sal_Int32 >( "reconnect-type", "CONNECTION-RECONNECTTYPE" );
+ dumpDec< sal_uInt8 >( "credentials", "CONNECTION-CREDENTIALS" );
+ dumpUnused( 1 );
+ dumpSegmentedUniString( "source-file" );
+ dumpSegmentedUniString( "source-conn-file" );
+ dumpSegmentedUniString( "name" );
+ dumpSegmentedUniString( "description" );
+ dumpSegmentedUniString( "sso-id" );
+ if( nFlags1 & 0x0004 ) dumpSegmentedUniString( "table-names" );
+ if( nFlags1 & 0x0010 )
+ {
+ break; // TODO: parameter array structure
+ }
+ bool bEscape = false;
+ switch( nType )
+ {
+ case 1:
+ dumpSegmentedUniString( "connection-string" );
+ break;
+ case 4:
+ dumpSegmentedUniStringArray( "urls" );
+ dumpSegmentedUniStringArray( "post-method" );
+ break;
+ case 5:
+ bEscape = true;
+ break;
+ case 6:
+ bEscape = true;
+ break;
+ }
+ if( bEscape )
+ break;
+ dumpSegmentedUniStringArray( "sql-command" );
+ dumpSegmentedUniStringArray( "orig-sql-command" );
+ dumpSegmentedUniStringArray( "webquery-dialog-url" );
+ switch( dumpDec< sal_uInt8 >( "linked-object-type", "CONNECTION-LINKEDOBJECTTYPE" ) )
+ {
+ case 1: dumpSegmentedUniString( "defined-name" ); break;
+ case 2: dumpHex< sal_uInt16 >( "cache-id" ); break;
+ }
+ }
+ break;
+
+ case BIFF_ID_CONT:
+ if( (eBiff == BIFF8) && (getLastRecId() == BIFF_ID_OBJ) )
+ dumpEmbeddedDff();
+ break;
+
+ case BIFF_ID_COORDLIST:
+ {
+ mxOut->resetItemIndex();
+ TableGuard aTabGuard( mxOut, 12, 10 );
+ while( rStrm.getRemaining() >= 4 )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#point" );
+ dumpDec< sal_uInt16 >( "x" );
+ dumpDec< sal_uInt16 >( "y" );
+ }
+ }
+ break;
+
+ case BIFF_ID_COUNTRY:
+ dumpDec< sal_uInt16 >( "ui-country", "COUNTRY" );
+ dumpDec< sal_uInt16 >( "sys-country", "COUNTRY" );
+ 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( mxOut, 14, 17 );
+ for( Address aPos( nCol1, nRow ); !rStrm.isEof() && (aPos.mnCol <= nCol2); ++aPos.mnCol )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeAddressItem( "pos", aPos );
+ dumpConstValue();
+ }
+ }
+ break;
+
+ case BIFF_ID_DCONBINAME:
+ dumpDec< sal_uInt8 >( "builtin-id", "DEFINEDNAME-BUILTINID" );
+ dumpUnused( 3 );
+ dumpString( "source-link", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
+ break;
+
+ case BIFF_ID_DCONNAME:
+ dumpString( "source-name", BIFF_STR_8BITLENGTH );
+ dumpString( "source-link", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
+ break;
+
+ case BIFF_ID_DCONREF:
+ dumpRange( "source-range", false );
+ dumpString( "source-link", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
+ 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 BIFF_ID_DBCELL:
+ dumpDec< sal_uInt32 >( "reverse-offset-to-row" );
+ mxOut->resetItemIndex();
+ while( rStrm.getRemaining() >= 2 )
+ dumpDec< sal_uInt16 >( "#cell-offset" );
+ break;
+
+ case BIFF_ID_DBQUERY:
+ if( eBiff == BIFF8 )
+ {
+ if( (getLastRecId() != BIFF_ID_PCITEM_STRING) && (getLastRecId() != BIFF_ID_DBQUERY) )
+ {
+ dumpHex< sal_uInt16 >( "flags", "DBQUERY-FLAGS" );
+ dumpDec< sal_uInt16 >( "sql-param-count" );
+ dumpDec< sal_uInt16 >( "command-count" );
+ dumpDec< sal_uInt16 >( "post-method-count" );
+ dumpDec< sal_uInt16 >( "server-sql-count" );
+ dumpDec< sal_uInt16 >( "odbc-connection-count" );
+ }
+ }
+ break;
+
+ case BIFF2_ID_DEFINEDNAME:
+ case BIFF3_ID_DEFINEDNAME:
+ {
+ rtl_TextEncoding eTextEnc = getBiffData().getTextEncoding();
+ dumpHex< sal_uInt16, sal_uInt8 >( eBiff != BIFF2, "flags", "DEFINEDNAME-FLAGS" );
+ if( eBiff == BIFF2 ) dumpDec< sal_uInt8 >( "macro-type", "DEFINEDNAME-MACROTYPE-BIFF2" );
+ dumpChar( "accelerator", eTextEnc );
+ sal_uInt8 nNameLen = dumpDec< sal_uInt8 >( "name-len" );
+ sal_uInt16 nFmlaSize = getFormulaDumper().dumpFormulaSize();
+ 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.readUniStringBody( nNameLen, true ) : rStrm.readCharArrayUC( nNameLen, eTextEnc, true ) );
+ getFormulaDumper().dumpNameFormula( EMPTY_STRING, nFmlaSize );
+ if( nMenuLen > 0 ) writeStringItem( "menu-text", bBiff8 ? rStrm.readUniStringBody( nMenuLen, true ) : rStrm.readCharArrayUC( nMenuLen, eTextEnc, true ) );
+ if( nDescrLen > 0 ) writeStringItem( "description-text", bBiff8 ? rStrm.readUniStringBody( nDescrLen, true ) : rStrm.readCharArrayUC( nDescrLen, eTextEnc, true ) );
+ if( nHelpLen > 0 ) writeStringItem( "help-text", bBiff8 ? rStrm.readUniStringBody( nHelpLen, true ) : rStrm.readCharArrayUC( nHelpLen, eTextEnc, true ) );
+ if( nStatusLen > 0 ) writeStringItem( "statusbar-text", bBiff8 ? rStrm.readUniStringBody( nStatusLen, true ) : rStrm.readCharArrayUC( nStatusLen, eTextEnc, true ) );
+ }
+ else
+ {
+ writeStringItem( "name", rStrm.readCharArrayUC( nNameLen, eTextEnc, true ) );
+ getFormulaDumper().dumpNameFormula( EMPTY_STRING, 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_DXF:
+ dumpFrHeader( true, true );
+ dumpHex< sal_uInt16 >( "flags", "DXF-FLAGS" );
+ dumpDxfProp();
+ break;
+
+ case BIFF_ID_EXTERNALBOOK:
+ {
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "sheet-count" );
+ if( rStrm.getRemaining() == 2 )
+ dumpHex< sal_uInt16 >( "special-key", "EXTERNALBOOK-KEY" );
+ else
+ {
+ dumpString( "workbook-url" );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nSheet = 0; !rStrm.isEof() && (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.getRemaining() >= 2) )
+ getFormulaDumper().dumpNameFormula();
+ }
+ break;
+
+ case BIFF_ID_EXTERNSHEET:
+ if( eBiff == BIFF8 )
+ {
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "ref-count" );
+ TableGuard aTabGuard( mxOut, 10, 17, 24 );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nRefId = 0; !rStrm.isEof() && (nRefId < nCount); ++nRefId )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ 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, true ) );
+ 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 BIFF_ID_FILEPASS:
+ {
+ rStrm.enableDecoder( false );
+ if( eBiff == BIFF8 )
+ {
+ switch( dumpDec< sal_uInt16 >( "type", "FILEPASS-TYPE" ) )
+ {
+ case 0:
+ dumpHex< sal_uInt16 >( "key" );
+ dumpHex< sal_uInt16 >( "verifier" );
+ break;
+ case 1:
+ {
+ sal_uInt16 nMajor = dumpDec< sal_uInt16 >( "major-version", "FILEPASS-MAJOR" );
+ dumpDec< sal_uInt16 >( "minor-version" );
+ switch( nMajor )
+ {
+ case 1:
+ dumpArray( "salt", 16 );
+ dumpArray( "verifier", 16 );
+ dumpArray( "verifier-hash", 16 );
+ break;
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ dumpHex< sal_uInt16 >( "key" );
+ dumpHex< sal_uInt16 >( "verifier" );
+ }
+ rStrm.seekToStart();
+ BiffDecoderRef xDecoder = BiffCodecHelper::implReadFilePass( rStrm, eBiff );
+ if( xDecoder.get() )
+ cfg().requestEncryptionData( *xDecoder );
+ setBinaryOnlyMode( !xDecoder || !xDecoder->isValid() );
+ }
+ break;
+
+ case BIFF_ID_FILESHARING:
+ dumpBool< sal_uInt16 >( "recommend-read-only" );
+ dumpHex< sal_uInt16 >( "password-hash" );
+ dumpString( "password-creator", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
+ break;
+
+ case BIFF_ID_FILTERCOLUMN:
+ {
+ dumpDec< sal_uInt16 >( "column-index" );
+ dumpHex< sal_uInt16 >( "flags", "FILTERCOLUMN-FLAGS" );
+ sal_uInt8 nStrLen1 = dumpFilterColumnOperator( "operator-1" );
+ sal_uInt8 nStrLen2 = dumpFilterColumnOperator( "operator-2" );
+ bool bBiff8 = eBiff == BIFF8;
+ rtl_TextEncoding eTextEnc = getBiffData().getTextEncoding();
+ if( nStrLen1 > 0 ) writeStringItem( "string-1", bBiff8 ? rStrm.readUniStringBody( nStrLen1, true ) : rStrm.readCharArrayUC( nStrLen1, eTextEnc, true ) );
+ if( nStrLen2 > 0 ) writeStringItem( "string-2", bBiff8 ? rStrm.readUniStringBody( nStrLen2, true ) : rStrm.readCharArrayUC( nStrLen2, eTextEnc, true ) );
+ }
+ break;
+
+ case BIFF2_ID_FONT:
+ case BIFF3_ID_FONT:
+ dumpFontRec();
+ break;
+
+ case BIFF_ID_FORCEFULLCALC:
+ dumpFrHeader( true, true );
+ dumpBool< sal_Int32 >( "recalc-all-formulas" );
+ 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.getRemaining() > 0 )
+ dumpString( "footer", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_GUTS:
+ dumpDec< sal_uInt16 >( "row-outlines-width" );
+ dumpDec< sal_uInt16 >( "column-outlines-height" );
+ dumpDec< sal_uInt16 >( "row-levels", "GUTS-LEVELS" );
+ dumpDec< sal_uInt16 >( "column-levels", "GUTS-LEVELS" );
+ break;
+
+ case BIFF_ID_HEADER:
+ if( rStrm.getRemaining() > 0 )
+ dumpString( "header", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_HEADERFOOTER:
+ {
+ dumpFrHeader( true, true );
+ dumpGuid( "view-guid" );
+ dumpHex< sal_uInt16 >( "flags", "HEADERFOOTER-FLAGS" );
+ sal_uInt16 nEvenHLen = dumpDec< sal_uInt16 >( "even-h-len" );
+ sal_uInt16 nEvenFLen = dumpDec< sal_uInt16 >( "even-f-len" );
+ sal_uInt16 nFirstHLen = dumpDec< sal_uInt16 >( "first-h-len" );
+ sal_uInt16 nFirstFLen = dumpDec< sal_uInt16 >( "first-f-len" );
+ if( nEvenHLen > 0 ) dumpUniString( "even-h" );
+ if( nEvenFLen > 0 ) dumpUniString( "even-f" );
+ if( nFirstHLen > 0 ) dumpUniString( "first-h" );
+ if( nFirstFLen > 0 ) dumpUniString( "first-f" );
+ }
+ break;
+
+ case BIFF_ID_HYPERLINK:
+ dumpRange();
+ if( cfg().getStringOption( dumpGuid( "guid" ), OUString() ).equalsAscii( "StdHlink" ) )
+ StdHlinkObject( *this ).dump();
+ break;
+
+ case BIFF3_ID_IMGDATA:
+ case BIFF8_ID_IMGDATA:
+ {
+ sal_uInt16 nFormat = dumpDec< sal_uInt16 >( "image-format", "IMGDATA-FORMAT" );
+ dumpDec< sal_uInt16 >( "environment", "IMGDATA-ENV" );
+ dumpDec< sal_uInt32 >( "data-size" );
+ if( nFormat == 9 )
+ {
+ writeEmptyItem( "bitmap-header" );
+ IndentGuard aIndGuard( mxOut );
+ if( dumpDec< sal_uInt32 >( "header-size" ) == 12 )
+ {
+ dumpDec< sal_Int16 >( "width" );
+ dumpDec< sal_Int16 >( "height" );
+ dumpDec< sal_Int16 >( "planes" );
+ dumpDec< sal_Int16 >( "bit-count" );
+ }
+ }
+ }
+ break;
+
+ case BIFF2_ID_INDEX:
+ case BIFF3_ID_INDEX:
+ if( eBiff <= BIFF4 )
+ dumpHex< sal_uInt32 >( "first-defname-pos", "CONV-DEC" );
+ else
+ dumpUnused( 4 );
+ dumpRowIndex( "first-row-with-cell", eBiff == BIFF8 );
+ dumpRowIndex( "first-free-row", eBiff == BIFF8 );
+ if( nRecId == BIFF3_ID_INDEX ) dumpHex< sal_uInt32 >( (eBiff <= BIFF4) ? "first-xf-pos" : "defcolwidth-pos", "CONV-DEC" );
+ mxOut->resetItemIndex();
+ while( rStrm.getRemaining() >= 4 )
+ dumpHex< sal_uInt32 >( "#first-row-pos-of-block", "CONV-DEC" );
+ 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:
+ dumpEmbeddedDff();
+ mbHasDff = true;
+ break;
+
+ case BIFF_ID_MTHREADSETTINGS:
+ dumpFrHeader( true, true );
+ dumpBool< sal_Int32 >( "multi-thread-enabled" );
+ dumpBool< sal_Int32 >( "manual-thread-count" );
+ dumpDec< sal_Int32 >( "thread-count" );
+ break;
+
+ case BIFF_ID_MULTBLANK:
+ {
+ Address aPos = dumpAddress();
+ {
+ TableGuard aTabGuard( mxOut, 12 );
+ for( ; rStrm.getRemaining() >= 4; ++aPos.mnCol )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeAddressItem( "pos", aPos );
+ dumpXfIdx();
+ }
+ }
+ dumpColIndex( "last-col-idx" );
+ }
+ break;
+
+ case BIFF_ID_MULTRK:
+ {
+ Address aPos = dumpAddress();
+ {
+ TableGuard aTabGuard( mxOut, 12, 12 );
+ for( ; rStrm.getRemaining() >= 8; ++aPos.mnCol )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeAddressItem( "pos", aPos );
+ dumpXfIdx();
+ dumpRk( "value" );
+ }
+ }
+ dumpColIndex( "last-col-idx" );
+ }
+ break;
+
+ case BIFF_ID_NOTE:
+ dumpAddress( "anchor-cell" );
+ if( eBiff == BIFF8 )
+ {
+ dumpHex< sal_uInt16 >( "flags", "NOTE-FLAGS" );
+ dumpDec< sal_uInt16 >( "obj-id" );
+ }
+ else
+ {
+ sal_uInt16 nTextLen = ::std::min( dumpDec< sal_uInt16 >( "text-len" ), static_cast< sal_uInt16 >( rStrm.getRemaining() ) );
+ writeStringItem( "note-text", rStrm.readCharArrayUC( nTextLen, getBiffData().getTextEncoding(), true ) );
+ }
+ 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_OLESIZE:
+ dumpUnused( 2 );
+ dumpRange( "visible-range", false );
+ break;
+
+ case BIFF_ID_PAGELAYOUTVIEW:
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt16 >( "scaling", "CONV-PERCENT" );
+ dumpHex< sal_uInt16 >( "flags", "PAGELAYOUTVIEW-FLAGS" );
+ 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_PCITEM_STRING:
+ dumpString( "value" );
+ 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_PTDATAFIELD:
+ dumpDec< sal_Int16 >( "field" );
+ dumpDec< sal_uInt16 >( "subtotal", "PTDATAFIELD-SUBTOTAL" );
+ dumpDec< sal_uInt16 >( "show-data-as", "PTDATAFIELD-SHOWDATAAS" );
+ dumpDec< sal_Int16 >( "base-field" );
+ dumpDec< sal_Int16 >( "base-item", "PTDATAFIELD-BASEITEM" );
+ dumpFormatIdx();
+ dumpPivotString( "name" );
+ break;
+
+ case BIFF_ID_PTDEFINITION:
+ {
+ 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", "PTFIELD-AXISTYPE" );
+ dumpDec< sal_Int16 >( "default-data-pos", "PTDEFINITION-DATAFIELD-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", "PTDEFINITION-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" );
+ dumpPivotString( "table-name", nTabNameLen );
+ dumpPivotString( "data-name", nDataNameLen );
+ mnPTRowColItemsIdx = 0;
+ }
+ break;
+
+ case BIFF_ID_PTDEFINITION2:
+ {
+ dumpDec< sal_uInt16 >( "format-rec-count" );
+ sal_uInt16 nErrCaptLen = dumpDec< sal_uInt16 >( "error-caption-len" );
+ sal_uInt16 nMissCaptLen = dumpDec< sal_uInt16 >( "missing-caption-len" );
+ sal_uInt16 nTagLen = dumpDec< sal_uInt16 >( "tag-len" );
+ dumpDec< sal_uInt16 >( "select-rec-count" );
+ dumpDec< sal_uInt16 >( "page-rows" );
+ dumpDec< sal_uInt16 >( "page-cols" );
+ dumpHex< sal_uInt32 >( "flags", "PTDEFINITION2-FLAGS" );
+ sal_uInt16 nPageStyleLen = dumpDec< sal_uInt16 >( "page-field-style-len" );
+ sal_uInt16 nTabStyleLen = dumpDec< sal_uInt16 >( "pivot-table-style-len" );
+ sal_uInt16 nVacStyleLen = dumpDec< sal_uInt16 >( "vacated-style-len" );
+ dumpPivotString( "error-caption", nErrCaptLen );
+ dumpPivotString( "missing-caption", nMissCaptLen );
+ dumpPivotString( "tag", nTagLen );
+ dumpPivotString( "page-field-style", nPageStyleLen );
+ dumpPivotString( "pivot-table-style", nTabStyleLen );
+ dumpPivotString( "vacated-style", nVacStyleLen );
+ }
+ break;
+
+ case BIFF_ID_PTFIELD:
+ dumpDec< sal_uInt16 >( "axis-type", "PTFIELD-AXISTYPE" );
+ dumpDec< sal_uInt16 >( "subtotal-count" );
+ dumpHex< sal_uInt16 >( "subtotals", "PTFIELD-SUBTOTALS" );
+ dumpDec< sal_uInt16 >( "item-count" );
+ dumpPivotString( "field-name" );
+ break;
+
+ case BIFF_ID_PTFIELD2:
+ dumpHex< sal_uInt32 >( "flags", "PTFIELD2-FLAGS" );
+ dumpDec< sal_Int16 >( "autosort-basefield-idx" );
+ dumpDec< sal_Int16 >( "autoshow-basefield-idx" );
+ dumpFormatIdx();
+ if( rStrm.getRemaining() >= 2 )
+ {
+ sal_uInt16 nFuncNameLen = dumpDec< sal_uInt16 >( "subtotal-func-name-len" );
+ dumpUnused( 8 );
+ dumpPivotString( "subtotal-func-name", nFuncNameLen );
+ }
+ break;
+
+ case BIFF_ID_PTFITEM:
+ dumpDec< sal_uInt16 >( "item-type", "PTFITEM-ITEMTYPE" );
+ dumpHex< sal_uInt16 >( "flags", "PTFITEM-FLAGS" );
+ dumpDec< sal_Int16 >( "cache-idx", "PTFITEM-CACHEIDX" );
+ dumpPivotString( "item-name" );
+ break;
+
+ case BIFF_ID_PTPAGEFIELDS:
+ {
+ mxOut->resetItemIndex();
+ TableGuard aTabGuard( mxOut, 17, 17, 17 );
+ while( rStrm.getRemaining() >= 6 )
+ {
+ writeEmptyItem( "#page-field" );
+ MultiItemsGuard aMultiGuard( mxOut );
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_Int16 >( "base-field" );
+ dumpDec< sal_Int16 >( "item", "PTPAGEFIELDS-ITEM" );
+ dumpDec< sal_uInt16 >( "dropdown-obj-id" );
+ }
+ }
+ break;
+
+ case BIFF_ID_PTROWCOLFIELDS:
+ mxOut->resetItemIndex();
+ for( sal_Int64 nIdx = 0, nCount = rStrm.getRemaining() / 2; nIdx < nCount; ++nIdx )
+ dumpDec< sal_Int16 >( "#field-idx" );
+ break;
+
+ case BIFF_ID_PTROWCOLITEMS:
+ if( mnPTRowColItemsIdx < 2 )
+ {
+ sal_uInt16 nCount = (mnPTRowColItemsIdx == 0) ? mnPTRowFields : mnPTColFields;
+ sal_Int64 nLineSize = 8 + 2 * nCount;
+ mxOut->resetItemIndex();
+ while( rStrm.getRemaining() >= nLineSize )
+ {
+ writeEmptyItem( "#line-data" );
+ IndentGuard aIndGuard( mxOut );
+ MultiItemsGuard aMultiGuard( mxOut );
+ dumpDec< sal_uInt16 >( "ident-count" );
+ dumpDec< sal_uInt16 >( "item-type", "PTROWCOLITEMS-ITEMTYPE" );
+ dumpDec< sal_uInt16 >( "used-count" );
+ dumpHex< sal_uInt16 >( "flags", "PTROWCOLITEMS-FLAGS" );
+ OUStringBuffer aItemList;
+ for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
+ StringHelper::appendToken( aItemList, mxStrm->readInt16() );
+ writeInfoItem( "item-idxs", aItemList.makeStringAndClear() );
+ }
+ ++mnPTRowColItemsIdx;
+ }
+ break;
+
+ case BIFF_ID_QUERYTABLE:
+ dumpHex< sal_uInt16 >( "flags", "QUERYTABLE-FLAGS" );
+ dumpDec< sal_uInt16 >( "autoformat-id" );
+ dumpHex< sal_uInt16 >( "autoformat-flags", "QUERYTABLE-AUTOFORMAT-FLAGS" );
+ dumpUnused( 4 );
+ dumpUniString( "defined-name" );
+ dumpUnused( 2 );
+ break;
+
+ case BIFF_ID_QUERYTABLEREFRESH:
+ {
+ dumpFrHeader( true, false );
+ bool bPivot = dumpBool< sal_uInt16 >( "pivot-table" );
+ dumpHex< sal_uInt16 >( "flags", "QUERYTABLEREFRESH-FLAGS" );
+ dumpHex< sal_uInt32 >( bPivot ? "pivottable-flags" : "querytable-flags", bPivot ? "QUERYTABLEREFRESH-PTFLAGS" : "QUERYTABLEREFRESH-QTFLAGS" );
+ dumpDec< sal_uInt8 >( "refreshed-version" );
+ dumpDec< sal_uInt8 >( "min-refresh-version" );
+ dumpUnused( 2 );
+ dumpUniString( "table-name" );
+ dumpUnused( 2 );
+ }
+ break;
+
+ case BIFF_ID_QUERYTABLESETTINGS:
+ {
+ dumpFrHeader( true, false );
+ sal_uInt16 nType = dumpDec< sal_uInt16 >( "data-source-type", "CONNECTION-SOURCETYPE" );
+ dumpHex< sal_uInt16 >( "flags-1", "QUERYTABLESETTINGS-FLAGS" );
+ switch( nType )
+ {
+ case 4: dumpHex< sal_uInt16 >( "html-flags", "QUERYTABLESETTINGS-HTML-FLAGS" ); break;
+ case 5: dumpHex< sal_uInt16 >( "oledb-flags", "QUERYTABLESETTINGS-OLEDB-FLAGS" ); break;
+ case 7: dumpHex< sal_uInt16 >( "ado-flags", "QUERYTABLESETTINGS-ADO-FLAGS" ); break;
+ default: dumpUnused( 2 );
+ }
+ dumpHex< sal_uInt16 >( "ext-flags", "QUERYTABLESETTINGS-EXT-FLAGS" );
+ dumpDec< sal_uInt8 >( "edited-version" );
+ dumpDec< sal_uInt8 >( "refreshed-version" );
+ dumpDec< sal_uInt8 >( "min-refresh-version" );
+ dumpUnused( 3 );
+ dumpDec< sal_uInt16 >( "oledb-count" );
+ dumpDec< sal_uInt16 >( "future-data-size" );
+ dumpDec< sal_uInt16 >( "refresh-interval", "QUERYTABLESETTINGS-INTERVAL" );
+ dumpDec< sal_uInt16 >( "html-format", "QUERYTABLESETTINGS-HTMLFORMAT" );
+ }
+ break;
+
+ case BIFF_ID_QUERYTABLESTRING:
+ dumpFrHeader( true, false );
+ dumpUniString( "connection-string" );
+ break;
+
+ case BIFF_ID_RECALCID:
+ dumpFrHeader( true, false );
+ dumpDec< sal_uInt32 >( "recalc-engine-id" );
+ 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 );
+ FontPortionModelList aPortions;
+ aPortions.importPortions( rStrm, eBiff == BIFF8 );
+ writeFontPortions( aPortions );
+ }
+ break;
+
+ case BIFF_ID_SCENARIO:
+ {
+ sal_uInt16 nCellCount = dumpDec< sal_uInt16 >( "cell-count" );
+ // two bytes instead of flag field
+ dumpBoolean( "locked" );
+ dumpBoolean( "hidden" );
+ sal_uInt16 nNameLen = dumpDec< sal_uInt8 >( "name-len" );
+ sal_uInt16 nCommentLen = dumpDec< sal_uInt8 >( "comment-len" );
+ sal_uInt16 nUserLen = dumpDec< sal_uInt8 >( "user-len" );
+ writeStringItem( "name", rStrm.readUniStringBody( nNameLen, true ) );
+ if( nUserLen > 0 ) dumpUniString( "user" ); // repeated string length
+ if( nCommentLen > 0 ) dumpUniString( "comment" ); // repeated string length
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nCell = 0; !rStrm.isEof() && (nCell < nCellCount); ++nCell )
+ dumpAddress( "#pos" );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nCell = 0; !rStrm.isEof() && (nCell < nCellCount); ++nCell )
+ dumpString( "#value" );
+ dumpUnused( 2 * nCellCount );
+ }
+ break;
+
+ case BIFF_ID_SCENARIOS:
+ dumpDec< sal_uInt16 >( "count" );
+ dumpDec< sal_uInt16 >( "selected" );
+ dumpDec< sal_uInt16 >( "shown" );
+ dumpRangeList( "result-cells" );
+ 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:
+ dumpFrHeader( false, true );
+ dumpNullUnicodeArray( "tooltip" );
+ 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_SHAREDFEATHEAD:
+ {
+ dumpFrHeader( true, true );
+ sal_uInt16 nType = dumpDec< sal_uInt16 >( "feature-type", "SHAREDFEATHEAD-TYPE" );
+ dumpUnused( 1 );
+ if( dumpBool< sal_Int32 >( "has-data" ) ) switch( nType )
+ {
+ case 2:
+ dumpHex< sal_uInt32 >( "allowed-flags", "SHAREDFEATHEAD-PROT-FLAGS" );
+ break;
+ }
+ }
+ 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 )
+ {
+ rStrm.enableDecoder( false );
+ dumpHex< sal_uInt32 >( "sheet-stream-pos", "CONV-DEC" );
+ rStrm.enableDecoder( true );
+ dumpDec< sal_uInt8 >( "sheet-state", "SHEET-STATE" );
+ dumpDec< sal_uInt8 >( "sheet-type", "SHEET-TYPE" );
+ }
+ dumpString( "sheet-name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_SHEETEXT:
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt32 >( "rec-size" );
+ dumpDec< sal_uInt32 >( "flags-1", "SHEETEXT-FLAGS1" );
+ if( rStrm.getRemaining() >= 20 )
+ {
+ dumpDec< sal_uInt32 >( "flags-2", "SHEETEXT-FLAGS2" );
+ dumpExtCfColor( "tab-color" );
+ }
+ break;
+
+ case BIFF_ID_SHEETHEADER:
+ dumpHex< sal_uInt32 >( "substream-size", "CONV-DEC" );
+ dumpByteString( "sheet-name", BIFF_STR_8BITLENGTH );
+ break;
+
+ case BIFF_ID_SST:
+ dumpDec< sal_uInt32 >( "string-cell-count" );
+ dumpDec< sal_uInt32 >( "sst-size" );
+ mxOut->resetItemIndex();
+ while( !rStrm.isEof() && (rStrm.getRemaining() >= 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_Int8 >( "builtin-idx", "STYLE-BUILTIN" );
+ dumpDec< sal_Int8 >( "outline-level" );
+ }
+ else
+ dumpString( "style-name", BIFF_STR_8BITLENGTH );
+ }
+ break;
+
+ case BIFF_ID_STYLEEXT:
+ dumpFrHeader( true, true );
+ dumpHex< sal_uInt8 >( "flags", "STYLEEXT-FLAGS" );
+ dumpDec< sal_uInt8 >( "category", "STYLEEXT-CATEGORY" );
+ dumpDec< sal_Int8 >( "builtin-idx", "STYLEEXT-BUILTIN" );
+ dumpDec< sal_Int8 >( "outline-level" );
+ dumpUnicodeArray( "style-name", rStrm.readuInt16() );
+ dumpDxfProp();
+ break;
+
+ case BIFF_ID_TABLESTYLES:
+ {
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt32 >( "table-style-count" );
+ sal_uInt16 nDefTableLen, nDefPivotLen;
+ rStrm >> nDefTableLen >> nDefPivotLen;
+ dumpUnicodeArray( "def-table-style", nDefTableLen );
+ dumpUnicodeArray( "def-pivot-style", nDefPivotLen );
+ }
+ break;
+
+ case BIFF_ID_THEME:
+ dumpFrHeader( true, true );
+ dumpDec< sal_uInt32 >( "theme-version", "THEME-VERSION" );
+ break;
+
+ case BIFF_ID_TXO:
+ dumpHex< sal_uInt16 >( "flags", "TXO-FLAGS" );
+ dumpDec< sal_uInt16 >( "orientation", "TEXTORIENTATION" );
+ dumpHex< sal_uInt16 >( "button-flags", "OBJ-BUTTON-FLAGS" );
+ dumpUnicode( "accelerator" );
+ dumpUnicode( "fareast-accelerator" );
+ dumpDec< sal_uInt16 >( "text-len" );
+ dumpDec< sal_uInt16 >( "format-run-size" );
+ dumpUnused( 4 );
+ 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" );
+ dumpColorABGR( "grid-color" );
+ 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.getRemaining() >= 8 )
+ {
+ dumpDec< sal_uInt16 >( "pagebreak-zoom", "CONV-PERCENT" );
+ dumpDec< sal_uInt16 >( "normal-zoom", "CONV-PERCENT" );
+ dumpUnused( 4 );
+ }
+ }
+ else
+ dumpColorABGR( "grid-color" );
+ break;
+
+ case BIFF_ID_WRITEACCESS:
+ dumpString( "user-name", BIFF_STR_8BITLENGTH );
+ 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;
+
+ case BIFF_ID_XFCRC:
+ dumpFrHeader( true, true );
+ dumpUnused( 2 );
+ dumpDec< sal_uInt16 >( "xf-count" );
+ dumpHex< sal_uInt32 >( "xf-checksum" );
+ break;
+
+ case BIFF_ID_XFEXT:
+ dumpFrHeader( true, true );
+ dumpUnused( 2 );
+ dumpXfIdx( "xf-idx" );
+ dumpUnused( 2 );
+ dumpXfExtProp();
+ break;
+ }
+}
+
+void WorkbookStreamObject::initializePerSheet()
+{
+ getBiffData().initializePerSheet();
+ mxFontNames = cfg().createNameList< ConstList >( "FONTNAMES" );
+ mxFontNames->setName( 0, createFontName( CREATE_OUSTRING( "Arial" ), 200, false, false ) );
+ mxFormats = cfg().createNameList< ConstList >( "FORMATS" );
+ mxFormats->includeList( cfg().getNameList( "BUILTIN-FORMATS" ) );
+ mnFormatIdx = 0;
+ mbHasCodePage = false;
+}
+
+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 String& rName, bool b16Bit )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, rName( "fill-pattern" ), mxFillPatterns );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpColorIdx( const String& rName, bool b16Bit )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, rName( "color-idx" ), mxColors );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpFontIdx( const String& rName, bool b16Bit )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, rName( "font-idx" ), mxFontNames );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpFormatIdx( const String& rName )
+{
+ return dumpDec< sal_uInt16, sal_uInt8 >( getBiff() >= BIFF5, rName( "fmt-idx" ), mxFormats );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpXfIdx( const String& rName, bool bBiff2Style )
+{
+ String aName = rName( "xf-idx" );
+ sal_uInt16 nXfIdx = 0;
+ if( bBiff2Style )
+ {
+ dumpHex< sal_uInt8 >( aName, "CELL-XFINDEX" );
+ dumpHex< sal_uInt8 >( "fmt-font-idx", "CELL-XFFORMAT" );
+ dumpHex< sal_uInt8 >( "style", "CELL-XFSTYLE" );
+ }
+ else
+ nXfIdx = dumpDec< sal_uInt16 >( aName );
+ return nXfIdx;
+}
+
+void WorkbookStreamObject::dumpExtColorValue( sal_uInt32 nColorType )
+{
+ switch( nColorType )
+ {
+ case 0: dumpUnused( 4 ); break;
+ case 1: dumpDec< sal_uInt32 >( "color-idx", mxColors ); break;
+ case 2: dumpColorABGR(); break;
+ case 3: dumpDec< sal_uInt32 >( "theme-id" ); break;
+ case 4: dumpUnused( 4 ); break;
+ default: dumpUnknown( 4 );
+ }
+}
+
+void WorkbookStreamObject::dumpExtColor( const String& rName )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( rName( "color" ) );
+ switch( extractValue< sal_uInt8 >( dumpDec< sal_uInt8 >( "flags", "EXTCOLOR-FLAGS" ), 1, 7 ) )
+ {
+ case 0: dumpUnused( 1 ); break;
+ case 1: dumpColorIdx( "color-idx", false ); break;
+ case 2: dumpUnused( 1 ); break;
+ case 3: dumpDec< sal_uInt8 >( "theme-id" ); break;
+ case 4: dumpUnused( 1 ); break;
+ default: dumpUnknown( 1 );
+ }
+ dumpDec< sal_Int16 >( "tint", "CONV-TINT" );
+ dumpColorABGR();
+}
+
+void WorkbookStreamObject::dumpExtCfColor( const String& rName )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( rName( "color" ) );
+ dumpExtColorValue( dumpExtColorType< sal_uInt32 >() );
+ dumpDec< double >( "tint", "CONV-FLOAT-TO-PERC" );
+}
+
+void WorkbookStreamObject::dumpExtGradientHead()
+{
+ dumpDec< sal_Int32 >( "gradient-type", "EXTGRADIENT-TYPE" );
+ dumpDec< double >( "linear-angle" );
+ dumpDec< double >( "pos-left" );
+ dumpDec< double >( "pos-right" );
+ dumpDec< double >( "pos-top" );
+ dumpDec< double >( "pos-bottom" );
+}
+
+sal_uInt8 WorkbookStreamObject::dumpFilterColumnOperator( const String& rName )
+{
+ sal_uInt8 nStrLen = 0;
+ writeEmptyItem( rName );
+ IndentGuard aIndGuard( mxOut );
+ sal_uInt8 nType = dumpDec< sal_uInt8 >( "data-type", "FILTERCOLUMN-DATATYPE" );
+ dumpDec< sal_uInt8 >( "operator", "FILTERCOLUMN-OPERATOR" );
+ switch( nType )
+ {
+ case 2:
+ dumpRk( "value" );
+ dumpUnused( 4 );
+ break;
+ case 4:
+ dumpDec< double >( "value" );
+ break;
+ case 6:
+ dumpUnused( 4 );
+ nStrLen = dumpDec< sal_uInt8 >( "length" );
+ dumpBoolean( "simple" );
+ dumpUnused( 2 );
+ break;
+ case 8:
+ dumpBoolErr();
+ dumpUnused( 6 );
+ break;
+ default:
+ dumpUnused( 8 );
+ }
+ return nStrLen;
+}
+
+OUString WorkbookStreamObject::dumpPivotString( const String& rName, sal_uInt16 nStrLen )
+{
+ OUString aString;
+ if( nStrLen != BIFF_PT_NOSTRING )
+ {
+ aString = (getBiff() == BIFF8) ?
+ getBiffStream().readUniStringBody( nStrLen ) :
+ getBiffStream().readCharArrayUC( nStrLen, getBiffData().getTextEncoding() );
+ writeStringItem( rName, aString );
+ }
+ return aString;
+}
+
+OUString WorkbookStreamObject::dumpPivotString( const String& rName )
+{
+ sal_uInt16 nStrLen = dumpDec< sal_uInt16 >( "string-len", "PIVOT-NAMELEN" );
+ return dumpPivotString( rName, nStrLen );
+}
+
+sal_uInt16 WorkbookStreamObject::dumpCellHeader( bool bBiff2Style )
+{
+ dumpAddress();
+ return dumpXfIdx( EMPTY_STRING, bBiff2Style );
+}
+
+void WorkbookStreamObject::dumpBoolErr()
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ sal_uInt8 nValue = dumpHex< sal_uInt8 >( "value" );
+ bool bErrCode = dumpBool< sal_uInt8 >( "is-error-code" );
+ if( bErrCode )
+ writeErrorCodeItem( "error-code", nValue );
+ else
+ writeBooleanItem( "boolean", nValue );
+}
+
+void WorkbookStreamObject::dumpCfRuleProp()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ sal_uInt32 nFlags1 = dumpHex< sal_uInt32 >( "flags-1", "CFRULE-FLAGS1" );
+ sal_uInt16 nFlags2 = dumpHex< sal_uInt16 >( "flags-2", "CFRULE-FLAGS2" );
+ if( getFlag< sal_uInt32 >( nFlags1, 0x02000000 ) )
+ {
+ writeEmptyItem( "numfmt-block" );
+ IndentGuard aIndGuard( mxOut );
+ if( getFlag< sal_uInt16 >( nFlags2, 0x0001 ) )
+ {
+ dumpDec< sal_uInt16 >( "size" );
+ dumpUniString( "numfmt" );
+ }
+ else
+ {
+ dumpUnused( 1 );
+ dumpDec< sal_uInt8 >( "fmt-idx", mxFormats );
+ }
+ }
+ if( getFlag< sal_uInt32 >( nFlags1, 0x04000000 ) )
+ {
+ writeEmptyItem( "font-block" );
+ IndentGuard aIndGuard( mxOut );
+ sal_Int64 nRecPos = rStrm.tell();
+ dumpUniString( "name", BIFF_STR_8BITLENGTH );
+ dumpUnused( static_cast< sal_Int32 >( nRecPos + 64 - rStrm.tell() ) );
+ dumpDec< sal_Int32 >( "height", "CONV-TWIP-TO-PT" );
+ dumpHex< sal_uInt32 >( "flags", "CFRULE-FONTFLAGS" );
+ dumpDec< sal_Int16 >( "weight", "CFRULE-FONTWEIGHT" );
+ dumpDec< sal_Int16 >( "escapement", "CFRULE-FONTESCAPEMENT" );
+ dumpDec< sal_Int8 >( "underline", "CFRULE-FONTUNDERLINE" );
+ dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
+ dumpDec< sal_uInt8 >( "charset", "CHARSET" );
+ dumpUnused( 1 );
+ dumpDec< sal_Int32 >( "color", "CFRULE-FONTCOLOR" );
+ dumpUnused( 4 );
+ dumpHex< sal_uInt32 >( "used-flags", "CFRULE-FONTUSEDFLAGS" );
+ dumpDec< sal_uInt32 >( "escapement-used", "CFRULE-FONTUSED" );
+ dumpDec< sal_uInt32 >( "underline-used", "CFRULE-FONTUSED" );
+ dumpDec< sal_uInt32 >( "weight-used", "CFRULE-FONTUSED" );
+ dumpUnused( 4 );
+ dumpDec< sal_Int32 >( "first-char" );
+ dumpDec< sal_Int32 >( "char-count" );
+ dumpDec< sal_uInt16 >( "font-idx" );
+ }
+ if( getFlag< sal_uInt32 >( nFlags1, 0x08000000 ) )
+ {
+ writeEmptyItem( "alignment-block" );
+ IndentGuard aIndGuard( mxOut );
+ dumpHex< sal_uInt8 >( "alignent", "CFRULE-ALIGNMENT" );
+ dumpHex< sal_uInt8 >( "rotation", "TEXTROTATION" );
+ dumpHex< sal_uInt16 >( "indent", "CFRULE-INDENT" );
+ dumpDec< sal_Int32 >( "relative-indent" );
+ }
+ if( getFlag< sal_uInt32 >( nFlags1, 0x10000000 ) )
+ {
+ writeEmptyItem( "border-block" );
+ IndentGuard aIndGuard( mxOut );
+ 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 >( nFlags1, 0x20000000 ) )
+ {
+ writeEmptyItem( "pattern-block" );
+ IndentGuard aIndGuard( mxOut );
+ dumpHex< sal_uInt32 >( "pattern", "CFRULE-FILLBLOCK" );
+ }
+ if( getFlag< sal_uInt32 >( nFlags1, 0x40000000 ) )
+ {
+ writeEmptyItem( "protection-block" );
+ IndentGuard aIndGuard( mxOut );
+ dumpHex< sal_uInt16 >( "flags", "CFRULE-PROTECTION-FLAGS" );
+ }
+}
+
+void WorkbookStreamObject::dumpXfExtProp()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "subrec-count" ); !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ {
+ mxOut->startMultiItems();
+ sal_Int64 nStartPos = rStrm.tell();
+ writeEmptyItem( "SUBREC" );
+ sal_uInt16 nSubRecId = dumpDec< sal_uInt16 >( "id", "XFEXT-SUBREC" );
+ sal_uInt16 nSubRecSize = dumpDec< sal_uInt16 >( "size" );
+ sal_Int64 nEndPos = nStartPos + nSubRecSize;
+ mxOut->endMultiItems();
+ IndentGuard aIndGuard( mxOut );
+ switch( nSubRecId )
+ {
+ case 4: case 5: case 7: case 8: case 9: case 10: case 11: case 13:
+ {
+ sal_uInt16 nColorType = dumpExtColorType< sal_uInt16 >();
+ dumpDec< sal_Int16 >( "tint", "CONV-TINT" );
+ dumpExtColorValue( nColorType );
+ dumpUnused( 8 );
+ }
+ break;
+ case 6:
+ dumpExtGradientHead();
+ mxOut->resetItemIndex();
+ for( sal_Int32 nStop = 0, nStopCount = dumpDec< sal_Int32 >( "stop-count" ); (nStop < nStopCount) && !mxStrm->isEof(); ++nStop )
+ {
+ writeEmptyItem( "#stop" );
+ IndentGuard aIndGuard2( mxOut );
+ sal_uInt16 nColorType = dumpExtColorType< sal_uInt16 >();
+ dumpExtColorValue( nColorType );
+ dumpDec< double >( "stop-pos" );
+ dumpDec< double >( "tint", "CONV-FLOAT-TO-PERC" );
+ }
+ break;
+ case 14:
+ dumpDec< sal_Int8 >( "font-scheme", "EXTFONT-SCHEME" );
+ break;
+ case 15:
+ dumpDec< sal_uInt16 >( "indent" );
+ break;
+ }
+ dumpRemainingTo( nEndPos );
+ }
+}
+
+void WorkbookStreamObject::dumpDxfProp()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ dumpUnused( 2 );
+ for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "subrec-count" ); !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ {
+ mxOut->startMultiItems();
+ sal_Int64 nStartPos = rStrm.tell();
+ writeEmptyItem( "SUBREC" );
+ sal_uInt16 nSubRecId = dumpDec< sal_uInt16 >( "id", "DXF-SUBREC" );
+ sal_uInt16 nSubRecSize = dumpDec< sal_uInt16 >( "size" );
+ sal_Int64 nEndPos = nStartPos + nSubRecSize;
+ mxOut->endMultiItems();
+ IndentGuard aIndGuard( mxOut );
+ switch( nSubRecId )
+ {
+ case 0:
+ dumpDec< sal_uInt8 >( "pattern", mxFillPatterns );
+ break;
+ case 1: case 2: case 5:
+ dumpExtColor();
+ break;
+ case 3:
+ dumpExtGradientHead();
+ break;
+ case 4:
+ dumpDec< sal_uInt16 >( "index" );
+ dumpDec< double >( "stop-position" );
+ dumpExtColor( "stop-color" );
+ break;
+ case 6: case 7: case 8: case 9: case 10: case 11: case 12:
+ dumpExtColor( "color" );
+ dumpDec< sal_uInt16 >( "style", mxBorderStyles );
+ 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: case 23:
+ dumpBoolean( "value" );
+ break;
+ case 24:
+ dumpUnicodeArray( "name", rStrm.readuInt16() );
+ 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 34:
+ dumpDec< sal_uInt8 >( "charset", "CHARSET" );
+ break;
+ case 35:
+ dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
+ break;
+ case 36:
+ dumpDec< sal_Int32 >( "height", "CONV-TWIP-TO-PT" );
+ break;
+ case 37:
+ dumpDec< sal_uInt8 >( "scheme", "EXTFONT-SCHEME" );
+ break;
+ case 38:
+ dumpUnicodeArray( "numfmt", rStrm.readuInt16() );
+ break;
+ case 41:
+ dumpDec< sal_uInt16 >( "fmt-idx", mxFormats );
+ break;
+ case 42:
+ dumpDec< sal_Int16 >( "relative-indent" );
+ break;
+ case 43: case 44:
+ dumpBoolean( "value" );
+ break;
+ }
+ dumpRemainingTo( nEndPos );
+ }
+}
+
+void WorkbookStreamObject::dumpDxf12Prop()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ writeEmptyItem( "dxf-data" );
+ IndentGuard aIndGuard( mxOut );
+ sal_uInt32 nSize = dumpDec< sal_uInt32 >( "dxf-size" );
+ if( nSize == 0 )
+ {
+ dumpUnused( 2 );
+ }
+ else
+ {
+ sal_Int64 nEndPos = rStrm.tell() + nSize;
+ dumpCfRuleProp();
+ if( rStrm.tell() + 8 <= nEndPos )
+ {
+ dumpUnused( 6 );
+ dumpXfExtProp();
+ }
+ dumpRemainingTo( nEndPos );
+ }
+}
+
+void WorkbookStreamObject::dumpCfRule12Param( sal_uInt16 nSubType )
+{
+ sal_uInt8 nSize = dumpDec< sal_uInt8 >( "params-size" );
+ sal_Int64 nEndPos = getBiffStream().tell() + nSize;
+ {
+ writeEmptyItem( "params" );
+ IndentGuard aIndGuard( mxOut );
+ switch( nSubType )
+ {
+ case 5:
+ dumpHex< sal_uInt8 >( "flags", "CFRULE12-TOP10-FLAGS" );
+ dumpDec< sal_uInt16 >( "rank" );
+ dumpUnused( 13 );
+ break;
+ case 8:
+ dumpDec< sal_uInt16 >( "operator", "CFRULE12-TEXT-OPERATOR" );
+ dumpUnused( 14 );
+ break;
+ case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24:
+ dumpDec< sal_uInt16 >( "operator", "CFRULE12-DATE-OPERATOR" );
+ dumpUnused( 14 );
+ break;
+ case 25: case 26: case 29: case 30:
+ dumpDec< sal_uInt16 >( "std-dev" );
+ dumpUnused( 14 );
+ break;
+ default:
+ dumpUnused( 16 );
+ }
+ }
+ dumpRemainingTo( nEndPos );
+}
+
+void WorkbookStreamObject::dumpFontRec()
+{
+ sal_uInt16 nFontId = getBiffData().getFontCount();
+ mxOut->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++;
+ mxOut->resetItemIndex( nFormatIdx );
+ writeEmptyItem( "#fmt" );
+ break;
+ case BIFF4:
+ nFormatIdx = mnFormatIdx++;
+ mxOut->resetItemIndex( nFormatIdx );
+ writeEmptyItem( "#fmt" );
+ dumpUnused( 2 );
+ break;
+ case BIFF5:
+ case BIFF8:
+ getBiffStream() >> nFormatIdx;
+ mxOut->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();
+ mxOut->resetItemIndex( nXfId );
+ writeEmptyItem( "#xf" );
+ sal_uInt16 nFontId = dumpFontIdx( EMPTY_STRING, 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 BIFF3:
+ dumpObjRecBiff3();
+ break;
+ case BIFF4:
+ dumpObjRecBiff4();
+ break;
+ case BIFF5:
+ dumpObjRecBiff5();
+ break;
+ case BIFF8:
+ // #i61786# OBJ records without DFF stream are in BIFF5 format
+ if( mbHasDff ) dumpObjRecBiff8(); else dumpObjRecBiff5();
+ break;
+ default:;
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecBiff3()
+{
+ 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" );
+ dumpDffClientRect();
+ sal_uInt16 nMacroSize = dumpDec< sal_uInt16 >( "macro-size" );
+ dumpUnused( 2 );
+ sal_uInt16 nTextLen = 0, nFormatSize = 0, nLinkSize = 0;
+ switch( nObjType )
+ {
+ case BIFF_OBJTYPE_GROUP:
+ dumpUnused( 4 );
+ dumpDec< sal_uInt16 >( "next-ungrouped-id" );
+ dumpUnused( 16 );
+ dumpObjRecString( "macro", nMacroSize, true );
+ break;
+ case BIFF_OBJTYPE_LINE:
+ dumpObjRecLineData();
+ dumpHex< sal_uInt16 >( "line-end", "OBJ-LINEENDS" );
+ dumpDec< sal_uInt8 >( "line-direction", "OBJ-LINEDIR" );
+ dumpUnused( 1 );
+ dumpObjRecString( "macro", nMacroSize, true );
+ break;
+ case BIFF_OBJTYPE_RECTANGLE:
+ case BIFF_OBJTYPE_OVAL:
+ dumpObjRecRectData();
+ dumpObjRecString( "macro", nMacroSize, true );
+ break;
+ case BIFF_OBJTYPE_ARC:
+ dumpObjRecFillData();
+ dumpObjRecLineData();
+ dumpDec< sal_uInt8 >( "quadrant", "OBJ-ARC-QUADRANT" );
+ dumpUnused( 1 );
+ dumpObjRecString( "macro", nMacroSize, true );
+ break;
+ case BIFF_OBJTYPE_CHART:
+ dumpObjRecRectData();
+ dumpUnused( 18 );
+ dumpObjRecString( "macro", nMacroSize, true );
+ break;
+ case BIFF_OBJTYPE_TEXT:
+ case BIFF_OBJTYPE_BUTTON:
+ dumpObjRecRectData();
+ dumpObjRecTextDataBiff3( nTextLen, nFormatSize );
+ dumpObjRecString( "macro", nMacroSize, true );
+ dumpObjRecString( "text", nTextLen, false );
+ dumpObjRecTextFmt( nFormatSize );
+ break;
+ case BIFF_OBJTYPE_PICTURE:
+ dumpObjRecRectData();
+ dumpDec< sal_Int16 >( "image-format", "IMGDATA-FORMAT" );
+ dumpUnused( 4 );
+ nLinkSize = dumpDec< sal_uInt16 >( "pic-link-size" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-PICTURE-FLAGS" );
+ dumpObjRecString( "macro", nMacroSize, true );
+ dumpObjRecPictFmla( nLinkSize );
+ break;
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecBiff4()
+{
+ 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" );
+ dumpDffClientRect();
+ sal_uInt16 nMacroSize = dumpDec< sal_uInt16 >( "macro-size" );
+ dumpUnused( 2 );
+ sal_uInt16 nTextLen = 0, nFormatSize = 0, nLinkSize = 0;
+ switch( nObjType )
+ {
+ case BIFF_OBJTYPE_GROUP:
+ dumpUnused( 4 );
+ dumpDec< sal_uInt16 >( "next-ungrouped-id" );
+ dumpUnused( 16 );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_LINE:
+ dumpObjRecLineData();
+ dumpHex< sal_uInt16 >( "line-end", "OBJ-LINEENDS" );
+ dumpDec< sal_uInt8 >( "line-direction", "OBJ-LINEDIR" );
+ dumpUnused( 1 );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_RECTANGLE:
+ case BIFF_OBJTYPE_OVAL:
+ dumpObjRecRectData();
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_ARC:
+ dumpObjRecFillData();
+ dumpObjRecLineData();
+ dumpDec< sal_uInt8 >( "quadrant", "OBJ-ARC-QUADRANT" );
+ dumpUnused( 1 );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_CHART:
+ dumpObjRecRectData();
+ dumpUnused( 18 );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_TEXT:
+ case BIFF_OBJTYPE_BUTTON:
+ dumpObjRecRectData();
+ dumpObjRecTextDataBiff3( nTextLen, nFormatSize );
+ dumpObjRecFmla( "macro", nMacroSize );
+ dumpObjRecString( "text", nTextLen, false );
+ dumpObjRecTextFmt( nFormatSize );
+ break;
+ case BIFF_OBJTYPE_PICTURE:
+ dumpObjRecRectData();
+ dumpDec< sal_Int16 >( "image-format", "IMGDATA-FORMAT" );
+ dumpUnused( 4 );
+ nLinkSize = dumpDec< sal_uInt16 >( "pic-link-size" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-PICTURE-FLAGS" );
+ dumpObjRecFmla( "macro", nMacroSize );
+ dumpObjRecPictFmla( nLinkSize );
+ break;
+ case BIFF_OBJTYPE_POLYGON:
+ dumpObjRecRectData();
+ dumpHex< sal_uInt16 >( "flags", "OBJ-POLYGON-FLAGS" );
+ dumpUnused( 10 );
+ dumpDec< sal_uInt16 >( "point-count" );
+ dumpUnused( 8 );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecBiff5()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ 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" );
+ dumpDffClientRect();
+ sal_uInt16 nMacroSize = dumpDec< sal_uInt16 >( "macro-size" );
+ dumpUnused( 2 );
+ sal_uInt16 nNameLen = dumpDec< sal_uInt16 >( "name-len" );
+ dumpUnused( 2 );
+ sal_uInt16 nTextLen = 0, nFormatSize = 0, nLinkSize = 0;
+ switch( nObjType )
+ {
+ case BIFF_OBJTYPE_GROUP:
+ dumpUnused( 4 );
+ dumpDec< sal_uInt16 >( "next-ungrouped-id" );
+ dumpUnused( 16 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_LINE:
+ dumpObjRecLineData();
+ dumpHex< sal_uInt16 >( "line-end", "OBJ-LINEENDS" );
+ dumpDec< sal_uInt8 >( "line-direction", "OBJ-LINEDIR" );
+ dumpUnused( 1 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_RECTANGLE:
+ case BIFF_OBJTYPE_OVAL:
+ dumpObjRecRectData();
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_ARC:
+ dumpObjRecFillData();
+ dumpObjRecLineData();
+ dumpDec< sal_uInt8 >( "quadrant", "OBJ-ARC-QUADRANT" );
+ dumpUnused( 1 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_CHART:
+ dumpObjRecRectData();
+ dumpHex< sal_uInt16 >( "chart-flags", "OBJ-CHART-FLAGS" );
+ dumpUnused( 16 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_TEXT:
+ case BIFF_OBJTYPE_BUTTON:
+ case BIFF_OBJTYPE_LABEL:
+ case BIFF_OBJTYPE_DIALOG:
+ dumpObjRecRectData();
+ dumpObjRecTextDataBiff5( nTextLen, nFormatSize, nLinkSize );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ dumpObjRecString( "text", nTextLen, false );
+ dumpObjRecFmla( "text-link", nLinkSize );
+ dumpObjRecTextFmt( nFormatSize );
+ break;
+ case BIFF_OBJTYPE_PICTURE:
+ dumpObjRecRectData();
+ dumpDec< sal_Int16 >( "image-format", "IMGDATA-FORMAT" );
+ dumpUnused( 4 );
+ nLinkSize = dumpDec< sal_uInt16 >( "pic-link-size" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-PICTURE-FLAGS" );
+ dumpUnused( 4 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ dumpObjRecPictFmla( nLinkSize );
+ if( rStrm.getRemaining() >= 4 )
+ dumpHex< sal_uInt32 >( "ole-storage-id" );
+ break;
+ case BIFF_OBJTYPE_POLYGON:
+ dumpObjRecRectData();
+ dumpHex< sal_uInt16 >( "flags", "OBJ-POLYGON-FLAGS" );
+ dumpUnused( 10 );
+ dumpDec< sal_uInt16 >( "point-count" );
+ dumpUnused( 8 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", nMacroSize );
+ break;
+ case BIFF_OBJTYPE_CHECKBOX:
+ dumpObjRecRectData();
+ dumpUnused( 10 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
+ dumpUnused( 20 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
+ dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
+ dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
+ dumpObjRecCblsData();
+ break;
+ case BIFF_OBJTYPE_OPTIONBUTTON:
+ dumpObjRecRectData();
+ dumpUnused( 10 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
+ dumpUnused( 32 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
+ dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
+ dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
+ dumpObjRecCblsData();
+ dumpObjRecRboData();
+ break;
+ case BIFF_OBJTYPE_EDIT:
+ dumpObjRecRectData();
+ dumpUnused( 10 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
+ dumpUnused( 14 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
+ dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
+ dumpObjRecEdoData();
+ break;
+ case BIFF_OBJTYPE_SPIN:
+ case BIFF_OBJTYPE_SCROLLBAR:
+ dumpObjRecRectData();
+ dumpObjRecSbsData();
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
+ dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
+ break;
+ case BIFF_OBJTYPE_LISTBOX:
+ dumpObjRecRectData();
+ dumpObjRecSbsData();
+ dumpUnused( 18 );
+ dumpFontIdx( "font-idx" );
+ dumpUnused( 4 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
+ dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
+ dumpObjRecLbsData();
+ break;
+ case BIFF_OBJTYPE_GROUPBOX:
+ dumpObjRecRectData();
+ dumpUnused( 10 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
+ dumpUnused( 26 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
+ dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
+ dumpObjRecGboData();
+ break;
+ case BIFF_OBJTYPE_DROPDOWN:
+ dumpObjRecRectData();
+ dumpObjRecSbsData();
+ dumpUnused( 18 );
+ dumpFontIdx( "font-idx" );
+ dumpUnused( 14 );
+ dumpDec< sal_uInt16 >( "bounding-left" );
+ dumpDec< sal_uInt16 >( "bounding-top" );
+ dumpDec< sal_uInt16 >( "bounding-right" );
+ dumpDec< sal_uInt16 >( "bounding-bottom" );
+ dumpUnused( 4 );
+ dumpObjRecString( "obj-name", nNameLen, true );
+ dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
+ dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
+ dumpObjRecLbsData();
+ dumpDec< sal_uInt16 >( "type", "OBJ-DROPDOWN-TYPE" );
+ dumpDec< sal_uInt16 >( "line-count" );
+ dumpDec< sal_uInt16 >( "min-list-width" );
+ dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
+ break;
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecBiff8()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ NameListRef xRecNames = cfg().getNameList( "OBJ-RECNAMES" );
+ sal_uInt16 nObjType = 0xFFFF;
+ bool bControl = false;
+ bool bCtlsStrm = false;
+ bool bLoop = true;
+ while( bLoop && (rStrm.getRemaining() >= 4) )
+ {
+ mxOut->emptyLine();
+ sal_uInt16 nSubRecId, nSubRecSize;
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "OBJREC" );
+ writeHexItem( "pos", static_cast< sal_uInt32 >( rStrm.tell() ) );
+ rStrm >> nSubRecId >> nSubRecSize;
+ writeHexItem( "size", nSubRecSize );
+ writeHexItem( "id", nSubRecId, xRecNames );
+ }
+
+ sal_Int64 nSubRecStart = rStrm.tell();
+ // sometimes the last subrecord has an invalid length
+ sal_Int64 nRealRecSize = ::std::min< sal_Int64 >( nSubRecSize, rStrm.getRemaining() );
+ sal_Int64 nSubRecEnd = nSubRecStart + nRealRecSize;
+
+ IndentGuard aIndGuard( mxOut );
+ switch( nSubRecId )
+ {
+ case BIFF_ID_OBJMACRO:
+ dumpObjRecFmlaRaw();
+ break;
+ case BIFF_ID_OBJCF:
+ dumpDec< sal_Int16 >( "clipboard-format", "IMGDATA-FORMAT" );
+ break;
+ case BIFF_ID_OBJFLAGS:
+ {
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "OBJFLAGS-FLAGS" );
+ bControl = getFlag( nFlags, BIFF_OBJFLAGS_CONTROL );
+ bCtlsStrm = getFlag( nFlags, BIFF_OBJFLAGS_CTLSSTREAM );
+ }
+ break;
+ case BIFF_ID_OBJPICTFMLA:
+ {
+ dumpObjRecPictFmla( dumpDec< sal_uInt16 >( "pic-link-size" ) );
+ if( rStrm.tell() + 4 <= nSubRecEnd )
+ {
+ if( bControl && bCtlsStrm )
+ dumpControl();
+ else
+ dumpHex< sal_uInt32 >( "ole-storage-id" );
+ }
+ if( bControl && (rStrm.tell() + 8 <= nSubRecEnd) )
+ {
+ sal_uInt32 nKeySize = dumpDec< sal_uInt32 >( "licence-key-size" );
+ if( nKeySize > 0 )
+ {
+ IndentGuard aIndGuard2( mxOut );
+ sal_Int64 nKeyEnd = rStrm.tell() + nKeySize;
+ dumpArray( "licence-key", static_cast< sal_Int32 >( nKeySize ) );
+ rStrm.seek( nKeyEnd );
+ }
+ dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
+ dumpObjRecFmla( "source-range", dumpDec< sal_uInt16 >( "source-range-size" ) );
+ }
+ }
+ break;
+ case BIFF_ID_OBJCBLS:
+ dumpDec< sal_uInt16 >( "state", "OBJ-CHECKBOX-STATE" );
+ dumpUnused( 4 );
+ dumpUnicode( "accelerator" );
+ dumpUnicode( "fareast-accelerator" );
+ dumpHex< sal_uInt16 >( "checkbox-flags", "OBJ-CHECKBOX-FLAGS" );
+ break;
+ case BIFF_ID_OBJRBO:
+ dumpUnused( 4 );
+ dumpBool< sal_uInt16 >( "first-in-group" );
+ break;
+ case BIFF_ID_OBJSBS:
+ dumpObjRecSbsData();
+ break;
+ case BIFF_ID_OBJGBODATA:
+ dumpObjRecGboData();
+ break;
+ case BIFF_ID_OBJEDODATA:
+ dumpObjRecEdoData();
+ break;
+ case BIFF_ID_OBJRBODATA:
+ dumpObjRecRboData();
+ break;
+ case BIFF_ID_OBJCBLSDATA:
+ dumpObjRecCblsData();
+ break;
+ case BIFF_ID_OBJLBSDATA:
+ dumpObjRecLbsData();
+ if( nObjType == BIFF_OBJTYPE_DROPDOWN )
+ {
+ dumpHex< sal_uInt16 >( "dropdown-flags", "OBJ-DROPDOWN-FLAGS" );
+ dumpDec< sal_uInt16 >( "line-count" );
+ dumpDec< sal_uInt16 >( "min-list-width" );
+ dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
+ }
+ break;
+ case BIFF_ID_OBJCBLSFMLA:
+ case BIFF_ID_OBJSBSFMLA:
+ dumpObjRecFmlaRaw();
+ break;
+ case BIFF_ID_OBJCMO:
+ nObjType = dumpDec< sal_uInt16 >( "type", "OBJ-TYPE" );
+ dumpDec< sal_uInt16 >( "id" );
+ dumpHex< sal_uInt16 >( "flags", "OBJCMO-FLAGS" );
+ dumpUnused( 12 );
+ break;
+ }
+ // remaining undumped data
+ if( !rStrm.isEof() && (rStrm.tell() == nSubRecStart) )
+ dumpRawBinary( nRealRecSize, false );
+ else
+ dumpRemainingTo( nSubRecEnd );
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecLineData()
+{
+ 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-AUTO-FLAGS" );
+}
+
+void WorkbookStreamObject::dumpObjRecFillData()
+{
+ dumpColorIdx( "back-color-idx", false );
+ dumpColorIdx( "patt-color-idx", false );
+ dumpPatternIdx( EMPTY_STRING, false );
+ dumpHex< sal_uInt8 >( "area-flags", "OBJ-AUTO-FLAGS" );
+}
+
+void WorkbookStreamObject::dumpObjRecRectData()
+{
+ dumpObjRecFillData();
+ dumpObjRecLineData();
+ dumpHex< sal_uInt16 >( "frame-style", "OBJ-FRAMESTYLE-FLAGS" );
+}
+
+void WorkbookStreamObject::dumpObjRecTextDataBiff3( sal_uInt16& ornTextLen, sal_uInt16& ornFormatSize )
+{
+ ornTextLen = dumpDec< sal_uInt16 >( "text-len" );
+ dumpUnused( 2 );
+ ornFormatSize = dumpDec< sal_uInt16 >( "format-run-size" );
+ dumpFontIdx( "default-font-idx" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
+ dumpDec< sal_uInt16 >( "orientation", "TEXTORIENTATION" );
+ dumpUnused( 8 );
+}
+
+void WorkbookStreamObject::dumpObjRecTextDataBiff5( sal_uInt16& ornTextLen, sal_uInt16& ornFormatSize, sal_uInt16& ornLinkSize )
+{
+ ornTextLen = dumpDec< sal_uInt16 >( "text-len" );
+ dumpUnused( 2 );
+ ornFormatSize = dumpDec< sal_uInt16 >( "format-run-size" );
+ dumpFontIdx( "default-font-idx" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
+ dumpDec< sal_uInt16 >( "orientation", "TEXTORIENTATION" );
+ dumpUnused( 2 );
+ ornLinkSize = dumpDec< sal_uInt16 >( "link-size" );
+ dumpUnused( 2 );
+ dumpHex< sal_uInt16 >( "button-flags", "OBJ-BUTTON-FLAGS" );
+ dumpUnicode( "accelerator" );
+ dumpUnicode( "fareast-accelerator" );
+}
+
+void WorkbookStreamObject::dumpObjRecSbsData()
+{
+ dumpUnused( 4 );
+ dumpDec< sal_uInt16 >( "value" );
+ dumpDec< sal_uInt16 >( "min" );
+ dumpDec< sal_uInt16 >( "max" );
+ dumpDec< sal_uInt16 >( "step" );
+ dumpDec< sal_uInt16 >( "page-step" );
+ dumpBool< sal_uInt16 >( "horizontal" );
+ dumpDec< sal_uInt16 >( "thumb-width" );
+ dumpHex< sal_uInt16 >( "scrollbar-flags", "OBJ-SCROLLBAR-FLAGS" );
+}
+
+void WorkbookStreamObject::dumpObjRecGboData()
+{
+ dumpUnicode( "accelerator" );
+ dumpUnicode( "fareast-accelerator" );
+ dumpHex< sal_uInt16 >( "groupbox-flags", "OBJ-GROUPBOX-FLAGS" );
+}
+
+void WorkbookStreamObject::dumpObjRecEdoData()
+{
+ dumpDec< sal_uInt16 >( "type", "OBJ-EDIT-TYPE" );
+ dumpBool< sal_uInt16 >( "multiline" );
+ dumpBool< sal_uInt16 >( "scrollbar" );
+ dumpDec< sal_uInt16 >( "listbox-obj-id" );
+}
+
+void WorkbookStreamObject::dumpObjRecRboData()
+{
+ dumpDec< sal_uInt16 >( "next-in-group" );
+ dumpBool< sal_uInt16 >( "first-in-group" );
+}
+
+void WorkbookStreamObject::dumpObjRecCblsData()
+{
+ dumpDec< sal_uInt16 >( "state", "OBJ-CHECKBOX-STATE" );
+ dumpUnicode( "accelerator" );
+ dumpUnicode( "fareast-accelerator" );
+ dumpHex< sal_uInt16 >( "checkbox-flags", "OBJ-CHECKBOX-FLAGS" );
+}
+
+void WorkbookStreamObject::dumpObjRecLbsData()
+{
+ dumpObjRecFmla( "source-range", dumpDec< sal_uInt16 >( "source-range-size" ) );
+ dumpDec< sal_uInt16 >( "entry-count" );
+ dumpDec< sal_uInt16 >( "selected-entry" );
+ dumpHex< sal_uInt16 >( "listbox-flags", "OBJ-LISTBOX-FLAGS" );
+ dumpDec< sal_uInt16 >( "edit-obj-id" );
+}
+
+void WorkbookStreamObject::dumpObjRecPadding()
+{
+ if( getBiffStream().tell() & 1 )
+ {
+ IndentGuard aIndGuard( mxOut );
+ dumpHex< sal_uInt8 >( "padding" );
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecString( const String& rName, sal_uInt16 nTextLen, bool bRepeatLen )
+{
+ if( nTextLen > 0 )
+ {
+ if( bRepeatLen )
+ dumpByteString( rName, BIFF_STR_8BITLENGTH );
+ else
+ writeStringItem( rName, getBiffStream().readCharArrayUC( nTextLen, getBiffData().getTextEncoding() ) );
+ dumpObjRecPadding();
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecTextFmt( sal_uInt16 nFormatSize )
+{
+ FontPortionModelList aPortions;
+ aPortions.importPortions( getBiffStream(), nFormatSize / 8, BIFF_FONTPORTION_OBJ );
+ writeFontPortions( aPortions );
+}
+
+void WorkbookStreamObject::dumpObjRecFmlaRaw()
+{
+ sal_uInt16 nFmlaSize = dumpDec< sal_uInt16 >( "fmla-size" );
+ dumpUnused( 4 );
+ getFormulaDumper().dumpNameFormula( "fmla", nFmlaSize );
+ dumpObjRecPadding();
+}
+
+void WorkbookStreamObject::dumpObjRecFmla( const String& rName, sal_uInt16 nFmlaSize )
+{
+ BiffInputStream& rStrm = getBiffStream();
+ if( nFmlaSize > 0 )
+ {
+ writeEmptyItem( rName );
+ IndentGuard aIndGuard( mxOut );
+ sal_Int64 nStrmEnd = rStrm.tell() + nFmlaSize;
+ dumpObjRecFmlaRaw();
+ if( rStrm.isEof() || (rStrm.tell() != nStrmEnd) )
+ writeEmptyItem( OOX_DUMP_ERRASCII( "fmla-size" ) );
+ dumpRemainingTo( nStrmEnd );
+ }
+}
+
+void WorkbookStreamObject::dumpObjRecPictFmla( sal_uInt16 nFmlaSize )
+{
+ BiffInputStream& rStrm = getBiffStream();
+ if( nFmlaSize > 0 )
+ {
+ writeEmptyItem( "pic-link" );
+ IndentGuard aIndGuard( mxOut );
+ sal_Int64 nStrmEnd = rStrm.tell() + nFmlaSize;
+ if( (getBiff() == BIFF3) && (nStrmEnd & 1) ) ++nStrmEnd; // BIFF3 size without padding
+ dumpObjRecFmlaRaw();
+ if( rStrm.tell() + 2 <= nStrmEnd )
+ {
+ dumpString( "class-name", BIFF_STR_DEFAULT, BIFF_STR_SMARTFLAGS );
+ dumpObjRecPadding();
+ }
+ if( rStrm.isEof() || (rStrm.tell() != nStrmEnd) )
+ writeEmptyItem( OOX_DUMP_ERRASCII( "pic-link-size" ) );
+ dumpRemainingTo( nStrmEnd );
+ }
+}
+
+void WorkbookStreamObject::dumpChFrExtProps()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ bool bValid = true;
+ while( bValid && (rStrm.getRemaining() > 4) )
+ {
+ ChFrExtPropInfo aInfo = dumpChFrExtPropHeader();
+ IndentGuard aIndGuard( mxOut );
+ switch( aInfo.first )
+ {
+ case 0: // start
+ case 1: // end
+ break;
+ case 2: // bool
+ dumpBoolean( "value" );
+ dumpUnused( 1 );
+ break;
+ case 3: // double
+ dumpUnused( 4 );
+ dumpDec< double >( "value", aInfo.second );
+ break;
+ case 4: // int32
+ dumpDec< sal_Int32 >( "value", aInfo.second );
+ break;
+ case 5: // string
+ dumpUnicodeArray( "value", rStrm.readInt32() );
+ break;
+ case 6: // uint16
+ dumpDec< sal_uInt16 >( "value", aInfo.second );
+ break;
+ case 7: // blob
+ dumpBinary( "value", rStrm.readuInt32() );
+ break;
+ default:
+ bValid = false;
+ }
+ }
+}
+
+WorkbookStreamObject::ChFrExtPropInfo WorkbookStreamObject::dumpChFrExtPropHeader()
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ ChFrExtPropInfo aInfo;
+ aInfo.first = dumpDec< sal_uInt8 >( "datatype", "CHFREXTPROPS-TYPE" );
+ dumpUnused( 1 );
+ sal_uInt16 nTag = dumpDec< sal_uInt16 >( "tag", "CHFREXTPROPS-TAG" );
+ aInfo.second = cfg().getName( "CHFREXTPROPS-TAG-NAMELIST", nTag );
+ return aInfo;
+}
+
+// ============================================================================
+
+PivotCacheStreamObject::PivotCacheStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, BiffType eBiff, const ::rtl::OUString& rSysFileName )
+{
+ RecordStreamObject::construct( rParent, rxStrm, eBiff, rSysFileName );
+}
+
+void PivotCacheStreamObject::implDumpRecordBody()
+{
+ BiffInputStream& rStrm = getBiffStream();
+ sal_uInt16 nRecId = rStrm.getRecId();
+
+ switch( nRecId )
+ {
+ case BIFF_ID_PCDEFINITION:
+ dumpDec< sal_Int32 >( "source-records" );
+ dumpHex< sal_uInt16 >( "cache-id" );
+ dumpHex< sal_uInt16 >( "flags", "PCDEFINITION-FLAGS" );
+ dumpUnused( 2 );
+ dumpDec< sal_uInt16 >( "sourcedata-field-count" );
+ dumpDec< sal_uInt16 >( "cache-field-count" );
+ dumpDec< sal_uInt16 >( "report-record-count" );
+ dumpDec< sal_uInt16 >( "database-type", "PCDSOURCE-TYPE" );
+ dumpString( "user-name" );
+ break;
+
+ case BIFF_ID_PCDEFINITION2:
+ dumpDec< double >( "refreshed-date" );
+ dumpDec< sal_Int32 >( "formula-count" );
+ break;
+
+ case BIFF_ID_PCDFDISCRETEPR:
+ mxOut->resetItemIndex();
+ while( !rStrm.isEof() && (rStrm.getRemaining() >= 2) )
+ dumpDec< sal_uInt16 >( "#item-index" );
+ break;
+
+ case BIFF_ID_PCDFIELD:
+ dumpHex< sal_uInt16 >( "flags", "PCDFIELD-FLAGS" );
+ dumpDec< sal_uInt16 >( "group-parent-field" );
+ dumpDec< sal_uInt16 >( "group-base-field" );
+ dumpDec< sal_uInt16 >( "unique-items" );
+ dumpDec< sal_uInt16 >( "group-items" );
+ dumpDec< sal_uInt16 >( "base-items" );
+ dumpDec< sal_uInt16 >( "shared-items" );
+ if( rStrm.getRemaining() >= 3 )
+ dumpString( "item-name" );
+ break;
+
+ case BIFF_ID_PCITEM_DATE:
+ {
+ DateTime aDateTime;
+ aDateTime.Year = mxStrm->readuInt16();
+ aDateTime.Month = mxStrm->readuInt16();
+ aDateTime.Day = mxStrm->readuInt8();
+ aDateTime.Hours = mxStrm->readuInt8();
+ aDateTime.Minutes = mxStrm->readuInt8();
+ aDateTime.Seconds = mxStrm->readuInt8();
+ writeDateTimeItem( "value", aDateTime );
+ }
+ break;
+
+ case BIFF_ID_PCITEM_STRING:
+ dumpString( "value" );
+ break;
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+RootStorageObject::RootStorageObject( const DumperBase& rParent )
+{
+ OleStorageObject::construct( rParent );
+ addPreferredStream( "Book" );
+ addPreferredStream( "Workbook" );
+}
+
+void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( (rStrgPath.getLength() == 0) && (rStrmName.equalsAscii( "Book" ) || rStrmName.equalsAscii( "Workbook" )) )
+ WorkbookStreamObject( *this, rxStrm, rSysFileName ).dump();
+ else if( rStrgPath.equalsAscii( "_SX_DB" ) )
+ PivotCacheStreamObject( *this, rxStrm, BIFF5, rSysFileName ).dump();
+ else if( rStrgPath.equalsAscii( "_SX_DB_CUR" ) )
+ PivotCacheStreamObject( *this, rxStrm, BIFF8, rSysFileName ).dump();
+ else
+ OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+void RootStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ if( rStrgPath.equalsAscii( "_VBA_PROJECT_CUR" ) )
+ VbaProjectStorageObject( *this, rxStrg, rSysPath ).dump();
+ else if( rStrgPath.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "MBD" ) ) )
+ VbaContainerStorageObject( *this, rxStrg, rSysPath ).dump();
+ else
+ OleStorageObject::implDumpStorage( rxStrg, rStrgPath, rSysPath );
+}
+
+void RootStorageObject::implDumpBaseStream( const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ WorkbookStreamObject( *this, rxStrm, rSysFileName ).dump();
+}
+
+// ============================================================================
+// ============================================================================
+
+#define DUMP_BIFF_CONFIG_ENVVAR "OOO_BIFFDUMPER"
+
+Dumper::Dumper( const FilterBase& rFilter )
+{
+ ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rFilter ) );
+ DumperBase::construct( xCfg );
+}
+
+Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
+{
+ if( rxFactory.is() && rxInStrm.is() )
+ {
+ StorageRef xStrg( new ::oox::ole::OleStorage( rxFactory, rxInStrm, true ) );
+ MediaDescriptor aMediaDesc;
+ ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
+ DumperBase::construct( xCfg );
+ }
+}
+
+void Dumper::implDump()
+{
+ RootStorageObject( *this ).dump();
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace biff
+} // namespace dump
+} // namespace oox
+
+#endif
diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini
new file mode 100644
index 000000000000..2e25ff81c890
--- /dev/null
+++ b/oox/source/dump/biffdumper.ini
@@ -0,0 +1,2378 @@
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+include-config-file=dffdumper.ini
+include-config-file=oledumper.ini
+
+# Enable entire dumper. This option does not affect the option 'enable-import'.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-dumper=1
+
+# Enable import after dumping. Disabling this option allows to dump a file
+# without loading it. This option is independent from the 'enable-dumper'
+# option.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-import=1
+
+# BIFF record settings -------------------------------------------------------
+
+# 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 lists =================================================================
+
+# common ---------------------------------------------------------------------
+
+unitconverter=CONV-PERCENT-NEG,-1,%
+unitconverter=CONV-COLWIDTH,/256,chars
+unitconverter=CONV-TINT,/327.67,%
+
+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=WINDOWS-PALETTE-0,0,black,white,red,green,blue,yellow,magenta,cyan
+shortlist=WINDOWS-PALETTE-8,8,black,white,red,green,blue,yellow,magenta,cyan
+shortlist=WINDOWS-PALETTE-16,16,dark-red,dark-green,dark-blue,dark-yellow,dark-magenta,dark-cyan,light-grey,dark-grey
+
+multilist=WINDOWS-SYSCOLORS-BIFF2
+ 24=sys-window-text,sys-window-bg
+ 0x7FFF=sys-window-text
+end
+
+multilist=WINDOWS-SYSCOLORS-BIFF5
+ 64=sys-window-text,sys-window-bg,,sys-button-face
+ 77=sys-window-text-chart,sys-window-bg-chart,auto-border-chart,sys-tooltip-bg,sys-tooltip-text
+ 0x7FFF=sys-window-text
+end
+
+constlist=COLORS-BIFF2
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-SYSCOLORS-BIFF2
+end
+
+constlist=COLORS-BIFF3
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-PALETTE-8
+ include=WINDOWS-PALETTE-16
+ include=WINDOWS-SYSCOLORS-BIFF2
+end
+
+multilist=COLORS-BIFF5
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-PALETTE-8
+ include=WINDOWS-PALETTE-16
+ 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
+ include=WINDOWS-SYSCOLORS-BIFF5
+end
+
+multilist=COLORS-BIFF8
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-PALETTE-8
+ include=WINDOWS-PALETTE-16
+ 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
+ include=WINDOWS-SYSCOLORS-BIFF5
+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
+
+constlist=PIVOT-NAMELEN
+ default=
+ 0xFFFF=name-in-cache
+end
+
+flagslist=FR-FLAGS
+ 0x0001=has-ref
+ 0x0002=alert-unsupported
+end
+
+shortlist=EXTCOLOR-TYPE,0,auto,indexed,rgb,theme,n/a
+
+combilist=EXTCOLOR-FLAGS
+ 0x01=rgb-valid
+ 0xFE=uint8,dec,type,EXTCOLOR-TYPE
+end
+
+shortlist=EXTGRADIENT-TYPE,0,linear,path
+
+shortlist=EXTFONT-SCHEME,-1,n/a,none,major,minor
+
+# DFF ------------------------------------------------------------------------
+
+flagslist=DFF-CLIENTANCHOR-FLAGS
+ 0x0001=pos-locked
+ 0x0002=size-locked
+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
+ 0x00=skip
+ 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,,
+ 0x0208=,,,INDEX,,,,
+ 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,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,,IMGDATA
+ 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,,,,,,
+ 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,,AUTOFILTER,FILTERCOLUMN,
+ 0x00A8=,,,,,,SCENARIOS,SCENARIO
+ 0x00B0=PTDEFINITION,PTFIELD,PTFITEM,,PTROWCOLFIELDS,PTROWCOLITEMS,PTPAGEFIELDS,
+ 0x00B8=DOCROUTE,RECIPNAME,,,,MULTRK,MULTBLANK,TOOLBARHDR
+ 0x00C0=TOOLBAREND,MMS,ADDMENU,DELMENU,,PTDATAFIELD,PCDEFINITION,PCDFIELD
+ 0x00C8=PCITEM_INDEXLIST,PCITEM_DOUBLE,PCITEM_BOOL,PCITEM_ERROR,PCITEM_INTEGER,PCITEM_STRING,PCITEM_DATE,PCITEM_MISSING
+ 0x00D0=SXTBL,SXTBRGITEM,SXTBPG,VBAPROJECT,,PIVOTCACHE,RSTRING,DBCELL
+ 0x00D8=PCDFRANGEPR,PCDFDISCRETEPR,BOOKBOOL,REVERT,DBORPARAMQUERY,SCENPROTECT,OLESIZE,UDDESC
+ 0x00E0=XF,INTERFACEHDR,INTERFACEEND,PCDSOURCE,,,,
+ 0x0206=FORMULA
+ 0x04BC=SHAREDFMLA
+ # chart records
+ exclude=0x1004,0x102D,0x102F,0x1036,0x1037,0x1038,0x103B
+ 0x1040=CHRADARAREA,CHAXESSET,,CHLEGENDENTRY,CHPROPERTIES,CHSERGROUP,CHUSEDAXESSETS,
+ 0x1048=CHPIVOTREF,,CHSERPARENT,CHSERTRENDLINE,,,CHFORMAT,CHFRAMEPOS
+ 0x1050=CHFORMATRUNS,CHSOURCELINK,,,,,,
+ 0x1058=,,,CHSERERRORBAR,,CHSERIESFORMAT,,
+end
+
+multilist=RECORD-NAMES-BIFF8
+ include=RECORD-NAMES-BIFF5
+ # worksheet/workbook records
+ 0x00E0=,,,,,CELLMERGING,,
+ 0x00E8=,IMGDATA,,MSODRAWINGGROUP,MSODRAWING,MSODRAWINGSELECTION,,PHONETICPR
+ 0x00F0=,PTDEFINITION2,,,,,,
+ 0x00F8=,PCDFORMULAFIELD,,,SST,LABELSST,,EXTSST
+ 0x0100=PTFIELD2,,,PCDFIELDINDEX,,,,
+ 0x0120=,,PCDEFINITION2,,,,,
+ 0x0130=,,,,,,,CHTRINSERT
+ 0x0138=CHTRINFO,,,CHTRCELLCONTENT,,TABID,,
+ 0x0140=CHTRMOVERANGE,,,,,,,
+ 0x0148=,,,,,CHTRINSERTTAB,,
+ 0x0158=,,,,,,,LABELRANGES
+ 0x0160=USESELFS,DSF,XL5MODIFY,,,,,
+ 0x0190=,,,,,,CHTRHEADER,
+ 0x01A8=,USERBVIEW,USERSVIEWBEGIN,USERSVIEWEND,,QUERYTABLE,EXTERNALBOOK,PROT4REV
+ 0x01B0=CFHEADER,CFRULE,DATAVALIDATIONS,,,DCONBINAME,TXO,REFRESHALL
+ 0x01B8=HYPERLINK,NLRDELNAME,CODENAME,PCDFSQLTYPE,PROT4REVPASS,VBAPROJECTEMPTY,DATAVALIDATION,
+ 0x01C0=XL9FILE,RECALCID,INTCACHEDDATA,,,,,
+ # future records
+ 0x0800=SCREENTIP,,QUERYTABLEREFRESH,QUERYTABLESETTINGS,QUERYTABLESTRING,,,
+ 0x0850=CHFRINFO,CHFRWRAPPER,CHFRBLOCKBEGIN,CHFRBLOCKEND,,,CHFRCATEGORYPROPS,CHFRUNITPROPS
+ 0x0858=CHPIVOTREF,CHPIVOTFLAGS,,,,,,
+ 0x0860=,,SHEETEXT,BOOKEXT,,,,SHAREDFEATHEAD
+ 0x0868=,,,CHFRLABELPROPS,,,,
+ 0x0870=,,,,,,CONNECTION,
+ 0x0878=,,CFRULE12,CFRULEEXT,XFCRC,XFEXT,FILTERCOLUMN12,CONTINUE12
+ 0x0888=,,,PAGELAYOUTVIEW,CHECKCOMPAT,DXF,TABLESTYLES,
+ 0x0890=,,STYLEEXT,,,,THEME,
+ 0x0898=,,MTHREADSETTINGS,COMPRESSPICS,HEADERFOOTER,CHFRLAYOUT,CHFREXTPROPS,CHFREXTPROPSCONT
+ 0x08A0=,,,FORCEFULLCALC,CHFRSHAPEPROPS,CHFRTEXTPROPS,,CHFRPLOTAREALAYOUT
+ # chart records
+ 0x1058=,,,,,,,CH3DDATAFORMAT
+ 0x1060=CHFONTBASE,CHPIEEXT,CHDATERANGE,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,contents-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
+ 0x009D=uint16,dec,column-count
+ 0x00C9=double,dec,value
+ 0x00CA=uint16,bool,value
+ 0x00CB=uint16,hex,error-code,ERRORCODES
+ 0x00CC=int16,dec,value
+ 0x00D5=uint16,hex,cache-id
+ 0x00D8=uint16,hex,flags,PCDFRANGEPR-FLAGS
+ 0x00DA=uint16,bool,strip-cached-values
+ 0x00DD=uint16,bool,scenarios-protected
+ 0x00E3=uint16,dec,source-type,PCDSOURCE-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,PCDFSQLTYPE-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
+
+shortlist=BOF-EXCELVERSION,0,excel-97,excel-2000,excel-2002,excel-2003,excel-2007,,excel-2010
+shortlist=BOF-LOWESTVERSION-BIFF,6,biff8
+
+combilist=BOF-HISTORY-FLAGS
+ ignore=0x000000C0
+ 0x00000001=windows
+ 0x00000002=risc
+ 0x00000004=beta
+ 0x00000008=win-any
+ 0x00000010=mac-any
+ 0x00000020=beta-any
+ 0x00000100=risc-any
+ 0x00000200=out-of-mem
+ 0x00000400=out-of-mem-renderer
+ 0x00002000=font-limit-255
+ 0x0003C000=uint8,dec,max-version-saved,BOF-EXCELVERSION
+end
+
+combilist=BOF-LOWESTVERSION-FLAGS
+ 0x000000FF=uint8,dec,biff-version,BOF-LOWESTVERSION-BIFF
+ 0x00000F00=uint8,dec,version-saved,BOF-EXCELVERSION
+end
+
+# BOOKEXT --------------------------------------------------------------------
+
+combilist=BOOKEXT-FLAGS1
+ 0x00000001=no-auto-recover
+ 0x00000002=hide-pivot-list
+ 0x00000004=filter-privacy
+ 0x00000008=embed-smarttags
+ 0x00000030=uint8,dec,display-smarttags,BOOKEXT-DISPLAY-SMARTTAGS
+ 0x00000040=saved-on-recovery
+ 0x00000080=minimal-save
+ 0x00000100=opened-on-recovery
+ 0x00000200=opened-in-save-mode
+end
+
+shortlist=BOOKEXT-DISPLAY-SMARTTAGS,0,button-and-indicator,button,nothing
+
+flagslist=BOOKEXT-FLAGS2
+ 0x01=warn-smart-doc-manifest
+ 0x02=show-inc-annotations
+end
+
+flagslist=BOOKEXT-FLAGS3
+ 0x02=!all-published!selected-items-published
+ 0x04=show-pivot-chart-filter
+end
+
+# CALCMODE -------------------------------------------------------------------
+
+shortlist=CALCMODE,-1,automatic-no-table,manual,automatic
+
+# CFHEADER -------------------------------------------------------------------
+
+combilist=CFHEADER-FLAGS
+ 0x0001=complex
+ 0xFFFE=uint16,dec,id
+end
+
+# 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-FLAGS1
+ ignore=0x00200000
+ 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
+ 0x00000080=!cell-merged-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
+ 0x00080000=!fmt-idx-used
+ 0x00100000=!def-font-used
+ 0x02000000=numfmt-block
+ 0x04000000=font-block
+ 0x08000000=alignment-block
+ 0x10000000=border-block
+ 0x20000000=pattern-block
+ 0x40000000=protection-block
+ 0x80000000=!text-dir-used
+end
+
+flagslist=CFRULE-FLAGS2
+ ignore=0x0002
+ 0x0001=!numfmt-id!numfmt-string
+ 0x0004=outline-border
+ 0x8000=use-text-dir
+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
+ 0x0020=cell-merged
+ 0x00C0=uint8,dec,text-dir,XF-TEXTDIRECTION
+end
+
+flagslist=CFRULE-FONTFLAGS
+ 0x00000002=italic
+ 0x00000008=outline
+ 0x00000010=shadow
+ 0x00000020=condense
+ 0x00000040=extend
+ 0x00000080=strikeout
+end
+
+constlist=CFRULE-FONTWEIGHT
+ include=FONT-WEIGHT
+ -1=unused
+end
+
+constlist=CFRULE-FONTESCAPEMENT
+ include=FONT-ESCAPEMENT
+ -1=unused
+end
+
+constlist=CFRULE-FONTUNDERLINE
+ include=FONT-UNDERLINE
+ -1=unused
+end
+
+constlist=CFRULE-FONTCOLOR
+ include=COLORS-BIFF8
+ -1=unused
+end
+
+flagslist=CFRULE-FONTUSEDFLAGS
+ ignore=0xFFFFFF00
+ 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
+
+# CFRULE12 -------------------------------------------------------------------
+
+shortlist=CFRULE12-TYPE,1,cell-is,expression,color-scale,data-bar,top-ten,icon-set
+
+flagslist=CFRULE12-FLAGS
+ 0x0002=stop-if-true
+end
+
+multilist=CFRULE12-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
+
+flagslist=CFRULE12-TOP10-FLAGS
+ 0x01=!bottom!top
+ 0x02=percent
+end
+
+shortlist=CFRULE12-TEXT-OPERATOR,0,contains,not-contains,begins-with,ends-with
+shortlist=CFRULE12-DATE-OPERATOR,0,today,yesterday,last-7-days,this-week,last-week,last-month,tomorrow,next-week,next-month,this-month
+
+# CFRULEEXT ------------------------------------------------------------------
+
+flagslist=CFRULEEXT-FLAGS
+ 0x0001=active
+ 0x0002=stop-if-true
+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
+
+# CHDATERANGE ----------------------------------------------------------------
+
+shortlist=CHDATERANGE-UNIT,0,days,months,years
+
+flagslist=CHDATERANGE-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
+
+# CHFRAME --------------------------------------------------------------------
+
+shortlist=CHFRAME-FORMAT,0,standard,,,,shadow
+
+flagslist=CHFRAME-FLAGS
+ 0x0001=auto-size
+ 0x0002=auto-pos
+end
+
+# CHFRAMEPOS -----------------------------------------------------------------
+
+shortlist=CHFRAMEPOS-POSMODE,0,rel-points,abssize-points,parent-dependent,offset-plotarea-size,,chartsize
+
+# CHFRBLOCKBEGIN, CHFRBLOCKEND -----------------------------------------------
+
+shortlist=CHFRBLOCK-TYPE,0,axes-set,,text,,axis,type-group,data-table,frame,,legend,legend-exception,,series,chart,data-format,drop-bar
+
+# CHFRCATEGORYPROPS ----------------------------------------------------------
+
+shortlist=CHFRCATEGORYPROPS-ALIGN,1,top-left,center,bottom-right
+
+flagslist=CHFRCATEGORYPROPS-FLAGS
+ ignore=0xFFFE
+ 0x0001=auto-label-frequency
+end
+
+# CHFREXTPROPS ---------------------------------------------------------------
+
+constlist=CHFREXTPROPS-PARENT
+ 0x0001=log-scaling
+ 0x0002=style
+ 0x0004=category-scaling
+ 0x0005=chart-props
+ 0x000F=legend
+ 0x0013=marker
+ 0x0016=plot-area
+ 0x0019=chart-title
+ 0x0037=3d-props
+end
+
+constlist=CHFREXTPROPS-TYPE
+ 0=start
+ 1=end
+ 2=bool
+ 3=double
+ 4=int32
+ 5=string
+ 6=uint16
+ 7=blob
+end
+
+constlist=CHFREXTPROPS-TAG
+ 0x0000=log-base
+ 0x0003=style
+ 0x001E=chart-formatting
+ 0x0020=text-formatting
+ 0x0022=symbol-type
+ 0x002E=no-multi-level
+ 0x002F=overlay
+ 0x0033=theme-override
+ 0x0034=color-mapping-override
+ 0x0035=backwall-thickness
+ 0x0036=floor-thickness
+ 0x004D=perspective
+ 0x004E=rotation-x
+ 0x004F=rotation-y
+ 0x0050=right-angled-axes-off
+ 0x0052=tick-mark-skip
+ 0x0051=tick-label-skip
+ 0x0053=major-unit
+ 0x0054=minor-unit
+ 0x0055=max
+ 0x0056=min
+ 0x0059=side-wall
+ 0x005B=show-data-labels-over-max
+ 0x005C=tick-label-pos
+ 0x005E=pie-combination
+ 0x005F=basetime-unit
+ 0x0064=format-code
+ 0x0065=height-percent
+ 0x0066=display-blanks-as
+ 0x006A=major-unit-type
+ 0x006B=minor-unit-type
+ 0x0076=edit-language
+end
+
+constlist=CHFREXTPROPS-TAG-NAMELIST
+ default=
+ 0x0022=CHFREXTPROPS-SYMBOLTYPE
+ 0x0035=CONV-PERCENT
+ 0x0036=CONV-PERCENT
+ 0x004E=CONV-DEG
+ 0x004F=CONV-DEG
+ 0x005C=CHFREXTPROPS-TICKLABELPOS
+ 0x005F=CHFREXTPROPS-TIMEUNIT
+ 0x0065=CONV-PERCENT
+ 0x0066=CHFREXTPROPS-DISPBLANKSAS
+ 0x006A=CHFREXTPROPS-TIMEUNIT
+ 0x006B=CHFREXTPROPS-TIMEUNIT
+end
+
+shortlist=CHFREXTPROPS-DISPBLANKSAS,0x0067,gap,,spanned
+shortlist=CHFREXTPROPS-SYMBOLTYPE,0x0023,none,diamond,square,triangle,x,star,dot,dash,circle,plus
+shortlist=CHFREXTPROPS-TICKLABELPOS,0x005D,center
+shortlist=CHFREXTPROPS-TIMEUNIT,0x0060,days,months,years
+
+# CHFRINFO -------------------------------------------------------------------
+
+shortlist=CHFRINFO-APPVERSION,9,excel-2000,excel-xp-2003,,excel-2007
+
+# CHFRLABELPROPS -------------------------------------------------------------
+
+flagslist=CHFRLABELPROPS-FLAGS
+ 0x0001=show-series
+ 0x0002=show-categ
+ 0x0004=show-value
+ 0x0008=show-percent
+ 0x0010=show-bubble
+end
+
+# CHFRLAYOUT -----------------------------------------------------------------
+
+combilist=CHFRLAYOUT-FLAGS
+ 0x001E=uint8,dec,legend-pos,CHFRLAYOUT-LEGENDPOS
+end
+
+shortlist=CHFRLAYOUT-LEGENDPOS,0,bottom,top-right,top,right,left
+
+shortlist=CHFRLAYOUT-MODE,0,auto,factor,egde
+
+# CHFRPLOTAREALAYOUT ---------------------------------------------------------
+
+flagslist=CHFRPLOTAREALAYOUT-FLAGS
+ 0x0001=!outer!inner
+end
+
+shortlist=CHFRLAYOUT-LEGENDPOS,0,bottom,top-right,top,right,left
+
+shortlist=CHFRLAYOUT-MODE,0,auto,factor,egde
+
+# CHFRUNITPROPS --------------------------------------------------------------
+
+shortlist=CHFRUNITPROPS-PRESET,-1,manual,none,hundred,thousand,10000,100000,million,10-million,100-million,billion,trillion
+
+flagslist=CHFRUNITPROPS-FLAGS
+ 0x0002=show-unit
+end
+
+# CHLABELRANGE ---------------------------------------------------------------
+
+flagslist=CHLABELRANGE-FLAGS
+ 0x0001=cross-between-categ
+ 0x0002=maximum-axis-cross
+ 0x0004=reverse-order
+end
+
+# CHLEGEND -------------------------------------------------------------------
+
+shortlist=CHLEGEND-DOCKPOS,0,bottom,top-right,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
+ 0x0008=system-color
+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
+
+# CHPIVOTFLAGS ---------------------------------------------------------------
+
+flagslist=CHPIVOTFLAGS-FLAGS
+ 0x0001=hide-field-captions
+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-series
+ 0x0002=plot-visible-only
+ 0x0004=fixed-size
+ 0x0008=manual-plotarea
+ 0x0010=apply-plotarea-pos
+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
+
+flagslist=CHTEXT-FLAGS1-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-FLAGS1-BIFF3
+ include=CHTEXT-FLAGS1-BIFF2
+ 0x0700=uint8,dec,orientation,TEXTORIENTATION
+end
+
+combilist=CHTEXT-FLAGS1-BIFF5
+ include=CHTEXT-FLAGS1-BIFF3
+ 0x0800=show-categ-percent
+ 0x1000=show-percent
+end
+
+combilist=CHTEXT-FLAGS1-BIFF8
+ include=CHTEXT-FLAGS1-BIFF5
+ 0x2000=show-bubble-size
+ 0x4000=show-categ
+end
+
+combilist=CHTEXT-FLAGS2
+ ignore=0x3FF0
+ 0x000F=uint8,dec,placement,CHTEXT-PLACEMENT
+ 0xC000=uint8,dec,text-dir,XF-TEXTDIRECTION
+end
+
+shortlist=CHTEXT-PLACEMENT,0,context,outside,inside,center,axis,above,below,left,right,auto,manual
+
+# 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
+
+# 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
+ 0x0008=show-phonetic
+ 0x0700=uint8,dec,outline-level
+ 0x1000=outline-collapsed
+end
+
+# CONNECTION -----------------------------------------------------------------
+
+shortlist=CONNECTION-SOURCETYPE,1,odbc,dao,file,html,ole-db,text,ado,dsp
+
+flagslist=CONNECTION-FLAGS
+ 0x0001=save-password
+ 0x0002=html-tables
+ 0x0004=table-names
+ 0x0008=deleted
+ 0x0010=stand-alone
+ 0x0020=only-use-conn-file
+ 0x0040=background
+ 0x0080=refresh-on-load
+ 0x0100=save-data
+end
+
+shortlist=CONNECTION-RECONNECTTYPE,0,as-required,always,never
+shortlist=CONNECTION-CREDENTIALS,0,integrated,none,stored-sso,prompt
+shortlist=CONNECTION-LINKEDOBJECTTYPE,0,none,query-table,pivot-cache
+
+# 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
+
+# DBQUERY --------------------------------------------------------------------
+
+combilist=DBQUERY-FLAGS
+ 0x0007=uint8,dec,source-type,CONNECTION-SOURCETYPE
+ 0x0008=odbc-connection
+ 0x0010=sql-query
+ 0x0020=server-sql
+ 0x0040=html-query
+ 0x0080=save-password
+ 0x0100=html-tables
+end
+
+# 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
+
+shortlist=DEFINEDNAME-BUILTINID,0,consolidate-area,auto-open,auto-close,extract,database,criteria,print-area,print-titles,recorder,data-form,auto-activate,auto-deactivate,sheet-title,filterdatabase
+
+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
+
+# DXF ------------------------------------------------------------------------
+
+flagslist=DXF-FLAGS
+ 0x0001=!swap-fg-bg-color
+ 0x0002=use-internal-borders
+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,ALIGN-MERGED,FONT-NAME
+ 25=FONT-WEIGHT,FONT-UNDERLINE,FONT-ESCAPEMENT,FONT-ITALIC,FONT-STRIKE
+ 30=FONT-OUTLINE,FONT-SHADOW,FONT-CONDENSE,FONT-EXTEND,FONT-CHARSET
+ 35=FONT-PITCHFAMILY,FONT-HEIGHT,FONT-SCHEME,NUMFMT-CODE,
+ 40=,NUMFMT-ID,ALIGN-RELINDENT,PROT-LOCKED,PROT-HIDDEN
+end
+
+# EXTERNALBOOK ---------------------------------------------------------------
+
+constlist=EXTERNALBOOK-KEY
+ 0x0401=self-reference
+ 0x3A01=analysis-addin
+end
+
+# EXTERNALNAME ---------------------------------------------------------------
+
+flagslist=EXTERNALNAME-FLAGS-BIFF3
+ 0x0001=builtin
+ 0x0002=automatic
+ 0x0004=pic-link
+ 0x0008=dde-stddocumentname
+end
+
+combilist=EXTERNALNAME-FLAGS-BIFF5
+ include=EXTERNALNAME-FLAGS-BIFF3
+ 0x0010=ole-link
+ 0x7FE0=uint16,dec,clipboard-format
+ 0x8000=iconified
+end
+
+# EXTERNSHEET ----------------------------------------------------------------
+
+constlist=EXTERNSHEET-IDX-BIFF8
+ default=
+ -1=deleted
+ -2=special
+end
+
+# FILEPASS -------------------------------------------------------------------
+
+shortlist=FILEPASS-TYPE,0,xor,rc4
+shortlist=FILEPASS-MAJOR,1,rc4,crypto-api-2003,crypto-api-2007
+
+# FILTERCOLUMN ---------------------------------------------------------------
+
+combilist=FILTERCOLUMN-FLAGS
+ 0x0001=!and!or
+ 0x0004=op-1-simple
+ 0x0008=op-2-simple
+ 0x0010=top-10
+ 0x0020=!bottom!top
+ 0x0040=percent
+ 0xFF80=uint16,dec,top-10-count
+end
+
+constlist=FILTERCOLUMN-DATATYPE
+ 0=none
+ 2=rk
+ 4=double
+ 6=string
+ 8=boolean
+ 12=blank
+ 14=not-blank
+end
+
+shortlist=FILTERCOLUMN-OPERATOR,0,none,less,equal,less-equal,greater,not-equal,greater-equal
+
+# FONT -----------------------------------------------------------------------
+
+flagslist=FONT-FLAGS
+ 0x0001=bold
+ 0x0002=italic
+ 0x0004=underline
+ 0x0008=strikeout
+ 0x0010=outline
+ 0x0020=shadow
+ 0x0040=condense
+ 0x0080=extend
+end
+
+multilist=FONT-UNDERLINE
+ 0x00=none,single,double
+ 0x21=single-acc,double-acc
+end
+
+shortlist=FONT-ESCAPEMENT,0,none,superscript,subscript
+
+# 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
+
+# GUTS -----------------------------------------------------------------------
+
+shortlist=GUTS-LEVELS,0,none,,1-level,2-levels,3-levels,4-levels,5-levels,6-levels,7-levels
+
+# HEADERFOOTER ---------------------------------------------------------------
+
+flagslist=HEADERFOOTER-FLAGS
+ ignore=0xFFF0
+ 0x0001=has-even-hf
+ 0x0002=has-first-hf
+ 0x0004=scale-with-sheet
+ 0x0008=align-with-margins
+end
+
+# HIDEOBJ --------------------------------------------------------------------
+
+shortlist=HIDEOBJ,0,show,placeholder,hide
+
+# IMGDATA --------------------------------------------------------------------
+
+constlist=IMGDATA-FORMAT
+ -1=none
+ 2=wmf-pict
+ 9=dib
+ 14=native
+end
+
+shortlist=IMGDATA-ENV,1,windows,apple
+
+# NOTE -----------------------------------------------------------------------
+
+flagslist=NOTE-FLAGS-BIFF8
+ 0x0002=visible
+end
+
+# OBJ ------------------------------------------------------------------------
+
+# object types ---
+
+multilist=OBJ-TYPE-BIFF3
+ 0=group,line,rectangle,oval,arc,chart,textbox,button,picture
+end
+
+multilist=OBJ-TYPE-BIFF4
+ include=OBJ-TYPE-BIFF3
+ 9=polygon
+end
+
+multilist=OBJ-TYPE-BIFF5
+ include=OBJ-TYPE-BIFF4
+ 10=,checkbox,optionbutton,edit,label,dialog,spin,scrollbar,listbox,groupbox
+ 20=dropdown
+end
+
+multilist=OBJ-TYPE-BIFF8
+ include=OBJ-TYPE-BIFF5
+ 25=note
+ 30=drawing
+end
+
+# flags and constants ---
+
+flagslist=OBJ-FLAGS-BIFF3
+ 0x0001=selected
+ 0x0002=auto-size
+ 0x0004=auto-move
+ 0x0010=protected
+ 0x0080=grouped
+ 0x0100=hidden
+ 0x0200=visible
+end
+
+flagslist=OBJ-FLAGS-BIFF4
+ include=OBJ-FLAGS-BIFF3
+ 0x0400=printable
+end
+
+flagslist=OBJ-AUTO-FLAGS
+ 0x01=auto
+end
+
+multilist=OBJ-LINETYPE
+ 0=solid,dash,dot,dash-dot,dash-dot-dot,25%-pattern,50%-pattern,75%-pattern
+ 255=none
+end
+
+shortlist=OBJ-LINEWEIGHT,0,hair,thin,medium,thick
+
+shortlist=OBJ-ARROWHEAD-TYPE,0,none,open,filled,double-end-open,double-end-filled
+shortlist=OBJ-ARROWHEAD-WIDTH,0,narrow,medium,wide
+shortlist=OBJ-ARROWHEAD-LENGTH,0,short,medium,long
+
+combilist=OBJ-LINEENDS
+ 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,0,topleft-to-bottomright,topright-to-bottomleft,bottomright-to-topleft,bottomleft-to-topright
+
+shortlist=OBJ-ARC-QUADRANT,0,upper-right,upper-left,lower-left,lower-right
+
+combilist=OBJ-FRAMESTYLE-FLAGS
+ 0x0001=rounded
+ 0x0002=shadow
+ 0x03FC=uint16,dec,rounded-diameter
+end
+
+shortlist=OBJ-HORALIGN,0,none,left,center,right,justify
+shortlist=OBJ-VERALIGN,0,none,top,center,bottom,justify
+
+combilist=OBJ-TEXT-FLAGS
+ 0x000E=uint16,dec,hor-align,OBJ-HORALIGN
+ 0x0070=uint16,dec,ver-align,OBJ-VERALIGN
+ 0x0080=auto-size
+ 0x0200=text-locked
+ 0x0400=selected
+end
+
+flagslist=OBJ-PICTURE-FLAGS
+ 0x0001=auto-size
+ 0x0002=linked
+ 0x0008=symbol
+end
+
+flagslist=OBJ-POLYGON-FLAGS
+ 0x0100=closed
+end
+
+flagslist=OBJ-CHART-FLAGS-BIFF5
+ 0x0001=linked-to-sheet
+end
+
+flagslist=OBJ-BUTTON-FLAGS-BIFF5
+ 0x0001=default-btn
+ 0x0002=help-btn
+ 0x0004=cancel-btn
+ 0x0008=close-btn
+end
+
+shortlist=OBJ-CHECKBOX-STATE-BIFF5,0,unchecked,checked,tristate
+
+flagslist=OBJ-CHECKBOX-FLAGS-BIFF5
+ 0x0001=flat
+ 0x0002=box-only
+end
+
+shortlist=OBJ-EDIT-TYPE-BIFF5,0,text,integer,double,reference,formula
+
+flagslist=OBJ-SCROLLBAR-FLAGS-BIFF5
+ 0x0001=visible
+ 0x0002=slider-only
+ 0x0004=tracking
+ 0x0008=flat
+end
+
+combilist=OBJ-LISTBOX-FLAGS-BIFF5
+ 0x0004=linked-edit
+ 0x0008=flat
+ 0x0030=uint8,dec,selection-type,OBJ-LISTBOX-SELTYPE-BIFF5
+end
+
+shortlist=OBJ-LISTBOX-SELTYPE-BIFF5,0,single,multi,range
+
+flagslist=OBJ-GROUPBOX-FLAGS-BIFF5
+ 0x0001=flat
+end
+
+combilist=OBJ-DROPDOWN-FLAGS-BIFF5
+ 0x0003=uint8,dec,type,OBJ-DROPDOWN-TYPE-BIFF5
+ 0x0008=filtered
+end
+
+shortlist=OBJ-DROPDOWN-TYPE-BIFF5,0,listbox,combobox,simple,max
+
+multilist=OBJ-RECNAMES-BIFF8
+ 0x0000=OBJEND,,,,OBJMACRO,,OBJGMO,OBJCF
+ 0x0008=OBJFLAGS,OBJPICTFMLA,OBJCBLS,OBJRBO,OBJSBS,OBJNTS,OBJSBSFMLA,OBJGBODATA
+ 0x0010=OBJEDODATA,OBJRBODATA,OBJCBLSDATA,OBJLBSDATA,OBJCBLSFMLA,OBJCMO,,
+end
+
+flagslist=OBJFLAGS-FLAGS
+ 0x0001=manual-size
+ 0x0002=linked
+ 0x0004=update-on-print
+ 0x0008=symbol
+ 0x0010=control
+ 0x0020=ctls-stream
+ 0x0080=camera-pic
+ 0x0100=default-size
+ 0x0200=auto-load
+end
+
+flagslist=OBJCMO-FLAGS
+ 0x0001=locked
+ 0x0004=default-size
+ 0x0008=published
+ 0x0010=printable
+ 0x0080=disabled
+ 0x0100=auxiliary
+ 0x0200=recalc-on-load
+ 0x1000=recalc-always
+ 0x2000=auto-line
+ 0x4000=auto-area
+end
+
+# PAGELAYOUTVIEW -------------------------------------------------------------
+
+flagslist=PAGELAYOUTVIEW-FLAGS
+ ignore=0xFFF8
+ 0x0001=page-layout-view
+ 0x0002=show-ruler
+ 0x0004=hide-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
+
+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
+
+# PCDEFINITION ---------------------------------------------------------------
+
+flagslist=PCDEFINITION-FLAGS
+ 0x0001=save-data
+ 0x0002=invalid
+ 0x0004=refresh-on-load
+ 0x0008=optimize-memory
+ 0x0010=background-query
+ 0x0020=enable-refresh
+end
+
+# PCDFIELD -------------------------------------------------------------------
+
+flagslist=PCDFIELD-FLAGS
+ 0x0001=has-items
+ 0x0002=has-unshared-items
+ 0x0004=calculated
+ 0x0008=has-parent
+ 0x0010=range-group
+ 0x0020=is-numeric
+ 0x0040=is-integer
+ 0x0080=has-semi-mixed-types
+ 0x0100=has-min-max
+ 0x0200=16bit-indexes
+ 0x0400=has-non-date
+ 0x0800=has-date
+end
+
+# PCDFRANGEPR ----------------------------------------------------------------
+
+combilist=PCDFRANGEPR-FLAGS
+ ignore=0xFFE0
+ 0x0001=auto-start
+ 0x0002=auto-end
+ 0x001C=uint8,dec,group-by,PCDFRANGEPR-GROUPBY
+end
+
+shortlist=PCDFRANGEPR-GROUPBY,0,numeric,seconds,minutes,hours,days,months,quarters,years
+
+# PCDFSQLTYPE ----------------------------------------------------------------
+
+shortlist=PCDFSQLTYPE-DATATYPE,0,unknown,char,numeric,decimal,int32,int16,float,real,double,,,datetime,var-char
+
+# PCDSOURCE ------------------------------------------------------------------
+
+flagslist=PCDSOURCE-TYPE
+ 0x0001=spreadsheet
+ 0x0002=extern
+ 0x0004=consolidation-area
+ 0x0010=scenario
+end
+
+# 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=0xFFF0
+ 0x0003=uint8,dec,type,PHONETICPR-TYPE
+ 0x000C=uint8,dec,alignment,PHONETICPR-ALIGNMENT
+end
+
+# PROJEXTSHEET ---------------------------------------------------------------
+
+shortlist=PROJEXTSHEET-TYPE,0,sheet,macro,chart
+
+# PTDATAFIELD ----------------------------------------------------------------
+
+shortlist=PTDATAFIELD-SUBTOTAL,0,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p
+shortlist=PTDATAFIELD-SHOWDATAAS,0,normal,diff-from,percent-of,percent-diff-from,running-total-in,percent-of-row,percent-of-column,percent-of-total,index
+
+multilist=PTDATAFIELD-BASEITEM
+ default=
+ 0x7FFB=previous-item,next-item
+end
+
+# PTDEFINITION ---------------------------------------------------------------
+
+flagslist=PTDEFINITION-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
+
+constlist=PTDEFINITION-DATAFIELD-POS
+ default=
+ -1=append
+end
+
+# PTDEFINITION2 --------------------------------------------------------------
+
+combilist=PTDEFINITION2-FLAGS
+ 0x00000001=page-over-then-down
+ 0x000001FE=dec,uint8,page-wrap
+ 0x00010000=enable-wizard
+ 0x00020000=enable-drill
+ 0x00040000=enable-field-props
+ 0x00080000=preserve-formatting
+ 0x00100000=merge-labels
+ 0x00200000=show-error
+ 0x00400000=show-missing
+ 0x00800000=multiple-page-items
+end
+
+# PTFIELD --------------------------------------------------------------------
+
+flagslist=PTFIELD-AXISTYPE
+ 0x0001=row
+ 0x0002=column
+ 0x0004=page
+ 0x0008=data
+end
+
+flagslist=PTFIELD-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
+
+# PTFIELD2 -------------------------------------------------------------------
+
+combilist=PTFIELD2-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=ascend-sort
+ 0x00000800=autoshow
+ 0x00001000=autoshow-top
+ 0x00002000=calculated
+ 0x00200000=outline
+ 0x00400000=insert-blank-row
+ 0x00800000=subtotal-top
+ 0xFF000000=uint8,dec,autoshow-item-count
+end
+
+# PTFITEM --------------------------------------------------------------------
+
+multilist=PTFITEM-ITEMTYPE
+ 0=data,default,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p,grandtotal
+ 254=page,none
+end
+
+flagslist=PTFITEM-FLAGS
+ 0x0001=hidden
+ 0x0002=hide-detail
+ 0x0008=calculated
+ 0x0010=missing
+end
+
+constlist=PTFITEM-CACHEIDX
+ default=
+ -1=no-cache-item
+end
+
+# PTPAGEFIELDS ---------------------------------------------------------------
+
+constlist=PTPAGEFIELDS-ITEM
+ default=
+ 0x7FFD=all
+end
+
+# PTROWCOLITEMS --------------------------------------------------------------
+
+shortlist=PTROWCOLITEMS-ITEMTYPE,0,data,default,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p,grandtotal,blank-line
+
+combilist=PTROWCOLITEMS-FLAGS
+ ignore=0xC000
+ 0x0001=field-name
+ 0x01FE=uint16,dec,data-field-idx
+ 0x0200=subtotal
+ 0x0400=blocktotal
+ 0x0800=grandtotal
+ 0x1000=multi-data
+end
+
+# QUERYTABLE -----------------------------------------------------------------
+
+combilist=QUERYTABLE-FLAGS
+ 0x0001=headers
+ 0x0002=row-numbers
+ 0x0004=disable-refresh
+ 0x0008=background
+ 0x0010=first-background
+ 0x0020=refresh-on-load
+ 0x0040=delete-unused
+ 0x0080=fill-formulas
+ 0x0100=adjust-column-width
+ 0x0200=save-data
+ 0x0400=disable-edit
+ 0x2000=overwrite-existing
+end
+
+combilist=QUERYTABLE-AUTOFORMAT-FLAGS
+ 0x0001=apply-num-fmt
+ 0x0002=apply-font
+ 0x0004=apply-alignment
+ 0x0008=apply-border
+ 0x0010=apply-fill
+ 0x0020=apply-protection
+end
+
+# QUERYTABLEREFRESH ----------------------------------------------------------
+
+flagslist=QUERYTABLEREFRESH-FLAGS
+ 0x0001=enable-refresh
+ 0x0002=pivot-cache-invalid
+ 0x0004=olap-pivot-table
+end
+
+flagslist=QUERYTABLEREFRESH-PTFLAGS
+ 0x00000001=disable-draw-drop
+ 0x00000002=hide-totals-annotation
+ 0x00000008=include-empty-rows
+ 0x00000010=include-empty-columns
+end
+
+flagslist=QUERYTABLEREFRESH-QTFLAGS
+ 0x00000001=preserve-formatting
+ 0x00000002=adjust-column-width
+ 0x00000010=ext-data-list
+ 0x00000040=create-table-list
+ 0x00000080=create-dummy-list
+end
+
+# QUERYTABLESETTINGS ---------------------------------------------------------
+
+flagslist=QUERYTABLESETTINGS-FLAGS
+ 0x0001=keep-alive
+ 0x0002=new
+ 0x0004=source-data
+ 0x0008=web-based-prov
+ 0x0010=reinit-list
+ 0x0080=xml
+end
+
+flagslist=QUERYTABLESETTINGS-HTML-FLAGS
+ 0x0001=parse-pre
+ 0x0002=consecutive-delimiters
+ 0x0004=first-row
+ 0x0008=xl97-created
+ 0x0010=text-dates
+ 0x0020=xl2000-refreshed
+end
+
+combilist=QUERYTABLESETTINGS-OLEDB-FLAGS
+ 0x0007=uint8,dec,command-type,QUERYTABLESETTINGS-OLEDB-COMMANDTYPE
+ 0x0008=alt-connection-string
+ 0x0010=no-refresh-cube
+ 0x0020=olap-has-locale
+ 0x0040=server-num-fmt
+ 0x0080=server-fill-color
+ 0x0100=server-font-color
+ 0x0200=server-font-format
+ 0x0400=olap-member-l10n
+end
+
+shortlist=QUERYTABLESETTINGS-OLEDB-COMMANDTYPE,0,none,cube,sql,table,default,list
+
+flagslist=QUERYTABLESETTINGS-ADO-FLAGS
+ 0x0100=ado-refreshable
+end
+
+flagslist=QUERYTABLESETTINGS-EXT-FLAGS
+ 0x0001=text-query
+ 0x0002=table-names
+end
+
+unitconverter=QUERYTABLESETTINGS-INTERVAL,60,sec
+shortlist=QUERYTABLESETTINGS-HTMLFORMAT,1,none,rtf,all
+
+# 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
+
+# SHAREDFEATHEAD -------------------------------------------------------------
+
+shortlist=SHAREDFEATHEAD-TYPE,2,protection,ignored-formula-errors,smarttag,table
+
+flagslist=SHAREDFEATHEAD-PROT-FLAGS
+ 0x00000001=edit-object
+ 0x00000002=edit-scenario
+ 0x00000004=format-cell
+ 0x00000008=format-column
+ 0x00000010=format-row
+ 0x00000020=insert-column
+ 0x00000040=insert-row
+ 0x00000080=insert-hyperlink
+ 0x00000100=delete-column
+ 0x00000200=delete-row
+ 0x00000400=select-locked
+ 0x00000800=sort
+ 0x00001000=use-autofilter
+ 0x00002000=pivottable-report
+ 0x00004000=select-unlocked
+end
+
+# SHEET ----------------------------------------------------------------------
+
+shortlist=SHEET-STATE,0,visible,hidden,very-hidden
+shortlist=SHEET-TYPE,0,worksheet,macrosheet,chartsheet,,,,vb-module
+
+# SHEETEXT -------------------------------------------------------------------
+
+combilist=SHEETEXT-FLAGS1
+ 0x0000007F=uint8,dec,color-idx,SHEETEXT-COLOR
+end
+
+constlist=SHEETEXT-COLOR
+ include=COLORS
+ 0x7F=undefined
+end
+
+combilist=SHEETEXT-FLAGS2
+ include=SHEETEXT-FLAGS1
+ 0x00000080=eval-cond-formats
+ 0x00000100=!published!unpublished
+end
+
+# SHEETPR --------------------------------------------------------------------
+
+shortlist=SHEETPR-WINDOWPOS,0,tiled,horizontal,vertical,cascaded
+
+flagslist=SHEETPR-FLAGS-BIFF3
+ 0x0001=show-autopagebreaks
+ 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
+ 0x0010=dialog-sheet
+end
+
+# STYLE ----------------------------------------------------------------------
+
+combilist=STYLE-FLAGS
+ 0x0FFF=uint16,dec,xf-idx
+ 0x8000=builtin
+end
+
+shortlist=STYLE-BUILTIN,-1,user-defined,normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink
+
+# STYLEEXT -------------------------------------------------------------------
+
+flagslist=STYLEEXT-FLAGS
+ 0x01=builtin
+ 0x02=hidden
+ 0x04=custom
+end
+
+shortlist=STYLEEXT-CATEGORY,0,custom,good-bad-neutral,data-model,title-heading,themed,number-format
+
+multilist=STYLEEXT-BUILTIN
+ include=STYLE-BUILTIN
+ 10=note,warning-text,,,,title,heading-1,heading-2,heading-3,heading-4
+ 20=input,output,calculation,check-cell,linked-cell,total,good,bad,neutral,accent1
+ 30=20%-accent1,40%-accent1,60%-accent1,accent2,20%-accent2,40%-accent2,60%-accent2,accent3,20%-accent3,40%-accent3
+ 40=60%-accent3,accent4,20%-accent4,40%-accent4,60%-accent4,accent5,20%-accent5,40%-accent5,60%-accent5,accent6
+ 50=20%-accent6,40%-accent6,60%-accent6,explanatory-text
+end
+
+# THEME ----------------------------------------------------------------------
+
+constlist=THEME-VERSION
+ 0=custom
+ 123820=default
+ 124226=default
+end
+
+# TXO ------------------------------------------------------------------------
+
+combilist=TXO-FLAGS
+ 0x000E=uint16,dec,hor-align,OBJ-HORALIGN
+ 0x0070=uint16,dec,ver-align,OBJ-VERALIGN
+ 0x0200=text-locked
+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
+ 0x08=apostroph-quote
+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
+
+# XFEXT ----------------------------------------------------------------------
+
+multilist=XFEXT-SUBREC
+ 0=,,,,FILL-FGCOLOR
+ 5=FILL-BGCOLOR,FILL-GRADIENT,BORDER-TOP-COLOR,BORDER-BOTTOM-COLOR,BORDER-LEFT-COLOR
+ 10=BORDER-RIGHT-COLOR,BORDER-DIAG-COLOR,,TEXT-COLOR,FONT-SCHEME
+ 15=INDENT
+end
+
+# ============================================================================
diff --git a/oox/source/dump/dffdumper.cxx b/oox/source/dump/dffdumper.cxx
new file mode 100644
index 000000000000..01994865c69d
--- /dev/null
+++ b/oox/source/dump/dffdumper.cxx
@@ -0,0 +1,324 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/dump/dffdumper.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 DFF_ID_BSE = 0xF007; /// BLIP store entry.
+const sal_uInt16 DFF_ID_BSTORECONTAINER = 0xF001; /// BLIP store container.
+const sal_uInt16 DFF_ID_CHILDANCHOR = 0xF00F; /// Child anchor (in groups).
+const sal_uInt16 DFF_ID_CLIENTANCHOR = 0xF010; /// Client anchor.
+const sal_uInt16 DFF_ID_DG = 0xF008; /// Drawing.
+const sal_uInt16 DFF_ID_DGG = 0xF006; /// Drawing group.
+const sal_uInt16 DFF_ID_OPT = 0xF00B; /// Property set.
+const sal_uInt16 DFF_ID_OPT2 = 0xF121; /// Secondary property set.
+const sal_uInt16 DFF_ID_OPT3 = 0xF122; /// Ternary property set.
+const sal_uInt16 DFF_ID_SP = 0xF00A; /// Shape.
+const sal_uInt16 DFF_ID_SPGR = 0xF009; /// Shape group.
+const sal_uInt16 DFF_ID_SPLITMENUCOLORS = 0xF11E; /// Current toolbar colors.
+
+const sal_uInt16 DFF_OPT_IDMASK = 0x3FFF;
+const sal_uInt16 DFF_OPT_PICTURE = 0x4000;
+const sal_uInt16 DFF_OPT_COMPLEX = 0x8000;
+const sal_uInt16 DFF_OPT_FLAGSMASK = 0x003F;
+
+} // namespace
+
+// ============================================================================
+
+void DffStreamObject::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ SequenceRecordObjectBase::construct( rParent, rxStrm, rSysFileName, "DFF-RECORD-NAMES" );
+ constructDffObj();
+}
+
+void DffStreamObject::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
+{
+ SequenceRecordObjectBase::construct( rParent, rxStrm, "DFF-RECORD-NAMES" );
+ constructDffObj();
+}
+
+bool DffStreamObject::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ sal_uInt16 nRecId;
+ rBaseStrm >> mnInstVer >> nRecId >> mnRealSize;
+ ornRecId = nRecId;
+ ornRecSize = isContainer() ? 0 : mnRealSize;
+ return !rBaseStrm.isEof();
+}
+
+void DffStreamObject::implWriteExtHeader()
+{
+ const sal_Char* pcListName = "DFF-RECORD-INST";
+ switch( getRecId() )
+ {
+ case DFF_ID_BSE: pcListName = "DFFBSE-RECORD-INST"; break; // BLIP type
+ case DFF_ID_BSTORECONTAINER: pcListName = "DFFBSTORECONT-RECORD-INST"; break; // BLIP count
+ case DFF_ID_DG: pcListName = "DFFDG-RECORD-INST"; break; // drawing ID
+ case DFF_ID_OPT: pcListName = "DFFOPT-RECORD-INST"; break; // property count
+ case DFF_ID_SP: pcListName = "DFFSP-RECORD-INST"; break; // shape type
+ case DFF_ID_SPLITMENUCOLORS: pcListName = "DFFSPLITMENUC-RECORD-INST"; break; // number of colors
+ }
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeHexItem( "instance", mnInstVer, pcListName );
+ if( isContainer() ) writeDecItem( "container-size", mnRealSize );
+}
+
+void DffStreamObject::implDumpRecordBody()
+{
+ switch( getRecId() )
+ {
+ case DFF_ID_BSE:
+ dumpDec< sal_uInt8 >( "win-type", "DFFBSE-TYPE" );
+ dumpDec< sal_uInt8 >( "mac-type", "DFFBSE-TYPE" );
+ dumpGuid( "guid" );
+ dumpDec< sal_uInt16 >( "tag" );
+ dumpDec< sal_uInt32 >( "blip-size" );
+ dumpDec< sal_uInt32 >( "blip-refcount" );
+ dumpDec< sal_uInt32 >( "blip-streampos" );
+ dumpDec< sal_uInt8 >( "blip-usage", "DFFBSE-USAGE" );
+ dumpDec< sal_uInt8 >( "blip-name-len" );
+ dumpUnused( 2 );
+ break;
+
+ case DFF_ID_CHILDANCHOR:
+ dumpDec< sal_uInt32 >( "left" );
+ dumpDec< sal_uInt32 >( "top" );
+ dumpDec< sal_uInt32 >( "right" );
+ dumpDec< sal_uInt32 >( "bottom" );
+ break;
+
+ case DFF_ID_CLIENTANCHOR:
+ implDumpClientAnchor();
+ break;
+
+ case DFF_ID_DG:
+ dumpDec< sal_uInt32 >( "shape-count" );
+ dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" );
+ break;
+
+ case DFF_ID_DGG:
+ {
+ dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" );
+ sal_uInt32 nClusters = dumpDec< sal_uInt32 >( "id-cluster-count" );
+ dumpDec< sal_uInt32 >( "shape-count" );
+ dumpDec< sal_uInt32 >( "drawing-count" );
+ mxOut->resetItemIndex( 1 );
+ TableGuard aTabGuard( mxOut, 15, 16 );
+ for( sal_uInt32 nCluster = 1; !mxStrm->isEof() && (nCluster < nClusters); ++nCluster )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#cluster" );
+ dumpDec< sal_uInt32 >( "drawing-id" );
+ dumpHex< sal_uInt32 >( "next-free-id", "CONV-DEC" );
+ }
+ }
+ break;
+
+ case DFF_ID_OPT:
+ case DFF_ID_OPT2:
+ case DFF_ID_OPT3:
+ dumpDffOpt();
+ break;
+
+ case DFF_ID_SP:
+ dumpHex< sal_uInt32 >( "shape-id", "CONV-DEC" );
+ dumpHex< sal_uInt32 >( "shape-flags", "DFFSP-FLAGS" );
+ break;
+
+ case DFF_ID_SPGR:
+ dumpDec< sal_uInt32 >( "left" );
+ dumpDec< sal_uInt32 >( "top" );
+ dumpDec< sal_uInt32 >( "right" );
+ dumpDec< sal_uInt32 >( "bottom" );
+ break;
+
+ case DFF_ID_SPLITMENUCOLORS:
+ dumpDffSimpleColor( "fill-color" );
+ dumpDffSimpleColor( "line-color" );
+ dumpDffSimpleColor( "shadow-color" );
+ dumpDffSimpleColor( "3d-color" );
+ break;
+ }
+}
+
+void DffStreamObject::implDumpClientAnchor()
+{
+}
+
+void DffStreamObject::constructDffObj()
+{
+ mnInstVer = 0;
+ mnRealSize = 0;
+ if( SequenceRecordObjectBase::implIsValid() )
+ {
+ maSimpleProps.insertFormats( cfg().getNameList( "DFFOPT-SIMPLE-PROPERTIES" ) );
+ maComplexProps.insertFormats( cfg().getNameList( "DFFOPT-COMPLEX-PROPERTIES" ) );
+ }
+}
+
+sal_uInt32 DffStreamObject::dumpDffSimpleColor( const String& rName )
+{
+ return dumpHex< sal_uInt32 >( rName, "DFF-SIMPLE-COLOR" );
+}
+
+sal_uInt32 DffStreamObject::dumpDffColor( const String& rName )
+{
+ return dumpHex< sal_uInt32 >( rName, "DFF-COLOR" );
+}
+
+namespace {
+
+enum PropType { PROPTYPE_BINARY, PROPTYPE_STRING, PROPTYPE_BLIP, PROPTYPE_COLORARRAY };
+
+struct PropInfo
+{
+ OUString maName;
+ PropType meType;
+ sal_uInt16 mnId;
+ sal_uInt32 mnSize;
+ inline explicit PropInfo( const OUString& rName, PropType eType, sal_uInt16 nId, sal_uInt32 nSize ) :
+ maName( rName ), meType( eType ), mnId( nId ), mnSize( nSize ) {}
+};
+
+typedef ::std::vector< PropInfo > PropInfoVector;
+
+} // namespace
+
+void DffStreamObject::dumpDffOpt()
+{
+ sal_uInt16 nPropCount = getInst();
+ PropInfoVector aPropInfos;
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nPropIdx = 0; !mxStrm->isEof() && (nPropIdx < nPropCount); ++nPropIdx )
+ {
+ sal_uInt16 nPropId = dumpDffOptPropHeader();
+ sal_uInt16 nBaseId = nPropId & DFF_OPT_IDMASK;
+ sal_uInt32 nValue = mxStrm->readuInt32();
+
+ IndentGuard aIndent( mxOut );
+ if( getFlag( nPropId, DFF_OPT_COMPLEX ) )
+ {
+ writeHexItem( "complex-size", nValue, "CONV-DEC" );
+ String aName;
+ PropType eType = PROPTYPE_BINARY;
+ ItemFormatMap::const_iterator aIt = maComplexProps.find( nBaseId );
+ if( aIt != maComplexProps.end() )
+ {
+ const ItemFormat& rItemFmt = aIt->second;
+ aName = rItemFmt.maItemName;
+ if( rItemFmt.maListName.equalsAscii( "binary" ) )
+ eType = PROPTYPE_BINARY;
+ else if( rItemFmt.maListName.equalsAscii( "string" ) )
+ eType = PROPTYPE_STRING;
+ else if( rItemFmt.maListName.equalsAscii( "blip" ) )
+ eType = PROPTYPE_BLIP;
+ else if( rItemFmt.maListName.equalsAscii( "colorarray" ) )
+ eType = PROPTYPE_COLORARRAY;
+ }
+ aPropInfos.push_back( PropInfo( aName( "property-data" ), eType, nBaseId, nValue ) );
+ }
+ else
+ {
+ ItemFormatMap::const_iterator aIt = maSimpleProps.find( nBaseId );
+ if( aIt != maSimpleProps.end() )
+ {
+ const ItemFormat& rItemFmt = aIt->second;
+ // flags always at end of block of 64 properties
+ if( (nBaseId & DFF_OPT_FLAGSMASK) == DFF_OPT_FLAGSMASK )
+ {
+ FlagsList* pFlagsList = dynamic_cast< FlagsList* >( cfg().getNameList( rItemFmt.maListName ).get() );
+ sal_Int64 nOldIgnoreFlags = 0;
+ if( pFlagsList )
+ {
+ nOldIgnoreFlags = pFlagsList->getIgnoreFlags();
+ pFlagsList->setIgnoreFlags( nOldIgnoreFlags | 0xFFFF0000 | ~(nValue >> 16) );
+ }
+ writeValueItem( rItemFmt, nValue );
+ if( pFlagsList )
+ pFlagsList->setIgnoreFlags( nOldIgnoreFlags );
+ }
+ else
+ writeValueItem( rItemFmt, nValue );
+ }
+ else
+ writeHexItem( "value", nValue );
+ }
+ }
+
+ mxOut->resetItemIndex();
+ for( PropInfoVector::iterator aIt = aPropInfos.begin(), aEnd = aPropInfos.end(); !mxStrm->isEof() && (aIt != aEnd); ++aIt )
+ {
+ mxOut->startMultiItems();
+ writeEmptyItem( "#complex-data" );
+ writeHexItem( "id", aIt->mnId, "DFFOPT-PROPERTY-NAMES" );
+ mxOut->endMultiItems();
+ IndentGuard aIndent( mxOut );
+ switch( aIt->meType )
+ {
+ case PROPTYPE_BINARY:
+ dumpBinary( aIt->maName, aIt->mnSize );
+ break;
+ case PROPTYPE_STRING:
+ dumpUnicodeArray( aIt->maName, aIt->mnSize / 2, true );
+ break;
+ case PROPTYPE_BLIP:
+ dumpBinary( aIt->maName, aIt->mnSize );
+ break;
+ case PROPTYPE_COLORARRAY:
+ dumpBinary( aIt->maName, aIt->mnSize );
+ break;
+ }
+ }
+}
+
+sal_uInt16 DffStreamObject::dumpDffOptPropHeader()
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ TableGuard aTabGuard( mxOut, 11 );
+ writeEmptyItem( "#prop" );
+ return dumpHex< sal_uInt16 >( "id", "DFFOPT-PROPERTY-ID" );
+}
+
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
diff --git a/oox/source/dump/dffdumper.ini b/oox/source/dump/dffdumper.ini
new file mode 100644
index 000000000000..5526663e0e15
--- /dev/null
+++ b/oox/source/dump/dffdumper.ini
@@ -0,0 +1,650 @@
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+
+# name lists =================================================================
+
+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,DFFOPT2,DFFOPT3
+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
+
+combilist=DFF-SIMPLE-COLOR
+ 0x000000FF=uint8,dec,red,,filter=0x10000000~0x00000000
+ 0x0000FF00=uint8,dec,green,,filter=0x10000000~0x00000000
+ 0x00FF0000=uint8,dec,blue,,filter=0x10000000~0x00000000
+ 0x000000FF=uint8,dec,scheme-idx,,filter=0x10000000~0x10000000
+ 0x10000000=!rgb!scheme
+ ignore=0x08000000
+end
+
+combilist=DFF-COLOR
+ 0x0000FFFF=uint16,dec,palette-idx,,filter=0xFF000000~0x01000000
+ 0x000000FF=uint8,dec,red,,filter=0xF9000000~0x00000000
+ 0x0000FF00=uint8,dec,green,,filter=0xF9000000~0x00000000
+ 0x00FF0000=uint8,dec,blue,,filter=0xF9000000~0x00000000
+ 0x000000FF=uint8,dec,scheme-idx,,filter=0xFF000000~0x08000000
+ 0x0000FFFF=uint16,dec,system-idx,DFF-SYSTEMCOLOR,filter=0xFF000000~0x10000000
+ 0x00FF0000=uint16,dec,mod-by,,filter=0xFF000000~0x10000000
+ 0x01000000=palette-idx
+ 0x02000000=palette-rgb
+ 0x04000000=system-rgb
+ 0x08000000=scheme-idx
+ 0x10000000=system-idx
+end
+
+combilist=DFF-SYSTEMCOLOR
+ 0x00FF=uint8,dec,color-id,DFF-SYSTEMCOLOR-ID
+ 0x0F00=uint8,dec,mod,DFF-SYSTEMCOLOR-MOD
+ 0x2000=invert-after
+ 0x4000=half-invert-after
+ 0x8000=grey-before
+end
+
+constlist=DFF-SYSTEMCOLOR-ID
+ include=SYSTEMCOLOR
+ 0xF0=shape-fill
+ 0xF1=shape-line-or-fill
+ 0xF2=shape-line
+ 0xF3=shape-shadow
+ 0xF4=current-or-last-used
+ 0xF5=shape-fill-back
+ 0xF6=shape-line-back
+ 0xF7=shape-fill-or-line
+end
+
+shortlist=DFF-SYSTEMCOLOR-MOD,0,none,darken-by,lighten-by,add-grey-by,sub-grey-by,reverse-sub-grey-by,monochrome-by
+
+combilist=DFF-COLORMOD
+ 0x00000300=uint8,dec,type,DFF-COLORMOD-TYPE
+ 0x00FF0000=uint8,dec,level
+ ignore=0x200000FF
+end
+
+shortlist=DFF-COLORMOD-TYPE,0,none,shade,tint
+
+# DFFBSE ---------------------------------------------------------------------
+
+combilist=DFFBSE-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,blip-type,DFFBSE-TYPE
+end
+
+multilist=DFFBSE-TYPE
+ 0=error,unknown,emf,wmf,pict,jpeg,png,dib
+ 17=tiff,cmyk-jpeg
+end
+
+shortlist=DFFBSE-USAGE,0,default,texture
+
+# DFFBSTORECONTAINER ---------------------------------------------------------
+
+combilist=DFFBSTORECONT-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,blip-count
+end
+
+# DFFDG ----------------------------------------------------------------------
+
+combilist=DFFDG-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,drawing-id
+end
+
+# DFFOPT ---------------------------------------------------------------------
+
+combilist=DFFOPT-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,property-count
+end
+
+combilist=DFFOPT-PROPERTY-ID
+ 0x3FFF=uint16,dec,id,DFFOPT-PROPERTY-NAMES
+ 0x4000=picture
+ 0x8000=complex
+end
+
+multilist=DFFOPT-PROPERTY-NAMES
+ # 0x0000-0x003F: transformation
+ 0x0000=transf-left,transf-top,transf-right,transf-bottom,transf-rotation,transf-page
+ 0x003F=transf-flags
+ # 0x0040-0x007F: protection
+ 0x007F=prot-flags
+ # 0x0080-0x00BF: 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-orient,text-next-shape,text-bidi
+ 0x00BF=text-flags
+ # 0x00C0-0x00FF: text geometry
+ 0x00C0=textgeo-unicode-string,textgeo-rtf-string,textgeo-curve-align,textgeo-def-size,textgeo-spacing,textgeo-font,textgeo-css-font
+ 0x00FF=textgeo-flags
+ # 0x0100-0x013F: picture (BLIP)
+ 0x0100=blip-crop-top,blip-crop-bottom,blip-crop-left,blip-crop-right,blip-id,blip-name,blip-opt,blip-transparency-color
+ 0x0108=blip-contrast,blip-brightness,blip-gamma,blip-ole-id,blip-double-cr-mod,blip-fill-cr-mod,blip-line-cr-mod,blip-print-id
+ 0x0110=blip-print-name,blip-print-opt,blip-movie,,,blip-transparency-color-ext,,blip-transparency-color-ext-mod
+ 0x0118,,blip-recolor,blip-recolor,blip-recolor-ext,,blip-recolor-ext-mod
+ 0x013F=blip-flags
+ # 0x0140-0x017F: shape 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,
+ 0x0150=,geo-connect-sites,geo-connect-sites-dir,geo-stretch-x,geo-stretch-y,geo-handles,geo-guides,geo-inscribe
+ 0x0158=geo-connect-points
+ 0x017F=geo-flags
+ # 0x0180-0x01BF: 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-opt,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,,fill-color-ext,
+ 0x01A0=fill-color-ext-mod,,fill-back-color-ext,,fill-back-color-ext-mod
+ 0x01BF=fill-flags
+ # 0x01C0-0x01FF: 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-opt
+ 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
+ 0x01D8=,line-color-ext,,line-color-ext-mod,,line-back-color-ext,,line-back-color-ext-mod
+ 0x01FF=line-flags
+ # 0x0200-0x023F: 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,,,,,,,
+ 0x0210=shadow-origin-x,shadow-origin-y,shadow-color-ext,,shadow-color-ext-mod,,shadow-highlight-ext,
+ 0x0218=shadow-highlight-ext-mod
+ 0x023F=shadow-flags
+ # 0x0240-0x027F: 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
+ # 0x0280-0x02BF: 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,3dobj-extrusion-color-ext,,3dobj-extrusion-color-ext-mod
+ 0x02BF=3dobj-flags
+ # 0x02C0-0x02FF: 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
+ # 0x0300-0x033F: shape
+ 0x0300=,shape-master,,shape-connect-style,shape-bw-mod,shape-bw-mode-pure-bw,shape-bw-mode-bw,shape-discuss-anchor-id
+ 0x0308=,shape-dia-layout,shape-dia-node-kind,shape-dia-layout-mru,shape-equation-xml
+ 0x033F=shape-flags
+ # 0x0340-0x037F: callout
+ 0x0340=callout-type,callout-box-distance,callout-angle,callout-drop-type,callout-drop-pos,callout-length
+ 0x037F=callout-flags
+ # 0x0380-0x03BF: group or shape
+ 0x0380=group-name,group-description,group-hyperlink,group-wrap-polygon-vertices,group-wrap-left,group-wrap-top,group-wrap-right,group-wrap-bottom
+ 0x0388=group-regroup-id,,,,,group-tooltip,group-script,group-pos-h
+ 0x0390=group-pos-rel-h,group-pos-v,group-pos-rel-v,group-rel-width-hr,group-align-hr,group-height-hr,group-width-hr,group-script-ext-attr
+ 0x0398=group-script-lang,,group-script-lang-attr,group-border-top-color,group-border-left-color,group-border-bottom-color,group-border-right-color,group-table-props
+ 0x03A0=group-table-row-props,,,,,group-web-bot,,
+ 0x03A8=,group-metro-blob,group-rel-z-order,
+ 0x03BF=group-flags
+ # 0x03C0-0x03FF: relative transformation
+ 0x03C0=reltransf-left,reltransf-top,reltransf-right,reltransf-bottom,reltransf-rotation,reltransf-page
+ 0x03FF=reltransf-flags
+ # 0x0400-0x043F: unknown HTML
+ 0x0400=,,uhtml-line-id,uhtml-fill-id,uhtml-pic-id,uhtml-path-id,uhtml-shadow-id,uhtml-persp-id
+ 0x0408=uhtml-text-path-id,uhtml-formulae-id,uhtml-handles-id,uhtml-callout-id,uhtml-lock-id,uhtml-text-id,uhtml-3d-id
+ 0x043F=uhtml-flags
+ # 0x0500-0x053F: diagram
+ 0x0500=dia-type,dia-style,,,dia-rel-table,dia-scale-x,dia-scale-y,dia-def-fontsize
+ 0x0508=dia-constrain-bounds,dia-base-text-scale
+ 0x053F=dia-flags
+ # 0x0540-0x057F: left line style
+ 0x0540=lline-color,lline-opacity,lline-back-color,lline-cr-mod,lline-type,lline-fill-blip,lline-fill-blip-name,lline-fill-blip-opt
+ 0x0548=lline-fill-width,lline-fill-height,lline-fill-dz-type,lline-width,lline-miter-limit,lline-style,lline-dash,lline-dash-style
+ 0x0550=lline-start-arrow-head,lline-end-arrow-head,lline-start-arrow-width,lline-start-arrow-length,lline-end-arrow-width,lline-end-arrow-length,lline-join-style,lline-end-cap-style
+ 0x0558=,lline-color-ext,,lline-color-ext-mod,,lline-back-color-ext,,lline-back-color-ext-mod
+ 0x057F=lline-flags
+ # 0x0580-0x05BF: top line style
+ 0x0580=tline-color,tline-opacity,tline-back-color,tline-cr-mod,tline-type,tline-fill-blip,tline-fill-blip-name,tline-fill-blip-opt
+ 0x0588=tline-fill-width,tline-fill-height,tline-fill-dz-type,tline-width,tline-miter-limit,tline-style,tline-dash,tline-dash-style
+ 0x0590=tline-start-arrow-head,tline-end-arrow-head,tline-start-arrow-width,tline-start-arrow-length,tline-end-arrow-width,tline-end-arrow-length,tline-join-style,tline-end-cap-style
+ 0x0598=,tline-color-ext,,tline-color-ext-mod,,tline-back-color-ext,,tline-back-color-ext-mod
+ 0x05BF=tline-flags
+ # 0x05C0-0x05FF: right line style
+ 0x05C0=rline-color,rline-opacity,rline-back-color,rline-cr-mod,rline-type,rline-fill-blip,rline-fill-blip-name,rline-fill-blip-opt
+ 0x05C8=rline-fill-width,rline-fill-height,rline-fill-dz-type,rline-width,rline-miter-limit,rline-style,rline-dash,rline-dash-style
+ 0x05D0=rline-start-arrow-head,rline-end-arrow-head,rline-start-arrow-width,rline-start-arrow-length,rline-end-arrow-width,rline-end-arrow-length,rline-join-style,rline-end-cap-style
+ 0x05D8=,rline-color-ext,,rline-color-ext-mod,,rline-back-color-ext,,rline-back-color-ext-mod
+ 0x05FF=rline-flags
+ # 0x0600-0x063F: bottom line style
+ 0x0600=bline-color,bline-opacity,bline-back-color,bline-cr-mod,bline-type,bline-fill-blip,bline-fill-blip-name,bline-fill-blip-opt
+ 0x0608=bline-fill-width,bline-fill-height,bline-fill-dz-type,bline-width,bline-miter-limit,bline-style,bline-dash,bline-dash-style
+ 0x0610=bline-start-arrow-head,bline-end-arrow-head,bline-start-arrow-width,bline-start-arrow-length,bline-end-arrow-width,bline-end-arrow-length,bline-join-style,bline-end-cap-style
+ 0x0618=,bline-color-ext,,bline-color-ext-mod,,bline-back-color-ext,,bline-back-color-ext-mod
+ 0x063F=bline-flags
+ # 0x0680-0x06BF: web component
+ 0x0680=webcomp-html,webcomp-name,webcomp-url
+ 0x06BF=webcomp-flags
+ # 0x0700-0x073F: ink data
+ 0x0700=ink-data
+ 0x073F=ink-flags
+ # 0x0780-0x07BF: signature line
+ 0x0780=,sigline-guid,sigline-provider-guid,sigline-suggested-signer,sigline-suggested-signer-info,sigline-suggested-signer-email,sigline-sign-instruction,sigline-add-xml
+ 0x0788=sigline-provider-url
+ 0x07BF=sigline-flags
+ # 0x07C0-0x07FF: group or shape #2
+ 0x07C0=group2-rel-width,group2-rel-height,group2-rel-pos-x,group2-rel-pos-y,group2-size-rel-h,group2-size-rel-v
+end
+
+constlist=DFFOPT-SIMPLE-PROPERTIES
+ # transformation
+ 0x003F=uint32,hex,flags,DFFOPT-TRANSFORM-FLAGS
+ # protection
+ 0x007F=uint32,hex,flags,DFFOPT-PROTECTION-FLAGS
+ # text
+ 0x00BF=uint32,hex,flags,DFFOPT-TEXT-FLAGS
+ # text geometry
+ 0x00FF=uint32,hex,flags,DFFOPT-TEXTGEO-FLAGS
+ # picture (BLIP)
+ 0x013F=uint32,hex,flags,DFFOPT-BLIP-FLAGS
+ # shape geometry
+ 0x017F=uint32,hex,flags,DFFOPT-GEO-FLAGS
+ # fill style
+ 0x0180=uint32,dec,type,DFFOPT-FILL-TYPE
+ 0x0181=uint32,hex,color,DFF-COLOR
+ 0x0182=int32,fix,opacity,CONV-FLOAT-TO-PERC
+ 0x0183=uint32,hex,color,DFF-COLOR
+ 0x0184=int32,fix,opacity,DFF-OPACITY
+ 0x0185=uint32,hex,color,DFF-COLOR
+ 0x0186=uint32,dec,blip-id
+ 0x0188=uint32,dec,blip-opt,DFFOPT-BLIPOPT
+ 0x0189=int32,dec,width
+ 0x018A=int32,dec,height
+ 0x018B=int32,fix,angle,CONV-DEG
+ 0x018C=int32,dec,focus,CONV-PERCENT
+ 0x018D=int32,fix,size,CONV-FLOAT-TO-PERC
+ 0x018E=int32,fix,size,CONV-FLOAT-TO-PERC
+ 0x018F=int32,fix,size,CONV-FLOAT-TO-PERC
+ 0x0190=int32,fix,size,CONV-FLOAT-TO-PERC
+ 0x0191=int32,fix,size,CONV-EMU-TO-CM
+ 0x0192=int32,fix,size,CONV-EMU-TO-CM
+ 0x0193=int32,fix,size,CONV-EMU-TO-CM
+ 0x0194=int32,fix,size,CONV-EMU-TO-CM
+ 0x0195=uint32,dec,type,DFFOPT-FILL-DZTYPE
+ 0x0196=int32,dec,preset
+ 0x0198=int32,fix,pos,CONV-FLOAT-TO-PERC
+ 0x0199=int32,fix,pos,CONV-FLOAT-TO-PERC
+ 0x019A=int32,fix,pos,CONV-FLOAT-TO-PERC
+ 0x019B=int32,fix,pos,CONV-FLOAT-TO-PERC
+ 0x019C=uint32,hex,type,DFFOPT-FILL-SHADETYPE
+ 0x019E=uint32,hex,color,DFF-COLOR
+ 0x01A0=uint32,hex,color-mod,DFF-COLORMOD
+ 0x01A2=uint32,hex,color,DFF-COLOR
+ 0x01A4=uint32,hex,color-mod,DFF-COLORMOD
+ 0x01BF=uint32,hex,flags,DFFOPT-FILL-FLAGS
+ # line style
+ 0x01C0=uint32,hex,color,DFF-COLOR
+ 0x01C2=uint32,hex,color,DFF-COLOR
+ 0x01FF=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # shadow style
+ 0x0201=uint32,hex,color,DFF-COLOR
+ 0x023F=uint32,hex,flags,DFFOPT-SHADOW-FLAGS
+ # perspective
+ 0x027F=uint32,hex,flags,DFFOPT-PERSP-FLAGS
+ # 3d object
+ 0x02BF=uint32,hex,flags,DFFOPT-3DOBJ-FLAGS
+ # 3d style
+ 0x02FF=uint32,hex,flags,DFFOPT-3DSTYLE-FLAGS
+ # shape
+ 0x033F=uint32,hex,flags,DFFOPT-SHAPE-FLAGS
+ # callout
+ 0x037F=uint32,hex,flags,DFFOPT-CALLOUT-FLAGS
+ # group or shape
+ 0x03BF=uint32,hex,flags,DFFOPT-GROUP-FLAGS
+ # relative transformation
+ 0x03FF=uint32,hex,flags,DFFOPT-TRANSFORM-FLAGS
+ # unknown HTML
+ 0x043F=uint32,hex,flags,DFFOPT-UHTML-FLAGS
+ # diagram
+ 0x053F=uint32,hex,flags,DFFOPT-DIAGRAM-FLAGS
+ # left line style
+ 0x0540=uint32,hex,color,DFF-COLOR
+ 0x0542=uint32,hex,color,DFF-COLOR
+ 0x057F=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # top line style
+ 0x0580=uint32,hex,color,DFF-COLOR
+ 0x0582=uint32,hex,color,DFF-COLOR
+ 0x05BF=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # right line style
+ 0x05C0=uint32,hex,color,DFF-COLOR
+ 0x05C2=uint32,hex,color,DFF-COLOR
+ 0x05FF=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # bottom line style
+ 0x0600=uint32,hex,color,DFF-COLOR
+ 0x0602=uint32,hex,color,DFF-COLOR
+ 0x063F=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # web component
+ 0x06BF=uint32,hex,flags,DFFOPT-WEBCOMP-FLAGS
+ # ink data
+ 0x073F=uint32,hex,flags,DFFOPT-INK-FLAGS
+ # signature line
+ 0x07BF=uint32,hex,flags,DFFOPT-SIGLINE-FLAGS
+ # group or shape #2
+end
+
+constlist=DFFOPT-COMPLEX-PROPERTIES
+ 0x0186=uint32,hex,blip,blip
+ 0x0187=uint32,hex,blip-name,string
+ 0x0197=uint32,hex,shade-colors,colorarray
+ 0x0380=uint32,hex,shape-name,string
+end
+
+# common
+
+combilist=DFFOPT-BLIPOPT
+ 0x00000003=uint8,dec,type,DFFOPT-BLIPOPT-TYPE
+ 0x00000004=do-not-save
+ 0x00000008=linked
+end
+
+shortlist=DFFOPT-BLIPOPT-TYPE,0,comment,file,url
+
+# transformation
+
+flagslist=DFFOPT-TRANSFORM-FLAGS
+ 0x0001=:flip-h
+ 0x0002=:flip-v
+end
+
+# protection
+
+flagslist=DFFOPT-PROTECTION-FLAGS
+ 0x0001=:lock-against-grouping
+ 0x0002=:lock-adjust-handles
+ 0x0004=:lock-text
+ 0x0008=:lock-vertices
+ 0x0010=:lock-cropping
+ 0x0020=:lock-against-select
+ 0x0040=:lock-position
+ 0x0080=:lock-aspect-ratio
+ 0x0100=:lock-rotation
+ 0x0200=:lock-against-ungrouping
+end
+
+# text
+
+flagslist=DFFOPT-TEXT-FLAGS
+ 0x0002=:fit-shape-to-text
+ 0x0008=:auto-text-margin
+ 0x0010=:select-text
+ ignore=0x0005
+end
+
+# text geometry
+
+flagslist=DFFOPT-TEXTGEO-FLAGS
+ 0x0001=:strike-through
+ 0x0002=:small-caps
+ 0x0004=:shadow
+ 0x0008=:underline
+ 0x0010=:italic
+ 0x0020=:bold
+ 0x0040=:no-measure-along-path
+ 0x0080=:normalize
+ 0x0100=:best-fit
+ 0x0200=:shrink-to-fit
+ 0x0400=:stretch-to-fit
+ 0x0800=:tightening
+ 0x1000=:kerning
+ 0x2000=:vertical
+ 0x4000=:has-effect
+ 0x8000=:reverse-rows
+end
+
+# picture (BLIP)
+
+flagslist=DFFOPT-BLIP-FLAGS
+ 0x0001=:ole-alive
+ 0x0002=:bi-level-display
+ 0x0004=:grayscale
+ 0x0008=:no-hit-test
+ 0x0010=:loop-anim
+ 0x0020=:rewind-anim
+ 0x0040=:preserve-gray
+end
+
+# shape geometry
+
+flagslist=DFFOPT-GEO-FLAGS
+ 0x0001=:fill-support
+ 0x0002=:fill-shade-shape-support
+ 0x0004=:fontwork-support
+ 0x0008=:line-support
+ 0x0010=:3d-support
+ 0x0020=:shadow-support
+end
+
+# fill style
+
+shortlist=DFFOPT-FILL-TYPE,0,solid,pattern,texture,picture,edge-shade,linear-shade,shape-shade,point-shade,title-shade,background
+
+combilist=DFFOPT-FILL-DZTYPE
+ 0x00000003=uint8,dec,unit,DFFOPT-FILL-DZTYPE-UNIT
+ 0x0000000C=uint8,dec,aspect,DFFOPT-FILL-DZTYPE-ASPECT
+end
+
+shortlist=DFFOPT-FILL-DZTYPE-UNIT,0,unused,emu,pixel,shape-size-rel
+shortlist=DFFOPT-FILL-DZTYPE-ASPECT,0,none,fixed,prefer-largest
+
+flagslist=DFFOPT-FILL-SHADETYPE
+ 0x00000001=none
+ 0x00000002=gamma
+ 0x00000004=sigma-transfer
+ 0x00000008=flat-band
+ 0x00000010=one-color
+end
+
+flagslist=DFFOPT-FILL-FLAGS
+ 0x0001=:no-fill-hit-test
+ 0x0002=:fill-to-rect
+ 0x0004=:fill-rel-to-shape
+ 0x0008=:hit-test-fill
+ 0x0010=:has-fill
+ 0x0020=:shape-anchor
+ 0x0040=:recolor-as-pic
+end
+
+# line style
+
+flagslist=DFFOPT-LINE-FLAGS
+ 0x0001=:draw-dash-for-invisible
+ 0x0002=:fill-rel-to-shape
+ 0x0004=:hit-test-line
+ 0x0008=:has-line
+ 0x0010=:arrowhead-support
+ 0x0020=:inset-pen-support
+ 0x0040=:inset-pen
+ 0x0200=:opaque-back-line
+end
+
+# shadow style
+
+flagslist=DFFOPT-SHADOW-FLAGS
+ 0x0001=:obscured-shadow
+ 0x0002=:has-shadow
+end
+
+# perspective
+
+flagslist=DFFOPT-PERSP-FLAGS
+ 0x0001=:has-perspective
+end
+
+# 3d object
+
+flagslist=DFFOPT-3DOBJ-FLAGS
+ 0x0001=:light-face
+ 0x0002=:extrusion-color
+ 0x0004=:metallic
+ 0x0008=:has-3d
+end
+
+# 3d style
+
+flagslist=DFFOPT-3DSTYLE-FLAGS
+ 0x0001=:fill-color-harsh
+ 0x0002=:key-color-harsh
+ 0x0004=:parallel
+ 0x0008=:rotation-center-auto
+ 0x0010=:constrain-rotation
+end
+
+# shape
+
+flagslist=DFFOPT-SHAPE-FLAGS
+ 0x0001=:background
+ 0x0004=:initiator
+ 0x0008=:lock-shape-type
+ 0x0010=:prefer-rel-resize
+ 0x0020=:ole-iconified
+ 0x0040=:flip-v-override
+ 0x0080=:flip-h-override
+ 0x0100=:policy-barcode
+ 0x0200=:policy-label
+end
+
+# callout
+
+flagslist=DFFOPT-CALLOUT-FLAGS
+ 0x0001=:length-specified
+ 0x0002=:drop-auto
+ 0x0004=:minus-y
+ 0x0008=:minus-x
+ 0x0010=:has-text-border
+ 0x0020=:has-accent-bar
+ 0x0040=:is-callout
+end
+
+# group or shape
+
+flagslist=DFFOPT-GROUP-FLAGS
+ 0x0001=:print
+ 0x0002=:hidden
+ 0x0004=:1d-adjustment
+ 0x0008=:is-button
+ 0x0010=:notify-double-click
+ 0x0020=:behind-doc
+ 0x0040=:wrap-edited
+ 0x0080=:script-anchor
+ 0x0100=:really-hidden
+ 0x0200=:allow-overlap
+ 0x0400=:user-drawn
+ 0x0800=:is-hr
+ 0x1000=:no-shade-hr
+ 0x2000=:standard-hr
+ 0x4000=:is-bullet
+ 0x8000=:layout-in-cell
+end
+
+# unknown HTML
+
+flagslist=DFFOPT-UHTML-FLAGS
+ 0x0002=:fake-master
+ 0x0004=:ole-from-html
+end
+
+# diagram
+
+flagslist=DFFOPT-DIAGRAM-FLAGS
+ 0x0001=:pseudo-inline
+ 0x0002=:do-layout
+ 0x0004=:reverse
+ 0x0008=:do-format
+end
+
+# web component
+
+flagslist=DFFOPT-WEBCOMP-FLAGS
+ 0x0001=:is-web-component
+end
+
+# ink data
+
+flagslist=DFFOPT-INK-FLAGS
+ 0x0001=:render-ink
+ 0x0002=:render-shape
+ 0x0004=:hit-test-ink
+ 0x0008=:ink-annotation
+end
+
+# signature line
+
+flagslist=DFFOPT-SIGLINE-FLAGS
+ 0x0001=:is-signature-line
+ 0x0002=:show-sign-instruction
+ 0x0004=:show-sign-comment
+ 0x0008=:show-sign-date
+end
+
+# group or shape #2
+
+# DFFSP ----------------------------------------------------------------------
+
+combilist=DFFSP-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,shape-type,DFFSP-TYPE
+end
+
+multilist=DFFSP-TYPE
+ 0=not-primitive,rectangle,round-rectangle,ellipse,diamond,isoceles-triangle,right-triangle,parallelogram,trapezoid,hexagon
+ 10=octagon,plus,star,arrow,thick-arrow,home-plate,cube,balloon,seal,arc
+ 20=line,plaque,can,donut,text-simple,text-octagon,text-hexagon,text-curve,text-wave,text-ring
+ 30=text-on-curve,text-on-ring,straight-connector-1,bent-connector-2,bent-connector-3,bent-connector-4,bent-connector-5,curved-connector-2,curved-connector-3,curved-connector-4
+ 40=curved-connector-5,callout-1,callout-2,callout-3,accent-callout-1,accent-callout-2,accent-callout-3,border-callout-1,border-callout-2,border-callout-3
+ 50=accent-border-callout-1,accent-border-callout-2,accent-border-callout-3,ribbon,ribbon-2,chevron,pentagon,no-smoking,seal-8,seal-16
+ 60=seal-32,wedge-rect-callout,wedge-rrect-callout,wedge-ellipse-callout,wave,folded-corner,left-arrow,down-arrow,up-arrow,left-right-arrow
+ 70=up-down-arrow,irregular-seal-1,irregular-seal-2,lightning-bolt,heart,picture-frame,quad-arrow,left-arrow-callout,right-arrow-callout,up-arrow-callout
+ 80=down-arrow-callout,left-right-arrow-callout,up-down-arrow-callout,quad-arrow-callout,bevel,left-bracket,right-bracket,left-brace,right-brace,left-up-arrow
+ 90=bent-up-arrow,bent-arrow,seal-24,striped-right-arrow,notched-right-arrow,block-arc,smiley-face,vertical-scroll,horizontal-scroll,circular-arrow
+ 100=notched-circular-arrow,uturn-arrow,curved-right-arrow,curved-left-arrow,curved-up-arrow,curved-down-arrow,cloud-callout,ellipse-ribbon,ellipse-ribbon-2,flow-chart-process
+ 110=flow-chart-decision,flow-chart-input-output,flow-chart-predefined-process,flow-chart-internal-storage,flow-chart-document,flow-chart-multidocument,flow-chart-terminator,flow-chart-preparation,flow-chart-manual-input,flow-chart-manual-operation
+ 120=flow-chart-connector,flow-chart-punched-card,flow-chart-punched-tape,flow-chart-summing-junction,flow-chart-or,flow-chart-collate,flow-chart-sort,flow-chart-extract,flow-chart-merge,flow-chart-offline-storage
+ 130=flow-chart-online-storage,flow-chart-magnetic-tape,flow-chart-magnetic-disk,flow-chart-magnetic-drum,flow-chart-display,flow-chart-delay,text-plain-text,text-stop,text-triangle,text-triangle-inverted
+ 140=text-chevron,text-chevron-inverted,text-ring-inside,text-ring-outside,text-arch-up-curve,text-arch-down-curve,text-circle-curve,text-button-curve,text-arch-up-pour,text-arch-down-pour
+ 150=text-circle-pour,text-button-pour,text-curve-up,text-curve-down,text-cascade-up,text-cascade-down,text-wave-1,text-wave-2,text-wave-3,text-wave-4
+ 160=text-inflate,text-deflate,text-inflate-bottom,text-deflate-bottom,text-inflate-top,text-deflate-top,text-deflate-inflate,text-deflate-inflate-deflate,text-fade-right,text-fade-left
+ 170=text-fade-up,text-fade-down,text-slant-up,text-slant-down,text-can-up,text-can-down,flow-chart-alternate-process,flow-chart-offpage-connector,callout-90,accent-callout-90
+ 180=border-callout-90,accent-border-callout-90,left-right-up-arrow,sun,moon,bracket-pair,brace-pair,seal-4,double-wave,action-button-blank
+ 190=action-button-home,action-button-help,action-button-information,action-button-forward-next,action-button-back-previous,action-button-end,action-button-beginning,action-button-return,action-button-document,action-button-sound
+ 200=action-button-movie,host-control,text-box
+end
+
+flagslist=DFFSP-FLAGS
+ 0x00000001=group
+ 0x00000002=child
+ 0x00000004=patriarch
+ 0x00000008=deleted
+ 0x00000010=ole
+ 0x00000020=has-master
+ 0x00000040=flip-horizontal
+ 0x00000080=flip-vertical
+ 0x00000100=connector
+ 0x00000200=has-anchor
+ 0x00000400=background
+ 0x00000800=has-shape-type
+end
+
+# DFFSPLITMENUCOLORS ---------------------------------------------------------
+
+combilist=DFFSPLITMENUC-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,color-count
+end
+
+# ============================================================================
diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx
new file mode 100644
index 000000000000..f7c6c6102b1d
--- /dev/null
+++ b/oox/source/dump/dumperbase.cxx
@@ -0,0 +1,3217 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/dump/dumperbase.hxx"
+
+#include <algorithm>
+#include <com/sun/star/lang/XMultiServiceFactory.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 <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <comphelper/docpasswordhelper.hxx>
+#include <osl/file.hxx>
+#include <rtl/math.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/helper/textinputstream.hxx"
+#include "oox/xls/biffhelper.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::comphelper::MediaDescriptor;
+using ::oox::core::FilterBase;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OUStringToOString;
+
+// ============================================================================
+
+namespace {
+
+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_Int64 OOX_DUMP_MAXARRAY = 16;
+
+} // namespace
+
+// ============================================================================
+// ============================================================================
+
+// 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);
+}
+
+OUString InputOutputHelper::getFileNameExtension( const OUString& rFileUrl )
+{
+ sal_Int32 nNamePos = getFileNamePos( rFileUrl );
+ sal_Int32 nExtPos = rFileUrl.lastIndexOf( '.' );
+ if( nExtPos >= nNamePos )
+ return rFileUrl.copy( nExtPos + 1 );
+ return OUString();
+}
+
+// input streams --------------------------------------------------------------
+
+Reference< XInputStream > InputOutputHelper::getXInputStream( BinaryInputStream& rStrm )
+{
+ if( BinaryXInputStream* pXStrm = dynamic_cast< BinaryXInputStream* >( &rStrm ) )
+ return pXStrm->getXInputStream();
+ return 0;
+}
+
+Reference< XInputStream > InputOutputHelper::openInputStream(
+ const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName )
+{
+ Reference< XInputStream > xInStrm;
+ if( rxFactory.is() ) try
+ {
+ Reference< XSimpleFileAccess > xFileAccess( rxFactory->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< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rEncoding )
+{
+ Reference< XTextInputStream > xTextInStrm;
+ if( rxFactory.is() && rxInStrm.is() ) try
+ {
+ Reference< XActiveDataSink > xDataSink( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW );
+ xDataSink->setInputStream( rxInStrm );
+ xTextInStrm.set( xDataSink, UNO_QUERY_THROW );
+ xTextInStrm->setEncoding( rEncoding );
+ }
+ catch( Exception& )
+ {
+ }
+ return xTextInStrm;
+}
+
+Reference< XTextInputStream > InputOutputHelper::openTextInputStream(
+ const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding )
+{
+ return openTextInputStream( rxFactory, openInputStream( rxFactory, rFileName ), rEncoding );
+}
+
+// output streams -------------------------------------------------------------
+
+Reference< XOutputStream > InputOutputHelper::openOutputStream(
+ const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName )
+{
+ Reference< XOutputStream > xOutStrm;
+ if( rxFactory.is() ) try
+ {
+ Reference< XSimpleFileAccess > xFileAccess( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
+ xOutStrm = xFileAccess->openFileWrite( rFileName );
+ }
+ catch( Exception& )
+ {
+ }
+ return xOutStrm;
+}
+
+Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream(
+ const Reference< XMultiServiceFactory >& rxFactory, const Reference< XOutputStream >& rxOutStrm, const OUString& rEncoding )
+{
+ Reference< XTextOutputStream > xTextOutStrm;
+ if( rxFactory.is() && rxOutStrm.is() ) try
+ {
+ Reference< XActiveDataSource > xDataSource( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW );
+ xDataSource->setOutputStream( rxOutStrm );
+ xTextOutStrm.set( xDataSource, UNO_QUERY_THROW );
+ xTextOutStrm->setEncoding( rEncoding );
+ }
+ catch( Exception& )
+ {
+ }
+ return xTextOutStrm;
+}
+
+Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream(
+ const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding )
+{
+ return openTextOutputStream( rxFactory, openOutputStream( rxFactory, 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( 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 )
+{
+ appendHex( rStr, nData, bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
+{
+ appendHex( rStr, nData, bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
+{
+ if( nData > SAL_MAX_UINT8 )
+ appendHex( rStr, nData, bPrefix );
+ else
+ appendHex( 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 > SAL_MAX_UINT16 )
+ 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 > SAL_MAX_UINT32 )
+ 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 );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, double fData, bool bPrefix )
+{
+ appendHex( rStr, fData, 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 );
+}
+
+OUString StringHelper::trimTrailingNul( const OUString& rStr )
+{
+ sal_Int32 nLastPos = rStr.getLength() - 1;
+ if( (nLastPos >= 0) && (rStr[ nLastPos ] == 0) )
+ return rStr.copy( 0, nLastPos );
+ return rStr;
+}
+
+OString StringHelper::convertToUtf8( const OUString& rStr )
+{
+ return 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( "shorthex" ) )
+ eType = FORMATTYPE_SHORTHEX;
+ 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);
+}
+
+OUStringPair StringHelper::convertStringToPair( const OUString& rString, sal_Unicode cSep )
+{
+ OUStringPair aPair;
+ if( rString.getLength() > 0 )
+ {
+ sal_Int32 nEqPos = rString.indexOf( cSep );
+ if( nEqPos < 0 )
+ {
+ aPair.first = rString;
+ }
+ else
+ {
+ aPair.first = StringHelper::trimSpaces( rString.copy( 0, nEqPos ) );
+ aPair.second = StringHelper::trimSpaces( rString.copy( nEqPos + 1 ) );
+ }
+ }
+ return aPair;
+}
+
+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 String& rOp, const OUString& rTokClass )
+{
+ maFmlaStack.push( rOp );
+ maClassStack.push( rTokClass );
+}
+
+void FormulaStack::pushOperand( const String& rOp )
+{
+ pushOperand( rOp, OUString( OOX_DUMP_BASECLASS ) );
+}
+
+void FormulaStack::pushUnaryOp( const String& rLOp, const String& rROp )
+{
+ pushUnaryOp( maFmlaStack, rLOp, rROp );
+ pushUnaryOp( maClassStack, rLOp, rROp );
+}
+
+void FormulaStack::pushBinaryOp( const String& rOp )
+{
+ pushBinaryOp( maFmlaStack, rOp );
+ pushBinaryOp( maClassStack, rOp );
+}
+
+void FormulaStack::pushFuncOp( const String& rFunc, const OUString& rTokClass, sal_uInt8 nParamCount )
+{
+ pushFuncOp( maFmlaStack, rFunc, 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( TextInputStream& rStrm )
+{
+ readConfigBlockContents( rStrm );
+}
+
+void ConfigItemBase::implProcessConfigItemStr(
+ TextInputStream& /*rStrm*/, const OUString& /*rKey*/, const OUString& /*rData*/ )
+{
+}
+
+void ConfigItemBase::implProcessConfigItemInt(
+ TextInputStream& /*rStrm*/, sal_Int64 /*nKey*/, const OUString& /*rData*/ )
+{
+}
+
+void ConfigItemBase::readConfigBlockContents( TextInputStream& rStrm )
+{
+ bool bLoop = true;
+ while( bLoop && !rStrm.isEof() )
+ {
+ OUString aKey, aData;
+ switch( readConfigLine( rStrm, aKey, aData ) )
+ {
+ case LINETYPE_DATA:
+ processConfigItem( rStrm, aKey, aData );
+ break;
+ case LINETYPE_END:
+ bLoop = false;
+ break;
+ }
+ }
+}
+
+ConfigItemBase::LineType ConfigItemBase::readConfigLine(
+ TextInputStream& rStrm, OUString& orKey, OUString& orData ) const
+{
+ OUString aLine;
+ while( !rStrm.isEof() && (aLine.getLength() == 0) )
+ {
+ aLine = rStrm.readLine();
+ 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();
+ }
+ }
+
+ OUStringPair aPair = StringHelper::convertStringToPair( aLine );
+ orKey = aPair.first;
+ orData = aPair.second;
+ return ((orKey.getLength() > 0) && ((orData.getLength() > 0) || !orKey.equalsAscii( "end" ))) ?
+ LINETYPE_DATA : LINETYPE_END;
+}
+
+ConfigItemBase::LineType ConfigItemBase::readConfigLine( TextInputStream& rStrm ) const
+{
+ OUString aKey, aData;
+ return readConfigLine( rStrm, aKey, aData );
+}
+
+void ConfigItemBase::processConfigItem(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ sal_Int64 nKey;
+ if( StringHelper::convertStringToInt( nKey, rKey ) )
+ implProcessConfigItemInt( rStrm, nKey, rData );
+ else
+ implProcessConfigItemStr( rStrm, rKey, rData );
+}
+
+// ============================================================================
+
+NameListBase::~NameListBase()
+{
+}
+
+void NameListBase::setName( sal_Int64 nKey, const String& rName )
+{
+ implSetName( nKey, rName );
+}
+
+void NameListBase::includeList( const NameListRef& rxList )
+{
+ if( rxList.get() )
+ {
+ for( const_iterator aIt = rxList->begin(), aEnd = rxList->end(); aIt != aEnd; ++aIt )
+ maMap[ aIt->first ] = aIt->second;
+ implIncludeList( *rxList );
+ }
+}
+
+bool NameListBase::implIsValid() const
+{
+ return true;
+}
+
+void NameListBase::implProcessConfigItemStr(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "include" ) )
+ include( rData );
+ else if( rKey.equalsAscii( "exclude" ) )
+ exclude( rData );
+ else
+ ConfigItemBase::implProcessConfigItemStr( rStrm, rKey, rData );
+}
+
+void NameListBase::implProcessConfigItemInt(
+ TextInputStream& /*rStrm*/, 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 );
+}
+
+// ============================================================================
+
+void ItemFormatMap::insertFormats( const NameListRef& rxNameList )
+{
+ if( Base::isValid( rxNameList ) )
+ for( NameListBase::const_iterator aIt = rxNameList->begin(), aEnd = rxNameList->end(); aIt != aEnd; ++aIt )
+ (*this)[ aIt->first ].parse( aIt->second );
+}
+
+// ============================================================================
+
+ConstList::ConstList( const SharedConfigData& rCfgData ) :
+ NameListBase( rCfgData ),
+ maDefName( OOX_DUMP_ERR_NONAME ),
+ mbQuoteNames( false )
+{
+}
+
+void ConstList::implProcessConfigItemStr(
+ TextInputStream& rStrm, 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( rStrm, 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(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "ignore-empty" ) )
+ mbIgnoreEmpty = StringHelper::convertStringToBool( rData );
+ else
+ ConstList::implProcessConfigItemStr( rStrm, 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(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "ignore" ) )
+ {
+ sal_Int64 nIgnore;
+ if( StringHelper::convertStringToInt( nIgnore, rData ) )
+ setIgnoreFlags( nIgnore );
+ }
+ else
+ {
+ NameListBase::implProcessConfigItemStr( rStrm, rKey, rData );
+ }
+}
+
+void FlagsList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ if( (nKey != 0) && ((nKey & (nKey - 1)) == 0) ) // only a single bit set?
+ insertRawName( nKey, rName );
+}
+
+OUString FlagsList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
+{
+ sal_Int64 nFound = mnIgnore;
+ OUStringBuffer aName;
+ // add known flags
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ {
+ sal_Int64 nMask = aIt->first;
+ setFlag( nFound, nMask );
+ if( !getFlag( mnIgnore, nMask ) )
+ {
+ const OUString& rFlagName = aIt->second;
+ bool bOnOff = (rFlagName.getLength() > 0) && (rFlagName[ 0 ] == ':');
+ bool bFlag = getFlag( nKey, nMask );
+ if( bOnOff )
+ {
+ StringHelper::appendToken( aName, rFlagName.copy( 1 ) );
+ aName.appendAscii( bFlag ? ":on" : ":off" );
+ }
+ else
+ {
+ bool bNegated = (rFlagName.getLength() > 0) && (rFlagName[ 0 ] == '!');
+ sal_Int32 nBothSep = bNegated ? rFlagName.indexOf( '!', 1 ) : -1;
+ if( bFlag )
+ {
+ if( !bNegated )
+ StringHelper::appendToken( aName, rFlagName );
+ else if( nBothSep > 0 )
+ StringHelper::appendToken( aName, rFlagName.copy( nBothSep + 1 ) );
+ }
+ else if( bNegated )
+ {
+ if( nBothSep > 0 )
+ StringHelper::appendToken( aName, rFlagName.copy( 1, nBothSep - 1 ) );
+ else
+ StringHelper::appendToken( aName, rFlagName.copy( 1 ) );
+ }
+ }
+ }
+ }
+ // add unknown flags
+ setFlag( nKey, nFound, false );
+ if( nKey != 0 )
+ {
+ OUStringBuffer aUnknown( CREATE_OUSTRING( OOX_DUMP_UNKNOWN ) );
+ aUnknown.append( OOX_DUMP_ITEMSEP );
+ StringHelper::appendShortHex( aUnknown, nKey, 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;
+}
+
+// ============================================================================
+
+bool CombiList::ExtItemFormatKey::operator<( const ExtItemFormatKey& rRight ) const
+{
+ return (mnKey < rRight.mnKey) || ((mnKey == rRight.mnKey) && (maFilter < rRight.maFilter));
+}
+
+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?
+ {
+ typedef ::std::set< ExtItemFormatKey > ExtItemFormatKeySet;
+ ::std::set< ExtItemFormatKey > aItemKeys;
+ ExtItemFormat aItemFmt;
+ OUStringVector aRemain = aItemFmt.parse( rName );
+ for( OUStringVector::iterator aIt = aRemain.begin(), aEnd = aRemain.end(); aIt != aEnd; ++aIt )
+ {
+ OUStringPair aPair = StringHelper::convertStringToPair( *aIt );
+ if( aPair.first.equalsAscii( "noshift" ) )
+ {
+ aItemFmt.mbShiftValue = StringHelper::convertStringToBool( aPair.second );
+ }
+ else if( aPair.first.equalsAscii( "filter" ) )
+ {
+ OUStringPair aFilter = StringHelper::convertStringToPair( aPair.second, '~' );
+ ExtItemFormatKey aKey( nKey );
+ if( (aFilter.first.getLength() > 0) && StringHelper::convertStringToInt( aKey.maFilter.first, aFilter.first ) &&
+ (aFilter.second.getLength() > 0) && StringHelper::convertStringToInt( aKey.maFilter.second, aFilter.second ) )
+ {
+ if( aKey.maFilter.first == 0 )
+ aKey.maFilter.second = 0;
+ aItemKeys.insert( aKey );
+ }
+ }
+ }
+ if( aItemKeys.empty() )
+ aItemKeys.insert( ExtItemFormatKey( nKey ) );
+ for( ExtItemFormatKeySet::iterator aIt = aItemKeys.begin(), aEnd = aItemKeys.end(); aIt != aEnd; ++aIt )
+ maFmtMap[ *aIt ] = aItemFmt;
+ }
+ else
+ {
+ FlagsList::implSetName( nKey, rName );
+ }
+}
+
+OUString CombiList::implGetName( const Config& rCfg, sal_Int64 nKey ) const
+{
+ sal_Int64 nFound = 0;
+ OUStringBuffer aName;
+ // add known flag fields
+ for( ExtItemFormatMap::const_iterator aIt = maFmtMap.begin(), aEnd = maFmtMap.end(); aIt != aEnd; ++aIt )
+ {
+ const ExtItemFormatKey& rMapKey = aIt->first;
+ sal_Int64 nMask = rMapKey.mnKey;
+ if( (nMask != 0) && ((nKey & rMapKey.maFilter.first) == rMapKey.maFilter.second) )
+ {
+ const ExtItemFormat& rItemFmt = aIt->second;
+
+ sal_uInt64 nUFlags = static_cast< sal_uInt64 >( nKey );
+ 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( nKey, nFound, false );
+ StringHelper::appendToken( aName, FlagsList::implGetName( rCfg, nKey ) );
+ 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( maName ));
+}
+
+// ============================================================================
+// ============================================================================
+
+SharedConfigData::SharedConfigData( const OUString& rFileName,
+ const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg,
+ const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) :
+ mxFactory( rxFactory ),
+ mxRootStrg( rxRootStrg ),
+ maSysFileName( rSysFileName ),
+ mrMediaDesc( rMediaDesc ),
+ mbLoaded( false ),
+ mbPwCancelled( false )
+{
+ OUString aFileUrl = InputOutputHelper::convertFileNameToUrl( rFileName );
+ if( aFileUrl.getLength() > 0 )
+ {
+ sal_Int32 nNamePos = InputOutputHelper::getFileNamePos( aFileUrl );
+ maConfigPath = aFileUrl.copy( 0, nNamePos );
+ mbLoaded = readConfigFile( aFileUrl );
+ }
+}
+
+SharedConfigData::~SharedConfigData()
+{
+}
+
+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, const NameListRef& rxList )
+{
+ if( rListName.getLength() > 0 )
+ maNameLists[ rListName ] = rxList;
+}
+
+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;
+}
+
+Sequence< NamedValue > SharedConfigData::requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier )
+{
+ Sequence< NamedValue > aEncryptionData;
+ if( !mbPwCancelled )
+ {
+ ::std::vector< OUString > aDefaultPasswords;
+ aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
+ aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+ rVerifier, mrMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
+ mbPwCancelled = !aEncryptionData.hasElements();
+ }
+ return aEncryptionData;
+}
+
+bool SharedConfigData::implIsValid() const
+{
+ return mbLoaded && mxFactory.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0);
+}
+
+void SharedConfigData::implProcessConfigItemStr(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if( rKey.equalsAscii( "include-config-file" ) )
+ readConfigFile( maConfigPath + rData );
+ else if( rKey.equalsAscii( "constlist" ) )
+ readNameList< ConstList >( rStrm, rData );
+ else if( rKey.equalsAscii( "multilist" ) )
+ readNameList< MultiList >( rStrm, rData );
+ else if( rKey.equalsAscii( "flagslist" ) )
+ readNameList< FlagsList >( rStrm, rData );
+ else if( rKey.equalsAscii( "combilist" ) )
+ readNameList< CombiList >( rStrm, 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 = maConfigFiles.count( rFileUrl ) > 0;
+ if( !bLoaded )
+ {
+ Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxFactory, rFileUrl );
+ BinaryXInputStream aInStrm( xInStrm, true );
+ TextInputStream aTxtStrm( aInStrm, RTL_TEXTENCODING_UTF8 );
+ if( !aTxtStrm.isEof() )
+ {
+ maConfigFiles.insert( rFileUrl );
+ readConfigBlockContents( aTxtStrm );
+ 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 sal_Char* pcEnvVar, const FilterBase& rFilter )
+{
+ construct( pcEnvVar, rFilter );
+}
+
+Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
+{
+ construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName, rMediaDesc );
+}
+
+Config::~Config()
+{
+}
+
+void Config::construct( const Config& rParent )
+{
+ *this = rParent;
+}
+
+void Config::construct( const sal_Char* pcEnvVar, const FilterBase& rFilter )
+{
+ if( rFilter.getFileUrl().getLength() > 0 )
+ construct( pcEnvVar, rFilter.getServiceFactory(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() );
+}
+
+void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
+{
+ if( pcEnvVar && rxRootStrg.get() && (rSysFileName.getLength() > 0) )
+ if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) )
+ mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName, rMediaDesc ) );
+}
+
+void Config::setStringOption( const String& rKey, const String& rData )
+{
+ mxCfgData->setOption( rKey, rData );
+}
+
+const OUString& Config::getStringOption( const String& rKey, const OUString& rDefault ) const
+{
+ const OUString* pData = implGetOption( rKey );
+ return pData ? *pData : rDefault;
+}
+
+bool Config::getBoolOption( const String& rKey, bool bDefault ) const
+{
+ const OUString* pData = implGetOption( rKey );
+ 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 String& rListName, const NameListRef& rxList )
+{
+ mxCfgData->setNameList( rListName, rxList );
+}
+
+void Config::eraseNameList( const String& rListName )
+{
+ mxCfgData->eraseNameList( rListName );
+}
+
+NameListRef Config::getNameList( const String& rListName ) const
+{
+ return implGetNameList( rListName );
+}
+
+Sequence< NamedValue > Config::requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier )
+{
+ return mxCfgData->requestEncryptionData( rVerifier );
+}
+
+bool Config::isPasswordCancelled() const
+{
+ return mxCfgData->isPasswordCancelled();
+}
+
+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 );
+}
+
+// ============================================================================
+// ============================================================================
+
+Output::Output( const Reference< XTextOutputStream >& rxStrm )
+{
+ construct( rxStrm );
+}
+
+Output::Output( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName )
+{
+ construct( InputOutputHelper::openTextOutputStream( rxFactory, 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 String& rItemName )
+{
+ if( mnItemLevel == 0 )
+ {
+ if( (mnMultiLevel > 0) && (maLine.getLength() > 0) )
+ tab();
+ if( rItemName.has() )
+ {
+ writeItemName( rItemName );
+ 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::writeColorABGR( sal_Int32 nColor )
+{
+ writeChar( 'a' );
+ writeDec( static_cast< sal_uInt8 >( nColor >> 24 ) );
+ writeAscii( ",r" );
+ writeDec( static_cast< sal_uInt8 >( nColor ) );
+ writeAscii( ",g" );
+ writeDec( static_cast< sal_uInt8 >( nColor >> 8 ) );
+ writeAscii( ",b" );
+ writeDec( static_cast< sal_uInt8 >( nColor >> 16 ) );
+}
+
+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 );
+ newLine();
+ }
+}
+
+bool Output::implIsValid() const
+{
+ return mxStrm.is();
+}
+
+void Output::writeItemName( const String& rItemName )
+{
+ if( rItemName.has() && (rItemName[ 0 ] == '#') )
+ {
+ writeString( rItemName.copy( 1 ) );
+ StringHelper::appendIndex( maLine, mnItemIdx++ );
+ }
+ else
+ writeString( rItemName );
+}
+
+// ============================================================================
+
+StorageIterator::StorageIterator( const StorageRef& rxStrg ) :
+ mxStrg( rxStrg )
+{
+ 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());
+}
+
+// ============================================================================
+// ============================================================================
+
+ObjectBase::~ObjectBase()
+{
+}
+
+void ObjectBase::construct( const ConfigRef& rxConfig )
+{
+ mxConfig = rxConfig;
+}
+
+void ObjectBase::construct( const ObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+void ObjectBase::dump()
+{
+ if( isValid() )
+ implDump();
+}
+
+bool ObjectBase::implIsValid() const
+{
+ return isValid( mxConfig );
+}
+
+void ObjectBase::implDump()
+{
+}
+
+void ObjectBase::reconstructConfig( const ConfigRef& rxConfig )
+{
+ if( isValid( rxConfig ) )
+ mxConfig = rxConfig;
+}
+
+// ============================================================================
+// ============================================================================
+
+void StorageObjectBase::construct( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
+{
+ ObjectBase::construct( rParent );
+ mxStrg = rxStrg;
+ maSysPath = rSysPath;
+}
+
+void StorageObjectBase::construct( const ObjectBase& rParent )
+{
+ ObjectBase::construct( rParent );
+ if( ObjectBase::implIsValid() )
+ {
+ mxStrg = cfg().getRootStorage();
+ maSysPath = cfg().getSysFileName();
+ }
+}
+
+bool StorageObjectBase::implIsValid() const
+{
+ return mxStrg.get() && (maSysPath.getLength() > 0) && ObjectBase::implIsValid();
+}
+
+void StorageObjectBase::implDump()
+{
+ bool bIsStrg = mxStrg->isStorage();
+ bool bIsRoot = mxStrg->isRootStorage();
+ Reference< XInputStream > xBaseStrm;
+ if( !bIsStrg )
+ xBaseStrm = mxStrg->openInputStream( OUString() );
+
+ OUString aSysOutPath = maSysPath;
+ if( bIsRoot ) try
+ {
+ aSysOutPath += OOX_DUMP_DUMPEXT;
+ Reference< XSimpleFileAccess > xFileAccess( getFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
+ xFileAccess->kill( aSysOutPath );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( bIsStrg )
+ {
+ extractStorage( mxStrg, OUString(), aSysOutPath );
+ }
+ else if( xBaseStrm.is() )
+ {
+ BinaryInputStreamRef xInStrm( new BinaryXInputStream( xBaseStrm, false ) );
+ xInStrm->seekToStart();
+ implDumpBaseStream( xInStrm, aSysOutPath );
+ }
+}
+
+void StorageObjectBase::implDumpStream( const BinaryInputStreamRef&, const OUString&, const OUString&, const OUString& )
+{
+}
+
+void StorageObjectBase::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ extractStorage( rxStrg, rStrgPath, rSysPath );
+}
+
+void StorageObjectBase::implDumpBaseStream( const BinaryInputStreamRef&, const OUString& )
+{
+}
+
+void StorageObjectBase::addPreferredStream( const String& rStrmName )
+{
+ if( rStrmName.has() )
+ maPreferred.push_back( PreferredItem( rStrmName, false ) );
+}
+
+void StorageObjectBase::addPreferredStorage( const String& rStrgPath )
+{
+ if( rStrgPath.has() )
+ maPreferred.push_back( PreferredItem( rStrgPath, true ) );
+}
+
+OUString StorageObjectBase::getSysFileName( const OUString& rStrmName, const OUString& rSysOutPath )
+{
+ // encode all characters < 0x20
+ OUStringBuffer aBuffer;
+ StringHelper::appendEncString( aBuffer, rStrmName, false );
+
+ // replace all characters reserved in file system
+ OUString aFileName = aBuffer.makeStringAndClear();
+ static const sal_Unicode spcReserved[] = { '/', '\\', ':', '*', '?', '<', '>', '|' };
+ for( const sal_Unicode* pcChar = spcReserved; pcChar < STATIC_ARRAY_END( spcReserved ); ++pcChar )
+ aFileName = aFileName.replace( *pcChar, '_' );
+
+ // build full path
+ return rSysOutPath + OUString( sal_Unicode( '/' ) ) + aFileName;
+}
+
+void StorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ BinaryXInputStream aInStrm( rStrg.openInputStream( rStrmName ), true );
+ if( !aInStrm.isEof() )
+ {
+ BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getFactory(), rSysFileName ), true );
+ if( !aOutStrm.isEof() )
+ aInStrm.copyToStream( aOutStrm );
+ }
+ BinaryXInputStreamRef xDumpStrm( new BinaryXInputStream( InputOutputHelper::openInputStream( getFactory(), rSysFileName ), true ) );
+ if( !xDumpStrm->isEof() )
+ implDumpStream( xDumpStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+void StorageObjectBase::extractStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ // create directory in file system
+ ::osl::FileBase::RC eRes = ::osl::Directory::create( rSysPath );
+ if( (eRes != ::osl::FileBase::E_None) && (eRes != ::osl::FileBase::E_EXIST) )
+ return;
+
+ // process preferred storages and streams in root storage first
+ if( rStrgPath.getLength() == 0 )
+ for( PreferredItemVector::iterator aIt = maPreferred.begin(), aEnd = maPreferred.end(); aIt != aEnd; ++aIt )
+ extractItem( rxStrg, rStrgPath, aIt->maName, rSysPath, aIt->mbStorage, !aIt->mbStorage );
+
+ // process children of the storage
+ for( StorageIterator aIt( rxStrg ); aIt.isValid(); ++aIt )
+ {
+ // skip processed preferred items
+ OUString aItemName = aIt.getName();
+ bool bFound = false;
+ if( rStrgPath.getLength() == 0 )
+ for( PreferredItemVector::iterator aIIt = maPreferred.begin(), aIEnd = maPreferred.end(); !bFound && (aIIt != aIEnd); ++aIIt )
+ bFound = aIIt->maName == aItemName;
+ if( !bFound )
+ extractItem( rxStrg, rStrgPath, aItemName, rSysPath, aIt.isStorage(), aIt.isStream() );
+ }
+}
+
+void StorageObjectBase::extractItem( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rItemName, const OUString& rSysPath, bool bIsStrg, bool bIsStrm )
+{
+ OUString aSysFileName = getSysFileName( rItemName, rSysPath );
+ if( bIsStrg )
+ {
+ OUStringBuffer aStrgPath( rStrgPath );
+ StringHelper::appendToken( aStrgPath, rItemName, '/' );
+ implDumpStorage( rxStrg->openSubStorage( rItemName, false ), aStrgPath.makeStringAndClear(), aSysFileName );
+ }
+ else if( bIsStrm )
+ {
+ extractStream( *rxStrg, rStrgPath, rItemName, aSysFileName );
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+OutputObjectBase::~OutputObjectBase()
+{
+}
+
+void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rSysFileName )
+{
+ ObjectBase::construct( rParent );
+ if( ObjectBase::implIsValid() )
+ mxOut.reset( new Output( getFactory(), rSysFileName + OOX_DUMP_DUMPEXT ) );
+}
+
+void OutputObjectBase::construct( const ObjectBase& rParent, const OutputRef& rxOut )
+{
+ ObjectBase::construct( rParent );
+ mxOut = rxOut;
+}
+
+void OutputObjectBase::construct( const OutputObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool OutputObjectBase::implIsValid() const
+{
+ return isValid( mxOut ) && ObjectBase::implIsValid();
+}
+
+void OutputObjectBase::writeEmptyItem( const String& rName )
+{
+ ItemGuard aItem( mxOut, rName );
+}
+
+void OutputObjectBase::writeInfoItem( const String& rName, const String& rData )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeString( rData );
+}
+
+void OutputObjectBase::writeCharItem( const String& rName, sal_Unicode cData )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+ mxOut->writeChar( cData );
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+}
+
+void OutputObjectBase::writeStringItem( const String& rName, const OUString& rData )
+{
+ ItemGuard aItem( mxOut, rName );
+ 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 String& rName, const sal_uInt8* pnData, sal_Size nSize, sal_Unicode cSep )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeArray( pnData, nSize, cSep );
+}
+
+void OutputObjectBase::writeBoolItem( const String& rName, bool bData )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeBool( bData );
+}
+
+double OutputObjectBase::writeRkItem( const String& rName, sal_Int32 nRk )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeHexItem( rName, static_cast< sal_uInt32 >( nRk ), "RK-FLAGS" );
+ double fValue = ::oox::xls::BiffHelper::calcDoubleFromRk( nRk );
+ writeDecItem( "decoded", fValue );
+ return fValue;
+}
+
+void OutputObjectBase::writeColorABGRItem( const String& rName, sal_Int32 nColor )
+{
+ ItemGuard aItem( mxOut, rName );
+ writeHexItem( rName, nColor );
+ mxOut->writeColorABGR( nColor );
+}
+
+void OutputObjectBase::writeDateTimeItem( const String& rName, const DateTime& rDateTime )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeDateTime( rDateTime );
+}
+
+void OutputObjectBase::writeGuidItem( const String& rName, const OUString& rGuid )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeString( rGuid );
+ aItem.cont();
+ mxOut->writeString( cfg().getStringOption( rGuid, OUString() ) );
+}
+
+void OutputObjectBase::writeColIndexItem( const String& rName, sal_Int32 nCol )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeDec( nCol );
+ aItem.cont();
+ mxOut->writeColIndex( nCol );
+}
+
+void OutputObjectBase::writeRowIndexItem( const String& rName, sal_Int32 nRow )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeDec( nRow );
+ aItem.cont();
+ mxOut->writeRowIndex( nRow );
+}
+
+void OutputObjectBase::writeColRangeItem( const String& rName, sal_Int32 nCol1, sal_Int32 nCol2 )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeColRowRange( nCol1, nCol2 );
+ aItem.cont();
+ mxOut->writeColRange( nCol1, nCol2 );
+}
+
+void OutputObjectBase::writeRowRangeItem( const String& rName, sal_Int32 nRow1, sal_Int32 nRow2 )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeColRowRange( nRow1, nRow2 );
+ aItem.cont();
+ mxOut->writeRowRange( nRow1, nRow2 );
+}
+
+void OutputObjectBase::writeAddressItem( const String& rName, const Address& rPos )
+{
+ ItemGuard aItem( mxOut, rName );
+ StringHelper::appendAddress( mxOut->getLine(), rPos );
+}
+
+void OutputObjectBase::writeRangeItem( const String& rName, const Range& rRange )
+{
+ ItemGuard aItem( mxOut, rName );
+ StringHelper::appendRange( mxOut->getLine(), rRange );
+}
+
+void OutputObjectBase::writeRangeListItem( const String& rName, const RangeList& rRanges )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( rName );
+ writeDecItem( "count", static_cast< sal_uInt16 >( rRanges.size() ) );
+ ItemGuard aItem( mxOut, "ranges" );
+ StringHelper::appendRangeList( mxOut->getLine(), rRanges );
+}
+
+void OutputObjectBase::writeTokenAddressItem( const String& rName, const TokenAddress& rPos, bool bNameMode )
+{
+ ItemGuard aItem( mxOut, rName );
+ StringHelper::appendAddress( mxOut->getLine(), rPos, bNameMode );
+}
+
+void OutputObjectBase::writeTokenAddress3dItem( const String& rName, const OUString& rRef, const TokenAddress& rPos, bool bNameMode )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeString( rRef );
+ StringHelper::appendAddress( mxOut->getLine(), rPos, bNameMode );
+}
+
+void OutputObjectBase::writeTokenRangeItem( const String& rName, const TokenRange& rRange, bool bNameMode )
+{
+ ItemGuard aItem( mxOut, rName );
+ StringHelper::appendRange( mxOut->getLine(), rRange, bNameMode );
+}
+
+void OutputObjectBase::writeTokenRange3dItem( const String& rName, const OUString& rRef, const TokenRange& rRange, bool bNameMode )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeString( rRef );
+ StringHelper::appendRange( mxOut->getLine(), rRange, bNameMode );
+}
+
+// ============================================================================
+// ============================================================================
+
+InputObjectBase::~InputObjectBase()
+{
+}
+
+void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ OutputObjectBase::construct( rParent, rSysFileName );
+ mxStrm = rxStrm;
+}
+
+void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OutputRef& rxOut )
+{
+ OutputObjectBase::construct( rParent, rxOut );
+ mxStrm = rxStrm;
+}
+
+void InputObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
+{
+ OutputObjectBase::construct( rParent );
+ mxStrm = rxStrm;
+}
+
+void InputObjectBase::construct( const InputObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool InputObjectBase::implIsValid() const
+{
+ return mxStrm.get() && OutputObjectBase::implIsValid();
+}
+
+void InputObjectBase::skipBlock( sal_Int64 nBytes, bool bShowSize )
+{
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() );
+ if( mxStrm->tell() < nEndPos )
+ {
+ if( bShowSize )
+ writeDecItem( "skipped-data-size", static_cast< sal_uInt64 >( nEndPos - mxStrm->tell() ) );
+ mxStrm->seek( nEndPos );
+ }
+}
+
+void InputObjectBase::dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bStream )
+{
+ TableGuard aTabGuard( mxOut,
+ bShowOffset ? 12 : 0,
+ 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
+ 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
+ OOX_DUMP_BYTESPERLINE / 2 + 1 );
+
+ sal_Int64 nMaxShowSize = cfg().getIntOption< sal_Int64 >(
+ bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64 );
+
+ bool bSeekable = mxStrm->getLength() >= 0;
+ sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() ) : 0;
+ sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize;
+ sal_Int64 nPos = bSeekable ? mxStrm->tell() : 0;
+ bool bLoop = true;
+
+ while( bLoop && (nPos < nDumpEnd) )
+ {
+ mxOut->writeHex( static_cast< sal_uInt32 >( nPos ) );
+ mxOut->tab();
+
+ sal_uInt8 pnLineData[ OOX_DUMP_BYTESPERLINE ];
+ sal_Int32 nLineSize = bSeekable ? ::std::min( static_cast< sal_Int32 >( nDumpEnd - mxStrm->tell() ), OOX_DUMP_BYTESPERLINE ) : OOX_DUMP_BYTESPERLINE;
+ sal_Int32 nReadSize = mxStrm->readMemory( 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) ) mxOut->tab();
+ mxOut->writeHex( *pnByte, false );
+ mxOut->writeChar( ' ' );
+ }
+
+ aTabGuard.tab( 3 );
+ for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
+ {
+ if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) mxOut->tab();
+ mxOut->writeChar( static_cast< sal_Unicode >( (*pnByte < 0x20) ? '.' : *pnByte ) );
+ }
+ mxOut->newLine();
+ }
+ }
+
+ // skip undumped data
+ if( bSeekable )
+ skipBlock( nEndPos - mxStrm->tell() );
+}
+
+void InputObjectBase::dumpBinary( const String& rName, sal_Int64 nBytes, bool bShowOffset )
+{
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( rName );
+ writeDecItem( "size", nBytes );
+ }
+ IndentGuard aIndGuard( mxOut );
+ dumpRawBinary( nBytes, bShowOffset );
+}
+
+void InputObjectBase::dumpRemaining( sal_Int64 nBytes )
+{
+ if( nBytes > 0 )
+ {
+ if( cfg().getBoolOption( "show-trailing-unknown", true ) )
+ dumpBinary( "remaining-data", nBytes, false );
+ else
+ skipBlock( nBytes );
+ }
+}
+
+void InputObjectBase::dumpRemainingTo( sal_Int64 nPos )
+{
+ if( mxStrm->isEof() || (mxStrm->tell() > nPos) )
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+ else
+ dumpRemaining( nPos - mxStrm->tell() );
+ mxStrm->seek( nPos );
+}
+
+void InputObjectBase::dumpRemainingStream()
+{
+ dumpRemainingTo( mxStrm->getLength() );
+}
+
+void InputObjectBase::dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep )
+{
+ sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nBytes );
+ if( nDumpSize > OOX_DUMP_MAXARRAY )
+ {
+ dumpBinary( rName, nBytes, false );
+ }
+ else if( nDumpSize > 1 )
+ {
+ sal_uInt8 pnData[ OOX_DUMP_MAXARRAY ];
+ mxStrm->readMemory( pnData, nDumpSize );
+ writeArrayItem( rName, pnData, nDumpSize, cSep );
+ }
+ else if( nDumpSize == 1 )
+ dumpHex< sal_uInt8 >( rName );
+}
+
+sal_Unicode InputObjectBase::dumpChar( const String& rName, rtl_TextEncoding eTextEnc )
+{
+ sal_uInt8 nChar;
+ *mxStrm >> nChar;
+ OUString aChar = OStringToOUString( OString( static_cast< sal_Char >( nChar ) ), eTextEnc );
+ sal_Unicode cChar = (aChar.getLength() > 0) ? aChar[ 0 ] : 0;
+ writeCharItem( rName( "char" ), cChar );
+ return cChar;
+}
+
+sal_Unicode InputObjectBase::dumpUnicode( const String& rName )
+{
+ sal_uInt16 nChar;
+ *mxStrm >> nChar;
+ sal_Unicode cChar = static_cast< sal_Unicode >( nChar );
+ writeCharItem( rName( "char" ), cChar );
+ return cChar;
+}
+
+OUString InputObjectBase::dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul )
+{
+ sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nLen );
+ OUString aString;
+ if( nDumpSize > 0 )
+ {
+ ::std::vector< sal_Char > aBuffer( static_cast< sal_Size >( nLen ) + 1 );
+ sal_Int32 nCharsRead = mxStrm->readMemory( &aBuffer.front(), nLen );
+ aBuffer[ nCharsRead ] = 0;
+ aString = OStringToOUString( OString( &aBuffer.front() ), eTextEnc );
+ }
+ if( bHideTrailingNul )
+ aString = StringHelper::trimTrailingNul( aString );
+ writeStringItem( rName( "text" ), aString );
+ return aString;
+}
+
+OUString InputObjectBase::dumpUnicodeArray( const String& rName, sal_Int32 nLen, bool bHideTrailingNul )
+{
+ OUStringBuffer aBuffer;
+ for( sal_Int32 nIndex = 0; !mxStrm->isEof() && (nIndex < nLen); ++nIndex )
+ aBuffer.append( static_cast< sal_Unicode >( mxStrm->readuInt16() ) );
+ OUString aString = aBuffer.makeStringAndClear();
+ if( bHideTrailingNul )
+ aString = StringHelper::trimTrailingNul( aString );
+ writeStringItem( rName( "text" ), aString );
+ return aString;
+}
+
+OUString InputObjectBase::dumpNullCharArray( const String& rName, rtl_TextEncoding eTextEnc )
+{
+ OStringBuffer aBuffer;
+ sal_uInt8 nChar;
+ for( *mxStrm >> nChar; !mxStrm->isEof() && (nChar > 0); *mxStrm >> nChar )
+ aBuffer.append( static_cast< sal_Char >( nChar ) );
+ OUString aString = OStringToOUString( aBuffer.makeStringAndClear(), eTextEnc );
+ writeStringItem( rName( "text" ), aString );
+ return aString;
+}
+
+OUString InputObjectBase::dumpNullUnicodeArray( const String& rName )
+{
+ OUStringBuffer aBuffer;
+ sal_uInt16 nChar;
+ for( *mxStrm >> nChar; !mxStrm->isEof() && (nChar > 0); *mxStrm >> nChar )
+ aBuffer.append( static_cast< sal_Unicode >( nChar ) );
+ OUString aString = aBuffer.makeStringAndClear();
+ writeStringItem( rName( "text" ), aString );
+ return aString;
+}
+
+double InputObjectBase::dumpRk( const String& rName )
+{
+ sal_Int32 nRk;
+ *mxStrm >> nRk;
+ return writeRkItem( rName( "rk-value" ), nRk );
+}
+
+sal_Int32 InputObjectBase::dumpColorABGR( const String& rName )
+{
+ sal_Int32 nColor;
+ *mxStrm >> nColor;
+ writeColorABGRItem( rName( "color" ), nColor );
+ return nColor;
+}
+
+DateTime InputObjectBase::dumpFileTime( const String& rName )
+{
+ DateTime aDateTime;
+
+ ItemGuard aItem( mxOut, rName( "file-time" ) );
+ sal_Int64 nFileTime = dumpDec< sal_Int64 >( EMPTY_STRING );
+ // 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 );
+
+ writeDateTimeItem( EMPTY_STRING, aDateTime );
+ return aDateTime;
+}
+
+OUString InputObjectBase::dumpGuid( const String& rName )
+{
+ OUStringBuffer aBuffer;
+ sal_uInt32 nData32;
+ sal_uInt16 nData16;
+ sal_uInt8 nData8;
+
+ *mxStrm >> nData32;
+ StringHelper::appendHex( aBuffer, nData32, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ *mxStrm >> nData16;
+ StringHelper::appendHex( aBuffer, nData16, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ *mxStrm >> nData16;
+ StringHelper::appendHex( aBuffer, nData16, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ *mxStrm >> nData8;
+ StringHelper::appendHex( aBuffer, nData8, false );
+ *mxStrm >> nData8;
+ StringHelper::appendHex( aBuffer, nData8, false );
+ aBuffer.append( sal_Unicode( '-' ) );
+ for( int nIndex = 0; nIndex < 6; ++nIndex )
+ {
+ *mxStrm >> nData8;
+ StringHelper::appendHex( aBuffer, nData8, false );
+ }
+ StringHelper::enclose( aBuffer, '{', '}' );
+ OUString aGuid = aBuffer.makeStringAndClear();
+ writeGuidItem( rName( "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:;
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+BinaryStreamObject::BinaryStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+BinaryStreamObject::BinaryStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
+{
+ InputObjectBase::construct( rParent, rxStrm );
+}
+
+void BinaryStreamObject::dumpBinaryStream( bool bShowOffset )
+{
+ mxStrm->seekToStart();
+ dumpRawBinary( mxStrm->getLength(), bShowOffset, true );
+ mxOut->emptyLine();
+}
+
+void BinaryStreamObject::implDump()
+{
+ dumpBinaryStream();
+}
+
+// ============================================================================
+
+TextStreamObject::TextStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+ if( rxStrm.get() )
+ mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) );
+}
+
+TextStreamObject::TextStreamObject( const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
+{
+ InputObjectBase::construct( rParent, rxStrm );
+ if( rxStrm.get() )
+ mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) );
+}
+
+bool TextStreamObject::implIsValid() const
+{
+ return InputObjectBase::implIsValid() && mxTextStrm.get();
+}
+
+void TextStreamObject::implDump()
+{
+ OUString aLine;
+ sal_uInt32 nLine = 0;
+ while( !mxTextStrm->isEof() )
+ {
+ aLine = mxTextStrm->readLine();
+ if( !mxTextStrm->isEof() )
+ implDumpLine( aLine, ++nLine );
+ }
+ mxOut->emptyLine();
+}
+
+void TextStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine )
+{
+ TableGuard aTabGuard( mxOut, 8 );
+ mxOut->writeDec( nLine, 6 );
+ mxOut->tab();
+ mxOut->writeString( rLine );
+ mxOut->newLine();
+}
+
+// ============================================================================
+
+XmlStreamObject::XmlStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) :
+ TextStreamObject( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName )
+{
+}
+
+void XmlStreamObject::implDump()
+{
+ maIncompleteLine = OUString();
+ TextStreamObject::implDump();
+ if( maIncompleteLine.getLength() > 0 )
+ {
+ mxOut->resetIndent();
+ mxOut->writeString( maIncompleteLine );
+ mxOut->emptyLine();
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+ }
+}
+
+void XmlStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 )
+{
+ // build input line from cached incomplete element and new text data
+ OUStringBuffer aLine;
+ if( maIncompleteLine.getLength() > 0 )
+ aLine.append( maIncompleteLine ).append( sal_Unicode( ' ' ) );
+ aLine.append( rLine );
+ maIncompleteLine = OUString();
+
+ if( aLine.getLength() == 0 )
+ {
+ mxOut->newLine();
+ return;
+ }
+
+ const sal_Unicode* pcPos = aLine.getStr();
+ const sal_Unicode* pcEnd = pcPos + aLine.getLength();
+ while( pcPos < pcEnd )
+ {
+ OUStringBuffer aOutLine;
+ bool bIsStartElement = false;
+ bool bIsComplElement = false;
+ bool bIsEndElement = false;
+
+ /* check for start element at beginning of the line - pcEnd and thus (pcPos+1)
+ are dereferenceable, because OUStringBuffer::getStr is null-terminated. */
+ if( (*pcPos == '<') && (pcPos[ 1 ] != '/') )
+ {
+ const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' );
+ if( pcElementEnd == pcEnd )
+ {
+ // incomplete start element
+ maIncompleteLine = OUString( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) );
+ pcPos = pcEnd;
+ }
+ else
+ {
+ bIsComplElement = (pcPos[ 1 ] == '?') || (pcPos[ 1 ] == '!') || (pcElementEnd[ -1 ] == '/');
+ bIsStartElement = !bIsComplElement;
+ ++pcElementEnd;
+ aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) );
+ pcPos = pcElementEnd;
+ }
+ }
+
+ // check for following element text
+ if( !bIsComplElement && (pcPos < pcEnd) )
+ {
+ const sal_Unicode* pcElementStart = ::std::find( pcPos, pcEnd, '<' );
+ // append text between elements
+ if( pcPos < pcElementStart )
+ {
+ OUString aText( pcPos, static_cast< sal_Int32 >( pcElementStart - pcPos ) );
+ if( aText.trim().getLength() > 0 )
+ aOutLine.append( aText );
+ pcPos = pcElementStart;
+ }
+ }
+
+ // check for stand-alone or following end element
+ if( !bIsComplElement && (pcPos < pcEnd) && (pcPos[ 1 ] == '/') )
+ {
+ const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' );
+ if( pcElementEnd == pcEnd )
+ {
+ // incomplete end element
+ aOutLine.append( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) );
+ maIncompleteLine = aOutLine.makeStringAndClear();
+ pcPos = pcEnd;
+ }
+ else
+ {
+ bIsEndElement = true;
+ ++pcElementEnd;
+ aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) );
+ pcPos = pcElementEnd;
+ }
+ }
+
+ // flush output line
+ if( maIncompleteLine.getLength() == 0 )
+ {
+ if( !bIsStartElement && bIsEndElement ) mxOut->decIndent();
+ mxOut->writeString( aOutLine.makeStringAndClear() );
+ mxOut->newLine();
+ if( bIsStartElement && !bIsEndElement ) mxOut->incIndent();
+ }
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+void RecordObjectBase::construct( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm, const OUString& rSysFileName,
+ const BinaryInputStreamRef& rxRecStrm, const String& rRecNames, const String& rSimpleRecs )
+{
+ InputObjectBase::construct( rParent, rxRecStrm, rSysFileName );
+ constructRecObjBase( rxBaseStrm, rRecNames, rSimpleRecs );
+}
+
+void RecordObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxBaseStrm,
+ const BinaryInputStreamRef& rxRecStrm, const String& rRecNames, const String& rSimpleRecs )
+{
+ InputObjectBase::construct( rParent, rxRecStrm );
+ constructRecObjBase( rxBaseStrm, rRecNames, rSimpleRecs );
+}
+
+bool RecordObjectBase::implIsValid() const
+{
+ return mxBaseStrm.get() && InputObjectBase::implIsValid();
+}
+
+void RecordObjectBase::implDump()
+{
+ NameListRef xRecNames = getRecNames();
+ ItemFormatMap aSimpleRecs( maSimpleRecs.getNameList( cfg() ) );
+
+ while( implStartRecord( *mxBaseStrm, mnRecPos, mnRecId, mnRecSize ) )
+ {
+ // record header
+ mxOut->emptyLine();
+ writeHeader();
+ implWriteExtHeader();
+ IndentGuard aIndGuard( mxOut );
+ sal_Int64 nRecPos = mxStrm->tell();
+
+ // record body
+ if( !mbBinaryOnly && cfg().hasName( xRecNames, mnRecId ) )
+ {
+ ItemFormatMap::const_iterator aIt = aSimpleRecs.find( mnRecId );
+ if( aIt != aSimpleRecs.end() )
+ dumpItem( aIt->second );
+ else
+ implDumpRecordBody();
+ }
+
+ // remaining undumped data
+ if( !mxStrm->isEof() && (mxStrm->tell() == nRecPos) )
+ dumpRawBinary( mnRecSize, false );
+ else
+ dumpRemainingTo( nRecPos + mnRecSize );
+ }
+}
+
+void RecordObjectBase::implWriteExtHeader()
+{
+}
+
+void RecordObjectBase::implDumpRecordBody()
+{
+}
+
+void RecordObjectBase::constructRecObjBase( const BinaryInputStreamRef& rxBaseStrm, const String& rRecNames, const String& rSimpleRecs )
+{
+ mxBaseStrm = rxBaseStrm;
+ maRecNames = rRecNames;
+ maSimpleRecs = rSimpleRecs;
+ mnRecPos = mnRecId = mnRecSize = 0;
+ mbBinaryOnly = false;
+ if( InputObjectBase::implIsValid() )
+ mbShowRecPos = cfg().getBoolOption( "show-record-position", true );
+}
+
+void RecordObjectBase::writeHeader()
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "REC" );
+ if( mbShowRecPos && mxBaseStrm->isSeekable() )
+ writeShortHexItem( "pos", mnRecPos, "CONV-DEC" );
+ writeShortHexItem( "size", mnRecSize, "CONV-DEC" );
+ ItemGuard aItem( mxOut, "id" );
+ mxOut->writeShortHex( mnRecId );
+ addNameToItem( mnRecId, "CONV-DEC" );
+ addNameToItem( mnRecId, maRecNames );
+}
+
+// ============================================================================
+
+void SequenceRecordObjectBase::construct( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm, const ::rtl::OUString& rSysFileName,
+ const String& rRecNames, const String& rSimpleRecs )
+{
+ BinaryInputStreamRef xRecStrm( new SequenceInputStream( *mxRecData ) );
+ RecordObjectBase::construct( rParent, rxBaseStrm, rSysFileName, xRecStrm, rRecNames, rSimpleRecs );
+}
+
+void SequenceRecordObjectBase::construct( const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm, const String& rRecNames, const String& rSimpleRecs )
+{
+ BinaryInputStreamRef xRecStrm( new SequenceInputStream( *mxRecData ) );
+ RecordObjectBase::construct( rParent, rxBaseStrm, xRecStrm, rRecNames, rSimpleRecs );
+}
+
+bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ bool bValid = true;
+ if( rBaseStrm.isSeekable() )
+ {
+ ornRecPos = rBaseStrm.tell();
+ // do not try to overread seekable streams, may cause assertions
+ bValid = ornRecPos < rBaseStrm.getLength();
+ }
+
+ // read the record header
+ if( bValid )
+ bValid = implReadRecordHeader( rBaseStrm, ornRecId, ornRecSize ) && !rBaseStrm.isEof() && (0 <= ornRecSize) && (ornRecSize <= 0x00100000);
+
+ // read record contents into data sequence
+ if( bValid )
+ {
+ sal_Int32 nRecSize = static_cast< sal_Int32 >( ornRecSize );
+ mxRecData->realloc( nRecSize );
+ bValid = (nRecSize == 0) || (rBaseStrm.readData( *mxRecData, nRecSize ) == nRecSize);
+ mxStrm->seekToStart();
+ }
+ return bValid;
+}
+
+// ============================================================================
+// ============================================================================
+
+DumperBase::~DumperBase()
+{
+}
+
+bool DumperBase::isImportEnabled() const
+{
+ return !isValid() || cfg().isImportEnabled();
+}
+
+bool DumperBase::isImportCancelled() const
+{
+ return isValid() && cfg().isPasswordCancelled();
+}
+
+void DumperBase::construct( const ConfigRef& rxConfig )
+{
+ if( isValid( rxConfig ) && rxConfig->isDumperEnabled() )
+ ObjectBase::construct( rxConfig );
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
diff --git a/oox/source/dump/dumperbase.ini b/oox/source/dump/dumperbase.ini
new file mode 100644
index 000000000000..28aa59a03b81
--- /dev/null
+++ b/oox/source/dump/dumperbase.ini
@@ -0,0 +1,395 @@
+
+# dumper settings ============================================================
+#
+# Basic concepts
+#
+# - Character encoding of dumper ini files is UTF-8.
+# - Whitespace characters are generally stripped, e.g. at start and end of
+# lines, before/after equal signs, commas, etc.
+# - Comments start with the hash (#) or semicolon (;) character. Leading
+# whitespace characters are ignored.
+#
+# ----------------------------------------------------------------------------
+
+# Enable entire dumper (default=off). This option does not affect the option
+# 'enable-import'.
+# 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=65536
+
+# Maximum size of binary data blocks in content dumps (default=infinite).
+max-binary-data-size=128
+
+# Shows unknown trailing data as binary dump (default=on).
+# 0=off, 1=on
+show-trailing-unknown=1
+
+# Shows the absolute stream position of records in the record header field
+# (default=on).
+# 0=off, 1=on
+show-record-position=0
+
+# name lists =================================================================
+#
+# Syntax descriptions
+#
+# - Optional items are enclosed in brackets [].
+# - Optional items that may be repeated are marked with an ellipsis (...).
+# - Items in a set to choose from are separated by vertical lines (|).
+# - <LISTNAME> denotes the name of a list. List names may consist of any non-
+# whitespace characters.
+# - <value>, <firstvalue>, <bitfield>, <bitmask> etc. denote integer values.
+# Decimal and hexadecimal notation is supported, using C/C++ notation.
+# - <bool> denotes a boolean value. Possible values are 0|1|false|true.
+# - <constname> denotes a literal name for a constant or bit.
+#
+# ----------------------------------------------------------------------------
+#
+# constlist
+#
+# Defines names for a list of specific values.
+#
+# Syntax:
+#
+# constlist = <LISTNAME>
+# default = <constname>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <value>[,<value>...]
+# quote-names = <bool>
+# <value> = <constname>
+# end
+#
+# - default (optional): Declares <constname> as a default name for values not
+# specified in the name list. <constname> may be the empty string. If not
+# set, the literal string '?err:no-name' (unquoted) is the default name.
+# - include (optional): Includes the specified name list(s) into the own list.
+# - exclude (optional): Removes values from the name lists, useful e.g. after
+# a name list has been included.
+# - quote-names (optional): Specifies whether to return the contained names
+# enclosed in single quote (') characters. Default is false.
+#
+# The order of the declarations is important, later declarations may overwrite
+# names generated from earlier declarations.
+#
+# Example:
+#
+# constlist = EXAMPLE-CONSTLIST
+# 1 = my-value
+# include = OTHER-LIST
+# exclude = 2,3
+# 0x0004 = other-value
+# end
+#
+# - Defines the name 'my-value' for the constant 1.
+# - Includes 'OTHER-LIST' which may overwrite the name of the constant 1.
+# - Excludes the names of constants 2 and 3, which may have been included from
+# the name list 'OTHER-LIST'.
+# - Defines the name 'other-value' for the constant 4, which may overwrite the
+# name of this constant included from the name list 'OTHER-LIST'.
+#
+# ----------------------------------------------------------------------------
+#
+# multilist
+#
+# Defines names for contiguous ranges of values.
+#
+# Syntax:
+#
+# multilist = <LISTNAME>
+# default = <constname>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <value>[,<value>...]
+# ignore-empty = <bool>
+# <firstvalue> = <constname>[,<constname>...]
+# end
+#
+# - default (optional): See constlist above.
+# - include (optional): See constlist above.
+# - exclude (optional): See constlist above.
+# - ignore-empty (optional): Specifies whether to skip empty names in a list.
+# - True = skips an empty entry, the default name will be generated.
+# - False = creates an empty string for the entry.
+# Default is true (skip empty entries).
+#
+# Examples:
+#
+# multilist = EXAMPLE-MULTILIST
+# 0 = value0,value1,,value3
+# 8 = value8
+# end
+#
+# - Defines the names 'value0' for the constant 0, 'value1' for the constant
+# 1, 'value3' for the constant 3, and 'value8' for the constant 8.
+#
+# multilist = EXAMPLE-MULTILIST-2
+# include = EXAMPLE-MULTILIST
+# ignore-empty = false
+# default = other
+# end
+#
+# - Same as example above (includes EXAMPLE-MULTILIST), but defines the empty
+# string for the constant 2. Other constants (less than 0 or greater than 3
+# and not equal to 8) get the default name 'other'.
+#
+# ----------------------------------------------------------------------------
+#
+# shortlist
+#
+# Defines names for a contiguous range of values. The entire list definition
+# is given in a single text line.
+#
+# Syntax:
+#
+# shortlist = <LISTNAME>,<firstvalue>,<constname>[,<constname>...]
+#
+# Uses default settings of the multi-list (i.e. skips empty entries).
+#
+# ----------------------------------------------------------------------------
+#
+# flagslist
+#
+# Defines names for single bits in a bit field.
+#
+# Syntax:
+#
+# flagslist = <LISTNAME>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <bitfield>[,<bitfield>...]
+# ignore = <bitfield>
+# <bitmask> = <cname> | !<cname> | :<cname> | !<cname0>!<cname1>
+# end
+#
+# - include (optional): See constlist above.
+# - exclude (optional): See constlist above.
+# - ignore (optional): Specifies bits to be ignored. Bits without an explicit
+# name and not set in this declaration will be shown as unknown. Default is
+# to not ignore a bit.
+# - <bitmask>: The bit to be named. Must be a value with a single bit set.
+# - <cname> - Sets a name for the bit that will be shown if the bit is set.
+# Does not show anything if the bit is cleared.
+# - !<cname> - Sets a name for the bit that will be shown if the bit is
+# cleared. Does not show anything if the bit is set.
+# - :<cname> - Sets a name for the bit that will always be shown together
+# with the actual state of the bit, appended as ':on' or ':off'.
+# - !<cname0>!<cname1> - Sets a name for both the cleared bit (cname0), and
+# for the set bit (cname1).
+#
+# ----------------------------------------------------------------------------
+#
+# combilist
+#
+# Defines names for single bits and for embedded values in a bit field. This
+# is an extension of the flagslist described above.
+#
+# Syntax:
+#
+# combilist = <LISTNAME>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <bitmask>[,<bitmask>...]
+# ignore = <bitfield>
+# <bitmask> = <cname> | !<cname> | :<cname> | !<cname0>!<cname1>
+# <bitfield> = <datatype>,<dataformat>,<bitfieldname>[,<LISTNAME>[,options...]]
+# end
+#
+# - include (optional): See constlist above.
+# - exclude (optional): See constlist above.
+# - ignore (optional): See flagslist above.
+# - <bitmask>: See flagslist above.
+# - <bitfield>: The mask of the embedded bitfield. Must be a value with
+# exactly one sequence of at least 2 consecutive bits.
+# - <datatype>: [u]int8 | [u]int16 | [u]int32 | [u]int64 | float | double
+# - <dataformat>: dec | hex | shorthex | bin | fix | bool
+# - <bitfieldname>: The name of the embedded bitfield.
+# - <LISTAME>: Optional name list with names for the values of the embedded
+# bitfield.
+# - options: Additional options for this bitfield:
+# - filter = <filterbitfield>~<filtervalue>: If set, the entire bitfield
+# will only be written, if the complete data item currently dumped
+# contains exactly the value specified in <filtervalue> in the bitfield
+# specified in <filterbitfield>. Otherwise, nothing is written. It is
+# possible to specify multiple filter rules for this bitfield. In that
+# case, the bitfield will be written, if at least one filter rule
+# applies for the current data item.
+# - noshift = <bool>: If set to 'true', the extracted value will be
+# shifted to the right (normalized). If set to 'false', the value will
+# be written unshifted. Default is 'true'.
+#
+# ----------------------------------------------------------------------------
+#
+# unitconverter
+#
+# Converts values and appends a unit name.
+#
+# Syntax:
+#
+# unitconverter = <LISTNAME>,[/]<factor>[,<unitname>]
+#
+# ----------------------------------------------------------------------------
+
+unitconverter=CONV-DEC,1
+unitconverter=CONV-PERCENT,1,%
+unitconverter=CONV-FLOAT-TO-PERC,100,%
+unitconverter=CONV-DEG,1,°
+unitconverter=CONV-HMM-TO-CM,/1000,cm
+unitconverter=CONV-INCH-TO-CM,2.54,cm
+unitconverter=CONV-PT-TO-CM,/28.346457,cm
+unitconverter=CONV-PT1616-TO-CM,/1857713.4,cm
+unitconverter=CONV-TWIP-TO-CM,/566.92913,cm
+unitconverter=CONV-TWIP-TO-PT,/20,pt
+unitconverter=CONV-EMU-TO-CM,/36000,cm
+
+constlist=BOOLEAN
+ 0=FALSE
+ default=TRUE
+end
+
+combilist=RK-FLAGS
+ 0x00000001=div-100
+ 0x00000002=integer
+ 0xFFFFFFFC=int32,hex,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
+
+combilist=FONT-PITCHFAMILY
+ 0x0F=uint8,dec,pitch,FONT-PITCH
+ 0xF0=uint8,dec,family,FONT-FAMILY
+end
+
+constlist=FONT-WEIGHT
+ 400=normal
+ 700=bold
+end
+
+shortlist=FONT-PITCH,0,unknown,fixed,variable
+shortlist=FONT-FAMILY,0,unknown,roman,swiss,modern,script,decorative
+
+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
+
+multilist=COUNTRY
+ 1=usa,canada,latin-america,,,,russia
+ 20=egypt
+ 30=greece,netherlands,belgium,france,spain,,hungary,,,italy
+ 40=,switzerland,,austria,uk,denmark,sweden,norway,poland,germany
+ 50=,,mexico,,,brazil
+ 60=,australia,,,new-zealand,,thailand
+ 80=,japan,korea,,vietnam,,china
+ 90=turkey
+ 210=,,,algeria,,,morocco,,libya
+ 350=,portugal,,,iceland,,,,finland
+ 420=czech
+ 880=,,,,,,taiwan
+ 960=,lebanon,jordan,syria,iraq,kuwait,saudi-arabia
+ 970=,uae,israel,,qatar
+ 980=,iran
+end
+
+multilist=SYSTEMCOLOR
+ 0x00=scrollbar,desktop,active-title,inactive-title,menu,window-back,window-frame,menu-text
+ 0x08=window-text,active-title-text,active-border,inactive-border,app-workspace,highlight,highlight-text,button-face
+ 0x10=button-shadow,disabled-text,button-text,inactive-title-text,button-highlight,button-dark-shadow,button-light-shadow,tooltip-text
+ 0x18=tooltip-back,,hot-light,active-title-2,inactive-title-2,menu-highlight,menubar
+end
+
+# ============================================================================
diff --git a/oox/source/dump/makefile.mk b/oox/source/dump/makefile.mk
new file mode 100644
index 000000000000..1e5f615675cc
--- /dev/null
+++ b/oox/source/dump/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+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)$/oledumper.obj \
+ $(SLO)$/pptxdumper.obj \
+ $(SLO)$/xlsbdumper.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/dump/oledumper.cxx b/oox/source/dump/oledumper.cxx
new file mode 100644
index 000000000000..bd2a0e05ecce
--- /dev/null
+++ b/oox/source/dump/oledumper.cxx
@@ -0,0 +1,2364 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/dump/oledumper.hxx"
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <rtl/tencinfo.h>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/ole/olestorage.hxx"
+#include "oox/ole/vbainputstream.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OString;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+// ============================================================================
+
+OUString OleInputObjectBase::dumpAnsiString32( const String& rName )
+{
+ return dumpCharArray( rName, mxStrm->readInt32(), RTL_TEXTENCODING_MS_1252 );
+}
+
+OUString OleInputObjectBase::dumpUniString32( const String& rName )
+{
+ return dumpUnicodeArray( rName, mxStrm->readInt32() );
+}
+
+sal_Int32 OleInputObjectBase::dumpStdClipboardFormat( const String& rName )
+{
+ return dumpDec< sal_Int32 >( rName( "clipboard-format" ), "OLE-STD-CLIPBOARD-FORMAT" );
+}
+
+OUString OleInputObjectBase::dumpAnsiString32OrStdClip( const String& rName )
+{
+ sal_Int32 nLen = mxStrm->readInt32();
+ return (nLen < 0) ? OUString::valueOf( dumpStdClipboardFormat( rName ) ) : dumpCharArray( rName, nLen, RTL_TEXTENCODING_MS_1252 );
+}
+
+OUString OleInputObjectBase::dumpUniString32OrStdClip( const String& rName )
+{
+ sal_Int32 nLen = mxStrm->readInt32();
+ return (nLen < 0) ? OUString::valueOf( dumpStdClipboardFormat( rName ) ) : dumpUnicodeArray( rName, nLen );
+}
+
+void OleInputObjectBase::writeOleColorItem( const String& rName, sal_uInt32 nColor )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeHexItem( rName, nColor, "OLE-COLOR" );
+}
+
+sal_uInt32 OleInputObjectBase::dumpOleColor( const String& rName )
+{
+ sal_uInt32 nOleColor = mxStrm->readuInt32();
+ writeOleColorItem( rName, nOleColor );
+ return nOleColor;
+}
+
+// ============================================================================
+// ============================================================================
+
+StdFontObject::StdFontObject( const InputObjectBase& rParent )
+{
+ construct( rParent );
+}
+
+void StdFontObject::implDump()
+{
+ dumpDec< sal_uInt8 >( "version" );
+ dumpDec< sal_uInt16 >( "charset", "CHARSET" );
+ dumpHex< sal_uInt8 >( "flags", "STDFONT-FLAGS" );
+ dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
+ dumpDec< sal_uInt32 >( "height", "STDFONT-HEIGHT" );
+ dumpCharArray( "name", mxStrm->readuInt8(), RTL_TEXTENCODING_ASCII_US );
+}
+
+// ============================================================================
+
+StdPicObject::StdPicObject( const InputObjectBase& rParent )
+{
+ construct( rParent );
+}
+
+void StdPicObject::implDump()
+{
+ dumpHex< sal_uInt32 >( "identifier", "STDPIC-ID" );
+ sal_uInt32 nSize = dumpHex< sal_uInt32 >( "image-size", "CONV-DEC" );
+ dumpBinary( "image-data", nSize );
+}
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 STDHLINK_HASTARGET = 0x00000001; /// Has hyperlink moniker.
+const sal_uInt32 STDHLINK_ABSOLUTE = 0x00000002; /// Absolute path.
+const sal_uInt32 STDHLINK_HASLOCATION = 0x00000008; /// Has target location.
+const sal_uInt32 STDHLINK_HASDISPLAY = 0x00000010; /// Has display string.
+const sal_uInt32 STDHLINK_HASGUID = 0x00000020; /// Has identification GUID.
+const sal_uInt32 STDHLINK_HASTIME = 0x00000040; /// Has creation time.
+const sal_uInt32 STDHLINK_HASFRAME = 0x00000080; /// Has frame.
+const sal_uInt32 STDHLINK_ASSTRING = 0x00000100; /// Hyperlink as simple string.
+
+} // namespace
+
+StdHlinkObject::StdHlinkObject( const InputObjectBase& rParent )
+{
+ construct( rParent );
+}
+
+void StdHlinkObject::implDump()
+{
+ dumpDec< sal_uInt32 >( "stream-version" );
+ sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "flags", "STDHLINK-FLAGS" );
+ if( getFlag( nFlags, STDHLINK_HASDISPLAY ) )
+ dumpHyperlinkString( "display", true );
+ if( getFlag( nFlags, STDHLINK_HASFRAME ) )
+ dumpHyperlinkString( "frame", true );
+ if( getFlag( nFlags, STDHLINK_HASTARGET ) )
+ {
+ if( getFlag( nFlags, STDHLINK_ASSTRING ) )
+ dumpHyperlinkString( "filename", true );
+ else if( !dumpGuidAndMoniker() )
+ return;
+ }
+ if( getFlag( nFlags, STDHLINK_HASLOCATION ) )
+ dumpHyperlinkString( "location", true );
+ if( getFlag( nFlags, STDHLINK_HASGUID ) )
+ dumpGuid( "id-guid" );
+ if( getFlag( nFlags, STDHLINK_HASTIME ) )
+ dumpFileTime( "creation-time" );
+}
+
+OUString StdHlinkObject::dumpHyperlinkString( const String& rName, bool bUnicode )
+{
+ return bUnicode ? dumpUniString32( rName ) : dumpAnsiString32( rName );
+}
+
+bool StdHlinkObject::dumpGuidAndMoniker()
+{
+ bool bValidMoniker = true;
+ OUString aGuid = cfg().getStringOption( dumpGuid( "moniker" ), OUString() );
+ IndentGuard aIndGuard( mxOut );
+ if( aGuid.equalsAscii( "URLMoniker" ) )
+ dumpUrlMoniker();
+ else if( aGuid.equalsAscii( "FileMoniker" ) )
+ dumpFileMoniker();
+ else if( aGuid.equalsAscii( "ItemMoniker" ) )
+ dumpItemMoniker();
+ else if( aGuid.equalsAscii( "AntiMoniker" ) )
+ dumpAntiMoniker();
+ else if( aGuid.equalsAscii( "CompositeMoniker" ) )
+ dumpCompositeMoniker();
+ else
+ bValidMoniker = false;
+ return bValidMoniker;
+}
+
+void StdHlinkObject::dumpUrlMoniker()
+{
+ sal_Int32 nBytes = dumpDec< sal_Int32 >( "url-bytes" );
+ sal_Int64 nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
+ dumpNullUnicodeArray( "url" );
+ if( mxStrm->tell() + 24 == nEndPos )
+ {
+ dumpGuid( "implementation-id" );
+ dumpDec< sal_uInt32 >( "version" );
+ dumpHex< sal_uInt32 >( "flags", "STDHLINK-URL-FLAGS" );
+ }
+ dumpRemainingTo( nEndPos );
+}
+
+void StdHlinkObject::dumpFileMoniker()
+{
+ dumpDec< sal_Int16 >( "up-levels" );
+ dumpHyperlinkString( "ansi-filename", false );
+ dumpDec< sal_Int16 >( "server-path-len" );
+ dumpHex< sal_uInt16 >( "version" );
+ dumpUnused( 20 );
+ sal_Int32 nBytes = dumpDec< sal_Int32 >( "total-bytes" );
+ sal_Int64 nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
+ if( nBytes > 0 )
+ {
+ sal_Int32 nFileBytes = dumpDec< sal_Int32 >( "uni-filename-bytes" );
+ dumpDec< sal_uInt16 >( "key-value" );
+ dumpUnicodeArray( "unicode-filename", nFileBytes / 2 );
+ }
+ dumpRemainingTo( nEndPos );
+}
+
+void StdHlinkObject::dumpItemMoniker()
+{
+ sal_Int32 nBytes = dumpDec< sal_Int32 >( "delimiter-bytes" );
+ sal_Int64 nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
+ dumpNullCharArray( "ansi-delimiter", RTL_TEXTENCODING_MS_1252 );
+ if( mxStrm->tell() < nEndPos )
+ dumpUnicodeArray( "unicode-delimiter", (nEndPos - mxStrm->tell()) / 2 );
+ mxStrm->seek( nEndPos );
+
+ nBytes = dumpDec< sal_Int32 >( "item-bytes" );
+ nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
+ dumpNullCharArray( "ansi-item", RTL_TEXTENCODING_MS_1252 );
+ if( mxStrm->tell() < nEndPos )
+ dumpUnicodeArray( "unicode-item", (nEndPos - mxStrm->tell()) / 2 );
+ mxStrm->seek( nEndPos );
+}
+
+void StdHlinkObject::dumpAntiMoniker()
+{
+ dumpDec< sal_Int32 >( "count" );
+}
+
+void StdHlinkObject::dumpCompositeMoniker()
+{
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "moniker-count" );
+ for( sal_Int32 nIndex = 0; !mxStrm->isEof() && (nIndex < nCount); ++nIndex )
+ dumpGuidAndMoniker();
+}
+
+// ============================================================================
+// ============================================================================
+
+OleStreamObject::OleStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ construct( rParent, rxStrm, rSysFileName );
+}
+
+// ============================================================================
+
+OleCompObjObject::OleCompObjObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) :
+ OleStreamObject( rParent, rxStrm, rSysFileName )
+{
+}
+
+void OleCompObjObject::implDump()
+{
+ dumpUnused( 4 );
+ dumpDec< sal_uInt32 >( "version" );
+ dumpUnused( 20 );
+ dumpAnsiString32( "ansi-display-name" );
+ dumpAnsiString32OrStdClip( "ansi-clipboard-format" );
+ if( mxStrm->getRemaining() >= 4 )
+ {
+ sal_Int32 nLen = mxStrm->readInt32();
+ if( (0 <= nLen) && (nLen <= 40) )
+ {
+ dumpCharArray( "ansi-unused", nLen, RTL_TEXTENCODING_MS_1252 );
+ if( (mxStrm->getRemaining() >= 4) && (dumpHex< sal_Int32 >( "unicode-marker" ) == 0x71B239F4) )
+ {
+ dumpUniString32( "unicode-display-name" );
+ dumpUniString32OrStdClip( "unicode-clipboard-format" );
+ dumpUniString32( "unicode-unused" );
+ }
+ }
+ else
+ writeDecItem( "length", nLen );
+ }
+ dumpRemainingStream();
+}
+
+// ============================================================================
+// ============================================================================
+
+namespace {
+
+const sal_Int32 OLEPROP_ID_DICTIONARY = 0;
+const sal_Int32 OLEPROP_ID_CODEPAGE = 1;
+
+const sal_uInt16 OLEPROP_TYPE_INT16 = 2;
+const sal_uInt16 OLEPROP_TYPE_INT32 = 3;
+const sal_uInt16 OLEPROP_TYPE_FLOAT = 4;
+const sal_uInt16 OLEPROP_TYPE_DOUBLE = 5;
+const sal_uInt16 OLEPROP_TYPE_DATE = 7;
+const sal_uInt16 OLEPROP_TYPE_STRING = 8;
+const sal_uInt16 OLEPROP_TYPE_STATUS = 10;
+const sal_uInt16 OLEPROP_TYPE_BOOL = 11;
+const sal_uInt16 OLEPROP_TYPE_VARIANT = 12;
+const sal_uInt16 OLEPROP_TYPE_INT8 = 16;
+const sal_uInt16 OLEPROP_TYPE_UINT8 = 17;
+const sal_uInt16 OLEPROP_TYPE_UINT16 = 18;
+const sal_uInt16 OLEPROP_TYPE_UINT32 = 19;
+const sal_uInt16 OLEPROP_TYPE_INT64 = 20;
+const sal_uInt16 OLEPROP_TYPE_UINT64 = 21;
+const sal_uInt16 OLEPROP_TYPE_STRING8 = 30;
+const sal_uInt16 OLEPROP_TYPE_STRING16 = 31;
+const sal_uInt16 OLEPROP_TYPE_FILETIME = 64;
+const sal_uInt16 OLEPROP_TYPE_BLOB = 65;
+const sal_uInt16 OLEPROP_TYPE_STREAM = 66;
+const sal_uInt16 OLEPROP_TYPE_STORAGE = 67;
+const sal_uInt16 OLEPROP_TYPE_CLIPFMT = 71;
+
+const sal_uInt16 OLEPROP_TYPE_SIMPLE = 0x0000;
+const sal_uInt16 OLEPROP_TYPE_VECTOR = 0x1000;
+const sal_uInt16 OLEPROP_TYPE_ARRAY = 0x2000;
+
+const sal_uInt16 CODEPAGE_UNICODE = 1200;
+
+const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000;
+
+} // namespace
+
+// ============================================================================
+
+OlePropertyStreamObject::OlePropertyStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ construct( rParent, rxStrm, rSysFileName );
+}
+
+void OlePropertyStreamObject::implDump()
+{
+ OUStringVector aGuidVec;
+ ::std::vector< sal_uInt32 > aStartPosVec;
+
+ // dump header
+ writeEmptyItem( "HEADER" );
+ {
+ IndentGuard aIndGuard( mxOut );
+ 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( mxOut, 15, 60 );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nSectIdx = 0; !mxStrm->isEof() && (nSectIdx < nSectCount); ++nSectIdx )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#section" );
+ aGuidVec.push_back( dumpGuid( "guid" ) );
+ aStartPosVec.push_back( dumpHex< sal_uInt32 >( "start-pos", "CONV-DEC" ) );
+ }
+ }
+ }
+ mxOut->emptyLine();
+
+ // dump sections
+ for( size_t nSectIdx = 0; !mxStrm->isEof() && (nSectIdx < aStartPosVec.size()); ++nSectIdx )
+ dumpSection( aGuidVec[ nSectIdx ], aStartPosVec[ nSectIdx ] );
+}
+
+void OlePropertyStreamObject::dumpSection( const OUString& rGuid, sal_uInt32 nStartPos )
+{
+ // 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( mxOut );
+ 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( mxOut, 15, 25 );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nPropIdx = 0; !mxStrm->isEof() && (nPropIdx < nPropCount); ++nPropIdx )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#property" );
+ sal_Int32 nPropId = dumpDec< sal_Int32 >( "id", mxPropIds );
+ sal_uInt32 nPropPos = nStartPos + dumpHex< sal_uInt32 >( "start-pos", "CONV-DEC" );
+ aPropMap[ nPropId ] = nPropPos;
+ }
+ }
+ }
+ mxOut->emptyLine();
+
+ // code page property
+ meTextEnc = RTL_TEXTENCODING_MS_1252;
+ 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( mxOut );
+ if( startElement( nStartPos ) )
+ dumpPropertyContents( nPropId );
+ mxOut->emptyLine();
+}
+
+void OlePropertyStreamObject::dumpCodePageProperty( sal_uInt32 nStartPos )
+{
+ writePropertyHeader( OLEPROP_ID_CODEPAGE, nStartPos );
+ IndentGuard aIndGuard( mxOut );
+ if( startElement( nStartPos ) )
+ {
+ sal_uInt16 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 );
+ }
+ mxOut->emptyLine();
+}
+
+void OlePropertyStreamObject::dumpDictionaryProperty( sal_uInt32 nStartPos )
+{
+ writePropertyHeader( OLEPROP_ID_DICTIONARY, nStartPos );
+ IndentGuard aIndGuard( mxOut );
+ if( startElement( nStartPos ) )
+ {
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "count" );
+ for( sal_Int32 nIdx = 0; !mxStrm->isEof() && (nIdx < nCount); ++nIdx )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ TableGuard aTabGuard( mxOut, 10, 20 );
+ sal_Int32 nId = dumpDec< sal_Int32 >( "id" );
+ OUString aName = dumpString8( "name" );
+ if( mxPropIds.get() )
+ mxPropIds->setName( nId, aName );
+ }
+ }
+ mxOut->emptyLine();
+}
+
+sal_uInt16 OlePropertyStreamObject::dumpPropertyContents( sal_Int32 nPropId )
+{
+ sal_uInt16 nType = dumpPropertyType();
+ sal_uInt16 nBaseType = static_cast< sal_uInt16 >( nType & 0x0FFF );
+ sal_uInt16 nArrayType = static_cast< sal_uInt16 >( nType & 0xF000 );
+ switch( nArrayType )
+ {
+ case OLEPROP_TYPE_SIMPLE: dumpPropertyValue( nPropId, nBaseType ); break;
+ case OLEPROP_TYPE_VECTOR: dumpPropertyVector( nPropId, nBaseType ); break;
+ case OLEPROP_TYPE_ARRAY: dumpPropertyArray( nPropId, nBaseType ); break;
+ }
+ return nType;
+}
+
+void OlePropertyStreamObject::dumpPropertyValue( sal_Int32 nPropId, sal_uInt16 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( nPropId, "data" ); break;
+ case OLEPROP_TYPE_STREAM: dumpString8( "stream-name" ); break;
+ case OLEPROP_TYPE_STORAGE: dumpString8( "storage-name" ); break;
+ case OLEPROP_TYPE_CLIPFMT: dumpBlob( nPropId, "clip-data" ); break;
+ }
+}
+
+void OlePropertyStreamObject::dumpPropertyVector( sal_Int32 nPropId, sal_uInt16 nBaseType )
+{
+ sal_Int32 nElemCount = dumpDec< sal_Int32 >( "element-count" );
+ for( sal_Int32 nElemIdx = 0; !mxStrm->isEof() && (nElemIdx < nElemCount); ++nElemIdx )
+ {
+ mxOut->resetItemIndex( nElemIdx );
+ writeEmptyItem( "#element" );
+ IndentGuard aIndGuard( mxOut );
+ dumpPropertyValue( nPropId, nBaseType );
+ }
+}
+
+void OlePropertyStreamObject::dumpPropertyArray( sal_Int32 /*nPropId*/, sal_uInt16 /*nBaseType*/ )
+{
+ // TODO
+}
+
+sal_uInt16 OlePropertyStreamObject::dumpPropertyType()
+{
+ return static_cast< sal_uInt16 >( dumpHex< sal_Int32 >( "type", "OLEPROP-TYPE" ) & 0xFFFF );
+}
+
+void OlePropertyStreamObject::dumpBlob( sal_Int32 nPropId, const String& rName )
+{
+ sal_Int32 nSize = dumpDec< sal_Int32 >( "data-size" );
+ if( nSize > 0 )
+ {
+ OUString aPropName = mxPropIds->getName( cfg(), nPropId );
+ if( aPropName == CREATE_OUSTRING( "'_PID_HLINKS'" ) )
+ dumpHlinks( nSize );
+ else
+ dumpBinary( rName, nSize );
+ }
+}
+
+OUString OlePropertyStreamObject::dumpString8( const String& rName )
+{
+ sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
+ return mbIsUnicode ? dumpCharArray16( rName, nLen ) : dumpCharArray8( rName, nLen );
+}
+
+OUString OlePropertyStreamObject::dumpCharArray8( const String& rName, sal_Int32 nLen )
+{
+ OUString aData;
+ size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 );
+ if( nNewLen > 0 )
+ {
+ ::std::vector< sal_Char > aBuffer( nNewLen + 1 );
+ mxStrm->readMemory( &aBuffer.front(), nNewLen );
+ aBuffer[ nNewLen ] = 0;
+ aData = OStringToOUString( OString( &aBuffer.front() ), meTextEnc );
+ }
+ writeStringItem( rName, aData );
+ return aData;
+}
+
+OUString OlePropertyStreamObject::dumpString16( const String& rName )
+{
+ sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
+ return dumpCharArray16( rName, nLen );
+}
+
+OUString OlePropertyStreamObject::dumpCharArray16( const String& rName, sal_Int32 nLen )
+{
+ size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 );
+ ::std::vector< sal_Unicode > aBuffer;
+ aBuffer.reserve( nNewLen + 1 );
+ for( size_t nIdx = 0; nIdx < nNewLen; ++nIdx )
+ aBuffer.push_back( static_cast< sal_Unicode >( mxStrm->readuInt16() ) );
+ aBuffer.push_back( 0 );
+ OUString aData( &aBuffer.front() );
+ writeStringItem( rName, aData );
+ if( nNewLen & 1 ) dumpUnused( 2 ); // always padding to 32bit
+ return aData;
+}
+
+bool OlePropertyStreamObject::dumpTypedProperty( const String& rName, sal_uInt16 nExpectedType )
+{
+ writeEmptyItem( rName );
+ IndentGuard aIndGuard( mxOut );
+ return (dumpPropertyContents( -1 ) == nExpectedType) && !mxStrm->isEof();
+}
+
+void OlePropertyStreamObject::dumpHlinks( sal_Int32 nSize )
+{
+ sal_Int64 nEndPos = mxStrm->tell() + nSize;
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "property-count" );
+ bool bValid = true;
+ for( sal_Int32 nHlinkIndex = 0, nHlinkCount = nCount / 6; bValid && !mxStrm->isEof() && (nHlinkIndex < nHlinkCount); ++nHlinkIndex )
+ {
+ writeEmptyItem( "HYPERLINK" );
+ IndentGuard aIndGuard( mxOut );
+ bValid =
+ dumpTypedProperty( "hash", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "app", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "shape-id", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "info", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "target", OLEPROP_TYPE_STRING16 ) &&
+ dumpTypedProperty( "location", OLEPROP_TYPE_STRING16 );
+ }
+ dumpRemainingTo( nEndPos );
+}
+
+bool OlePropertyStreamObject::startElement( sal_uInt32 nStartPos )
+{
+ mxStrm->seek( nStartPos );
+ if( mxStrm->isEof() )
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+ return !mxStrm->isEof();
+}
+
+void OlePropertyStreamObject::writeSectionHeader( const OUString& rGuid, sal_uInt32 nStartPos )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "SECTION" );
+ writeHexItem( "pos", nStartPos, "CONV-DEC" );
+ writeGuidItem( "guid", rGuid );
+}
+
+void OlePropertyStreamObject::writePropertyHeader( sal_Int32 nPropId, sal_uInt32 nStartPos )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "PROPERTY" );
+ writeHexItem( "pos", nStartPos, "CONV-DEC" );
+ writeDecItem( "id", nPropId, mxPropIds );
+}
+
+// ============================================================================
+
+OleStorageObject::OleStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
+{
+ construct( rParent, rxStrg, rSysPath );
+}
+
+void OleStorageObject::construct( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
+{
+ StorageObjectBase::construct( rParent, rxStrg, rSysPath );
+}
+
+void OleStorageObject::construct( const ObjectBase& rParent )
+{
+ StorageObjectBase::construct( rParent );
+}
+
+void OleStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( rStrmName.equalsAscii( "\001CompObj" ) )
+ OleCompObjObject( *this, rxStrm, rSysFileName ).dump();
+ else if( rStrmName.equalsAscii( "\005SummaryInformation" ) || rStrmName.equalsAscii( "\005DocumentSummaryInformation" ) )
+ OlePropertyStreamObject( *this, rxStrm, rSysFileName ).dump();
+ else
+ BinaryStreamObject( *this, rxStrm, rSysFileName ).dump();
+}
+
+// ============================================================================
+// ============================================================================
+
+ComCtlObjectBase::ComCtlObjectBase( const InputObjectBase& rParent,
+ sal_uInt32 nDataId5, sal_uInt32 nDataId6, sal_uInt16 nVersion, bool bCommonPart, bool bComplexPart ) :
+ mnDataId5( nDataId5 ),
+ mnDataId6( nDataId6 ),
+ mnVersion( nVersion ),
+ mbCommonPart( bCommonPart ),
+ mbComplexPart( bComplexPart )
+{
+ construct( rParent );
+}
+
+void ComCtlObjectBase::implDump()
+{
+ sal_uInt32 nCommonSize = 0;
+ dumpComCtlSize() && dumpComCtlData( nCommonSize ) && (!mbCommonPart || dumpComCtlCommon( nCommonSize )) && (!mbComplexPart || dumpComCtlComplex());
+}
+
+void ComCtlObjectBase::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+}
+
+void ComCtlObjectBase::implDumpCommonTrailing()
+{
+}
+
+bool ComCtlObjectBase::dumpComCtlHeader( sal_uInt32 nExpId, sal_uInt16 nExpMajor, sal_uInt16 nExpMinor )
+{
+ // no idea if all this is correct...
+ sal_uInt32 nId = dumpHex< sal_uInt32 >( "header-id", "COMCTL-HEADER-IDS" );
+ ItemGuard aItem( mxOut, "version" );
+ sal_uInt16 nMinor, nMajor;
+ *mxStrm >> nMinor >> nMajor;
+ mxOut->writeDec( nMajor );
+ mxOut->writeChar( '.' );
+ mxOut->writeDec( nMinor );
+ return !mxStrm->isEof() && (nId == nExpId) && ((nExpMajor == SAL_MAX_UINT16) || (nExpMajor == nMajor)) && ((nExpMinor == SAL_MAX_UINT16) || (nExpMinor == nMinor));
+}
+
+bool ComCtlObjectBase::dumpComCtlSize()
+{
+ if( dumpComCtlHeader( 0x12344321, 0, 8 ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_Int32 >( "width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "height", "CONV-HMM-TO-CM" );
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+bool ComCtlObjectBase::dumpComCtlData( sal_uInt32& ornCommonPartSize )
+{
+ if( dumpComCtlHeader( (mnVersion == 5) ? mnDataId5 : mnDataId6, mnVersion ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ if( mbCommonPart )
+ ornCommonPartSize = dumpDec< sal_uInt32 >( "common-part-size" );
+ implDumpProperties();
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+bool ComCtlObjectBase::dumpComCtlCommon( sal_uInt32 nPartSize )
+{
+ sal_Int64 nEndPos = mxStrm->tell() + nPartSize;
+ if( (nPartSize >= 16) && dumpComCtlHeader( 0xABCDEF01, 5, 0 ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ dumpUnknown( 4 );
+ dumpHex< sal_uInt32 >( "common-flags", "COMCTL-COMMON-FLAGS" );
+ implDumpCommonExtra( nEndPos );
+ dumpRemainingTo( nEndPos );
+ implDumpCommonTrailing();
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+bool ComCtlObjectBase::dumpComCtlComplex()
+{
+ if( dumpComCtlHeader( 0xBDECDE1F, 5, 1 ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "comctl-complex-flags", "COMCTL-COMPLEX-FLAGS" );
+ if( !mxStrm->isEof() && (nFlags & 0x01) )
+ {
+ writeEmptyItem( "font" );
+ IndentGuard aIndGuard2( mxOut );
+ OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
+ if( aClassName.equalsAscii( "StdFont" ) )
+ StdFontObject( *this ).dump();
+ }
+ if( !mxStrm->isEof() && (nFlags & 0x02) )
+ {
+ writeEmptyItem( "mouse-icon" );
+ IndentGuard aIndGuard2( mxOut );
+ OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
+ if( aClassName.equalsAscii( "StdPic" ) )
+ StdPicObject( *this ).dump();
+ }
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+// ============================================================================
+
+ComCtlScrollBarObject::ComCtlScrollBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, SAL_MAX_UINT32, 0x99470A83, nVersion, true, true )
+{
+}
+
+void ComCtlScrollBarObject::implDumpProperties()
+{
+ dumpHex< sal_uInt32 >( "flags", "COMCTL-SCROLLBAR-FLAGS" );
+ dumpDec< sal_Int32 >( "large-change" );
+ dumpDec< sal_Int32 >( "small-change" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpDec< sal_Int32 >( "value" );
+}
+
+// ============================================================================
+
+ComCtlProgressBarObject::ComCtlProgressBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E84, 0x97AB8A01, nVersion, true, true )
+{
+}
+
+void ComCtlProgressBarObject::implDumpProperties()
+{
+ dumpDec< float >( "min" );
+ dumpDec< float >( "max" );
+ if( mnVersion == 6 )
+ {
+ dumpBool< sal_uInt16 >( "vertical" );
+ dumpBool< sal_uInt16 >( "smooth-scroll" );
+ }
+}
+
+// ============================================================================
+
+ComCtlSliderObject::ComCtlSliderObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E86, 0x0A2BAE11, nVersion, true, true )
+{
+}
+
+void ComCtlSliderObject::implDumpProperties()
+{
+ dumpBool< sal_Int32 >( "vertical" );
+ dumpDec< sal_Int32 >( "large-change" );
+ dumpDec< sal_Int32 >( "small-change" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpDec< sal_Int16 >( "select-range", "COMCTL-SLIDER-SELECTRANGE" );
+ dumpUnused( 2 );
+ dumpDec< sal_Int32 >( "select-start" );
+ dumpDec< sal_Int32 >( "select-length" );
+ dumpDec< sal_Int32 >( "tick-style", "COMCTL-SLIDER-TICKSTYLE" );
+ dumpDec< sal_Int32 >( "tick-frequency" );
+ dumpDec< sal_Int32 >( "value" );
+ if( mnVersion == 6 )
+ dumpBool< sal_Int32 >( "tooltip-below" );
+}
+
+// ============================================================================
+
+ComCtlUpDownObject::ComCtlUpDownObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xFF3626A0, 0xFF3626A0, nVersion, false, false )
+{
+}
+
+void ComCtlUpDownObject::implDumpProperties()
+{
+ dumpUnknown( 16 ); // buddy-property, somehow
+ dumpDec< sal_Int32 >( "buddy-control" );
+ dumpUnknown( 8 );
+ dumpDec< sal_Int32 >( "value" );
+ dumpUnknown( 4 );
+ dumpDec< sal_Int32 >( "increment" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpHex< sal_uInt32 >( "flags-1", "COMCTL-UPDOWN-FLAGS1" );
+ dumpHex< sal_uInt32 >( "flags-2", "COMCTL-UPDOWN-FLAGS2" );
+ dumpUnknown( 4 );
+}
+
+// ============================================================================
+
+ComCtlImageListObject::ComCtlImageListObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E80, 0xE6E17E80, nVersion, true, false )
+{
+}
+
+void ComCtlImageListObject::implDumpProperties()
+{
+ dumpDec< sal_uInt16 >( "image-width" );
+ dumpDec< sal_uInt16 >( "image-height" );
+ dumpOleColor( "mask-color" );
+ dumpBool< sal_Int16 >( "use-mask-color" );
+ dumpUnknown( 2 );
+}
+
+void ComCtlImageListObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpUnknown( 4 );
+ dumpOleColor( "back-color" );
+ dumpUnknown( 4 );
+ sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
+ {
+ writeEmptyItem( "#image" );
+ IndentGuard aIndGuard( mxOut );
+ sal_uInt8 nFlags = dumpHex< sal_uInt8 >( "text-flags", "COMCTL-IMAGELIST-TEXTFLAGS" );
+ if( nFlags & 0x01 ) dumpUniString32( "caption" );
+ if( nFlags & 0x02 ) dumpUniString32( "key" );
+ }
+}
+
+void ComCtlImageListObject::implDumpCommonTrailing()
+{
+ sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
+ {
+ writeEmptyItem( "#image" );
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_Int32 >( "index" );
+ StdPicObject( *this ).dump();
+ }
+}
+
+// ============================================================================
+
+ComCtlTabStripObject::ComCtlTabStripObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E8A, 0xD12A7AC1, nVersion, true, true )
+{
+}
+
+void ComCtlTabStripObject::implDumpProperties()
+{
+ dumpHex< sal_uInt32 >( "flags-1", "COMCTL-TABSTRIP-FLAGS1" );
+ dumpDec< sal_uInt16 >( "tab-fixed-width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_uInt16 >( "tab-fixed-height", "CONV-HMM-TO-CM" );
+ if( mnVersion == 6 )
+ {
+ dumpHex< sal_uInt32 >( "flags-2", "COMCTL-TABSTRIP-FLAGS2" );
+ dumpDec< sal_uInt16 >( "tab-min-width", "CONV-HMM-TO-CM" );
+ dumpUnknown( 2 );
+ dumpHex< sal_uInt32 >( "flags-3", "COMCTL-TABSTRIP-FLAGS3" );
+ }
+}
+
+void ComCtlTabStripObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpUnknown( 12 );
+ dumpUniString32( "image-list" );
+ sal_Int32 nTabCount = dumpDec< sal_Int32 >( "tab-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nTabIndex = 0; (nTabIndex < nTabCount) && !mxStrm->isEof(); ++nTabIndex )
+ {
+ writeEmptyItem( "#tab" );
+ IndentGuard aIndGuard( mxOut );
+ dumpUnknown( 4 );
+ sal_uInt32 nTabFlags = dumpHex< sal_uInt32 >( "tab-flags", "COMCTL-TABSTRIP-TABFLAGS" );
+ if( nTabFlags & 0x01 ) dumpUniString32( "caption" );
+ if( nTabFlags & 0x02 ) dumpUniString32( "key" );
+ if( nTabFlags & 0x04 ) dumpUniString32( "tag" );
+ if( nTabFlags & 0x08 ) dumpUniString32( "tooltip" );
+ dumpDec< sal_uInt16 >( "image-id" );
+ }
+}
+
+// ============================================================================
+
+ComCtlTreeViewObject::ComCtlTreeViewObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E8E, 0x6AC13CB1, nVersion, true, true ),
+ mnStringFlags( 0 )
+{
+}
+
+void ComCtlTreeViewObject::implDumpProperties()
+{
+ dumpHex< sal_uInt32 >( "flags", "COMCTL-TREEVIEW-FLAGS" );
+ dumpDec< sal_Int32 >( "indentation", "CONV-HMM-TO-CM" );
+ if( mnVersion == 6 )
+ dumpHex< sal_uInt32 >( "flags-2", "COMCTL-TREEVIEW-FLAGS2" );
+ mnStringFlags = dumpHex< sal_uInt32 >( "string-flags", "COMCTL-TREEVIEW-STRINGFLAGS" );
+}
+
+void ComCtlTreeViewObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpOleColor( "text-color" );
+ dumpOleColor( "back-color" );
+ dumpUnknown( 4 );
+ if( mnStringFlags & 0x02 )
+ dumpUniString32( "image-list" );
+ dumpUniString32( "path-separator" );
+}
+
+// ============================================================================
+
+ComCtlStatusBarObject::ComCtlStatusBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E88, SAL_MAX_UINT32, nVersion, true, true )
+{
+}
+
+void ComCtlStatusBarObject::implDumpProperties()
+{
+ dumpBool< sal_Int32 >( "style-simple-text" );
+ dumpBool< sal_Int16 >( "show-tips" );
+ dumpUnknown( 2 );
+}
+
+void ComCtlStatusBarObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpUnknown( 12 );
+ dumpUniString32( "simple-text" );
+ sal_Int32 nPanelCount = dumpDec< sal_Int32 >( "panel-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nPanelIndex = 0; (nPanelIndex < nPanelCount) && !mxStrm->isEof(); ++nPanelIndex )
+ {
+ writeEmptyItem( "#panel" );
+ IndentGuard aIndGuard( mxOut );
+ dumpHex< sal_uInt32 >( "panel-flags", "COMCTL-STATUSBAR-PANELFLAGS" );
+ dumpDec< sal_Int32 >( "current-width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "minimal-width", "CONV-HMM-TO-CM" );
+ sal_uInt32 nTextFlags = dumpHex< sal_uInt32 >( "text-flags", "COMCTL-STATUSBAR-TEXTFLAGS" );
+ if( nTextFlags & 0x01 ) dumpUniString32( "text" );
+ if( nTextFlags & 0x02 ) dumpUniString32( "vis-text" );
+ if( nTextFlags & 0x04 ) dumpUniString32( "key" );
+ if( nTextFlags & 0x08 ) dumpUniString32( "tag" );
+ if( nTextFlags & 0x10 ) dumpUniString32( "tooltip" );
+ }
+}
+
+void ComCtlStatusBarObject::implDumpCommonTrailing()
+{
+ sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
+ {
+ writeEmptyItem( "#image" );
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_Int32 >( "panel-index" );
+ StdPicObject( *this ).dump();
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+void AxPropertyObjectBase::construct( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, const String& rPropNameList, bool b64BitPropFlags )
+{
+ OleInputObjectBase::construct( rParent, rxStrm, rSysFileName );
+ constructAxPropObj( rPropNameList, b64BitPropFlags );
+}
+
+void AxPropertyObjectBase::construct( const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const String& rPropNameList, bool b64BitPropFlags )
+{
+ OleInputObjectBase::construct( rParent, rxStrm );
+ constructAxPropObj( rPropNameList, b64BitPropFlags );
+}
+
+void AxPropertyObjectBase::construct( const InputObjectBase& rParent,
+ const String& rPropNameList, bool b64BitPropFlags )
+{
+ OleInputObjectBase::construct( rParent );
+ constructAxPropObj( rPropNameList, b64BitPropFlags );
+}
+
+bool AxPropertyObjectBase::implIsValid() const
+{
+ return OleInputObjectBase::implIsValid() && mxStrm->isSeekable();
+}
+
+void AxPropertyObjectBase::implDump()
+{
+ mbValid = true;
+ // header
+ setAlignAnchor();
+ dumpVersion();
+ sal_uInt16 nSize = dumpDec< sal_uInt16 >( "size" );
+ mnPropertiesEnd = mxStrm->tell() + nSize;
+ // property flags
+ maLargeProps.clear();
+ maStreamProps.clear();
+ mnPropFlags = dumpHex< sal_Int64, sal_uInt32 >( mb64BitPropFlags, "properties", mxPropNames );
+ mnCurrProp = 0;
+ // properties
+ dumpShortProperties();
+ dumpLargeProperties();
+ setAlignAnchor();
+ if( ensureValid() )
+ implDumpExtended();
+}
+
+void AxPropertyObjectBase::implDumpShortProperties()
+{
+}
+
+void AxPropertyObjectBase::implDumpExtended()
+{
+}
+
+bool AxPropertyObjectBase::ensureValid( bool bCondition )
+{
+ if( mbValid && (!bCondition || mxStrm->isEof()) )
+ {
+ if( !bCondition )
+ writeInfoItem( "state", OOX_DUMP_ERRASCII( "format-error" ) );
+ mbValid = false;
+ }
+ return mbValid;
+}
+
+void AxPropertyObjectBase::setAlignAnchor()
+{
+ mnPropertiesStart = mxStrm->tell();
+}
+
+bool AxPropertyObjectBase::startNextProperty()
+{
+ if( mnCurrProp == 0 ) mnCurrProp = 1; else mnCurrProp <<= 1;
+ bool bHasProp = getFlag( mnPropFlags, mnCurrProp );
+ setFlag( mnPropFlags, mnCurrProp, false );
+ return ensureValid() && bHasProp;
+}
+
+OUString AxPropertyObjectBase::getPropertyName() const
+{
+ return cfg().getName( mxPropNames, mnCurrProp );
+}
+
+sal_uInt32 AxPropertyObjectBase::dumpFlagsProperty( sal_uInt32 nDefault, const sal_Char* pcNameList )
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ return dumpHex< sal_uInt32 >( getPropertyName(), pcNameList );
+ }
+ return nDefault;
+}
+
+sal_uInt32 AxPropertyObjectBase::dumpColorProperty( sal_uInt32 nDefault )
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ return dumpOleColor( getPropertyName() );
+ }
+ return nDefault;
+}
+
+sal_Unicode AxPropertyObjectBase::dumpUnicodeProperty()
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt16 >();
+ return dumpUnicode( getPropertyName() );
+ }
+ return '\0';
+}
+
+void AxPropertyObjectBase::dumpUnknownProperty()
+{
+ if( startNextProperty() )
+ ensureValid( false );
+}
+
+void AxPropertyObjectBase::dumpPosProperty()
+{
+ if( startNextProperty() )
+ maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_POS, getPropertyName(), 8 ) );
+}
+
+void AxPropertyObjectBase::dumpSizeProperty()
+{
+ if( startNextProperty() )
+ maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_SIZE, getPropertyName(), 8 ) );
+}
+
+void AxPropertyObjectBase::dumpGuidProperty( OUString* pValue )
+{
+ if( startNextProperty() )
+ maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_GUID, getPropertyName(), 16, pValue ) );
+}
+
+void AxPropertyObjectBase::dumpStringProperty( OUString* pValue )
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ sal_uInt32 nLen = dumpHex< sal_uInt32 >( getPropertyName(), "AX-STRINGLEN" );
+ maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_STRING, getPropertyName(), nLen, pValue ) );
+ }
+}
+
+void AxPropertyObjectBase::dumpStringArrayProperty()
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ sal_uInt32 nLen = dumpHex< sal_uInt32 >( getPropertyName(), "CONV-DEC" );
+ maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_STRINGARRAY, getPropertyName(), nLen ) );
+ }
+}
+
+void AxPropertyObjectBase::dumpStreamProperty()
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt16 >();
+ sal_uInt16 nData = dumpHex< sal_uInt16 >( getPropertyName() );
+ maStreamProps.push_back( StreamProperty( getPropertyName(), nData ) );
+ }
+}
+
+void AxPropertyObjectBase::dumpEmbeddedFont()
+{
+ if( ensureValid() )
+ {
+ writeEmptyItem( "embedded-fontdata" );
+ IndentGuard aIndGuard( mxOut );
+ AxCFontNewObject( *this ).dump();
+ }
+}
+
+void AxPropertyObjectBase::dumpToPosition( sal_Int64 nPos )
+{
+ dumpRemainingTo( nPos );
+ mbValid = true;
+ ensureValid();
+}
+
+void AxPropertyObjectBase::constructAxPropObj( const String& rPropNameList, bool b64BitPropFlags )
+{
+ if( OleInputObjectBase::implIsValid() )
+ {
+ mxPropNames = cfg().getNameList( rPropNameList );
+ mb64BitPropFlags = b64BitPropFlags;
+ mbValid = true;
+ }
+}
+
+void AxPropertyObjectBase::dumpVersion()
+{
+ ItemGuard aItem( mxOut, "version" );
+ sal_uInt8 nMinor, nMajor;
+ *mxStrm >> nMinor >> nMajor;
+ mxOut->writeDec( nMajor );
+ mxOut->writeChar( '.' );
+ mxOut->writeDec( nMinor );
+}
+
+OUString AxPropertyObjectBase::dumpString( const String& rName, sal_uInt32 nSize, bool bArray )
+{
+ bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
+ sal_uInt32 nBufSize = extractValue< sal_uInt32 >( nSize, 0, 31 );
+ OUString aString = bCompressed ?
+ dumpCharArray( rName, nBufSize, RTL_TEXTENCODING_ISO_8859_1 ) :
+ dumpUnicodeArray( rName, bArray ? nBufSize : (nBufSize / 2) );
+ alignInput< sal_Int32 >();
+ return aString;
+}
+
+void AxPropertyObjectBase::dumpShortProperties()
+{
+ if( ensureValid() )
+ {
+ writeEmptyItem( "short-properties" );
+ IndentGuard aIndGuard( mxOut );
+ implDumpShortProperties();
+ alignInput< sal_uInt32 >();
+ }
+}
+
+void AxPropertyObjectBase::dumpLargeProperties()
+{
+ if( ensureValid( mnPropFlags == 0 ) && !maLargeProps.empty() )
+ {
+ writeEmptyItem( "large-properties" );
+ IndentGuard aIndGuard( mxOut );
+ for( LargePropertyVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
+ {
+ switch( aIt->mePropType )
+ {
+ case LargeProperty::PROPTYPE_POS:
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( aIt->maItemName );
+ dumpDec< sal_Int32 >( "top", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "left", "CONV-HMM-TO-CM" );
+ }
+ break;
+ case LargeProperty::PROPTYPE_SIZE:
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( aIt->maItemName );
+ dumpDec< sal_Int32 >( "width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "height", "CONV-HMM-TO-CM" );
+ }
+ break;
+ case LargeProperty::PROPTYPE_GUID:
+ {
+ OUString aGuid = dumpGuid( aIt->maItemName );
+ if( aIt->mpItemValue )
+ *aIt->mpItemValue = cfg().getStringOption( aGuid, OUString() );
+ }
+ break;
+ case LargeProperty::PROPTYPE_STRING:
+ {
+ OUString aString = dumpString( aIt->maItemName, aIt->mnDataSize, false );
+ if( aIt->mpItemValue )
+ *aIt->mpItemValue = aString;
+ }
+ break;
+ case LargeProperty::PROPTYPE_STRINGARRAY:
+ {
+ writeEmptyItem( aIt->maItemName );
+ IndentGuard aIndGuard2( mxOut );
+ mxOut->resetItemIndex();
+ sal_Int64 nEndPos = mxStrm->tell() + aIt->mnDataSize;
+ while( mxStrm->tell() < nEndPos )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ sal_uInt32 nDataSize = dumpHex< sal_uInt32 >( "#flags", "AX-ARRAYSTRINGLEN" );
+ dumpString( "string", nDataSize, true );
+ }
+ dumpToPosition( nEndPos );
+ }
+ break;
+ }
+ }
+ }
+ dumpToPosition( mnPropertiesEnd );
+
+ if( ensureValid() && !maStreamProps.empty() )
+ {
+ writeEmptyItem( "stream-properties" );
+ IndentGuard aIndGuard( mxOut );
+ for( StreamPropertyVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
+ {
+ writeEmptyItem( aIt->maItemName );
+ if( ensureValid( aIt->mnData == 0xFFFF ) )
+ {
+ IndentGuard aIndGuard2( mxOut );
+ OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
+ if( aClassName.equalsAscii( "StdFont" ) )
+ StdFontObject( *this ).dump();
+ else if( aClassName.equalsAscii( "StdPic" ) )
+ StdPicObject( *this ).dump();
+ else if( aClassName.equalsAscii( "CFontNew" ) )
+ AxCFontNewObject( *this ).dump();
+ else
+ ensureValid( false );
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+AxCFontNewObject::AxCFontNewObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-CFONTNEW-PROPERTIES" );
+}
+
+void AxCFontNewObject::implDumpShortProperties()
+{
+ dumpStringProperty();
+ dumpFlagsProperty( 0, "AX-CFONTNEW-FLAGS" );
+ dumpDecProperty< sal_Int32 >( 160 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_uInt8 >( WINDOWS_CHARSET_DEFAULT, "CHARSET" );
+ dumpDecProperty< sal_uInt8 >( 0, "FONT-PITCHFAMILY" );
+ dumpDecProperty< sal_uInt8 >( 1, "AX-CFONTNEW-ALIGNMENT" );
+ dumpDecProperty< sal_uInt16 >( 400, "FONT-WEIGHT" );
+}
+
+// ============================================================================
+
+AxColumnInfoObject::AxColumnInfoObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-COLUMNINFO-PROPERTIES" );
+}
+
+void AxColumnInfoObject::implDumpShortProperties()
+{
+ dumpDecProperty< sal_Int32 >( -1, "CONV-HMM-TO-CM" );
+}
+
+// ============================================================================
+
+AxCommandButtonObject::AxCommandButtonObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-COMMANDBUTTON-PROPERTIES" );
+}
+
+void AxCommandButtonObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x80000008 );
+ dumpFlagsProperty( 0x0000001B );
+ dumpStringProperty();
+ dumpImagePosProperty();
+ dumpSizeProperty();
+ dumpMousePtrProperty();
+ dumpStreamProperty();
+ dumpUnicodeProperty();
+ dumpBoolProperty();
+ dumpStreamProperty();
+}
+
+void AxCommandButtonObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+}
+
+// ============================================================================
+
+AxMorphControlObject::AxMorphControlObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-MORPH-PROPERTIES", true );
+}
+
+void AxMorphControlObject::implDumpShortProperties()
+{
+ dumpFlagsProperty( 0x2C80081B );
+ dumpColorProperty( 0x80000005 );
+ dumpColorProperty( 0x80000008 );
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpBorderStyleProperty< sal_uInt8 >( 0 );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SCROLLBARS" );
+ mnCtrlType = dumpDecProperty< sal_uInt8 >( 1, "AX-MORPH-CONTROLTYPE" );
+ dumpMousePtrProperty();
+ dumpSizeProperty();
+ dumpUnicodeProperty();
+ dumpDecProperty< sal_uInt32 >( 0, "CONV-HMM-TO-CM" );
+ dumpDecProperty< sal_uInt16 >( 1, "AX-MORPH-BOUNDCOLUMN" );
+ dumpDecProperty< sal_Int16 >( -1, "AX-MORPH-TEXTCOLUMN" );
+ dumpDecProperty< sal_Int16 >( 1, "AX-MORPH-COLUMNCOUNT" );
+ dumpDecProperty< sal_uInt16 >( 8 );
+ mnColInfoCount = dumpDecProperty< sal_uInt16 >( 1 );
+ dumpDecProperty< sal_uInt8 >( 2, "AX-MORPH-MATCHENTRYTYPE" );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-LISTSTYLE" );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SHOWDROPDOWNMODE" );
+ dumpUnknownProperty();
+ dumpDecProperty< sal_uInt8 >( 1, "AX-MORPH-DROPDOWNSTYLE" );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SELECTIONTYPE" );
+ dumpStringProperty();
+ dumpStringProperty();
+ dumpImagePosProperty();
+ dumpColorProperty( 0x80000006 );
+ dumpSpecialEffectProperty< sal_uInt32 >( 2 );
+ dumpStreamProperty();
+ dumpStreamProperty();
+ dumpUnicodeProperty();
+ dumpUnknownProperty();
+ dumpBoolProperty();
+ dumpStringProperty();
+}
+
+void AxMorphControlObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+ dumpColumnInfos();
+}
+
+void AxMorphControlObject::dumpColumnInfos()
+{
+ if( ensureValid() && (mnColInfoCount > 0) && ((mnCtrlType == 2) || (mnCtrlType == 3)) )
+ {
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nIdx = 0; ensureValid() && (nIdx < mnColInfoCount); ++nIdx )
+ {
+ writeEmptyItem( "#column-info" );
+ IndentGuard aIndGuard( mxOut );
+ AxColumnInfoObject( *this ).dump();
+ }
+ }
+}
+
+// ============================================================================
+
+AxLabelObject::AxLabelObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-LABEL-PROPERTIES" );
+}
+
+void AxLabelObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x8000000F );
+ dumpFlagsProperty( 0x0080001B );
+ dumpStringProperty();
+ dumpImagePosProperty();
+ dumpSizeProperty();
+ dumpMousePtrProperty();
+ dumpColorProperty( 0x80000006 );
+ dumpBorderStyleProperty< sal_uInt16 >( 0 );
+ dumpSpecialEffectProperty< sal_uInt16 >( 0 );
+ dumpStreamProperty();
+ dumpUnicodeProperty();
+ dumpStreamProperty();
+}
+
+void AxLabelObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+}
+
+// ============================================================================
+
+AxImageObject::AxImageObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-IMAGE-PROPERTIES" );
+}
+
+void AxImageObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ dumpUnknownProperty();
+ dumpBoolProperty();
+ dumpColorProperty( 0x80000006 );
+ dumpColorProperty( 0x8000000F );
+ dumpBorderStyleProperty< sal_uInt8 >( 1 );
+ dumpMousePtrProperty();
+ dumpImageSizeModeProperty();
+ dumpSpecialEffectProperty< sal_uInt8 >( 0 );
+ dumpSizeProperty();
+ dumpStreamProperty();
+ dumpImageAlignProperty();
+ dumpBoolProperty();
+ dumpFlagsProperty( 0x0000001B );
+ dumpStreamProperty();
+}
+
+// ============================================================================
+
+AxScrollBarObject::AxScrollBarObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-SCROLLBAR-PROPERTIES" );
+}
+
+void AxScrollBarObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x8000000F );
+ dumpFlagsProperty( 0x0000001B );
+ dumpSizeProperty();
+ dumpMousePtrProperty();
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 32767 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpHexProperty< sal_uInt32 >( 0 );
+ dumpEnabledProperty();
+ dumpEnabledProperty();
+ dumpDecProperty< sal_Int32 >( 1 );
+ dumpDecProperty< sal_Int32 >( 1 );
+ dumpOrientationProperty();
+ dumpDecProperty< sal_Int16 >( -1, "AX-SCROLLBAR-PROPTHUMB" );
+ dumpDelayProperty();
+ dumpStreamProperty();
+}
+
+// ============================================================================
+
+AxSpinButtonObject::AxSpinButtonObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-SPINBUTTON-PROPERTIES" );
+}
+
+void AxSpinButtonObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x8000000F );
+ dumpFlagsProperty( 0x0000001B );
+ dumpSizeProperty();
+ dumpHexProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 100 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpEnabledProperty();
+ dumpEnabledProperty();
+ dumpDecProperty< sal_Int32 >( 1 );
+ dumpOrientationProperty();
+ dumpDelayProperty();
+ dumpStreamProperty();
+ dumpMousePtrProperty();
+}
+
+// ============================================================================
+
+AxTabStripObject::AxTabStripObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-TABSTRIP-PROPERTIES" );
+}
+
+void AxTabStripObject::implDumpShortProperties()
+{
+ dumpDecProperty< sal_Int32 >( -1 );
+ dumpColorProperty( 0x8000000F );
+ dumpColorProperty( 0x80000012 );
+ dumpUnknownProperty();
+ dumpSizeProperty();
+ dumpStringArrayProperty();
+ dumpMousePtrProperty();
+ dumpUnknownProperty();
+ dumpDecProperty< sal_uInt32 >( 0, "AX-TABSTRIP-ORIENTATION" );
+ dumpDecProperty< sal_uInt32 >( 0, "AX-TABSTRIP-TABSTYLE" );
+ dumpBoolProperty();
+ dumpHmmProperty();
+ dumpHmmProperty();
+ dumpBoolProperty();
+ dumpUnknownProperty();
+ dumpStringArrayProperty();
+ dumpUnknownProperty();
+ dumpStringArrayProperty();
+ dumpFlagsProperty( 0x0000001B );
+ dumpBoolProperty();
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpStringArrayProperty();
+ mnTabFlagCount = dumpDecProperty< sal_Int32 >( 0 );
+ dumpStringArrayProperty();
+ dumpStreamProperty();
+}
+
+void AxTabStripObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+ if( mnTabFlagCount > 0 )
+ {
+ writeEmptyItem( "tab-flags" );
+ IndentGuard aIndGuard( mxOut );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nIdx = 0; ensureValid() && (nIdx < mnTabFlagCount); ++nIdx )
+ dumpHex< sal_uInt32 >( "#flags", "AX-TABSTRIP-FLAGS" );
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+FormControlStreamObject::FormControlStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, const OUString* pProgId )
+{
+ construct( rParent, rxStrm, rSysFileName );
+ constructFormCtrlStrmObj( pProgId );
+}
+
+FormControlStreamObject::FormControlStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString* pProgId )
+{
+ construct( rParent, rxStrm );
+ constructFormCtrlStrmObj( pProgId );
+}
+
+void FormControlStreamObject::implDump()
+{
+ if( mbReadGuid )
+ maProgId = cfg().getStringOption( dumpGuid(), OUString() );
+
+ if( (maProgId.getLength() > 0) && !mxStrm->isEof() )
+ {
+ if( maProgId.equalsAscii( "Forms.CommandButton.1" ) )
+ AxCommandButtonObject( *this ).dump();
+ else if( maProgId.equalsAscii( "Forms.TextBox.1" ) ||
+ maProgId.equalsAscii( "Forms.ListBox.1" ) ||
+ maProgId.equalsAscii( "Forms.ComboBox.1" ) ||
+ maProgId.equalsAscii( "Forms.CheckBox.1" ) ||
+ maProgId.equalsAscii( "Forms.OptionButton.1" ) ||
+ maProgId.equalsAscii( "Forms.ToggleButton.1" ) ||
+ maProgId.equalsAscii( "RefEdit.Ctrl" ) )
+ AxMorphControlObject( *this ).dump();
+ else if( maProgId.equalsAscii( "Forms.Label.1" ) )
+ AxLabelObject( *this ).dump();
+ else if( maProgId.equalsAscii( "Forms.Image.1" ) )
+ AxImageObject( *this ).dump();
+ else if( maProgId.equalsAscii( "Forms.ScrollBar.1" ) )
+ AxScrollBarObject( *this ).dump();
+ else if( maProgId.equalsAscii( "Forms.SpinButton.1" ) )
+ AxSpinButtonObject( *this ).dump();
+ else if( maProgId.equalsAscii( "Forms.TabStrip.1" ) )
+ AxTabStripObject( *this ).dump();
+ else if( maProgId.equalsAscii( "MSComCtl2.FlatScrollBar.2" ) )
+ ComCtlScrollBarObject( *this, 6 ).dump();
+ else if( maProgId.equalsAscii( "COMCTL.ProgCtrl.1" ) )
+ ComCtlProgressBarObject( *this, 5 ).dump();
+ else if( maProgId.equalsAscii( "MSComctlLib.ProgCtrl.2" ) )
+ ComCtlProgressBarObject( *this, 6 ).dump();
+ else if( maProgId.equalsAscii( "COMCTL.Slider.1" ) )
+ ComCtlSliderObject( *this, 5 ).dump();
+ else if( maProgId.equalsAscii( "MSComctlLib.Slider.2" ) )
+ ComCtlSliderObject( *this, 6 ).dump();
+ else if( maProgId.equalsAscii( "ComCtl2.UpDown.1" ) )
+ ComCtlUpDownObject( *this, 5 ).dump();
+ else if( maProgId.equalsAscii( "MSComCtl2.UpDown.2" ) )
+ ComCtlUpDownObject( *this, 6 ).dump();
+ else if( maProgId.equalsAscii( "COMCTL.ImageListCtrl.1" ) )
+ ComCtlImageListObject( *this, 5 ).dump();
+ else if( maProgId.equalsAscii( "MSComctlLib.ImageListCtrl.2" ) )
+ ComCtlImageListObject( *this, 6 ).dump();
+ else if( maProgId.equalsAscii( "COMCTL.TabStrip.1" ) )
+ ComCtlTabStripObject( *this, 5 ).dump();
+ else if( maProgId.equalsAscii( "MSComctlLib.TabStrip.2" ) )
+ ComCtlTabStripObject( *this, 6 ).dump();
+ else if( maProgId.equalsAscii( "COMCTL.TreeCtrl.1" ) )
+ ComCtlTreeViewObject( *this, 5 ).dump();
+ else if( maProgId.equalsAscii( "MSComctlLib.TreeCtrl.2" ) )
+ ComCtlTreeViewObject( *this, 6 ).dump();
+ else if( maProgId.equalsAscii( "COMCTL.SBarCtrl.1" ) )
+ ComCtlStatusBarObject( *this, 5 ).dump();
+ else if( maProgId.equalsAscii( "StdPic" ) )
+ StdPicObject( *this ).dump();
+ }
+ dumpRemainingStream();
+}
+
+void FormControlStreamObject::constructFormCtrlStrmObj( const OUString* pProgId )
+{
+ mbReadGuid = pProgId == 0;
+ if( pProgId )
+ maProgId = *pProgId;
+}
+
+// ============================================================================
+// ============================================================================
+
+VbaFormClassInfoObject::VbaFormClassInfoObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-CLASSINFO-PROPERTIES" );
+}
+
+void VbaFormClassInfoObject::implDumpShortProperties()
+{
+ mrFormData.maClassInfoProgIds.push_back( OUString() );
+ dumpGuidProperty( &mrFormData.maClassInfoProgIds.back() );
+ dumpGuidProperty();
+ dumpUnknownProperty();
+ dumpGuidProperty();
+ dumpFlagsProperty( 0, "VBA-CLASSINFO-FLAGS" );
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_Int32 >( -1 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0, "OLEPROP-TYPE" );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0, "OLEPROP-TYPE" );
+ dumpDecProperty< sal_Int32 >( -1 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+}
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 VBA_FORMSITE_OBJSTREAM = 0x0010;
+
+const sal_uInt16 VBA_FORMSITE_CLASSTABLEINDEX = 0x8000;
+const sal_uInt16 VBA_FORMSITE_CLASSTABLEMASK = 0x7FFF;
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+VbaFormSiteObject::VbaFormSiteObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-FORMSITE-PROPERTIES" );
+}
+
+void VbaFormSiteObject::implDumpShortProperties()
+{
+ VbaFormSiteInfo aSiteInfo;
+ dumpStringProperty();
+ dumpStringProperty();
+ sal_Int32 nId = dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ sal_uInt32 nFlags = dumpFlagsProperty( 0x00000033, "VBA-FORMSITE-FLAGS" );
+ sal_uInt32 nLength = dumpDecProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_Int16 >( -1 );
+ sal_uInt16 nClassId = dumpHexProperty< sal_uInt16 >( 0x7FFF, "VBA-FORMSITE-CLASSIDCACHE" );
+ dumpPosProperty();
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpUnknownProperty();
+ dumpStringProperty();
+ dumpStringProperty();
+ dumpStringProperty();
+ dumpStringProperty();
+
+ sal_uInt16 nIndex = nClassId & VBA_FORMSITE_CLASSTABLEMASK;
+ if( getFlag( nClassId, VBA_FORMSITE_CLASSTABLEINDEX ) )
+ {
+ if( nIndex < mrFormData.maClassInfoProgIds.size() )
+ aSiteInfo.maProgId = mrFormData.maClassInfoProgIds[ nIndex ];
+ }
+ else
+ {
+ if( cfg().hasName( "VBA-FORMSITE-CLASSNAMES", nIndex ) )
+ aSiteInfo.maProgId = cfg().getName( "VBA-FORMSITE-CLASSNAMES", nIndex );
+ }
+ aSiteInfo.mnId = nId;
+ aSiteInfo.mnLength = nLength;
+ aSiteInfo.mbInStream = getFlag( nFlags, VBA_FORMSITE_OBJSTREAM );
+
+ mrFormData.maSiteInfos.push_back( aSiteInfo );
+}
+
+// ============================================================================
+
+VbaFormDesignExtObject::VbaFormDesignExtObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-FORMDESIGNEXT-PROPERTIES" );
+}
+
+void VbaFormDesignExtObject::implDumpShortProperties()
+{
+ dumpFlagsProperty( 0x00015F55, "VBA-FORMDESIGNEXT-FLAGS" );
+ dumpHmmProperty();
+ dumpHmmProperty();
+ dumpDecProperty< sal_Int8 >( 0, "VBA-FORMDESIGNEXT-CLICKCTRLMODE" );
+ dumpDecProperty< sal_Int8 >( 0, "VBA-FORMDESIGNEXT-DBLCLICKCTRLMODE" );
+}
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 AX_FORM_HASDESIGNEXTENDER = 0x00004000;
+const sal_uInt32 AX_FORM_SKIPCLASSTABLE = 0x00008000;
+
+const sal_uInt8 AX_FORM_SITECOUNTTYPE_COUNT = 0x80;
+const sal_uInt8 AX_FORM_SITECOUNTTYPE_MASK = 0x7F;
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+VbaFStreamObject::VbaFStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ AxPropertyObjectBase::construct( rParent, rxStrm, rSysFileName, "VBA-FORM-PROPERTIES" );
+}
+
+void VbaFStreamObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ dumpColorProperty( 0x8000000F );
+ dumpColorProperty( 0x80000012 );
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpUnknownProperty();
+ dumpUnknownProperty();
+ mnFlags = dumpFlagsProperty( 0x00000004, "VBA-FORM-FLAGS" );
+ dumpBorderStyleProperty< sal_uInt8 >( 0 );
+ dumpMousePtrProperty();
+ dumpHexProperty< sal_uInt8 >( 0x0C, "VBA-FORM-SCROLLBARS" );
+ dumpSizeProperty();
+ dumpSizeProperty();
+ dumpPosProperty();
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpUnknownProperty();
+ dumpStreamProperty();
+ dumpDecProperty< sal_uInt8 >( 0, "VBA-FORM-CYCLE" );
+ dumpSpecialEffectProperty< sal_uInt8 >( 0 );
+ dumpColorProperty( 0x80000012 );
+ dumpStringProperty();
+ dumpStreamProperty();
+ dumpStreamProperty();
+ dumpDecProperty< sal_Int32 >( 100, "CONV-PERCENT" );
+ dumpImageAlignProperty();
+ dumpBoolProperty();
+ dumpImageSizeModeProperty();
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_uInt32 >( 0 );
+}
+
+void VbaFStreamObject::implDumpExtended()
+{
+ dumpClassInfos();
+ dumpSiteData();
+ dumpDesignExtender();
+ dumpRemainingStream();
+}
+
+void VbaFStreamObject::dumpClassInfos()
+{
+ if( ensureValid() && !getFlag( mnFlags, AX_FORM_SKIPCLASSTABLE ) )
+ {
+ mxOut->emptyLine();
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "class-info-count" );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nIdx = 0; ensureValid() && (nIdx < nCount); ++nIdx )
+ {
+ writeEmptyItem( "#class-info" );
+ IndentGuard aIndGuard( mxOut );
+ VbaFormClassInfoObject( *this, mrFormData ).dump();
+ }
+ }
+}
+
+void VbaFStreamObject::dumpFormSites( sal_uInt32 nCount )
+{
+ mxOut->resetItemIndex();
+ for( sal_uInt32 nIdx = 0; ensureValid() && (nIdx < nCount); ++nIdx )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "#form-site" );
+ IndentGuard aIndGuard( mxOut );
+ VbaFormSiteObject( *this, mrFormData ).dump();
+ }
+}
+
+void VbaFStreamObject::dumpSiteData()
+{
+ if( ensureValid() )
+ {
+ mxOut->emptyLine();
+ setAlignAnchor();
+ sal_uInt32 nSiteCount = dumpDec< sal_uInt32 >( "site-count" );
+ sal_uInt32 nSiteLength = dumpDec< sal_uInt32 >( "site-data-size" );
+ sal_Int64 nEndPos = mxStrm->tell() + nSiteLength;
+ if( ensureValid( nEndPos <= mxStrm->getLength() ) )
+ {
+ mxOut->resetItemIndex();
+ sal_uInt32 nSiteIdx = 0;
+ while( ensureValid() && (nSiteIdx < nSiteCount) )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "#site-info" );
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_uInt8 >( "depth" );
+ sal_uInt8 nTypeCount = dumpHex< sal_uInt8 >( "type-count", "VBA-FORM-SITE-TYPECOUNT" );
+ if( getFlag( nTypeCount, AX_FORM_SITECOUNTTYPE_COUNT ) )
+ {
+ dumpDec< sal_uInt8 >( "repeated-type" );
+ nSiteIdx += (nTypeCount & AX_FORM_SITECOUNTTYPE_MASK);
+ }
+ else
+ {
+ ++nSiteIdx;
+ }
+ }
+ alignInput< sal_uInt32 >();
+ dumpFormSites( nSiteCount );
+ dumpToPosition( nEndPos );
+ }
+ }
+}
+
+void VbaFStreamObject::dumpDesignExtender()
+{
+ if( ensureValid() && getFlag( mnFlags, AX_FORM_HASDESIGNEXTENDER ) )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "design-extender" );
+ IndentGuard aIndGuard( mxOut );
+ VbaFormDesignExtObject( *this ).dump();
+ }
+}
+
+// ============================================================================
+
+VbaOStreamObject::VbaOStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ OleInputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+void VbaOStreamObject::implDump()
+{
+ for( VbaFormSiteInfoVector::iterator aIt = mrFormData.maSiteInfos.begin(), aEnd = mrFormData.maSiteInfos.end(); !mxStrm->isEof() && (aIt != aEnd); ++aIt )
+ {
+ if( (aIt->mbInStream) && (aIt->mnLength > 0) )
+ {
+ mxOut->emptyLine();
+ writeDecItem( "control-id", aIt->mnId );
+ writeInfoItem( "prog-id", aIt->maProgId );
+ IndentGuard aIndGuard( mxOut );
+ RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) );
+ FormControlStreamObject( *this, xRelStrm, &aIt->maProgId ).dump();
+ }
+ }
+ dumpRemainingStream();
+}
+
+// ============================================================================
+
+VbaPageObject::VbaPageObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-PAGE-PROPERTIES" );
+}
+
+void VbaPageObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ dumpDecProperty< sal_uInt32 >( 0, "VBA-PAGE-TRANSITIONEFFECT" );
+ dumpDecProperty< sal_uInt32 >( 0, "AX-CONV-MS" );
+}
+
+// ============================================================================
+
+VbaMultiPageObject::VbaMultiPageObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-MULTIPAGE-PROPERTIES" );
+}
+
+void VbaMultiPageObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ mnPageCount = dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpBoolProperty();
+}
+
+void VbaMultiPageObject::implDumpExtended()
+{
+ if( ensureValid() && (mnPageCount > 0) )
+ {
+ writeEmptyItem( "page-ids" );
+ IndentGuard aIndGuard( mxOut );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nIdx = 0; ensureValid() && (nIdx < mnPageCount); ++nIdx )
+ dumpDec< sal_Int32 >( "#id" );
+ }
+}
+
+// ============================================================================
+
+VbaXStreamObject::VbaXStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+void VbaXStreamObject::implDump()
+{
+ for( size_t nIdx = 0, nCount = mrFormData.maSiteInfos.size(); !mxStrm->isEof() && (nIdx < nCount); ++nIdx )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "page" );
+ IndentGuard aIndGuard( mxOut );
+ VbaPageObject( *this ).dump();
+ }
+ if( !mxStrm->isEof() )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "multi-page" );
+ IndentGuard aIndGuard( mxOut );
+ VbaMultiPageObject( *this ).dump();
+ }
+ dumpRemainingStream();
+}
+
+// ============================================================================
+
+VbaContainerStorageObject::VbaContainerStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
+ OleStorageObject( rParent, rxStrg, rSysPath )
+{
+ addPreferredStream( "f" );
+}
+
+void VbaContainerStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( rStrmName.equalsAscii( "f" ) )
+ VbaFStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
+ else if( rStrmName.equalsAscii( "o" ) )
+ VbaOStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
+ else if( rStrmName.equalsAscii( "x" ) )
+ VbaXStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
+ else
+ OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+void VbaContainerStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ if( isFormStorage( rStrgPath ) )
+ VbaContainerStorageObject( *this, rxStrg, rSysPath ).dump();
+ else
+ OleStorageObject( *this, rxStrg, rSysPath ).dump();
+}
+
+bool VbaContainerStorageObject::isFormStorage( const OUString& rStrgPath ) const
+{
+ if( (rStrgPath.getLength() >= 3) && (rStrgPath[ 0 ] == 'i') )
+ {
+ OUString aId = rStrgPath.copy( 1 );
+ if( (aId.getLength() == 2) && (aId[ 0 ] == '0') )
+ aId = aId.copy( 1 );
+ sal_Int32 nId = aId.toInt32();
+ if( (nId > 0) && (OUString::valueOf( nId ) == aId) )
+ for( VbaFormSiteInfoVector::const_iterator aIt = maFormData.maSiteInfos.begin(), aEnd = maFormData.maSiteInfos.end(); aIt != aEnd; ++aIt )
+ if( aIt->mnId == nId )
+ return true;
+ }
+ return false;
+}
+
+// ============================================================================
+// ============================================================================
+
+VbaSharedData::VbaSharedData() :
+ meTextEnc( RTL_TEXTENCODING_MS_1252 )
+{
+}
+
+bool VbaSharedData::isModuleStream( const ::rtl::OUString& rStrmName ) const
+{
+ return maStrmOffsets.count( rStrmName ) > 0;
+}
+
+sal_Int32 VbaSharedData::getStreamOffset( const OUString& rStrmName ) const
+{
+ StreamOffsetMap::const_iterator aIt = maStrmOffsets.find( rStrmName );
+ return (aIt == maStrmOffsets.end()) ? 0 : aIt->second;
+}
+
+// ============================================================================
+
+VbaDirStreamObject::VbaDirStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaSharedData& rVbaData ) :
+ mrVbaData( rVbaData )
+{
+ mxInStrm = rxStrm;
+ if( mxInStrm.get() )
+ {
+ BinaryInputStreamRef xVbaStrm( new ::oox::ole::VbaInputStream( *mxInStrm ) );
+ SequenceRecordObjectBase::construct( rParent, xVbaStrm, rSysFileName, "VBA-DIR-RECORD-NAMES", "VBA-DIR-SIMPLE-RECORDS" );
+ }
+}
+
+bool VbaDirStreamObject::implIsValid() const
+{
+ return mxInStrm.get() && SequenceRecordObjectBase::implIsValid();
+}
+
+bool VbaDirStreamObject::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ ornRecId = rBaseStrm.readuInt16();
+ ornRecSize = rBaseStrm.readInt32();
+
+ // for no obvious reason, PROJECTVERSION record contains size field of 4, but is 6 bytes long
+ if( ornRecId == 9 )
+ ornRecSize = 6;
+
+ return !rBaseStrm.isEof();
+}
+
+void VbaDirStreamObject::implDumpRecordBody()
+{
+ switch( getRecId() )
+ {
+ case 0x0003:
+ mrVbaData.meTextEnc = rtl_getTextEncodingFromWindowsCodePage( dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" ) );
+ break;
+ case 0x0004:
+ dumpByteString( "name" );
+ break;
+ case 0x0005:
+ dumpByteString( "description" );
+ break;
+ case 0x0006:
+ dumpByteString( "helpfile-path" );
+ break;
+ case 0x0009:
+ dumpDec< sal_uInt32 >( "major" );
+ dumpDec< sal_uInt16 >( "minor" );
+ break;
+ case 0x000C:
+ dumpByteString( "constants" );
+ break;
+ case 0x000D:
+ dumpByteStringWithLength( "lib-id" );
+ dumpUnused( 6 );
+ break;
+ case 0x000E:
+ dumpByteStringWithLength( "lib-id-absolute" );
+ dumpByteStringWithLength( "lib-id-relative" );
+ dumpDec< sal_uInt32 >( "major" );
+ dumpDec< sal_uInt16 >( "minor" );
+ break;
+ case 0x0016:
+ dumpByteString( "name" );
+ break;
+ case 0x0019:
+ dumpByteString( "name" );
+ maCurrStream = OUString();
+ mnCurrOffset = 0;
+ break;
+ case 0x001A:
+ maCurrStream = dumpByteString( "stream-name" );
+ break;
+ case 0x001C:
+ dumpByteString( "description" );
+ break;
+ case 0x002B:
+ if( maCurrStream.getLength() > 0 )
+ mrVbaData.maStrmOffsets[ maCurrStream ] = mnCurrOffset;
+ maCurrStream = OUString();
+ mnCurrOffset = 0;
+ break;
+ case 0x002F:
+ dumpByteStringWithLength( "lib-id-twiddled" );
+ dumpUnused( 6 );
+ break;
+ case 0x0030:
+ dumpByteStringWithLength( "lib-id-extended" );
+ dumpUnused( 6 );
+ dumpGuid( "original-typelib" );
+ dumpDec< sal_uInt32 >( "cookie" );
+ break;
+ case 0x0031:
+ mnCurrOffset = dumpHex< sal_Int32 >( "stream-offset", "CONV-DEC" );
+ break;
+ case 0x0032:
+ dumpUniString( "stream-name" );
+ break;
+ case 0x0033:
+ dumpByteString( "lib-id-original" );
+ break;
+ case 0x003C:
+ dumpUniString( "constants" );
+ break;
+ case 0x003D:
+ dumpByteString( "helpfile-path" );
+ break;
+ case 0x003E:
+ dumpUniString( "name" );
+ break;
+ case 0x0040:
+ dumpUniString( "description" );
+ break;
+ case 0x0047:
+ dumpUniString( "name" );
+ break;
+ case 0x0048:
+ dumpUniString( "description" );
+ break;
+ }
+}
+
+OUString VbaDirStreamObject::dumpByteString( const String& rName )
+{
+ return dumpCharArray( rName, static_cast< sal_Int32 >( getRecSize() ), mrVbaData.meTextEnc );
+}
+
+OUString VbaDirStreamObject::dumpUniString( const String& rName )
+{
+ return dumpUnicodeArray( rName, static_cast< sal_Int32 >( getRecSize() / 2 ) );
+}
+
+OUString VbaDirStreamObject::dumpByteStringWithLength( const String& rName )
+{
+ return dumpCharArray( rName, mxStrm->readInt32(), mrVbaData.meTextEnc );
+}
+
+// ============================================================================
+
+VbaModuleStreamObject::VbaModuleStreamObject(
+ const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm,
+ const OUString& rSysFileName, VbaSharedData& rVbaData, sal_Int32 nStrmOffset ) :
+ mrVbaData( rVbaData ),
+ mnStrmOffset( nStrmOffset )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+void VbaModuleStreamObject::implDump()
+{
+ dumpBinary( "perf-cache", mnStrmOffset );
+ mxOut->emptyLine();
+ writeEmptyItem( "source-code" );
+ IndentGuard aIndGuard( mxOut );
+ BinaryInputStreamRef xVbaStrm( new ::oox::ole::VbaInputStream( *mxStrm ) );
+ TextStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump();
+}
+
+// ============================================================================
+
+VbaStorageObject::VbaStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath, VbaSharedData& rVbaData ) :
+ OleStorageObject( rParent, rxStrg, rSysPath ),
+ mrVbaData( rVbaData )
+{
+ addPreferredStream( "dir" );
+}
+
+void VbaStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "dir" ) )
+ VbaDirStreamObject( *this, rxStrm, rSysFileName, mrVbaData ).dump();
+ else if( mrVbaData.isModuleStream( rStrmName ) )
+ VbaModuleStreamObject( *this, rxStrm, rSysFileName, mrVbaData, mrVbaData.getStreamOffset( rStrmName ) ).dump();
+ else
+ OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+// ============================================================================
+
+VbaFormStorageObject::VbaFormStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath, VbaSharedData& rVbaData ) :
+ VbaContainerStorageObject( rParent, rxStrg, rSysPath ),
+ mrVbaData( rVbaData )
+{
+}
+
+void VbaFormStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( rStrmName.equalsAscii( "\003VBFrame" ) )
+ TextStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump();
+ else
+ VbaContainerStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+// ============================================================================
+
+VbaProjectStorageObject::VbaProjectStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
+ OleStorageObject( rParent, rxStrg, rSysPath )
+{
+ addPreferredStorage( "VBA" );
+}
+
+void VbaProjectStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "PROJECT" ) )
+ TextStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump();
+ else
+ OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+void VbaProjectStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ if( rStrgPath.equalsAscii( "VBA" ) )
+ VbaStorageObject( *this, rxStrg, rSysPath, maVbaData ).dump();
+ else
+ VbaFormStorageObject( *this, rxStrg, rSysPath, maVbaData ).dump();
+}
+
+// ============================================================================
+// ============================================================================
+
+ActiveXStorageObject::ActiveXStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
+ VbaContainerStorageObject( rParent, rxStrg, rSysPath )
+{
+}
+
+void ActiveXStorageObject::implDumpBaseStream( const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ FormControlStreamObject( *this, rxStrm, rSysFileName ).dump();
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace dump
+} // namespace oox
+
+#endif
diff --git a/oox/source/dump/oledumper.ini b/oox/source/dump/oledumper.ini
new file mode 100644
index 000000000000..c8461d4b28a7
--- /dev/null
+++ b/oox/source/dump/oledumper.ini
@@ -0,0 +1,887 @@
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+
+# OLE name lists =============================================================
+
+constlist=OLE-STD-CLIPBOARD-FORMAT
+ 2=bmp
+ 3=wmf
+ 8=dib
+ 14=emf
+end
+
+combilist=OLE-COLOR
+ 0x0000FFFF=uint32,dec,palette-index,,filter=0xFF000000~0x01000000
+ 0x000000FF=uint32,dec,red,,filter=0xFF000000~0x00000000,filter=0xFF000000~0x02000000
+ 0x0000FF00=uint32,dec,green,,filter=0xFF000000~0x00000000,filter=0xFF000000~0x02000000
+ 0x00FF0000=uint32,dec,blue,,filter=0xFF000000~0x00000000,filter=0xFF000000~0x02000000
+ 0x0000FFFF=uint32,dec,system-color,SYSTEMCOLOR,filter=0xFF000000~0x80000000
+ 0xFF000000=uint8,dec,type,OLE-COLORTYPE
+end
+
+constlist=OLE-COLORTYPE
+ 0x00=default
+ 0x01=palette
+ 0x02=rgb
+ 0x80=system-color
+end
+
+multilist=OLE-MOUSEPTR
+ 0=default,arrow,cross,i-beam
+ 6=size-diag-down,size-vert,size-diag-up,size-hor
+ 10=up-arrow,hour-glass,no-drop,app-starting,help,size-all
+ 99=custom
+end
+
+# StdFont --------------------------------------------------------------------
+
+{0BE35203-8F91-11CE-9DE3-00AA004BB851}=StdFont
+
+flagslist=STDFONT-FLAGS
+ 0x01=bold
+ 0x02=italic
+ 0x04=underline
+ 0x08=strikeout
+end
+
+unitconverter=STDFONT-HEIGHT,/10000,pt
+
+# StdPic ---------------------------------------------------------------------
+
+{0BE35204-8F91-11CE-9DE3-00AA004BB851}=StdPic
+
+shortlist=STDPIC-ID,0x0000746C,StdPic
+
+# StdHlink -------------------------------------------------------------------
+
+{79EAC9D0-BAF9-11CE-8C82-00AA004BA90B}=StdHlink
+{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}=URLMoniker
+{00000303-0000-0000-C000-000000000046}=FileMoniker
+{00000304-0000-0000-C000-000000000046}=ItemMoniker
+{00000305-0000-0000-C000-000000000046}=AntiMoniker
+{00000309-0000-0000-C000-000000000046}=CompositeMoniker
+
+flagslist=STDHLINK-FLAGS
+ 0x00000001=has-target
+ 0x00000002=!relative!absolute
+ 0x00000004=display-specified
+ 0x00000008=has-location
+ 0x00000010=has-display
+ 0x00000020=has-guid
+ 0x00000040=has-creation-time
+ 0x00000080=has-frame
+ 0x00000100=!as-guid!as-string
+ 0x00000200=has-abs-from-rel
+end
+
+flagslist=STDHLINK-URL-FLAGS
+ 0x00000001=allow-relative
+ 0x00000002=wildcard-scheme
+ 0x00000004=implicit-file-scheme
+ 0x00000008=no-fragment
+ 0x00000010=no-canonicalize
+ 0x00000020=canonicalize
+ 0x00000040=dos-path
+ 0x00000080=decode-extra-info
+ 0x00000100=no-decode-extra-info
+ 0x00000200=crack-unknown-schemes
+ 0x00000400=no-crack-unknown-schemes
+ 0x00000800=preprocess-html
+ 0x00001000=no-preprocess-html
+ 0x00002000=registry-settings
+ 0x00004000=no-registry-settings
+ 0x00008000=no-encode-forbidden-chars
+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,currency,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,,,,,record,intptr,uintptr
+ 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
+
+# ComCtl controls ============================================================
+
+constlist=COMCTL-HEADER-IDS
+ 0x0A2BAE11=COMCTL_SLIDER_60
+ 0x12344321=COMCTL_SIZE
+ 0x6AC13CB1=COMCTL_TREEVIEW_60
+ 0x97AB8A01=COMCTL_PROGRESSBAR_60
+ 0x99470A83=COMCTL_SCROLLBAR_60
+ 0xABCDEF01=COMCTL_COMMONDATA
+ 0xBDECDE1F=COMCTL_COMPLEXDATA
+ 0xD12A7AC1=COMCTL_TABSTRIP_60
+ 0xE6E17E80=COMCTL_IMAGELIST_50_60
+ 0xE6E17E84=COMCTL_PROGRESSBAR_50
+ 0xE6E17E86=COMCTL_SLIDER_50
+ 0xE6E17E88=COMCTL_STATUSBAR_50
+ 0xE6E17E8A=COMCTL_TABSTRIP_50
+ 0xE6E17E8E=COMCTL_TREEVIEW_50
+ 0xFF3626A0=COMCTL_UPDOWN_50_60
+end
+
+combilist=COMCTL-COMMON-FLAGS
+ ignore=0xFFFF8000
+ 0x00000001=flat-border
+ 0x00000002=enabled
+ 0x00000004=3d-border
+ 0x000007F8=uint8,dec,mouse-ptr,OLE-MOUSEPTR
+ 0x00000800=ole-drag-auto
+ 0x00002000=ole-drop-manual
+end
+
+flagslist=COMCTL-COMPLEX-FLAGS
+ ignore=0xFFFFFFFC
+ 0x00000001=font
+ 0x00000002=mouse-icon
+end
+
+# flat scrollbar -------------------------------------------------------------
+
+{FE38753A-44A3-11D1-B5B7-0000C09000C4}=MSComCtl2.FlatScrollBar.2
+
+combilist=COMCTL-SCROLLBAR-FLAGS
+ 0x00000003=uint8,dec,appearance,COMCTL-SCROLLBAR-APPEARANCE
+ 0x0000000C=uint8,dec,arrows,COMCTL-SCROLLBAR-ARROWS
+ 0x00000010=!vertical!horizontal
+end
+
+shortlist=COMCTL-SCROLLBAR-APPEARANCE,0,3d,flat,track-3d
+shortlist=COMCTL-SCROLLBAR-ARROWS,0,both,left-up,right-down
+
+# progress bar ---------------------------------------------------------------
+
+{0713E8D2-850A-101B-AFC0-4210102A8DA7}=COMCTL.ProgCtrl.1
+{35053A22-8589-11D1-B16A-00C0F0283628}=MSComctlLib.ProgCtrl.2
+
+# slider ---------------------------------------------------------------------
+
+{373FF7F0-EB8B-11CD-8820-08002B2F4F5A}=COMCTL.Slider.1
+{F08DF954-8592-11D1-B16A-00C0F0283628}=MSComctlLib.Slider.2
+
+constlist=COMCTL-SLIDER-SELECTRANGE
+ 0x00000000=off
+ 0x0000FFFF=on
+end
+
+shortlist=COMCTL-SLIDER-TICKSTYLE,0,bottom-right,top-left,both,no-ticks
+
+# updown ---------------------------------------------------------------------
+
+{026371C0-1B7C-11CF-9D53-00AA003C9CB6}=ComCtl2.UpDown.1
+{603C7E80-87C2-11D1-8BE3-0000F8754DA1}=MSComCtl2.UpDown.2
+
+flagslist=COMCTL-UPDOWN-FLAGS1
+ 0x00000001=!align-left!align-right
+ 0x00000004=!vertical!horizontal
+end
+
+flagslist=COMCTL-UPDOWN-FLAGS2
+ 0x00000004=wrap
+ 0x00000020=ole-drop-manual
+ 0x00000080=enabled
+end
+
+# image list -----------------------------------------------------------------
+
+{58DA8D8F-9D6A-101B-AFC0-4210102A8DA7}=COMCTL.ImageListCtrl.1
+{2C247F23-8591-11D1-B16A-00C0F0283628}=MSComctlLib.ImageListCtrl.2
+
+flagslist=COMCTL-IMAGELIST-TEXTFLAGS
+ 0x01=key
+ 0x02=tag
+end
+
+# tab strip ------------------------------------------------------------------
+
+{9ED94440-E5E8-101B-B9B5-444553540000}=COMCTL.TabStrip.1
+{1EFB6596-857C-11D1-B16A-00C0F0283628}=MSComctlLib.TabStrip.2
+
+combilist=COMCTL-TABSTRIP-FLAGS1
+ ignore=0xFFFFFFE0
+ 0x00000001=multi-row
+ 0x00000002=show-tooltips
+ 0x00000018=uint8,dec,tab-width-style,COMCTL-TABSTRIP-TABWIDTHSTYLE
+end
+
+combilist=COMCTL-TABSTRIP-FLAGS2
+ ignore=0xFFFF0000
+ 0x00000003=uint8,dec,style,COMCTL-TABSTRIP-STYLE
+ 0x00000004=hot-tracking
+ 0x00000008=multi-select
+ 0x00000030=uint8,dec,placement,COMCTL-TABSTRIP-PLACEMENT
+ 0x00000040=separators
+end
+
+flagslist=COMCTL-TABSTRIP-FLAGS3
+ ignore=0xFFFF0000
+ 0x00000001=tabstyle-opposite
+end
+
+shortlist=COMCTL-TABSTRIP-TABWIDTHSTYLE,0,justified,non-justified,fixed
+shortlist=COMCTL-TABSTRIP-STYLE,0,tabs,tab-buttons,flat-buttons
+shortlist=COMCTL-TABSTRIP-PLACEMENT,0,top,bottom,left,right
+
+flagslist=COMCTL-TABSTRIP-TABFLAGS
+ 0x00000001=caption
+ 0x00000002=key
+ 0x00000004=tag
+ 0x00000008=tooltip
+end
+
+# tree view ------------------------------------------------------------------
+
+{0713E8A2-850A-101B-AFC0-4210102A8DA7}=COMCTL.TreeCtrl.1
+{C74190B6-8589-11D1-B16A-00C0F0283628}=MSComctlLib.TreeCtrl.2
+
+combilist=COMCTL-TREEVIEW-FLAGS
+ ignore=0xFFFF0000
+ 0x00000001=!tree-lines!root-lines
+ 0x0000001C=uint8,dec,style,COMCTL-TREEVIEW-STYLE
+ 0x00000020=label-edit
+ 0x00000080=hide-selection
+ 0x00000100=sorted
+end
+
+flagslist=COMCTL-TREEVIEW-STRINGFLAGS
+ ignore=0xFFFFFFF8
+ 0x00000001=separator
+ 0x00000002=image-list
+end
+
+shortlist=COMCTL-TREEVIEW-STYLE,0,text,pic-text,plusminus-text,plusminus-pic-text,treelines-text,treelines-pic-text,treelines-plusminus-text,treelines-plusminus-pic-text
+
+flagslist=COMCTL-TREEVIEW-FLAGS2
+ 0x00000001=checkboxes
+ 0x00000002=full-row-select
+ 0x00000004=hot-tracking
+ 0x00000008=scroll
+ 0x00000010=single-select
+end
+
+# status bar -----------------------------------------------------------------
+
+{6B7E638F-850A-101B-AFC0-4210102A8DA7}=COMCTL.SBarCtrl.1
+
+combilist=COMCTL-STATUSBAR-PANELFLAGS
+ ignore=0xFFFFF000
+ 0x00000007=uint8,dec,style,COMCTL-STATUSBAR-STYLE
+ 0x00000018=uint8,dec,alignment,COMCTL-STATUSBAR-ALIGN
+ 0x00000060=uint8,dec,bevel,COMCTL-STATUSBAR-BEVEL
+ 0x00000080=enabled
+ 0x00000300=uint8,dec,autosize,COMCTL-STATUSBAR-AUTOSIZE
+ 0x00000400=visible
+end
+
+shortlist=COMCTL-STATUSBAR-STYLE,0,text,caps,num,ins,scrl,time,date,kana
+shortlist=COMCTL-STATUSBAR-ALIGN,0,left,center,right
+shortlist=COMCTL-STATUSBAR-BEVEL,0,no-bevel,inset,raised
+shortlist=COMCTL-STATUSBAR-AUTOSIZE,0,no-auto,spring,content
+
+flagslist=COMCTL-STATUSBAR-TEXTFLAGS
+ 0x00000001=text
+ 0x00000002=vis-text
+ 0x00000004=key
+ 0x00000008=tag
+ 0x00000010=tooltip
+end
+
+# other controls =============================================================
+
+# Microsoft Web Browser
+{8856F961-340A-11D0-A96B-00C04FD705A2}=Shell.Explorer.2
+
+# ActiveX name lists =========================================================
+
+combilist=AX-STRINGLEN
+ 0x80000000=!unicode!compressed
+ 0x7FFFFFFF=int32,dec,buffer-size
+end
+
+combilist=AX-ARRAYSTRINGLEN
+ 0x80000000=!unicode!compressed
+ 0x7FFFFFFF=int32,dec,len
+end
+
+combilist=AX-FLAGS
+ 0x00000001=reserved-1
+ 0x00000002=enabled
+ 0x00000004=locked
+ 0x00000008=opaque
+ 0x00000010=reserved-2
+ 0x00000400=column-heads
+ 0x00000800=entire-rows
+ 0x00001000=existing-entries-only
+ 0x00002000=caption-left
+ 0x00004000=editable
+ 0x00078000=uint8,dec,ime-mode,AX-IMEMODE
+ 0x00080000=drag-enabled
+ 0x00100000=enter-as-newline
+ 0x00200000=keep-selection
+ 0x00400000=tab-as-character
+ 0x00800000=word-wrap
+ 0x02000000=borders-suppressed
+ 0x04000000=select-line
+ 0x08000000=single-char-select
+ 0x10000000=auto-size
+ 0x20000000=hide-selection
+ 0x40000000=maxlength-autotab
+ 0x80000000=multi-line
+end
+
+multilist=AX-IMEMODE
+ 0=no-control,on,off,disabled
+ 4=hiragana,fillwidth-katakana,halfwidth-katakana
+ 7=fullwidth-alpha,halfwidth-alpha
+ 9=fullwidth-hangul,halfwidth-hangul
+ 11=fullwidth-hanzi,halfwidth-hanzi
+end
+
+combilist=AX-IMAGEPOS
+ 0x0000FFFF=uint16,dec,image,AX-POS
+ 0xFFFF0000=uint16,dec,label,AX-POS
+end
+
+unitconverter=AX-CONV-MS,1,ms
+
+shortlist=AX-ENABLED,0,disabled,enabled
+shortlist=AX-BORDERSTYLE,0,none,single
+shortlist=AX-SPECIALEFFECT,0,flat,raised,sunken,etched,,,bump
+shortlist=AX-ORIENTATION,-1,auto,vertical,horizontal
+shortlist=AX-POS,0,top-left,top,top-right,left,center,right,bottom-left,bottom,bottom-right
+shortlist=AX-IMAGEALIGN,0,top-left,top-right,center,bottom-left,bottom-right
+shortlist=AX-IMAGESIZEMODE,0,clip,stretch,,stretch-ratio
+
+# CFontNew -------------------------------------------------------------------
+
+{AFC20920-DA4E-11CE-B94300AA006887B4}=CFontNew
+
+flagslist=AX-CFONTNEW-PROPERTIES
+ 0x0001=font-name
+ 0x0002=flags
+ 0x0004=font-size
+ 0x0008=font-offset
+ 0x0010=charset
+ 0x0020=pitch-family
+ 0x0040=alignment
+ 0x0080=font-weight
+end
+
+flagslist=AX-CFONTNEW-FLAGS
+ 0x00000001=bold
+ 0x00000002=italic
+ 0x00000004=underline
+ 0x00000008=strikeout
+ 0x00002000=sunken
+ 0x00002000=sunken
+ 0x40000000=auto-color
+end
+
+shortlist=AX-CFONTNEW-ALIGNMENT,1,left,right,center
+
+# column info ----------------------------------------------------------------
+
+flagslist=AX-COLUMNINFO-PROPERTIES
+ 0x00000001=column-width
+end
+
+# command button -------------------------------------------------------------
+
+{D7053240-CE69-11CD-A777-00DD01143C57}=Forms.CommandButton.1
+
+flagslist=AX-COMMANDBUTTON-PROPERTIES
+ 0x00000001=text-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=caption
+ 0x00000010=image-pos
+ 0x00000020=size
+ 0x00000040=mouse-ptr
+ 0x00000080=image
+ 0x00000100=accelerator
+ 0x00000200=no-take-focus
+ 0x00000400=mouse-icon
+end
+
+# toggle button, check box, option button, text box, list box, combo box -----
+
+{8BD21D10-EC42-11CE-9E0D-00AA006002F3}=Forms.TextBox.1
+{8BD21D20-EC42-11CE-9E0D-00AA006002F3}=Forms.ListBox.1
+{8BD21D30-EC42-11CE-9E0D-00AA006002F3}=Forms.ComboBox.1
+{8BD21D40-EC42-11CE-9E0D-00AA006002F3}=Forms.CheckBox.1
+{8BD21D50-EC42-11CE-9E0D-00AA006002F3}=Forms.OptionButton.1
+{8BD21D60-EC42-11CE-9E0D-00AA006002F3}=Forms.ToggleButton.1
+{00024512-0000-0000-C000-000000000046}=RefEdit.Ctrl
+
+flagslist=AX-MORPH-PROPERTIES
+ 0x0000000000000001=flags
+ 0x0000000000000002=fill-color
+ 0x0000000000000004=text-color
+ 0x0000000000000008=max-length
+ 0x0000000000000010=border-style
+ 0x0000000000000020=scrollbars
+ 0x0000000000000040=control-type
+ 0x0000000000000080=mouse-ptr
+ 0x0000000000000100=size
+ 0x0000000000000200=password-char
+ 0x0000000000000400=list-width
+ 0x0000000000000800=bound-column
+ 0x0000000000001000=text-column
+ 0x0000000000002000=column-count
+ 0x0000000000004000=list-rowcount
+ 0x0000000000008000=column-info-count
+ 0x0000000000010000=match-entry-mode
+ 0x0000000000020000=list-style
+ 0x0000000000040000=show-dropdown-mode
+ 0x0000000000100000=dropdown-style
+ 0x0000000000200000=selection-type
+ 0x0000000000400000=value
+ 0x0000000000800000=caption
+ 0x0000000001000000=image-pos
+ 0x0000000002000000=border-color
+ 0x0000000004000000=special-effect
+ 0x0000000008000000=mouse-icon
+ 0x0000000010000000=image
+ 0x0000000020000000=accelerator
+ 0x0000000080000000=reserved
+ 0x0000000100000000=groupname
+end
+
+shortlist=AX-MORPH-SCROLLBARS,0,none,horizontal,vertical,both
+shortlist=AX-MORPH-CONTROLTYPE,1,edit,listbox,combobox,checkbox,optionbutton,togglebutton,dropdown-listbox
+shortlist=AX-MORPH-MATCHENTRYTYPE,0,first-letter,complete,none
+shortlist=AX-MORPH-LISTSTYLE,0,plain,with-buttons
+shortlist=AX-MORPH-SHOWDROPDOWNMODE,0,never,on-focus,always
+shortlist=AX-MORPH-DROPDOWNSTYLE,0,no-symbol,arrow,ellipsis,underline
+shortlist=AX-MORPH-SELECTIONTYPE,0,single,multi,range
+
+constlist=AX-MORPH-BOUNDCOLUMN
+ default=
+ 0=value-is-row-index
+end
+
+constlist=AX-MORPH-TEXTCOLUMN
+ default=
+ -1=first-column-with-width
+ 0=row-numbers
+end
+
+constlist=AX-MORPH-COLUMNCOUNT
+ default=
+ -1=all-columns
+end
+
+# label ----------------------------------------------------------------------
+
+{978C9E23-D4B0-11CE-BF2D-00AA003F40D0}=Forms.Label.1
+
+flagslist=AX-LABEL-PROPERTIES
+ 0x00000001=text-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=caption
+ 0x00000010=image-pos
+ 0x00000020=size
+ 0x00000040=mouse-ptr
+ 0x00000080=border-color
+ 0x00000100=border-style
+ 0x00000200=special-effect
+ 0x00000400=image
+ 0x00000800=accelerator
+ 0x00001000=mouse-icon
+end
+
+# image ----------------------------------------------------------------------
+
+{4C599241-6926-101B-9992-00000B65C6F9}=Forms.Image.1
+
+flagslist=AX-IMAGE-PROPERTIES
+ 0x00000004=auto-size
+ 0x00000008=border-color
+ 0x00000010=fill-color
+ 0x00000020=border-style
+ 0x00000040=mouse-ptr
+ 0x00000080=image-size-mode
+ 0x00000100=special-effect
+ 0x00000200=size
+ 0x00000400=image
+ 0x00000800=image-align
+ 0x00001000=image-tiling
+ 0x00002000=flags
+ 0x00004000=mouse-icon
+end
+
+# scroll bar -----------------------------------------------------------------
+
+{DFD181E0-5E2F-11CE-A449-00AA004A803D}=Forms.ScrollBar.1
+
+flagslist=AX-SCROLLBAR-PROPERTIES
+ 0x00000001=arrow-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=size
+ 0x00000010=mouse-ptr
+ 0x00000020=min
+ 0x00000040=max
+ 0x00000080=value
+ 0x00000100=unused
+ 0x00000200=prev-enabled
+ 0x00000400=next-enabled
+ 0x00000800=step
+ 0x00001000=page-step
+ 0x00002000=orientation
+ 0x00004000=prop-thumb
+ 0x00008000=delay
+ 0x00010000=mouse-icon
+end
+
+shortlist=AX-SCROLLBAR-PROPTHUMB,-1,proportional,fixed
+
+# spin button ----------------------------------------------------------------
+
+{79176FB0-B7F2-11CE-97EF-00AA006D2776}=Forms.SpinButton.1
+
+flagslist=AX-SPINBUTTON-PROPERTIES
+ 0x00000001=arrow-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=size
+ 0x00000010=unused
+ 0x00000020=min
+ 0x00000040=max
+ 0x00000080=value
+ 0x00000100=prev-enabled
+ 0x00000200=next-enabled
+ 0x00000400=step
+ 0x00000800=orientation
+ 0x00001000=delay
+ 0x00002000=mouse-icon
+ 0x00004000=mouse-ptr
+end
+
+# tab strip ------------------------------------------------------------------
+
+{EAE50EB0-4A62-11CE-BED6-00AA00611080}=Forms.TabStrip.1
+
+flagslist=AX-TABSTRIP-PROPERTIES
+ 0x00000001=selected-tab
+ 0x00000002=fill-color
+ 0x00000004=text-color
+ 0x00000010=size
+ 0x00000020=tab-captions
+ 0x00000040=mouse-ptr
+ 0x00000100=tab-orientation
+ 0x00000200=tab-style
+ 0x00000400=multi-row
+ 0x00000800=tab-fixed-width
+ 0x00001000=tab-fixed-height
+ 0x00002000=tooltips
+ 0x00008000=tooltip-strings
+ 0x00020000=tab-names
+ 0x00040000=flags
+ 0x00080000=new-version
+ 0x00100000=tabs-allocated
+ 0x00200000=tags
+ 0x00400000=tab-flag-count
+ 0x00800000=accelerators
+ 0x01000000=mouse-icon
+end
+
+shortlist=AX-TABSTRIP-ORIENTATION,0,top,bottom,left,right
+shortlist=AX-TABSTRIP-TABSTYLE,0,tabs,buttons,none
+
+flagslist=AX-TABSTRIP-FLAGS
+ 0x00000001=visible
+ 0x00000002=enabled
+end
+
+# VBA forms ==================================================================
+
+# form class info ------------------------------------------------------------
+
+flagslist=VBA-CLASSINFO-PROPERTIES
+ 0x00000001=class-id
+ 0x00000002=disp-event
+ 0x00000008=default-prog
+ 0x00000010=class-flags
+ 0x00000020=method-count
+ 0x00000040=dispatch-id-bind
+ 0x00000080=get-bind-index
+ 0x00000100=put-bind-index
+ 0x00000200=bind-type
+ 0x00000400=get-value-index
+ 0x00000800=put-value-index
+ 0x00001000=value-type
+ 0x00002000=dispatch-id-rowset
+ 0x00004000=set-rowset
+end
+
+combilist=VBA-CLASSINFO-FLAGS
+ 0x0000FFFF=uint16,hex,classtable-flags,VBA-CLASSTABLE-CLASSFLAGS
+ 0xFFFF0000=uint16,hex,var-flags,VBA-CLASSTABLE-VARFLAGS
+end
+
+flagslist=VBA-CLASSTABLE-CLASSFLAGS
+ 0x0001=exclusive-value
+ 0x0002=dual-interface
+ 0x0004=no-aggregation
+end
+
+flagslist=VBA-CLASSTABLE-VARFLAGS
+ 0x0001=read-only
+ 0x0002=source
+ 0x0004=bindable
+ 0x0008=request-edit
+ 0x0010=display-bind
+ 0x0020=default-bind
+ 0x0040=hidden
+ 0x0080=restricted
+ 0x0100=default-coll-elem
+ 0x0200=ui-default
+ 0x0400=non-browsable
+ 0x0800=replaceable
+ 0x1000=immediate-bind
+end
+
+# form site ------------------------------------------------------------------
+
+flagslist=VBA-FORMSITE-PROPERTIES
+ 0x00000001=name
+ 0x00000002=tag
+ 0x00000004=id
+ 0x00000008=help-context-id
+ 0x00000010=flags
+ 0x00000020=stream-size
+ 0x00000040=tab-index
+ 0x00000080=class-id-cache-index
+ 0x00000100=pos
+ 0x00000200=group-id
+ 0x00000800=tool-tip
+ 0x00001000=licence-key
+ 0x00002000=control-source
+ 0x00004000=row-source
+end
+
+flagslist=VBA-FORMSITE-FLAGS
+ 0x00000001=tabstop
+ 0x00000002=visible
+ 0x00000004=default
+ 0x00000008=cancel
+ 0x00000010=!storage!obj-stream
+ 0x00000020=auto-size
+ 0x00000100=preserve-height
+ 0x00000200=fit-to-parent
+ 0x00002000=select-child
+ 0x00040000=container
+end
+
+combilist=VBA-FORMSITE-CLASSIDCACHE
+ 0x7FFF=uint16,dec,cache-idx,VBA-FORMSITE-CLASSIDCACHEINDEX,filter=0x8000~0x0000
+ 0x7FFF=uint16,dec,class-table-idx,,filter=0x8000~0x8000
+ 0x8000=!predefined-class-id!class-table-index
+end
+
+constlist=VBA-FORMSITE-CLASSNAMES
+ 7=Forms.Form.1
+ 12=Forms.Image.1
+ 14=Forms.Frame.1
+ 15=Internal.MorphData
+ 16=Forms.SpinButton.1
+ 17=Forms.CommandButton.1
+ 18=Forms.TabStrip.1
+ 21=Forms.Label.1
+ 23=Forms.TextBox.1
+ 24=Forms.ListBox.1
+ 25=Forms.ComboBox.1
+ 26=Forms.CheckBox.1
+ 27=Forms.OptionButton.1
+ 28=Forms.ToggleButton.1
+ 47=Forms.ScrollBar.1
+ 57=Forms.MultiPage.1
+end
+
+constlist=VBA-FORMSITE-CLASSIDCACHEINDEX
+ include=VBA-FORMSITE-CLASSNAMES
+ 0x7FFF=invalid
+end
+
+# form design extender ------------------------------------------------------
+
+flagslist=VBA-FORMDESIGNEXT-PROPERTIES
+ 0x00000001=flags
+ 0x00000002=grid-x
+ 0x00000004=grid-y
+ 0x00000008=click-control-mode
+ 0x00000010=dblclick-control-mode
+end
+
+flagslist=VBA-FORMDESIGNEXT-FLAGS
+ 0x00000001=inherit-design-mode
+ 0x00000002=design-mode
+ 0x00000004=inherit-show-toolbox
+ 0x00000008=show-toolbox
+ 0x00000010=inherit-show-grid
+ 0x00000020=show-grid
+ 0x00000040=inherit-snap-to-grid
+ 0x00000080=snap-to-grid
+ 0x00000100=inherit-grid-x
+ 0x00000200=inherit-grid-y
+ 0x00000400=inherit-click-control-mode
+ 0x00000800=inherit-dblclick-control-mode
+ 0x00001000=inherit-show-invisible
+ 0x00002000=show-invisible
+ 0x00004000=inherit-show-tooltips
+ 0x00008000=show-tooltips
+ 0x00010000=inherit-immediate-layout
+ 0x00020000=immediate-layout
+end
+
+shortlist=VBA-FORMDESIGNEXT-CLICKCTRLMODE,-2,inherit,default,insertion-point,select-then-insert
+shortlist=VBA-FORMDESIGNEXT-DBLCLICKCTRLMODE,-2,inherit,,select-text,edit-code,edit-properties
+
+# form -----------------------------------------------------------------------
+
+{C62A69F0-16DC-11CE-9E98-00AA00574A4F}=Forms.Form.1
+{6E182020-F460-11CE-9BCD-00AA00608E01}=Forms.Frame.1
+
+flagslist=VBA-FORM-PROPERTIES
+ 0x00000002=fill-color
+ 0x00000004=text-color
+ 0x00000008=next-available-id
+ 0x00000040=flags
+ 0x00000080=border-style
+ 0x00000100=mouse-ptr
+ 0x00000200=scrollbars
+ 0x00000400=display-size
+ 0x00000800=logical-size
+ 0x00001000=scroll-pos
+ 0x00002000=group-count
+ 0x00008000=mouse-icon
+ 0x00010000=cycle
+ 0x00020000=special-effect
+ 0x00040000=border-color
+ 0x00080000=caption
+ 0x00100000=font
+ 0x00200000=image
+ 0x00400000=zoom
+ 0x00800000=image-align
+ 0x01000000=image-tiling
+ 0x02000000=image-sizemode
+ 0x04000000=shape-cookie
+ 0x08000000=draw-buffer
+end
+
+flagslist=VBA-FORM-FLAGS
+ 0x00000004=enabled
+ 0x00004000=has-design-extender
+ 0x00008000=!has-class-table!skip-class-table
+end
+
+flagslist=VBA-FORM-SCROLLBARS
+ 0x01=horizontal
+ 0x02=vertical
+ 0x04=keep-horizontal
+ 0x08=keep-vertical
+ 0x10=vertical-left
+end
+
+shortlist=VBA-FORM-CYCLE,0,all-forms,,current-form
+
+combilist=VBA-FORM-SITE-TYPECOUNT
+ 0x7F=uint8,dec,type-count
+ 0x80=!type!count
+end
+
+# page -----------------------------------------------------------------------
+
+flagslist=VBA-PAGE-PROPERTIES
+ 0x00000002=transition-effect
+ 0x00000004=transition-period
+end
+
+shortlist=VBA-PAGE-TRANSITIONEFFECT,0,none,cover-up,cover-right-up,cover-right,cover-right-down,cover-down,cover-left-down,cover-left,cover-left-up,push-up,push-right,push-down,push-left
+
+# multi page -----------------------------------------------------------------
+
+{46E31370-3F7A-11CE-BED6-00AA00611080}=Forms.MultiPage.1
+
+flagslist=VBA-MULTIPAGE-PROPERTIES
+ 0x00000002=page-count
+ 0x00000004=id
+ 0x00000008=enabled
+end
+
+# VBA project name lists =====================================================
+
+multilist=VBA-DIR-RECORD-NAMES
+ 0x0000=,PROJECTSYSKIND,PROJECTLCID,PROJECTCODEPAGE,PROJECTNAME,PROJECTDOCSTRING,PROJECTHELPFILEPATH1,PROJECTHELPCONTEXT
+ 0x0008=PROJECTLIBFLAGS,PROJECTVERSION,,,PROJECTCONSTANTS,REFERENCEREGISTERED,REFERENCEPROJECT,PROJECTMODULES
+ 0x0010=PROJECTEND,,,PROJECTCOOKIE,PROJECTLCIDINVOKE,,REFERENCENAME,
+ 0x0018=,MODULENAME,MODULESTREAMNAME,,MODULEDOCSTRING,,MODULEHELPCONTEXT,
+ 0x0020=,MODULETYPEPROCEDURAL,MODULETYPEDOCUMENT,,,MODULEREADONLY,,
+ 0x0028=MODULEPRIVATE,,,MODULEEND,MODULECOOKIE,,,REFERENCECONTROL
+ 0x0030=REFERENCEEXTENDED,MODULEOFFSET,MODULESTREAMNAMEUNICODE,REFERENCEORIGINAL,,,,
+ 0x0038=,,,,PROJECTCONSTANTSUNICODE,PROJECTHELPFILEPATH2,REFERENCENAMEUNICODE,
+ 0x0040=PROJECTDOCSTRINGUNICODE,,,,,,,MODULENAMEUNICODE
+ 0x0048=MODULEDOCSTRINGUNICODE,,,,,,,
+end
+
+constlist=VBA-DIR-SIMPLE-RECORDS
+ 0x0001=uint32,dec,platform,VBA-DIR-PROJECTSYSKIND-PLATFORM
+ 0x0002=uint32,hex,lang-id
+ 0x0007=uint32,dec,help-context-id
+ 0x0008=uint32,hex,libflags
+ 0x000F=uint16,dec,module-count
+ 0x0013=int16,dec,cookie
+ 0x0014=uint32,hex,lang-id
+ 0x001E=uint32,dec,help-context-id
+ 0x002C=int16,dec,cookie
+end
+
+shortlist=VBA-DIR-PROJECTSYSKIND-PLATFORM,0,16-bit-windows,32-bit-windows,macintosh
+
+# ============================================================================
diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx
new file mode 100644
index 000000000000..39e0ccc2be55
--- /dev/null
+++ b/oox/source/dump/pptxdumper.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/dump/pptxdumper.hxx"
+
+#include "oox/dump/biffdumper.hxx"
+#include "oox/dump/oledumper.hxx"
+#include "oox/dump/xlsbdumper.hxx"
+#include "oox/helper/zipstorage.hxx"
+#include "oox/ole/olestorage.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+namespace pptx {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::comphelper::MediaDescriptor;
+using ::oox::core::FilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
+RootStorageObject::RootStorageObject( const DumperBase& rParent )
+{
+ StorageObjectBase::construct( rParent );
+}
+
+void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName );
+ Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm );
+ if( aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "potx" ) )
+ {
+ Dumper( getFactory(), xInStrm, rSysFileName ).dump();
+ }
+ else if(
+ aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlsm" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlsx" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) )
+ {
+ ::oox::dump::xlsb::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
+ }
+ else if(
+ aExt.equalsIgnoreAsciiCaseAscii( "xla" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlc" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlm" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xls" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) )
+ {
+ ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
+ }
+ else if(
+ aExt.equalsIgnoreAsciiCaseAscii( "xml" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "vml" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "rels" ) )
+ {
+ XmlStreamObject( *this, rxStrm, rSysFileName ).dump();
+ }
+ else if( aExt.equalsIgnoreAsciiCaseAscii( "bin" ) )
+ {
+ if( rStrgPath.equalsAscii( "ppt" ) && rStrmName.equalsAscii( "vbaProject.bin" ) )
+ {
+ StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
+ VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else if( rStrgPath.equalsAscii( "ppt/embeddings" ) )
+ {
+ StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
+ OleStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else if( rStrgPath.equalsAscii( "ppt/activeX" ) )
+ {
+ StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) );
+ ActiveXStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else
+ {
+ BinaryStreamObject( *this, rxStrm, rSysFileName ).dump();
+ }
+ }
+}
+
+// ============================================================================
+
+#define DUMP_PPTX_CONFIG_ENVVAR "OOO_PPTXDUMPER"
+
+Dumper::Dumper( const FilterBase& rFilter )
+{
+ ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rFilter ) );
+ DumperBase::construct( xCfg );
+}
+
+Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
+{
+ if( rxFactory.is() && rxInStrm.is() )
+ {
+ StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) );
+ MediaDescriptor aMediaDesc;
+ ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
+ DumperBase::construct( xCfg );
+ }
+}
+
+void Dumper::implDump()
+{
+ RootStorageObject( *this ).dump();
+}
+
+// ============================================================================
+
+} // namespace pptx
+} // namespace dump
+} // namespace oox
+
+#endif
diff --git a/oox/source/dump/pptxdumper.ini b/oox/source/dump/pptxdumper.ini
new file mode 100644
index 000000000000..f3c058ecfbf5
--- /dev/null
+++ b/oox/source/dump/pptxdumper.ini
@@ -0,0 +1,18 @@
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+
+# Enable entire dumper (default=off). This option does not affect the option
+# 'enable-import'.
+# 0=off, 1=on, missing: setting from dumperbase.ini
+# 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, missing: setting from dumperbase.ini
+# enable-import=1
+
+# ============================================================================
diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx
new file mode 100644
index 000000000000..3dc2974420a6
--- /dev/null
+++ b/oox/source/dump/xlsbdumper.cxx
@@ -0,0 +1,2340 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/dump/xlsbdumper.hxx"
+
+#include <com/sun/star/io/XTextInputStream.hpp>
+#include "oox/core/filterbase.hxx"
+#include "oox/dump/biffdumper.hxx"
+#include "oox/dump/oledumper.hxx"
+#include "oox/dump/pptxdumper.hxx"
+#include "oox/helper/zipstorage.hxx"
+#include "oox/ole/olestorage.hxx"
+#include "oox/xls/biffhelper.hxx"
+#include "oox/xls/formulabase.hxx"
+#include "oox/xls/richstring.hxx"
+
+#if OOX_INCLUDE_DUMPER
+
+namespace oox {
+namespace dump {
+namespace xlsb {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::oox::xls;
+
+using ::comphelper::MediaDescriptor;
+using ::oox::core::FilterBase;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt8 BIFF12_STRINGFLAG_FONTS = 0x01;
+const sal_uInt8 BIFF12_STRINGFLAG_PHONETICS = 0x02;
+
+const sal_uInt16 BIFF12_OLEOBJECT_LINKED = 0x0001;
+
+} // namespace
+
+// ============================================================================
+
+RecordObjectBase::RecordObjectBase()
+{
+}
+
+RecordObjectBase::~RecordObjectBase()
+{
+}
+
+void RecordObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ mxBiffStrm.reset( new SequenceInputStream( getRecordDataSequence() ) );
+ SequenceRecordObjectBase::construct( rParent, rxStrm, rSysFileName, mxBiffStrm, "RECORD-NAMES", "SIMPLE-RECORDS" );
+ if( SequenceRecordObjectBase::implIsValid() )
+ mxErrCodes = cfg().getNameList( "ERRORCODES" );
+}
+
+void RecordObjectBase::construct( const RecordObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool RecordObjectBase::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ sal_Int32 nRecId = 0, nRecSize = 0;
+ bool bValid = readCompressedInt( rBaseStrm, nRecId ) && (nRecId >= 0) && readCompressedInt( rBaseStrm, nRecSize ) && (nRecSize >= 0);
+ ornRecId = nRecId;
+ ornRecSize = nRecSize;
+ return bValid;
+}
+
+OUString RecordObjectBase::getErrorName( sal_uInt8 nErrCode ) const
+{
+ return cfg().getName( mxErrCodes, nErrCode );
+}
+
+// ------------------------------------------------------------------------
+
+void RecordObjectBase::readAddress( Address& orAddress )
+{
+ *mxStrm >> orAddress.mnRow >> orAddress.mnCol;
+}
+
+void RecordObjectBase::readRange( Range& orRange )
+{
+ *mxStrm >> orRange.maFirst.mnRow >> orRange.maLast.mnRow >> orRange.maFirst.mnCol >> orRange.maLast.mnCol;
+}
+
+void RecordObjectBase::readRangeList( RangeList& orRanges )
+{
+ sal_Int32 nCount;
+ *mxStrm >> 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(); !mxStrm->isEof() && (aIt != aEnd); ++aIt )
+ readRange( *aIt );
+ }
+ else
+ orRanges.clear();
+}
+
+// ----------------------------------------------------------------------------
+
+void RecordObjectBase::writeBooleanItem( const String& rName, sal_uInt8 nBool )
+{
+ writeDecItem( rName, nBool, "BOOLEAN" );
+}
+
+void RecordObjectBase::writeErrorCodeItem( const String& rName, sal_uInt8 nErrCode )
+{
+ writeHexItem( rName, nErrCode, mxErrCodes );
+}
+
+void RecordObjectBase::writeFontPortions( const FontPortionModelList& rPortions )
+{
+ if( !rPortions.empty() )
+ {
+ writeDecItem( "font-count", static_cast< sal_uInt32 >( rPortions.size() ) );
+ IndentGuard aIndGuard( mxOut );
+ TableGuard aTabGuard( mxOut, 14 );
+ for( FontPortionModelList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeDecItem( "char-pos", aIt->mnPos );
+ writeDecItem( "font-id", aIt->mnFontId, "FONTNAMES" );
+ }
+ }
+}
+
+void RecordObjectBase::writePhoneticPortions( const PhoneticPortionModelList& rPortions )
+{
+ if( !rPortions.empty() )
+ {
+ writeDecItem( "portion-count", static_cast< sal_uInt32 >( rPortions.size() ) );
+ IndentGuard aIndGuard( mxOut );
+ TableGuard aTabGuard( mxOut, 14, 21 );
+ for( PhoneticPortionModelList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeDecItem( "char-pos", aIt->mnPos );
+ writeDecItem( "base-text-start", aIt->mnBasePos );
+ writeDecItem( "base-text-length", aIt->mnBaseLen );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+sal_uInt8 RecordObjectBase::dumpBoolean( const String& rName )
+{
+ sal_uInt8 nBool;
+ *mxStrm >> nBool;
+ writeBooleanItem( rName( "boolean" ), nBool );
+ return nBool;
+}
+
+sal_uInt8 RecordObjectBase::dumpErrorCode( const String& rName )
+{
+ sal_uInt8 nErrCode;
+ *mxStrm >> nErrCode;
+ writeErrorCodeItem( rName( "error-code" ), nErrCode );
+ return nErrCode;
+}
+
+OUString RecordObjectBase::dumpString( const String& rName, bool bRich, bool b32BitLen )
+{
+ sal_uInt8 nFlags = bRich ? dumpHex< sal_uInt8 >( "flags", "STRING-FLAGS" ) : 0;
+
+ OUString aString = BiffHelper::readString( *mxBiffStrm, b32BitLen );
+ writeStringItem( rName( "text" ), aString );
+
+ // --- formatting ---
+ if( getFlag( nFlags, BIFF12_STRINGFLAG_FONTS ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ FontPortionModelList aPortions;
+ aPortions.importPortions( *mxBiffStrm );
+ writeFontPortions( aPortions );
+ }
+
+ // --- phonetic text ---
+ if( getFlag( nFlags, BIFF12_STRINGFLAG_PHONETICS ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ dumpString( "phonetic-text" );
+ PhoneticPortionModelList aPortions;
+ aPortions.importPortions( *mxBiffStrm );
+ writePhoneticPortions( aPortions );
+ dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
+ dumpHex< sal_uInt16 >( "flags", "PHONETIC-FLAGS" );
+ }
+
+ return aString;
+}
+
+void RecordObjectBase::dumpColor( const String& rName )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( rName( "color" ) );
+ switch( extractValue< sal_uInt8 >( dumpDec< sal_uInt8 >( "flags", "COLOR-FLAGS" ), 1, 7 ) )
+ {
+ case 0: dumpUnused( 1 ); break;
+ case 1: dumpDec< sal_uInt8 >( "index", "PALETTE-COLORS" ); break;
+ case 2: dumpUnused( 1 ); break;
+ case 3: dumpDec< sal_uInt8 >( "theme-id" ); break;
+ default: dumpUnknown( 1 );
+ }
+ dumpDec< sal_Int16 >( "tint", "CONV-TINT" );
+ dumpColorABGR();
+}
+
+DateTime RecordObjectBase::dumpPivotDateTime( const String& rName )
+{
+ DateTime aDateTime;
+ aDateTime.Year = mxStrm->readuInt16();
+ aDateTime.Month = mxStrm->readuInt16();
+ aDateTime.Day = mxStrm->readuInt8();
+ aDateTime.Hours = mxStrm->readuInt8();
+ aDateTime.Minutes = mxStrm->readuInt8();
+ aDateTime.Seconds = mxStrm->readuInt8();
+ writeDateTimeItem( rName, aDateTime );
+ return aDateTime;
+}
+
+sal_Int32 RecordObjectBase::dumpColIndex( const String& rName )
+{
+ sal_Int32 nCol;
+ *mxStrm >> nCol;
+ writeColIndexItem( rName( "col-idx" ), nCol );
+ return nCol;
+}
+
+sal_Int32 RecordObjectBase::dumpRowIndex( const String& rName )
+{
+ sal_Int32 nRow;
+ *mxStrm >> nRow;
+ writeRowIndexItem( rName( "row-idx" ), nRow );
+ return nRow;
+}
+
+sal_Int32 RecordObjectBase::dumpColRange( const String& rName )
+{
+ sal_Int32 nCol1, nCol2;
+ *mxStrm >> nCol1 >> nCol2;
+ writeColRangeItem( rName( "col-range" ), nCol1, nCol2 );
+ return nCol2 - nCol1 + 1;
+}
+
+sal_Int32 RecordObjectBase::dumpRowRange( const String& rName )
+{
+ sal_Int32 nRow1, nRow2;
+ *mxStrm >> nRow1 >> nRow2;
+ writeRowRangeItem( rName( "row-range" ), nRow1, nRow2 );
+ return nRow2 - nRow1 + 1;
+}
+
+Address RecordObjectBase::dumpAddress( const String& rName )
+{
+ Address aPos;
+ readAddress( aPos );
+ writeAddressItem( rName( "addr" ), aPos );
+ return aPos;
+}
+
+Range RecordObjectBase::dumpRange( const String& rName )
+{
+ Range aRange;
+ readRange( aRange );
+ writeRangeItem( rName( "range" ), aRange );
+ return aRange;
+}
+
+void RecordObjectBase::dumpRangeList( const String& rName )
+{
+ RangeList aRanges;
+ readRangeList( aRanges );
+ writeRangeListItem( rName( "range-list" ), aRanges );
+}
+
+// private --------------------------------------------------------------------
+
+bool RecordObjectBase::readCompressedInt( BinaryInputStream& rStrm, sal_Int32& ornValue )
+{
+ ornValue = 0;
+ sal_uInt8 nByte;
+ rStrm >> nByte;
+ ornValue = nByte & 0x7F;
+ if( (nByte & 0x80) != 0 )
+ {
+ rStrm >> nByte;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 7;
+ if( (nByte & 0x80) != 0 )
+ {
+ rStrm >> nByte;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 14;
+ if( (nByte & 0x80) != 0 )
+ {
+ rStrm >> nByte;
+ ornValue |= sal_Int32( nByte & 0x7F ) << 21;
+ }
+ }
+ }
+ return !rStrm.isEof();
+}
+
+// ============================================================================
+
+FormulaObject::FormulaObject( const RecordObjectBase& rParent ) :
+ mnSize( 0 )
+{
+ RecordObjectBase::construct( rParent );
+ constructFmlaObj();
+}
+
+FormulaObject::~FormulaObject()
+{
+}
+
+void FormulaObject::dumpCellFormula( const String& rName )
+{
+ dumpFormula( rName, false );
+}
+
+void FormulaObject::dumpNameFormula( const String& rName )
+{
+ dumpFormula( rName, true );
+}
+
+void FormulaObject::implDump()
+{
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( maName );
+ writeDecItem( "formula-size", mnSize );
+ }
+ if( mnSize < 0 ) return;
+
+ sal_Int64 nStartPos = mxStrm->tell();
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() );
+
+ bool bValid = mxTokens.get();
+ mxStack.reset( new FormulaStack );
+ maAddData.clear();
+ IndentGuard aIndGuard( mxOut );
+ {
+ TableGuard aTabGuard( mxOut, 8, 18 );
+ while( bValid && (mxStrm->tell() < nEndPos) )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeHexItem( EMPTY_STRING, static_cast< sal_uInt16 >( mxStrm->tell() - nStartPos ) );
+ sal_uInt8 nTokenId = dumpHex< sal_uInt8 >( EMPTY_STRING, 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 == mxStrm->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 - mxStrm->tell() ), false );
+ sal_Int32 nAddDataSize = dumpDec< sal_Int32 >( "add-data-size" );
+ dumpBinary( "add-data", nAddDataSize, false );
+ }
+
+ mnSize = 0;
+}
+
+void FormulaObject::dumpFormula( const String& rName, bool bNameMode )
+{
+ maName = rName( "formula" );
+ *mxStrm >> mnSize;
+ mbNameMode = bNameMode;
+ dump();
+}
+
+// private --------------------------------------------------------------------
+
+void FormulaObject::constructFmlaObj()
+{
+ if( RecordObjectBase::implIsValid() )
+ {
+ mxFuncProv.reset( new FunctionProvider( FILTER_OOXML, BIFF_UNKNOWN, 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 aItem( mxOut, "func-id" );
+ writeHexItem( EMPTY_STRING, nFuncId, "FUNCID" );
+ OUStringBuffer aBuffer;
+ const FunctionInfo* pFuncInfo = mxFuncProv->getFuncInfoFromBiff12FuncId( 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();
+ aItem.cont();
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+ mxOut->writeString( aFuncName );
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+ if( oppFuncInfo ) *oppFuncInfo = pFuncInfo;
+ return aFuncName;
+}
+
+sal_Int32 FormulaObject::dumpTokenCol( const String& rName, bool& rbRelC, bool& rbRelR )
+{
+ sal_uInt16 nCol = dumpHex< sal_uInt16 >( rName, mxRelFlags );
+ rbRelC = getFlag( nCol, BIFF12_TOK_REF_COLREL );
+ rbRelR = getFlag( nCol, BIFF12_TOK_REF_ROWREL );
+ nCol &= BIFF12_TOK_REF_COLMASK;
+ return nCol;
+}
+
+sal_Int32 FormulaObject::dumpTokenRow( const String& rName )
+{
+ return dumpDec< sal_Int32 >( rName );
+}
+
+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( mxOut->getLastItemValue() );
+}
+
+void FormulaObject::dumpDoubleToken()
+{
+ dumpDec< double >( "value" );
+ mxStack->pushOperand( mxOut->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( mxOut->getLastItemValue() );
+}
+
+void FormulaObject::dumpErrorToken()
+{
+ dumpErrorCode( "value" );
+ mxStack->pushOperand( mxOut->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( mxOut->getLastItemValue() ), rTokClass );
+}
+
+void FormulaObject::dumpAreaToken( const OUString& rTokClass, bool bNameMode )
+{
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRangeItem( "range", aRange, bNameMode );
+ mxStack->pushOperand( createRef( mxOut->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( mxOut->getLastItemValue(), rTokClass );
+}
+
+void FormulaObject::dumpArea3dToken( const OUString& rTokClass, bool bNameMode )
+{
+ OUString aRef = dumpTokenRefId();
+ TokenRange aRange = dumpTokenRange( bNameMode );
+ writeTokenRange3dItem( "range", aRef, aRange, bNameMode );
+ mxStack->pushOperand( mxOut->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 String& rName )
+{
+ Address aPos;
+ dumpRowIndex( "base-row" );
+ OUStringBuffer aOp( rName );
+ StringHelper::appendIndex( aOp, createPlaceHolder() + mxOut->getLastItemValue() );
+ mxStack->pushOperand( aOp.makeStringAndClear() );
+ maAddData.push_back( ADDDATA_EXP );
+}
+
+void FormulaObject::dumpUnaryOpToken( const String& rLOp, const String& rROp )
+{
+ mxStack->pushUnaryOp( rLOp, rROp );
+}
+
+void FormulaObject::dumpBinaryOpToken( const String& rOp )
+{
+ mxStack->pushBinaryOp( rOp );
+}
+
+void FormulaObject::dumpFuncToken( const OUString& rTokClass )
+{
+ sal_uInt16 nFuncId;
+ *mxStrm >> 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;
+ *mxStrm >> 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()
+{
+ dumpUnused( 3 );
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "TABLEFLAGS" );
+ sal_uInt16 nTabId = dumpDec< sal_uInt16 >( "table-id" );
+ dumpUnused( 2 );
+ {
+ sal_uInt16 nCol1, nCol2;
+ *mxStrm >> nCol1 >> nCol2;
+ ItemGuard aItem( mxOut, "cols" );
+ mxOut->writeDec( nCol1 );
+ if( nCol1 != nCol2 )
+ {
+ mxOut->writeChar( OOX_DUMP_RANGESEP );
+ mxOut->writeDec( nCol2 );
+ }
+ }
+ OUStringBuffer aColRange;
+ StringHelper::appendIndex( aColRange, mxOut->getLastItemValue() );
+ OUStringBuffer aParams;
+ size_t nParams = 0;
+ if( getFlag( nFlags, BIFF12_TOK_TABLE_ALL ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#All]" ) );
+ if( getFlag( nFlags, BIFF12_TOK_TABLE_HEADERS ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Headers]" ) );
+ if( getFlag( nFlags, BIFF12_TOK_TABLE_DATA ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Data]" ) );
+ if( getFlag( nFlags, BIFF12_TOK_TABLE_TOTALS ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Totals]" ) );
+ if( getFlag( nFlags, BIFF12_TOK_TABLE_THISROW ) && ++nParams )
+ StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#This Row]" ) );
+ if( (getFlag( nFlags, BIFF12_TOK_TABLE_COLUMN ) || getFlag( nFlags, BIFF12_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 BIFF_TOK_ATTR_VOLATILE:
+ dumpUnused( 2 );
+ break;
+ case BIFF_TOK_ATTR_IF:
+ dumpDec< sal_uInt16 >( "skip" );
+ break;
+ case BIFF_TOK_ATTR_CHOOSE:
+ {
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "choices" );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
+ dumpDec< sal_uInt16 >( "#skip" );
+ dumpDec< sal_uInt16 >( "skip-err" );
+ }
+ break;
+ case BIFF_TOK_ATTR_SKIP:
+ dumpDec< sal_uInt16 >( "skip" );
+ break;
+ case BIFF_TOK_ATTR_SUM:
+ dumpUnused( 2 );
+ mxStack->pushFuncOp( CREATE_OUSTRING( "SUM" ), OUString( OOX_DUMP_BASECLASS ), 1 );
+ break;
+ case BIFF_TOK_ATTR_ASSIGN:
+ dumpUnused( 2 );
+ break;
+ case BIFF_TOK_ATTR_SPACE:
+ case BIFF_TOK_ATTR_SPACE | BIFF_TOK_ATTR_VOLATILE:
+ dumpDec< sal_uInt8 >( "char-type", mxSpTypes );
+ dumpDec< sal_uInt8 >( "char-count" );
+ break;
+ case BIFF_TOK_ATTR_IFERROR:
+ dumpDec< sal_uInt16 >( "skip" );
+ break;
+ default:
+ bValid = false;
+ }
+ return bValid;
+}
+
+void FormulaObject::dumpAddTokenData()
+{
+ mxOut->resetItemIndex();
+ sal_Int32 nAddDataSize = (mxStrm->getLength() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0;
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->getLength() );
+ for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); (aIt != aEnd) && !mxStrm->isEof() && (mxStrm->tell() < nEndPos); ++aIt )
+ {
+ AddDataType eType = *aIt;
+
+ {
+ ItemGuard aItem( mxOut, "#add-data" );
+ switch( eType )
+ {
+ case ADDDATA_EXP: mxOut->writeAscii( "tExp" ); break;
+ case ADDDATA_ARRAY: mxOut->writeAscii( "tArray" ); break;
+ case ADDDATA_MEMAREA: mxOut->writeAscii( "tMemArea" ); break;
+ }
+ }
+
+ size_t nIdx = aIt - maAddData.begin();
+ IndentGuard aIndGuard( mxOut );
+ 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 ), mxOut->getLastItemValue() );
+}
+
+void FormulaObject::dumpAddDataArray( size_t nIdx )
+{
+ sal_Int32 nCols, nRows;
+ dumpaddDataArrayHeader( nCols, nRows );
+
+ OUStringBuffer aOp;
+ TableGuard aTabGuard( mxOut, 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 )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ rnRows = dumpDec< sal_Int32 >( "height" );
+ rnCols = dumpDec< sal_Int32 >( "width" );
+ ItemGuard aItem( mxOut, "size" );
+ mxOut->writeDec( rnCols );
+ mxOut->writeChar( 'x' );
+ mxOut->writeDec( rnRows );
+ aItem.cont();
+ mxOut->writeDec( rnCols * rnRows );
+}
+
+OUString FormulaObject::dumpaddDataArrayValue()
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ OUStringBuffer aValue;
+ switch( dumpDec< sal_uInt8 >( "type", "ARRAYVALUE-TYPE" ) )
+ {
+ case BIFF_TOK_ARRAY_DOUBLE:
+ dumpDec< double >( "value" );
+ aValue.append( mxOut->getLastItemValue() );
+ break;
+ case BIFF_TOK_ARRAY_STRING:
+ aValue.append( dumpString( "value", false, false ) );
+ StringHelper::enclose( aValue, OOX_DUMP_STRQUOTE );
+ break;
+ case BIFF_TOK_ARRAY_BOOL:
+ dumpBoolean( "value" );
+ aValue.append( mxOut->getLastItemValue() );
+ break;
+ case BIFF_TOK_ARRAY_ERROR:
+ dumpErrorCode( "value" );
+ aValue.append( mxOut->getLastItemValue() );
+ dumpUnused( 3 );
+ break;
+ }
+ return aValue.makeStringAndClear();
+}
+
+// ============================================================================
+
+RecordStreamObject::RecordStreamObject( ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ RecordObjectBase::construct( rParent, rxStrm, rSysFileName );
+ if( RecordObjectBase::implIsValid() )
+ mxFmlaObj.reset( new FormulaObject( *this ) );
+}
+
+bool RecordStreamObject::implIsValid() const
+{
+ return isValid( mxFmlaObj ) && RecordObjectBase::implIsValid();
+}
+
+void RecordStreamObject::implDumpRecordBody()
+{
+ switch( getRecId() )
+ {
+ case BIFF12_ID_ARRAY:
+ dumpRange( "array-range" );
+ dumpHex< sal_uInt8 >( "flags", "ARRAY-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case BIFF12_ID_AUTOFILTER:
+ dumpRange( "filter-range" );
+ break;
+
+ case BIFF12_ID_BINARYINDEXBLOCK:
+ dumpRowRange( "row-range" );
+ dumpUnknown( 12 );
+ break;
+
+ case BIFF12_ID_BINARYINDEXROWS:
+ {
+ sal_uInt32 nUsedRows = dumpBin< sal_uInt32 >( "used-rows" );
+ dumpDec< sal_Int64 >( "stream-offset" );
+ for( ; nUsedRows > 0; nUsedRows >>= 1 )
+ if( (nUsedRows & 1) != 0 )
+ dumpBin< sal_uInt16 >( "used-columns" );
+ }
+ break;
+
+ case BIFF12_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 BIFF12_ID_BRK:
+ dumpDec< sal_Int32 >( "id" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpDec< sal_Int32 >( "manual-break", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "pivot-break", "BOOLEAN" );
+ break;
+
+ case BIFF12_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 BIFF12_ID_CELL_BLANK:
+ dumpCellHeader( true );
+ break;
+
+ case BIFF12_ID_CELL_BOOL:
+ dumpCellHeader( true );
+ dumpBoolean();
+ break;
+
+ case BIFF12_ID_CELL_DOUBLE:
+ dumpCellHeader( true );
+ dumpDec< double >( "value" );
+ break;
+
+ case BIFF12_ID_CELL_ERROR:
+ dumpCellHeader( true );
+ dumpErrorCode();
+ break;
+
+ case BIFF12_ID_CELL_RK:
+ dumpCellHeader( true );
+ dumpRk( "value" );
+ break;
+
+ case BIFF12_ID_CELL_RSTRING:
+ dumpCellHeader( true );
+ dumpString( "value", true );
+ break;
+
+ case BIFF12_ID_CELL_SI:
+ dumpCellHeader( true );
+ dumpDec< sal_Int32 >( "string-id" );
+ break;
+
+ case BIFF12_ID_CELL_STRING:
+ dumpCellHeader( true );
+ dumpString( "value" );
+ break;
+
+ case BIFF12_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 BIFF12_ID_CFCOLOR:
+ dumpColor();
+ break;
+
+ case BIFF12_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-DATE-OPERATOR" ); break;
+ case 16: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 17: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 18: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 19: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 20: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 21: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 22: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 23: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
+ case 24: dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-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( mxStrm->getRemaining() >= 8 )
+ mxFmlaObj->dumpNameFormula( "formula1" );
+ if( mxStrm->getRemaining() >= 8 )
+ mxFmlaObj->dumpNameFormula( "formula2" );
+ if( mxStrm->getRemaining() >= 8 )
+ mxFmlaObj->dumpNameFormula( "formula3" );
+ }
+ break;
+
+ case BIFF12_ID_CHARTPAGESETUP:
+ dumpDec< sal_Int32 >( "paper-size", "PAGESETUP-PAPERSIZE" );
+ dumpDec< sal_Int32 >( "horizontal-res", "PAGESETUP-DPI" );
+ dumpDec< sal_Int32 >( "vertical-res", "PAGESETUP-DPI" );
+ dumpDec< sal_Int32 >( "copies" );
+ dumpDec< sal_uInt16 >( "first-page" );
+ dumpHex< sal_uInt16 >( "flags", "CHARTPAGESETUP-FLAGS" );
+ dumpString( "printer-settings-rel-id" );
+ break;
+
+ case BIFF12_ID_CHARTPROTECTION:
+ dumpHex< sal_uInt16 >( "password-hash" );
+ // no flags field for the boolean flags?!?
+ dumpDec< sal_Int32 >( "content-locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "objects-locked", "BOOLEAN" );
+ break;
+
+ case BIFF12_ID_CHARTSHEETPR:
+ dumpHex< sal_uInt16 >( "flags", "CHARTSHEETPR-FLAGS" );
+ dumpColor( "tab-color" );
+ dumpString( "codename" );
+ break;
+
+ case BIFF12_ID_CHARTSHEETVIEW:
+ dumpHex< sal_uInt16 >( "flags", "CHARTSHEETVIEW-FLAGS" );
+ dumpDec< sal_Int32 >( "zoom-scale", "CONV-PERCENT" );
+ dumpDec< sal_Int32 >( "workbookview-id" );
+ break;
+
+ case BIFF12_ID_COL:
+ dumpColRange();
+ dumpDec< sal_Int32 >( "col-width", "CONV-COLWIDTH" );
+ dumpDec< sal_Int32 >( "custom-xf-id" );
+ dumpHex< sal_uInt16 >( "flags", "COL-FLAGS" );
+ break;
+
+ case BIFF12_ID_COLBREAKS:
+ dumpDec< sal_Int32 >( "count" );
+ dumpDec< sal_Int32 >( "manual-count" );
+ break;
+
+ case BIFF12_ID_COLOR:
+ dumpColor();
+ break;
+
+ case BIFF12_ID_COMMENT:
+ dumpDec< sal_Int32 >( "author-id" );
+ dumpRange( "ref" );
+ dumpGuid();
+ break;
+
+ case BIFF12_ID_COMMENTAUTHOR:
+ dumpString( "author" );
+ break;
+
+ case BIFF12_ID_COMMENTTEXT:
+ dumpString( "text", true );
+ break;
+
+ case BIFF12_ID_CONDFORMATTING:
+ dumpDec< sal_Int32 >( "cfrule-count" );
+ dumpDec< sal_Int32 >( "pivot-table", "BOOLEAN" );
+ dumpRangeList();
+ break;
+
+ case BIFF12_ID_CONNECTION:
+ {
+ dumpDec< sal_uInt8 >( "refreshed-version" );
+ dumpDec< sal_uInt8 >( "min-refresh-version" );
+ dumpDec< sal_uInt8 >( "save-password", "CONNECTION-SAVEPASSWORD" );
+ dumpUnused( 1 );
+ dumpDec< sal_uInt16 >( "refresh-interval", "CONNECTION-INTERVAL" );
+ dumpHex< sal_uInt16 >( "flags", "CONNECTION-FLAGS" );
+ sal_uInt16 nStrFlags = dumpHex< sal_uInt16 >( "string-flags", "CONNECTION-STRINGFLAGS" );
+ dumpDec< sal_Int32 >( "data-source-type", "CONNECTION-SOURCETYPE" );
+ dumpDec< sal_Int32 >( "reconnect-type", "CONNECTION-RECONNECTTYPE" );
+ dumpDec< sal_Int32 >( "id" );
+ dumpDec< sal_uInt8 >( "credentials", "CONNECTION-CREDENTIALS" );
+ if( nStrFlags & 0x0001 ) dumpString( "source-file" );
+ if( nStrFlags & 0x0002 ) dumpString( "source-conn-file" );
+ if( nStrFlags & 0x0004 ) dumpString( "description" );
+ if( nStrFlags & 0x0008 ) dumpString( "name" );
+ if( nStrFlags & 0x0010 ) dumpString( "sso-id" );
+ }
+ break;
+
+ case BIFF12_ID_CONTROL:
+ dumpDec< sal_Int32 >( "shape-id" );
+ dumpString( "rel-id" );
+ dumpString( "name" );
+ break;
+
+ case BIFF12_ID_CUSTOMFILTER:
+ {
+ sal_uInt8 nType = dumpDec< sal_uInt8 >( "data-type", "CUSTOMFILTER-DATATYPE" );
+ dumpDec< sal_uInt8 >( "operator", "CUSTOMFILTER-OPERATOR" );
+ switch( nType )
+ {
+ case 4: dumpDec< double >( "value" ); break;
+ case 6: dumpUnused( 8 ); dumpString( "value" ); break;
+ case 8: dumpBoolean( "value" ); dumpUnused( 7 ); break;
+ default: dumpUnused( 8 );
+ }
+ }
+ break;
+
+ case BIFF12_ID_DATATABLE:
+ dumpRange( "table-range" );
+ dumpAddress( "ref1" );
+ dumpAddress( "ref2" );
+ dumpHex< sal_uInt8 >( "flags", "DATATABLE-FLAGS" );
+ break;
+
+ case BIFF12_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 BIFF12_ID_DATAVALIDATIONS:
+ dumpHex< sal_uInt16 >( "flags", "DATAVALIDATIONS-FLAGS" );
+ dumpDec< sal_Int32 >( "input-x" );
+ dumpDec< sal_Int32 >( "input-y" );
+ dumpUnused( 4 );
+ dumpDec< sal_Int32 >( "count" );
+ break;
+
+ case BIFF12_ID_DDEITEMVALUES:
+ dumpDec< sal_Int32 >( "rows" );
+ dumpDec< sal_Int32 >( "columns" );
+ break;
+
+ case BIFF12_ID_DDEITEM_STRING:
+ dumpString( "value" );
+ break;
+
+ case BIFF12_ID_DEFINEDNAME:
+ dumpHex< sal_uInt32 >( "flags", "DEFINEDNAME-FLAGS" );
+ dumpChar( "accelerator", RTL_TEXTENCODING_ISO_8859_1 );
+ dumpDec< sal_Int32 >( "sheet-id", "DEFINEDNAME-SHEETID" );
+ dumpString( "name" );
+ mxFmlaObj->dumpNameFormula();
+ dumpString( "comment" );
+ if( mxStrm->getRemaining() >= 4 ) dumpString( "menu-text" );
+ if( mxStrm->getRemaining() >= 4 ) dumpString( "description-text" );
+ if( mxStrm->getRemaining() >= 4 ) dumpString( "help-text" );
+ if( mxStrm->getRemaining() >= 4 ) dumpString( "statusbar-text" );
+ break;
+
+ case BIFF12_ID_DIMENSION:
+ dumpRange( "used-range" );
+ break;
+
+ case BIFF12_ID_DISCRETEFILTER:
+ dumpString( "value" );
+ break;
+
+ case BIFF12_ID_DISCRETEFILTERS:
+ dumpBool< sal_Int32 >( "show-blank" );
+ dumpDec< sal_Int32 >( "calendar-type", "DISCRETEFILTERS-CALTYPE" );
+ break;
+
+ case BIFF12_ID_DRAWING:
+ dumpString( "rel-id" );
+ break;
+
+ case BIFF12_ID_DXF:
+ dumpHex< sal_uInt32 >( "flags", "DXF-FLAGS" );
+ for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "subrec-count" ); !mxStrm->isEof() && (nIndex < nCount); ++nIndex )
+ {
+ mxOut->startMultiItems();
+ sal_Int64 nStartPos = mxStrm->tell();
+ writeEmptyItem( "SUBREC" );
+ sal_uInt16 nSubRecId = dumpDec< sal_uInt16 >( "id", "DXF-SUBREC" );
+ sal_uInt16 nSubRecSize = dumpDec< sal_uInt16 >( "size" );
+ sal_Int64 nEndPos = nStartPos + nSubRecSize;
+ mxOut->endMultiItems();
+ IndentGuard aIndGuard( mxOut );
+ switch( nSubRecId )
+ {
+ case 0:
+ dumpDec< sal_uInt8 >( "pattern", "FILLPATTERNS" );
+ break;
+ case 1: case 2: case 5:
+ dumpColor();
+ break;
+ case 3:
+ dumpGradientHead();
+ break;
+ case 4:
+ dumpDec< sal_uInt16 >( "index" );
+ dumpDec< double >( "stop-position" );
+ dumpColor( "stop-color" );
+ 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 34:
+ dumpDec< sal_uInt8 >( "charset", "CHARSET" );
+ break;
+ case 35:
+ dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
+ 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_Int16 >( "relative-indent" );
+ break;
+ case 43: case 44:
+ dumpBoolean( "value" );
+ break;
+ }
+ dumpRemainingTo( nEndPos );
+ }
+ break;
+
+ case BIFF12_ID_EXTCELL_BOOL:
+ dumpColIndex();
+ dumpBoolean();
+ break;
+
+ case BIFF12_ID_EXTCELL_DOUBLE:
+ dumpColIndex();
+ dumpDec< double >( "value" );
+ break;
+
+ case BIFF12_ID_EXTCELL_ERROR:
+ dumpColIndex();
+ dumpErrorCode();
+ break;
+
+ case BIFF12_ID_EXTCELL_STRING:
+ dumpColIndex();
+ dumpString( "value" );
+ break;
+
+ case BIFF12_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 BIFF12_ID_EXTERNALNAME:
+ dumpString( "name" );
+ break;
+
+ case BIFF12_ID_EXTERNALNAMEFLAGS:
+ dumpHex< sal_uInt16 >( "flags", "EXTERNALNAMEFLAGS-FLAGS" );
+ dumpDec< sal_Int32 >( "sheet-id" );
+ dumpBoolean( "is-dde-ole" );
+ break;
+
+ case BIFF12_ID_EXTERNALREF:
+ dumpString( "rel-id" );
+ break;
+
+ case BIFF12_ID_EXTERNALSHEETS:
+ {
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "ref-count" );
+ TableGuard aTabGuard( mxOut, 13, 17, 24 );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nRefId = 0; !mxStrm->isEof() && (nRefId < nCount); ++nRefId )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#ref" );
+ dumpDec< sal_Int32 >( "extref-id" );
+ dumpDec< sal_Int32 >( "first-sheet", "EXTERNALSHEETS-ID" );
+ dumpDec< sal_Int32 >( "last-sheet", "EXTERNALSHEETS-ID" );
+ }
+ }
+ break;
+
+ case BIFF12_ID_EXTROW:
+ dumpRowIndex();
+ break;
+
+ case BIFF12_ID_EXTSHEETDATA:
+ dumpDec< sal_Int32 >( "sheet-id" );
+ dumpHex< sal_uInt8 >( "flags", "EXTSHEETDATA-FLAGS" );
+ break;
+
+ case BIFF12_ID_EXTSHEETNAMES:
+ mxOut->resetItemIndex();
+ for( sal_Int32 nSheet = 0, nCount = dumpDec< sal_Int32 >( "sheet-count" ); !mxStrm->isEof() && (nSheet < nCount); ++nSheet )
+ dumpString( "#sheet-name" );
+ break;
+
+ case BIFF12_ID_FILESHARING:
+ dumpBool< sal_uInt16 >( "recommend-read-only" );
+ dumpHex< sal_uInt16 >( "password-hash" );
+ dumpString( "password-creator" );
+ break;
+
+ case BIFF12_ID_FILL:
+ dumpDec< sal_Int32 >( "fill-pattern", "FILLPATTERNS" );
+ dumpColor( "fg-color" );
+ dumpColor( "bg-color" );
+ dumpGradientHead();
+ mxOut->resetItemIndex();
+ for( sal_Int32 nStop = 0, nStopCount = dumpDec< sal_Int32 >( "stop-count" ); (nStop < nStopCount) && !mxStrm->isEof(); ++nStop )
+ {
+ writeEmptyItem( "#stop" );
+ IndentGuard aIndGuard( mxOut );
+ dumpColor( "stop-color" );
+ dumpDec< double >( "stop-position" );
+ }
+ break;
+
+ case BIFF12_ID_FILEVERSION:
+ dumpGuid( "codename" );
+ dumpString( "app-name" );
+ dumpString( "last-edited" );
+ dumpString( "lowest-edited" );
+ dumpString( "build-version" );
+ break;
+
+ case BIFF12_ID_FILTERCOLUMN:
+ dumpDec< sal_Int32 >( "column-index" );
+ dumpHex< sal_uInt16 >( "flags", "FILTERCOLUMN-FLAGS" );
+ break;
+
+ case BIFF12_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" );
+ dumpUnused( 1 );
+ dumpColor();
+ dumpDec< sal_uInt8 >( "scheme", "FONT-SCHEME" );
+ dumpString( "name" );
+ break;
+
+ case BIFF12_ID_FORMULA_BOOL:
+ dumpCellHeader( true );
+ dumpBoolean();
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case BIFF12_ID_FORMULA_DOUBLE:
+ dumpCellHeader( true );
+ dumpDec< double >( "value" );
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case BIFF12_ID_FORMULA_ERROR:
+ dumpCellHeader( true );
+ dumpErrorCode();
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case BIFF12_ID_FORMULA_STRING:
+ dumpCellHeader( true );
+ dumpString( "value" );
+ dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case BIFF12_ID_FUNCTIONGROUP:
+ dumpString( "name" );
+ break;
+
+ case BIFF12_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 BIFF12_ID_HYPERLINK:
+ dumpRange();
+ dumpString( "rel-id" );
+ dumpString( "location" );
+ dumpString( "tooltip" );
+ dumpString( "display" );
+ break;
+
+ case BIFF12_ID_INPUTCELLS:
+ dumpAddress( "pos" );
+ dumpUnused( 8 );
+ dumpDec< sal_uInt16 >( "numfmt-id" );
+ dumpString( "value" );
+ break;
+
+ case BIFF12_ID_LEGACYDRAWING:
+ dumpString( "rel-id" );
+ break;
+
+ case BIFF12_ID_MERGECELL:
+ dumpRange();
+ break;
+
+ case BIFF12_ID_MULTCELL_BLANK:
+ dumpCellHeader( false );
+ break;
+
+ case BIFF12_ID_MULTCELL_BOOL:
+ dumpCellHeader( false );
+ dumpBoolean();
+ break;
+
+ case BIFF12_ID_MULTCELL_DOUBLE:
+ dumpCellHeader( false );
+ dumpDec< double >( "value" );
+ break;
+
+ case BIFF12_ID_MULTCELL_ERROR:
+ dumpCellHeader( false );
+ dumpErrorCode();
+ break;
+
+ case BIFF12_ID_MULTCELL_RK:
+ dumpCellHeader( false );
+ dumpRk( "value" );
+ break;
+
+ case BIFF12_ID_MULTCELL_RSTRING:
+ dumpCellHeader( false );
+ dumpString( "value", true );
+ break;
+
+ case BIFF12_ID_MULTCELL_SI:
+ dumpCellHeader( false );
+ dumpDec< sal_Int32 >( "string-id" );
+ break;
+
+ case BIFF12_ID_MULTCELL_STRING:
+ dumpCellHeader( false );
+ dumpString( "value" );
+ break;
+
+ case BIFF12_ID_NUMFMT:
+ dumpDec< sal_uInt16 >( "numfmt-id" );
+ dumpString( "format" );
+ break;
+
+ case BIFF12_ID_OLEOBJECT:
+ {
+ dumpDec< sal_Int32 >( "aspect", "OLEOBJECT-ASPECT" );
+ dumpDec< sal_Int32 >( "update", "OLEOBJECT-UPDATE" );
+ dumpDec< sal_Int32 >( "shape-id" );
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "OLEOBJECT-FLAGS" );
+ dumpString( "prog-id" );
+ if( getFlag( nFlags, BIFF12_OLEOBJECT_LINKED ) )
+ mxFmlaObj->dumpNameFormula( "link" );
+ else
+ dumpString( "rel-id" );
+ }
+ break;
+
+ case BIFF12_ID_OLESIZE:
+ dumpRange( "visible-range" );
+ break;
+
+ case BIFF12_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 BIFF12_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 BIFF12_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 BIFF12_ID_PCDEFINITION:
+ {
+ dumpDec< sal_uInt8 >( "refreshed-version" );
+ dumpDec< sal_uInt8 >( "min-refresh-version" );
+ dumpDec< sal_uInt8 >( "created-version" );
+ dumpHex< sal_uInt8 >( "flags-1", "PCDEFINITION-FLAGS1" );
+ dumpDec< sal_Int32 >( "missing-items-limit", "PCDEFINITION-MISSINGITEMS" );
+ dumpDec< double >( "refreshed-date" );
+ sal_uInt8 nFlags2 = dumpHex< sal_uInt8 >( "flags-2", "PCDEFINITION-FLAGS2" );
+ dumpDec< sal_Int32 >( "record-count" );
+ if( nFlags2 & 0x01 ) dumpString( "refreshed-by" );
+ if( nFlags2 & 0x02 ) dumpString( "rel-id" );
+ }
+ break;
+
+ case BIFF12_ID_PCDFIELD:
+ {
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PCDFIELD-FLAGS" );
+ dumpDec< sal_Int32 >( "numfmt-id" );
+ dumpDec< sal_Int16 >( "sql-datatype" );
+ dumpDec< sal_Int32 >( "hierarchy" );
+ dumpDec< sal_Int32 >( "hierarchy-level" );
+ sal_Int32 nMappingCount = dumpDec< sal_Int32 >( "property-mapping-count" );
+ dumpString( "name" );
+ if( nFlags & 0x0008 ) dumpString( "caption" );
+ if( nFlags & 0x0100 ) mxFmlaObj->dumpNameFormula( "formula" );
+ if( nMappingCount > 0 )
+ {
+ sal_Int32 nBytes = dumpDec< sal_Int32 >( "property-mapping-size" );
+ dumpArray( "property-mapping-indexes", nBytes );
+ }
+ if( nFlags & 0x0200 ) dumpString( "property-name" );
+ }
+ break;
+
+ case BIFF12_ID_PCDFIELDGROUP:
+ dumpDec< sal_Int32 >( "parent-field" );
+ dumpDec< sal_Int32 >( "base-field" );
+ break;
+
+ case BIFF12_ID_PCDFRANGEPR:
+ dumpDec< sal_uInt8 >( "group-by", "PCDFRANGEPR-GROUPBY" );
+ dumpHex< sal_uInt8 >( "flags", "PCDFRANGEPR-FLAGS" );
+ dumpDec< double >( "start-value" );
+ dumpDec< double >( "end-value" );
+ dumpDec< double >( "interval" );
+ break;
+
+ case BIFF12_ID_PCDFSHAREDITEMS:
+ {
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PCDFSHAREDITEMS-FLAGS" );
+ dumpDec< sal_Int32 >( "count" );
+ if( nFlags & 0x0100 ) dumpDec< double >( "min-value" );
+ if( nFlags & 0x0100 ) dumpDec< double >( "max-value" );
+ }
+ break;
+
+ case BIFF12_ID_PCDSHEETSOURCE:
+ {
+ sal_uInt8 nIsDefName = dumpBoolean( "is-def-name" );
+ dumpBoolean( "is-builtin-def-name" );
+ sal_uInt8 nFlags = dumpHex< sal_uInt8 >( "flags", "PCDWORKSHEETSOURCE-FLAGS" );
+ if( nFlags & 0x02 ) dumpString( "sheet-name" );
+ if( nFlags & 0x01 ) dumpString( "rel-id" );
+ if( nIsDefName == 0 ) dumpRange(); else dumpString( "def-name" );
+ }
+ break;
+
+ case BIFF12_ID_PCDSOURCE:
+ dumpDec< sal_Int32 >( "source-type", "PCDSOURCE-TYPE" );
+ dumpDec< sal_Int32 >( "connection-id" );
+ break;
+
+ case BIFF12_ID_PCITEM_ARRAY:
+ {
+ sal_uInt16 nType = dumpDec< sal_uInt16 >( "type", "PCITEM_ARRAY-TYPE" );
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
+ {
+ switch( nType )
+ {
+ case 1: dumpDec< double >( "#value" ); break;
+ case 2: dumpString( "#value" ); break;
+ case 16: dumpErrorCode( "#value" ); break;
+ case 32: dumpPivotDateTime( "#value" ); break;
+ default: nIdx = nCount;
+ }
+ }
+ }
+ break;
+
+ case BIFF12_ID_PCITEM_BOOL:
+ dumpBoolean( "value" );
+ break;
+
+ case BIFF12_ID_PCITEM_DATE:
+ dumpPivotDateTime( "value" );
+ break;
+
+ case BIFF12_ID_PCITEM_DOUBLE:
+ dumpDec< double >( "value" );
+ // TODO: server formatting
+ break;
+
+ case BIFF12_ID_PCITEM_ERROR:
+ dumpErrorCode( "value" );
+ // TODO: server formatting
+ break;
+
+ case BIFF12_ID_PCITEM_INDEX:
+ dumpDec< sal_Int32 >( "index" );
+ break;
+
+ case BIFF12_ID_PCITEM_MISSING:
+ // TODO: server formatting
+ break;
+
+
+ case BIFF12_ID_PCITEM_STRING:
+ dumpString( "value" );
+ // TODO: server formatting
+ break;
+
+ case BIFF12_ID_PCITEMA_BOOL:
+ dumpBoolean( "value" );
+ // TODO: additional info
+ break;
+
+ case BIFF12_ID_PCITEMA_DATE:
+ dumpPivotDateTime( "value" );
+ // TODO: additional info
+ break;
+
+ case BIFF12_ID_PCITEMA_DOUBLE:
+ dumpDec< double >( "value" );
+ // TODO: additional info
+ break;
+
+ case BIFF12_ID_PCITEMA_ERROR:
+ dumpErrorCode( "value" );
+ // TODO: additional info
+ break;
+
+ case BIFF12_ID_PCITEMA_MISSING:
+ // TODO: additional info
+ break;
+
+ case BIFF12_ID_PCITEMA_STRING:
+ dumpString( "value" );
+ // TODO: additional info
+ break;
+
+ case BIFF12_ID_PHONETICPR:
+ dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
+ dumpDec< sal_Int32 >( "type", "PHONETICPR-TYPE" );
+ dumpDec< sal_Int32 >( "alignment", "PHONETICPR-ALIGNMENT" );
+ break;
+
+ case BIFF12_ID_PICTURE:
+ dumpString( "rel-id" );
+ break;
+
+ case BIFF12_ID_PIVOTAREA:
+ dumpDec< sal_Int32 >( "field" );
+ dumpDec< sal_uInt8 >( "type", "PIVOTAREA-TYPE" );
+ dumpHex< sal_uInt8 >( "flags-1", "PIVOTAREA-FLAGS1" );
+ dumpHex< sal_uInt16 >( "flags-2", "PIVOTAREA-FLAGS2" );
+ break;
+
+ case BIFF12_ID_PIVOTCACHE:
+ dumpDec< sal_Int32 >( "cache-id" );
+ dumpString( "rel-id" );
+ break;
+
+ case BIFF12_ID_PTCOLFIELDS:
+ dumpDec< sal_Int32 >( "count" );
+ mxOut->resetItemIndex();
+ while( mxStrm->getRemaining() >= 4 )
+ dumpDec< sal_Int32 >( "#field", "PT-FIELDINDEX" );
+ break;
+
+ case BIFF12_ID_PTDATAFIELD:
+ dumpDec< sal_Int32 >( "field" );
+ dumpDec< sal_Int32 >( "subtotal", "PTDATAFIELD-SUBTOTAL" );
+ dumpDec< sal_Int32 >( "show-data-as", "PTDATAFIELD-SHOWDATAAS" );
+ dumpDec< sal_Int32 >( "base-field" );
+ dumpDec< sal_Int32 >( "base-item", "PTDATAFIELD-BASEITEM" );
+ dumpDec< sal_Int32 >( "number-format" );
+ if( dumpBool< sal_uInt8 >( "has-name" ) )
+ dumpString( "name" );
+ break;
+
+ case BIFF12_ID_PTDEFINITION:
+ {
+ dumpDec< sal_uInt8 >( "created-version" );
+ dumpHex< sal_uInt8 >( "flags-1", "PTDEFINITION-FLAGS1" );
+ dumpHex< sal_uInt16 >( "flags-2", "PTDEFINITION-FLAGS2" );
+ sal_uInt32 nFlags3 = dumpHex< sal_uInt32 >( "flags-3", "PTDEFINITION-FLAGS3" );
+ sal_uInt32 nFlags4 = dumpHex< sal_uInt32 >( "flags-4", "PTDEFINITION-FLAGS4" );
+ dumpDec< sal_uInt8 >( "datafield-axis", "PTDEFINITION-DATAFIELD-AXIS" );
+ dumpDec< sal_uInt8 >( "page-wrap" );
+ dumpDec< sal_uInt8 >( "refreshed-version" );
+ dumpDec< sal_uInt8 >( "min-refresh-version" );
+ dumpDec< sal_Int32 >( "datafield-position", "PTDEFINITION-DATAFIELD-POS" );
+ dumpDec< sal_Int16 >( "autoformat-id" );
+ dumpUnused( 2 );
+ dumpDec< sal_Int32 >( "next-chart-id" );
+ dumpDec< sal_Int32 >( "cache-id" );
+ dumpString( "name" );
+ if( nFlags3 & 0x00080000 ) dumpString( "data-caption" );
+ if( nFlags3 & 0x00100000 ) dumpString( "grand-total-caption" );
+ if( (nFlags4 & 0x00000040) == 0 ) dumpString( "error-caption" );
+ if( (nFlags4 & 0x00000080) == 0 ) dumpString( "missing-caption" );
+ if( nFlags3 & 0x00200000 ) dumpString( "page-field-style" );
+ if( nFlags3 & 0x00400000 ) dumpString( "pivot-table-style" );
+ if( nFlags3 & 0x00800000 ) dumpString( "vacated-style" );
+ if( nFlags3 & 0x40000000 ) dumpString( "tag" );
+ if( nFlags4 & 0x00000800 ) dumpString( "col-header-caption" );
+ if( nFlags4 & 0x00000400 ) dumpString( "row-header-caption" );
+ }
+ break;
+
+ case BIFF12_ID_PTFIELD:
+ dumpHex< sal_uInt32 >( "flags-1", "PTFIELD-FLAGS1" );
+ dumpDec< sal_Int32 >( "num-fmt" );
+ dumpHex< sal_uInt32 >( "flags-2", "PTFIELD-FLAGS2" );
+ dumpDec< sal_Int32 >( "autoshow-items" );
+ dumpDec< sal_Int32 >( "autoshow-datafield-idx" );
+ break;
+
+ case BIFF12_ID_PTFILTER:
+ {
+ dumpDec< sal_Int32 >( "field" );
+ dumpDec< sal_Int32 >( "member-prop-field" );
+ dumpDec< sal_Int32 >( "type", "PTFILTER-TYPE" );
+ dumpUnused( 4 );
+ dumpDec< sal_Int32 >( "unique-id" );
+ dumpDec< sal_Int32 >( "measure-data-field" );
+ dumpDec< sal_Int32 >( "measure-data-hierarchy" );
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PTFILTER-FLAGS" );
+ if( nFlags & 0x0001 ) dumpString( "name" );
+ if( nFlags & 0x0002 ) dumpString( "description" );
+ if( nFlags & 0x0004 ) dumpString( "str-value1" );
+ if( nFlags & 0x0008 ) dumpString( "str-value2" );
+ }
+ break;
+
+ case BIFF12_ID_PTFITEM:
+ {
+ dumpDec< sal_uInt8 >( "type", "PTFITEM-TYPE" );
+ sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PTFITEM-FLAGS" );
+ dumpDec< sal_Int32 >( "cache-idx" );
+ if( nFlags & 0x0010 ) dumpString( "display-name" );
+ }
+ break;
+
+ case BIFF12_ID_PTLOCATION:
+ dumpRange( "location" );
+ dumpDec< sal_Int32 >( "first-header-row" );
+ dumpDec< sal_Int32 >( "first-data-row" );
+ dumpDec< sal_Int32 >( "first-data-col" );
+ dumpDec< sal_Int32 >( "page-row-count" );
+ dumpDec< sal_Int32 >( "page-col-count" );
+ break;
+
+ case BIFF12_ID_PTPAGEFIELD:
+ {
+ dumpDec< sal_Int32 >( "field" );
+ dumpDec< sal_Int32 >( "cache-item", "PTPAGEFIELD-ITEM" );
+ dumpDec< sal_Int32 >( "olap-hierarchy" );
+ sal_uInt8 nFlags = dumpHex< sal_uInt8 >( "flags", "PTPAGEFIELD-FLAGS" );
+ if( nFlags & 0x01 ) dumpString( "unique-name" );
+ if( nFlags & 0x02 ) dumpString( "olap-caption" );
+ }
+ break;
+
+ case BIFF12_ID_PTREFERENCE:
+ dumpDec< sal_Int32 >( "field", "PT-FIELDINDEX" );
+ dumpDec< sal_Int32 >( "item-count" );
+ dumpHex< sal_uInt16 >( "flags-1", "PTREFERENCE-FLAGS1" );
+ dumpHex< sal_uInt8 >( "flags-2", "PTREFERENCE-FLAGS2" );
+ break;
+
+ case BIFF12_ID_PTROWFIELDS:
+ dumpDec< sal_Int32 >( "count" );
+ mxOut->resetItemIndex();
+ while( mxStrm->getRemaining() >= 4 )
+ dumpDec< sal_Int32 >( "#field", "PT-FIELDINDEX" );
+ break;
+
+ case BIFF12_ID_QUERYTABLE:
+ dumpHex< sal_uInt32 >( "flags", "QUERYTABLE-FLAGS" );
+ dumpDec< sal_uInt16 >( "autoformat-id" );
+ dumpDec< sal_Int32 >( "connection-id" );
+ dumpString( "defined-name" );
+ break;
+
+ case BIFF12_ID_ROW:
+ dumpRowIndex();
+ dumpDec< sal_Int32 >( "custom-xf-id" );
+ dumpDec< sal_uInt16 >( "height", "CONV-TWIP-TO-PT" );
+ dumpHex< sal_uInt16 >( "flags", "ROW-FLAGS1" );
+ dumpHex< sal_uInt8 >( "flags", "ROW-FLAGS2" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nSpan = 0, nSpanCount = dumpDec< sal_Int32 >( "row-spans-count" ); !mxStrm->isEof() && (nSpan < nSpanCount); ++nSpan )
+ dumpRowRange( "#row-spans" );
+ break;
+
+ case BIFF12_ID_ROWBREAKS:
+ dumpDec< sal_Int32 >( "count" );
+ dumpDec< sal_Int32 >( "manual-count" );
+ break;
+
+ case BIFF12_ID_SCENARIO:
+ dumpDec< sal_uInt16 >( "cell-count" );
+ // two longs instead of flag field
+ dumpDec< sal_Int32 >( "locked", "BOOLEAN" );
+ dumpDec< sal_Int32 >( "hidden", "BOOLEAN" );
+ dumpString( "name" );
+ dumpString( "comment" );
+ dumpString( "user" );
+ break;
+
+ case BIFF12_ID_SCENARIOS:
+ dumpDec< sal_uInt16 >( "selected" );
+ dumpDec< sal_uInt16 >( "shown" );
+ dumpRangeList( "result-cells" );
+ break;
+
+ case BIFF12_ID_SELECTION:
+ dumpDec< sal_Int32 >( "pane", "PANE-ID" );
+ dumpAddress( "active-cell" );
+ dumpDec< sal_Int32 >( "active-cell-id" );
+ dumpRangeList( "selection" );
+ break;
+
+ case BIFF12_ID_SHAREDFMLA:
+ dumpRange( "formula-range" );
+ mxFmlaObj->dumpCellFormula();
+ break;
+
+ case BIFF12_ID_SHEET:
+ dumpDec< sal_Int32 >( "sheet-state", "SHEET-STATE" );
+ dumpDec< sal_Int32 >( "sheet-id" );
+ dumpString( "rel-id" );
+ dumpString( "sheet-name" );
+ break;
+
+ case BIFF12_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 BIFF12_ID_SHEETPR:
+ dumpHex< sal_uInt16 >( "flags1", "SHEETPR-FLAGS1" );
+ dumpHex< sal_uInt8 >( "flags2", "SHEETPR-FLAGS2" );
+ dumpColor( "tab-color" );
+ dumpAddress( "window-anchor" );
+ dumpString( "codename" );
+ break;
+
+ case BIFF12_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 BIFF12_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 BIFF12_ID_SI:
+ dumpString( "string", true );
+ break;
+
+ case BIFF12_ID_SST:
+ dumpDec< sal_Int32 >( "string-cell-count" );
+ dumpDec< sal_Int32 >( "sst-size" );
+ break;
+
+ case BIFF12_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 BIFF12_ID_TABLEPART:
+ dumpString( "rel-id" );
+ break;
+
+ case BIFF12_ID_TABLESTYLEINFO:
+ dumpHex< sal_uInt16 >( "flags", "TABLESTYLEINFO-FLAGS" );
+ dumpString( "style-name" );
+ break;
+
+ case BIFF12_ID_TOP10FILTER:
+ dumpHex< sal_uInt8 >( "flags", "TOP10FILTER-FLAGS" );
+ dumpDec< double >( "value" );
+ dumpDec< double >( "cell-value" );
+ break;
+
+ case BIFF12_ID_VOLTYPEMAIN:
+ dumpString( "first" );
+ break;
+
+ case BIFF12_ID_VOLTYPESTP:
+ dumpString( "topic-value" );
+ break;
+
+ case BIFF12_ID_VOLTYPETR:
+ dumpAddress( "ref" );
+ dumpDec< sal_Int32 >( "sheet-id" );
+ break;
+
+ case BIFF12_ID_WEBPR:
+ {
+ dumpHex< sal_uInt32 >( "flags", "WEBPR-FLAGS" );
+ sal_uInt8 nStrFlags = dumpHex< sal_uInt8 >( "string-flags", "WEBPR-STRINGFLAGS" );
+ if( nStrFlags & 0x04 ) dumpString( "url" );
+ if( nStrFlags & 0x01 ) dumpString( "post-method" );
+ if( nStrFlags & 0x02 ) dumpString( "edit-page" );
+ }
+ break;
+
+ case BIFF12_ID_WORKBOOKPR:
+ dumpHex< sal_uInt32 >( "flags", "WORKBBOKPR-FLAGS" );
+ dumpDec< sal_Int32 >( "default-theme-version" );
+ dumpString( "codename" );
+ break;
+
+ case BIFF12_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 BIFF12_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;
+ }
+}
+
+void RecordStreamObject::dumpGradientHead()
+{
+ 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" );
+}
+
+void RecordStreamObject::dumpCellHeader( bool bWithColumn )
+{
+ if( bWithColumn ) dumpColIndex();
+ dumpHex< sal_uInt32 >( "xf-id", "CELL-XFID" );
+}
+
+// ============================================================================
+
+RootStorageObject::RootStorageObject( const DumperBase& rParent )
+{
+ StorageObjectBase::construct( rParent );
+}
+
+void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName );
+ Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm );
+ if(
+ aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlsm" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlsx" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) )
+ {
+ Dumper( getFactory(), xInStrm, rSysFileName ).dump();
+ }
+ else if(
+ aExt.equalsIgnoreAsciiCaseAscii( "xla" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlc" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlm" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xls" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) )
+ {
+ ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
+ }
+ else if(
+ aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "potx" ) )
+ {
+ ::oox::dump::pptx::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
+ }
+ else if(
+ aExt.equalsIgnoreAsciiCaseAscii( "xml" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "vml" ) ||
+ aExt.equalsIgnoreAsciiCaseAscii( "rels" ) )
+ {
+ XmlStreamObject( *this, rxStrm, rSysFileName ).dump();
+ }
+ else if( aExt.equalsIgnoreAsciiCaseAscii( "bin" ) )
+ {
+ if( rStrgPath.equalsAscii( "xl" ) && rStrmName.equalsAscii( "vbaProject.bin" ) )
+ {
+ StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
+ VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else if( rStrgPath.equalsAscii( "xl/embeddings" ) )
+ {
+ StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
+ OleStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else if(
+ rStrgPath.equalsAscii( "xl" ) ||
+ rStrgPath.equalsAscii( "xl/chartsheets" ) ||
+ rStrgPath.equalsAscii( "xl/dialogsheets" ) ||
+ rStrgPath.equalsAscii( "xl/externalLinks" ) ||
+ rStrgPath.equalsAscii( "xl/macrosheets" ) ||
+ rStrgPath.equalsAscii( "xl/pivotCache" ) ||
+ rStrgPath.equalsAscii( "xl/pivotTables" ) ||
+ rStrgPath.equalsAscii( "xl/queryTables" ) ||
+ rStrgPath.equalsAscii( "xl/tables" ) ||
+ rStrgPath.equalsAscii( "xl/worksheets" ) )
+ {
+ RecordStreamObject( *this, rxStrm, rSysFileName ).dump();
+ }
+ else if( rStrgPath.equalsAscii( "xl/activeX" ) )
+ {
+ StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) );
+ ActiveXStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else
+ {
+ BinaryStreamObject( *this, rxStrm, rSysFileName ).dump();
+ }
+ }
+}
+
+// ============================================================================
+
+#define DUMP_XLSB_CONFIG_ENVVAR "OOO_XLSBDUMPER"
+
+Dumper::Dumper( const FilterBase& rFilter )
+{
+ ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rFilter ) );
+ DumperBase::construct( xCfg );
+}
+
+Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
+{
+ if( rxFactory.is() && rxInStrm.is() )
+ {
+ StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) );
+ MediaDescriptor aMediaDesc;
+ ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
+ DumperBase::construct( xCfg );
+ }
+}
+
+void Dumper::implDump()
+{
+ RootStorageObject( *this ).dump();
+}
+
+// ============================================================================
+
+} // namespace xlsb
+} // namespace dump
+} // namespace oox
+
+#endif
diff --git a/oox/source/dump/xlsbdumper.ini b/oox/source/dump/xlsbdumper.ini
new file mode 100644
index 000000000000..3490111c4ba5
--- /dev/null
+++ b/oox/source/dump/xlsbdumper.ini
@@ -0,0 +1,1186 @@
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+include-config-file=oledumper.ini
+
+# Enable entire dumper. This option does not affect the option 'enable-import'.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-dumper=1
+
+# Enable import after dumping. Disabling this option allows to dump a file
+# without loading it. This option is independent from the 'enable-dumper'
+# option.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-import=1
+
+# name lists =================================================================
+
+# 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
+
+combilist=CELL-XFID
+ 0x00FFFFFF=int32,dec,xf-id
+ 0x01000000=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,auto,indexed,rgb,theme
+
+combilist=COLOR-FLAGS
+ 0x01=rgb-valid
+ 0xFE=uint8,dec,type,COLOR-TYPE
+end
+
+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,MULTCELL_BLANK,MULTCELL_RK,MULTCELL_ERROR,MULTCELL_BOOL
+ 0x0010=MULTCELL_DOUBLE,MULTCELL_STRING,MULTCELL_SI,SI,PCITEM_MISSING,PCITEM_DOUBLE,PCITEM_BOOL,PCITEM_ERROR
+ 0x0018=PCITEM_STRING,PCITEM_DATE,PCITEM_INDEX,PCITEMA_MISSING,PCITEMA_DOUBLE,PCITEMA_BOOL,PCITEMA_ERROR,PCITEMA_STRING
+ 0x0020=PCITEMA_DATE,PCRECORD,PCRECORDDT,FRT,FRT_END,,,DEFINEDNAME
+ 0x0028=BINARYINDEXROWS,,BINARYINDEXBLOCK,FONT,NUMFMT,FILL,BORDER,XF
+ 0x0030=CELLSTYLE,,,,,,,
+ 0x0038=,,,,COL,MULTCELL_RSTRING,CELL_RSTRING,CALCCHAINCELL
+ 0x0040=DATAVALIDATION,,,,,,,
+
+ 0x0080=FILEVERSION,WORKSHEET,WORKSHEET_END,WORKBOOK,WORKBOOK_END,SHEETVIEWS,SHEETVIEWS_END,BOOKVIEWS
+ 0x0088=BOOKVIEWS_END,SHEETVIEW,SHEETVIEW_END,CHARTSHEETVIEWS,CHARTSHEETVIEWS_END,CHARTSHEETVIEW,CHARTSHEETVIEW_END,SHEETS
+ 0x0090=SHEETS_END,SHEETDATA,SHEETDATA_END,SHEETPR,DIMENSION,,,PANE
+ 0x0098=SELECTION,WORKBOOKPR,SMARTTAGPR,FILERECOVERYPR,SHEET,CALCPR,WORKBOOKVIEW,SST
+ 0x00A0=SST_END,AUTOFILTER,AUTOFILTER_END,FILTERCOLUMN,FILTERCOLUMN_END,DISCRETEFILTERS,DISCRETEFILTERS_END,DISCRETEFILTER
+ 0x00A8=COLORFILTER,ICONFILTER,TOP10FILTER,DYNAMICFILTER,CUSTOMFILTERS,CUSTOMFILTERS_END,CUSTOMFILTER,AFDATEGROUPITEM
+ 0x00B0=MERGECELL,MERGECELLS,MERGECELLS_END,PCDEFINITION,PCDEFINITION_END,PCDFIELDS,PCDFIELDS_END,PCDFIELD
+ 0x00B8=PCDFIELD_END,PCDSOURCE,PCDSOURCE_END,PCDSHEETSOURCE,PCDSHEETSOURCE_END,PCDFSHAREDITEMS,PCDFSHAREDITEMS_END,PCITEM_ARRAY
+ 0x00C0=PCITEM_ARRAY_END,PCRECORDS,PCRECORDS_END,,,,,
+ 0x00C8=,CONNECTION,CONNECTION_END,,,,,
+
+ 0x00D8=,,,PCDFIELDGROUP,PCDFIELDGROUP_END,PCDFGROUPITEMS,PCDFGROUPITEMS_END,PCDFRANGEPR
+ 0x00E0=PCDFRANGEPR_END,PCDFDISCRETEPR,PCDFDISCRETEPR_END,,,,,
+
+ 0x00F0=,,,,,,,PIVOTAREA
+ 0x00F8=PIVOTAREA_END,PTREFERENCES,PTREFERENCES_END,PTREFERENCE,PTREFERENCE_END,,,
+ 0x0100=,,,,,WEBPR,WEBPR_END,WEBPRTABLES
+ 0x0108=WEBPRTABLES_END,,,,,,,
+ 0x0110=,,,,,BINARYINDEX_END,STYLESHEET,STYLESHEET_END
+ 0x0118=PTDEFINITION,PTFITEM_END,PTFITEM,PTFITEMS,PTFITEMS_END,PTFIELD,PTFIELD_END,PTFIELDS
+ 0x0120=PTFIELDS_END,PTPAGEFIELD,PTPAGEFIELD_END,PTPAGEFIELDS,PTPAGEFIELDS_END,PTDATAFIELD,PTDATAFIELD_END,PTDATAFIELDS
+ 0x0128=PTDATAFIELDS_END,,,,,,,
+ 0x0130=,,,,,PTROWFIELDS,PTROWFIELDS_END,PTCOLFIELDS
+ 0x0138=PTCOLFIELDS_END,PTLOCATION_END,PTLOCATION,PTDEFINITION_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,EXTCELL_BLANK
+ 0x0170=EXTCELL_DOUBLE,EXTCELL_BOOL,EXTCELL_ERROR,EXTCELL_STRING,,,,
+ 0x0178=,,,,,,PTREFERENCEITEM,PTREFERENCEITEM_END
+ 0x0180=PIVOTCACHES,PIVOTCACHES_END,PIVOTCACHE,PIVOTCACHE_END,,,COLS,COLS_END
+ 0x0188=ROWBREAKS,ROWBREAKS_END,COLBREAKS,COLBREAKS_END,BRK,CUSTOMWORKBOOKVIEW,,
+
+ 0x01A0=,,,,,,CUSTOMSHEETVIEWS,CUSTOMSHEETVIEW
+ 0x01A8=CUSTOMSHEETVIEW_END,CUSTOMSHEETVIEWS_END,ARRAY,SHAREDFMLA,DATATABLE,CONNECTIONS,CONNECTIONS_END,
+
+ 0x01B8=,,,,,,,QUERYTABLE
+ 0x01C0=QUERYTABLE_END,QUERYTABLEREFRESH,QUERYTABLEREFRESH_END,,,,,
+ 0x01C8=,,,AUTOSORTSCOPE,AUTOSORTSCOPE_END,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,PTCHARTFORMAT,PTCHARTFORMAT_END,PTCHARTFORMATS,PTCHARTFORMATS_END,SHEETFORMATPR,,
+ 0x01E8=,,,,,,HYPERLINK,
+ 0x01F0=,,,,SCENARIOS,SCENARIOS_END,SCENARIO,SCENARIO_END
+ 0x01F8=INPUTCELLS,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=,,,,,OLESIZE,DRAWING,LEGACYDRAWING
+
+ 0x0230=,,PICTURE,,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,EXTERNALNAME_END,EXTERNALBOOK_END,,,
+ 0x0250=,,,,,,,PTFILTERS
+ 0x0258=PTFILTERS_END,PTFILTER,PTFILTER_END,FILLS,FILLS_END,,,
+ 0x0260=,,,FONTS,FONTS_END,BORDERS,BORDERS_END,NUMFMTS
+ 0x0268=NUMFMTS_END,CELLXFS,CELLXFS_END,CELLSTYLES,CELLSTYLES_END,,,
+ 0x0270=,,CELLSTYLEXFS,CELLSTYLEXFS_END,COMMENTS,COMMENTS_END,COMMENTAUTHORS,COMMENTAUTHORS_END
+ 0x0278=COMMENTAUTHOR,COMMENTLIST,COMMENTLIST_END,COMMENT,COMMENT_END,COMMENTTEXT,OLEOBJECTS,OLEOBJECT
+ 0x0280=OLEOBJECTS_END,,,CONTROLS,CONTROL,CONTROLS_END,,
+ 0x0288=,,,CHARTSHEETPR,CHARTPAGESETUP,CUSTOMCHARTVIEWS,CUSTOMCHARTVIEWS_END,CUSTOMCHARTVIEW
+ 0x0290=CUSTOMCHARTVIEW_END,,,,TABLEPARTS,TABLEPART,TABLEPARTS_END,SHEETCALCPR
+ 0x0298=FUNCTIONGROUPS,FUNCTIONGROUP,FUNCTIONGROUPS_END,EXTERNALADDIN,,CHARTPROTECTION,,
+end
+
+# simple records -------------------------------------------------------------
+
+constlist=SIMPLE-RECORDS
+ 0x001A=int32,dec,item-index
+ 0x00AC=int32,dec,relation,CUSTOMFILTERS-RELATION
+ 0x00B5=int32,dec,count
+ 0x00C1=int32,dec,count
+ 0x00DD=int32,dec,count
+ 0x00E1=int32,dec,count
+ 0x00F9=int32,dec,count
+ 0x0107=int32,dec,count
+ 0x011B=int32,dec,count
+ 0x011F=int32,dec,count
+ 0x0123=int32,dec,count
+ 0x0159=int32,dec,count
+ 0x017E=int32,dec,item-index
+ 0x01DD=uint16,hex,flags,PRINTOPTIONS-FLAGS
+ 0x01E3=int32,dec,count
+ 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
+ 0x0257=int32,dec,count
+ 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
+ 0x0297=uint8,hex,flags,SHEETCALCPR-FLAGS
+ 0x0298=uint8,dec,builtin-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
+
+# CALCPR ---------------------------------------------------------------------
+
+shortlist=CALCPR-CALCMODE,0,manual,auto,auto-no-tables
+
+flagslist=CALCPR-FLAGS
+ 0x0001=calc-on-load
+ 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-DATE-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
+ 0x0001=table-row
+ 0x0002=stop-if-true
+ 0x0004=above-average
+ 0x0008=bottom
+ 0x0010=percent
+end
+
+# CHARTPAGESETUP ------------------------------------------------------------------
+
+combilist=CHARTPAGESETUP-FLAGS
+ 0x0001=landscape
+ 0x0002=uninitialized
+ 0x0004=black-and-white
+ 0x0008=default-orientation
+ 0x0010=use-first-page
+ 0x0020=draft-quality
+end
+
+# CHARTSHEETPR ---------------------------------------------------------------
+
+flagslist=CHARTSHEETPR-FLAGS
+ 0x0001=published
+end
+
+# CHARTSHEETVIEW -------------------------------------------------------------
+
+flagslist=CHARTSHEETVIEW-FLAGS
+ 0x0001=selected
+ 0x0002=zoom-to-fit
+end
+
+# COL ------------------------------------------------------------------------
+
+combilist=COL-FLAGS
+ 0x0001=hidden
+ 0x0002=custom-width
+ 0x0004=best-fit
+ 0x0008=show-phonetic
+ 0x0700=uint8,dec,outline-level
+ 0x1000=outline-collapsed
+end
+
+# CONNECTION -----------------------------------------------------------------
+
+shortlist=CONNECTION-SAVEPASSWORD,1,on,off
+unitconverter=CONNECTION-INTERVAL,60,sec
+shortlist=CONNECTION-SOURCETYPE,1,odbc,dao,file,html,ole-db,text,ado,dsp
+shortlist=CONNECTION-RECONNECTTYPE,1,as-required,always,never
+shortlist=CONNECTION-CREDENTIALS,0,integrated,none,stored-sso,prompt
+
+flagslist=CONNECTION-FLAGS
+ 0x0001=keep-alive
+ 0x0002=new
+ 0x0004=deleted
+ 0x0008=only-use-conn-file
+ 0x0010=background
+ 0x0020=refresh-on-load
+ 0x0040=save-data
+end
+
+flagslist=CONNECTION-STRINGFLAGS
+ 0x0001=has-source-file
+ 0x0002=has-source-conn-file
+ 0x0004=has-description
+ 0x0008=has-name
+ 0x0010=has-sso-id
+end
+
+# CUSTOMFILTER ---------------------------------------------------------------
+
+constlist=CUSTOMFILTER-DATATYPE
+ 4=double
+ 6=string
+ 8=boolean
+ 12=blank
+ 14=not-blank
+end
+
+shortlist=CUSTOMFILTER-OPERATOR,1,less,equal,less-equal,greater,not-equal,greater-equal
+
+# CUSTOMFILTERS --------------------------------------------------------------
+
+shortlist=CUSTOMFILTERS-RELATION,0,and,or
+
+# DATATABLE ------------------------------------------------------------------
+
+flagslist=DATATABLE-FLAGS
+ 0x01=row-table
+ 0x02=table-2d
+ 0x04=ref1-deleted
+ 0x08=ref2-deleted
+ 0x10=recalc-always
+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 ------------------------------------------------------------
+
+combilist=DATAVALIDATIONS-FLAGS
+ 0x0001=disable-prompts
+end
+
+# DEFINEDNAME ----------------------------------------------------------------
+
+combilist=DEFINEDNAME-FLAGS
+ 0x00000001=hidden
+ 0x00000002=function
+ 0x00000004=vba
+ 0x00000008=macro
+ 0x00000010=complex
+ 0x00000020=built-in
+ 0x00007FC0=int32,dec,func-group,DEFINEDNAME-FUNCGROUP
+ 0x00008000=published
+ 0x00010000=workbook-param
+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
+
+# DISCRETEFILTERS --------------------------------------------------------------------
+
+shortlist=DISCRETEFILTERS-CALTYPE,0,none,gregorian,gregorian-us,japan,taiwan,korea,hijri,thai,hebrew,gregorian-mideast-fr,gregorian-ar,gregorian-xlit-en,gregorian-xlit-fr
+
+# 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,FONT-CHARSET
+ 35=FONT-PITCHFAMILY,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
+
+# FILTERCOLUMN ---------------------------------------------------------------
+
+flagslist=FILTERCOLUMN-FLAGS
+ 0x0001=hidden-button
+ 0x0002=show-button
+end
+
+# FONT -----------------------------------------------------------------------
+
+flagslist=FONT-FLAGS
+ 0x0001=bold
+ 0x0002=italic
+ 0x0004=underline
+ 0x0008=strikeout
+ 0x0010=outline
+ 0x0020=shadow
+ 0x0040=condense
+ 0x0080=extend
+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
+
+# HEADERFOOTER ---------------------------------------------------------------
+
+flagslist=HEADERFOOTER-FLAGS
+ 0x0001=diff-odd-even
+ 0x0002=diff-dirst
+ 0x0004=scale-with-doc
+ 0x0008=align-with-margins
+end
+
+# OLEOBJECT ------------------------------------------------------------------
+
+shortlist=OLEOBJECT-ASPECT,1,content,,,icon
+shortlist=OLEOBJECT-UPDATE,0,na,automatic,,manual
+
+flagslist=OLEOBJECT-FLAGS
+ 0x0001=linked
+ 0x0002=auto-load
+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
+
+# PCDEFINITION ---------------------------------------------------------------
+
+flagslist=PCDEFINITION-FLAGS1
+ 0x01=save-data
+ 0x02=invalid
+ 0x04=refresh-on-load
+ 0x08=optimize-memory
+ 0x10=enable-refresh
+ 0x20=background-query
+ 0x40=upgrade-on-refresh
+ 0x80=tupel-cache
+end
+
+constlist=PCDEFINITION-MISSINGITEMS
+ default=
+ -1=clear-automatic
+ 0=clear-always
+end
+
+flagslist=PCDEFINITION-FLAGS2
+ 0x01=has-username
+ 0x02=has-rel-id
+ 0x04=support-subquery
+ 0x08=support-drilldown
+end
+
+# PCDFIELD -------------------------------------------------------------------
+
+flagslist=PCDFIELD-FLAGS
+ 0x0001=server-field
+ 0x0002=no-unique-items
+ 0x0004=database-field
+ 0x0008=has-caption
+ 0x0010=member-property-field
+ 0x0100=has-formula
+ 0x0200=has-property-name
+end
+
+# PCDFRANGEPR ----------------------------------------------------------------
+
+shortlist=PCDFRANGEPR-GROUPBY,0,numeric,seconds,minutes,hours,days,months,quarters,years
+
+flagslist=PCDFRANGEPR-FLAGS
+ 0x01=auto-start
+ 0x02=auto-end
+ 0x04=date-group
+end
+
+# PCDFSHAREDITEMS ------------------------------------------------------------
+
+flagslist=PCDFSHAREDITEMS-FLAGS
+ 0x0001=has-semi-mixed-types
+ 0x0002=has-non-date
+ 0x0004=has-date
+ 0x0008=has-string-bool-err
+ 0x0010=has-blank
+ 0x0020=has-mixed-types
+ 0x0040=is-numeric
+ 0x0080=is-integer
+ 0x0100=has-min-max
+ 0x0200=long-text
+end
+
+# PCDSOURCE ------------------------------------------------------------------
+
+shortlist=PCDSOURCE-TYPE,0,worksheet,external,consolidation,scenario
+
+# PCDWORKSHEETSOURCE ---------------------------------------------------------
+
+flagslist=PCDWORKSHEETSOURCE-FLAGS
+ 0x01=has-rel-id
+ 0x02=has-sheet
+end
+
+# PCITEM_ARRAY ---------------------------------------------------------------
+
+constlist=PCITEM_ARRAY-TYPE
+ 0x0001=double
+ 0x0002=string
+ 0x0010=error
+ 0x0020=date
+end
+
+# PHONETICPR -----------------------------------------------------------------
+
+shortlist=PHONETICPR-TYPE,0,halfwidth-katakana,fullwidth-katakana,hiragana,no-conversion
+shortlist=PHONETICPR-ALIGNMENT,0,no-control,left,center,distributed
+
+# PIVOTAREA ------------------------------------------------------------------
+
+shortlist=PIVOTAREA-TYPE,0,none,normal,data,all,origin,button,top-right
+
+flagslist=PIVOTAREA-FLAGS1
+ 0x01=data-only
+ 0x02=label-only
+ 0x04=grand-row
+ 0x08=grand-col
+ 0x10=cache-based
+ 0x20=line-mode
+ 0x40=part
+ 0x80=fuzzy
+end
+
+combilist=PIVOTAREA-FLAGS2
+ 0x0001=row
+ 0x0002=col
+ 0x0004=page
+ 0x0008=data
+ 0x0FF0=uint8,dec,pos-on-axis
+end
+
+# PRINTOPTIONS ---------------------------------------------------------------
+
+flagslist=PRINTOPTIONS-FLAGS
+ 0x0001=horizontal-centered
+ 0x0002=vertical-centered
+ 0x0004=print-headings
+ 0x0008=print-gridlines
+ 0x0010=gridlines-set
+end
+
+# Pivot table globals --------------------------------------------------------
+
+constlist=PT-FIELDINDEX
+ default=
+ -2=data-field
+end
+
+# PTDATAFIELD ----------------------------------------------------------------
+
+shortlist=PTDATAFIELD-SUBTOTAL,0,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,var,var-p
+shortlist=PTDATAFIELD-SHOWDATAAS,0,normal,difference,percent,percent-diff,run-total,percent-of-row,percent-of-col,percent-of-total,index
+
+constlist=PTDATAFIELD-BASEITEM
+ default=
+ 0x001000FC=previous-item
+ 0x001000FD=next-item
+end
+
+# PTDEFINITION ---------------------------------------------------------------
+
+flagslist=PTDEFINITION-FLAGS1
+ 0x01=show-items
+ 0x02=edit-data
+ 0x04=disable-field-list
+ 0x08=refresh-on-load
+ 0x10=hide-calc-members
+ 0x20=with-hidden-totals
+ 0x40=show-multiple-label
+end
+
+combilist=PTDEFINITION-FLAGS2
+ 0x0001=hide-data-drop-down
+ 0x0010=hide-drill
+ 0x0020=print-drill
+ 0x0040=show-member-prop-tips
+ 0x0080=hide-data-tips
+ 0x7F00=uint8,dec,indent
+ 0x8000=hide-headers
+end
+
+flagslist=PTDEFINITION-FLAGS3
+ ignore=0x00010000
+ 0x00000001=hide-drop-zones
+ 0x00000002=no-asterisk-totals
+ 0x00000004=show-empty-row
+ 0x00000008=show-empty-col
+ 0x00000010=enable-wizard
+ 0x00000020=enable-drill
+ 0x00000040=enable-field-props
+ 0x00000080=preserve-formatting
+ 0x00000100=use-auto-formatting
+ 0x00000200=show-error
+ 0x00000400=show-missing
+ 0x00000800=page-over-then-down
+ 0x00001000=multiple-page-items
+ 0x00002000=row-grand-totals
+ 0x00004000=col-grand-totals
+ 0x00008000=field-print-titles
+ 0x00020000=item-print-titles
+ 0x00040000=merge-item
+ 0x00080000=has-data-caption
+ 0x00100000=has-grand-total-caption
+ 0x00200000=has-page-field-style
+ 0x00400000=has-pivot-table-style
+ 0x00800000=has-vacated-style
+ 0x01000000=apply-num-fmt
+ 0x02000000=apply-font
+ 0x04000000=apply-alignment
+ 0x08000000=apply-border
+ 0x10000000=apply-fill
+ 0x20000000=apply-protection
+ 0x40000000=has-tag
+end
+
+flagslist=PTDEFINITION-FLAGS4
+ 0x00000001=compact
+ 0x00000002=outline
+ 0x00000004=outline-data
+ 0x00000008=compact-data
+ 0x00000010=no-grid-drop-zones
+ 0x00000020=published
+ 0x00000040=!has-error-caption
+ 0x00000080=!has-missing-caption
+ 0x00000100=immersive-off
+ 0x00000200=single-field-filters
+ 0x00000400=has-row-header-caption
+ 0x00000800=has-col-header-caption
+ 0x00001000=field-list-sort-asc
+ 0x00004000=no-custom-list-sort
+end
+
+shortlist=PTDEFINITION-DATAFIELD-AXIS,1,row-axis,col-axis
+
+constlist=PTDEFINITION-DATAFIELD-POS
+ default=
+ -1=append
+end
+
+# PTFIELD --------------------------------------------------------------------
+
+flagslist=PTFIELD-FLAGS1
+ 0x00000001=row
+ 0x00000002=col
+ 0x00000004=page
+ 0x00000008=data
+ 0x00000100=default
+ 0x00000200=sum
+ 0x00000400=count-all
+ 0x00000800=average
+ 0x00001000=max
+ 0x00002000=min
+ 0x00004000=product
+ 0x00008000=count-num
+ 0x00010000=std-dev
+ 0x00020000=std-dev-p
+ 0x00040000=variance
+ 0x00080000=variance-p
+ 0x01000000=drilled-level
+ 0x02000000=hide-dropdown
+ 0x04000000=hidden-level
+ 0x08000000=has-member-prop-caption
+ 0x10000000=compact
+ 0x20000000=has-display-name
+ 0x40000000=has-subtotal-caption
+ 0x80000000=source-ordered
+end
+
+flagslist=PTFIELD-FLAGS2
+ 0x00000001=drag-to-row
+ 0x00000002=drag-to-col
+ 0x00000004=drag-to-page
+ 0x00000008=drag-to-hide
+ 0x00000010=drag-to-data
+ 0x00000020=show-all-items
+ 0x00000040=outline
+ 0x00000080=insert-blank-row
+ 0x00000100=subtotal-top
+ 0x00000200=server-based
+ 0x00000800=insert-page-break
+ 0x00001000=autosort
+ 0x00002000=ascend-sort
+ 0x00004000=autoshow
+ 0x00008000=autoshow-top
+ 0x00010000=hide-new-items
+ 0x00020000=has-value-filter
+ 0x00040000=exclude-new-items
+ 0x00080000=multiple-page-items
+ 0x00100000=simple-data-sort
+ 0x00200000=show-member-prop-report
+ 0x00400000=show-member-prop-tooltip
+ 0x00800000=show-member-prop-caption
+ 0x01000000=items-drilled
+end
+
+# PTFILTER -------------------------------------------------------------------
+
+multilist=PTFILTER-TYPE
+ 0=unknown,count,percent,sum,caption-equal,caption-not-equal,caption-begins-width,caption-not-begins-with,caption-ends-width,caption-not-ends-with
+ 10=caption-contains,caption-not-contains,caption-greater-than,caption-greater-equal,caption-less-than,caption-less-equal,caption-between,caption-not-between,value-equal,value-not-equal
+ 20=value-greater-than,value-greater-equal,value-less-than,value-less-equal,value-between,value-not-between,date-equal,date-older-than,date-newer-than,date-between
+ 30=date-tomorrow,date-today,date-yesterday,date-next-week,date-this-week,date-last-week,date-next-month,date-this-month,date-last-month,date-next-quarter
+ 40=date-this-quarter,date-last-quarter,date-next-year,date-this-year,date-last-year,year-to-date,date-q1,date-q2,date-q3,date-q4
+ 50=date-jan,date-feb,date-mar,date-apr,date-may,date-jun,date-jul,date-aug,date-sep,date-oct
+ 60=date-nov,date-dec,date-not-equal,date-older-equal,date-newer-equal,date-not-between
+end
+
+flagslist=PTFILTER-FLAGS
+ 0x0001=has-name
+ 0x0002=has-description
+ 0x0004=has-str-value1
+ 0x0008=has-str-value2
+end
+
+# PTFITEM --------------------------------------------------------------------
+
+shortlist=PTFITEM-TYPE,0,data,default,sum,count-all,average,max,min,product,count-mumbers,std-dev,std-dev-p,var,var-p,grand-total,blank
+
+flagslist=PTFITEM-FLAGS
+ 0x0001=hidden
+ 0x0002=hide-detail
+ 0x0004=calculated
+ 0x0008=missing
+ 0x0010=has-name
+ 0x0020=drilled-member
+ 0x0040=can-have-children
+ 0x0080=collapsed-member
+ 0x0100=olap-filter-selected
+end
+
+# PTPAGEFIELD ----------------------------------------------------------------
+
+constlist=PTPAGEFIELD-ITEM
+ default=
+ 0x001000FE=mutiple-items
+end
+
+flagslist=PTPAGEFIELD-FLAGS
+ 0x01=has-unique-name
+ 0x02=has-member-caption
+end
+
+# PTREFERENCE ----------------------------------------------------------------
+
+flagslist=PTREFERENCE-FLAGS1
+ 0x0001=data
+ 0x0002=default
+ 0x0004=sum
+ 0x0008=count-all
+ 0x0010=average
+ 0x0020=max
+ 0x0040=min
+ 0x0080=product
+ 0x0100=count-num
+ 0x0200=std-dev
+ 0x0400=std-dev-p
+ 0x0800=variance
+ 0x1000=variance-p
+end
+
+flagslist=PTREFERENCE-FLAGS2
+ 0x01=selected
+end
+
+# QUERYTABLE -----------------------------------------------------------------
+
+combilist=QUERYTABLE-FLAGS
+ 0x00000001=headers
+ 0x00000002=row-numbers
+ 0x00000004=disable-refresh
+ 0x00000008=background
+ 0x00000010=first-background
+ 0x00000020=refresh-on-load
+ 0x000000C0=uint8,dec,grow-shrink,QUERYTABLE-GROWSHRINK
+ 0x00000100=fill-formulas
+ 0x00000200=save-data
+ 0x00000400=disable-edit
+ 0x00000800=preserve-formatting
+ 0x00001000=adjust-column-width
+ 0x00002000=intermediate
+ 0x00004000=apply-num-fmt
+ 0x00008000=apply-font
+ 0x00010000=apply-alignment
+ 0x00020000=apply-border
+ 0x00040000=apply-fill
+ 0x00080000=apply-protection
+end
+
+shortlist=QUERYTABLE-GROWSHRINK,0,insert-clear,insert-delete,overwrite-clear
+
+# ROW ------------------------------------------------------------------------
+
+combilist=ROW-FLAGS1
+ 0x0001=thick-top
+ 0x0002=thick-bottom
+ 0x0700=uint8,dec,outline-level
+ 0x0800=outline-collapsed
+ 0x1000=hidden
+ 0x2000=custom-height
+ 0x4000=custom-format
+end
+
+flagslist=ROW-FLAGS2
+ 0x01=show-phonetic
+end
+
+# SHEET ----------------------------------------------------------------------
+
+shortlist=SHEET-STATE,0,visible,hidden,very-hidden
+
+# SHEETCALCPR ----------------------------------------------------------------
+
+flagslist=SHEETCALCPR-FLAGS
+ 0x01=calc-on-load
+end
+
+# SHEETFORMATPR --------------------------------------------------------------
+
+flagslist=SHEETFORMATPR-FLAGS
+ 0x0001=custom-row-height
+ 0x0002=rows-hidden
+end
+
+# SHEETPR --------------------------------------------------------------------
+
+flagslist=SHEETPR-FLAGS1
+ 0x0001=show-autopagebreaks
+ 0x0008=published
+ 0x0010=dialog-sheet
+ 0x0020=outline-auto-style
+ 0x0040=row-symbols-below
+ 0x0080=column-symbols-right
+ 0x0100=fit-to-pages
+ 0x0400=show-outline-symbols
+ 0x1000=is-row-synched
+ 0x2000=is-col-synched
+ 0x4000=lotus-formula-eval
+ 0x8000=lotus-formula-entry
+end
+
+flagslist=SHEETPR-FLAGS2
+ 0x01=is-filtered
+ 0x02=eval-cond-formats
+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
+ 0x0010=show-row-headers
+ 0x0020=show-column-headers
+end
+
+# TOP10FILTER ----------------------------------------------------------------
+
+flagslist=TOP10FILTER-FLAGS
+ 0x01=!bottom!top
+ 0x02=percent
+ 0x04=applied
+end
+
+# VOLTYPE --------------------------------------------------------------------
+
+shortlist=VOLTYPE-TYPE,0,realtime-data,olap-functions
+
+# WEBPR ----------------------------------------------------------------------
+
+combilist=WEBPR-FLAGS
+ 0x000000FF=uint8,dec,html-format,WEBPR-HTMLFORMAT
+ 0x00000100=xml
+ 0x00000200=source-data
+ 0x00000400=parse-pre
+ 0x00000800=consecutive-delimiters
+ 0x00001000=first-row
+ 0x00002000=xl97-created
+ 0x00004000=text-dates
+ 0x00008000=xl2000-refreshed
+ 0x00010000=html-tables
+end
+
+shortlist=WEBPR-HTMLFORMAT,0,none,rtf,all
+
+flagslist=WEBPR-STRINGFLAGS
+ 0x01=has-post-method
+ 0x02=has-edit-page
+ 0x04=has-url
+end
+
+# 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
+ 0x00020000=refresh-all-links
+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/export/README b/oox/source/export/README
new file mode 100644
index 000000000000..56195b97706d
--- /dev/null
+++ b/oox/source/export/README
@@ -0,0 +1,2 @@
+presetTextWarpDefinitions.xml and presetShapeDefinitions.xml come from the
+OOXML documentation (TC45).
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
new file mode 100644
index 000000000000..85ef2519f029
--- /dev/null
+++ b/oox/source/export/drawingml.cxx
@@ -0,0 +1,1393 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/export/drawingml.hxx"
+#include "oox/export/utils.hxx"
+
+#include <cstdio>
+#include <com/sun/star/awt/CharSet.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <unotools/fontcvt.hxx>
+#include <vcl/graph.hxx>
+#include <svtools/grfmgr.hxx>
+#include <rtl/strbuf.hxx>
+#include <sfx2/app.hxx>
+#include <svl/languageoptions.hxx>
+#include <svx/escherex.hxx>
+#include <svx/svxenum.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::i18n;
+using ::com::sun::star::beans::PropertyState;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::XPropertyState;
+using ::com::sun::star::container::XEnumeration;
+using ::com::sun::star::container::XEnumerationAccess;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::text::XText;
+using ::com::sun::star::text::XTextContent;
+using ::com::sun::star::text::XTextField;
+using ::com::sun::star::text::XTextRange;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::sax_fastparser::FSHelperPtr;
+
+DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
+
+namespace oox {
+namespace drawingml {
+
+#define GETA(propName) \
+ GetProperty( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ) )
+
+#define GETAD(propName) \
+ ( GetPropertyAndState( rXPropSet, rXPropState, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
+
+#define GET(variable, propName) \
+ if ( GETA(propName) ) \
+ mAny >>= variable;
+
+// not thread safe
+int DrawingML::mnImageCounter = 1;
+
+void DrawingML::ResetCounters()
+{
+ mnImageCounter = 1;
+}
+
+bool DrawingML::GetProperty( Reference< XPropertySet > rXPropSet, String aName )
+{
+ bool bRetValue = false;
+
+ try {
+ mAny = rXPropSet->getPropertyValue( aName );
+ if ( mAny.hasValue() )
+ bRetValue = true;
+ } catch( Exception& ) { /* printf ("exception when trying to get value of property: %s\n", ST(aName)); */ }
+
+ return bRetValue;
+}
+
+bool DrawingML::GetPropertyAndState( Reference< XPropertySet > rXPropSet, Reference< XPropertyState > rXPropState, String aName, PropertyState& eState )
+{
+ bool bRetValue = false;
+
+ try {
+ mAny = rXPropSet->getPropertyValue( aName );
+ if ( mAny.hasValue() ) {
+ bRetValue = true;
+ eState = rXPropState->getPropertyState( aName );
+ }
+ } catch( Exception& ) { /* printf ("exception when trying to get value of property: %s\n", ST(aName)); */ }
+
+ return bRetValue;
+}
+
+void DrawingML::WriteColor( sal_uInt32 nColor )
+{
+ OString sColor = OString::valueOf( ( sal_Int64 ) nColor, 16 );
+ if( sColor.getLength() < 6 ) {
+ OStringBuffer sBuf( "0" );
+ int remains = 5 - sColor.getLength();
+
+ while( remains > 0 ) {
+ sBuf.append( "0" );
+ remains--;
+ }
+
+ sBuf.append( sColor );
+
+ sColor = sBuf.getStr();
+ }
+ mpFS->singleElementNS( XML_a, XML_srgbClr, XML_val, sColor.getStr(), FSEND );
+}
+
+void DrawingML::WriteSolidFill( sal_uInt32 nColor )
+{
+ mpFS->startElementNS( XML_a, XML_solidFill, FSEND );
+ WriteColor( nColor );
+ mpFS->endElementNS( XML_a, XML_solidFill );
+}
+
+void DrawingML::WriteSolidFill( Reference< XPropertySet > rXPropSet )
+{
+ if ( GetProperty( rXPropSet, S( "FillColor" ) ) )
+ WriteSolidFill( *((sal_uInt32*) mAny.getValue()) & 0xffffff );
+}
+
+void DrawingML::WriteGradientStop( sal_uInt16 nStop, sal_uInt32 nColor )
+{
+ mpFS->startElementNS( XML_a, XML_gs,
+ XML_pos, I32S( nStop * 1000 ),
+ FSEND );
+ WriteColor( nColor );
+ mpFS->endElementNS( XML_a, XML_gs );
+}
+
+sal_uInt32 DrawingML::ColorWithIntensity( sal_uInt32 nColor, sal_uInt32 nIntensity )
+{
+ return ( ( ( nColor & 0xff ) * nIntensity ) / 100 )
+ | ( ( ( ( ( nColor & 0xff00 ) >> 8 ) * nIntensity ) / 100 ) << 8 )
+ | ( ( ( ( ( nColor & 0xff0000 ) >> 8 ) * nIntensity ) / 100 ) << 8 );
+}
+
+void DrawingML::WriteGradientFill( Reference< XPropertySet > rXPropSet )
+{
+ awt::Gradient aGradient;
+ if( GETA( FillGradient ) ) {
+ aGradient = *static_cast< const awt::Gradient* >( mAny.getValue() );
+
+ mpFS->startElementNS( XML_a, XML_gradFill, FSEND );
+
+ switch( aGradient.Style ) {
+ default:
+ case GradientStyle_LINEAR:
+ mpFS->startElementNS( XML_a, XML_gsLst, FSEND );
+ WriteGradientStop( 0, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) );
+ WriteGradientStop( 100, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
+ mpFS->endElementNS( XML_a, XML_gsLst );
+ mpFS->singleElementNS( XML_a, XML_lin,
+ XML_ang, I32S( ( ( ( 3600 - aGradient.Angle + 900 ) * 6000 ) % 21600000 ) ),
+ FSEND );
+ break;
+
+ case GradientStyle_AXIAL:
+ mpFS->startElementNS( XML_a, XML_gsLst, FSEND );
+ WriteGradientStop( 0, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
+ WriteGradientStop( 50, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) );
+ WriteGradientStop( 100, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
+ mpFS->endElementNS( XML_a, XML_gsLst );
+ mpFS->singleElementNS( XML_a, XML_lin,
+ XML_ang, I32S( ( ( ( 3600 - aGradient.Angle + 900 ) * 6000 ) % 21600000 ) ),
+ FSEND );
+ break;
+
+ /* I don't see how to apply transformation to gradients, so
+ * elliptical will end as radial and square as
+ * rectangular. also position offsets are not applied */
+ case GradientStyle_RADIAL:
+ case GradientStyle_ELLIPTICAL:
+ case GradientStyle_RECT:
+ case GradientStyle_SQUARE:
+ mpFS->startElementNS( XML_a, XML_gsLst, FSEND );
+ WriteGradientStop( 0, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) );
+ WriteGradientStop( 100, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) );
+ mpFS->endElementNS( XML_a, XML_gsLst );
+ mpFS->singleElementNS( XML_a, XML_path,
+ XML_path, ( aGradient.Style == awt::GradientStyle_RADIAL || aGradient.Style == awt::GradientStyle_ELLIPTICAL ) ? "circle" : "rect",
+ FSEND );
+ break;
+ }
+
+ mpFS->endElementNS( XML_a, XML_gradFill );
+ }
+
+}
+
+void DrawingML::WriteLineArrow( Reference< XPropertySet > rXPropSet, sal_Bool bLineStart )
+{
+ ESCHER_LineEnd eLineEnd;
+ sal_Int32 nArrowLength;
+ sal_Int32 nArrowWidth;
+
+ if ( EscherPropertyContainer::GetLineArrow( bLineStart, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) ) {
+ const char* len;
+ const char* type;
+ const char* width;
+
+ switch( nArrowLength ) {
+ case ESCHER_LineShortArrow:
+ len = "sm";
+ break;
+ default:
+ case ESCHER_LineMediumLenArrow:
+ len = "med";
+ break;
+ case ESCHER_LineLongArrow:
+ len = "lg";
+ break;
+ }
+
+ switch( eLineEnd ) {
+ default:
+ case ESCHER_LineNoEnd:
+ type = "none";
+ break;
+ case ESCHER_LineArrowEnd:
+ type = "triangle";
+ break;
+ case ESCHER_LineArrowStealthEnd:
+ type = "stealth";
+ break;
+ case ESCHER_LineArrowDiamondEnd:
+ type = "diamond";
+ break;
+ case ESCHER_LineArrowOvalEnd:
+ type = "oval";
+ break;
+ case ESCHER_LineArrowOpenEnd:
+ type = "arrow";
+ break;
+ }
+
+ switch( nArrowWidth ) {
+ case ESCHER_LineNarrowArrow:
+ width = "sm";
+ break;
+ default:
+ case ESCHER_LineMediumWidthArrow:
+ width = "med";
+ break;
+ case ESCHER_LineWideArrow:
+ width = "lg";
+ break;
+ }
+
+ mpFS->singleElementNS( XML_a, bLineStart ? XML_headEnd : XML_tailEnd,
+ XML_len, len,
+ XML_type, type,
+ XML_w, width,
+ FSEND );
+ }
+}
+
+void DrawingML::WriteOutline( Reference< XPropertySet > rXPropSet )
+{
+ drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
+
+ GET( aLineStyle, LineStyle );
+
+ if( aLineStyle == drawing::LineStyle_NONE )
+ return;
+
+ sal_uInt32 nLineWidth = 0;
+ sal_uInt32 nColor = 0;
+ sal_Bool bColorSet = FALSE;
+ const char* cap = NULL;
+ drawing::LineDash aLineDash;
+ sal_Bool bDashSet = FALSE;
+
+ GET( nLineWidth, LineWidth );
+
+ switch( aLineStyle ) {
+ case drawing::LineStyle_DASH:
+ if( GETA( LineDash ) ) {
+ aLineDash = *(drawing::LineDash*) mAny.getValue();
+ bDashSet = TRUE;
+ if( aLineDash.Style == DashStyle_ROUND || aLineDash.Style == DashStyle_ROUNDRELATIVE )
+ cap = "rnd";
+
+ DBG(printf("dash dots: %d dashes: %d dotlen: %d dashlen: %d distance: %d\n",
+ int( aLineDash.Dots ), int( aLineDash.Dashes ), int( aLineDash.DotLen ), int( aLineDash.DashLen ), int( aLineDash.Distance )));
+ }
+ /* fallthru intended */
+ case drawing::LineStyle_SOLID:
+ default:
+ if ( GETA( LineColor ) ) {
+ nColor = *((sal_uInt32*) mAny.getValue()) & 0xffffff;
+ bColorSet = TRUE;
+ }
+ break;
+ }
+
+ mpFS->startElementNS( XML_a, XML_ln,
+ XML_cap, cap,
+ XML_w, nLineWidth > 1 ? I64S( MM100toEMU( nLineWidth ) ) : NULL,
+ FSEND );
+ if( bColorSet )
+ WriteSolidFill( nColor );
+
+ if( bDashSet ) {
+ mpFS->startElementNS( XML_a, XML_custDash, FSEND );
+ int i;
+ for( i = 0; i < aLineDash.Dots; i ++ )
+ mpFS->singleElementNS( XML_a, XML_ds,
+ XML_d, aLineDash.DotLen ? I64S( aLineDash.DotLen*1000 ) : "100000",
+ XML_sp, I64S( aLineDash.Distance*1000 ),
+ FSEND );
+ for( i = 0; i < aLineDash.Dashes; i ++ )
+ mpFS->singleElementNS( XML_a, XML_ds,
+ XML_d, aLineDash.DashLen ? I64S( aLineDash.DashLen*1000 ) : "100000",
+ XML_sp, I64S( aLineDash.Distance*1000 ),
+ FSEND );
+ mpFS->endElementNS( XML_a, XML_custDash );
+ }
+
+ if( nLineWidth > 1 && GETA( LineJoint ) ) {
+ LineJoint eLineJoint;
+
+ mAny >>= eLineJoint;
+ switch( eLineJoint ) {
+ case LineJoint_NONE:
+ case LineJoint_MIDDLE:
+ case LineJoint_BEVEL:
+ mpFS->singleElementNS( XML_a, XML_bevel, FSEND );
+ break;
+ default:
+ case LineJoint_MITER:
+ mpFS->singleElementNS( XML_a, XML_miter, FSEND );
+ break;
+ case LineJoint_ROUND:
+ mpFS->singleElementNS( XML_a, XML_round, FSEND );
+ break;
+ }
+ }
+
+ WriteLineArrow( rXPropSet, sal_True );
+ WriteLineArrow( rXPropSet, sal_False );
+
+ mpFS->endElementNS( XML_a, XML_ln );
+}
+
+OUString DrawingML::WriteImage( const OUString& rURL )
+{
+ ByteString aURLBS( UniString( rURL ), RTL_TEXTENCODING_UTF8 );
+
+ const char aURLBegin[] = "vnd.sun.star.GraphicObject:";
+ int index = aURLBS.Search( aURLBegin );
+
+ if ( index != STRING_NOTFOUND ) {
+ DBG(printf ("begin: %ld %s\n", long( sizeof( aURLBegin ) ), USS( rURL ) + sizeof( aURLBegin ) - 1 ));
+ aURLBS.Erase( 0, sizeof( aURLBegin ) - 1 );
+ Graphic aGraphic = GraphicObject( aURLBS ).GetTransformedGraphic ();
+
+ return WriteImage( aGraphic );
+ } else {
+ // add link to relations
+ }
+
+ return OUString();
+}
+
+OUString DrawingML::WriteImage( const Graphic& rGraphic )
+{
+ GfxLink aLink = rGraphic.GetLink ();
+ OUString sMediaType;
+ const char* sExtension = NULL;
+ OUString sRelId;
+
+ SvMemoryStream aStream;
+ const void* aData = aLink.GetData();
+ sal_Size nDataSize = aLink.GetDataSize();
+
+ switch ( aLink.GetType() ) {
+ case GFX_LINK_TYPE_NATIVE_GIF:
+ sMediaType = US( "image/gif" );
+ sExtension = ".gif";
+ break;
+ case GFX_LINK_TYPE_NATIVE_JPG:
+ sMediaType = US( "image/jpeg" );
+ sExtension = ".jpeg";
+ break;
+ case GFX_LINK_TYPE_NATIVE_PNG:
+ sMediaType = US( "image/png" );
+ sExtension = ".png";
+ break;
+ case GFX_LINK_TYPE_NATIVE_TIF:
+ sMediaType = US( "image/tiff" );
+ sExtension = ".tiff";
+ break;
+ case GFX_LINK_TYPE_NATIVE_WMF:
+ sMediaType = US( "image/x-wmf" );
+ sExtension = ".wmf";
+ break;
+ case GFX_LINK_TYPE_NATIVE_MET:
+ sMediaType = US( "image/x-met" );
+ sExtension = ".met";
+ break;
+ case GFX_LINK_TYPE_NATIVE_PCT:
+ sMediaType = US( "image/x-pict" );
+ sExtension = ".pct";
+ break;
+ default: {
+ GraphicType aType = rGraphic.GetType();
+ if ( aType == GRAPHIC_BITMAP ) {
+ GraphicConverter::Export( aStream, rGraphic, CVT_PNG );
+ sMediaType = US( "image/png" );
+ sExtension = ".png";
+ } else if ( aType == GRAPHIC_GDIMETAFILE ) {
+ GraphicConverter::Export( aStream, rGraphic, CVT_EMF );
+ sMediaType = US( "image/x-emf" );
+ sExtension = ".emf";
+ } else {
+ OSL_TRACE( "unhandled graphic type" );
+ break;
+ }
+
+ aData = aStream.GetData();
+ nDataSize = aStream.GetSize();
+ break;
+ }
+ }
+
+ const char *pComponent = NULL;
+ switch ( meDocumentType )
+ {
+ case DOCUMENT_DOCX: pComponent = "word"; break;
+ case DOCUMENT_PPTX: pComponent = "ppt"; break;
+ case DOCUMENT_XLSX: pComponent = "xl"; break;
+ }
+
+ Reference< XOutputStream > xOutStream = mpFB->openOutputStream( OUStringBuffer()
+ .appendAscii( pComponent )
+ .appendAscii( "/media/image" )
+ .append( (sal_Int32) mnImageCounter )
+ .appendAscii( sExtension )
+ .makeStringAndClear(),
+ sMediaType );
+ xOutStream->writeBytes( Sequence< sal_Int8 >( (const sal_Int8*) aData, nDataSize ) );
+ xOutStream->closeOutput();
+
+ const char *pImagePrefix = NULL;
+ switch ( meDocumentType )
+ {
+ case DOCUMENT_DOCX:
+ pImagePrefix = "media/image";
+ break;
+ case DOCUMENT_PPTX:
+ case DOCUMENT_XLSX:
+ pImagePrefix = "../media/image";
+ break;
+ }
+
+ sRelId = mpFB->addRelation( mpFS->getOutputStream(),
+ US( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ),
+ OUStringBuffer()
+ .appendAscii( pImagePrefix )
+ .append( (sal_Int32) mnImageCounter ++ )
+ .appendAscii( sExtension )
+ .makeStringAndClear() );
+
+ return sRelId;
+}
+
+OUString DrawingML::WriteBlip( OUString& rURL )
+{
+ OUString sRelId = WriteImage( rURL );
+
+ mpFS->singleElementNS( XML_a, XML_blip,
+ FSNS( XML_r, XML_embed), OUStringToOString( sRelId, RTL_TEXTENCODING_UTF8 ).getStr(),
+ FSEND );
+
+ return sRelId;
+}
+
+void DrawingML::WriteBlipMode( Reference< XPropertySet > rXPropSet )
+{
+ BitmapMode eBitmapMode( BitmapMode_NO_REPEAT );
+ if (GetProperty( rXPropSet, S( "FillBitmapMode" ) ) )
+ mAny >>= eBitmapMode;
+
+ DBG(printf("fill bitmap mode: %d\n", eBitmapMode));
+
+ switch (eBitmapMode) {
+ case BitmapMode_REPEAT:
+ mpFS->singleElementNS( XML_a, XML_tile, FSEND );
+ break;
+ default:
+ ;
+ }
+}
+
+void DrawingML::WriteBlipFill( Reference< XPropertySet > rXPropSet, String sURLPropName )
+{
+ WriteBlipFill( rXPropSet, sURLPropName, XML_a );
+}
+
+void DrawingML::WriteBlipFill( Reference< XPropertySet > rXPropSet, String sURLPropName, sal_Int32 nXmlNamespace )
+{
+ if ( GetProperty( rXPropSet, sURLPropName ) ) {
+ OUString aURL;
+ mAny >>= aURL;
+
+ DBG(printf ("URL: %s\n", OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr() ));
+
+ if( !aURL.getLength() )
+ return;
+
+ mpFS->startElementNS( nXmlNamespace , XML_blipFill, FSEND );
+
+ WriteBlip( aURL );
+
+ if( sURLPropName == S( "FillBitmapURL" ) )
+ WriteBlipMode( rXPropSet );
+ else if( GetProperty( rXPropSet, S( "FillBitmapStretch" ) ) ) {
+ bool bStretch = false;
+ mAny >>= bStretch;
+
+ if( bStretch )
+ WriteStretch();
+ }
+
+ mpFS->endElementNS( nXmlNamespace, XML_blipFill );
+ }
+}
+
+void DrawingML::WriteStretch()
+{
+ mpFS->startElementNS( XML_a, XML_stretch, FSEND );
+ mpFS->singleElementNS( XML_a, XML_fillRect, FSEND );
+ mpFS->endElementNS( XML_a, XML_stretch );
+}
+
+void DrawingML::WriteTransformation( const Rectangle& rRect,
+ sal_Bool bFlipH, sal_Bool bFlipV, sal_Int32 nRotation )
+{
+ mpFS->startElementNS( XML_a, XML_xfrm,
+ XML_flipH, bFlipH ? "1" : NULL,
+ XML_flipV, bFlipV ? "1" : NULL,
+ XML_rot, nRotation ? I32S( nRotation ) : NULL,
+ FSEND );
+
+ mpFS->singleElementNS( XML_a, XML_off, XML_x, IS( MM100toEMU( rRect.Left() ) ), XML_y, IS( MM100toEMU( rRect.Top() ) ), FSEND );
+ mpFS->singleElementNS( XML_a, XML_ext, XML_cx, IS( MM100toEMU( rRect.GetWidth() ) ), XML_cy, IS( MM100toEMU( rRect.GetHeight() ) ), FSEND );
+
+ mpFS->endElementNS( XML_a, XML_xfrm );
+}
+
+void DrawingML::WriteShapeTransformation( Reference< XShape > rXShape, sal_Bool bFlipH, sal_Bool bFlipV, sal_Int32 nRotation )
+{
+ DBG(printf( "write shape transformation\n" ));
+
+ awt::Point aPos = rXShape->getPosition();
+ awt::Size aSize = rXShape->getSize();
+
+ WriteTransformation( Rectangle( Point( aPos.X, aPos.Y ), Size( aSize.Width, aSize.Height ) ), bFlipH, bFlipV, nRotation );
+}
+
+void DrawingML::WriteRunProperties( Reference< XTextRange > rRun )
+{
+ Reference< XPropertySet > rXPropSet( rRun, UNO_QUERY );
+ Reference< XPropertyState > rXPropState( rRun, UNO_QUERY );
+ OUString usLanguage;
+ PropertyState eState;
+ sal_Int16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
+ sal_Bool bComplex = ( nScriptType == ScriptType::COMPLEX );
+ const char* bold = NULL;
+ const char* italic = NULL;
+ const char* underline = NULL;
+ sal_Int32 nSize = 1800;
+
+ if( GETAD( CharHeight ) )
+ nSize = (sal_Int32) (100*(*((float*) mAny.getValue())));
+
+ if ( ( bComplex && GETAD( CharWeightComplex ) ) || GETAD( CharWeight ) )
+ if ( *((float*) mAny.getValue()) >= awt::FontWeight::SEMIBOLD )
+ bold = "1";
+
+ if ( ( bComplex && GETAD( CharPostureComplex ) ) || GETAD( CharPosture ) )
+ switch ( *((awt::FontSlant*) mAny.getValue()) )
+ {
+ case awt::FontSlant_OBLIQUE :
+ case awt::FontSlant_ITALIC :
+ italic = "1";
+ break;
+ default:
+ break;
+ }
+
+ if ( GETAD( CharUnderline ) )
+ switch ( *((sal_Int16*) mAny.getValue()) )
+ {
+ case awt::FontUnderline::SINGLE :
+ underline = "sng";
+ break;
+ case awt::FontUnderline::DOUBLE :
+ underline = "dbl";
+ break;
+ case awt::FontUnderline::DOTTED :
+ underline = "dotted";
+ break;
+ case awt::FontUnderline::DASH :
+ underline = "dash";
+ break;
+ case awt::FontUnderline::LONGDASH :
+ underline = "dashLong";
+ break;
+ case awt::FontUnderline::DASHDOT :
+ underline = "dotDash";
+ break;
+ case awt::FontUnderline::DASHDOTDOT :
+ underline = "dotDotDash";
+ break;
+ case awt::FontUnderline::WAVE :
+ underline = "wavy";
+ break;
+ case awt::FontUnderline::DOUBLEWAVE :
+ underline = "wavyDbl";
+ break;
+ case awt::FontUnderline::BOLD :
+ underline = "heavy";
+ break;
+ case awt::FontUnderline::BOLDDOTTED :
+ underline = "dottedHeavy";
+ break;
+ case awt::FontUnderline::BOLDDASH :
+ underline = "dashHeavy";
+ break;
+ case awt::FontUnderline::BOLDLONGDASH :
+ underline = "dashLongHeavy";
+ break;
+ case awt::FontUnderline::BOLDDASHDOT :
+ underline = "dotDashHeavy";
+ break;
+ case awt::FontUnderline::BOLDDASHDOTDOT :
+ underline = "dotDotDashHeavy";
+ break;
+ case awt::FontUnderline::BOLDWAVE :
+ underline = "wavyHeavy";
+ break;
+ }
+
+ if( GETA( CharLocale ) ) {
+ com::sun::star::lang::Locale eLocale;
+ mAny >>= eLocale;
+
+ OUStringBuffer usLanguageBuffer = eLocale.Language;
+ if( eLocale.Country.getLength() ) {
+ usLanguageBuffer.appendAscii( "-" );
+ usLanguageBuffer.append( eLocale.Country );
+ }
+
+ if( usLanguageBuffer.getLength() )
+ usLanguage = usLanguageBuffer.makeStringAndClear();
+ }
+
+ mpFS->startElementNS( XML_a, XML_rPr,
+ XML_b, bold,
+ XML_i, italic,
+ XML_lang, usLanguage.getLength() ? USS( usLanguage ) : NULL,
+ XML_sz, nSize == 1800 ? NULL : IS( nSize ),
+ XML_u, underline,
+ FSEND );
+
+ // mso doesn't like text color to be placed after typeface
+ if( GETAD( CharColor ) ) {
+ sal_uInt32 color = *((sal_uInt32*) mAny.getValue());
+ DBG(printf("run color: %x auto: %x\n", static_cast<unsigned int>( color ), static_cast<unsigned int>( COL_AUTO )));
+
+ if( color == COL_AUTO ) { // nCharColor depends to the background color
+ sal_Bool bIsDark = sal_False;
+ GET( bIsDark, IsBackgroundDark );
+ color = bIsDark ? 0xffffff : 0x000000;
+ }
+ color &= 0xffffff;
+
+ // TODO: special handle embossed/engraved
+
+ WriteSolidFill( color );
+ }
+
+ if( GETAD( CharFontName ) ) {
+ const char* typeface = NULL;
+ const char* pitch = NULL;
+ const char* charset = NULL;
+ OUString usTypeface, usPitch, usCharset;
+
+ mAny >>= usTypeface;
+ String aSubstName( GetSubsFontName( usTypeface, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
+ if( aSubstName.Len() )
+ typeface = ST( aSubstName );
+ else
+ typeface = USS( usTypeface );
+
+
+
+ mpFS->singleElementNS( XML_a, XML_latin,
+ XML_typeface, typeface,
+ XML_pitchFamily, pitch,
+ XML_charset, charset,
+ FSEND );
+ }
+
+ if( ( bComplex && GETAD( CharFontNameComplex ) ) || ( !bComplex && GETAD( CharFontNameAsian ) ) ) {
+ const char* typeface = NULL;
+ const char* pitch = NULL;
+ const char* charset = NULL;
+ OUString usTypeface, usPitch, usCharset;
+
+ mAny >>= usTypeface;
+ String aSubstName( GetSubsFontName( usTypeface, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
+ if( aSubstName.Len() )
+ typeface = ST( aSubstName );
+ else
+ typeface = USS( usTypeface );
+
+ mpFS->singleElementNS( XML_a, bComplex ? XML_cs : XML_ea,
+ XML_typeface, typeface,
+ XML_pitchFamily, pitch,
+ XML_charset, charset,
+ FSEND );
+ }
+
+ mpFS->endElementNS( XML_a, XML_rPr );
+}
+
+const char* DrawingML::GetFieldType( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun )
+{
+ const char* sType = NULL;
+ Reference< XPropertySet > rXPropSet( rRun, UNO_QUERY );
+ String aFieldType;
+
+ if( GETA( TextPortionType ) ) {
+ aFieldType = String( *(::rtl::OUString*)mAny.getValue() );
+ DBG(printf ("field type: %s\n", ST(aFieldType) ));
+ }
+
+ if( aFieldType == S( "TextField" ) ) {
+ Reference< XTextField > rXTextField;
+ GET( rXTextField, TextField );
+ if( rXTextField.is() ) {
+ rXPropSet.set( rXTextField, UNO_QUERY );
+ if( rXPropSet.is() ) {
+ String aFieldKind( rXTextField->getPresentation( TRUE ) );
+ DBG(printf ("field kind: %s\n", ST(aFieldKind) ));
+ if( aFieldKind == S( "Page" ) ) {
+ return "slidenum";
+ }
+ }
+ }
+ }
+
+ return sType;
+}
+
+void DrawingML::GetUUID( OStringBuffer& rBuffer )
+{
+ Sequence< sal_uInt8 > aSeq( 16 );
+ static char cDigits[17] = "0123456789ABCDEF";
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ int i;
+
+ rBuffer.append( '{' );
+ for( i = 0; i < 4; i++ ) {
+ rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
+ rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
+ }
+ rBuffer.append( '-' );
+ for( ; i < 6; i++ ) {
+ rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
+ rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
+ }
+ rBuffer.append( '-' );
+ for( ; i < 8; i++ ) {
+ rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
+ rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
+ }
+ rBuffer.append( '-' );
+ for( ; i < 10; i++ ) {
+ rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
+ rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
+ }
+ rBuffer.append( '-' );
+ for( ; i < 16; i++ ) {
+ rBuffer.append( cDigits[ aSeq[i] >> 4 ] );
+ rBuffer.append( cDigits[ aSeq[i] && 0xf ] );
+ }
+ rBuffer.append( '}' );
+}
+
+void DrawingML::WriteRun( Reference< XTextRange > rRun )
+{
+ const char* sFieldType;
+ bool bIsField = false;
+ OUString sText = rRun->getString();
+
+ if( sText.getLength() < 1)
+ return;
+
+ if( ( sFieldType = GetFieldType( rRun ) ) ) {
+ OStringBuffer sUUID(39);
+
+ GetUUID( sUUID );
+ mpFS->startElementNS( XML_a, XML_fld,
+ XML_id, sUUID.getStr(),
+ XML_type, sFieldType,
+ FSEND );
+ bIsField = true;
+ } else
+ mpFS->startElementNS( XML_a, XML_r, FSEND );
+
+ WriteRunProperties( rRun );
+
+ mpFS->startElementNS( XML_a, XML_t, FSEND );
+ mpFS->writeEscaped( sText );
+ mpFS->endElementNS( XML_a, XML_t );
+
+ if( bIsField )
+ mpFS->endElementNS( XML_a, XML_fld );
+ else
+ mpFS->endElementNS( XML_a, XML_r );
+}
+
+#define AUTONUM(x) \
+ if( bPBoth ) \
+ pAutoNumType = #x "ParenBoth"; \
+ else if( bPBehind ) \
+ pAutoNumType = #x "ParenR"; \
+ else if( bSDot ) \
+ pAutoNumType = #x "Period";
+
+
+inline static const char* GetAutoNumType( sal_Int16 nNumberingType, bool bSDot, bool bPBehind, bool bPBoth )
+{
+ const char* pAutoNumType = NULL;
+
+ switch( (SvxExtNumType)nNumberingType )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER_N :
+ case SVX_NUM_CHARS_UPPER_LETTER :
+ AUTONUM( alphaUc );
+ break;
+ case SVX_NUM_CHARS_LOWER_LETTER_N :
+ case SVX_NUM_CHARS_LOWER_LETTER :
+ AUTONUM( alphaLc );
+ break;
+ case SVX_NUM_ROMAN_UPPER :
+ AUTONUM( romanUc );
+ break;
+ case SVX_NUM_ROMAN_LOWER :
+ AUTONUM( romanLc );
+ break;
+ case SVX_NUM_ARABIC :
+ AUTONUM( arabic )
+ else
+ pAutoNumType = "arabicPlain";
+ break;
+ default:
+ break;
+ }
+
+ return pAutoNumType;
+}
+
+void DrawingML::WriteParagraphNumbering( Reference< XPropertySet > rXPropSet, sal_Int16 nLevel )
+{
+ if( nLevel >= 0 && GETA( NumberingRules ) )
+ {
+ Reference< XIndexAccess > rXIndexAccess;
+
+ if ( ( mAny >>= rXIndexAccess ) && nLevel < rXIndexAccess->getCount() )
+ {
+ DBG(printf ("numbering rules\n"));
+
+ Sequence< PropertyValue > aPropertySequence;
+ rXIndexAccess->getByIndex( nLevel ) >>= aPropertySequence;
+
+
+ const PropertyValue* pPropValue = aPropertySequence.getArray();
+
+ sal_Int32 nPropertyCount = aPropertySequence.getLength();
+
+ if ( nPropertyCount ) {
+
+ sal_Int16 nNumberingType = -1;
+ bool bSDot = false;
+ bool bPBehind = false;
+ bool bPBoth = false;
+ sal_Unicode aBulletChar = 0x2022; // a bullet
+ awt::FontDescriptor aFontDesc;
+ bool bHasFontDesc = false;
+ OUString aGraphicURL;
+ sal_Int16 nBulletRelSize = 0;
+
+ for ( sal_Int32 i = 0; i < nPropertyCount; i++ ) {
+ const void* pValue = pPropValue[ i ].Value.getValue();
+ if ( pValue ) {
+ OUString aPropName( pPropValue[ i ].Name );
+ DBG(printf ("pro name: %s\n", OUStringToOString( aPropName, RTL_TEXTENCODING_UTF8 ).getStr()));
+ if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "NumberingType" ) ) )
+ nNumberingType = *( (sal_Int16*)pValue );
+ else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Prefix" ) ) ) {
+ if( *(OUString*)pValue == US( ")" ) )
+ bPBoth = true;
+ } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Suffix" ) ) ) {
+ if( *(OUString*)pValue == US( "." ) )
+ bSDot = true;
+ else if( *(OUString*)pValue == US( ")" ) )
+ bPBehind = true;
+ } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletChar" ) ) )
+ {
+ aBulletChar = String ( *( (String*)pValue ) ).GetChar( 0 );
+ //printf ("bullet char: %d\n", aBulletChar.getStr());
+ }
+ else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletFont" ) ) )
+ {
+ aFontDesc = *( (awt::FontDescriptor*)pValue );
+ bHasFontDesc = true;
+
+ // Our numbullet dialog has set the wrong textencoding for our "StarSymbol" font,
+ // instead of a Unicode encoding the encoding RTL_TEXTENCODING_SYMBOL was used.
+ // Because there might exist a lot of damaged documemts I added this two lines
+ // which fixes the bullet problem for the export.
+ if ( aFontDesc.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StarSymbol" ) ) )
+ aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
+
+ } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletRelSize" ) ) ) {
+ nBulletRelSize = *( (sal_Int16*)pValue );
+ } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicURL" ) ) ) {
+ aGraphicURL = ( *(OUString*)pValue );
+ DBG(printf ("graphic url: %s\n", OUStringToOString( aGraphicURL, RTL_TEXTENCODING_UTF8 ).getStr()));
+ } else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicSize" ) ) )
+ {
+ if ( pPropValue[ i ].Value.getValueType() == ::getCppuType( (awt::Size*)0) )
+ {
+ // don't cast awt::Size to Size as on 64-bits they are not the same.
+ ::com::sun::star::awt::Size aSize;
+ pPropValue[ i ].Value >>= aSize;
+ //aBuGraSize.nA = aSize.Width;
+ //aBuGraSize.nB = aSize.Height;
+ DBG(printf("graphic size: %dx%d\n", int( aSize.Width ), int( aSize.Height )));
+ }
+ }
+ }
+ }
+
+ const char* pAutoNumType = GetAutoNumType( nNumberingType, bSDot, bPBehind, bPBoth );
+
+ if( nLevel >= 0 ) {
+ if( aGraphicURL.getLength() > 0 ) {
+ OUString sRelId = WriteImage( aGraphicURL );
+
+ mpFS->startElementNS( XML_a, XML_buBlip, FSEND );
+ mpFS->singleElementNS( XML_a, XML_blip, FSNS( XML_r, XML_embed ), USS( sRelId ), FSEND );
+ mpFS->endElementNS( XML_a, XML_buBlip );
+ } else {
+ if( nBulletRelSize && nBulletRelSize != 100 )
+ mpFS->singleElementNS( XML_a, XML_buSzPct,
+ XML_val, IS( 1000*( (sal_Int32)nBulletRelSize ) ), FSEND );
+ if( bHasFontDesc )
+ mpFS->singleElementNS( XML_a, XML_buFont,
+ XML_typeface, OUStringToOString( aFontDesc.Name, RTL_TEXTENCODING_UTF8 ).getStr(),
+ XML_charset, (aFontDesc.CharSet == awt::CharSet::SYMBOL) ? "2" : NULL,
+ FSEND );
+
+ if( pAutoNumType )
+ mpFS->singleElementNS( XML_a, XML_buAutoNum, XML_type, pAutoNumType, FSEND );
+ else {
+ aBulletChar = SubstituteBullet( aBulletChar, aFontDesc );
+ mpFS->singleElementNS( XML_a, XML_buChar, XML_char, USS( OUString( aBulletChar ) ), FSEND );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+const char* DrawingML::GetAlignment( sal_Int32 nAlignment )
+{
+ const char* sAlignment = NULL;
+
+ switch( nAlignment ) {
+ case style::ParagraphAdjust_CENTER:
+ sAlignment = "ctr";
+ break;
+ case style::ParagraphAdjust_RIGHT:
+ sAlignment = "r";
+ break;
+ case style::ParagraphAdjust_BLOCK:
+ sAlignment = "just";
+ break;
+ default:
+ ;
+ }
+
+ return sAlignment;
+}
+
+void DrawingML::WriteParagraphProperties( Reference< XTextContent > rParagraph )
+{
+ Reference< XPropertySet > rXPropSet( rParagraph, UNO_QUERY );
+ Reference< XPropertyState > rXPropState( rParagraph, UNO_QUERY );
+
+ if( !rXPropSet.is() || !rXPropState.is() )
+ return;
+
+ sal_Int16 nLevel = -1;
+ GET( nLevel, NumberingLevel );
+
+ sal_Int32 nLeftMargin = 0;
+ // fix coordinates
+ //GET( nLeftMargin, ParaLeftMargin );
+
+ sal_Int16 nAlignment( style::ParagraphAdjust_LEFT );
+ GET( nAlignment, ParaAdjust );
+
+ if( nLevel != -1
+ || nLeftMargin > 0
+ || nAlignment != style::ParagraphAdjust_LEFT ) {
+ mpFS->startElementNS( XML_a, XML_pPr,
+ XML_lvl, nLevel > 0 ? I32S( nLevel ) : NULL,
+ XML_marL, nLeftMargin > 0 ? IS( nLeftMargin ) : NULL,
+ XML_algn, GetAlignment( nAlignment ),
+ FSEND );
+
+ WriteParagraphNumbering( rXPropSet, nLevel );
+
+ mpFS->endElementNS( XML_a, XML_pPr );
+ }
+}
+
+void DrawingML::WriteParagraph( Reference< XTextContent > rParagraph )
+{
+ Reference< XEnumerationAccess > access( rParagraph, UNO_QUERY );
+ if( !access.is() )
+ return;
+
+ Reference< XEnumeration > enumeration( access->createEnumeration() );
+ if( !enumeration.is() )
+ return;
+
+ mpFS->startElementNS( XML_a, XML_p, FSEND );
+
+ sal_Bool bPropertiesWritten = FALSE;
+ while( enumeration->hasMoreElements() ) {
+ Reference< XTextRange > run;
+ Any any ( enumeration->nextElement() );
+
+ if (any >>= run) {
+ if( !bPropertiesWritten && run->getString().getLength() ) {
+ WriteParagraphProperties( rParagraph );
+ bPropertiesWritten = TRUE;
+ }
+ WriteRun( run );
+ }
+ }
+ mpFS->singleElementNS( XML_a, XML_endParaRPr, FSEND );
+
+ mpFS->endElementNS( XML_a, XML_p );
+}
+
+void DrawingML::WriteText( Reference< XShape > rXShape )
+{
+ Reference< XText > xXText( rXShape, UNO_QUERY );
+ Reference< XPropertySet > rXPropSet( rXShape, UNO_QUERY );
+
+ if( !xXText.is() )
+ return;
+
+#define DEFLRINS 254
+#define DEFTBINS 127
+ sal_Int32 nLeft, nRight, nTop, nBottom;
+ nLeft = nRight = DEFLRINS;
+ nTop = nBottom = DEFTBINS;
+
+ // top inset looks a bit different compared to ppt export
+ // check if something related doesn't work as expected
+ GET( nLeft, TextLeftDistance );
+ GET( nRight, TextRightDistance );
+ GET( nTop, TextUpperDistance );
+ GET( nBottom, TextLowerDistance );
+
+ TextVerticalAdjust eVerticalAlignment( TextVerticalAdjust_TOP );
+ const char* sVerticalAlignment = NULL;
+ GET( eVerticalAlignment, TextVerticalAdjust );
+ switch( eVerticalAlignment ) {
+ case TextVerticalAdjust_BOTTOM:
+ sVerticalAlignment = "b";
+ break;
+ case TextVerticalAdjust_CENTER:
+ sVerticalAlignment = "ctr";
+ break;
+ case TextVerticalAdjust_TOP:
+ default:
+ ;
+ }
+
+ TextHorizontalAdjust eHorizontalAlignment( TextHorizontalAdjust_CENTER );
+ bool bHorizontalCenter = false;
+ GET( eHorizontalAlignment, TextHorizontalAdjust );
+ if( eHorizontalAlignment == TextHorizontalAdjust_CENTER )
+ bHorizontalCenter = true;
+
+ sal_Bool bHasWrap = FALSE;
+ sal_Bool bWrap = FALSE;
+ if( GETA( TextWordWrap ) ) {
+ mAny >>= bWrap;
+ bHasWrap = TRUE;
+ //DBG(printf("wrap: %d\n", bWrap));
+ }
+
+ mpFS->singleElementNS( XML_a, XML_bodyPr,
+ XML_wrap, bHasWrap && !bWrap ? "none" : NULL,
+ XML_lIns, (nLeft != DEFLRINS) ? IS( MM100toEMU( nLeft ) ) : NULL,
+ XML_rIns, (nRight != DEFLRINS) ? IS( MM100toEMU( nRight ) ) : NULL,
+ XML_tIns, (nTop != DEFTBINS) ? IS( MM100toEMU( nTop ) ) : NULL,
+ XML_bIns, (nBottom != DEFTBINS) ? IS( MM100toEMU( nBottom ) ) : NULL,
+ XML_anchor, sVerticalAlignment,
+ XML_anchorCtr, bHorizontalCenter ? "1" : NULL,
+ FSEND );
+
+ Reference< XEnumerationAccess > access( xXText, UNO_QUERY );
+ if( !access.is() )
+ return;
+
+ Reference< XEnumeration > enumeration( access->createEnumeration() );
+ if( !enumeration.is() )
+ return;
+
+ while( enumeration->hasMoreElements() ) {
+ Reference< XTextContent > paragraph;
+ Any any ( enumeration->nextElement() );
+
+ if( any >>= paragraph)
+ WriteParagraph( paragraph );
+ }
+
+}
+
+void DrawingML::WritePresetShape( const char* pShape )
+{
+ mpFS->startElementNS( XML_a, XML_prstGeom,
+ XML_prst, pShape,
+ FSEND );
+ mpFS->singleElementNS( XML_a, XML_avLst, FSEND );
+ mpFS->endElementNS( XML_a, XML_prstGeom );
+}
+
+void DrawingML::WritePresetShape( const char* pShape, MSO_SPT eShapeType, sal_Bool bPredefinedHandlesUsed, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, const PropertyValue& rProp )
+{
+ mpFS->startElementNS( XML_a, XML_prstGeom,
+ XML_prst, pShape,
+ FSEND );
+ mpFS->startElementNS( XML_a, XML_avLst, FSEND );
+
+ Sequence< drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
+ if ( rProp.Value >>= aAdjustmentSeq ) {
+ DBG(printf("adj seq len: %d\n", int( aAdjustmentSeq.getLength() )));
+ if ( bPredefinedHandlesUsed )
+ EscherPropertyContainer::LookForPolarHandles( eShapeType, nAdjustmentsWhichNeedsToBeConverted );
+
+ sal_Int32 nValue, nLength = aAdjustmentSeq.getLength();
+ for( sal_Int32 i=0; i < nLength; i++ )
+ if( EscherPropertyContainer::GetAdjustmentValue( aAdjustmentSeq[ i ], i, nAdjustmentsWhichNeedsToBeConverted, nValue ) )
+ mpFS->singleElementNS( XML_a, XML_gd,
+ XML_name, nLength > 1 ? ( OString( "adj" ) + OString::valueOf( i + 1 ) ).getStr() : "adj",
+ XML_fmla, (OString("val ") + OString::valueOf( nValue )).getStr(),
+ FSEND );
+ }
+
+ mpFS->endElementNS( XML_a, XML_avLst );
+ mpFS->endElementNS( XML_a, XML_prstGeom );
+}
+
+void DrawingML::WritePolyPolygon( const PolyPolygon& rPolyPolygon )
+{
+ if( rPolyPolygon.Count() < 1 )
+ return;
+
+ mpFS->startElementNS( XML_a, XML_custGeom, FSEND );
+ mpFS->singleElementNS( XML_a, XML_avLst, FSEND );
+ mpFS->singleElementNS( XML_a, XML_gdLst, FSEND );
+ mpFS->singleElementNS( XML_a, XML_ahLst, FSEND );
+ mpFS->singleElementNS( XML_a, XML_rect,
+ XML_l, "0",
+ XML_t, "0",
+ XML_r, "r",
+ XML_b, "b",
+ FSEND );
+
+ mpFS->startElementNS( XML_a, XML_pathLst, FSEND );
+
+ for( USHORT i = 0; i < rPolyPolygon.Count(); i ++ ) {
+
+ const Polygon& rPoly = rPolyPolygon[ i ];
+ Rectangle aRect( rPoly.GetBoundRect() );
+ sal_Bool bBezier = FALSE;
+
+ mpFS->startElementNS( XML_a, XML_path,
+ XML_w, I64S( aRect.GetWidth() ),
+ XML_h, I64S( aRect.GetHeight() ),
+ FSEND );
+
+ if( rPoly.GetSize() > 0 )
+ {
+ mpFS->startElementNS( XML_a, XML_moveTo, FSEND );
+
+ mpFS->singleElementNS( XML_a, XML_pt,
+ XML_x, I64S( rPoly[ 0 ].X() - aRect.Left() ),
+ XML_y, I64S( rPoly[ 0 ].Y() - aRect.Top() ),
+ FSEND );
+
+ mpFS->endElementNS( XML_a, XML_moveTo );
+ }
+
+ for( USHORT j = 1; j < rPoly.GetSize(); j ++ )
+ {
+ enum PolyFlags flags = rPoly.GetFlags(j);
+ if( flags == POLY_CONTROL && !bBezier )
+ {
+ mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND );
+ bBezier = TRUE;
+ }
+ else if( flags == POLY_NORMAL && !bBezier )
+ mpFS->startElementNS( XML_a, XML_lnTo, FSEND );
+
+ mpFS->singleElementNS( XML_a, XML_pt,
+ XML_x, I64S( rPoly[j].X() - aRect.Left() ),
+ XML_y, I64S( rPoly[j].Y() - aRect.Top() ),
+ FSEND );
+
+ if( ( flags == POLY_NORMAL || flags == POLY_SYMMTR ) && bBezier )
+ {
+ mpFS->endElementNS( XML_a, XML_cubicBezTo );
+ bBezier = FALSE;
+ }
+ else if( flags == POLY_NORMAL && !bBezier )
+ mpFS->endElementNS( XML_a, XML_lnTo );
+ else if( bBezier && ( j % 3 ) == 0 )
+ {
+ // //a:cubicBezTo can only contain 3 //a:pt elements, so we
+ // need to break things up...
+ mpFS->endElementNS( XML_a, XML_cubicBezTo );
+ mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND );
+ }
+// switch( rPoly.GetFlags(j) ) {
+// case POLY_NORMAL:
+// DBG(printf("normal\n"));
+// break;
+// case POLY_SMOOTH:
+// DBG(printf("smooth\n"));
+// break;
+// case POLY_CONTROL:
+// DBG(printf("control\n"));
+// break;
+// case POLY_SYMMTR:
+// DBG(printf("symmtr\n"));
+// break;
+// }
+// DBG(printf("point %ld %ld\n", rPoly[j].X() - aRect.Left(), rPoly[j].Y() - aRect.Top()));
+ }
+
+ mpFS->endElementNS( XML_a, XML_path );
+ }
+
+ mpFS->endElementNS( XML_a, XML_pathLst );
+
+ mpFS->endElementNS( XML_a, XML_custGeom );
+}
+
+void DrawingML::WriteConnectorConnections( EscherConnectorListEntry& rConnectorEntry, sal_Int32 nStartID, sal_Int32 nEndID )
+{
+ mpFS->singleElementNS( XML_a, XML_stCxn,
+ XML_id, I32S( nStartID ),
+ XML_idx, I64S( rConnectorEntry.GetConnectorRule( TRUE ) ),
+ FSEND );
+ mpFS->singleElementNS( XML_a, XML_endCxn,
+ XML_id, I32S( nEndID ),
+ XML_idx, I64S( rConnectorEntry.GetConnectorRule( FALSE ) ),
+ FSEND );
+}
+
+// from sw/source/filter/ww8/wrtw8num.cxx for default bullets to export to MS intact
+static void lcl_SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, String& rFontName)
+{
+ sal_Unicode cChar = rNumStr.GetChar(0);
+ StarSymbolToMSMultiFont *pConvert = CreateStarSymbolToMSMultiFont();
+ String sFont = pConvert->ConvertChar(cChar);
+ delete pConvert;
+ if (sFont.Len())
+ {
+ rNumStr = static_cast< sal_Unicode >(cChar | 0xF000);
+ rFontName = sFont;
+ rChrSet = RTL_TEXTENCODING_SYMBOL;
+ }
+ else if ( (rNumStr.GetChar(0) < 0xE000 || rNumStr.GetChar(0) > 0xF8FF) )
+ {
+ /*
+ Ok we can't fit into a known windows unicode font, but
+ we are not in the private area, so we are a
+ standardized symbol, so turn off the symbol bit and
+ let words own font substitution kick in
+ */
+ rChrSet = RTL_TEXTENCODING_UNICODE;
+ rFontName = ::GetFontToken(rFontName, 0);
+ }
+ else
+ {
+ /*
+ Well we don't have an available substition, and we're
+ in our private area, so give up and show a standard
+ bullet symbol
+ */
+ rFontName.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Wingdings"));
+ rNumStr = static_cast< sal_Unicode >(0x6C);
+ }
+}
+
+sal_Unicode DrawingML::SubstituteBullet( sal_Unicode cBulletId, ::com::sun::star::awt::FontDescriptor& rFontDesc )
+{
+ String sNumStr = cBulletId;
+
+ if ( rFontDesc.Name.equalsIgnoreAsciiCaseAscii("starsymbol") ||
+ rFontDesc.Name.equalsIgnoreAsciiCaseAscii("opensymbol") ) {
+ String sFontName = rFontDesc.Name;
+ rtl_TextEncoding aCharSet = rFontDesc.CharSet;
+
+ lcl_SubstituteBullet( sNumStr, aCharSet, sFontName );
+
+ rFontDesc.Name = sFontName;
+ rFontDesc.CharSet = aCharSet;
+ }
+
+ return sNumStr.GetChar( 0 );
+}
+
+}
+}
diff --git a/oox/source/export/makefile.mk b/oox/source/export/makefile.mk
new file mode 100644
index 000000000000..08fa7a09dff8
--- /dev/null
+++ b/oox/source/export/makefile.mk
@@ -0,0 +1,27 @@
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=export
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/drawingml.obj \
+ $(SLO)$/shapes.obj \
+ $(SLO)$/vmlexport.obj \
+ $(SLO)$/vmlexport-shape-types.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(MISC)$/vmlexport-shape-types.cxx : preset-definitions-to-shape-types.pl presetShapeDefinitions.xml presetTextWarpDefinitions.xml
+ $(PERL) $< > $@.in_progress 2> $(MISC)$/vmlexport-shape-types.log && mv $@.in_progress $@
diff --git a/oox/source/export/preset-definitions-to-shape-types.pl b/oox/source/export/preset-definitions-to-shape-types.pl
new file mode 100644
index 000000000000..5ecb82f814de
--- /dev/null
+++ b/oox/source/export/preset-definitions-to-shape-types.pl
@@ -0,0 +1,1242 @@
+#! /usr/bin/perl -w
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+use warnings;
+
+sub usage() {
+ print STDERR <<EOF;
+Usage: preset-definitions-to-shape-types.pl <shapes> <text>
+
+Converts presetShapeDefinitions.xml and presetTextWarpDefinitions.xml to a
+.cxx that contains VML with the definitions of the shapes. The result is
+written to stdout.
+
+<shapes> presetShapeDefinitions.xml (including the path to it)
+<text> presetTextWarpDefinitions.xml (including the path to it)
+EOF
+ exit 1;
+}
+
+sub show_call_stack
+{
+ my ( $path, $line, $subr );
+ my $max_depth = 30;
+ my $i = 1;
+ print STDERR "--- Begin stack trace ---\n";
+ while ( (my @call_details = (caller($i++))) && ($i<$max_depth) ) {
+ print STDERR "$call_details[1] line $call_details[2] in function $call_details[3]\n";
+ }
+ print STDERR "--- End stack trace ---\n";
+}
+
+$src_shapes = shift;
+$src_text = shift;
+
+usage() if ( !defined( $src_shapes ) || !defined( $src_text ) ||
+ $src_shapes eq "-h" || $src_shapes eq "--help" ||
+ !-f $src_shapes || !-f $src_text );
+
+# Global variables
+@levels = ();
+$shape_name = "";
+$state = "";
+$path = "";
+$adjust = "";
+$max_adj_no = 0;
+@formulas = ();
+%variables = ();
+$ignore_this_shape = 0;
+$handles = "";
+$textboxrect = "";
+$last_pos_x = "";
+$last_pos_y = "";
+$no_stroke = 0;
+$no_fill = 0;
+$path_w = 1;
+$path_h = 1;
+@quadratic_bezier = ();
+
+%result_shapes = ();
+
+%shapes_ids = (
+ 0 => 'notPrimitive',
+ 1 => 'rectangle',
+ 2 => 'roundRectangle',
+ 3 => 'ellipse',
+ 4 => 'diamond',
+ 5 => 'triangle',
+ 6 => 'rtTriangle',
+ 7 => 'parallelogram',
+ 8 => 'trapezoid',
+ 9 => 'hexagon',
+ 10 => 'octagon',
+ 11 => 'plus',
+ 12 => 'star5',
+ 13 => 'rightArrow',
+ 14 => 'thickArrow', # should not be used
+ 15 => 'homePlate',
+ 16 => 'cube',
+ 17 => 'wedgeRoundRectCallout', # balloon
+ 18 => 'star16', # seal
+ 19 => 'arc',
+ 20 => 'line',
+ 21 => 'plaque',
+ 22 => 'can',
+ 23 => 'donut',
+ 24 => 'textPlain', # textSimple - FIXME MS Office 2007 converts these to textboxes with unstyled text, so is it actually correct to map it to a real style?
+ 25 => 'textStop', # textOctagon FIXME see 24
+ 26 => 'textTriangle', # textHexagon FIXMME see 24
+ 27 => 'textCanDown', # textCurve FIXMME see 24
+ 28 => 'textWave1', # textWave FIXMME see 24
+ 29 => 'textArchUpPour', # textRing FIXMME see 24
+ 30 => 'textCanDown', # textOnCurve FIXMME see 24
+ 31 => 'textArchUp', # textOnRing FIXMME see 24
+ 32 => 'straightConnector1',
+ 33 => 'bentConnector2',
+ 34 => 'bentConnector3',
+ 35 => 'bentConnector4',
+ 36 => 'bentConnector5',
+ 37 => 'curvedConnector2',
+ 38 => 'curvedConnector3',
+ 39 => 'curvedConnector4',
+ 40 => 'curvedConnector5',
+ 41 => 'callout1',
+ 42 => 'callout2',
+ 43 => 'callout3',
+ 44 => 'accentCallout1',
+ 45 => 'accentCallout2',
+ 46 => 'accentCallout3',
+ 47 => 'borderCallout1',
+ 48 => 'borderCallout2',
+ 49 => 'borderCallout3',
+ 50 => 'accentBorderCallout1',
+ 51 => 'accentBorderCallout2',
+ 52 => 'accentBorderCallout3',
+ 53 => 'ribbon',
+ 54 => 'ribbon2',
+ 55 => 'chevron',
+ 56 => 'pentagon',
+ 57 => 'noSmoking',
+ 58 => 'star8', # seal8
+ 59 => 'star16', # seal16
+ 60 => 'star32', # seal32
+ 61 => 'wedgeRectCallout',
+ 62 => 'wedgeRoundRectCallout', # wedgeRRectCallout
+ 63 => 'wedgeEllipseCallout',
+ 64 => 'wave',
+ 65 => 'foldedCorner',
+ 66 => 'leftArrow',
+ 67 => 'downArrow',
+ 68 => 'upArrow',
+ 69 => 'leftRightArrow',
+ 70 => 'upDownArrow',
+ 71 => 'irregularSeal1',
+ 72 => 'irregularSeal2',
+ 73 => 'lightningBolt',
+ 74 => 'heart',
+ 75 => 'frame', # pictureFrame
+ 76 => 'quadArrow',
+ 77 => 'leftArrowCallout',
+ 78 => 'rightArrowCallout',
+ 79 => 'upArrowCallout',
+ 80 => 'downArrowCallout',
+ 81 => 'leftRightArrowCallout',
+ 82 => 'upDownArrowCallout',
+ 83 => 'quadArrowCallout',
+ 84 => 'bevel',
+ 85 => 'leftBracket',
+ 86 => 'rightBracket',
+ 87 => 'leftBrace',
+ 88 => 'rightBrace',
+ 89 => 'leftUpArrow',
+ 90 => 'bentUpArrow',
+ 91 => 'bentArrow',
+ 92 => 'star24', # seal24
+ 93 => 'stripedRightArrow',
+ 94 => 'notchedRightArrow',
+ 95 => 'blockArc',
+ 96 => 'smileyFace',
+ 97 => 'verticalScroll',
+ 98 => 'horizontalScroll',
+ 99 => 'circularArrow',
+ 100 => 'notchedCircularArrow', # should not be used
+ 101 => 'uturnArrow',
+ 102 => 'curvedRightArrow',
+ 103 => 'curvedLeftArrow',
+ 104 => 'curvedUpArrow',
+ 105 => 'curvedDownArrow',
+ 106 => 'cloudCallout',
+ 107 => 'ellipseRibbon',
+ 108 => 'ellipseRibbon2',
+ 109 => 'flowChartProcess',
+ 110 => 'flowChartDecision',
+ 111 => 'flowChartInputOutput',
+ 112 => 'flowChartPredefinedProcess',
+ 113 => 'flowChartInternalStorage',
+ 114 => 'flowChartDocument',
+ 115 => 'flowChartMultidocument',
+ 116 => 'flowChartTerminator',
+ 117 => 'flowChartPreparation',
+ 118 => 'flowChartManualInput',
+ 119 => 'flowChartManualOperation',
+ 120 => 'flowChartConnector',
+ 121 => 'flowChartPunchedCard',
+ 122 => 'flowChartPunchedTape',
+ 123 => 'flowChartSummingJunction',
+ 124 => 'flowChartOr',
+ 125 => 'flowChartCollate',
+ 126 => 'flowChartSort',
+ 127 => 'flowChartExtract',
+ 128 => 'flowChartMerge',
+ 129 => 'flowChartOfflineStorage',
+ 130 => 'flowChartOnlineStorage',
+ 131 => 'flowChartMagneticTape',
+ 132 => 'flowChartMagneticDisk',
+ 133 => 'flowChartMagneticDrum',
+ 134 => 'flowChartDisplay',
+ 135 => 'flowChartDelay',
+ 136 => 'textPlain', # textPlainText
+ 137 => 'textStop',
+ 138 => 'textTriangle',
+ 139 => 'textTriangleInverted',
+ 140 => 'textChevron',
+ 141 => 'textChevronInverted',
+ 142 => 'textRingInside',
+ 143 => 'textRingOutside',
+ 144 => 'textArchUp', # textArchUpCurve
+ 145 => 'textArchDown', # textArchDownCurve
+ 146 => 'textCircle', # textCircleCurve
+ 147 => 'textButton', # textButtonCurve
+ 148 => 'textArchUpPour',
+ 149 => 'textArchDownPour',
+ 150 => 'textCirclePour',
+ 151 => 'textButtonPour',
+ 152 => 'textCurveUp',
+ 153 => 'textCurveDown',
+ 154 => 'textCascadeUp',
+ 155 => 'textCascadeDown',
+ 156 => 'textWave1',
+ 157 => 'textWave2',
+ 158 => 'textWave3',
+ 159 => 'textWave4',
+ 160 => 'textInflate',
+ 161 => 'textDeflate',
+ 162 => 'textInflateBottom',
+ 163 => 'textDeflateBottom',
+ 164 => 'textInflateTop',
+ 165 => 'textDeflateTop',
+ 166 => 'textDeflateInflate',
+ 167 => 'textDeflateInflateDeflate',
+ 168 => 'textFadeRight',
+ 169 => 'textFadeLeft',
+ 170 => 'textFadeUp',
+ 171 => 'textFadeDown',
+ 172 => 'textSlantUp',
+ 173 => 'textSlantDown',
+ 174 => 'textCanUp',
+ 175 => 'textCanDown',
+ 176 => 'flowChartAlternateProcess',
+ 177 => 'flowChartOffpageConnector',
+ 178 => 'callout1', # callout90
+ 179 => 'accentCallout1', # accentCallout90
+ 180 => 'borderCallout1', # borderCallout90
+ 181 => 'accentBorderCallout1', # accentBorderCallout90
+ 182 => 'leftRightUpArrow',
+ 183 => 'sun',
+ 184 => 'moon',
+ 185 => 'bracketPair',
+ 186 => 'bracePair',
+ 187 => 'star4', # seal4
+ 188 => 'doubleWave',
+ 189 => 'actionButtonBlank',
+ 190 => 'actionButtonHome',
+ 191 => 'actionButtonHelp',
+ 192 => 'actionButtonInformation',
+ 193 => 'actionButtonForwardNext',
+ 194 => 'actionButtonBackPrevious',
+ 195 => 'actionButtonEnd',
+ 196 => 'actionButtonBeginning',
+ 197 => 'actionButtonReturn',
+ 198 => 'actionButtonDocument',
+ 199 => 'actionButtonSound',
+ 200 => 'actionButtonMovie',
+ 201 => 'hostControl', # should not be used
+ 202 => 'textBox'
+);
+# An error occured, we have to ignore this shape
+sub error( $ )
+{
+ my ( $msg ) = @_;
+
+ $ignore_this_shape = 1;
+ print STDERR "ERROR (in $shape_name ): $msg\n";
+}
+
+# Check that we are in the correct level
+sub is_level( $$ )
+{
+ my ( $level, $value ) = @_;
+
+ if ( $level > 0 ) {
+ error( "Error in is_level(), \$level should be <= 0." );
+ }
+ return ( $#levels + $level > 0 ) && ( $levels[$#levels + $level] eq $value );
+}
+
+# Setup the %variables map with predefined values
+sub setup_variables()
+{
+ %variables = (
+ 'l' => 0,
+ 't' => 0,
+ 'r' => 21600,
+ 'b' => 21600,
+
+ 'w' => 21600,
+ 'h' => 21600,
+ 'ss' => 21600,
+ 'ls' => 21600,
+
+ 'ssd2' => 10800, # 1/2
+ 'ssd4' => 5400, # 1/4
+ 'ssd6' => 3600, # 1/6
+ 'ssd8' => 2700, # 1/8
+ 'ssd16' => 1350, # 1/16
+ 'ssd32' => 675, # 1/32
+
+ 'hc' => 10800, # horizontal center
+ 'vc' => 10800, # vertical center
+
+ 'wd2' => 10800, # 1/2
+ 'wd3' => 7200, # 1/3
+ 'wd4' => 5400, # 1/4
+ 'wd5' => 4320, # 1/5
+ 'wd6' => 3600, # 1/6
+ 'wd8' => 2700, # 1/8
+ 'wd10' => 2160, # 1/10
+ 'wd12' => 1800, # 1/12
+ 'wd32' => 675, # 1/32
+
+ 'hd2' => 10800, # 1/2
+ 'hd3' => 7200, # 1/3
+ 'hd4' => 5400, # 1/4
+ 'hd5' => 4320, # 1/5
+ 'hd6' => 3600, # 1/6
+ 'hd8' => 2700, # 1/8
+ 'hd10' => 2160, # 1/10
+ 'hd12' => 1800, # 1/12
+ 'hd32' => 675, # 1/32
+
+ '25000' => 5400,
+ '12500' => 2700,
+
+ 'cd4' => 90, # 1/4 of a circle
+ 'cd2' => 180, # 1/2 of a circle
+ '3cd4' => 270, # 3/4 of a circle
+
+ 'cd8' => 45, # 1/8 of a circle
+ '3cd8' => 135, # 3/8 of a circle
+ '5cd8' => 225, # 5/8 of a circle
+ '7cd8' => 315, # 7/8 of a circle
+
+ '-5400000' => -90,
+ '-10800000'=> -180,
+ '-16200000'=> -270,
+ '-21600000'=> -360,
+ '-21599999'=> -360,
+
+ '5400000' => 90,
+ '10800000' => 180,
+ '16200000' => 270,
+ '21600000' => 360,
+ '21599999' => 360
+#
+# '21600000' => 360, # angle conversions
+# '27000000' => 450,
+# '32400000' => 540,
+# '37800000' => 630
+ );
+}
+
+# Convert the (predefiend) value to a number
+sub value( $ )
+{
+ my ( $val ) = @_;
+
+ my $result = $variables{$val};
+ return $result if ( defined( $result ) );
+
+ return $val if ( $val =~ /^[0-9-]+$/ );
+
+ error( "Unknown variable '$val'." );
+
+ show_call_stack();
+ return $val;
+}
+
+# Convert the DrawingML formula to a VML one
+%command_variables = (
+ 'w' => 'width',
+ 'h' => 'height',
+ 'r' => 'width',
+ 'b' => 'height'
+);
+
+# The same as value(), but some of the hardcoded values can have a name
+sub command_value( $ )
+{
+ my ( $value ) = @_;
+
+ return "" if ( $value eq "" );
+
+ return $value if ( $value =~ /^@/ );
+
+ my $command_val = $command_variables{$value};
+ if ( defined( $command_val ) ) {
+ return $command_val;
+ }
+
+ return value( $value );
+}
+
+# Insert the new formula to the list of formulas
+# Creates the name if it's empty...
+sub insert_formula( $$ )
+{
+ my ( $name, $fmla ) = @_;
+
+ my $i = 0;
+ foreach $f ( @formulas ) {
+ if ( $f eq $fmla ) {
+ if ( $name ne "" ) {
+ $variables{$name} = "@" . $i;
+ }
+ return "@" . $i;
+ }
+ ++$i;
+ }
+
+ if ( $name eq "" ) {
+ $name = "@" . ( $#formulas + 1 );
+ }
+
+ $variables{$name} = "@" . ( $#formulas + 1 );
+ push @formulas, $fmla;
+
+ if ( $#formulas > 127 ) {
+ error( "Reached the maximum amount of formulas, have to ignore the shape '$shape_name'" );
+ }
+
+ return $variables{$name};
+}
+
+# The same as insert_formula(), but converts the params
+sub insert_formula_params( $$$$$ )
+{
+ my ( $name, $command, $p1, $p2, $p3 ) = @_;
+
+ my $result = $command;
+ if ( $p1 ne "" ) {
+ $result .= " " . command_value( $p1 );
+ if ( $p2 ne "" ) {
+ $result .= " " . command_value( $p2 );
+ if ( $p3 ne "" ) {
+ $result .= " " . command_value( $p3 );
+ }
+ }
+ }
+
+ return insert_formula( $name, $result );
+}
+
+# Convert the formula from DrawingML to VML
+sub convert_formula( $$ )
+{
+ my ( $name, $fmla ) = @_;
+
+ if ( $fmla =~ /^([^ ]+)/ ) {
+ my $command = $1;
+
+ # parse the parameters
+ ( my $values = $fmla ) =~ s/^([^ ]+) *//;
+ my $p1 = "", $p2 = "", $p3 = "";
+ if ( $values =~ /^([^ ]+)/ ) {
+ $p1 = $1;
+ $values =~ s/^([^ ]+) *//;
+ if ( $values =~ /^([^ ]+)/ ) {
+ $p2 = $1;
+ $values =~ s/^([^ ]+) *//;
+ if ( $values =~ /^([^ ]+)/ ) {
+ $p3 = $1;
+ }
+ }
+ }
+
+ # now convert the formula
+ if ( $command eq "+-" ) {
+ if ( $p1 eq "100000" ) {
+ $p1 = value( 'w' );
+ }
+ insert_formula_params( $name, "sum", $p1, $p2, $p3 );
+ return;
+ }
+ elsif ( $command eq "*/" ) {
+ if ( ( $p2 =~ /^(w|h|ss|hd2|wd2|vc)$/ ) && defined( $variables{$p1} ) ) {
+ # switch it ;-) - presetTextWarpDefinitions.xml has it in other order
+ my $tmp = $p1;
+ $p1 = $p2;
+ $p2 = $tmp;
+ }
+
+ if ( ( $p1 =~ /^(w|h|ss|hd2|wd2|vc)$/ ) && defined( $variables{$p2} ) ) {
+ my $val3 = $p3;
+ if ( $val3 =~ /^[0-9-]+$/ ) {
+ $val3 *= ( value( 'w' ) / value( $p1 ) );
+
+ # Oh yes, I'm too lazy to implement the full GCD here ;-)
+ if ( ( $val3 % 100000 ) == 0 ) {
+ $p1 = 1;
+ $p3 = sprintf( "%.0f", ( $val3 / 100000 ) );
+ }
+ elsif ( $val3 < 100000 ) {
+ $p3 = 1;
+ while ( ( ( $p3 * 100000 ) % $val3 ) != 0 ) {
+ ++$p3
+ }
+ $p1 = ( $p3 * 100000 ) / $val3;
+ }
+ else {
+ error( "Need to count the greatest common divisor." );
+ }
+ }
+ }
+ elsif ( $p3 eq "100000" && $p2 =~ /^[0-9-]+$/ ) {
+ # prevent overflows in some shapes
+ $p2 = sprintf( "%.0f", ( $p2 / 10 ) );
+ $p3 /= 10;
+ }
+ elsif ( $p3 eq "32768" && $p2 =~ /^[0-9-]+$/ ) {
+ # prevent overflows in some shapes
+ $p2 = sprintf( "%.0f", ( $p2 / 8 ) );
+ $p3 /= 8;
+ }
+ elsif ( $p3 eq "50000" ) {
+ $p3 = 10800;
+ }
+ elsif ( $name =~ /^maxAdj/ ) {
+ my $val = value( $p1 );
+ if ( $val =~ /^[0-9-]+$/ ) {
+ $p1 = sprintf( "%.0f", ( value( 'w' ) * $val / 100000 ) );
+ }
+ }
+
+ if ( ( value( $p1 ) eq value( $p3 ) ) || ( value( $p2 ) eq value( $p3 ) ) ) {
+ my $val = value( ( value( $p1 ) eq value( $p3 ) )? $p2: $p1 );
+ if ( $val =~ /^@([0-9]+)$/ ) {
+ insert_formula( $name, $formulas[$1] );
+ }
+ else {
+ insert_formula( $name, "val $val" );
+ }
+ }
+ else {
+ insert_formula_params( $name, "prod", $p1, $p2, $p3 );
+ }
+ return;
+ }
+ elsif ( $command eq "+/" ) {
+ # we have to split this into 2 formulas - 'sum' and 'prod'
+ my $constructed = insert_formula_params( "", "sum", $p1, $p2, "0" );
+ insert_formula_params( $name, "prod", 1, $constructed, $p3); # references the 'sum' formula
+ return;
+ }
+ elsif ( $command eq "?:" ) {
+ insert_formula_params( $name, "if", $p1, $p2, $p3 );
+ return;
+ }
+ elsif ( $command eq "sin" || $command eq "cos" ) {
+ if ( $p2 =~ /^[0-9-]+$/ && ( ( $p2 % 60000 ) == 0 ) ) {
+ $p2 /= 60000;
+ }
+ else {
+ $p2 = insert_formula_params( "", "prod", "1", $p2, "60000" );
+ }
+ # we have to use 'sumangle' even for the case when $p2 is const
+ # and theoretically could be written as such; but Word does not
+ # accept it :-(
+ my $conv = insert_formula_params( "", "sumangle", "0", $p2, "0" );
+
+ $p2 = $conv;
+
+ insert_formula_params( $name, $command, $p1, $p2, "" );
+ return;
+ }
+ elsif ( $command eq "abs" ) {
+ insert_formula_params( $name, $command, $p1, "", "" );
+ return;
+ }
+ elsif ( $command eq "max" || $command eq "min" ) {
+ insert_formula_params( $name, $command, $p1, $p2, "" );
+ return;
+ }
+ elsif ( $command eq "at2" ) {
+ insert_formula_params( $name, "atan2", $p1, $p2, "" );
+ return;
+ }
+ elsif ( $command eq "cat2" ) {
+ insert_formula_params( $name, "cosatan2", $p1, $p2, $p3 );
+ return;
+ }
+ elsif ( $command eq "sat2" ) {
+ insert_formula_params( $name, "sinatan2", $p1, $p2, $p3 );
+ return;
+ }
+ elsif ( $command eq "sqrt" ) {
+ insert_formula_params( $name, "sqrt", $p1, "", "" );
+ return;
+ }
+ elsif ( $command eq "mod" ) {
+ insert_formula_params( $name, "mod", $p1, $p2, $p3 );
+ return;
+ }
+ elsif ( $command eq "val" ) {
+ insert_formula_params( $name, "val", value( $p1 ), "", "" );
+ return;
+ }
+ else {
+ error( "Unknown formula '$name', '$fmla'." );
+ }
+ }
+ else {
+ error( "Cannot convert formula's command '$name', '$fmla'." );
+ }
+}
+
+# There's no exact equivalent of 'arcTo' in VML, we have to do some special casing...
+%convert_arcTo = (
+ '0' => {
+ '90' => {
+ 'path' => 'qy',
+ 'op' => [ 'sum 0 __last_x__ __wR__', 'sum __hR__ __last_y__ 0' ],
+ },
+ '-90' => {
+ 'path' => 'qy',
+ 'op' => [ 'sum 0 __last_x__ __wR__', 'sum 0 __last_y__ __hR__' ],
+ },
+ },
+ '90' => {
+ '90' => {
+ 'path' => 'qx',
+ 'op' => [ 'sum 0 __last_x__ __wR__', 'sum 0 __last_y__ __hR__' ],
+ },
+ '-90' => {
+ 'path' => 'qx',
+ 'op' => [ 'sum __wR__ __last_x__ 0', 'sum 0 __last_y__ __hR__' ],
+ },
+ },
+ '180' => {
+ '90' => {
+ 'path' => 'qy',
+ 'op' => [ 'sum __wR__ __last_x__ 0', 'sum 0 __last_y__ __hR__' ],
+ },
+ '-90' => {
+ 'path' => 'qy',
+ 'op' => [ 'sum __wR__ __last_x__ 0', 'sum __hR__ __last_y__ 0' ],
+ },
+ },
+ '270' => {
+ '90' => {
+ 'path' => 'qx',
+ 'op' => [ 'sum __wR__ __last_x__ 0', 'sum __hR__ __last_y__ 0' ],
+ },
+ '-90' => {
+ 'path' => 'qx',
+ 'op' => [ 'sum 0 __last_x__ __wR__', 'sum __hR__ __last_y__ 0' ],
+ },
+ },
+);
+
+# Elliptic quadrant
+# FIXME optimize so that we compute the const values when possible
+sub elliptic_quadrant( $$$$ )
+{
+ my ( $wR, $hR, $stAng, $swAng ) = @_;
+
+ if ( defined( $convert_arcTo{$stAng} ) && defined( $convert_arcTo{$stAng}{$swAng} ) ) {
+ my $conv_path = $convert_arcTo{$stAng}{$swAng}{'path'};
+ my $conv_op_ref = $convert_arcTo{$stAng}{$swAng}{'op'};
+
+ $path .= "$conv_path";
+
+ my $pos_x = $last_pos_x;
+ my $pos_y = $last_pos_y;
+ for ( my $i = 0; $i <= $#{$conv_op_ref}; ++$i ) {
+ my $op = $conv_op_ref->[$i];
+
+ $op =~ s/__last_x__/$last_pos_x/g;
+ $op =~ s/__last_y__/$last_pos_y/g;
+ $op =~ s/__wR__/$wR/g;
+ $op =~ s/__hR__/$hR/g;
+
+ my $fmla = insert_formula( "", $op );
+
+ $path .= $fmla;
+
+ # so far it's sufficient just to rotate the positions
+ # FIXME if not ;-)
+ $pos_x = $pos_y;
+ $pos_y = $fmla;
+ }
+ $last_pos_x = $pos_x;
+ $last_pos_y = $pos_y;
+ }
+ else {
+ error( "Unhandled elliptic_quadrant(), input is ($wR, $hR, $stAng, $swAng)." );
+ }
+}
+
+# Convert the quadratic bezier to cubic (exact)
+# No idea why, but the 'qb' did not work for me :-(
+sub quadratic_to_cubic_bezier( $ )
+{
+ my ( $axis ) = @_;
+
+ my $a0 = $quadratic_bezier[0]->{$axis};
+ my $a1 = $quadratic_bezier[1]->{$axis};
+ my $a2 = $quadratic_bezier[2]->{$axis};
+
+ my $b0 = $a0;
+
+ # $b1 = $a0 + 2/3 * ( $a1 - $a0 ), but in VML
+ # FIXME optimize for constants - compute directly
+ my $b1_1 = insert_formula_params( "", "sum", "0", $a1, $a0 );
+ my $b1_2 = insert_formula_params( "", "prod", "2", $b1_1, "3" );
+ my $b1 = insert_formula_params( "", "sum", $a0, $b1_2, "0" );
+
+ # $b2 = $b1 + 1/3 * ( $a2 - $a0 );
+ # FIXME optimize for constants - compute directly
+ my $b2_1 = insert_formula_params( "", "sum", "0", $a2, $a0 );
+ my $b2_2 = insert_formula_params( "", "prod", "1", $b2_1, "3" );
+ my $b2 = insert_formula_params( "", "sum", $b1, $b2_2, "0" );
+
+ my $b3 = $a2;
+
+ return ( $b0, $b1, $b2, $b3 );
+}
+
+# Extend $path by one more point
+sub add_point_to_path( $$ )
+{
+ my ( $x, $y ) = @_;
+
+ if ( $path =~ /[0-9]$/ && $x =~ /^[0-9-]/ ) {
+ $path .= ",";
+ }
+ $path .= $x;
+
+ if ( $path =~ /[0-9]$/ && $y =~ /^[0-9-]/ ) {
+ $path .= ",";
+ }
+ $path .= $y;
+}
+
+# Start of an element
+sub start_element( $% )
+{
+ my ( $element, %attr ) = @_;
+
+ push @levels, $element;
+
+ #print "element: $element\n";
+
+ if ( is_level( -1, "presetShapeDefinitons" ) || is_level( -1, "presetTextWarpDefinitions" ) ) {
+ $shape_name = $element;
+
+ $state = "";
+ $ignore_this_shape = 0;
+ $path = "";
+ $adjust = "";
+ $max_adj_no = 0;
+ @formulas = ();
+ $handles = "";
+ $textboxrect = "";
+ $last_pos_x = "";
+ $last_pos_y = "";
+ $no_stroke = 0;
+ $no_fill = 0;
+ @quadratic_bezier = ();
+
+ setup_variables();
+
+ if ( $shape_name eq "sun" ) {
+ # hack for this shape
+ $variables{'100000'} = "21600";
+ $variables{'50000'} = "10800";
+ $variables{'25000'} = "5400";
+ $variables{'12500'} = "2700";
+ $variables{'3662'} = "791";
+ }
+
+ my $found = 0;
+ foreach my $name ( values( %shapes_ids ) ) {
+ if ( $name eq $shape_name ) {
+ $found = 1;
+ last;
+ }
+ }
+ if ( !$found ) {
+ error( "Unknown shape '$shape_name'." );
+ }
+ }
+ elsif ( $element eq "pathLst" ) {
+ $state = "path";
+ }
+ elsif ( $element eq "avLst" ) {
+ $state = "adjust";
+ }
+ elsif ( $element eq "gdLst" ) {
+ $state = "formulas";
+ }
+ elsif ( $element eq "ahLst" ) {
+ $state = "handles";
+ }
+ elsif ( $element eq "rect" ) {
+ $textboxrect = value( $attr{'l'} ) . "," . value( $attr{'t'} ) . "," .
+ value( $attr{'r'} ) . "," . value( $attr{'b'} );
+ }
+ elsif ( $state eq "path" ) {
+ if ( $element eq "path" ) {
+ $no_stroke = ( defined( $attr{'stroke'} ) && $attr{'stroke'} eq 'false' );
+ $no_fill = ( defined( $attr{'fill'} ) && $attr{'fill'} eq 'none' );
+ $path_w = $attr{'w'};
+ $path_h = $attr{'h'};
+ }
+ elsif ( $element eq "moveTo" ) {
+ $path .= "m";
+ }
+ elsif ( $element eq "lnTo" ) {
+ $path .= "l";
+ }
+ elsif ( $element eq "cubicBezTo" ) {
+ $path .= "c";
+ }
+ elsif ( $element eq "quadBezTo" ) {
+ my %points = ( 'x' => $last_pos_x, 'y' => $last_pos_y );
+ @quadratic_bezier = ( \%points );
+ }
+ elsif ( $element eq "close" ) {
+ $path .= "x";
+ }
+ elsif ( $element eq "pt" ) {
+ # rememeber the last position for the arcTo
+ $last_pos_x = value( $attr{'x'} );
+ $last_pos_y = value( $attr{'y'} );
+
+ $last_pos_x *= ( value( 'w' ) / $path_w ) if ( defined( $path_w ) );
+ $last_pos_y *= ( value( 'h' ) / $path_h ) if ( defined( $path_h ) );
+
+ if ( $#quadratic_bezier >= 0 ) {
+ my %points = ( 'x' => $last_pos_x, 'y' => $last_pos_y );
+ push( @quadratic_bezier, \%points );
+ }
+ else {
+ add_point_to_path( $last_pos_x, $last_pos_y );
+ }
+ }
+ elsif ( ( $element eq "arcTo" ) && ( $last_pos_x ne "" ) && ( $last_pos_y ne "" ) ) {
+ # there's no exact equivalent of arcTo in VML, so we have to
+ # compute here a bit...
+ my $stAng = value( $attr{'stAng'} );
+ my $swAng = value( $attr{'swAng'} );
+ my $wR = value( $attr{'wR'} );
+ my $hR = value( $attr{'hR'} );
+
+ $wR *= ( value( 'w' ) / $path_w ) if ( defined( $path_w ) );
+ $hR *= ( value( 'h' ) / $path_h ) if ( defined( $path_h ) );
+
+ if ( ( $stAng =~ /^[0-9-]+$/ ) && ( $swAng =~ /^[0-9-]+$/ ) ) {
+ if ( ( ( $stAng % 90 ) == 0 ) && ( ( $swAng % 90 ) == 0 ) && ( $swAng != 0 ) ) {
+ my $end = $stAng + $swAng;
+ my $step = ( $swAng > 0 )? 90: -90;
+
+ for ( my $cur = $stAng; $cur != $end; $cur += $step ) {
+ elliptic_quadrant( $wR, $hR, ( $cur % 360 ), $step );
+ }
+ }
+ else {
+ error( "Unsupported numeric 'arcTo' ($attr{'wR'}, $attr{'hR'}, $stAng, $swAng)." );
+ }
+ }
+ else {
+ error( "Unsupported 'arcTo' conversion ($attr{'wR'}, $attr{'hR'}, $stAng, $swAng)." );
+ }
+ }
+ else {
+ error( "Unhandled path element '$element'." );
+ }
+ }
+ elsif ( $state eq "adjust" ) {
+ if ( $element eq "gd" ) {
+ my $adj_no = $attr{'name'};
+ my $is_const = 0;
+
+ $adj_no =~ s/^adj//;
+ if ( $adj_no eq "" ) {
+ $max_adj_no = 0;
+ }
+ elsif ( !( $adj_no =~ /^[0-9]*$/ ) ) {
+ ++$max_adj_no;
+ $is_const = 1;
+ }
+ elsif ( $adj_no != $max_adj_no + 1 ) {
+ error( "Wrong order of adj values." );
+ ++$max_adj_no;
+ }
+ else {
+ $max_adj_no = $adj_no;
+ }
+
+ if ( $attr{'fmla'} =~ /^val ([0-9-]*)$/ ) {
+ my $val = sprintf( "%.0f", ( 21600 * $1 ) / 100000 );
+ if ( $is_const ) {
+ $variables{$adj_no} = $val;
+ }
+ elsif ( $adjust eq "" ) {
+ $adjust = $val;
+ }
+ else {
+ $adjust = "$val,$adjust";
+ }
+ }
+ else {
+ error( "Wrong fmla '$attr{'fmla'}'." );
+ }
+ }
+ else {
+ error( "Unhandled adjust element '$element'." );
+ }
+ }
+ elsif ( $state eq "formulas" ) {
+ if ( $element eq "gd" ) {
+ if ( $attr{'fmla'} =~ /^\*\/ (h|w|ss) adj([0-9]+) 100000$/ ) {
+ insert_formula( $attr{'name'}, "val #" . ( $max_adj_no - $2 ) );
+ }
+ elsif ( $attr{'fmla'} =~ /^pin [^ ]+ ([^ ]+) / ) {
+ print STDERR "TODO Map 'pin' to VML as xrange for handles.\n";
+ my $pin_val = $1;
+ if ( $pin_val eq "adj" ) {
+ insert_formula( $attr{'name'}, "val #0" );
+ }
+ elsif ( $pin_val =~ /^adj([0-9]+)/ ) {
+ insert_formula( $attr{'name'}, "val #" . ( $max_adj_no - $1 ) );
+ }
+ else {
+ insert_formula( $attr{'name'}, "val " . value( $pin_val ) );
+ }
+ }
+ elsif ( $attr{'fmla'} =~ /adj/ ) {
+ error( "Non-standard usage of adj in '$attr{'fmla'}'." );
+ }
+ else {
+ convert_formula( $attr{'name'}, $attr{'fmla'} );
+ }
+ }
+ }
+ elsif ( $state eq "handles" ) {
+ if ( $element eq "pos" ) {
+ $handles .= "<v:h position=\"" . value( $attr{'x'} ) . "," . value( $attr{'y'} ) . "\"/>\n";
+ }
+ }
+}
+
+# End of an element
+sub end_element( $ )
+{
+ my ( $element ) = @_;
+
+ pop @levels;
+
+ if ( $element eq $shape_name ) {
+ if ( !$ignore_this_shape ) {
+ # we have all the info, generate the shape now
+ $state = "";
+
+ # shape path
+ my $out = "<v:shapetype id=\"shapetype___ID__\" coordsize=\"21600,21600\" o:spt=\"__ID__\" ";
+ if ( $adjust ne "" ) {
+ $out .= "adj=\"$adjust\" ";
+ }
+
+ # optimize it [yes, we need this twice ;-)]
+ $path =~ s/([^0-9-@])0([^0-9-@])/$1$2/g;
+ $path =~ s/([^0-9-@])0([^0-9-@])/$1$2/g;
+
+ $out .= "path=\"$path\">\n";
+
+ # stroke
+ $out .= "<v:stroke joinstyle=\"miter\"/>\n";
+
+ # formulas
+ if ( $#formulas >= 0 )
+ {
+ $out .= "<v:formulas>\n";
+ foreach $fmla ( @formulas ) {
+ $out .= "<v:f eqn=\"$fmla\"/>\n"
+ }
+ $out .= "</v:formulas>\n";
+ }
+
+ # path
+ if ( $textboxrect ne "" ) { # TODO connectlocs, connectangles
+ $out .= "<v:path gradientshapeok=\"t\" o:connecttype=\"rect\" textboxrect=\"$textboxrect\"/>\n";
+ }
+
+ # handles
+ if ( $handles ne "" ) {
+ $out .= "<v:handles>\n$handles</v:handles>\n";
+ }
+
+ $out .="</v:shapetype>";
+
+ # hooray! :-)
+ $result_shapes{$shape_name} = $out;
+ }
+ else {
+ print STDERR "Shape '$shape_name' ignored; see the above error(s) for the reason.\n";
+ }
+ $shape_name = "";
+ }
+ elsif ( $state eq "path" ) {
+ if ( $element eq "path" ) {
+ $path .= "ns" if ( $no_stroke );
+ $path .= "nf" if ( $no_fill );
+ $path .= "e";
+ }
+ elsif ( $element eq "quadBezTo" ) {
+ # we have to convert the quadratic bezier to cubic
+ if ( $#quadratic_bezier == 2 ) {
+ my @points_x = quadratic_to_cubic_bezier( 'x' );
+ my @points_y = quadratic_to_cubic_bezier( 'y' );
+
+ $path .= "c";
+ # ignore the starting point
+ for ( my $i = 1; $i < 4; ++$i ) {
+ add_point_to_path( $points_x[$i], $points_y[$i] );
+ }
+ }
+ else {
+ error( "Wrong number of points of the quadratic bezier." );
+ }
+ @quadratic_bezier = ();
+ }
+ }
+ elsif ( $element eq "avLst" ) {
+ $state = "";
+ }
+ elsif ( $element eq "gdLst" ) {
+ $state = "";
+ }
+ elsif ( $element eq "ahLst" ) {
+ $state = "";
+ }
+}
+
+# Text inside an element
+sub characters( $ )
+{
+ #my ( $text ) = @_;
+}
+
+#################### A trivial XML parser ####################
+
+# Parse the attributes
+sub parse_start_element( $ )
+{
+ # split the string containing both the elements and attributes
+ my ( $element_tmp ) = @_;
+
+ $element_tmp =~ s/\s*$//;
+ $element_tmp =~ s/^\s*//;
+
+ ( my $element = $element_tmp ) =~ s/\s.*$//;
+ if ( $element_tmp =~ /\s/ ) {
+ $element_tmp =~ s/^[^\s]*\s//;
+ }
+ else {
+ $element_tmp = "";
+ }
+
+ # we have the element, now the attributes
+ my %attr;
+ my $is_key = 1;
+ my $key = "";
+ foreach my $tmp ( split( /"/, $element_tmp ) ) {
+ if ( $is_key ) {
+ $key = $tmp;
+ $key =~ s/^\s*//;
+ $key =~ s/\s*=\s*$//;
+ }
+ else {
+ $attr{$key} = $tmp;
+ }
+ $is_key = !$is_key;
+ }
+
+ if ( $element ne "" ) {
+ start_element( $element, %attr );
+ }
+}
+
+# Parse the file
+sub parse( $ )
+{
+ my ( $file ) = @_;
+
+ my $in_comment = 0;
+ my $line = "";
+ while (<$file>) {
+ # ignore comments
+ s/<\?[^>]*\?>//g;
+ s/<!--[^>]*-->//g;
+ if ( /<!--/ ) {
+ $in_comment = 1;
+ s/<!--.*//;
+ }
+ elsif ( /-->/ && $in_comment ) {
+ $in_comment = 0;
+ s/.*-->//;
+ }
+ elsif ( $in_comment ) {
+ next;
+ }
+ # ignore empty lines
+ chomp;
+ s/^\s*//;
+ s/\s*$//;
+ next if ( $_ eq "" );
+
+ # take care of lines where element continues
+ if ( $line ne "" ) {
+ $line .= " " . $_;
+ }
+ else {
+ $line = $_;
+ }
+ next if ( !/>$/ );
+
+ # the actual parsing
+ my @starts = split( /</, $line );
+ $line = "";
+ foreach $start ( @starts ) {
+ next if ( $start eq "" );
+
+ @ends = split( />/, $start );
+ my $element = $ends[0];
+ my $data = $ends[1];
+
+ # start or end element
+ if ( $element =~ /^\/(.*)/ ) {
+ end_element( $1 );
+ }
+ elsif ( $element =~ /^(.*)\/$/ ) {
+ parse_start_element( $1 );
+ ( my $end = $1 ) =~ s/\s.*$//;
+ end_element( $end );
+ }
+ else {
+ parse_start_element( $element );
+ }
+
+ # the data
+ characters( $data ) if ( defined( $data ) && $data ne "" );
+ }
+ }
+}
+
+# Do the real work
+open( IN, "<$src_shapes" ) || die "Cannot open $src_shapes.";
+parse( IN );
+close( IN );
+
+open( IN, "<$src_text" ) || die "Cannot open $src_text.";
+parse( IN );
+close( IN );
+
+if ( !defined( $result_shapes{'textBox'} ) ) {
+ $result_shapes{'textBox'} =
+ "<v:shapetype id=\"shapetype___ID__\" coordsize=\"21600,21600\" " .
+ "o:spt=\"__ID__\" path=\"m,l,21600l21600,21600l21600,xe\">\n" .
+ "<v:stroke joinstyle=\"miter\"/>\n" .
+ "<v:path gradientshapeok=\"t\" o:connecttype=\"rect\"/>\n" .
+ "</v:shapetype>";
+}
+
+# Generate the code
+print <<EOF;
+// Shape types generated from
+// '$src_shapes'
+// and
+// '$src_text'
+// which are part of the OOXML documentation
+
+#include <svx/escherex.hxx>
+
+const char* pShapeTypes[ ESCHER_ShpInst_COUNT ] =
+{
+EOF
+
+for ( $i = 0; $i < 203; ++$i ) {
+ if ( $i < 4 ) {
+ print " /* $i - $shapes_ids{$i} - handled separately */\n NULL,\n";
+ }
+ else {
+ print " /* $i - $shapes_ids{$i} */\n";
+ my $out = $result_shapes{$shapes_ids{$i}};
+ if ( defined( $out ) ) {
+ # set the id
+ $out =~ s/__ID__/$i/g;
+
+ # escape the '"'s
+ $out =~ s/"/\\"/g;
+
+ # output as string
+ $out =~ s/^/ "/;
+ $out =~ s/\n/"\n "/g;
+ $out =~ s/$/"/;
+
+ print "$out,\n";
+ }
+ else {
+ print " NULL,\n";
+ }
+ }
+}
+
+print <<EOF;
+};
+EOF
diff --git a/oox/source/export/presetShapeDefinitions.xml b/oox/source/export/presetShapeDefinitions.xml
new file mode 100644
index 000000000000..77612e2b1652
--- /dev/null
+++ b/oox/source/export/presetShapeDefinitions.xml
@@ -0,0 +1,19915 @@
+<?xml version="1.0" encoding="utf-8"?>
+<presetShapeDefinitons>
+ <accentBorderCallout1>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 112500" />
+
+ <gd name="adj4" fmla="val -38333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <close />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </accentBorderCallout1>
+ <accentBorderCallout2>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 112500" />
+
+ <gd name="adj6" fmla="val -46667" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <close />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </accentBorderCallout2>
+ <accentBorderCallout3>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 100000" />
+
+ <gd name="adj6" fmla="val -16667" />
+
+ <gd name="adj7" fmla="val 112963" />
+
+ <gd name="adj8" fmla="val -8333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ <gd name="y4" fmla="*/ h adj7 100000" />
+ <gd name="x4" fmla="*/ w adj8 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ <ahXY gdRefX="adj8" minX="-2147483647" maxX="2147483647" gdRefY="adj7" minY="-2147483647" maxY="2147483647">
+ <pos x="x4" y="y4" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <close />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </accentBorderCallout3>
+ <accentCallout1>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 112500" />
+
+ <gd name="adj4" fmla="val -38333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <close />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </accentCallout1>
+ <accentCallout2>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 112500" />
+
+ <gd name="adj6" fmla="val -46667" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <close />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </accentCallout2>
+ <accentCallout3>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 100000" />
+
+ <gd name="adj6" fmla="val -16667" />
+
+ <gd name="adj7" fmla="val 112963" />
+
+ <gd name="adj8" fmla="val -8333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ <gd name="y4" fmla="*/ h adj7 100000" />
+ <gd name="x4" fmla="*/ w adj8 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ <ahXY gdRefX="adj8" minX="-2147483647" maxX="2147483647" gdRefY="adj7" minY="-2147483647" maxY="2147483647">
+ <pos x="x4" y="y4" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <close />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </accentCallout3>
+ <actionButtonBackPrevious>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ </gdLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g11" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g11" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g11" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </actionButtonBackPrevious>
+ <actionButtonBeginning>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 1 8" />
+ <gd name="g15" fmla="*/ g13 1 4" />
+ <gd name="g16" fmla="+- g11 g14 0" />
+ <gd name="g17" fmla="+- g11 g15 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g17" y="vc" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g16" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g16" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g17" y="vc" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g16" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g16" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g17" y="vc" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g16" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g16" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonBeginning>
+ <actionButtonBlank>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonBlank>
+ <actionButtonDocument>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="dx1" fmla="*/ ss 9 32" />
+ <gd name="g11" fmla="+- hc 0 dx1" />
+ <gd name="g12" fmla="+- hc dx1 0" />
+ <gd name="g13" fmla="*/ ss 3 16" />
+ <gd name="g14" fmla="+- g12 0 g13" />
+ <gd name="g15" fmla="+- g9 g13 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g11" y="g9" />
+ </moveTo>
+ <lnTo>
+ <pt x="g14" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g15" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="g11" y="g9" />
+ </moveTo>
+ <lnTo>
+ <pt x="g14" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g14" y="g15" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g15" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g14" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g14" y="g15" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g15" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g11" y="g9" />
+ </moveTo>
+ <lnTo>
+ <pt x="g14" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g15" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g12" y="g15" />
+ </moveTo>
+ <lnTo>
+ <pt x="g14" y="g15" />
+ </lnTo>
+ <lnTo>
+ <pt x="g14" y="g9" />
+ </lnTo>
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonDocument>
+ <actionButtonEnd>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 3 4" />
+ <gd name="g15" fmla="*/ g13 7 8" />
+ <gd name="g16" fmla="+- g11 g14 0" />
+ <gd name="g17" fmla="+- g11 g15 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g16" y="vc" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g17" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g17" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g16" y="vc" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g17" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g17" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g16" y="vc" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g17" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g12" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g17" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonEnd>
+ <actionButtonForwardNext>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ </gdLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g12" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g12" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g12" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g11" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g9" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </actionButtonForwardNext>
+ <actionButtonHelp>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 1 7" />
+ <gd name="g15" fmla="*/ g13 3 14" />
+ <gd name="g16" fmla="*/ g13 2 7" />
+ <gd name="g19" fmla="*/ g13 3 7" />
+ <gd name="g20" fmla="*/ g13 4 7" />
+ <gd name="g21" fmla="*/ g13 17 28" />
+ <gd name="g23" fmla="*/ g13 21 28" />
+ <gd name="g24" fmla="*/ g13 11 14" />
+ <gd name="g27" fmla="+- g9 g16 0" />
+ <gd name="g29" fmla="+- g9 g21 0" />
+ <gd name="g30" fmla="+- g9 g23 0" />
+ <gd name="g31" fmla="+- g9 g24 0" />
+ <gd name="g33" fmla="+- g11 g15 0" />
+ <gd name="g36" fmla="+- g11 g19 0" />
+ <gd name="g37" fmla="+- g11 g20 0" />
+ <gd name="g41" fmla="*/ g13 1 14" />
+ <gd name="g42" fmla="*/ g13 3 28" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g33" y="g27" />
+ </moveTo>
+
+ <arcTo wR="g16" hR="g16" stAng="cd2" swAng="cd2" />
+ <arcTo wR="g14" hR="g15" stAng="0" swAng="cd4" />
+ <arcTo wR="g41" hR="g42" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="g37" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g29" />
+ </lnTo>
+ <arcTo wR="g14" hR="g15" stAng="cd2" swAng="cd4" />
+ <arcTo wR="g41" hR="g42" stAng="cd4" swAng="-5400000" />
+ <arcTo wR="g14" hR="g14" stAng="0" swAng="-10800000" />
+ <close />
+ <moveTo>
+ <pt x="hc" y="g31" />
+ </moveTo>
+
+ <arcTo wR="g42" hR="g42" stAng="3cd4" swAng="21600000" />
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g33" y="g27" />
+ </moveTo>
+
+ <arcTo wR="g16" hR="g16" stAng="cd2" swAng="cd2" />
+ <arcTo wR="g14" hR="g15" stAng="0" swAng="cd4" />
+ <arcTo wR="g41" hR="g42" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="g37" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g29" />
+ </lnTo>
+ <arcTo wR="g14" hR="g15" stAng="cd2" swAng="cd4" />
+ <arcTo wR="g41" hR="g42" stAng="cd4" swAng="-5400000" />
+ <arcTo wR="g14" hR="g14" stAng="0" swAng="-10800000" />
+ <close />
+ <moveTo>
+ <pt x="hc" y="g31" />
+ </moveTo>
+
+ <arcTo wR="g42" hR="g42" stAng="3cd4" swAng="21600000" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g33" y="g27" />
+ </moveTo>
+
+ <arcTo wR="g16" hR="g16" stAng="cd2" swAng="cd2" />
+ <arcTo wR="g14" hR="g15" stAng="0" swAng="cd4" />
+ <arcTo wR="g41" hR="g42" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="g37" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g29" />
+ </lnTo>
+ <arcTo wR="g14" hR="g15" stAng="cd2" swAng="cd4" />
+ <arcTo wR="g41" hR="g42" stAng="cd4" swAng="-5400000" />
+ <arcTo wR="g14" hR="g14" stAng="0" swAng="-10800000" />
+ <close />
+ <moveTo>
+ <pt x="hc" y="g31" />
+ </moveTo>
+
+ <arcTo wR="g42" hR="g42" stAng="3cd4" swAng="21600000" />
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonHelp>
+ <actionButtonHome>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 1 16" />
+ <gd name="g15" fmla="*/ g13 1 8" />
+ <gd name="g16" fmla="*/ g13 3 16" />
+ <gd name="g17" fmla="*/ g13 5 16" />
+ <gd name="g18" fmla="*/ g13 7 16" />
+ <gd name="g19" fmla="*/ g13 9 16" />
+ <gd name="g20" fmla="*/ g13 11 16" />
+ <gd name="g21" fmla="*/ g13 3 4" />
+ <gd name="g22" fmla="*/ g13 13 16" />
+ <gd name="g23" fmla="*/ g13 7 8" />
+ <gd name="g24" fmla="+- g9 g14 0" />
+ <gd name="g25" fmla="+- g9 g16 0" />
+ <gd name="g26" fmla="+- g9 g17 0" />
+ <gd name="g27" fmla="+- g9 g21 0" />
+ <gd name="g28" fmla="+- g11 g15 0" />
+ <gd name="g29" fmla="+- g11 g18 0" />
+ <gd name="g30" fmla="+- g11 g19 0" />
+ <gd name="g31" fmla="+- g11 g20 0" />
+ <gd name="g32" fmla="+- g11 g22 0" />
+ <gd name="g33" fmla="+- g11 g23 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="hc" y="g9" />
+ </moveTo>
+ <lnTo>
+ <pt x="g11" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g28" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g28" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g26" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g24" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g24" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g25" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="g32" y="g26" />
+ </moveTo>
+ <lnTo>
+ <pt x="g32" y="g24" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g24" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g25" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g28" y="vc" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g28" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g29" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g29" y="g27" />
+ </lnTo>
+ <lnTo>
+ <pt x="g30" y="g27" />
+ </lnTo>
+ <lnTo>
+ <pt x="g30" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="hc" y="g9" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="vc" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g29" y="g27" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g30" y="g27" />
+ </lnTo>
+ <lnTo>
+ <pt x="g30" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g29" y="g10" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="hc" y="g9" />
+ </moveTo>
+ <lnTo>
+ <pt x="g31" y="g25" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g24" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g24" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g26" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g28" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g28" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="vc" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g31" y="g25" />
+ </moveTo>
+ <lnTo>
+ <pt x="g32" y="g26" />
+ </lnTo>
+
+ <moveTo>
+ <pt x="g33" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g28" y="vc" />
+ </lnTo>
+
+ <moveTo>
+ <pt x="g29" y="g10" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g29" y="g27" />
+ </lnTo>
+ <lnTo>
+ <pt x="g30" y="g27" />
+ </lnTo>
+ <lnTo>
+ <pt x="g30" y="g10" />
+ </lnTo>
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonHome>
+ <actionButtonInformation>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 1 32" />
+ <gd name="g17" fmla="*/ g13 5 16" />
+ <gd name="g18" fmla="*/ g13 3 8" />
+ <gd name="g19" fmla="*/ g13 13 32" />
+ <gd name="g20" fmla="*/ g13 19 32" />
+ <gd name="g22" fmla="*/ g13 11 16" />
+ <gd name="g23" fmla="*/ g13 13 16" />
+ <gd name="g24" fmla="*/ g13 7 8" />
+ <gd name="g25" fmla="+- g9 g14 0" />
+ <gd name="g28" fmla="+- g9 g17 0" />
+ <gd name="g29" fmla="+- g9 g18 0" />
+ <gd name="g30" fmla="+- g9 g23 0" />
+ <gd name="g31" fmla="+- g9 g24 0" />
+ <gd name="g32" fmla="+- g11 g17 0" />
+ <gd name="g34" fmla="+- g11 g19 0" />
+ <gd name="g35" fmla="+- g11 g20 0" />
+ <gd name="g37" fmla="+- g11 g22 0" />
+ <gd name="g38" fmla="*/ g13 3 32" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="hc" y="g9" />
+ </moveTo>
+
+ <arcTo wR="dx2" hR="dx2" stAng="3cd4" swAng="21600000" />
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="hc" y="g9" />
+ </moveTo>
+
+ <arcTo wR="dx2" hR="dx2" stAng="3cd4" swAng="21600000" />
+ <close />
+ <moveTo>
+ <pt x="hc" y="g25" />
+ </moveTo>
+
+ <arcTo wR="g38" hR="g38" stAng="3cd4" swAng="21600000" />
+ <moveTo>
+ <pt x="g32" y="g28" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g32" y="g29" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g29" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g31" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g31" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g28" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="lighten" extrusionOk="false">
+ <moveTo>
+ <pt x="hc" y="g25" />
+ </moveTo>
+
+ <arcTo wR="g38" hR="g38" stAng="3cd4" swAng="21600000" />
+ <moveTo>
+ <pt x="g32" y="g28" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g35" y="g28" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g31" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g31" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g29" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g29" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="hc" y="g9" />
+ </moveTo>
+
+ <arcTo wR="dx2" hR="dx2" stAng="3cd4" swAng="21600000" />
+ <close />
+ <moveTo>
+ <pt x="hc" y="g25" />
+ </moveTo>
+
+ <arcTo wR="g38" hR="g38" stAng="3cd4" swAng="21600000" />
+ <moveTo>
+ <pt x="g32" y="g28" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g35" y="g28" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g31" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g31" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g30" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g29" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g29" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonInformation>
+ <actionButtonMovie>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 1455 21600" />
+ <gd name="g15" fmla="*/ g13 1905 21600" />
+ <gd name="g16" fmla="*/ g13 2325 21600" />
+ <gd name="g17" fmla="*/ g13 16155 21600" />
+ <gd name="g18" fmla="*/ g13 17010 21600" />
+ <gd name="g19" fmla="*/ g13 19335 21600" />
+ <gd name="g20" fmla="*/ g13 19725 21600" />
+ <gd name="g21" fmla="*/ g13 20595 21600" />
+ <gd name="g22" fmla="*/ g13 5280 21600" />
+ <gd name="g23" fmla="*/ g13 5730 21600" />
+ <gd name="g24" fmla="*/ g13 6630 21600" />
+ <gd name="g25" fmla="*/ g13 7492 21600" />
+ <gd name="g26" fmla="*/ g13 9067 21600" />
+ <gd name="g27" fmla="*/ g13 9555 21600" />
+ <gd name="g28" fmla="*/ g13 13342 21600" />
+ <gd name="g29" fmla="*/ g13 14580 21600" />
+ <gd name="g30" fmla="*/ g13 15592 21600" />
+ <gd name="g31" fmla="+- g11 g14 0" />
+ <gd name="g32" fmla="+- g11 g15 0" />
+ <gd name="g33" fmla="+- g11 g16 0" />
+ <gd name="g34" fmla="+- g11 g17 0" />
+ <gd name="g35" fmla="+- g11 g18 0" />
+ <gd name="g36" fmla="+- g11 g19 0" />
+ <gd name="g37" fmla="+- g11 g20 0" />
+ <gd name="g38" fmla="+- g11 g21 0" />
+ <gd name="g39" fmla="+- g9 g22 0" />
+ <gd name="g40" fmla="+- g9 g23 0" />
+ <gd name="g41" fmla="+- g9 g24 0" />
+ <gd name="g42" fmla="+- g9 g25 0" />
+ <gd name="g43" fmla="+- g9 g26 0" />
+ <gd name="g44" fmla="+- g9 g27 0" />
+ <gd name="g45" fmla="+- g9 g28 0" />
+ <gd name="g46" fmla="+- g9 g29 0" />
+ <gd name="g47" fmla="+- g9 g30 0" />
+ <gd name="g48" fmla="+- g9 g31 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g11" y="g39" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g44" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g44" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g43" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g43" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g47" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g47" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g45" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g45" />
+ </lnTo>
+ <lnTo>
+ <pt x="g38" y="g46" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g46" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g38" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g42" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g42" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g40" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g40" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g39" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g11" y="g39" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g44" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g44" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g43" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g43" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g47" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g47" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g45" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g45" />
+ </lnTo>
+ <lnTo>
+ <pt x="g38" y="g46" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g46" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g38" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g42" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g42" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g40" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g40" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g39" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g11" y="g39" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g31" y="g39" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g40" />
+ </lnTo>
+ <lnTo>
+ <pt x="g34" y="g40" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g42" />
+ </lnTo>
+ <lnTo>
+ <pt x="g37" y="g42" />
+ </lnTo>
+ <lnTo>
+ <pt x="g38" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g41" />
+ </lnTo>
+ <lnTo>
+ <pt x="g12" y="g46" />
+ </lnTo>
+ <lnTo>
+ <pt x="g38" y="g46" />
+ </lnTo>
+ <lnTo>
+ <pt x="g36" y="g45" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g45" />
+ </lnTo>
+ <lnTo>
+ <pt x="g35" y="g47" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g47" />
+ </lnTo>
+ <lnTo>
+ <pt x="g33" y="g43" />
+ </lnTo>
+ <lnTo>
+ <pt x="g32" y="g43" />
+ </lnTo>
+ <lnTo>
+ <pt x="g31" y="g44" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g44" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonMovie>
+ <actionButtonReturn>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 7 8" />
+ <gd name="g15" fmla="*/ g13 3 4" />
+ <gd name="g16" fmla="*/ g13 5 8" />
+ <gd name="g17" fmla="*/ g13 3 8" />
+ <gd name="g18" fmla="*/ g13 1 4" />
+ <gd name="g19" fmla="+- g9 g15 0" />
+ <gd name="g20" fmla="+- g9 g16 0" />
+ <gd name="g21" fmla="+- g9 g18 0" />
+ <gd name="g22" fmla="+- g11 g14 0" />
+ <gd name="g23" fmla="+- g11 g15 0" />
+ <gd name="g24" fmla="+- g11 g16 0" />
+ <gd name="g25" fmla="+- g11 g17 0" />
+ <gd name="g26" fmla="+- g11 g18 0" />
+ <gd name="g27" fmla="*/ g13 1 8" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g12" y="g21" />
+ </moveTo>
+ <lnTo>
+ <pt x="g23" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g20" />
+ </lnTo>
+ <arcTo wR="g27" hR="g27" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="g25" y="g19" />
+ </lnTo>
+ <arcTo wR="g27" hR="g27" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="g26" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g20" />
+ </lnTo>
+ <arcTo wR="g17" hR="g17" stAng="cd2" swAng="-5400000" />
+ <lnTo>
+ <pt x="hc" y="g10" />
+ </lnTo>
+ <arcTo wR="g17" hR="g17" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="g22" y="g21" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g12" y="g21" />
+ </moveTo>
+ <lnTo>
+ <pt x="g23" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g20" />
+ </lnTo>
+ <arcTo wR="g27" hR="g27" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="g25" y="g19" />
+ </lnTo>
+ <arcTo wR="g27" hR="g27" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="g26" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g20" />
+ </lnTo>
+ <arcTo wR="g17" hR="g17" stAng="cd2" swAng="-5400000" />
+ <lnTo>
+ <pt x="hc" y="g10" />
+ </lnTo>
+ <arcTo wR="g17" hR="g17" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="g22" y="g21" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g12" y="g21" />
+ </moveTo>
+ <lnTo>
+ <pt x="g22" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g22" y="g20" />
+ </lnTo>
+ <arcTo wR="g17" hR="g17" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="g25" y="g10" />
+ </lnTo>
+ <arcTo wR="g17" hR="g17" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="g11" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g26" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g26" y="g20" />
+ </lnTo>
+ <arcTo wR="g27" hR="g27" stAng="cd2" swAng="-5400000" />
+ <lnTo>
+ <pt x="hc" y="g19" />
+ </lnTo>
+ <arcTo wR="g27" hR="g27" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="g24" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g23" y="g9" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonReturn>
+ <actionButtonSound>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx2" fmla="*/ ss 3 8" />
+ <gd name="g9" fmla="+- vc 0 dx2" />
+ <gd name="g10" fmla="+- vc dx2 0" />
+ <gd name="g11" fmla="+- hc 0 dx2" />
+ <gd name="g12" fmla="+- hc dx2 0" />
+ <gd name="g13" fmla="*/ ss 3 4" />
+ <gd name="g14" fmla="*/ g13 1 8" />
+ <gd name="g15" fmla="*/ g13 5 16" />
+ <gd name="g16" fmla="*/ g13 5 8" />
+ <gd name="g17" fmla="*/ g13 11 16" />
+ <gd name="g18" fmla="*/ g13 3 4" />
+ <gd name="g19" fmla="*/ g13 7 8" />
+ <gd name="g20" fmla="+- g9 g14 0" />
+ <gd name="g21" fmla="+- g9 g15 0" />
+ <gd name="g22" fmla="+- g9 g17 0" />
+ <gd name="g23" fmla="+- g9 g19 0" />
+ <gd name="g24" fmla="+- g11 g15 0" />
+ <gd name="g25" fmla="+- g11 g16 0" />
+ <gd name="g26" fmla="+- g11 g18 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g11" y="g21" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g22" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g22" />
+ </lnTo>
+ <lnTo>
+ <pt x="g25" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g25" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g21" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+ <moveTo>
+ <pt x="g11" y="g21" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g11" y="g22" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g22" />
+ </lnTo>
+ <lnTo>
+ <pt x="g25" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g25" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g21" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="g11" y="g21" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="g24" y="g21" />
+ </lnTo>
+ <lnTo>
+ <pt x="g25" y="g9" />
+ </lnTo>
+ <lnTo>
+ <pt x="g25" y="g10" />
+ </lnTo>
+ <lnTo>
+ <pt x="g24" y="g22" />
+ </lnTo>
+ <lnTo>
+ <pt x="g11" y="g22" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="g26" y="g21" />
+ </moveTo>
+ <lnTo>
+ <pt x="g12" y="g20" />
+ </lnTo>
+ <moveTo>
+ <pt x="g26" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="g12" y="vc" />
+ </lnTo>
+ <moveTo>
+ <pt x="g26" y="g22" />
+ </moveTo>
+ <lnTo>
+ <pt x="g12" y="g23" />
+ </lnTo>
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </actionButtonSound>
+ <arc>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 16200000" />
+ <gd name="adj2" fmla="val 0" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="stAng" fmla="pin 0 adj1 21599999" />
+ <gd name="enAng" fmla="pin 0 adj2 21599999" />
+ <gd name="sw11" fmla="+- enAng 0 stAng" />
+ <gd name="sw12" fmla="+- sw11 21600000 0" />
+ <gd name="swAng" fmla="?: sw11 sw11 sw12" />
+ <gd name="wt1" fmla="sin wd2 stAng" />
+ <gd name="ht1" fmla="cos hd2 stAng" />
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1" />
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1" />
+ <gd name="wt2" fmla="sin wd2 enAng" />
+ <gd name="ht2" fmla="cos hd2 enAng" />
+ <gd name="dx2" fmla="cat2 wd2 ht2 wt2" />
+ <gd name="dy2" fmla="sat2 hd2 ht2 wt2" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc dy1 0" />
+ <gd name="x2" fmla="+- hc dx2 0" />
+ <gd name="y2" fmla="+- vc dy2 0" />
+ <gd name="sw0" fmla="+- 21600000 0 stAng" />
+ <gd name="da1" fmla="+- swAng 0 sw0" />
+ <gd name="g1" fmla="max x1 x2" />
+ <gd name="ir" fmla="?: da1 r g1" />
+ <gd name="sw1" fmla="+- cd4 0 stAng" />
+ <gd name="sw2" fmla="+- 27000000 0 stAng" />
+ <gd name="sw3" fmla="?: sw1 sw1 sw2" />
+ <gd name="da2" fmla="+- swAng 0 sw3" />
+ <gd name="g5" fmla="max y1 y2" />
+ <gd name="ib" fmla="?: da2 b g5" />
+ <gd name="sw4" fmla="+- cd2 0 stAng" />
+ <gd name="sw5" fmla="+- 32400000 0 stAng" />
+ <gd name="sw6" fmla="?: sw4 sw4 sw5" />
+ <gd name="da3" fmla="+- swAng 0 sw6" />
+ <gd name="g9" fmla="min x1 x2" />
+ <gd name="il" fmla="?: da3 l g9" />
+ <gd name="sw7" fmla="+- 3cd4 0 stAng" />
+ <gd name="sw8" fmla="+- 37800000 0 stAng" />
+ <gd name="sw9" fmla="?: sw7 sw7 sw8" />
+ <gd name="da4" fmla="+- swAng 0 sw9" />
+ <gd name="g13" fmla="min y1 y2" />
+ <gd name="it" fmla="?: da4 t g13" />
+ <gd name="cang1" fmla="+- stAng 0 cd4" />
+ <gd name="cang2" fmla="+- enAng cd4 0" />
+ <gd name="cang3" fmla="+/ cang1 cang2 2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="x1" y="y1" />
+ </ahPolar>
+ <ahPolar gdRefAng="adj2" minAng="0" maxAng="21599999">
+ <pos x="x2" y="y2" />
+ </ahPolar>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cang1">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="cang3">
+ <pos x="hc" y="vc" />
+ </cxn>
+ <cxn ang="cang2">
+ <pos x="x2" y="y2" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng" swAng="swAng" />
+ <lnTo>
+ <pt x="hc" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng" swAng="swAng" />
+ </path>
+ </pathLst>
+ </arc>
+ <bentArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 43750" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="a3" fmla="pin 0 adj3 50000" />
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="aw2" fmla="*/ ss a2 100000" />
+
+ <gd name="th2" fmla="*/ th 1 2" />
+ <gd name="dh2" fmla="+- aw2 0 th2" />
+
+ <gd name="ah" fmla="*/ ss a3 100000" />
+
+ <gd name="bw" fmla="+- r 0 ah" />
+
+ <gd name="bh" fmla="+- b 0 dh2" />
+
+ <gd name="bs" fmla="min bw bh" />
+
+ <gd name="maxAdj4" fmla="*/ 100000 bs ss" />
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+
+ <gd name="bd" fmla="*/ ss a4 100000" />
+
+
+ <gd name="bd3" fmla="+- bd 0 th" />
+ <gd name="bd2" fmla="max bd3 0" />
+ <gd name="x3" fmla="+- th bd2 0" />
+ <gd name="x4" fmla="+- r 0 ah" />
+
+
+ <gd name="y3" fmla="+- dh2 th 0" />
+ <gd name="y4" fmla="+- y3 dh2 0" />
+ <gd name="y5" fmla="+- dh2 bd 0" />
+ <gd name="y6" fmla="+- y3 bd2 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="th" y="b" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="50000">
+ <pos x="r" y="y4" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="0" maxX="50000">
+ <pos x="x4" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="0" maxX="maxAdj4">
+ <pos x="bd" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x4" y="t" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x4" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="th2" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="aw2" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="l" y="y5" />
+ </lnTo>
+ <arcTo wR="bd" hR="bd" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x4" y="dh2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="aw2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <arcTo wR="bd2" hR="bd2" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="th" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </bentArrow>
+ <bentConnector2>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ </path>
+ </pathLst>
+ </bentConnector2>
+ <bentConnector3>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x1" fmla="*/ w adj1 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647">
+ <pos x="x1" y="vc" />
+ </ahXY>
+ </ahLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ </path>
+ </pathLst>
+ </bentConnector3>
+ <bentConnector4>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x1" fmla="*/ w adj1 100000" />
+ <gd name="x2" fmla="+/ x1 r 2" />
+ <gd name="y2" fmla="*/ h adj2 100000" />
+ <gd name="y1" fmla="+/ t y2 2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ </ahLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ </path>
+ </pathLst>
+ </bentConnector4>
+ <bentConnector5>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 50000" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x1" fmla="*/ w adj1 100000" />
+
+ <gd name="x3" fmla="*/ w adj3 100000" />
+
+ <gd name="x2" fmla="+/ x1 x3 2" />
+
+ <gd name="y2" fmla="*/ h adj2 100000" />
+
+ <gd name="y1" fmla="+/ t y2 2" />
+
+ <gd name="y3" fmla="+/ b y2 2" />
+
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="-2147483647" maxX="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ </ahLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </bentConnector5>
+ <bentUpArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="a3" fmla="pin 0 adj3 50000" />
+ <gd name="y1" fmla="*/ ss a3 100000" />
+ <gd name="dx1" fmla="*/ ss a2 50000" />
+
+ <gd name="x1" fmla="+- r 0 dx1" />
+ <gd name="dx3" fmla="*/ ss a2 100000" />
+
+ <gd name="x3" fmla="+- r 0 dx3" />
+ <gd name="dx2" fmla="*/ ss a1 200000" />
+
+ <gd name="x2" fmla="+- x3 0 dx2" />
+ <gd name="x4" fmla="+- x3 dx2 0" />
+ <gd name="dy2" fmla="*/ ss a1 100000" />
+
+ <gd name="y2" fmla="+- b 0 dy2" />
+ <gd name="x0" fmla="*/ x4 1 2" />
+ <gd name="y3" fmla="+/ y2 b 2" />
+ <gd name="y15" fmla="+/ y1 b 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="50000">
+ <pos x="l" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="50000">
+ <pos x="x2" y="y1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x0" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y15" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="y2" r="x4" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </bentUpArrow>
+ <bevel>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 12500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+
+
+
+ <gd name="x2" fmla="+- r 0 x1" />
+
+ <gd name="y2" fmla="+- b 0 x1" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="x1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="x1" r="x2" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x1" y="x1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="lightenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="x1" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="lighten" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darken" extrusionOk="false">
+
+ <moveTo>
+ <pt x="r" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x1" y="x1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="x1" />
+ </lnTo>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <moveTo>
+ <pt x="r" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <moveTo>
+ <pt x="r" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </bevel>
+ <blockArc>
+
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 10800000" />
+
+ <gd name="adj2" fmla="val 0" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="stAng" fmla="pin 0 adj1 21599999" />
+ <gd name="istAng" fmla="pin 0 adj2 21599999" />
+ <gd name="a3" fmla="pin 0 adj3 50000" />
+ <gd name="sw11" fmla="+- istAng 0 stAng" />
+
+ <gd name="sw12" fmla="+- sw11 21600000 0" />
+
+ <gd name="swAng" fmla="?: sw11 sw11 sw12" />
+
+ <gd name="iswAng" fmla="+- 0 0 swAng" />
+
+
+ <gd name="wt1" fmla="sin wd2 stAng" />
+ <gd name="ht1" fmla="cos hd2 stAng" />
+ <gd name="wt3" fmla="sin wd2 istAng" />
+ <gd name="ht3" fmla="cos hd2 istAng" />
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1" />
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1" />
+ <gd name="dx3" fmla="cat2 wd2 ht3 wt3" />
+ <gd name="dy3" fmla="sat2 hd2 ht3 wt3" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+
+ <gd name="y1" fmla="+- vc dy1 0" />
+
+ <gd name="x3" fmla="+- hc dx3 0" />
+
+ <gd name="y3" fmla="+- vc dy3 0" />
+
+
+ <gd name="dr" fmla="*/ ss a3 100000" />
+ <gd name="iwd2" fmla="+- wd2 0 dr" />
+ <gd name="ihd2" fmla="+- hd2 0 dr" />
+ <gd name="wt2" fmla="sin iwd2 istAng" />
+ <gd name="ht2" fmla="cos ihd2 istAng" />
+ <gd name="wt4" fmla="sin iwd2 stAng" />
+ <gd name="ht4" fmla="cos ihd2 stAng" />
+ <gd name="dx2" fmla="cat2 iwd2 ht2 wt2" />
+ <gd name="dy2" fmla="sat2 ihd2 ht2 wt2" />
+ <gd name="dx4" fmla="cat2 iwd2 ht4 wt4" />
+ <gd name="dy4" fmla="sat2 ihd2 ht4 wt4" />
+ <gd name="x2" fmla="+- hc dx2 0" />
+
+ <gd name="y2" fmla="+- vc dy2 0" />
+
+ <gd name="x4" fmla="+- hc dx4 0" />
+
+ <gd name="y4" fmla="+- vc dy4 0" />
+
+
+ <gd name="sw0" fmla="+- 21600000 0 stAng" />
+ <gd name="da1" fmla="+- swAng 0 sw0" />
+ <gd name="g1" fmla="max x1 x2" />
+ <gd name="g2" fmla="max x3 x4" />
+ <gd name="g3" fmla="max g1 g2" />
+ <gd name="ir" fmla="?: da1 r g3" />
+
+ <gd name="sw1" fmla="+- cd4 0 stAng" />
+ <gd name="sw2" fmla="+- 27000000 0 stAng" />
+ <gd name="sw3" fmla="?: sw1 sw1 sw2" />
+ <gd name="da2" fmla="+- swAng 0 sw3" />
+ <gd name="g5" fmla="max y1 y2" />
+ <gd name="g6" fmla="max y3 y4" />
+ <gd name="g7" fmla="max g5 g6" />
+ <gd name="ib" fmla="?: da2 b g7" />
+
+ <gd name="sw4" fmla="+- cd2 0 stAng" />
+ <gd name="sw5" fmla="+- 32400000 0 stAng" />
+ <gd name="sw6" fmla="?: sw4 sw4 sw5" />
+ <gd name="da3" fmla="+- swAng 0 sw6" />
+ <gd name="g9" fmla="min x1 x2" />
+ <gd name="g10" fmla="min x3 x4" />
+ <gd name="g11" fmla="min g9 g10" />
+ <gd name="il" fmla="?: da3 l g11" />
+
+ <gd name="sw7" fmla="+- 3cd4 0 stAng" />
+ <gd name="sw8" fmla="+- 37800000 0 stAng" />
+ <gd name="sw9" fmla="?: sw7 sw7 sw8" />
+ <gd name="da4" fmla="+- swAng 0 sw9" />
+ <gd name="g13" fmla="min y1 y2" />
+ <gd name="g14" fmla="min y3 y4" />
+ <gd name="g15" fmla="min g13 g14" />
+ <gd name="it" fmla="?: da4 t g15" />
+
+ <gd name="x5" fmla="+/ x1 x4 2" />
+
+ <gd name="y5" fmla="+/ y1 y4 2" />
+
+ <gd name="x6" fmla="+/ x3 x2 2" />
+
+ <gd name="y6" fmla="+/ y3 y2 2" />
+
+ <gd name="cang1" fmla="+- stAng 0 cd4" />
+ <gd name="cang2" fmla="+- istAng cd4 0" />
+ <gd name="cang3" fmla="+/ cang1 cang2 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="x1" y="y1" />
+ </ahPolar>
+ <ahPolar gdRefR="adj3" minR="0" maxR="50000" gdRefAng="adj2" minAng="0" maxAng="21599999">
+ <pos x="x2" y="y2" />
+ </ahPolar>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cang1">
+ <pos x="x5" y="y5" />
+ </cxn>
+ <cxn ang="cang2">
+ <pos x="x6" y="y6" />
+ </cxn>
+ <cxn ang="cang3">
+ <pos x="hc" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng" swAng="swAng" />
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="istAng" swAng="iswAng" />
+ <close />
+ </path>
+ </pathLst>
+
+ </blockArc>
+ <borderCallout1>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 112500" />
+
+ <gd name="adj4" fmla="val -38333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </borderCallout1>
+ <borderCallout2>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 112500" />
+
+ <gd name="adj6" fmla="val -46667" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </borderCallout2>
+ <borderCallout3>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 100000" />
+
+ <gd name="adj6" fmla="val -16667" />
+
+ <gd name="adj7" fmla="val 112963" />
+
+ <gd name="adj8" fmla="val -8333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ <gd name="y4" fmla="*/ h adj7 100000" />
+ <gd name="x4" fmla="*/ w adj8 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ <ahXY gdRefX="adj8" minX="-2147483647" maxX="2147483647" gdRefY="adj7" minY="-2147483647" maxY="2147483647">
+ <pos x="x4" y="y4" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </borderCallout3>
+ <bracePair>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 8333" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 25000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="*/ ss a 50000" />
+ <gd name="x3" fmla="+- r 0 x2" />
+ <gd name="x4" fmla="+- r 0 x1" />
+
+ <gd name="y2" fmla="+- vc 0 x1" />
+ <gd name="y3" fmla="+- vc x1 0" />
+ <gd name="y4" fmla="+- b 0 x1" />
+ <gd name="it" fmla="*/ x1 29289 100000" />
+
+ <gd name="il" fmla="+- x1 it 0" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 it" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="25000">
+ <pos x="l" y="x1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="x2" y="b" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="-5400000" />
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="x1" y="x1" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="-5400000" />
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="x2" y="b" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="-5400000" />
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="x1" y="x1" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="cd4" />
+ <moveTo>
+ <pt x="x3" y="t" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="-5400000" />
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="cd4" />
+ </path>
+ </pathLst>
+
+ </bracePair>
+ <bracketPair>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 16667" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="+- r 0 x1" />
+
+ <gd name="y2" fmla="+- b 0 x1" />
+ <gd name="il" fmla="*/ x1 29289 100000" />
+
+
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 il" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="l" y="x1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="x1" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="x1" y="b" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="l" y="x1" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="cd4" />
+ <moveTo>
+ <pt x="x2" y="t" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="cd4" />
+ </path>
+ </pathLst>
+
+ </bracketPair>
+ <callout1>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 112500" />
+
+ <gd name="adj4" fmla="val -38333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </callout1>
+ <callout2>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 112500" />
+
+ <gd name="adj6" fmla="val -46667" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </callout2>
+ <callout3>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="adj1" fmla="val 18750" />
+
+ <gd name="adj2" fmla="val -8333" />
+
+ <gd name="adj3" fmla="val 18750" />
+
+ <gd name="adj4" fmla="val -16667" />
+
+ <gd name="adj5" fmla="val 100000" />
+
+ <gd name="adj6" fmla="val -16667" />
+
+ <gd name="adj7" fmla="val 112963" />
+
+ <gd name="adj8" fmla="val -8333" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h adj1 100000" />
+ <gd name="x1" fmla="*/ w adj2 100000" />
+ <gd name="y2" fmla="*/ h adj3 100000" />
+ <gd name="x2" fmla="*/ w adj4 100000" />
+ <gd name="y3" fmla="*/ h adj5 100000" />
+ <gd name="x3" fmla="*/ w adj6 100000" />
+ <gd name="y4" fmla="*/ h adj7 100000" />
+ <gd name="x4" fmla="*/ w adj8 100000" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj2" minX="-2147483647" maxX="2147483647" gdRefY="adj1" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="-2147483647" maxX="2147483647" gdRefY="adj3" minY="-2147483647" maxY="2147483647">
+ <pos x="x2" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj6" minX="-2147483647" maxX="2147483647" gdRefY="adj5" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ <ahXY gdRefX="adj8" minX="-2147483647" maxX="2147483647" gdRefY="adj7" minY="-2147483647" maxY="2147483647">
+ <pos x="x4" y="y4" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </callout3>
+ <can>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 50000 h ss" />
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="y1" fmla="*/ ss a 200000" />
+ <gd name="y2" fmla="+- y1 y1 0" />
+ <gd name="y3" fmla="+- b 0 y1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="maxAdj">
+ <pos x="hc" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="y2" r="r" b="y3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd2" swAng="-10800000" />
+ <lnTo>
+ <pt x="r" y="y3" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="cd2" />
+ <close />
+ </path>
+ <path stroke="false" fill="lighten" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd2" swAng="cd2" />
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="cd2" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="r" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="cd2" />
+ <arcTo wR="wd2" hR="y1" stAng="cd2" swAng="cd2" />
+ <lnTo>
+ <pt x="r" y="y3" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="cd2" />
+ <lnTo>
+ <pt x="l" y="y1" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </can>
+ <chartPlus>
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="10" h="10" fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="5" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="5" y="10" />
+ </lnTo>
+ <moveTo>
+ <pt x="0" y="5" />
+ </moveTo>
+ <lnTo>
+ <pt x="10" y="5" />
+ </lnTo>
+ </path>
+ <path w="10" h="10" stroke="false">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="0" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="0" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </chartPlus>
+ <chartStar>
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="10" h="10" fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="10" y="10" />
+ </lnTo>
+ <moveTo>
+ <pt x="0" y="10" />
+ </moveTo>
+ <lnTo>
+ <pt x="10" y="0" />
+ </lnTo>
+ <moveTo>
+ <pt x="5" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="5" y="10" />
+ </lnTo>
+ </path>
+ <path w="10" h="10" stroke="false">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="0" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="0" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </chartStar>
+ <chartX>
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="10" h="10" fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="10" y="10" />
+ </lnTo>
+ <moveTo>
+ <pt x="0" y="10" />
+ </moveTo>
+ <lnTo>
+ <pt x="10" y="0" />
+ </lnTo>
+ </path>
+ <path w="10" h="10" stroke="false">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="0" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="0" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </chartX>
+ <chevron>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 100000 w ss" />
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="+- r 0 x1" />
+ <gd name="x3" fmla="*/ x2 1 2" />
+ <gd name="dx" fmla="+- x2 0 x1" />
+ <gd name="il" fmla="?: dx x1 l" />
+ <gd name="ir" fmla="?: dx x2 r" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="maxAdj">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="t" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </chevron>
+ <chord>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 2700000" />
+
+ <gd name="adj2" fmla="val 16200000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="stAng" fmla="pin 0 adj1 21599999" />
+ <gd name="enAng" fmla="pin 0 adj2 21599999" />
+ <gd name="sw1" fmla="+- enAng 0 stAng" />
+
+ <gd name="sw2" fmla="+- sw1 21600000 0" />
+
+ <gd name="swAng" fmla="?: sw1 sw1 sw2" />
+
+ <gd name="wt1" fmla="sin wd2 stAng" />
+ <gd name="ht1" fmla="cos hd2 stAng" />
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1" />
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1" />
+ <gd name="wt2" fmla="sin wd2 enAng" />
+ <gd name="ht2" fmla="cos hd2 enAng" />
+ <gd name="dx2" fmla="cat2 wd2 ht2 wt2" />
+ <gd name="dy2" fmla="sat2 hd2 ht2 wt2" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+
+ <gd name="y1" fmla="+- vc dy1 0" />
+
+ <gd name="x2" fmla="+- hc dx2 0" />
+
+ <gd name="y2" fmla="+- vc dy2 0" />
+
+ <gd name="x3" fmla="+/ x1 x2 2" />
+ <gd name="y3" fmla="+/ y1 y2 2" />
+ <gd name="midAng0" fmla="*/ swAng 1 2" />
+ <gd name="midAng" fmla="+- stAng midAng0 cd2" />
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="x1" y="y1" />
+ </ahPolar>
+ <ahPolar gdRefAng="adj2" minAng="0" maxAng="21599999">
+ <pos x="x2" y="y2" />
+ </ahPolar>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="stAng">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="enAng">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="midAng">
+ <pos x="x3" y="y3" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng" swAng="swAng" />
+ <close />
+ </path>
+ </pathLst>
+
+ </chord>
+ <circularArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 12500" />
+
+ <gd name="adj2" fmla="val 1142319" />
+
+ <gd name="adj3" fmla="val 20457681" />
+
+ <gd name="adj4" fmla="val 10800000" />
+
+ <gd name="adj5" fmla="val 12500" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a5" fmla="pin 0 adj5 25000" />
+
+ <gd name="maxAdj1" fmla="*/ a5 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="enAng" fmla="pin 1 adj3 21599999" />
+ <gd name="stAng" fmla="pin 0 adj4 21599999" />
+
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="thh" fmla="*/ ss a5 100000" />
+
+ <gd name="th2" fmla="*/ th 1 2" />
+
+
+ <gd name="rw1" fmla="+- wd2 th2 thh" />
+
+ <gd name="rh1" fmla="+- hd2 th2 thh" />
+
+ <gd name="rw2" fmla="+- rw1 0 th" />
+
+ <gd name="rh2" fmla="+- rh1 0 th" />
+
+ <gd name="rw3" fmla="+- rw2 th2 0" />
+
+ <gd name="rh3" fmla="+- rh2 th2 0" />
+
+
+ <gd name="wtH" fmla="sin rw3 enAng" />
+ <gd name="htH" fmla="cos rh3 enAng" />
+ <gd name="dxH" fmla="cat2 rw3 htH wtH" />
+ <gd name="dyH" fmla="sat2 rh3 htH wtH" />
+ <gd name="xH" fmla="+- hc dxH 0" />
+
+ <gd name="yH" fmla="+- vc dyH 0" />
+
+
+ <gd name="rI" fmla="min rw2 rh2" />
+
+ <gd name="u1" fmla="*/ dxH dxH 1" />
+ <gd name="u2" fmla="*/ dyH dyH 1" />
+ <gd name="u3" fmla="*/ rI rI 1" />
+ <gd name="u4" fmla="+- u1 0 u3" />
+ <gd name="u5" fmla="+- u2 0 u3" />
+ <gd name="u6" fmla="*/ u4 u5 u1" />
+ <gd name="u7" fmla="*/ u6 1 u2" />
+ <gd name="u8" fmla="+- 1 0 u7" />
+ <gd name="u9" fmla="sqrt u8" />
+ <gd name="u10" fmla="*/ u4 1 dxH" />
+ <gd name="u11" fmla="*/ u10 1 dyH" />
+ <gd name="u12" fmla="+/ 1 u9 u11" />
+ <gd name="u13" fmla="at2 1 u12" />
+ <gd name="u14" fmla="+- u13 21600000 0" />
+ <gd name="u15" fmla="?: u13 u13 u14" />
+ <gd name="u16" fmla="+- u15 0 enAng" />
+
+ <gd name="u17" fmla="+- u16 21600000 0" />
+ <gd name="u18" fmla="?: u16 u16 u17" />
+ <gd name="u19" fmla="+- u18 0 cd2" />
+ <gd name="u20" fmla="+- u18 0 21600000" />
+ <gd name="u21" fmla="?: u19 u20 u18" />
+ <gd name="maxAng" fmla="abs u21" />
+ <gd name="aAng" fmla="pin 0 adj2 maxAng" />
+
+ <gd name="ptAng" fmla="+- enAng aAng 0" />
+
+
+ <gd name="wtA" fmla="sin rw3 ptAng" />
+ <gd name="htA" fmla="cos rh3 ptAng" />
+ <gd name="dxA" fmla="cat2 rw3 htA wtA" />
+ <gd name="dyA" fmla="sat2 rh3 htA wtA" />
+ <gd name="xA" fmla="+- hc dxA 0" />
+
+ <gd name="yA" fmla="+- vc dyA 0" />
+
+
+ <gd name="wtE" fmla="sin rw1 stAng" />
+ <gd name="htE" fmla="cos rh1 stAng" />
+ <gd name="dxE" fmla="cat2 rw1 htE wtE" />
+ <gd name="dyE" fmla="sat2 rh1 htE wtE" />
+ <gd name="xE" fmla="+- hc dxE 0" />
+
+ <gd name="yE" fmla="+- vc dyE 0" />
+
+
+ <gd name="dxG" fmla="cos thh ptAng" />
+ <gd name="dyG" fmla="sin thh ptAng" />
+ <gd name="xG" fmla="+- xH dxG 0" />
+
+ <gd name="yG" fmla="+- yH dyG 0" />
+
+
+ <gd name="dxB" fmla="cos thh ptAng" />
+ <gd name="dyB" fmla="sin thh ptAng" />
+ <gd name="xB" fmla="+- xH 0 dxB 0" />
+
+ <gd name="yB" fmla="+- yH 0 dyB 0" />
+
+
+ <gd name="sx1" fmla="+- xB 0 hc" />
+
+ <gd name="sy1" fmla="+- yB 0 vc" />
+
+ <gd name="sx2" fmla="+- xG 0 hc" />
+
+ <gd name="sy2" fmla="+- yG 0 vc" />
+
+
+ <gd name="rO" fmla="min rw1 rh1" />
+
+ <gd name="x1O" fmla="*/ sx1 rO rw1" />
+
+ <gd name="y1O" fmla="*/ sy1 rO rh1" />
+
+ <gd name="x2O" fmla="*/ sx2 rO rw1" />
+
+ <gd name="y2O" fmla="*/ sy2 rO rh1" />
+
+
+ <gd name="dxO" fmla="+- x2O 0 x1O" />
+ <gd name="dyO" fmla="+- y2O 0 y1O" />
+ <gd name="dO" fmla="mod dxO dyO 0" />
+
+ <gd name="q1" fmla="*/ x1O y2O 1" />
+ <gd name="q2" fmla="*/ x2O y1O 1" />
+ <gd name="DO" fmla="+- q1 0 q2" />
+
+
+ <gd name="q3" fmla="*/ rO rO 1" />
+
+ <gd name="q4" fmla="*/ dO dO 1" />
+
+ <gd name="q5" fmla="*/ q3 q4 1" />
+
+ <gd name="q6" fmla="*/ DO DO 1" />
+
+ <gd name="q7" fmla="+- q5 0 q6" />
+
+ <gd name="q8" fmla="max q7 0" />
+
+ <gd name="sdelO" fmla="sqrt q8" />
+
+ <gd name="ndyO" fmla="*/ dyO -1 1" />
+ <gd name="sdyO" fmla="?: ndyO -1 1" />
+
+ <gd name="q9" fmla="*/ sdyO dxO 1" />
+
+ <gd name="q10" fmla="*/ q9 sdelO 1" />
+
+ <gd name="q11" fmla="*/ DO dyO 1" />
+
+ <gd name="dxF1" fmla="+/ q11 q10 q4" />
+
+ <gd name="q12" fmla="+- q11 0 q10" />
+ <gd name="dxF2" fmla="*/ q12 1 q4" />
+
+
+ <gd name="adyO" fmla="abs dyO" />
+ <gd name="q13" fmla="*/ adyO sdelO 1" />
+
+ <gd name="q14" fmla="*/ DO dxO -1" />
+
+ <gd name="dyF1" fmla="+/ q14 q13 q4" />
+
+ <gd name="q15" fmla="+- q14 0 q13" />
+ <gd name="dyF2" fmla="*/ q15 1 q4" />
+
+
+
+ <gd name="q16" fmla="+- x2O 0 dxF1" />
+ <gd name="q17" fmla="+- x2O 0 dxF2" />
+ <gd name="q18" fmla="+- y2O 0 dyF1" />
+ <gd name="q19" fmla="+- y2O 0 dyF2" />
+ <gd name="q20" fmla="mod q16 q18 0" />
+
+ <gd name="q21" fmla="mod q17 q19 0" />
+
+ <gd name="q22" fmla="+- q21 0 q20" />
+ <gd name="dxF" fmla="?: q22 dxF1 dxF2" />
+
+ <gd name="dyF" fmla="?: q22 dyF1 dyF2" />
+
+ <gd name="sdxF" fmla="*/ dxF rw1 rO" />
+
+ <gd name="sdyF" fmla="*/ dyF rh1 rO" />
+
+ <gd name="xF" fmla="+- hc sdxF 0" />
+
+ <gd name="yF" fmla="+- vc sdyF 0" />
+
+
+
+
+ <gd name="x1I" fmla="*/ sx1 rI rw2" />
+
+ <gd name="y1I" fmla="*/ sy1 rI rh2" />
+
+ <gd name="x2I" fmla="*/ sx2 rI rw2" />
+
+ <gd name="y2I" fmla="*/ sy2 rI rh2" />
+
+
+ <gd name="dxI" fmla="+- x2I 0 x1I" />
+ <gd name="dyI" fmla="+- y2I 0 y1I" />
+ <gd name="dI" fmla="mod dxI dyI 0" />
+ <gd name="v1" fmla="*/ x1I y2I 1" />
+ <gd name="v2" fmla="*/ x2I y1I 1" />
+ <gd name="DI" fmla="+- v1 0 v2" />
+
+ <gd name="v3" fmla="*/ rI rI 1" />
+ <gd name="v4" fmla="*/ dI dI 1" />
+ <gd name="v5" fmla="*/ v3 v4 1" />
+ <gd name="v6" fmla="*/ DI DI 1" />
+ <gd name="v7" fmla="+- v5 0 v6" />
+ <gd name="v8" fmla="max v7 0" />
+ <gd name="sdelI" fmla="sqrt v8" />
+ <gd name="v9" fmla="*/ sdyO dxI 1" />
+ <gd name="v10" fmla="*/ v9 sdelI 1" />
+ <gd name="v11" fmla="*/ DI dyI 1" />
+ <gd name="dxC1" fmla="+/ v11 v10 v4" />
+ <gd name="v12" fmla="+- v11 0 v10" />
+ <gd name="dxC2" fmla="*/ v12 1 v4" />
+
+ <gd name="adyI" fmla="abs dyI" />
+ <gd name="v13" fmla="*/ adyI sdelI 1" />
+ <gd name="v14" fmla="*/ DI dxI -1" />
+ <gd name="dyC1" fmla="+/ v14 v13 v4" />
+ <gd name="v15" fmla="+- v14 0 v13" />
+ <gd name="dyC2" fmla="*/ v15 1 v4" />
+
+ <gd name="v16" fmla="+- x1I 0 dxC1" />
+ <gd name="v17" fmla="+- x1I 0 dxC2" />
+ <gd name="v18" fmla="+- y1I 0 dyC1" />
+ <gd name="v19" fmla="+- y1I 0 dyC2" />
+ <gd name="v20" fmla="mod v16 v18 0" />
+ <gd name="v21" fmla="mod v17 v19 0" />
+ <gd name="v22" fmla="+- v21 0 v20" />
+ <gd name="dxC" fmla="?: v22 dxC1 dxC2" />
+ <gd name="dyC" fmla="?: v22 dyC1 dyC2" />
+ <gd name="sdxC" fmla="*/ dxC rw2 rI" />
+ <gd name="sdyC" fmla="*/ dyC rh2 rI" />
+ <gd name="xC" fmla="+- hc sdxC 0" />
+
+ <gd name="yC" fmla="+- vc sdyC 0" />
+
+
+ <gd name="ist0" fmla="at2 sdxC sdyC" />
+ <gd name="ist1" fmla="+- ist0 21600000 0" />
+ <gd name="istAng" fmla="?: ist0 ist0 ist1" />
+ <gd name="isw1" fmla="+- stAng 0 istAng" />
+ <gd name="isw2" fmla="+- isw1 0 21600000" />
+ <gd name="iswAng" fmla="?: isw1 isw2 isw1" />
+
+
+ <gd name="p1" fmla="+- xF 0 xC" />
+ <gd name="p2" fmla="+- yF 0 yC" />
+ <gd name="p3" fmla="mod p1 p2 0" />
+ <gd name="p4" fmla="*/ p3 1 2" />
+ <gd name="p5" fmla="+- p4 0 thh" />
+ <gd name="xGp" fmla="?: p5 xF xG" />
+ <gd name="yGp" fmla="?: p5 yF yG" />
+ <gd name="xBp" fmla="?: p5 xC xB" />
+ <gd name="yBp" fmla="?: p5 yC yB" />
+
+ <gd name="en0" fmla="at2 sdxF sdyF" />
+ <gd name="en1" fmla="+- en0 21600000 0" />
+ <gd name="en2" fmla="?: en0 en0 en1" />
+ <gd name="sw0" fmla="+- en2 0 stAng" />
+ <gd name="sw1" fmla="+- sw0 21600000 0" />
+ <gd name="swAng" fmla="?: sw0 sw0 sw1" />
+
+ <gd name="wtI" fmla="sin rw3 stAng" />
+ <gd name="htI" fmla="cos rh3 stAng" />
+ <gd name="dxI" fmla="cat2 rw3 htI wtI" />
+ <gd name="dyI" fmla="sat2 rh3 htI wtI" />
+ <gd name="xI" fmla="+- hc dxI 0" />
+
+ <gd name="yI" fmla="+- vc dyI 0" />
+
+
+ <gd name="aI" fmla="+- stAng 0 cd4" />
+ <gd name="aA" fmla="+- ptAng cd4 0" />
+ <gd name="aB" fmla="+- ptAng cd2 0" />
+
+ <gd name="idx" fmla="cos rw1 2700000" />
+ <gd name="idy" fmla="sin rh1 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj2" minAng="0" maxAng="maxAng">
+ <pos x="xA" y="yA" />
+ </ahPolar>
+ <ahPolar gdRefAng="adj4" minAng="0" maxAng="21599999">
+ <pos x="xE" y="yE" />
+ </ahPolar>
+ <ahPolar gdRefR="adj1" minR="0" maxR="maxAdj1" gdRefAng="adj3" minAng="0" maxAng="21599999">
+ <pos x="xF" y="yF" />
+ </ahPolar>
+ <ahPolar gdRefR="adj5" minR="0" maxR="25000">
+ <pos x="xB" y="yB" />
+ </ahPolar>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="aI">
+ <pos x="xI" y="yI" />
+ </cxn>
+ <cxn ang="ptAng">
+ <pos x="xGp" y="yGp" />
+ </cxn>
+ <cxn ang="aA">
+ <pos x="xA" y="yA" />
+ </cxn>
+ <cxn ang="aB">
+ <pos x="xBp" y="yBp" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="xE" y="yE" />
+ </moveTo>
+ <arcTo wR="rw1" hR="rh1" stAng="stAng" swAng="swAng" />
+ <lnTo>
+ <pt x="xGp" y="yGp" />
+ </lnTo>
+ <lnTo>
+ <pt x="xA" y="yA" />
+ </lnTo>
+ <lnTo>
+ <pt x="xBp" y="yBp" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC" y="yC" />
+ </lnTo>
+ <arcTo wR="rw2" hR="rh2" stAng="istAng" swAng="iswAng" />
+ <close />
+ </path>
+ </pathLst>
+
+ </circularArrow>
+ <cloud>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="il" fmla="*/ w 2977 21600" />
+ <gd name="it" fmla="*/ h 3262 21600" />
+ <gd name="ir" fmla="*/ w 17087 21600" />
+ <gd name="ib" fmla="*/ h 17337 21600" />
+ <gd name="g27" fmla="*/ w 67 21600" />
+ <gd name="g28" fmla="*/ h 21577 21600" />
+ <gd name="g29" fmla="*/ w 21582 21600" />
+ <gd name="g30" fmla="*/ h 1235 21600" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="g29" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="g28" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="g27" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="g30" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="43200" h="43200">
+ <moveTo>
+ <pt x="3900" y="14370" />
+ </moveTo>
+ <arcTo wR="6753" hR="9190" stAng="-11429249" swAng="7426832" />
+ <arcTo wR="5333" hR="7267" stAng="-8646143" swAng="5396714" />
+ <arcTo wR="4365" hR="5945" stAng="-8748475" swAng="5983381" />
+ <arcTo wR="4857" hR="6595" stAng="-7859164" swAng="7034504" />
+ <arcTo wR="5333" hR="7273" stAng="-4722533" swAng="6541615" />
+ <arcTo wR="6775" hR="9220" stAng="-2776035" swAng="7816140" />
+ <arcTo wR="5785" hR="7867" stAng="37501" swAng="6842000" />
+ <arcTo wR="6752" hR="9215" stAng="1347096" swAng="6910353" />
+ <arcTo wR="7720" hR="10543" stAng="3974558" swAng="4542661" />
+ <arcTo wR="4360" hR="5918" stAng="-16496525" swAng="8804134" />
+ <arcTo wR="4345" hR="5945" stAng="-14809710" swAng="9151131" />
+ <close />
+ </path>
+ <path w="43200" h="43200" fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="4693" y="26177" />
+ </moveTo>
+ <arcTo wR="4345" hR="5945" stAng="5204520" swAng="1585770" />
+ <moveTo>
+ <pt x="6928" y="34899" />
+ </moveTo>
+ <arcTo wR="4360" hR="5918" stAng="4416628" swAng="686848" />
+ <moveTo>
+ <pt x="16478" y="39090" />
+ </moveTo>
+ <arcTo wR="6752" hR="9215" stAng="8257449" swAng="844866" />
+ <moveTo>
+ <pt x="28827" y="34751" />
+ </moveTo>
+ <arcTo wR="6752" hR="9215" stAng="387196" swAng="959901" />
+ <moveTo>
+ <pt x="34129" y="22954" />
+ </moveTo>
+ <arcTo wR="5785" hR="7867" stAng="-4217541" swAng="4255042" />
+ <moveTo>
+ <pt x="41798" y="15354" />
+ </moveTo>
+ <arcTo wR="5333" hR="7273" stAng="1819082" swAng="1665090" />
+ <moveTo>
+ <pt x="38324" y="5426" />
+ </moveTo>
+ <arcTo wR="4857" hR="6595" stAng="-824660" swAng="891534" />
+ <moveTo>
+ <pt x="29078" y="3952" />
+ </moveTo>
+ <arcTo wR="4857" hR="6595" stAng="-8950887" swAng="1091722" />
+ <moveTo>
+ <pt x="22141" y="4720" />
+ </moveTo>
+ <arcTo wR="4365" hR="5945" stAng="-9809656" swAng="1061181" />
+ <moveTo>
+ <pt x="14000" y="5192" />
+ </moveTo>
+ <arcTo wR="6753" hR="9190" stAng="-4002417" swAng="739161" />
+ <moveTo>
+ <pt x="4127" y="15789" />
+ </moveTo>
+ <arcTo wR="6753" hR="9190" stAng="9459261" swAng="711490" />
+ </path>
+ </pathLst>
+
+ </cloud>
+ <cloudCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val -20833" />
+
+ <gd name="adj2" fmla="val 62500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dxPos" fmla="*/ w adj1 100000" />
+ <gd name="dyPos" fmla="*/ h adj2 100000" />
+ <gd name="xPos" fmla="+- hc dxPos 0" />
+ <gd name="yPos" fmla="+- vc dyPos 0" />
+ <gd name="ht" fmla="cat2 hd2 dxPos dyPos" />
+ <gd name="wt" fmla="sat2 wd2 dxPos dyPos" />
+ <gd name="g2" fmla="cat2 wd2 ht wt" />
+ <gd name="g3" fmla="sat2 hd2 ht wt" />
+ <gd name="g4" fmla="+- hc g2 0" />
+
+ <gd name="g5" fmla="+- vc g3 0" />
+
+ <gd name="g6" fmla="+- g4 0 xPos" />
+
+ <gd name="g7" fmla="+- g5 0 yPos" />
+
+ <gd name="g8" fmla="mod g6 g7 0" />
+
+ <gd name="g9" fmla="*/ ss 6600 21600" />
+
+ <gd name="g10" fmla="+- g8 0 g9" />
+
+ <gd name="g11" fmla="*/ g10 1 3" />
+
+ <gd name="g12" fmla="*/ ss 1800 21600" />
+
+ <gd name="g13" fmla="+- g11 g12 0" />
+
+ <gd name="g14" fmla="*/ g13 g6 g8" />
+
+ <gd name="g15" fmla="*/ g13 g7 g8" />
+
+ <gd name="g16" fmla="+- g14 xPos 0" />
+
+ <gd name="g17" fmla="+- g15 yPos 0" />
+
+ <gd name="g18" fmla="*/ ss 4800 21600" />
+
+ <gd name="g19" fmla="*/ g11 2 1" />
+
+ <gd name="g20" fmla="+- g18 g19 0" />
+
+ <gd name="g21" fmla="*/ g20 g6 g8" />
+ <gd name="g22" fmla="*/ g20 g7 g8" />
+ <gd name="g23" fmla="+- g21 xPos 0" />
+ <gd name="g24" fmla="+- g22 yPos 0" />
+ <gd name="g25" fmla="*/ ss 1200 21600" />
+ <gd name="g26" fmla="*/ ss 600 21600" />
+
+ <gd name="x23" fmla="+- xPos g26 0" />
+ <gd name="x24" fmla="+- g16 g25 0" />
+ <gd name="x25" fmla="+- g23 g12 0" />
+ <gd name="il" fmla="*/ w 2977 21600" />
+ <gd name="it" fmla="*/ h 3262 21600" />
+ <gd name="ir" fmla="*/ w 17087 21600" />
+ <gd name="ib" fmla="*/ h 17337 21600" />
+
+ <gd name="g27" fmla="*/ w 67 21600" />
+ <gd name="g28" fmla="*/ h 21577 21600" />
+ <gd name="g29" fmla="*/ w 21582 21600" />
+ <gd name="g30" fmla="*/ h 1235 21600" />
+ <gd name="pang" fmla="at2 dxPos dyPos" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647" gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="xPos" y="yPos" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd2">
+ <pos x="g27" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="g28" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="g29" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="g30" />
+ </cxn>
+ <cxn ang="pang">
+ <pos x="xPos" y="yPos" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="43200" h="43200">
+ <moveTo>
+ <pt x="3900" y="14370" />
+ </moveTo>
+ <arcTo wR="6753" hR="9190" stAng="-11429249" swAng="7426832" />
+ <arcTo wR="5333" hR="7267" stAng="-8646143" swAng="5396714" />
+ <arcTo wR="4365" hR="5945" stAng="-8748475" swAng="5983381" />
+ <arcTo wR="4857" hR="6595" stAng="-7859164" swAng="7034504" />
+ <arcTo wR="5333" hR="7273" stAng="-4722533" swAng="6541615" />
+ <arcTo wR="6775" hR="9220" stAng="-2776035" swAng="7816140" />
+ <arcTo wR="5785" hR="7867" stAng="37501" swAng="6842000" />
+ <arcTo wR="6752" hR="9215" stAng="1347096" swAng="6910353" />
+ <arcTo wR="7720" hR="10543" stAng="3974558" swAng="4542661" />
+ <arcTo wR="4360" hR="5918" stAng="-16496525" swAng="8804134" />
+ <arcTo wR="4345" hR="5945" stAng="-14809710" swAng="9151131" />
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x23" y="yPos" />
+ </moveTo>
+ <arcTo wR="g26" hR="g26" stAng="0" swAng="21600000" />
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x24" y="g17" />
+ </moveTo>
+ <arcTo wR="g25" hR="g25" stAng="0" swAng="21600000" />
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x25" y="g24" />
+ </moveTo>
+ <arcTo wR="g12" hR="g12" stAng="0" swAng="21600000" />
+ <close />
+ </path>
+ <path w="43200" h="43200" fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="4693" y="26177" />
+ </moveTo>
+ <arcTo wR="4345" hR="5945" stAng="5204520" swAng="1585770" />
+ <moveTo>
+ <pt x="6928" y="34899" />
+ </moveTo>
+ <arcTo wR="4360" hR="5918" stAng="4416628" swAng="686848" />
+ <moveTo>
+ <pt x="16478" y="39090" />
+ </moveTo>
+ <arcTo wR="6752" hR="9215" stAng="8257449" swAng="844866" />
+ <moveTo>
+ <pt x="28827" y="34751" />
+ </moveTo>
+ <arcTo wR="6752" hR="9215" stAng="387196" swAng="959901" />
+ <moveTo>
+ <pt x="34129" y="22954" />
+ </moveTo>
+ <arcTo wR="5785" hR="7867" stAng="-4217541" swAng="4255042" />
+ <moveTo>
+ <pt x="41798" y="15354" />
+ </moveTo>
+ <arcTo wR="5333" hR="7273" stAng="1819082" swAng="1665090" />
+ <moveTo>
+ <pt x="38324" y="5426" />
+ </moveTo>
+ <arcTo wR="4857" hR="6595" stAng="-824660" swAng="891534" />
+ <moveTo>
+ <pt x="29078" y="3952" />
+ </moveTo>
+ <arcTo wR="4857" hR="6595" stAng="-8950887" swAng="1091722" />
+ <moveTo>
+ <pt x="22141" y="4720" />
+ </moveTo>
+ <arcTo wR="4365" hR="5945" stAng="-9809656" swAng="1061181" />
+ <moveTo>
+ <pt x="14000" y="5192" />
+ </moveTo>
+ <arcTo wR="6753" hR="9190" stAng="-4002417" swAng="739161" />
+ <moveTo>
+ <pt x="4127" y="15789" />
+ </moveTo>
+ <arcTo wR="6753" hR="9190" stAng="9459261" swAng="711490" />
+ </path>
+ </pathLst>
+
+ </cloudCallout>
+ <corner>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj1" fmla="*/ 100000 h ss" />
+ <gd name="maxAdj2" fmla="*/ 100000 w ss" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="x1" fmla="*/ ss a2 100000" />
+ <gd name="dy1" fmla="*/ ss a1 100000" />
+ <gd name="y1" fmla="+- b 0 dy1" />
+ <gd name="cx1" fmla="*/ x1 1 2" />
+ <gd name="cy1" fmla="+/ y1 b 2" />
+ <gd name="d" fmla="+- w 0 h" />
+ <gd name="it" fmla="?: d y1 t" />
+ <gd name="ir" fmla="?: d r x1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="cy1" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="cx1" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="it" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </corner>
+ <cornerTabs>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="md" fmla="mod w h 0" />
+ <gd name="dx" fmla="*/ 1 md 20" />
+
+ <gd name="y1" fmla="+- 0 b dx" />
+
+ <gd name="x1" fmla="+- 0 r dx" />
+
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd2">
+ <pos x="l" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="dx" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="dx" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="t" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="dx" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="t" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="dx" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="b" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="dx" t="dx" r="x1" b="y1" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="dx" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="dx" />
+ </lnTo>
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="dx" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="dx" />
+ </lnTo>
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="r" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </cornerTabs>
+ <cube>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 100000" />
+ <gd name="y1" fmla="*/ ss a 100000" />
+ <gd name="y4" fmla="+- b 0 y1" />
+ <gd name="y2" fmla="*/ y4 1 2" />
+ <gd name="y3" fmla="+/ y1 b 2" />
+ <gd name="x4" fmla="+- r 0 y1" />
+ <gd name="x2" fmla="*/ x4 1 2" />
+ <gd name="x3" fmla="+/ y1 r 2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="100000">
+ <pos x="l" y="y1" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y3" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y2" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="y1" r="x4" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+ <moveTo>
+ <pt x="x4" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="lightenLess" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="y1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="y1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <moveTo>
+ <pt x="x4" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ </path>
+ </pathLst>
+ </cube>
+ <curvedConnector2>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="wd2" y="t" />
+ <pt x="r" y="hd2" />
+ <pt x="r" y="b" />
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </curvedConnector2>
+ <curvedConnector3>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w adj1 100000" />
+ <gd name="x1" fmla="+/ l x2 2" />
+ <gd name="x3" fmla="+/ r x2 2" />
+ <gd name="y3" fmla="*/ h 3 4" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647">
+ <pos x="x2" y="vc" />
+ </ahXY>
+ </ahLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x1" y="t" />
+ <pt x="x2" y="hd4" />
+ <pt x="x2" y="vc" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x2" y="y3" />
+ <pt x="x3" y="b" />
+ <pt x="r" y="b" />
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </curvedConnector3>
+ <curvedConnector4>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w adj1 100000" />
+ <gd name="x1" fmla="+/ l x2 2" />
+ <gd name="x3" fmla="+/ r x2 2" />
+ <gd name="x4" fmla="+/ x2 x3 2" />
+ <gd name="x5" fmla="+/ x3 r 2" />
+ <gd name="y4" fmla="*/ h adj2 100000" />
+ <gd name="y1" fmla="+/ t y4 2" />
+ <gd name="y2" fmla="+/ t y1 2" />
+ <gd name="y3" fmla="+/ y1 y4 2" />
+ <gd name="y5" fmla="+/ b y4 2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647">
+ <pos x="x2" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="x3" y="y4" />
+ </ahXY>
+ </ahLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x1" y="t" />
+ <pt x="x2" y="y2" />
+ <pt x="x2" y="y1" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x2" y="y3" />
+ <pt x="x4" y="y4" />
+ <pt x="x3" y="y4" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x5" y="y4" />
+ <pt x="r" y="y5" />
+ <pt x="r" y="b" />
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </curvedConnector4>
+ <curvedConnector5>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 50000" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x3" fmla="*/ w adj1 100000" />
+ <gd name="x6" fmla="*/ w adj3 100000" />
+ <gd name="x1" fmla="+/ x3 x6 2" />
+ <gd name="x2" fmla="+/ l x3 2" />
+ <gd name="x4" fmla="+/ x3 x1 2" />
+ <gd name="x5" fmla="+/ x6 x1 2" />
+ <gd name="x7" fmla="+/ x6 r 2" />
+ <gd name="y4" fmla="*/ h adj2 100000" />
+ <gd name="y1" fmla="+/ t y4 2" />
+ <gd name="y2" fmla="+/ t y1 2" />
+ <gd name="y3" fmla="+/ y1 y4 2" />
+ <gd name="y5" fmla="+/ b y4 2" />
+ <gd name="y6" fmla="+/ y5 y4 2" />
+ <gd name="y7" fmla="+/ y5 b 2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647">
+ <pos x="x3" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="x1" y="y4" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="-2147483647" maxX="2147483647">
+ <pos x="x6" y="y5" />
+ </ahXY>
+ </ahLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x2" y="t" />
+ <pt x="x3" y="y2" />
+ <pt x="x3" y="y1" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x3" y="y3" />
+ <pt x="x4" y="y4" />
+ <pt x="x1" y="y4" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x5" y="y4" />
+ <pt x="x6" y="y6" />
+ <pt x="x6" y="y5" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x6" y="y7" />
+ <pt x="x7" y="b" />
+ <pt x="r" y="b" />
+ </cubicBezTo>
+ </path>
+ </pathLst>
+
+ </curvedConnector5>
+ <curvedDownArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 w ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="aw" fmla="*/ ss a2 100000" />
+
+ <gd name="q1" fmla="+/ th aw 4" />
+
+ <gd name="wR" fmla="+- wd2 0 q1" />
+
+ <gd name="q7" fmla="*/ wR 2 1" />
+
+ <gd name="q8" fmla="*/ q7 q7 1" />
+
+ <gd name="q9" fmla="*/ th th 1" />
+
+ <gd name="q10" fmla="+- q8 0 q9" />
+ <gd name="q11" fmla="sqrt q10" />
+ <gd name="idy" fmla="*/ q11 h q7" />
+ <gd name="maxAdj3" fmla="*/ 100000 idy ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="ah" fmla="*/ ss adj3 100000" />
+
+
+
+
+
+ <gd name="x3" fmla="+- wR th 0" />
+
+ <gd name="q2" fmla="*/ h h 1" />
+ <gd name="q3" fmla="*/ ah ah 1" />
+ <gd name="q4" fmla="+- q2 0 q3" />
+ <gd name="q5" fmla="sqrt q4" />
+ <gd name="dx" fmla="*/ q5 wR h" />
+ <gd name="x5" fmla="+- wR dx 0" />
+
+ <gd name="x7" fmla="+- x3 dx 0" />
+
+ <gd name="q6" fmla="+- aw 0 th" />
+ <gd name="dh" fmla="*/ q6 1 2" />
+
+ <gd name="x4" fmla="+- x5 0 dh" />
+
+ <gd name="x8" fmla="+- x7 dh 0" />
+
+ <gd name="aw2" fmla="*/ aw 1 2" />
+ <gd name="x6" fmla="+- r 0 aw2" />
+
+ <gd name="y1" fmla="+- b 0 ah" />
+ <gd name="swAng" fmla="at2 ah dx" />
+
+ <gd name="mswAng" fmla="+- 0 0 swAng" />
+ <gd name="iy" fmla="+- b 0 idy" />
+
+ <gd name="ix" fmla="+/ wR x3 2" />
+
+ <gd name="q12" fmla="*/ th 1 2" />
+ <gd name="dang2" fmla="at2 idy q12" />
+ <gd name="stAng" fmla="+- 3cd4 swAng 0" />
+ <gd name="stAng2" fmla="+- 3cd4 0 dang2" />
+ <gd name="swAng2" fmla="+- dang2 0 cd4" />
+ <gd name="swAng3" fmla="+- cd4 dang2 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="adj2">
+ <pos x="x7" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x4" y="b" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="y1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="ix" y="t" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="q12" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x4" y="y1" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x6" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x8" y="y1" />
+ </cxn>
+ </cxnLst>
+
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="x6" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y1" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="stAng" swAng="mswAng" />
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="3cd4" swAng="swAng" />
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <close />
+ </path>
+
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="ix" y="iy" />
+ </moveTo>
+ <arcTo wR="wR" hR="h" stAng="stAng2" swAng="swAng2" />
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="cd2" swAng="swAng3" />
+ <close />
+ </path>
+
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="ix" y="iy" />
+ </moveTo>
+ <arcTo wR="wR" hR="h" stAng="stAng2" swAng="swAng2" />
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="3cd4" swAng="swAng" />
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y1" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="stAng" swAng="mswAng" />
+ </path>
+ </pathLst>
+
+ </curvedDownArrow>
+ <curvedLeftArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 h ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="a1" fmla="pin 0 adj1 a2" />
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="aw" fmla="*/ ss a2 100000" />
+
+ <gd name="q1" fmla="+/ th aw 4" />
+
+ <gd name="hR" fmla="+- hd2 0 q1" />
+
+ <gd name="q7" fmla="*/ hR 2 1" />
+
+ <gd name="q8" fmla="*/ q7 q7 1" />
+
+ <gd name="q9" fmla="*/ th th 1" />
+
+ <gd name="q10" fmla="+- q8 0 q9" />
+ <gd name="q11" fmla="sqrt q10" />
+ <gd name="idx" fmla="*/ q11 w q7" />
+ <gd name="maxAdj3" fmla="*/ 100000 idx ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="ah" fmla="*/ ss a3 100000" />
+
+
+
+
+
+ <gd name="y3" fmla="+- hR th 0" />
+
+ <gd name="q2" fmla="*/ w w 1" />
+ <gd name="q3" fmla="*/ ah ah 1" />
+ <gd name="q4" fmla="+- q2 0 q3" />
+ <gd name="q5" fmla="sqrt q4" />
+ <gd name="dy" fmla="*/ q5 hR w" />
+ <gd name="y5" fmla="+- hR dy 0" />
+
+ <gd name="y7" fmla="+- y3 dy 0" />
+
+ <gd name="q6" fmla="+- aw 0 th" />
+ <gd name="dh" fmla="*/ q6 1 2" />
+
+ <gd name="y4" fmla="+- y5 0 dh" />
+
+ <gd name="y8" fmla="+- y7 dh 0" />
+
+ <gd name="aw2" fmla="*/ aw 1 2" />
+ <gd name="y6" fmla="+- b 0 aw2" />
+
+ <gd name="x1" fmla="+- l ah 0" />
+ <gd name="swAng" fmla="at2 ah dy" />
+
+ <gd name="mswAng" fmla="+- 0 0 swAng" />
+ <gd name="ix" fmla="+- l idx 0" />
+
+ <gd name="iy" fmla="+/ hR y3 2" />
+
+ <gd name="q12" fmla="*/ th 1 2" />
+ <gd name="dang2" fmla="at2 idx q12" />
+ <gd name="swAng2" fmla="+- dang2 0 swAng" />
+ <gd name="swAng3" fmla="+- swAng dang2 0" />
+ <gd name="stAng3" fmla="+- 0 0 dang2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="a2">
+ <pos x="x1" y="y5" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="r" y="y4" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="0" maxX="maxAdj3">
+ <pos x="x1" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd2">
+ <pos x="l" y="q12" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y4" />
+ </cxn>
+ <cxn ang="cd3">
+ <pos x="l" y="y6" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="y8" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="iy" />
+ </cxn>
+ </cxnLst>
+
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="y6" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y5" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="swAng" swAng="swAng2" />
+ <arcTo wR="w" hR="hR" stAng="stAng3" swAng="swAng3" />
+ <lnTo>
+ <pt x="x1" y="y8" />
+ </lnTo>
+ <close />
+ </path>
+
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="r" y="y3" />
+ </moveTo>
+ <arcTo wR="w" hR="hR" stAng="0" swAng="-5400000" />
+ <lnTo>
+ <pt x="l" y="t" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="3cd4" swAng="cd4" />
+ <close />
+ </path>
+
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="r" y="y3" />
+ </moveTo>
+ <arcTo wR="w" hR="hR" stAng="0" swAng="-5400000" />
+ <lnTo>
+ <pt x="l" y="t" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y3" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="0" swAng="swAng" />
+ <lnTo>
+ <pt x="x1" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y5" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="swAng" swAng="swAng2" />
+ </path>
+ </pathLst>
+
+ </curvedLeftArrow>
+ <curvedRightArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 h ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="a1" fmla="pin 0 adj1 a2" />
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="aw" fmla="*/ ss a2 100000" />
+
+ <gd name="q1" fmla="+/ th aw 4" />
+
+ <gd name="hR" fmla="+- hd2 0 q1" />
+
+ <gd name="q7" fmla="*/ hR 2 1" />
+
+ <gd name="q8" fmla="*/ q7 q7 1" />
+
+ <gd name="q9" fmla="*/ th th 1" />
+
+ <gd name="q10" fmla="+- q8 0 q9" />
+ <gd name="q11" fmla="sqrt q10" />
+ <gd name="idx" fmla="*/ q11 w q7" />
+ <gd name="maxAdj3" fmla="*/ 100000 idx ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="ah" fmla="*/ ss a3 100000" />
+
+
+
+
+
+ <gd name="y3" fmla="+- hR th 0" />
+
+ <gd name="q2" fmla="*/ w w 1" />
+ <gd name="q3" fmla="*/ ah ah 1" />
+ <gd name="q4" fmla="+- q2 0 q3" />
+ <gd name="q5" fmla="sqrt q4" />
+ <gd name="dy" fmla="*/ q5 hR w" />
+ <gd name="y5" fmla="+- hR dy 0" />
+
+ <gd name="y7" fmla="+- y3 dy 0" />
+
+ <gd name="q6" fmla="+- aw 0 th" />
+ <gd name="dh" fmla="*/ q6 1 2" />
+
+ <gd name="y4" fmla="+- y5 0 dh" />
+
+ <gd name="y8" fmla="+- y7 dh 0" />
+
+ <gd name="aw2" fmla="*/ aw 1 2" />
+ <gd name="y6" fmla="+- b 0 aw2" />
+
+ <gd name="x1" fmla="+- r 0 ah" />
+ <gd name="swAng" fmla="at2 ah dy" />
+
+ <gd name="stAng" fmla="+- cd2 0 swAng" />
+ <gd name="mswAng" fmla="+- 0 0 swAng" />
+ <gd name="ix" fmla="+- r 0 idx" />
+
+ <gd name="iy" fmla="+/ hR y3 2" />
+
+ <gd name="q12" fmla="*/ th 1 2" />
+ <gd name="dang2" fmla="at2 idx q12" />
+ <gd name="swAng2" fmla="+- dang2 0 cd4" />
+ <gd name="swAng3" fmla="+- cd4 dang2 0" />
+ <gd name="stAng3" fmla="+- cd2 0 dang2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="a2">
+ <pos x="x1" y="y5" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="r" y="y4" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="0" maxX="maxAdj3">
+ <pos x="x1" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd2">
+ <pos x="l" y="iy" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="y8" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y6" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x1" y="y4" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="q12" />
+ </cxn>
+ </cxnLst>
+
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="hR" />
+ </moveTo>
+ <arcTo wR="w" hR="hR" stAng="cd2" swAng="mswAng" />
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y7" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="stAng" swAng="swAng" />
+ <close />
+ </path>
+
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="r" y="th" />
+ </moveTo>
+ <arcTo wR="w" hR="hR" stAng="3cd4" swAng="swAng2" />
+ <arcTo wR="w" hR="hR" stAng="stAng3" swAng="swAng3" />
+ <close />
+ </path>
+
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="hR" />
+ </moveTo>
+ <arcTo wR="w" hR="hR" stAng="cd2" swAng="mswAng" />
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y7" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="stAng" swAng="swAng" />
+ <lnTo>
+ <pt x="l" y="hR" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="th" />
+ </lnTo>
+ <arcTo wR="w" hR="hR" stAng="3cd4" swAng="swAng2" />
+ </path>
+ </pathLst>
+
+ </curvedRightArrow>
+ <curvedUpArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 w ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="aw" fmla="*/ ss a2 100000" />
+
+ <gd name="q1" fmla="+/ th aw 4" />
+
+ <gd name="wR" fmla="+- wd2 0 q1" />
+
+ <gd name="q7" fmla="*/ wR 2 1" />
+
+ <gd name="q8" fmla="*/ q7 q7 1" />
+
+ <gd name="q9" fmla="*/ th th 1" />
+
+ <gd name="q10" fmla="+- q8 0 q9" />
+ <gd name="q11" fmla="sqrt q10" />
+ <gd name="idy" fmla="*/ q11 h q7" />
+ <gd name="maxAdj3" fmla="*/ 100000 idy ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="ah" fmla="*/ ss adj3 100000" />
+
+
+
+
+
+ <gd name="x3" fmla="+- wR th 0" />
+
+ <gd name="q2" fmla="*/ h h 1" />
+ <gd name="q3" fmla="*/ ah ah 1" />
+ <gd name="q4" fmla="+- q2 0 q3" />
+ <gd name="q5" fmla="sqrt q4" />
+ <gd name="dx" fmla="*/ q5 wR h" />
+ <gd name="x5" fmla="+- wR dx 0" />
+
+ <gd name="x7" fmla="+- x3 dx 0" />
+
+ <gd name="q6" fmla="+- aw 0 th" />
+ <gd name="dh" fmla="*/ q6 1 2" />
+
+ <gd name="x4" fmla="+- x5 0 dh" />
+
+ <gd name="x8" fmla="+- x7 dh 0" />
+
+ <gd name="aw2" fmla="*/ aw 1 2" />
+ <gd name="x6" fmla="+- r 0 aw2" />
+
+ <gd name="y1" fmla="+- t ah 0" />
+ <gd name="swAng" fmla="at2 ah dx" />
+
+ <gd name="mswAng" fmla="+- 0 0 swAng" />
+ <gd name="iy" fmla="+- t idy 0" />
+
+ <gd name="ix" fmla="+/ wR x3 2" />
+
+ <gd name="q12" fmla="*/ th 1 2" />
+ <gd name="dang2" fmla="at2 idy q12" />
+ <gd name="swAng2" fmla="+- dang2 0 swAng" />
+ <gd name="mswAng2" fmla="+- 0 0 swAng2" />
+ <gd name="stAng3" fmla="+- cd4 0 swAng" />
+ <gd name="swAng3" fmla="+- swAng dang2 0" />
+ <gd name="stAng2" fmla="+- cd4 0 dang2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="a2">
+ <pos x="x7" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x4" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="y1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x6" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x4" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="q12" y="t" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ix" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x8" y="y1" />
+ </cxn>
+ </cxnLst>
+
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="x6" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y1" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="stAng3" swAng="swAng3" />
+ <arcTo wR="wR" hR="h" stAng="stAng2" swAng="swAng2" />
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <close />
+ </path>
+
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="wR" y="b" />
+ </moveTo>
+ <arcTo wR="wR" hR="h" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="th" y="t" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="cd2" swAng="-5400000" />
+ <close />
+ </path>
+
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="ix" y="iy" />
+ </moveTo>
+ <arcTo wR="wR" hR="h" stAng="stAng2" swAng="swAng2" />
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y1" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="stAng3" swAng="swAng" />
+ <lnTo>
+ <pt x="wR" y="b" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="th" y="t" />
+ </lnTo>
+ <arcTo wR="wR" hR="h" stAng="cd2" swAng="-5400000" />
+ </path>
+ </pathLst>
+
+ </curvedUpArrow>
+ <decagon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="vf" fmla="val 105146" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="shd2" fmla="*/ hd2 vf 100000" />
+ <gd name="dx1" fmla="cos wd2 2160000" />
+ <gd name="dx2" fmla="cos wd2 4320000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="dy1" fmla="sin shd2 4320000" />
+ <gd name="dy2" fmla="sin shd2 2160000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc dy2 0" />
+ <gd name="y4" fmla="+- vc dy1 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x4" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="y4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x3" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y2" r="x4" b="y3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </decagon>
+ <diagStripe>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 100000" />
+ <gd name="x2" fmla="*/ w a 100000" />
+ <gd name="x1" fmla="*/ x2 1 2" />
+ <gd name="x3" fmla="+/ x2 r 2" />
+ <gd name="y2" fmla="*/ h a 100000" />
+ <gd name="y1" fmla="*/ y2 1 2" />
+ <gd name="y3" fmla="+/ y2 b 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="100000">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="hc" y="vc" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="x3" b="y3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </diagStripe>
+ <diamond>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="ir" fmla="*/ w 3 4" />
+ <gd name="ib" fmla="*/ h 3 4" />
+ </gdLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="wd4" t="hd4" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </diamond>
+ <dodecagon>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x1" fmla="*/ w 2894 21600" />
+ <gd name="x2" fmla="*/ w 7906 21600" />
+ <gd name="x3" fmla="*/ w 13694 21600" />
+ <gd name="x4" fmla="*/ w 18706 21600" />
+ <gd name="y1" fmla="*/ h 2894 21600" />
+ <gd name="y2" fmla="*/ h 7906 21600" />
+ <gd name="y3" fmla="*/ h 13694 21600" />
+ <gd name="y4" fmla="*/ h 18706 21600" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x4" y="y1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y3" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y1" r="x4" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y3" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </dodecagon>
+ <donut>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dr" fmla="*/ ss a 100000" />
+ <gd name="iwd2" fmla="+- wd2 0 dr" />
+ <gd name="ihd2" fmla="+- hd2 0 dr" />
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefR="adj" minR="0" maxR="50000">
+ <pos x="dr" y="vc" />
+ </ahPolar>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ <moveTo>
+ <pt x="dr" y="vc" />
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="cd2" swAng="-5400000" />
+ <arcTo wR="iwd2" hR="ihd2" stAng="cd4" swAng="-5400000" />
+ <arcTo wR="iwd2" hR="ihd2" stAng="0" swAng="-5400000" />
+ <arcTo wR="iwd2" hR="ihd2" stAng="3cd4" swAng="-5400000" />
+ <close />
+ </path>
+ </pathLst>
+
+ </donut>
+ <doubleWave>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 6250" />
+
+ <gd name="adj2" fmla="val 0" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 12500" />
+ <gd name="a2" fmla="pin -10000 adj2 10000" />
+ <gd name="y1" fmla="*/ h a1 100000" />
+
+ <gd name="dy2" fmla="*/ y1 10 3" />
+ <gd name="y2" fmla="+- y1 0 dy2" />
+
+ <gd name="y3" fmla="+- y1 dy2 0" />
+
+ <gd name="y4" fmla="+- b 0 y1" />
+
+ <gd name="y5" fmla="+- y4 0 dy2" />
+
+ <gd name="y6" fmla="+- y4 dy2 0" />
+
+ <gd name="dx1" fmla="*/ w a2 100000" />
+
+ <gd name="of2" fmla="*/ w a2 50000" />
+
+ <gd name="x1" fmla="abs dx1" />
+
+ <gd name="dx2" fmla="?: of2 0 of2" />
+ <gd name="x2" fmla="+- l 0 dx2" />
+
+ <gd name="dx8" fmla="?: of2 of2 0" />
+ <gd name="x8" fmla="+- r 0 dx8" />
+
+ <gd name="dx3" fmla="+/ dx2 x8 6" />
+ <gd name="x3" fmla="+- x2 dx3 0" />
+
+ <gd name="dx4" fmla="+/ dx2 x8 3" />
+ <gd name="x4" fmla="+- x2 dx4 0" />
+
+ <gd name="x5" fmla="+/ x2 x8 2" />
+
+ <gd name="x6" fmla="+- x5 dx3 0" />
+
+ <gd name="x7" fmla="+/ x6 x8 2" />
+
+ <gd name="x9" fmla="+- l dx8 0" />
+
+ <gd name="x15" fmla="+- r dx2 0" />
+
+ <gd name="x10" fmla="+- x9 dx3 0" />
+
+ <gd name="x11" fmla="+- x9 dx4 0" />
+
+ <gd name="x12" fmla="+/ x9 x15 2" />
+
+ <gd name="x13" fmla="+- x12 dx3 0" />
+
+ <gd name="x14" fmla="+/ x13 x15 2" />
+
+ <gd name="x16" fmla="+- r 0 x1" />
+
+ <gd name="xAdj" fmla="+- hc dx1 0" />
+ <gd name="il" fmla="max x2 x9" />
+ <gd name="ir" fmla="min x8 x15" />
+ <gd name="it" fmla="*/ h a1 50000" />
+ <gd name="ib" fmla="+- b 0 it" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="12500">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="-10000" maxX="10000">
+ <pos x="xAdj" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="x12" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x5" y="y4" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x16" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x2" y="y1" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x3" y="y2" />
+ <pt x="x4" y="y3" />
+ <pt x="x5" y="y1" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x6" y="y2" />
+ <pt x="x7" y="y3" />
+ <pt x="x8" y="y1" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="x15" y="y4" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="x14" y="y6" />
+ <pt x="x13" y="y5" />
+ <pt x="x12" y="y4" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x11" y="y6" />
+ <pt x="x10" y="y5" />
+ <pt x="x9" y="y4" />
+ </cubicBezTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </doubleWave>
+ <downArrow>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 100000 h ss" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="dy1" fmla="*/ ss a2 100000" />
+ <gd name="y1" fmla="+- b 0 dy1" />
+ <gd name="dx1" fmla="*/ w a1 200000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc dx1 0" />
+ <gd name="dy2" fmla="*/ x1 dy1 wd2" />
+ <gd name="y2" fmla="+- y1 dy2 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="100000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="l" y="y1" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y1" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y1" />
+ </cxn>
+ </cxnLst>
+ <rect l="x1" t="t" r="x2" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </downArrow>
+ <downArrowCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 64977" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 w ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ 100000 h ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q2" fmla="*/ a3 ss h" />
+
+ <gd name="maxAdj4" fmla="+- 100000 0 q2" />
+
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+ <gd name="dx1" fmla="*/ ss a2 100000" />
+
+ <gd name="dx2" fmla="*/ ss a1 200000" />
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="dy3" fmla="*/ ss a3 100000" />
+
+ <gd name="y3" fmla="+- b 0 dy3" />
+ <gd name="y2" fmla="*/ h a4 100000" />
+
+ <gd name="y1" fmla="*/ y2 1 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="x2" y="y3" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x1" y="b" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="y3" />
+ </ahXY>
+ <ahXY gdRefY="adj4" minY="0" maxY="maxAdj4">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y1" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </downArrowCallout>
+ <ellipse>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+ </ellipse>
+ <ellipseRibbon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 12500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 25000 adj2 75000" />
+ <gd name="q10" fmla="+- 100000 0 a1" />
+ <gd name="q11" fmla="*/ q10 1 2" />
+ <gd name="q12" fmla="+- a1 0 q11" />
+ <gd name="minAdj3" fmla="max 0 q12" />
+ <gd name="a3" fmla="pin minAdj3 adj3 a1" />
+
+
+ <gd name="dx2" fmla="*/ w a2 200000" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+
+ <gd name="x3" fmla="+- x2 wd8 0" />
+
+ <gd name="x4" fmla="+- r 0 x3" />
+
+ <gd name="x5" fmla="+- r 0 x2" />
+
+ <gd name="x6" fmla="+- r 0 wd8" />
+
+ <gd name="dy1" fmla="*/ h a3 100000" />
+
+ <gd name="f1" fmla="*/ 4 dy1 w" />
+
+ <gd name="q1" fmla="*/ x3 x3 w" />
+ <gd name="q2" fmla="+- x3 0 q1" />
+ <gd name="y1" fmla="*/ f1 q2 1" />
+
+ <gd name="cx1" fmla="*/ x3 1 2" />
+
+ <gd name="cy1" fmla="*/ f1 cx1 1" />
+
+ <gd name="cx2" fmla="+- r 0 cx1" />
+
+
+
+ <gd name="q1" fmla="*/ h a1 100000" />
+
+ <gd name="dy3" fmla="+- q1 0 dy1" />
+
+ <gd name="q3" fmla="*/ x2 x2 w" />
+ <gd name="q4" fmla="+- x2 0 q3" />
+ <gd name="q5" fmla="*/ f1 q4 1" />
+ <gd name="y3" fmla="+- q5 dy3 0" />
+
+
+
+ <gd name="q6" fmla="+- dy1 dy3 y3" />
+ <gd name="q7" fmla="+- q6 dy1 0" />
+ <gd name="cy3" fmla="+- q7 dy3 0" />
+
+ <gd name="rh" fmla="+- b 0 q1" />
+
+ <gd name="q8" fmla="*/ dy1 14 16" />
+ <gd name="y2" fmla="+/ q8 rh 2" />
+
+
+ <gd name="y5" fmla="+- q5 rh 0" />
+
+ <gd name="y6" fmla="+- y3 rh 0" />
+
+ <gd name="cx4" fmla="*/ x2 1 2" />
+
+ <gd name="q9" fmla="*/ f1 cx4 1" />
+ <gd name="cy4" fmla="+- q9 rh 0" />
+
+ <gd name="cx5" fmla="+- r 0 cx4" />
+
+
+
+
+
+ <gd name="cy6" fmla="+- cy3 rh 0" />
+
+ <gd name="y7" fmla="+- y1 dy3 0" />
+ <gd name="cy7" fmla="+- q1 q1 y7" />
+ <gd name="y8" fmla="+- b 0 dy1" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="hc" y="q1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="25000" maxX="75000">
+ <pos x="x2" y="b" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="minAdj3" maxY="a1">
+ <pos x="l" y="y8" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="q1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd8" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="y2" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="q1" r="x5" b="y6" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <quadBezTo>
+ <pt x="cx1" y="cy1" />
+ <pt x="x3" y="y1" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy3" />
+ <pt x="x5" y="y3" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx2" y="cy1" />
+ <pt x="r" y="t" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="rh" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx5" y="cy4" />
+ <pt x="x5" y="y5" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x5" y="y6" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy6" />
+ <pt x="x2" y="y6" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x2" y="y5" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx4" y="cy4" />
+ <pt x="l" y="rh" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="wd8" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="x3" y="y7" />
+ </moveTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy3" />
+ <pt x="x5" y="y3" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y7" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy7" />
+ <pt x="x3" y="y7" />
+ </quadBezTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <quadBezTo>
+ <pt x="cx1" y="cy1" />
+ <pt x="x3" y="y1" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy3" />
+ <pt x="x5" y="y3" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx2" y="cy1" />
+ <pt x="r" y="t" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="rh" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx5" y="cy4" />
+ <pt x="x5" y="y5" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x5" y="y6" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy6" />
+ <pt x="x2" y="y6" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x2" y="y5" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx4" y="cy4" />
+ <pt x="l" y="rh" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="wd8" y="y2" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x2" y="y5" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <moveTo>
+ <pt x="x5" y="y3" />
+ </moveTo>
+ <lnTo>
+ <pt x="x5" y="y5" />
+ </lnTo>
+ <moveTo>
+ <pt x="x3" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x3" y="y7" />
+ </lnTo>
+ <moveTo>
+ <pt x="x4" y="y7" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </ellipseRibbon>
+ <ellipseRibbon2>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 12500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 25000 adj2 75000" />
+ <gd name="q10" fmla="+- 100000 0 a1" />
+ <gd name="q11" fmla="*/ q10 1 2" />
+ <gd name="q12" fmla="+- a1 0 q11" />
+ <gd name="minAdj3" fmla="max 0 q12" />
+ <gd name="a3" fmla="pin minAdj3 adj3 a1" />
+ <gd name="dx2" fmla="*/ w a2 200000" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+
+ <gd name="x3" fmla="+- x2 wd8 0" />
+
+ <gd name="x4" fmla="+- r 0 x3" />
+
+ <gd name="x5" fmla="+- r 0 x2" />
+
+ <gd name="x6" fmla="+- r 0 wd8" />
+
+ <gd name="dy1" fmla="*/ h a3 100000" />
+
+ <gd name="f1" fmla="*/ 4 dy1 w" />
+
+ <gd name="q1" fmla="*/ x3 x3 w" />
+ <gd name="q2" fmla="+- x3 0 q1" />
+ <gd name="u1" fmla="*/ f1 q2 1" />
+
+ <gd name="y1" fmla="+- b 0 u1" />
+ <gd name="cx1" fmla="*/ x3 1 2" />
+
+ <gd name="cu1" fmla="*/ f1 cx1 1" />
+
+ <gd name="cy1" fmla="+- b 0 cu1" />
+ <gd name="cx2" fmla="+- r 0 cx1" />
+
+
+
+ <gd name="q1" fmla="*/ h a1 100000" />
+
+ <gd name="dy3" fmla="+- q1 0 dy1" />
+
+ <gd name="q3" fmla="*/ x2 x2 w" />
+ <gd name="q4" fmla="+- x2 0 q3" />
+ <gd name="q5" fmla="*/ f1 q4 1" />
+ <gd name="u3" fmla="+- q5 dy3 0" />
+
+ <gd name="y3" fmla="+- b 0 u3" />
+
+
+ <gd name="q6" fmla="+- dy1 dy3 u3" />
+ <gd name="q7" fmla="+- q6 dy1 0" />
+ <gd name="cu3" fmla="+- q7 dy3 0" />
+
+ <gd name="cy3" fmla="+- b 0 cu3" />
+ <gd name="rh" fmla="+- b 0 q1" />
+
+ <gd name="q8" fmla="*/ dy1 14 16" />
+ <gd name="u2" fmla="+/ q8 rh 2" />
+
+ <gd name="y2" fmla="+- b 0 u2" />
+
+ <gd name="u5" fmla="+- q5 rh 0" />
+
+ <gd name="y5" fmla="+- b 0 u5" />
+ <gd name="u6" fmla="+- u3 rh 0" />
+
+ <gd name="y6" fmla="+- b 0 u6" />
+ <gd name="cx4" fmla="*/ x2 1 2" />
+
+ <gd name="q9" fmla="*/ f1 cx4 1" />
+ <gd name="cu4" fmla="+- q9 rh 0" />
+
+ <gd name="cy4" fmla="+- b 0 cu4" />
+ <gd name="cx5" fmla="+- r 0 cx4" />
+
+
+
+
+
+ <gd name="cu6" fmla="+- cu3 rh 0" />
+
+ <gd name="cy6" fmla="+- b 0 cu6" />
+ <gd name="u7" fmla="+- u1 dy3 0" />
+ <gd name="y7" fmla="+- b 0 u7" />
+ <gd name="cu7" fmla="+- q1 q1 u7" />
+ <gd name="cy7" fmla="+- b 0 cu7" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="hc" y="rh" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="25000" maxX="100000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="minAdj3" maxY="a1">
+ <pos x="l" y="dy1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd8" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="rh" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="y2" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="y6" r="x5" b="rh" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <quadBezTo>
+ <pt x="cx1" y="cy1" />
+ <pt x="x3" y="y1" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy3" />
+ <pt x="x5" y="y3" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx2" y="cy1" />
+ <pt x="r" y="b" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="q1" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx5" y="cy4" />
+ <pt x="x5" y="y5" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x5" y="y6" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy6" />
+ <pt x="x2" y="y6" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x2" y="y5" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx4" y="cy4" />
+ <pt x="l" y="q1" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="wd8" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="x3" y="y7" />
+ </moveTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy3" />
+ <pt x="x5" y="y3" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y7" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy7" />
+ <pt x="x3" y="y7" />
+ </quadBezTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="wd8" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="q1" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx4" y="cy4" />
+ <pt x="x2" y="y5" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x2" y="y6" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy6" />
+ <pt x="x5" y="y6" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x5" y="y5" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx5" y="cy4" />
+ <pt x="r" y="q1" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx2" y="cy1" />
+ <pt x="x4" y="y1" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x5" y="y3" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="hc" y="cy3" />
+ <pt x="x2" y="y3" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="cx1" y="cy1" />
+ <pt x="l" y="b" />
+ </quadBezTo>
+ <close />
+ <moveTo>
+ <pt x="x2" y="y3" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y5" />
+ </lnTo>
+ <moveTo>
+ <pt x="x5" y="y5" />
+ </moveTo>
+ <lnTo>
+ <pt x="x5" y="y3" />
+ </lnTo>
+ <moveTo>
+ <pt x="x3" y="y7" />
+ </moveTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <moveTo>
+ <pt x="x4" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="y7" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </ellipseRibbon2>
+ <flowChartAlternateProcess>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="+- r 0 ssd6" />
+ <gd name="y2" fmla="+- b 0 ssd6" />
+ <gd name="il" fmla="*/ ssd6 29289 100000" />
+
+
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 il" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="ssd6" />
+ </moveTo>
+ <arcTo wR="ssd6" hR="ssd6" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <arcTo wR="ssd6" hR="ssd6" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <arcTo wR="ssd6" hR="ssd6" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="ssd6" y="b" />
+ </lnTo>
+ <arcTo wR="ssd6" hR="ssd6" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartAlternateProcess>
+ <flowChartCollate>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="ir" fmla="*/ w 3 4" />
+ <gd name="ib" fmla="*/ h 3 4" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd4" t="hd4" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="2" h="2">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="2" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="2" y="2" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="2" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartCollate>
+ <flowChartConnector>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartConnector>
+ <flowChartDecision>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="ir" fmla="*/ w 3 4" />
+ <gd name="ib" fmla="*/ h 3 4" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd4" t="hd4" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="2" h="2">
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="2" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartDecision>
+ <flowChartDelay>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartDelay>
+ <flowChartDisplay>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 5 6" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd6" t="t" r="x2" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="6" h="6">
+ <moveTo>
+ <pt x="0" y="3" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="5" y="0" />
+ </lnTo>
+ <arcTo wR="1" hR="3" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="1" y="6" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartDisplay>
+ <flowChartDocument>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h 17322 21600" />
+ <gd name="y2" fmla="*/ h 20172 21600" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="y1" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="21600" h="21600">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="21600" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="17322" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="10800" y="17322" />
+ <pt x="10800" y="23922" />
+ <pt x="0" y="20172" />
+ </cubicBezTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartDocument>
+ <flowChartExtract>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 3 4" />
+ </gdLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd4" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd4" t="vc" r="x2" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="2" h="2">
+ <moveTo>
+ <pt x="0" y="2" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="2" y="2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartExtract>
+ <flowChartInputOutput>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x3" fmla="*/ w 2 5" />
+ <gd name="x4" fmla="*/ w 3 5" />
+ <gd name="x5" fmla="*/ w 4 5" />
+ <gd name="x6" fmla="*/ w 9 10" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x4" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd10" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd5" t="t" r="x5" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="5" h="5">
+ <moveTo>
+ <pt x="0" y="5" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="5" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="4" y="5" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartInputOutput>
+ <flowChartInternalStorage>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd8" t="hd8" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false" w="1" h="1">
+
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="1" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false" w="8" h="8">
+
+ <moveTo>
+ <pt x="1" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="8" />
+ </lnTo>
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <lnTo>
+ <pt x="8" y="1" />
+ </lnTo>
+ </path>
+ <path fill="none" w="1" h="1">
+
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartInternalStorage>
+ <flowChartMagneticDisk>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y3" fmla="*/ h 5 6" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="hd3" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="hd3" r="r" b="y3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false" w="6" h="6">
+
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <arcTo wR="3" hR="1" stAng="cd2" swAng="cd2" />
+ <lnTo>
+ <pt x="6" y="5" />
+ </lnTo>
+ <arcTo wR="3" hR="1" stAng="0" swAng="cd2" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false" w="6" h="6">
+
+ <moveTo>
+ <pt x="6" y="1" />
+ </moveTo>
+ <arcTo wR="3" hR="1" stAng="0" swAng="cd2" />
+ </path>
+ <path fill="none" w="6" h="6">
+
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <arcTo wR="3" hR="1" stAng="cd2" swAng="cd2" />
+ <lnTo>
+ <pt x="6" y="5" />
+ </lnTo>
+ <arcTo wR="3" hR="1" stAng="0" swAng="cd2" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartMagneticDisk>
+ <flowChartMagneticDrum>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 2 3" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd6" t="t" r="x2" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false" w="6" h="6">
+
+ <moveTo>
+ <pt x="1" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="5" y="0" />
+ </lnTo>
+ <arcTo wR="1" hR="3" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="1" y="6" />
+ </lnTo>
+ <arcTo wR="1" hR="3" stAng="cd4" swAng="cd2" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false" w="6" h="6">
+
+ <moveTo>
+ <pt x="5" y="6" />
+ </moveTo>
+ <arcTo wR="1" hR="3" stAng="cd4" swAng="cd2" />
+ </path>
+ <path fill="none" w="6" h="6">
+
+ <moveTo>
+ <pt x="1" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="5" y="0" />
+ </lnTo>
+ <arcTo wR="1" hR="3" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="1" y="6" />
+ </lnTo>
+ <arcTo wR="1" hR="3" stAng="cd4" swAng="cd2" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartMagneticDrum>
+ <flowChartMagneticTape>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ <gd name="ang1" fmla="at2 w h" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="hc" y="b" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="ang1" />
+ <lnTo>
+ <pt x="r" y="ib" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartMagneticTape>
+ <flowChartManualInput>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="hd10" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="hd5" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="5" h="5">
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <lnTo>
+ <pt x="5" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="5" y="5" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="5" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartManualInput>
+ <flowChartManualOperation>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x3" fmla="*/ w 4 5" />
+ <gd name="x4" fmla="*/ w 9 10" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd10" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd5" t="t" r="x3" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="5" h="5">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="5" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="4" y="5" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="5" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartManualOperation>
+ <flowChartMerge>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 3 4" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd4" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd4" t="t" r="x2" b="vc" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="2" h="2">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="2" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartMerge>
+ <flowChartMultidocument>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y2" fmla="*/ h 3675 21600" />
+ <gd name="y8" fmla="*/ h 20782 21600" />
+ <gd name="x3" fmla="*/ w 9298 21600" />
+ <gd name="x4" fmla="*/ w 12286 21600" />
+ <gd name="x5" fmla="*/ w 18595 21600" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x4" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y8" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="y2" r="x5" b="y8" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false" w="21600" h="21600">
+
+ <moveTo>
+ <pt x="0" y="20782" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="9298" y="23542" />
+ <pt x="9298" y="18022" />
+ <pt x="18595" y="18022" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="18595" y="3675" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="3675" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="1532" y="3675" />
+ </moveTo>
+ <lnTo>
+ <pt x="1532" y="1815" />
+ </lnTo>
+ <lnTo>
+ <pt x="20000" y="1815" />
+ </lnTo>
+ <lnTo>
+ <pt x="20000" y="16252" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="19298" y="16252" />
+ <pt x="18595" y="16352" />
+ <pt x="18595" y="16352" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="18595" y="3675" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="2972" y="1815" />
+ </moveTo>
+ <lnTo>
+ <pt x="2972" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="14392" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="20800" y="14392" />
+ <pt x="20000" y="14467" />
+ <pt x="20000" y="14467" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="20000" y="1815" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false" w="21600" h="21600">
+
+ <moveTo>
+ <pt x="0" y="3675" />
+ </moveTo>
+ <lnTo>
+ <pt x="18595" y="3675" />
+ </lnTo>
+ <lnTo>
+ <pt x="18595" y="18022" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="9298" y="18022" />
+ <pt x="9298" y="23542" />
+ <pt x="0" y="20782" />
+ </cubicBezTo>
+ <close />
+ <moveTo>
+ <pt x="1532" y="3675" />
+ </moveTo>
+ <lnTo>
+ <pt x="1532" y="1815" />
+ </lnTo>
+ <lnTo>
+ <pt x="20000" y="1815" />
+ </lnTo>
+ <lnTo>
+ <pt x="20000" y="16252" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="19298" y="16252" />
+ <pt x="18595" y="16352" />
+ <pt x="18595" y="16352" />
+ </cubicBezTo>
+ <moveTo>
+ <pt x="2972" y="1815" />
+ </moveTo>
+ <lnTo>
+ <pt x="2972" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="14392" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="20800" y="14392" />
+ <pt x="20000" y="14467" />
+ <pt x="20000" y="14467" />
+ </cubicBezTo>
+ </path>
+ <path stroke="false" fill="none" w="21600" h="21600">
+
+ <moveTo>
+ <pt x="0" y="20782" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="9298" y="23542" />
+ <pt x="9298" y="18022" />
+ <pt x="18595" y="18022" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="18595" y="16352" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="18595" y="16352" />
+ <pt x="19298" y="16252" />
+ <pt x="20000" y="16252" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="20000" y="14467" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="20000" y="14467" />
+ <pt x="20800" y="14392" />
+ <pt x="21600" y="14392" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="21600" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="2972" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="2972" y="1815" />
+ </lnTo>
+ <lnTo>
+ <pt x="1532" y="1815" />
+ </lnTo>
+ <lnTo>
+ <pt x="1532" y="3675" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="3675" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartMultidocument>
+ <flowChartOfflineStorage>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x4" fmla="*/ w 3 4" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x4" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd4" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd4" t="t" r="x4" b="vc" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false" w="2" h="2">
+
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="2" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false" w="5" h="5">
+
+ <moveTo>
+ <pt x="2" y="4" />
+ </moveTo>
+ <lnTo>
+ <pt x="3" y="4" />
+ </lnTo>
+ </path>
+ <path fill="none" extrusionOk="true" w="2" h="2">
+
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="2" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartOfflineStorage>
+ <flowChartOffpageConnector>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y1" fmla="*/ h 4 5" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="y1" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="10" h="10">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="10" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="8" />
+ </lnTo>
+ <lnTo>
+ <pt x="5" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="8" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartOffpageConnector>
+ <flowChartOnlineStorage>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 5 6" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd6" t="t" r="x2" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="6" h="6">
+ <moveTo>
+ <pt x="1" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="6" y="0" />
+ </lnTo>
+ <arcTo wR="1" hR="3" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="1" y="6" />
+ </lnTo>
+ <arcTo wR="1" hR="3" stAng="cd4" swAng="cd2" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartOnlineStorage>
+ <flowChartOr>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="hc" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ </path>
+ <path fill="none">
+
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartOr>
+ <flowChartPredefinedProcess>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 7 8" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd8" t="t" r="x2" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false" w="1" h="1">
+
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="1" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false" w="8" h="8">
+
+ <moveTo>
+ <pt x="1" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="8" />
+ </lnTo>
+ <moveTo>
+ <pt x="7" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="7" y="8" />
+ </lnTo>
+ </path>
+ <path fill="none" w="1" h="1">
+
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartPredefinedProcess>
+ <flowChartPreparation>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 4 5" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd5" t="t" r="x2" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="10" h="10">
+ <moveTo>
+ <pt x="0" y="5" />
+ </moveTo>
+ <lnTo>
+ <pt x="2" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="8" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="10" y="5" />
+ </lnTo>
+ <lnTo>
+ <pt x="8" y="10" />
+ </lnTo>
+ <lnTo>
+ <pt x="2" y="10" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartPreparation>
+ <flowChartProcess>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="1" h="1">
+ <moveTo>
+ <pt x="0" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartProcess>
+ <flowChartPunchedCard>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="hd5" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="5" h="5">
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="5" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="5" y="5" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="5" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartPunchedCard>
+ <flowChartPunchedTape>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="y2" fmla="*/ h 9 10" />
+ <gd name="ib" fmla="*/ h 4 5" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="hd10" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="hd5" r="r" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="20" h="20">
+ <moveTo>
+ <pt x="0" y="2" />
+ </moveTo>
+ <arcTo wR="5" hR="2" stAng="cd2" swAng="-10800000" />
+ <arcTo wR="5" hR="2" stAng="cd2" swAng="cd2" />
+ <lnTo>
+ <pt x="20" y="18" />
+ </lnTo>
+ <arcTo wR="5" hR="2" stAng="0" swAng="-10800000" />
+ <arcTo wR="5" hR="2" stAng="0" swAng="cd2" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartPunchedTape>
+ <flowChartSort>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="ir" fmla="*/ w 3 4" />
+ <gd name="ib" fmla="*/ h 3 4" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="wd4" t="hd4" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false" w="2" h="2">
+
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="2" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false" w="2" h="2">
+
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <lnTo>
+ <pt x="2" y="1" />
+ </lnTo>
+ </path>
+ <path fill="none" w="2" h="2">
+
+ <moveTo>
+ <pt x="0" y="1" />
+ </moveTo>
+ <lnTo>
+ <pt x="1" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="2" y="1" />
+ </lnTo>
+ <lnTo>
+ <pt x="1" y="2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartSort>
+ <flowChartSummingJunction>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="il" y="it" />
+ </moveTo>
+ <lnTo>
+ <pt x="ir" y="ib" />
+ </lnTo>
+ <moveTo>
+ <pt x="ir" y="it" />
+ </moveTo>
+ <lnTo>
+ <pt x="il" y="ib" />
+ </lnTo>
+ </path>
+ <path fill="none">
+
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartSummingJunction>
+ <flowChartTerminator>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="il" fmla="*/ w 1018 21600" />
+ <gd name="ir" fmla="*/ w 20582 21600" />
+ <gd name="it" fmla="*/ h 3163 21600" />
+ <gd name="ib" fmla="*/ h 18437 21600" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="21600" h="21600">
+ <moveTo>
+ <pt x="3475" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="18125" y="0" />
+ </lnTo>
+ <arcTo wR="3475" hR="10800" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="3475" y="21600" />
+ </lnTo>
+ <arcTo wR="3475" hR="10800" stAng="cd4" swAng="cd2" />
+ <close />
+ </path>
+ </pathLst>
+
+ </flowChartTerminator>
+ <foldedCorner>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 16667" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dy2" fmla="*/ ss a 100000" />
+ <gd name="dy1" fmla="*/ dy2 1 5" />
+ <gd name="x1" fmla="+- r 0 dy2" />
+ <gd name="x2" fmla="+- x1 dy1 0" />
+ <gd name="y2" fmla="+- b 0 dy2" />
+ <gd name="y1" fmla="+- y2 dy1 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x1" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+ <moveTo>
+ <pt x="x1" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </foldedCorner>
+ <frame>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 12500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="x1" fmla="*/ ss a1 100000" />
+
+ <gd name="x4" fmla="+- r 0 x1" />
+
+
+
+ <gd name="y4" fmla="+- b 0 x1" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="x1" r="x4" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x1" y="x1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="x1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </frame>
+ <funnel>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="d" fmla="*/ ss 1 20" />
+
+
+ <gd name="rw2" fmla="+- wd2 0 d" />
+
+ <gd name="rh2" fmla="+- hd4 0 d" />
+
+
+
+ <gd name="t1" fmla="cos wd2 480000" />
+
+ <gd name="t2" fmla="sin hd4 480000" />
+
+ <gd name="da" fmla="at2 t1 t2" />
+
+
+ <gd name="2da" fmla="*/ da 2 1" />
+ <gd name="stAng1" fmla="+- cd2 0 da" />
+ <gd name="swAng1" fmla="+- cd2 2da 0" />
+
+
+ <gd name="swAng3" fmla="+- cd2 0 2da" />
+
+
+ <gd name="rw3" fmla="*/ wd2 1 4" />
+ <gd name="rh3" fmla="*/ hd4 1 4" />
+
+
+ <gd name="ct1" fmla="cos hd4 stAng1" />
+ <gd name="st1" fmla="sin wd2 stAng1" />
+ <gd name="m1" fmla="mod ct1 st1 0" />
+ <gd name="n1" fmla="*/ wd2 hd4 m1" />
+ <gd name="dx1" fmla="cos n1 stAng1" />
+ <gd name="dy1" fmla="sin n1 stAng1" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- hd4 dy1 0" />
+
+
+ <gd name="ct3" fmla="cos rh3 da" />
+ <gd name="st3" fmla="sin rw3 da" />
+ <gd name="m3" fmla="mod ct3 st3 0" />
+ <gd name="n3" fmla="*/ rw3 rh3 m3" />
+ <gd name="dx3" fmla="cos n3 da" />
+ <gd name="dy3" fmla="sin n3 da" />
+ <gd name="x3" fmla="+- hc dx3 0" />
+ <gd name="vc3" fmla="+- b 0 rh3" />
+ <gd name="y2" fmla="+- vc3 dy3 0" />
+
+
+ <gd name="x2" fmla="+- wd2 0 rw2" />
+
+ <gd name="cd" fmla="*/ cd2 2 1" />
+ </gdLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <arcTo hR="hd4" wR="wd2" stAng="stAng1" swAng="swAng1" />
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <arcTo hR="rh3" wR="rw3" stAng="da" swAng="swAng3" />
+ <close />
+ <moveTo>
+ <pt x="x2" y="hd4" />
+ </moveTo>
+ <arcTo hR="rh2" wR="rw2" stAng="cd2" swAng="-21600000" />
+ <close />
+ </path>
+ </pathLst>
+
+ </funnel>
+ <gear6>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 15000" />
+
+ <gd name="adj2" fmla="val 3526" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+
+
+
+ <gd name="a1" fmla="pin 0 adj1 20000" />
+ <gd name="a2" fmla="pin 0 adj2 5358" />
+
+
+ <gd name="th" fmla="*/ ss a1 100000" />
+ <gd name="lFD" fmla="*/ ss a2 100000" />
+
+ <gd name="th2" fmla="*/ th 1 2" />
+ <gd name="l2" fmla="*/ lFD 1 2" />
+ <gd name="l3" fmla="+- th2 l2 0" />
+
+
+ <gd name="rh" fmla="+- hd2 0 th" />
+ <gd name="rw" fmla="+- wd2 0 th" />
+
+
+ <gd name="dr" fmla="+- rw 0 rh" />
+ <gd name="maxr" fmla="?: dr rh rw" />
+ <gd name="ha" fmla="at2 maxr l3" />
+
+
+ <gd name="aA1" fmla="+- 19800000 0 ha" />
+ <gd name="aD1" fmla="+- 19800000 ha 0" />
+
+
+ <gd name="ta11" fmla="cos rw aA1" />
+ <gd name="ta12" fmla="sin rh aA1" />
+ <gd name="bA1" fmla="at2 ta11 ta12" />
+
+ <gd name="cta1" fmla="cos rh bA1" />
+ <gd name="sta1" fmla="sin rw bA1" />
+ <gd name="ma1" fmla="mod cta1 sta1 0" />
+ <gd name="na1" fmla="*/ rw rh ma1" />
+ <gd name="dxa1" fmla="cos na1 bA1" />
+ <gd name="dya1" fmla="sin na1 bA1" />
+ <gd name="xA1" fmla="+- hc dxa1 0" />
+ <gd name="yA1" fmla="+- vc dya1 0" />
+
+
+ <gd name="td11" fmla="cos rw aD1" />
+ <gd name="td12" fmla="sin rh aD1" />
+ <gd name="bD1" fmla="at2 td11 td12" />
+
+ <gd name="ctd1" fmla="cos rh bD1" />
+ <gd name="std1" fmla="sin rw bD1" />
+ <gd name="md1" fmla="mod ctd1 std1 0" />
+ <gd name="nd1" fmla="*/ rw rh md1" />
+ <gd name="dxd1" fmla="cos nd1 bD1" />
+ <gd name="dyd1" fmla="sin nd1 bD1" />
+ <gd name="xD1" fmla="+- hc dxd1 0" />
+ <gd name="yD1" fmla="+- vc dyd1 0" />
+
+
+ <gd name="xAD1" fmla="+- xA1 0 xD1" />
+ <gd name="yAD1" fmla="+- yA1 0 yD1" />
+ <gd name="lAD1" fmla="mod xAD1 yAD1 0" />
+ <gd name="a1" fmla="at2 yAD1 xAD1" />
+
+
+ <gd name="dxF1" fmla="sin lFD a1" />
+ <gd name="dyF1" fmla="cos lFD a1" />
+ <gd name="xF1" fmla="+- xD1 dxF1 0" />
+ <gd name="yF1" fmla="+- yD1 dyF1 0" />
+ <gd name="xE1" fmla="+- xA1 0 dxF1" />
+ <gd name="yE1" fmla="+- yA1 0 dyF1" />
+
+
+ <gd name="yC1t" fmla="sin th a1" />
+ <gd name="xC1t" fmla="cos th a1" />
+ <gd name="yC1" fmla="+- yF1 yC1t 0" />
+ <gd name="xC1" fmla="+- xF1 0 xC1t" />
+
+
+ <gd name="yB1" fmla="+- yE1 yC1t 0" />
+ <gd name="xB1" fmla="+- xE1 0 xC1t" />
+
+
+ <gd name="aD6" fmla="+- 3cd4 ha 0" />
+
+
+ <gd name="td61" fmla="cos rw aD6" />
+ <gd name="td62" fmla="sin rh aD6" />
+ <gd name="bD6" fmla="at2 td61 td62" />
+
+ <gd name="ctd6" fmla="cos rh bD6" />
+ <gd name="std6" fmla="sin rw bD6" />
+ <gd name="md6" fmla="mod ctd6 std6 0" />
+ <gd name="nd6" fmla="*/ rw rh md6" />
+ <gd name="dxd6" fmla="cos nd6 bD6" />
+ <gd name="dyd6" fmla="sin nd6 bD6" />
+ <gd name="xD6" fmla="+- hc dxd6 0" />
+ <gd name="yD6" fmla="+- vc dyd6 0" />
+
+
+ <gd name="xA6" fmla="+- hc 0 dxd6" />
+
+
+ <gd name="xF6" fmla="+- xD6 0 lFD" />
+ <gd name="xE6" fmla="+- xA6 lFD 0" />
+
+
+ <gd name="yC6" fmla="+- yD6 0 th" />
+
+ <gd name="swAng1" fmla="+- bA1 0 bD6" />
+
+
+ <gd name="aA2" fmla="+- 1800000 0 ha" />
+ <gd name="aD2" fmla="+- 1800000 ha 0" />
+
+
+ <gd name="ta21" fmla="cos rw aA2" />
+ <gd name="ta22" fmla="sin rh aA2" />
+ <gd name="bA2" fmla="at2 ta21 ta22" />
+
+ <gd name="yA2" fmla="+- h 0 yD1" />
+
+
+ <gd name="td21" fmla="cos rw aD2" />
+ <gd name="td22" fmla="sin rh aD2" />
+ <gd name="bD2" fmla="at2 td21 td22" />
+
+ <gd name="yD2" fmla="+- h 0 yA1" />
+
+
+ <gd name="yC2" fmla="+- h 0 yB1" />
+
+
+ <gd name="yB2" fmla="+- h 0 yC1" />
+ <gd name="xB2" fmla="val xC1" />
+
+ <gd name="swAng2" fmla="+- bA2 0 bD1" />
+
+
+ <gd name="aD3" fmla="+- cd4 ha 0" />
+
+ <gd name="td31" fmla="cos rw aD3" />
+ <gd name="td32" fmla="sin rh aD3" />
+ <gd name="bD3" fmla="at2 td31 td32" />
+
+
+ <gd name="yD3" fmla="+- h 0 yD6" />
+
+
+ <gd name="yB3" fmla="+- h 0 yC6" />
+
+
+ <gd name="aD4" fmla="+- 9000000 ha 0" />
+
+ <gd name="td41" fmla="cos rw aD4" />
+ <gd name="td42" fmla="sin rh aD4" />
+ <gd name="bD4" fmla="at2 td41 td42" />
+
+
+ <gd name="xD4" fmla="+- w 0 xD1" />
+
+
+ <gd name="xC4" fmla="+- w 0 xC1" />
+
+
+ <gd name="xB4" fmla="+- w 0 xB1" />
+
+
+ <gd name="aD5" fmla="+- 12600000 ha 0" />
+
+ <gd name="td51" fmla="cos rw aD5" />
+ <gd name="td52" fmla="sin rh aD5" />
+ <gd name="bD5" fmla="at2 td51 td52" />
+
+
+ <gd name="xD5" fmla="+- w 0 xA1" />
+
+
+ <gd name="xC5" fmla="+- w 0 xB1" />
+
+
+ <gd name="xB5" fmla="+- w 0 xC1" />
+
+
+ <gd name="xCxn1" fmla="+/ xB1 xC1 2" />
+ <gd name="yCxn1" fmla="+/ yB1 yC1 2" />
+ <gd name="yCxn2" fmla="+- b 0 yCxn1" />
+ <gd name="xCxn4" fmla="+/ r 0 xCxn1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="20000">
+ <pos x="xD6" y="yD6" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="5358">
+ <pos x="xA6" y="yD6" />
+ </ahXY>
+
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="19800000">
+ <pos x="xCxn1" y="yCxn1" />
+ </cxn>
+
+ <cxn ang="1800000">
+ <pos x="xCxn1" y="yCxn2" />
+ </cxn>
+
+ <cxn ang="cd4">
+ <pos x="hc" y="yB3" />
+ </cxn>
+
+ <cxn ang="9000000">
+ <pos x="xCxn4" y="yCxn2" />
+ </cxn>
+
+ <cxn ang="12600000">
+ <pos x="xCxn4" y="yCxn1" />
+ </cxn>
+
+ <cxn ang="3cd4">
+ <pos x="hc" y="yC6" />
+ </cxn>
+
+ </cxnLst>
+
+ <rect l="xD5" t="yA1" r="xA1" b="yD2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="xA1" y="yA1" />
+ </moveTo>
+ <lnTo>
+ <pt x="xB1" y="yB1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC1" y="yC1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD1" y="yD1" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD1" swAng="swAng2" />
+
+ <lnTo>
+ <pt x="xC1" y="yB2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xB1" y="yC2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xA1" y="yD2" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD2" swAng="swAng1" />
+
+ <lnTo>
+ <pt x="xF6" y="yB3" />
+ </lnTo>
+ <lnTo>
+ <pt x="xE6" y="yB3" />
+ </lnTo>
+ <lnTo>
+ <pt x="xA6" y="yD3" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD3" swAng="swAng1" />
+
+ <lnTo>
+ <pt x="xB4" y="yC2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC4" y="yB2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD4" y="yA2" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD4" swAng="swAng2" />
+
+ <lnTo>
+ <pt x="xB5" y="yC1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC5" y="yB1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD5" y="yA1" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD5" swAng="swAng1" />
+
+ <lnTo>
+ <pt x="xE6" y="yC6" />
+ </lnTo>
+ <lnTo>
+ <pt x="xF6" y="yC6" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD6" y="yD6" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD6" swAng="swAng1" />
+ <close />
+ </path>
+ </pathLst>
+
+ </gear6>
+ <gear9>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 10000" />
+
+ <gd name="adj2" fmla="val 1763" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+
+
+
+ <gd name="a1" fmla="pin 0 adj1 20000" />
+ <gd name="a2" fmla="pin 0 adj2 2679" />
+
+
+ <gd name="th" fmla="*/ ss a1 100000" />
+ <gd name="lFD" fmla="*/ ss a2 100000" />
+
+ <gd name="th2" fmla="*/ th 1 2" />
+ <gd name="l2" fmla="*/ lFD 1 2" />
+ <gd name="l3" fmla="+- th2 l2 0" />
+
+
+ <gd name="rh" fmla="+- hd2 0 th" />
+ <gd name="rw" fmla="+- wd2 0 th" />
+
+
+ <gd name="dr" fmla="+- rw 0 rh" />
+ <gd name="maxr" fmla="?: dr rh rw" />
+ <gd name="ha" fmla="at2 maxr l3" />
+
+
+ <gd name="aA1" fmla="+- 18600000 0 ha" />
+ <gd name="aD1" fmla="+- 18600000 ha 0" />
+
+
+ <gd name="ta11" fmla="cos rw aA1" />
+ <gd name="ta12" fmla="sin rh aA1" />
+ <gd name="bA1" fmla="at2 ta11 ta12" />
+
+ <gd name="cta1" fmla="cos rh bA1" />
+ <gd name="sta1" fmla="sin rw bA1" />
+ <gd name="ma1" fmla="mod cta1 sta1 0" />
+ <gd name="na1" fmla="*/ rw rh ma1" />
+ <gd name="dxa1" fmla="cos na1 bA1" />
+ <gd name="dya1" fmla="sin na1 bA1" />
+ <gd name="xA1" fmla="+- hc dxa1 0" />
+ <gd name="yA1" fmla="+- vc dya1 0" />
+
+
+ <gd name="td11" fmla="cos rw aD1" />
+ <gd name="td12" fmla="sin rh aD1" />
+ <gd name="bD1" fmla="at2 td11 td12" />
+
+ <gd name="ctd1" fmla="cos rh bD1" />
+ <gd name="std1" fmla="sin rw bD1" />
+ <gd name="md1" fmla="mod ctd1 std1 0" />
+ <gd name="nd1" fmla="*/ rw rh md1" />
+ <gd name="dxd1" fmla="cos nd1 bD1" />
+ <gd name="dyd1" fmla="sin nd1 bD1" />
+ <gd name="xD1" fmla="+- hc dxd1 0" />
+ <gd name="yD1" fmla="+- vc dyd1 0" />
+
+
+ <gd name="xAD1" fmla="+- xA1 0 xD1" />
+ <gd name="yAD1" fmla="+- yA1 0 yD1" />
+ <gd name="lAD1" fmla="mod xAD1 yAD1 0" />
+ <gd name="a1" fmla="at2 yAD1 xAD1" />
+
+
+ <gd name="dxF1" fmla="sin lFD a1" />
+ <gd name="dyF1" fmla="cos lFD a1" />
+ <gd name="xF1" fmla="+- xD1 dxF1 0" />
+ <gd name="yF1" fmla="+- yD1 dyF1 0" />
+ <gd name="xE1" fmla="+- xA1 0 dxF1" />
+ <gd name="yE1" fmla="+- yA1 0 dyF1" />
+
+
+ <gd name="yC1t" fmla="sin th a1" />
+ <gd name="xC1t" fmla="cos th a1" />
+ <gd name="yC1" fmla="+- yF1 yC1t 0" />
+ <gd name="xC1" fmla="+- xF1 0 xC1t" />
+
+
+ <gd name="yB1" fmla="+- yE1 yC1t 0" />
+ <gd name="xB1" fmla="+- xE1 0 xC1t" />
+
+
+ <gd name="aA2" fmla="+- 21000000 0 ha" />
+ <gd name="aD2" fmla="+- 21000000 ha 0" />
+
+
+ <gd name="ta21" fmla="cos rw aA2" />
+ <gd name="ta22" fmla="sin rh aA2" />
+ <gd name="bA2" fmla="at2 ta21 ta22" />
+
+ <gd name="cta2" fmla="cos rh bA2" />
+ <gd name="sta2" fmla="sin rw bA2" />
+ <gd name="ma2" fmla="mod cta2 sta2 0" />
+ <gd name="na2" fmla="*/ rw rh ma2" />
+ <gd name="dxa2" fmla="cos na2 bA2" />
+ <gd name="dya2" fmla="sin na2 bA2" />
+ <gd name="xA2" fmla="+- hc dxa2 0" />
+ <gd name="yA2" fmla="+- vc dya2 0" />
+
+
+ <gd name="td21" fmla="cos rw aD2" />
+ <gd name="td22" fmla="sin rh aD2" />
+ <gd name="bD2" fmla="at2 td21 td22" />
+
+ <gd name="ctd2" fmla="cos rh bD2" />
+ <gd name="std2" fmla="sin rw bD2" />
+ <gd name="md2" fmla="mod ctd2 std2 0" />
+ <gd name="nd2" fmla="*/ rw rh md2" />
+ <gd name="dxd2" fmla="cos nd2 bD2" />
+ <gd name="dyd2" fmla="sin nd2 bD2" />
+ <gd name="xD2" fmla="+- hc dxd2 0" />
+ <gd name="yD2" fmla="+- vc dyd2 0" />
+
+
+ <gd name="xAD2" fmla="+- xA2 0 xD2" />
+ <gd name="yAD2" fmla="+- yA2 0 yD2" />
+ <gd name="lAD2" fmla="mod xAD2 yAD2 0" />
+ <gd name="a2" fmla="at2 yAD2 xAD2" />
+
+
+ <gd name="dxF2" fmla="sin lFD a2" />
+ <gd name="dyF2" fmla="cos lFD a2" />
+ <gd name="xF2" fmla="+- xD2 dxF2 0" />
+ <gd name="yF2" fmla="+- yD2 dyF2 0" />
+ <gd name="xE2" fmla="+- xA2 0 dxF2" />
+ <gd name="yE2" fmla="+- yA2 0 dyF2" />
+
+
+ <gd name="yC2t" fmla="sin th a2" />
+ <gd name="xC2t" fmla="cos th a2" />
+ <gd name="yC2" fmla="+- yF2 yC2t 0" />
+ <gd name="xC2" fmla="+- xF2 0 xC2t" />
+
+
+ <gd name="yB2" fmla="+- yE2 yC2t 0" />
+ <gd name="xB2" fmla="+- xE2 0 xC2t" />
+
+ <gd name="swAng1" fmla="+- bA2 0 bD1" />
+
+
+ <gd name="aA3" fmla="+- 1800000 0 ha" />
+ <gd name="aD3" fmla="+- 1800000 ha 0" />
+
+
+ <gd name="ta31" fmla="cos rw aA3" />
+ <gd name="ta32" fmla="sin rh aA3" />
+ <gd name="bA3" fmla="at2 ta31 ta32" />
+
+ <gd name="cta3" fmla="cos rh bA3" />
+ <gd name="sta3" fmla="sin rw bA3" />
+ <gd name="ma3" fmla="mod cta3 sta3 0" />
+ <gd name="na3" fmla="*/ rw rh ma3" />
+ <gd name="dxa3" fmla="cos na3 bA3" />
+ <gd name="dya3" fmla="sin na3 bA3" />
+ <gd name="xA3" fmla="+- hc dxa3 0" />
+ <gd name="yA3" fmla="+- vc dya3 0" />
+
+
+ <gd name="td31" fmla="cos rw aD3" />
+ <gd name="td32" fmla="sin rh aD3" />
+ <gd name="bD3" fmla="at2 td31 td32" />
+
+ <gd name="ctd3" fmla="cos rh bD3" />
+ <gd name="std3" fmla="sin rw bD3" />
+ <gd name="md3" fmla="mod ctd3 std3 0" />
+ <gd name="nd3" fmla="*/ rw rh md3" />
+ <gd name="dxd3" fmla="cos nd3 bD3" />
+ <gd name="dyd3" fmla="sin nd3 bD3" />
+ <gd name="xD3" fmla="+- hc dxd3 0" />
+ <gd name="yD3" fmla="+- vc dyd3 0" />
+
+
+ <gd name="xAD3" fmla="+- xA3 0 xD3" />
+ <gd name="yAD3" fmla="+- yA3 0 yD3" />
+ <gd name="lAD3" fmla="mod xAD3 yAD3 0" />
+ <gd name="a3" fmla="at2 yAD3 xAD3" />
+
+
+ <gd name="dxF3" fmla="sin lFD a3" />
+ <gd name="dyF3" fmla="cos lFD a3" />
+ <gd name="xF3" fmla="+- xD3 dxF3 0" />
+ <gd name="yF3" fmla="+- yD3 dyF3 0" />
+ <gd name="xE3" fmla="+- xA3 0 dxF3" />
+ <gd name="yE3" fmla="+- yA3 0 dyF3" />
+
+
+ <gd name="yC3t" fmla="sin th a3" />
+ <gd name="xC3t" fmla="cos th a3" />
+ <gd name="yC3" fmla="+- yF3 yC3t 0" />
+ <gd name="xC3" fmla="+- xF3 0 xC3t" />
+
+
+ <gd name="yB3" fmla="+- yE3 yC3t 0" />
+ <gd name="xB3" fmla="+- xE3 0 xC3t" />
+
+ <gd name="swAng2" fmla="+- bA3 0 bD2" />
+
+
+ <gd name="aA4" fmla="+- 4200000 0 ha" />
+ <gd name="aD4" fmla="+- 4200000 ha 0" />
+
+
+ <gd name="ta41" fmla="cos rw aA4" />
+ <gd name="ta42" fmla="sin rh aA4" />
+ <gd name="bA4" fmla="at2 ta41 ta42" />
+
+ <gd name="cta4" fmla="cos rh bA4" />
+ <gd name="sta4" fmla="sin rw bA4" />
+ <gd name="ma4" fmla="mod cta4 sta4 0" />
+ <gd name="na4" fmla="*/ rw rh ma4" />
+ <gd name="dxa4" fmla="cos na4 bA4" />
+ <gd name="dya4" fmla="sin na4 bA4" />
+ <gd name="xA4" fmla="+- hc dxa4 0" />
+ <gd name="yA4" fmla="+- vc dya4 0" />
+
+
+ <gd name="td41" fmla="cos rw aD4" />
+ <gd name="td42" fmla="sin rh aD4" />
+ <gd name="bD4" fmla="at2 td41 td42" />
+
+ <gd name="ctd4" fmla="cos rh bD4" />
+ <gd name="std4" fmla="sin rw bD4" />
+ <gd name="md4" fmla="mod ctd4 std4 0" />
+ <gd name="nd4" fmla="*/ rw rh md4" />
+ <gd name="dxd4" fmla="cos nd4 bD4" />
+ <gd name="dyd4" fmla="sin nd4 bD4" />
+ <gd name="xD4" fmla="+- hc dxd4 0" />
+ <gd name="yD4" fmla="+- vc dyd4 0" />
+
+
+ <gd name="xAD4" fmla="+- xA4 0 xD4" />
+ <gd name="yAD4" fmla="+- yA4 0 yD4" />
+ <gd name="lAD4" fmla="mod xAD4 yAD4 0" />
+ <gd name="a4" fmla="at2 yAD4 xAD4" />
+
+
+ <gd name="dxF4" fmla="sin lFD a4" />
+ <gd name="dyF4" fmla="cos lFD a4" />
+ <gd name="xF4" fmla="+- xD4 dxF4 0" />
+ <gd name="yF4" fmla="+- yD4 dyF4 0" />
+ <gd name="xE4" fmla="+- xA4 0 dxF4" />
+ <gd name="yE4" fmla="+- yA4 0 dyF4" />
+
+
+ <gd name="yC4t" fmla="sin th a4" />
+ <gd name="xC4t" fmla="cos th a4" />
+ <gd name="yC4" fmla="+- yF4 yC4t 0" />
+ <gd name="xC4" fmla="+- xF4 0 xC4t" />
+
+
+ <gd name="yB4" fmla="+- yE4 yC4t 0" />
+ <gd name="xB4" fmla="+- xE4 0 xC4t" />
+
+ <gd name="swAng3" fmla="+- bA4 0 bD3" />
+
+
+ <gd name="aA5" fmla="+- 6600000 0 ha" />
+ <gd name="aD5" fmla="+- 6600000 ha 0" />
+
+ <gd name="ta51" fmla="cos rw aA5" />
+ <gd name="ta52" fmla="sin rh aA5" />
+ <gd name="bA5" fmla="at2 ta51 ta52" />
+
+ <gd name="td51" fmla="cos rw aD5" />
+ <gd name="td52" fmla="sin rh aD5" />
+ <gd name="bD5" fmla="at2 td51 td52" />
+
+
+ <gd name="xD5" fmla="+- w 0 xA4" />
+
+
+ <gd name="xC5" fmla="+- w 0 xB4" />
+
+
+ <gd name="xB5" fmla="+- w 0 xC4" />
+
+ <gd name="swAng4" fmla="+- bA5 0 bD4" />
+
+
+ <gd name="aD6" fmla="+- 9000000 ha 0" />
+
+ <gd name="td61" fmla="cos rw aD6" />
+ <gd name="td62" fmla="sin rh aD6" />
+ <gd name="bD6" fmla="at2 td61 td62" />
+
+
+ <gd name="xD6" fmla="+- w 0 xA3" />
+
+
+ <gd name="xC6" fmla="+- w 0 xB3" />
+
+
+ <gd name="xB6" fmla="+- w 0 xC3" />
+
+
+ <gd name="aD7" fmla="+- 11400000 ha 0" />
+
+ <gd name="td71" fmla="cos rw aD7" />
+ <gd name="td72" fmla="sin rh aD7" />
+ <gd name="bD7" fmla="at2 td71 td72" />
+
+
+ <gd name="xD7" fmla="+- w 0 xA2" />
+
+
+ <gd name="xC7" fmla="+- w 0 xB2" />
+
+
+ <gd name="xB7" fmla="+- w 0 xC2" />
+
+
+ <gd name="aD8" fmla="+- 13800000 ha 0" />
+
+ <gd name="td81" fmla="cos rw aD8" />
+ <gd name="td82" fmla="sin rh aD8" />
+ <gd name="bD8" fmla="at2 td81 td82" />
+
+
+ <gd name="xA8" fmla="+- w 0 xD1" />
+
+ <gd name="xD8" fmla="+- w 0 xA1" />
+
+
+ <gd name="xC8" fmla="+- w 0 xB1" />
+
+
+ <gd name="xB8" fmla="+- w 0 xC1" />
+
+
+ <gd name="aA9" fmla="+- 3cd4 0 ha" />
+ <gd name="aD9" fmla="+- 3cd4 ha 0" />
+
+
+ <gd name="td91" fmla="cos rw aD9" />
+ <gd name="td92" fmla="sin rh aD9" />
+ <gd name="bD9" fmla="at2 td91 td92" />
+
+ <gd name="ctd9" fmla="cos rh bD9" />
+ <gd name="std9" fmla="sin rw bD9" />
+ <gd name="md9" fmla="mod ctd9 std9 0" />
+ <gd name="nd9" fmla="*/ rw rh md9" />
+ <gd name="dxd9" fmla="cos nd9 bD9" />
+ <gd name="dyd9" fmla="sin nd9 bD9" />
+ <gd name="xD9" fmla="+- hc dxd9 0" />
+ <gd name="yD9" fmla="+- vc dyd9 0" />
+
+
+ <gd name="ta91" fmla="cos rw aA9" />
+ <gd name="ta92" fmla="sin rh aA9" />
+ <gd name="bA9" fmla="at2 ta91 ta92" />
+
+ <gd name="xA9" fmla="+- hc 0 dxd9" />
+
+
+ <gd name="xF9" fmla="+- xD9 0 lFD" />
+ <gd name="xE9" fmla="+- xA9 lFD 0" />
+
+
+ <gd name="yC9" fmla="+- yD9 0 th" />
+
+ <gd name="swAng5" fmla="+- bA9 0 bD8" />
+
+
+ <gd name="xCxn1" fmla="+/ xB1 xC1 2" />
+ <gd name="yCxn1" fmla="+/ yB1 yC1 2" />
+ <gd name="xCxn2" fmla="+/ xB2 xC2 2" />
+ <gd name="yCxn2" fmla="+/ yB2 yC2 2" />
+ <gd name="xCxn3" fmla="+/ xB3 xC3 2" />
+ <gd name="yCxn3" fmla="+/ yB3 yC3 2" />
+ <gd name="xCxn4" fmla="+/ xB4 xC4 2" />
+ <gd name="yCxn4" fmla="+/ yB4 yC4 2" />
+ <gd name="xCxn5" fmla="+/ r 0 xCxn4" />
+ <gd name="xCxn6" fmla="+/ r 0 xCxn3" />
+ <gd name="xCxn7" fmla="+/ r 0 xCxn2" />
+ <gd name="xCxn8" fmla="+/ r 0 xCxn1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="20000">
+ <pos x="xD9" y="yD9" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="2679">
+ <pos x="xA9" y="yD9" />
+ </ahXY>
+
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="18600000">
+ <pos x="xCxn1" y="yCxn1" />
+ </cxn>
+
+ <cxn ang="21000000">
+ <pos x="xCxn2" y="yCxn2" />
+ </cxn>
+
+ <cxn ang="1800000">
+ <pos x="xCxn3" y="yCxn3" />
+ </cxn>
+
+ <cxn ang="4200000">
+ <pos x="xCxn4" y="yCxn4" />
+ </cxn>
+
+ <cxn ang="6600000">
+ <pos x="xCxn5" y="yCxn4" />
+ </cxn>
+
+ <cxn ang="9000000">
+ <pos x="xCxn6" y="yCxn3" />
+ </cxn>
+
+ <cxn ang="11400000">
+ <pos x="xCxn7" y="yCxn2" />
+ </cxn>
+
+ <cxn ang="13800000">
+ <pos x="xCxn8" y="yCxn1" />
+ </cxn>
+
+ <cxn ang="3cd4">
+ <pos x="hc" y="yC9" />
+ </cxn>
+
+ </cxnLst>
+
+ <rect l="xA8" t="yD1" r="xD1" b="yD3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="xA1" y="yA1" />
+ </moveTo>
+ <lnTo>
+ <pt x="xB1" y="yB1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC1" y="yC1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD1" y="yD1" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD1" swAng="swAng1" />
+
+ <lnTo>
+ <pt x="xB2" y="yB2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC2" y="yC2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD2" y="yD2" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD2" swAng="swAng2" />
+
+ <lnTo>
+ <pt x="xB3" y="yB3" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC3" y="yC3" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD3" y="yD3" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD3" swAng="swAng3" />
+
+ <lnTo>
+ <pt x="xB4" y="yB4" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC4" y="yC4" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD4" y="yD4" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD4" swAng="swAng4" />
+
+ <lnTo>
+ <pt x="xB5" y="yC4" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC5" y="yB4" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD5" y="yA4" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD5" swAng="swAng3" />
+
+ <lnTo>
+ <pt x="xB6" y="yC3" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC6" y="yB3" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD6" y="yA3" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD6" swAng="swAng2" />
+
+ <lnTo>
+ <pt x="xB7" y="yC2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC7" y="yB2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD7" y="yA2" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD7" swAng="swAng1" />
+
+ <lnTo>
+ <pt x="xB8" y="yC1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC8" y="yB1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD8" y="yA1" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD8" swAng="swAng5" />
+
+ <lnTo>
+ <pt x="xE9" y="yC9" />
+ </lnTo>
+ <lnTo>
+ <pt x="xF9" y="yC9" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD9" y="yD9" />
+ </lnTo>
+ <arcTo hR="rh" wR="rw" stAng="bD9" swAng="swAng5" />
+ <close />
+ </path>
+ </pathLst>
+
+ </gear9>
+ <halfFrame>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 33333" />
+
+ <gd name="adj2" fmla="val 33333" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 100000 w ss" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="x1" fmla="*/ ss a2 100000" />
+ <gd name="g1" fmla="*/ h x1 w" />
+ <gd name="g2" fmla="+- h 0 g1" />
+ <gd name="maxAdj1" fmla="*/ 100000 g2 ss" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="y1" fmla="*/ ss a1 100000" />
+ <gd name="dx2" fmla="*/ y1 w h" />
+ <gd name="x2" fmla="+- r 0 dx2" />
+ <gd name="dy2" fmla="*/ x1 h w" />
+ <gd name="y2" fmla="+- b 0 dy2" />
+ <gd name="cx1" fmla="*/ x1 1 2" />
+ <gd name="cy1" fmla="+/ y2 b 2" />
+ <gd name="cx2" fmla="+/ x2 r 2" />
+ <gd name="cy2" fmla="*/ y1 1 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="cx2" y="cy2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="cx1" y="cy1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </halfFrame>
+ <heart>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dx1" fmla="*/ w 49 48" />
+ <gd name="dx2" fmla="*/ w 10 48" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- t 0 hd3" />
+
+
+ <gd name="il" fmla="*/ w 1 6" />
+ <gd name="ir" fmla="*/ w 5 6" />
+ <gd name="ib" fmla="*/ h 2 3" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="hd4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="hd4" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="hc" y="hd4" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x3" y="y1" />
+ <pt x="x4" y="hd4" />
+ <pt x="hc" y="b" />
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x1" y="hd4" />
+ <pt x="x2" y="y1" />
+ <pt x="hc" y="hd4" />
+ </cubicBezTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </heart>
+ <heptagon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="hf" fmla="val 102572" />
+ <gd name="vf" fmla="val 105210" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="swd2" fmla="*/ wd2 hf 100000" />
+ <gd name="shd2" fmla="*/ hd2 vf 100000" />
+ <gd name="svc" fmla="*/ vc vf 100000" />
+ <gd name="dx1" fmla="*/ swd2 97493 100000" />
+ <gd name="dx2" fmla="*/ swd2 78183 100000" />
+ <gd name="dx3" fmla="*/ swd2 43388 100000" />
+ <gd name="dy1" fmla="*/ shd2 62349 100000" />
+ <gd name="dy2" fmla="*/ shd2 22252 100000" />
+ <gd name="dy3" fmla="*/ shd2 90097 100000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc 0 dx3" />
+ <gd name="x4" fmla="+- hc dx3 0" />
+ <gd name="x5" fmla="+- hc dx2 0" />
+ <gd name="x6" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- svc 0 dy1" />
+ <gd name="y2" fmla="+- svc dy2 0" />
+ <gd name="y3" fmla="+- svc dy3 0" />
+ <gd name="ib" fmla="+- b 0 y1" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x5" y="y1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x4" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x2" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="y1" r="x5" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </heptagon>
+ <hexagon>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+ <gd name="vf" fmla="val 115470" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 50000 w ss" />
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="shd2" fmla="*/ hd2 vf 100000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="+- r 0 x1" />
+ <gd name="dy1" fmla="sin shd2 3600000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc dy1 0" />
+ <gd name="q1" fmla="*/ maxAdj -1 2" />
+ <gd name="q2" fmla="+- a q1 0" />
+ <gd name="q3" fmla="?: q2 4 2" />
+ <gd name="q4" fmla="?: q2 3 2" />
+ <gd name="q5" fmla="?: q2 q1 0" />
+ <gd name="q6" fmla="+/ a q5 q1" />
+ <gd name="q7" fmla="*/ q6 q4 -1" />
+ <gd name="q8" fmla="+- q3 q7 0" />
+ <gd name="il" fmla="*/ w q8 24" />
+ <gd name="it" fmla="*/ h q8 24" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 it" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="maxAdj">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="y1" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </hexagon>
+ <homePlate>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 100000 w ss" />
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="dx1" fmla="*/ ss a 100000" />
+ <gd name="x1" fmla="+- r 0 dx1" />
+ <gd name="ir" fmla="+/ x1 r 2" />
+ <gd name="x2" fmla="*/ x1 1 2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="maxAdj">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x2" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </homePlate>
+ <horizontalScroll>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 12500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 25000" />
+ <gd name="ch" fmla="*/ ss a 100000" />
+
+ <gd name="ch2" fmla="*/ ch 1 2" />
+
+ <gd name="ch4" fmla="*/ ch 1 4" />
+
+
+
+
+
+ <gd name="y3" fmla="+- ch ch2 0" />
+
+ <gd name="y4" fmla="+- ch ch 0" />
+
+ <gd name="y6" fmla="+- b 0 ch" />
+
+ <gd name="y7" fmla="+- b 0 ch2" />
+
+ <gd name="y5" fmla="+- y6 0 ch2" />
+
+
+
+
+
+ <gd name="x3" fmla="+- r 0 ch" />
+
+ <gd name="x4" fmla="+- r 0 ch2" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="25000">
+ <pos x="ch" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="hc" y="ch" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="y6" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="ch" t="ch" r="x4" b="y6" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="r" y="ch2" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="x4" y="ch2" />
+ </lnTo>
+ <arcTo wR="ch4" hR="ch4" stAng="0" swAng="cd2" />
+ <lnTo>
+ <pt x="x3" y="ch" />
+ </lnTo>
+ <lnTo>
+ <pt x="ch2" y="ch" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="l" y="y7" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd2" swAng="-10800000" />
+ <lnTo>
+ <pt x="ch" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y6" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="-5400000" />
+ <close />
+ <moveTo>
+ <pt x="ch2" y="y4" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="-5400000" />
+ <arcTo wR="ch4" hR="ch4" stAng="0" swAng="-10800000" />
+ <close />
+ </path>
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="ch2" y="y4" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="-5400000" />
+ <arcTo wR="ch4" hR="ch4" stAng="0" swAng="-10800000" />
+ <close />
+ <moveTo>
+ <pt x="x4" y="ch" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="-16200000" />
+ <arcTo wR="ch4" hR="ch4" stAng="cd2" swAng="-10800000" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="y3" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x3" y="ch" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="ch2" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd2" swAng="cd2" />
+ <lnTo>
+ <pt x="r" y="y5" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="ch" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="ch" y="y7" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd2" />
+ <close />
+ <moveTo>
+ <pt x="x3" y="ch" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="ch" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="-5400000" />
+ <moveTo>
+ <pt x="x4" y="ch" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="ch2" />
+ </lnTo>
+ <arcTo wR="ch4" hR="ch4" stAng="0" swAng="cd2" />
+ <moveTo>
+ <pt x="ch2" y="y4" />
+ </moveTo>
+ <lnTo>
+ <pt x="ch2" y="y3" />
+ </lnTo>
+ <arcTo wR="ch4" hR="ch4" stAng="cd2" swAng="cd2" />
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd2" />
+ <moveTo>
+ <pt x="ch" y="y3" />
+ </moveTo>
+ <lnTo>
+ <pt x="ch" y="y6" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </horizontalScroll>
+ <irregularSeal1>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x5" fmla="*/ w 4627 21600" />
+ <gd name="x12" fmla="*/ w 8485 21600" />
+ <gd name="x21" fmla="*/ w 16702 21600" />
+ <gd name="x24" fmla="*/ w 14522 21600" />
+ <gd name="y3" fmla="*/ h 6320 21600" />
+ <gd name="y6" fmla="*/ h 8615 21600" />
+ <gd name="y9" fmla="*/ h 13937 21600" />
+ <gd name="y18" fmla="*/ h 13290 21600" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x24" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y6" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x12" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y18" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x5" t="y3" r="x21" b="y9" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="21600" h="21600">
+ <moveTo>
+ <pt x="10800" y="5800" />
+ </moveTo>
+ <lnTo>
+ <pt x="14522" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="14155" y="5325" />
+ </lnTo>
+ <lnTo>
+ <pt x="18380" y="4457" />
+ </lnTo>
+ <lnTo>
+ <pt x="16702" y="7315" />
+ </lnTo>
+ <lnTo>
+ <pt x="21097" y="8137" />
+ </lnTo>
+ <lnTo>
+ <pt x="17607" y="10475" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="13290" />
+ </lnTo>
+ <lnTo>
+ <pt x="16837" y="12942" />
+ </lnTo>
+ <lnTo>
+ <pt x="18145" y="18095" />
+ </lnTo>
+ <lnTo>
+ <pt x="14020" y="14457" />
+ </lnTo>
+ <lnTo>
+ <pt x="13247" y="19737" />
+ </lnTo>
+ <lnTo>
+ <pt x="10532" y="14935" />
+ </lnTo>
+ <lnTo>
+ <pt x="8485" y="21600" />
+ </lnTo>
+ <lnTo>
+ <pt x="7715" y="15627" />
+ </lnTo>
+ <lnTo>
+ <pt x="4762" y="17617" />
+ </lnTo>
+ <lnTo>
+ <pt x="5667" y="13937" />
+ </lnTo>
+ <lnTo>
+ <pt x="135" y="14587" />
+ </lnTo>
+ <lnTo>
+ <pt x="3722" y="11775" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="8615" />
+ </lnTo>
+ <lnTo>
+ <pt x="4627" y="7617" />
+ </lnTo>
+ <lnTo>
+ <pt x="370" y="2295" />
+ </lnTo>
+ <lnTo>
+ <pt x="7312" y="6320" />
+ </lnTo>
+ <lnTo>
+ <pt x="8352" y="2295" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </irregularSeal1>
+ <irregularSeal2>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x2" fmla="*/ w 9722 21600" />
+ <gd name="x5" fmla="*/ w 5372 21600" />
+ <gd name="x16" fmla="*/ w 11612 21600" />
+ <gd name="x19" fmla="*/ w 14640 21600" />
+ <gd name="y2" fmla="*/ h 1887 21600" />
+ <gd name="y3" fmla="*/ h 6382 21600" />
+ <gd name="y8" fmla="*/ h 12877 21600" />
+ <gd name="y14" fmla="*/ h 19712 21600" />
+ <gd name="y16" fmla="*/ h 18842 21600" />
+ <gd name="y17" fmla="*/ h 15935 21600" />
+ <gd name="y24" fmla="*/ h 6645 21600" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y8" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x16" y="y16" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y24" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x5" t="y3" r="x19" b="y17" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="21600" h="21600">
+ <moveTo>
+ <pt x="11462" y="4342" />
+ </moveTo>
+ <lnTo>
+ <pt x="14790" y="0" />
+ </lnTo>
+ <lnTo>
+ <pt x="14525" y="5777" />
+ </lnTo>
+ <lnTo>
+ <pt x="18007" y="3172" />
+ </lnTo>
+ <lnTo>
+ <pt x="16380" y="6532" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="6645" />
+ </lnTo>
+ <lnTo>
+ <pt x="16985" y="9402" />
+ </lnTo>
+ <lnTo>
+ <pt x="18270" y="11290" />
+ </lnTo>
+ <lnTo>
+ <pt x="16380" y="12310" />
+ </lnTo>
+ <lnTo>
+ <pt x="18877" y="15632" />
+ </lnTo>
+ <lnTo>
+ <pt x="14640" y="14350" />
+ </lnTo>
+ <lnTo>
+ <pt x="14942" y="17370" />
+ </lnTo>
+ <lnTo>
+ <pt x="12180" y="15935" />
+ </lnTo>
+ <lnTo>
+ <pt x="11612" y="18842" />
+ </lnTo>
+ <lnTo>
+ <pt x="9872" y="17370" />
+ </lnTo>
+ <lnTo>
+ <pt x="8700" y="19712" />
+ </lnTo>
+ <lnTo>
+ <pt x="7527" y="18125" />
+ </lnTo>
+ <lnTo>
+ <pt x="4917" y="21600" />
+ </lnTo>
+ <lnTo>
+ <pt x="4805" y="18240" />
+ </lnTo>
+ <lnTo>
+ <pt x="1285" y="17825" />
+ </lnTo>
+ <lnTo>
+ <pt x="3330" y="15370" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="12877" />
+ </lnTo>
+ <lnTo>
+ <pt x="3935" y="11592" />
+ </lnTo>
+ <lnTo>
+ <pt x="1172" y="8270" />
+ </lnTo>
+ <lnTo>
+ <pt x="5372" y="7817" />
+ </lnTo>
+ <lnTo>
+ <pt x="4502" y="3625" />
+ </lnTo>
+ <lnTo>
+ <pt x="8550" y="6382" />
+ </lnTo>
+ <lnTo>
+ <pt x="9722" y="1887" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </irregularSeal2>
+ <leftArrow>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 100000 w ss" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="dx2" fmla="*/ ss a2 100000" />
+ <gd name="x2" fmla="+- l dx2 0" />
+ <gd name="dy1" fmla="*/ h a1 200000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc dy1 0" />
+ <gd name="dx1" fmla="*/ y1 dx2 hd2" />
+ <gd name="x1" fmla="+- x2 0 dx1" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="r" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x2" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="x1" t="y1" r="r" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </leftArrow>
+ <leftArrowCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 64977" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 h ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ 100000 w ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q2" fmla="*/ a3 ss w" />
+
+ <gd name="maxAdj4" fmla="+- 100000 0 q2" />
+
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+ <gd name="dy1" fmla="*/ ss a2 100000" />
+
+ <gd name="dy2" fmla="*/ ss a1 200000" />
+
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc dy2 0" />
+ <gd name="y4" fmla="+- vc dy1 0" />
+ <gd name="x1" fmla="*/ ss a3 100000" />
+
+ <gd name="dx2" fmla="*/ w a4 100000" />
+
+ <gd name="x2" fmla="+- r 0 dx2" />
+ <gd name="x3" fmla="+/ x2 r 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="x1" y="y2" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="0" maxX="maxAdj3">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="0" maxX="maxAdj4">
+ <pos x="x2" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </leftArrowCallout>
+ <leftBrace>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 8333" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 100000" />
+ <gd name="q1" fmla="+- 100000 0 a2" />
+ <gd name="q2" fmla="min q1 a2" />
+ <gd name="q3" fmla="*/ q2 1 2" />
+ <gd name="maxAdj1" fmla="*/ q3 h ss" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="y1" fmla="*/ ss a1 100000" />
+ <gd name="y3" fmla="*/ h a2 100000" />
+ <gd name="y4" fmla="+- y3 y1 0" />
+ <gd name="dx1" fmla="cos wd2 2700000" />
+ <gd name="dy1" fmla="sin y1 2700000" />
+ <gd name="il" fmla="+- r 0 dx1" />
+ <gd name="it" fmla="+- y1 0 dy1" />
+ <gd name="ib" fmla="+- b dy1 y1" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="hc" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="100000">
+ <pos x="l" y="y3" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="r" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y3" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="r" y="b" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="r" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="r" y="b" />
+ </moveTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="hc" y="y4" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="-5400000" />
+ <arcTo wR="wd2" hR="y1" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="hc" y="y1" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd2" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="r" y="b" />
+ </moveTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="hc" y="y4" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="-5400000" />
+ <arcTo wR="wd2" hR="y1" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="hc" y="y1" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd2" swAng="cd4" />
+ </path>
+ </pathLst>
+ </leftBrace>
+ <leftBracket>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 8333" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 50000 h ss" />
+
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="y1" fmla="*/ ss a 100000" />
+
+ <gd name="y2" fmla="+- b 0 y1" />
+
+ <gd name="dx1" fmla="cos w 2700000" />
+ <gd name="dy1" fmla="sin y1 2700000" />
+ <gd name="il" fmla="+- r 0 dx1" />
+ <gd name="it" fmla="+- y1 0 dy1" />
+ <gd name="ib" fmla="+- b dy1 y1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="maxAdj">
+ <pos x="l" y="y1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="r" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="r" y="b" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="r" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="r" y="b" />
+ </moveTo>
+ <arcTo wR="w" hR="y1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="l" y="y1" />
+ </lnTo>
+ <arcTo wR="w" hR="y1" stAng="cd2" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none">
+
+ <moveTo>
+ <pt x="r" y="b" />
+ </moveTo>
+ <arcTo wR="w" hR="y1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="l" y="y1" />
+ </lnTo>
+ <arcTo wR="w" hR="y1" stAng="cd2" swAng="cd4" />
+ </path>
+ </pathLst>
+
+ </leftBracket>
+ <leftCircularArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 12500" />
+
+ <gd name="adj2" fmla="val -1142319" />
+
+ <gd name="adj3" fmla="val 1142319" />
+
+ <gd name="adj4" fmla="val 10800000" />
+
+ <gd name="adj5" fmla="val 12500" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a5" fmla="pin 0 adj5 25000" />
+
+ <gd name="maxAdj1" fmla="*/ a5 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="enAng" fmla="pin 1 adj3 21599999" />
+ <gd name="stAng" fmla="pin 0 adj4 21599999" />
+
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="thh" fmla="*/ ss a5 100000" />
+
+ <gd name="th2" fmla="*/ th 1 2" />
+
+
+ <gd name="rw1" fmla="+- wd2 th2 thh" />
+
+ <gd name="rh1" fmla="+- hd2 th2 thh" />
+
+ <gd name="rw2" fmla="+- rw1 0 th" />
+
+ <gd name="rh2" fmla="+- rh1 0 th" />
+
+ <gd name="rw3" fmla="+- rw2 th2 0" />
+
+ <gd name="rh3" fmla="+- rh2 th2 0" />
+
+
+ <gd name="wtH" fmla="sin rw3 enAng" />
+ <gd name="htH" fmla="cos rh3 enAng" />
+ <gd name="dxH" fmla="cat2 rw3 htH wtH" />
+ <gd name="dyH" fmla="sat2 rh3 htH wtH" />
+ <gd name="xH" fmla="+- hc dxH 0" />
+
+ <gd name="yH" fmla="+- vc dyH 0" />
+
+
+ <gd name="rI" fmla="min rw2 rh2" />
+
+ <gd name="u1" fmla="*/ dxH dxH 1" />
+ <gd name="u2" fmla="*/ dyH dyH 1" />
+ <gd name="u3" fmla="*/ rI rI 1" />
+ <gd name="u4" fmla="+- u1 0 u3" />
+ <gd name="u5" fmla="+- u2 0 u3" />
+ <gd name="u6" fmla="*/ u4 u5 u1" />
+ <gd name="u7" fmla="*/ u6 1 u2" />
+ <gd name="u8" fmla="+- 1 0 u7" />
+ <gd name="u9" fmla="sqrt u8" />
+ <gd name="u10" fmla="*/ u4 1 dxH" />
+ <gd name="u11" fmla="*/ u10 1 dyH" />
+ <gd name="u12" fmla="+/ 1 u9 u11" />
+ <gd name="u13" fmla="at2 1 u12" />
+ <gd name="u14" fmla="+- u13 21600000 0" />
+ <gd name="u15" fmla="?: u13 u13 u14" />
+ <gd name="u16" fmla="+- u15 0 enAng" />
+
+ <gd name="u17" fmla="+- u16 21600000 0" />
+ <gd name="u18" fmla="?: u16 u16 u17" />
+ <gd name="u19" fmla="+- u18 0 cd2" />
+ <gd name="u20" fmla="+- u18 0 21600000" />
+ <gd name="u21" fmla="?: u19 u20 u18" />
+ <gd name="u22" fmla="abs u21" />
+ <gd name="minAng" fmla="*/ u22 -1 1" />
+ <gd name="u23" fmla="abs adj2" />
+ <gd name="a2" fmla="*/ u23 -1 1" />
+ <gd name="aAng" fmla="pin minAng a2 0" />
+
+ <gd name="ptAng" fmla="+- enAng aAng 0" />
+
+
+ <gd name="wtA" fmla="sin rw3 ptAng" />
+ <gd name="htA" fmla="cos rh3 ptAng" />
+ <gd name="dxA" fmla="cat2 rw3 htA wtA" />
+ <gd name="dyA" fmla="sat2 rh3 htA wtA" />
+ <gd name="xA" fmla="+- hc dxA 0" />
+
+ <gd name="yA" fmla="+- vc dyA 0" />
+
+
+ <gd name="wtE" fmla="sin rw1 stAng" />
+ <gd name="htE" fmla="cos rh1 stAng" />
+ <gd name="dxE" fmla="cat2 rw1 htE wtE" />
+ <gd name="dyE" fmla="sat2 rh1 htE wtE" />
+ <gd name="xE" fmla="+- hc dxE 0" />
+
+ <gd name="yE" fmla="+- vc dyE 0" />
+
+
+ <gd name="wtD" fmla="sin rw2 stAng" />
+ <gd name="htD" fmla="cos rh2 stAng" />
+ <gd name="dxD" fmla="cat2 rw2 htD wtD" />
+ <gd name="dyD" fmla="sat2 rh2 htD wtD" />
+ <gd name="xD" fmla="+- hc dxD 0" />
+
+ <gd name="yD" fmla="+- vc dyD 0" />
+
+
+ <gd name="dxG" fmla="cos thh ptAng" />
+ <gd name="dyG" fmla="sin thh ptAng" />
+ <gd name="xG" fmla="+- xH dxG 0" />
+
+ <gd name="yG" fmla="+- yH dyG 0" />
+
+
+ <gd name="dxB" fmla="cos thh ptAng" />
+ <gd name="dyB" fmla="sin thh ptAng" />
+ <gd name="xB" fmla="+- xH 0 dxB 0" />
+
+ <gd name="yB" fmla="+- yH 0 dyB 0" />
+
+
+ <gd name="sx1" fmla="+- xB 0 hc" />
+
+ <gd name="sy1" fmla="+- yB 0 vc" />
+
+ <gd name="sx2" fmla="+- xG 0 hc" />
+
+ <gd name="sy2" fmla="+- yG 0 vc" />
+
+
+ <gd name="rO" fmla="min rw1 rh1" />
+
+ <gd name="x1O" fmla="*/ sx1 rO rw1" />
+
+ <gd name="y1O" fmla="*/ sy1 rO rh1" />
+
+ <gd name="x2O" fmla="*/ sx2 rO rw1" />
+
+ <gd name="y2O" fmla="*/ sy2 rO rh1" />
+
+
+ <gd name="dxO" fmla="+- x2O 0 x1O" />
+ <gd name="dyO" fmla="+- y2O 0 y1O" />
+ <gd name="dO" fmla="mod dxO dyO 0" />
+
+ <gd name="q1" fmla="*/ x1O y2O 1" />
+ <gd name="q2" fmla="*/ x2O y1O 1" />
+ <gd name="DO" fmla="+- q1 0 q2" />
+
+
+ <gd name="q3" fmla="*/ rO rO 1" />
+
+ <gd name="q4" fmla="*/ dO dO 1" />
+
+ <gd name="q5" fmla="*/ q3 q4 1" />
+
+ <gd name="q6" fmla="*/ DO DO 1" />
+
+ <gd name="q7" fmla="+- q5 0 q6" />
+
+ <gd name="q8" fmla="max q7 0" />
+
+ <gd name="sdelO" fmla="sqrt q8" />
+
+ <gd name="ndyO" fmla="*/ dyO -1 1" />
+ <gd name="sdyO" fmla="?: ndyO -1 1" />
+
+ <gd name="q9" fmla="*/ sdyO dxO 1" />
+
+ <gd name="q10" fmla="*/ q9 sdelO 1" />
+
+ <gd name="q11" fmla="*/ DO dyO 1" />
+
+ <gd name="dxF1" fmla="+/ q11 q10 q4" />
+
+ <gd name="q12" fmla="+- q11 0 q10" />
+ <gd name="dxF2" fmla="*/ q12 1 q4" />
+
+
+ <gd name="adyO" fmla="abs dyO" />
+ <gd name="q13" fmla="*/ adyO sdelO 1" />
+
+ <gd name="q14" fmla="*/ DO dxO -1" />
+
+ <gd name="dyF1" fmla="+/ q14 q13 q4" />
+
+ <gd name="q15" fmla="+- q14 0 q13" />
+ <gd name="dyF2" fmla="*/ q15 1 q4" />
+
+
+
+ <gd name="q16" fmla="+- x2O 0 dxF1" />
+ <gd name="q17" fmla="+- x2O 0 dxF2" />
+ <gd name="q18" fmla="+- y2O 0 dyF1" />
+ <gd name="q19" fmla="+- y2O 0 dyF2" />
+ <gd name="q20" fmla="mod q16 q18 0" />
+
+ <gd name="q21" fmla="mod q17 q19 0" />
+
+ <gd name="q22" fmla="+- q21 0 q20" />
+ <gd name="dxF" fmla="?: q22 dxF1 dxF2" />
+
+ <gd name="dyF" fmla="?: q22 dyF1 dyF2" />
+
+ <gd name="sdxF" fmla="*/ dxF rw1 rO" />
+
+ <gd name="sdyF" fmla="*/ dyF rh1 rO" />
+
+ <gd name="xF" fmla="+- hc sdxF 0" />
+
+ <gd name="yF" fmla="+- vc sdyF 0" />
+
+
+
+
+ <gd name="x1I" fmla="*/ sx1 rI rw2" />
+
+ <gd name="y1I" fmla="*/ sy1 rI rh2" />
+
+ <gd name="x2I" fmla="*/ sx2 rI rw2" />
+
+ <gd name="y2I" fmla="*/ sy2 rI rh2" />
+
+
+ <gd name="dxI" fmla="+- x2I 0 x1I" />
+ <gd name="dyI" fmla="+- y2I 0 y1I" />
+ <gd name="dI" fmla="mod dxI dyI 0" />
+ <gd name="v1" fmla="*/ x1I y2I 1" />
+ <gd name="v2" fmla="*/ x2I y1I 1" />
+ <gd name="DI" fmla="+- v1 0 v2" />
+
+ <gd name="v3" fmla="*/ rI rI 1" />
+ <gd name="v4" fmla="*/ dI dI 1" />
+ <gd name="v5" fmla="*/ v3 v4 1" />
+ <gd name="v6" fmla="*/ DI DI 1" />
+ <gd name="v7" fmla="+- v5 0 v6" />
+ <gd name="v8" fmla="max v7 0" />
+ <gd name="sdelI" fmla="sqrt v8" />
+ <gd name="v9" fmla="*/ sdyO dxI 1" />
+ <gd name="v10" fmla="*/ v9 sdelI 1" />
+ <gd name="v11" fmla="*/ DI dyI 1" />
+ <gd name="dxC1" fmla="+/ v11 v10 v4" />
+ <gd name="v12" fmla="+- v11 0 v10" />
+ <gd name="dxC2" fmla="*/ v12 1 v4" />
+
+ <gd name="adyI" fmla="abs dyI" />
+ <gd name="v13" fmla="*/ adyI sdelI 1" />
+ <gd name="v14" fmla="*/ DI dxI -1" />
+ <gd name="dyC1" fmla="+/ v14 v13 v4" />
+ <gd name="v15" fmla="+- v14 0 v13" />
+ <gd name="dyC2" fmla="*/ v15 1 v4" />
+
+ <gd name="v16" fmla="+- x1I 0 dxC1" />
+ <gd name="v17" fmla="+- x1I 0 dxC2" />
+ <gd name="v18" fmla="+- y1I 0 dyC1" />
+ <gd name="v19" fmla="+- y1I 0 dyC2" />
+ <gd name="v20" fmla="mod v16 v18 0" />
+ <gd name="v21" fmla="mod v17 v19 0" />
+ <gd name="v22" fmla="+- v21 0 v20" />
+ <gd name="dxC" fmla="?: v22 dxC1 dxC2" />
+ <gd name="dyC" fmla="?: v22 dyC1 dyC2" />
+ <gd name="sdxC" fmla="*/ dxC rw2 rI" />
+ <gd name="sdyC" fmla="*/ dyC rh2 rI" />
+ <gd name="xC" fmla="+- hc sdxC 0" />
+
+ <gd name="yC" fmla="+- vc sdyC 0" />
+
+
+ <gd name="ist0" fmla="at2 sdxC sdyC" />
+ <gd name="ist1" fmla="+- ist0 21600000 0" />
+ <gd name="istAng0" fmla="?: ist0 ist0 ist1" />
+ <gd name="isw1" fmla="+- stAng 0 istAng0" />
+ <gd name="isw2" fmla="+- isw1 21600000 0" />
+ <gd name="iswAng0" fmla="?: isw1 isw1 isw2" />
+
+ <gd name="istAng" fmla="+- istAng0 iswAng0 0" />
+ <gd name="iswAng" fmla="+- 0 0 iswAng0" />
+
+ <gd name="p1" fmla="+- xF 0 xC" />
+ <gd name="p2" fmla="+- yF 0 yC" />
+ <gd name="p3" fmla="mod p1 p2 0" />
+ <gd name="p4" fmla="*/ p3 1 2" />
+ <gd name="p5" fmla="+- p4 0 thh" />
+ <gd name="xGp" fmla="?: p5 xF xG" />
+ <gd name="yGp" fmla="?: p5 yF yG" />
+ <gd name="xBp" fmla="?: p5 xC xB" />
+ <gd name="yBp" fmla="?: p5 yC yB" />
+
+ <gd name="en0" fmla="at2 sdxF sdyF" />
+ <gd name="en1" fmla="+- en0 21600000 0" />
+ <gd name="en2" fmla="?: en0 en0 en1" />
+ <gd name="sw0" fmla="+- en2 0 stAng" />
+ <gd name="sw1" fmla="+- sw0 0 21600000" />
+ <gd name="swAng" fmla="?: sw0 sw1 sw0" />
+
+
+ <gd name="stAng0" fmla="+- stAng swAng 0" />
+
+ <gd name="swAng0" fmla="+- 0 0 swAng" />
+
+
+ <gd name="wtI" fmla="sin rw3 stAng" />
+ <gd name="htI" fmla="cos rh3 stAng" />
+ <gd name="dxI" fmla="cat2 rw3 htI wtI" />
+ <gd name="dyI" fmla="sat2 rh3 htI wtI" />
+ <gd name="xI" fmla="+- hc dxI 0" />
+
+ <gd name="yI" fmla="+- vc dyI 0" />
+
+
+ <gd name="aI" fmla="+- stAng cd4 0" />
+ <gd name="aA" fmla="+- ptAng 0 cd4" />
+ <gd name="aB" fmla="+- ptAng cd2 0" />
+
+ <gd name="idx" fmla="cos rw1 2700000" />
+ <gd name="idy" fmla="sin rh1 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj2" minAng="minAng" maxAng="0">
+ <pos x="xA" y="yA" />
+ </ahPolar>
+ <ahPolar gdRefAng="adj4" minAng="0" maxAng="21599999">
+ <pos x="xE" y="yE" />
+ </ahPolar>
+ <ahPolar gdRefR="adj1" minR="0" maxR="maxAdj1" gdRefAng="adj3" minAng="0" maxAng="21599999">
+ <pos x="xF" y="yF" />
+ </ahPolar>
+ <ahPolar gdRefR="adj5" minR="0" maxR="25000">
+ <pos x="xB" y="yB" />
+ </ahPolar>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="aI">
+ <pos x="xI" y="yI" />
+ </cxn>
+ <cxn ang="ptAng">
+ <pos x="xGp" y="yGp" />
+ </cxn>
+ <cxn ang="aA">
+ <pos x="xA" y="yA" />
+ </cxn>
+ <cxn ang="aB">
+ <pos x="xBp" y="yBp" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="xE" y="yE" />
+ </moveTo>
+ <lnTo>
+ <pt x="xD" y="yD" />
+ </lnTo>
+ <arcTo wR="rw2" hR="rh2" stAng="istAng" swAng="iswAng" />
+ <lnTo>
+ <pt x="xBp" y="yBp" />
+ </lnTo>
+ <lnTo>
+ <pt x="xA" y="yA" />
+ </lnTo>
+ <lnTo>
+ <pt x="xGp" y="yGp" />
+ </lnTo>
+ <lnTo>
+ <pt x="xF" y="yF" />
+ </lnTo>
+ <arcTo wR="rw1" hR="rh1" stAng="stAng0" swAng="swAng0" />
+ <close />
+ </path>
+ </pathLst>
+
+ </leftCircularArrow>
+ <leftRightArrow>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 w ss" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="x2" fmla="*/ ss a2 100000" />
+ <gd name="x3" fmla="+- r 0 x2" />
+ <gd name="dy" fmla="*/ h a1 200000" />
+ <gd name="y1" fmla="+- vc 0 dy" />
+ <gd name="y2" fmla="+- vc dy 0" />
+ <gd name="dx1" fmla="*/ y1 x2 hd2" />
+ <gd name="x1" fmla="+- x2 0 dx1" />
+ <gd name="x4" fmla="+- x3 dx1 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="x3" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="x1" t="y1" r="x4" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </leftRightArrow>
+ <leftRightArrowCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 48123" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 h ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ 50000 w ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q2" fmla="*/ a3 ss wd2" />
+
+ <gd name="maxAdj4" fmla="+- 100000 0 q2" />
+
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+ <gd name="dy1" fmla="*/ ss a2 100000" />
+
+ <gd name="dy2" fmla="*/ ss a1 200000" />
+
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc dy2 0" />
+ <gd name="y4" fmla="+- vc dy1 0" />
+ <gd name="x1" fmla="*/ ss a3 100000" />
+
+ <gd name="x4" fmla="+- r 0 x1" />
+
+ <gd name="dx2" fmla="*/ w a4 200000" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+
+ <gd name="x3" fmla="+- hc dx2 0" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="x1" y="y2" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="0" maxX="maxAdj3">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="0" maxX="maxAdj4">
+ <pos x="x2" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="t" r="x3" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </leftRightArrowCallout>
+ <leftRightCircularArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 12500" />
+
+ <gd name="adj2" fmla="val 1142319" />
+
+ <gd name="adj3" fmla="val 20457681" />
+
+ <gd name="adj4" fmla="val 11942319" />
+
+ <gd name="adj5" fmla="val 12500" />
+
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a5" fmla="pin 0 adj5 25000" />
+
+ <gd name="maxAdj1" fmla="*/ a5 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="enAng" fmla="pin 1 adj3 21599999" />
+ <gd name="stAng" fmla="pin 0 adj4 21599999" />
+
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="thh" fmla="*/ ss a5 100000" />
+
+ <gd name="th2" fmla="*/ th 1 2" />
+
+
+ <gd name="rw1" fmla="+- wd2 th2 thh" />
+
+ <gd name="rh1" fmla="+- hd2 th2 thh" />
+
+ <gd name="rw2" fmla="+- rw1 0 th" />
+
+ <gd name="rh2" fmla="+- rh1 0 th" />
+
+ <gd name="rw3" fmla="+- rw2 th2 0" />
+
+ <gd name="rh3" fmla="+- rh2 th2 0" />
+
+
+ <gd name="wtH" fmla="sin rw3 enAng" />
+ <gd name="htH" fmla="cos rh3 enAng" />
+ <gd name="dxH" fmla="cat2 rw3 htH wtH" />
+ <gd name="dyH" fmla="sat2 rh3 htH wtH" />
+ <gd name="xH" fmla="+- hc dxH 0" />
+
+ <gd name="yH" fmla="+- vc dyH 0" />
+
+
+ <gd name="rI" fmla="min rw2 rh2" />
+
+ <gd name="u1" fmla="*/ dxH dxH 1" />
+ <gd name="u2" fmla="*/ dyH dyH 1" />
+ <gd name="u3" fmla="*/ rI rI 1" />
+ <gd name="u4" fmla="+- u1 0 u3" />
+ <gd name="u5" fmla="+- u2 0 u3" />
+ <gd name="u6" fmla="*/ u4 u5 u1" />
+ <gd name="u7" fmla="*/ u6 1 u2" />
+ <gd name="u8" fmla="+- 1 0 u7" />
+ <gd name="u9" fmla="sqrt u8" />
+ <gd name="u10" fmla="*/ u4 1 dxH" />
+ <gd name="u11" fmla="*/ u10 1 dyH" />
+ <gd name="u12" fmla="+/ 1 u9 u11" />
+ <gd name="u13" fmla="at2 1 u12" />
+ <gd name="u14" fmla="+- u13 21600000 0" />
+ <gd name="u15" fmla="?: u13 u13 u14" />
+ <gd name="u16" fmla="+- u15 0 enAng" />
+
+ <gd name="u17" fmla="+- u16 21600000 0" />
+ <gd name="u18" fmla="?: u16 u16 u17" />
+ <gd name="u19" fmla="+- u18 0 cd2" />
+ <gd name="u20" fmla="+- u18 0 21600000" />
+ <gd name="u21" fmla="?: u19 u20 u18" />
+ <gd name="maxAng" fmla="abs u21" />
+ <gd name="aAng" fmla="pin 0 adj2 maxAng" />
+
+ <gd name="ptAng" fmla="+- enAng aAng 0" />
+
+
+ <gd name="wtA" fmla="sin rw3 ptAng" />
+ <gd name="htA" fmla="cos rh3 ptAng" />
+ <gd name="dxA" fmla="cat2 rw3 htA wtA" />
+ <gd name="dyA" fmla="sat2 rh3 htA wtA" />
+ <gd name="xA" fmla="+- hc dxA 0" />
+
+ <gd name="yA" fmla="+- vc dyA 0" />
+
+
+ <gd name="dxG" fmla="cos thh ptAng" />
+ <gd name="dyG" fmla="sin thh ptAng" />
+ <gd name="xG" fmla="+- xH dxG 0" />
+
+ <gd name="yG" fmla="+- yH dyG 0" />
+
+
+ <gd name="dxB" fmla="cos thh ptAng" />
+ <gd name="dyB" fmla="sin thh ptAng" />
+ <gd name="xB" fmla="+- xH 0 dxB 0" />
+
+ <gd name="yB" fmla="+- yH 0 dyB 0" />
+
+
+ <gd name="sx1" fmla="+- xB 0 hc" />
+
+ <gd name="sy1" fmla="+- yB 0 vc" />
+
+ <gd name="sx2" fmla="+- xG 0 hc" />
+
+ <gd name="sy2" fmla="+- yG 0 vc" />
+
+
+ <gd name="rO" fmla="min rw1 rh1" />
+
+ <gd name="x1O" fmla="*/ sx1 rO rw1" />
+
+ <gd name="y1O" fmla="*/ sy1 rO rh1" />
+
+ <gd name="x2O" fmla="*/ sx2 rO rw1" />
+
+ <gd name="y2O" fmla="*/ sy2 rO rh1" />
+
+
+ <gd name="dxO" fmla="+- x2O 0 x1O" />
+ <gd name="dyO" fmla="+- y2O 0 y1O" />
+ <gd name="dO" fmla="mod dxO dyO 0" />
+
+ <gd name="q1" fmla="*/ x1O y2O 1" />
+ <gd name="q2" fmla="*/ x2O y1O 1" />
+ <gd name="DO" fmla="+- q1 0 q2" />
+
+
+ <gd name="q3" fmla="*/ rO rO 1" />
+
+ <gd name="q4" fmla="*/ dO dO 1" />
+
+ <gd name="q5" fmla="*/ q3 q4 1" />
+
+ <gd name="q6" fmla="*/ DO DO 1" />
+
+ <gd name="q7" fmla="+- q5 0 q6" />
+
+ <gd name="q8" fmla="max q7 0" />
+
+ <gd name="sdelO" fmla="sqrt q8" />
+
+ <gd name="ndyO" fmla="*/ dyO -1 1" />
+ <gd name="sdyO" fmla="?: ndyO -1 1" />
+
+ <gd name="q9" fmla="*/ sdyO dxO 1" />
+
+ <gd name="q10" fmla="*/ q9 sdelO 1" />
+
+ <gd name="q11" fmla="*/ DO dyO 1" />
+
+ <gd name="dxF1" fmla="+/ q11 q10 q4" />
+
+ <gd name="q12" fmla="+- q11 0 q10" />
+ <gd name="dxF2" fmla="*/ q12 1 q4" />
+
+
+ <gd name="adyO" fmla="abs dyO" />
+ <gd name="q13" fmla="*/ adyO sdelO 1" />
+
+ <gd name="q14" fmla="*/ DO dxO -1" />
+
+ <gd name="dyF1" fmla="+/ q14 q13 q4" />
+
+ <gd name="q15" fmla="+- q14 0 q13" />
+ <gd name="dyF2" fmla="*/ q15 1 q4" />
+
+
+
+ <gd name="q16" fmla="+- x2O 0 dxF1" />
+ <gd name="q17" fmla="+- x2O 0 dxF2" />
+ <gd name="q18" fmla="+- y2O 0 dyF1" />
+ <gd name="q19" fmla="+- y2O 0 dyF2" />
+ <gd name="q20" fmla="mod q16 q18 0" />
+
+ <gd name="q21" fmla="mod q17 q19 0" />
+
+ <gd name="q22" fmla="+- q21 0 q20" />
+ <gd name="dxF" fmla="?: q22 dxF1 dxF2" />
+
+ <gd name="dyF" fmla="?: q22 dyF1 dyF2" />
+
+ <gd name="sdxF" fmla="*/ dxF rw1 rO" />
+
+ <gd name="sdyF" fmla="*/ dyF rh1 rO" />
+
+ <gd name="xF" fmla="+- hc sdxF 0" />
+
+ <gd name="yF" fmla="+- vc sdyF 0" />
+
+
+
+
+ <gd name="x1I" fmla="*/ sx1 rI rw2" />
+
+ <gd name="y1I" fmla="*/ sy1 rI rh2" />
+
+ <gd name="x2I" fmla="*/ sx2 rI rw2" />
+
+ <gd name="y2I" fmla="*/ sy2 rI rh2" />
+
+
+ <gd name="dxI" fmla="+- x2I 0 x1I" />
+ <gd name="dyI" fmla="+- y2I 0 y1I" />
+ <gd name="dI" fmla="mod dxI dyI 0" />
+ <gd name="v1" fmla="*/ x1I y2I 1" />
+ <gd name="v2" fmla="*/ x2I y1I 1" />
+ <gd name="DI" fmla="+- v1 0 v2" />
+
+ <gd name="v3" fmla="*/ rI rI 1" />
+ <gd name="v4" fmla="*/ dI dI 1" />
+ <gd name="v5" fmla="*/ v3 v4 1" />
+ <gd name="v6" fmla="*/ DI DI 1" />
+ <gd name="v7" fmla="+- v5 0 v6" />
+ <gd name="v8" fmla="max v7 0" />
+ <gd name="sdelI" fmla="sqrt v8" />
+ <gd name="v9" fmla="*/ sdyO dxI 1" />
+ <gd name="v10" fmla="*/ v9 sdelI 1" />
+ <gd name="v11" fmla="*/ DI dyI 1" />
+ <gd name="dxC1" fmla="+/ v11 v10 v4" />
+ <gd name="v12" fmla="+- v11 0 v10" />
+ <gd name="dxC2" fmla="*/ v12 1 v4" />
+
+ <gd name="adyI" fmla="abs dyI" />
+ <gd name="v13" fmla="*/ adyI sdelI 1" />
+ <gd name="v14" fmla="*/ DI dxI -1" />
+ <gd name="dyC1" fmla="+/ v14 v13 v4" />
+ <gd name="v15" fmla="+- v14 0 v13" />
+ <gd name="dyC2" fmla="*/ v15 1 v4" />
+
+ <gd name="v16" fmla="+- x1I 0 dxC1" />
+ <gd name="v17" fmla="+- x1I 0 dxC2" />
+ <gd name="v18" fmla="+- y1I 0 dyC1" />
+ <gd name="v19" fmla="+- y1I 0 dyC2" />
+ <gd name="v20" fmla="mod v16 v18 0" />
+ <gd name="v21" fmla="mod v17 v19 0" />
+ <gd name="v22" fmla="+- v21 0 v20" />
+ <gd name="dxC" fmla="?: v22 dxC1 dxC2" />
+ <gd name="dyC" fmla="?: v22 dyC1 dyC2" />
+ <gd name="sdxC" fmla="*/ dxC rw2 rI" />
+ <gd name="sdyC" fmla="*/ dyC rh2 rI" />
+ <gd name="xC" fmla="+- hc sdxC 0" />
+
+ <gd name="yC" fmla="+- vc sdyC 0" />
+
+
+ <gd name="wtI" fmla="sin rw3 stAng" />
+ <gd name="htI" fmla="cos rh3 stAng" />
+ <gd name="dxI" fmla="cat2 rw3 htI wtI" />
+ <gd name="dyI" fmla="sat2 rh3 htI wtI" />
+ <gd name="xI" fmla="+- hc dxI 0" />
+
+ <gd name="yI" fmla="+- vc dyI 0" />
+
+
+ <gd name="lptAng" fmla="+- stAng 0 aAng" />
+
+
+ <gd name="wtL" fmla="sin rw3 lptAng" />
+ <gd name="htL" fmla="cos rh3 lptAng" />
+ <gd name="dxL" fmla="cat2 rw3 htL wtL" />
+ <gd name="dyL" fmla="sat2 rh3 htL wtL" />
+ <gd name="xL" fmla="+- hc dxL 0" />
+
+ <gd name="yL" fmla="+- vc dyL 0" />
+
+
+ <gd name="dxK" fmla="cos thh lptAng" />
+ <gd name="dyK" fmla="sin thh lptAng" />
+ <gd name="xK" fmla="+- xI dxK 0" />
+
+ <gd name="yK" fmla="+- yI dyK 0" />
+
+
+ <gd name="dxJ" fmla="cos thh lptAng" />
+ <gd name="dyJ" fmla="sin thh lptAng" />
+ <gd name="xJ" fmla="+- xI 0 dxJ 0" />
+
+ <gd name="yJ" fmla="+- yI 0 dyJ 0" />
+
+
+ <gd name="p1" fmla="+- xF 0 xC" />
+ <gd name="p2" fmla="+- yF 0 yC" />
+ <gd name="p3" fmla="mod p1 p2 0" />
+ <gd name="p4" fmla="*/ p3 1 2" />
+ <gd name="p5" fmla="+- p4 0 thh" />
+ <gd name="xGp" fmla="?: p5 xF xG" />
+ <gd name="yGp" fmla="?: p5 yF yG" />
+ <gd name="xBp" fmla="?: p5 xC xB" />
+ <gd name="yBp" fmla="?: p5 yC yB" />
+
+ <gd name="en0" fmla="at2 sdxF sdyF" />
+ <gd name="en1" fmla="+- en0 21600000 0" />
+ <gd name="en2" fmla="?: en0 en0 en1" />
+ <gd name="od0" fmla="+- en2 0 enAng" />
+ <gd name="od1" fmla="+- od0 21600000 0" />
+ <gd name="od2" fmla="?: od0 od0 od1" />
+
+ <gd name="st0" fmla="+- stAng 0 od2" />
+ <gd name="st1" fmla="+- st0 21600000 0" />
+ <gd name="st2" fmla="?: st0 st0 st1" />
+
+ <gd name="sw0" fmla="+- en2 0 st2" />
+ <gd name="sw1" fmla="+- sw0 21600000 0" />
+ <gd name="swAng" fmla="?: sw0 sw0 sw1" />
+
+
+ <gd name="ist0" fmla="at2 sdxC sdyC" />
+ <gd name="ist1" fmla="+- ist0 21600000 0" />
+ <gd name="istAng" fmla="?: ist0 ist0 ist1" />
+
+ <gd name="id0" fmla="+- istAng 0 enAng" />
+ <gd name="id1" fmla="+- id0 0 21600000" />
+ <gd name="id2" fmla="?: id0 id1 id0" />
+
+ <gd name="ien0" fmla="+- stAng 0 id2" />
+ <gd name="ien1" fmla="+- ien0 0 21600000" />
+ <gd name="ien2" fmla="?: ien1 ien1 ien0" />
+
+ <gd name="isw1" fmla="+- ien2 0 istAng" />
+ <gd name="isw2" fmla="+- isw1 0 21600000" />
+ <gd name="iswAng" fmla="?: isw1 isw2 isw1" />
+
+
+ <gd name="wtE" fmla="sin rw1 st2" />
+ <gd name="htE" fmla="cos rh1 st2" />
+ <gd name="dxE" fmla="cat2 rw1 htE wtE" />
+ <gd name="dyE" fmla="sat2 rh1 htE wtE" />
+ <gd name="xE" fmla="+- hc dxE 0" />
+
+ <gd name="yE" fmla="+- vc dyE 0" />
+
+
+ <gd name="wtD" fmla="sin rw2 ien2" />
+ <gd name="htD" fmla="cos rh2 ien2" />
+ <gd name="dxD" fmla="cat2 rw2 htD wtD" />
+ <gd name="dyD" fmla="sat2 rh2 htD wtD" />
+ <gd name="xD" fmla="+- hc dxD 0" />
+
+ <gd name="yD" fmla="+- vc dyD 0" />
+
+
+ <gd name="xKp" fmla="?: p5 xE xK" />
+ <gd name="yKp" fmla="?: p5 yE yK" />
+ <gd name="xJp" fmla="?: p5 xD xJ" />
+ <gd name="yJp" fmla="?: p5 yD yJ" />
+
+ <gd name="aL" fmla="+- lptAng 0 cd4" />
+ <gd name="aA" fmla="+- ptAng cd4 0" />
+ <gd name="aB" fmla="+- ptAng cd2 0" />
+ <gd name="aJ" fmla="+- lptAng cd2 0" />
+
+ <gd name="idx" fmla="cos rw1 2700000" />
+ <gd name="idy" fmla="sin rh1 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj2" minAng="0" maxAng="maxAng">
+ <pos x="xA" y="yA" />
+ </ahPolar>
+ <ahPolar gdRefAng="adj4" minAng="0" maxAng="21599999">
+ <pos x="xE" y="yE" />
+ </ahPolar>
+ <ahPolar gdRefR="adj1" minR="0" maxR="maxAdj1" gdRefAng="adj3" minAng="0" maxAng="21599999">
+ <pos x="xF" y="yF" />
+ </ahPolar>
+ <ahPolar gdRefR="adj5" minR="0" maxR="25000">
+ <pos x="xB" y="yB" />
+ </ahPolar>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="aL">
+ <pos x="xL" y="yL" />
+ </cxn>
+ <cxn ang="lptAng">
+ <pos x="xKp" y="yKp" />
+ </cxn>
+ <cxn ang="ptAng">
+ <pos x="xGp" y="yGp" />
+ </cxn>
+ <cxn ang="aA">
+ <pos x="xA" y="yA" />
+ </cxn>
+ <cxn ang="aB">
+ <pos x="xBp" y="yBp" />
+ </cxn>
+ <cxn ang="aJ">
+ <pos x="xJp" y="yJp" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="xL" y="yL" />
+ </moveTo>
+ <lnTo>
+ <pt x="xKp" y="yKp" />
+ </lnTo>
+ <lnTo>
+ <pt x="xE" y="yE" />
+ </lnTo>
+ <arcTo wR="rw1" hR="rh1" stAng="st2" swAng="swAng" />
+ <lnTo>
+ <pt x="xGp" y="yGp" />
+ </lnTo>
+ <lnTo>
+ <pt x="xA" y="yA" />
+ </lnTo>
+ <lnTo>
+ <pt x="xBp" y="yBp" />
+ </lnTo>
+ <lnTo>
+ <pt x="xC" y="yC" />
+ </lnTo>
+ <arcTo wR="rw2" hR="rh2" stAng="istAng" swAng="iswAng" />
+ <lnTo>
+ <pt x="xJp" y="yJp" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </leftRightCircularArrow>
+ <leftRightRibbon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ <gd name="adj3" fmla="val 16667" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a3" fmla="pin 0 adj3 33333" />
+ <gd name="maxAdj1" fmla="+- 100000 0 a3" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+
+ <gd name="w1" fmla="+- wd2 0 wd32" />
+ <gd name="maxAdj2" fmla="*/ 100000 w1 ss" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+
+ <gd name="x1" fmla="*/ ss a2 100000" />
+
+ <gd name="x4" fmla="+- r 0 x1" />
+
+ <gd name="dy1" fmla="*/ h a1 200000" />
+
+ <gd name="dy2" fmla="*/ h a3 -200000" />
+
+ <gd name="ly1" fmla="+- vc dy2 dy1" />
+
+ <gd name="ry4" fmla="+- vc dy1 dy2" />
+
+ <gd name="ly2" fmla="+- ly1 dy1 0" />
+
+ <gd name="ry3" fmla="+- b 0 ly2" />
+
+ <gd name="ly4" fmla="*/ ly2 2 1" />
+
+ <gd name="ry1" fmla="+- b 0 ly4" />
+
+ <gd name="ly3" fmla="+- ly4 0 ly1" />
+
+ <gd name="ry2" fmla="+- b 0 ly3" />
+
+
+ <gd name="hR" fmla="*/ a3 ss 400000" />
+
+ <gd name="x2" fmla="+- hc 0 wd32" />
+
+ <gd name="x3" fmla="+- hc wd32 0" />
+
+ <gd name="y1" fmla="+- ly1 hR 0" />
+
+ <gd name="y2" fmla="+- ry2 0 hR" />
+
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="x4" y="ry2" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="33333">
+ <pos x="x3" y="ry2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="ry3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x4" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="ly4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="ly2" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x4" y="ry1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="ly1" r="x4" b="ry4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="ly2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="ly1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="ly1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd2" />
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x4" y="ry2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="ry1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="ry3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="ry4" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="ry4" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="ly3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="ly3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="ly4" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x3" y="y1" />
+ </moveTo>
+ <arcTo wR="wd32" hR="hR" stAng="0" swAng="cd4" />
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x3" y="ry2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="ly2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="ly1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="ly1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd2" />
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x4" y="ry2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="ry1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="ry3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="ry4" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="ry4" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="ly3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="ly3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="ly4" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x3" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x3" y="ry2" />
+ </lnTo>
+ <moveTo>
+ <pt x="x2" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="ly3" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </leftRightRibbon>
+ <leftRightUpArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="q1" fmla="+- 100000 0 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ q1 1 2" />
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="x1" fmla="*/ ss a3 100000" />
+ <gd name="dx2" fmla="*/ ss a2 100000" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x5" fmla="+- hc dx2 0" />
+ <gd name="dx3" fmla="*/ ss a1 200000" />
+
+ <gd name="x3" fmla="+- hc 0 dx3" />
+ <gd name="x4" fmla="+- hc dx3 0" />
+ <gd name="x6" fmla="+- r 0 x1" />
+
+ <gd name="dy2" fmla="*/ ss a2 50000" />
+
+ <gd name="y2" fmla="+- b 0 dy2" />
+ <gd name="y4" fmla="+- b 0 dx2" />
+ <gd name="y3" fmla="+- y4 0 dx3" />
+ <gd name="y5" fmla="+- y4 dx3 0" />
+ <gd name="il" fmla="*/ dx3 x1 dx2" />
+ <gd name="ir" fmla="+- r 0 il" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="x3" y="x1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="x1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y5" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y4" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="y3" r="ir" b="y5" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y4" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </leftRightUpArrow>
+ <leftUpArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="+- 100000 0 maxAdj1" />
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="x1" fmla="*/ ss a3 100000" />
+
+ <gd name="dx2" fmla="*/ ss a2 50000" />
+
+ <gd name="x2" fmla="+- r 0 dx2" />
+ <gd name="y2" fmla="+- b 0 dx2" />
+ <gd name="dx4" fmla="*/ ss a2 100000" />
+
+ <gd name="x4" fmla="+- r 0 dx4" />
+ <gd name="y4" fmla="+- b 0 dx4" />
+ <gd name="dx3" fmla="*/ ss a1 200000" />
+
+ <gd name="x3" fmla="+- x4 0 dx3" />
+ <gd name="x5" fmla="+- x4 dx3 0" />
+ <gd name="y3" fmla="+- y4 0 dx3" />
+ <gd name="y5" fmla="+- y4 dx3 0" />
+ <gd name="il" fmla="*/ dx3 x1 dx4" />
+ <gd name="cx1" fmla="+/ x1 x5 2" />
+ <gd name="cy1" fmla="+/ x1 y5 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="x3" y="y3" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="x3" y="x1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x4" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x2" y="x1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="cx1" y="y5" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x5" y="cy1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="x1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="y3" r="x4" b="y5" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y4" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </leftUpArrow>
+ <lightningBolt>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="x1" fmla="*/ w 5022 21600" />
+ <gd name="x3" fmla="*/ w 8472 21600" />
+ <gd name="x4" fmla="*/ w 8757 21600" />
+
+ <gd name="x5" fmla="*/ w 10012 21600" />
+ <gd name="x8" fmla="*/ w 12860 21600" />
+ <gd name="x9" fmla="*/ w 13917 21600" />
+
+ <gd name="x11" fmla="*/ w 16577 21600" />
+ <gd name="y1" fmla="*/ h 3890 21600" />
+ <gd name="y2" fmla="*/ h 6080 21600" />
+ <gd name="y4" fmla="*/ h 7437 21600" />
+
+ <gd name="y6" fmla="*/ h 9705 21600" />
+ <gd name="y7" fmla="*/ h 12007 21600" />
+ <gd name="y10" fmla="*/ h 14277 21600" />
+
+ <gd name="y11" fmla="*/ h 14915 21600" />
+
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x3" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="l" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y6" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x5" y="y11" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="r" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x11" y="y7" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x8" y="y2" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x4" t="y4" r="x9" b="y10" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path w="21600" h="21600">
+ <moveTo>
+ <pt x="8472" y="0" />
+ </moveTo>
+ <lnTo>
+ <pt x="12860" y="6080" />
+ </lnTo>
+ <lnTo>
+ <pt x="11050" y="6797" />
+ </lnTo>
+ <lnTo>
+ <pt x="16577" y="12007" />
+ </lnTo>
+ <lnTo>
+ <pt x="14767" y="12877" />
+ </lnTo>
+ <lnTo>
+ <pt x="21600" y="21600" />
+ </lnTo>
+ <lnTo>
+ <pt x="10012" y="14915" />
+ </lnTo>
+ <lnTo>
+ <pt x="12222" y="13987" />
+ </lnTo>
+ <lnTo>
+ <pt x="5022" y="9705" />
+ </lnTo>
+ <lnTo>
+ <pt x="7602" y="8382" />
+ </lnTo>
+ <lnTo>
+ <pt x="0" y="3890" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </lightningBolt>
+ <line>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="l" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="r" y="b" />
+ </cxn>
+ </cxnLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ </path>
+ </pathLst>
+ </line>
+ <lineInv>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="r" y="t" />
+ </cxn>
+ </cxnLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ </path>
+ </pathLst>
+ </lineInv>
+ <mathDivide>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 23520" />
+
+ <gd name="adj2" fmla="val 5880" />
+
+ <gd name="adj3" fmla="val 11760" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+ <gd name="a1" fmla="pin 1000 adj1 36745" />
+ <gd name="ma1" fmla="+- 0 0 a1" />
+
+ <gd name="ma3h" fmla="+/ 73490 ma1 4" />
+
+ <gd name="ma3w" fmla="*/ 36745 w h" />
+
+ <gd name="maxAdj3" fmla="min ma3h ma3w" />
+ <gd name="a3" fmla="pin 1000 adj3 maxAdj3" />
+ <gd name="m4a3" fmla="*/ -4 a3 1" />
+
+ <gd name="maxAdj2" fmla="+- 73490 m4a3 a1" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+
+ <gd name="dy1" fmla="*/ h a1 200000" />
+
+ <gd name="yg" fmla="*/ h a2 100000" />
+
+ <gd name="rad" fmla="*/ h a3 100000" />
+
+ <gd name="dx1" fmla="*/ w 73490 200000" />
+
+
+ <gd name="y3" fmla="+- vc 0 dy1" />
+
+ <gd name="y4" fmla="+- vc dy1 0" />
+
+ <gd name="a" fmla="+- yg rad 0" />
+ <gd name="y2" fmla="+- y3 0 a" />
+
+ <gd name="y1" fmla="+- y2 0 rad" />
+
+ <gd name="y5" fmla="+- b 0 y1" />
+
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+
+ <gd name="x3" fmla="+- hc dx1 0" />
+
+ <gd name="x2" fmla="+- hc 0 rad" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="1000" maxY="36745">
+ <pos x="l" y="y3" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="r" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="1000" maxX="maxAdj3">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x3" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y5" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y3" r="x3" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="hc" y="y1" />
+ </moveTo>
+ <arcTo hR="rad" wR="rad" stAng="3cd4" swAng="21600000" />
+ <close />
+ <moveTo>
+ <pt x="hc" y="y5" />
+ </moveTo>
+ <arcTo hR="rad" wR="rad" stAng="cd4" swAng="21600000" />
+ <close />
+ <moveTo>
+ <pt x="x1" y="y3" />
+ </moveTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </mathDivide>
+ <mathEqual>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 23520" />
+
+ <gd name="adj2" fmla="val 11760" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 36745" />
+
+
+ <gd name="2a1" fmla="*/ a1 2 1" />
+
+ <gd name="mAdj2" fmla="+- 100000 0 2a1" />
+
+ <gd name="a2" fmla="pin 0 adj2 mAdj2" />
+ <gd name="dy1" fmla="*/ h a1 100000" />
+
+ <gd name="dy2" fmla="*/ h a2 200000" />
+
+ <gd name="dx1" fmla="*/ w 73490 200000" />
+
+
+ <gd name="y2" fmla="+- vc 0 dy2" />
+
+ <gd name="y3" fmla="+- vc dy2 0" />
+
+ <gd name="y1" fmla="+- y2 0 dy1" />
+
+ <gd name="y4" fmla="+- y3 dy1 0" />
+
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+
+ <gd name="x2" fmla="+- hc dx1 0" />
+
+
+
+ <gd name="yC1" fmla="+/ y1 y2 2" />
+
+ <gd name="yC2" fmla="+/ y3 y4 2" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="36745">
+ <pos x="l" y="y1" />
+ </ahXY>
+
+ <ahXY gdRefY="adj2" minY="0" maxY="mAdj2">
+ <pos x="r" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x2" y="yC1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="yC2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="yC1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="yC2" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y1" r="x2" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x1" y="y3" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </mathEqual>
+ <mathMinus>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 23520" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="dy1" fmla="*/ h a1 200000" />
+
+ <gd name="dx1" fmla="*/ w 73490 200000" />
+
+
+ <gd name="y1" fmla="+- vc 0 dy1" />
+
+ <gd name="y2" fmla="+- vc dy1 0" />
+
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+
+ <gd name="x2" fmla="+- hc dx1 0" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="l" y="y1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y1" r="x2" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </mathMinus>
+ <mathMultiply>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 23520" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+
+
+
+
+ <gd name="a1" fmla="pin 0 adj1 51965" />
+
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+
+ <gd name="a" fmla="at2 w h" />
+
+ <gd name="sa" fmla="sin 1 a" />
+ <gd name="ca" fmla="cos 1 a" />
+ <gd name="ta" fmla="tan 1 a" />
+
+
+ <gd name="dl" fmla="mod w h 0" />
+
+ <gd name="rw" fmla="*/ dl 51965 100000" />
+
+
+
+ <gd name="lM" fmla="+- dl 0 rw" />
+ <gd name="xM" fmla="*/ ca lM 2" />
+ <gd name="yM" fmla="*/ sa lM 2" />
+
+
+ <gd name="dxAM" fmla="*/ sa th 2" />
+ <gd name="dyAM" fmla="*/ ca th 2" />
+ <gd name="xA" fmla="+- xM 0 dxAM" />
+ <gd name="yA" fmla="+- yM dyAM 0" />
+
+
+ <gd name="xB" fmla="+- xM dxAM 0" />
+ <gd name="yB" fmla="+- yM 0 dyAM" />
+
+
+ <gd name="xBC" fmla="+- hc 0 xB" />
+ <gd name="yBC" fmla="*/ xBC ta 1" />
+ <gd name="yC" fmla="+- yBC yB 0" />
+
+
+ <gd name="xD" fmla="+- r 0 xB" />
+ <gd name="xE" fmla="+- r 0 xA" />
+
+ <gd name="yFE" fmla="+- vc 0 yA" />
+ <gd name="xFE" fmla="*/ yFE 1 ta" />
+ <gd name="xF" fmla="+- xE 0 xFE" />
+ <gd name="xL" fmla="+- xA xFE 0" />
+ <gd name="yG" fmla="+- b 0 yA" />
+ <gd name="yH" fmla="+- b 0 yB" />
+ <gd name="yI" fmla="+- b 0 yC" />
+
+
+ <gd name="xC2" fmla="+- r 0 xM" />
+
+ <gd name="yC3" fmla="+- b 0 yM" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="51965">
+ <pos x="l" y="th" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd2">
+ <pos x="xM" y="yM" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="xC2" y="yM" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="xC2" y="yC3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="xM" y="yC3" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="xA" t="yB" r="xE" b="yH" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="xA" y="yA" />
+ </moveTo>
+ <lnTo>
+ <pt x="xB" y="yB" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="yC" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD" y="yB" />
+ </lnTo>
+ <lnTo>
+ <pt x="xE" y="yA" />
+ </lnTo>
+ <lnTo>
+ <pt x="xF" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="xE" y="yG" />
+ </lnTo>
+ <lnTo>
+ <pt x="xD" y="yH" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="yI" />
+ </lnTo>
+ <lnTo>
+ <pt x="xB" y="yH" />
+ </lnTo>
+ <lnTo>
+ <pt x="xA" y="yG" />
+ </lnTo>
+ <lnTo>
+ <pt x="xL" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </mathMultiply>
+ <mathNotEqual>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 23520" />
+
+ <gd name="adj2" fmla="val 6600000" />
+
+ <gd name="adj3" fmla="val 11760" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="crAng" fmla="pin 4200000 adj2 6600000" />
+
+
+ <gd name="2a1" fmla="*/ a1 2 1" />
+ <gd name="maxAdj3" fmla="+- 100000 0 2a1" />
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+
+ <gd name="dy1" fmla="*/ h a1 100000" />
+
+ <gd name="dy2" fmla="*/ h a3 200000" />
+
+ <gd name="dx1" fmla="*/ w 73490 200000" />
+
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+
+ <gd name="x8" fmla="+- hc dx1 0" />
+
+
+
+ <gd name="y2" fmla="+- vc 0 dy2" />
+
+ <gd name="y3" fmla="+- vc dy2 0" />
+
+ <gd name="y1" fmla="+- y2 0 dy1" />
+
+ <gd name="y4" fmla="+- y3 dy1 0" />
+
+
+ <gd name="cadj2" fmla="+- crAng 0 cd4" />
+ <gd name="xadj2" fmla="tan hd2 cadj2" />
+
+
+
+ <gd name="len" fmla="mod xadj2 hd2 0" />
+
+
+
+ <gd name="bhw" fmla="*/ len dy1 hd2" />
+
+ <gd name="bhw2" fmla="*/ bhw 1 2" />
+ <gd name="x7" fmla="+- hc xadj2 bhw2" />
+
+ <gd name="dx67" fmla="*/ xadj2 y1 hd2" />
+ <gd name="x6" fmla="+- x7 0 dx67" />
+
+ <gd name="dx57" fmla="*/ xadj2 y2 hd2" />
+ <gd name="x5" fmla="+- x7 0 dx57" />
+
+ <gd name="dx47" fmla="*/ xadj2 y3 hd2" />
+ <gd name="x4" fmla="+- x7 0 dx47" />
+
+ <gd name="dx37" fmla="*/ xadj2 y4 hd2" />
+ <gd name="x3" fmla="+- x7 0 dx37" />
+
+ <gd name="dx27" fmla="*/ xadj2 2 1" />
+ <gd name="x2" fmla="+- x7 0 dx27" />
+
+
+ <gd name="rx7" fmla="+- x7 bhw 0" />
+
+ <gd name="rx6" fmla="+- x6 bhw 0" />
+
+ <gd name="rx5" fmla="+- x5 bhw 0" />
+
+ <gd name="rx4" fmla="+- x4 bhw 0" />
+
+ <gd name="rx3" fmla="+- x3 bhw 0" />
+
+ <gd name="rx2" fmla="+- x2 bhw 0" />
+
+
+
+ <gd name="dx7" fmla="*/ dy1 hd2 len" />
+ <gd name="rxt" fmla="+- x7 dx7 0" />
+
+ <gd name="lxt" fmla="+- rx7 0 dx7" />
+
+ <gd name="rx" fmla="?: cadj2 rxt rx7" />
+
+ <gd name="lx" fmla="?: cadj2 x7 lxt" />
+
+
+ <gd name="dy3" fmla="*/ dy1 xadj2 len" />
+ <gd name="dy4" fmla="+- 0 0 dy3" />
+ <gd name="ry" fmla="?: cadj2 dy3 t" />
+
+ <gd name="ly" fmla="?: cadj2 t dy4" />
+
+
+ <gd name="dlx" fmla="+- w 0 rx" />
+
+ <gd name="drx" fmla="+- w 0 lx" />
+
+
+ <gd name="dly" fmla="+- h 0 ry" />
+
+ <gd name="dry" fmla="+- h 0 ly" />
+
+
+
+ <gd name="xC1" fmla="+/ rx lx 2" />
+
+ <gd name="xC2" fmla="+/ drx dlx 2" />
+
+
+ <gd name="yC1" fmla="+/ ry ly 2" />
+
+ <gd name="yC2" fmla="+/ y1 y2 2" />
+
+ <gd name="yC3" fmla="+/ y3 y4 2" />
+
+ <gd name="yC4" fmla="+/ dry dly 2" />
+
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="50000">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahPolar gdRefAng="adj2" minAng="4200000" maxAng="6600000">
+ <pos x="lx" y="t" />
+ </ahPolar>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x8" y="yC2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x8" y="yC3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="xC2" y="yC4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="yC2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="yC3" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="xC1" y="yC1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y1" r="x8" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x6" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="lx" y="ly" />
+ </lnTo>
+ <lnTo>
+ <pt x="rx" y="ry" />
+ </lnTo>
+ <lnTo>
+ <pt x="rx6" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="rx5" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="rx4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="rx3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="drx" y="dry" />
+ </lnTo>
+ <lnTo>
+ <pt x="dlx" y="dly" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </mathNotEqual>
+ <mathPlus>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 23520" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 73490" />
+ <gd name="dx1" fmla="*/ w 73490 200000" />
+
+ <gd name="dy1" fmla="*/ h 73490 200000" />
+
+ <gd name="dx2" fmla="*/ ss a1 200000" />
+
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+
+ <gd name="x3" fmla="+- hc dx2 0" />
+
+ <gd name="x4" fmla="+- hc dx1 0" />
+
+
+ <gd name="y1" fmla="+- vc 0 dy1" />
+
+ <gd name="y2" fmla="+- vc 0 dx2" />
+
+ <gd name="y3" fmla="+- vc dx2 0" />
+
+ <gd name="y4" fmla="+- vc dy1 0" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="73490">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x4" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y2" r="x4" b="y3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </mathPlus>
+ <moon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 87500" />
+ <gd name="g0" fmla="*/ ss a 100000" />
+ <gd name="g0w" fmla="*/ g0 w ss" />
+ <gd name="g1" fmla="+- ss 0 g0" />
+ <gd name="g2" fmla="*/ g0 g0 g1" />
+ <gd name="g3" fmla="*/ ss ss g1" />
+ <gd name="g4" fmla="*/ g3 2 1" />
+ <gd name="g5" fmla="+- g4 0 g2" />
+ <gd name="g6" fmla="+- g5 0 g0" />
+ <gd name="g6w" fmla="*/ g6 w ss" />
+ <gd name="g7" fmla="*/ g5 1 2" />
+ <gd name="g8" fmla="+- g7 0 g0" />
+ <gd name="dy1" fmla="*/ g8 hd2 ss" />
+
+ <gd name="g10h" fmla="+- vc 0 dy1" />
+ <gd name="g11h" fmla="+- vc dy1 0" />
+ <gd name="g12" fmla="*/ g0 9598 32768" />
+ <gd name="g12w" fmla="*/ g12 w ss" />
+ <gd name="g13" fmla="+- ss 0 g12" />
+ <gd name="q1" fmla="*/ ss ss 1" />
+ <gd name="q2" fmla="*/ g13 g13 1" />
+ <gd name="q3" fmla="+- q1 0 q2" />
+ <gd name="q4" fmla="sqrt q3" />
+ <gd name="dy4" fmla="*/ q4 hd2 ss" />
+ <gd name="g15h" fmla="+- vc 0 dy4" />
+ <gd name="g16h" fmla="+- vc dy4 0" />
+ <gd name="g17w" fmla="+- g6w 0 g0w" />
+ <gd name="g18w" fmla="*/ g17w 1 2" />
+
+
+ <gd name="dx2p" fmla="+- g0w g18w w" />
+ <gd name="dx2" fmla="*/ dx2p -1 1" />
+
+ <gd name="dy2" fmla="*/ hd2 -1 1" />
+
+ <gd name="stAng1" fmla="at2 dx2 dy2" />
+ <gd name="enAngp1" fmla="at2 dx2 hd2" />
+ <gd name="enAng1" fmla="+- enAngp1 0 21600000" />
+ <gd name="swAng1" fmla="+- enAng1 0 stAng1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="87500">
+ <pos x="g0w" y="vc" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="r" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="r" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="g0w" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="g12w" t="g15h" r="g0w" b="g16h" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="r" y="b" />
+ </moveTo>
+ <arcTo wR="w" hR="hd2" stAng="cd4" swAng="cd2" />
+ <arcTo wR="g18w" hR="dy1" stAng="stAng1" swAng="swAng1" />
+ <close />
+ </path>
+ </pathLst>
+
+ </moon>
+ <nonIsoscelesTrapezoid>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 50000 w ss" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj" />
+ <gd name="x1" fmla="*/ ss a1 200000" />
+
+ <gd name="x2" fmla="*/ ss a1 100000" />
+
+ <gd name="dx3" fmla="*/ ss a2 100000" />
+
+ <gd name="x3" fmla="+- r 0 dx3" />
+ <gd name="x4" fmla="+/ r x3 2" />
+ <gd name="il" fmla="*/ wd3 a1 maxAdj" />
+
+ <gd name="adjm" fmla="max a1 a2" />
+ <gd name="it" fmla="*/ hd3 adjm maxAdj" />
+
+ <gd name="irt" fmla="*/ wd3 a2 maxAdj" />
+ <gd name="ir" fmla="+- r 0 irt" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj">
+ <pos x="x2" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj">
+ <pos x="x3" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x4" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+
+ <rect l="il" t="it" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </nonIsoscelesTrapezoid>
+ <noSmoking>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 18750" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dr" fmla="*/ ss a 100000" />
+ <gd name="iwd2" fmla="+- wd2 0 dr" />
+ <gd name="ihd2" fmla="+- hd2 0 dr" />
+ <gd name="ang" fmla="at2 w h" />
+ <gd name="ct" fmla="cos ihd2 ang" />
+ <gd name="st" fmla="sin iwd2 ang" />
+ <gd name="m" fmla="mod ct st 0" />
+ <gd name="n" fmla="*/ iwd2 ihd2 m" />
+ <gd name="drd2" fmla="*/ dr 1 2" />
+ <gd name="dang" fmla="at2 n drd2" />
+ <gd name="2dang" fmla="*/ dang 2 1" />
+ <gd name="swAng" fmla="+- -10800000 2dang 0" />
+ <gd name="t3" fmla="at2 w h" />
+ <gd name="stAng1" fmla="+- t3 0 dang" />
+ <gd name="stAng2" fmla="+- stAng1 0 cd2" />
+ <gd name="ct1" fmla="cos ihd2 stAng1" />
+ <gd name="st1" fmla="sin iwd2 stAng1" />
+ <gd name="m1" fmla="mod ct1 st1 0" />
+ <gd name="n1" fmla="*/ iwd2 ihd2 m1" />
+ <gd name="dx1" fmla="cos n1 stAng1" />
+ <gd name="dy1" fmla="sin n1 stAng1" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc dy1 0" />
+ <gd name="x2" fmla="+- hc 0 dx1" />
+ <gd name="y2" fmla="+- vc 0 dy1" />
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefR="adj" minR="0" maxR="50000">
+ <pos x="dr" y="vc" />
+ </ahPolar>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="3cd4" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="stAng1" swAng="swAng" />
+ <close />
+ <moveTo>
+ <pt x="x2" y="y2" />
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="stAng2" swAng="swAng" />
+ <close />
+ </path>
+ </pathLst>
+
+ </noSmoking>
+ <notchedRightArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 100000 w ss" />
+
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="dx2" fmla="*/ ss a2 100000" />
+ <gd name="x2" fmla="+- r 0 dx2" />
+ <gd name="dy1" fmla="*/ h a1 200000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc dy1 0" />
+ <gd name="x1" fmla="*/ dy1 dx2 hd2" />
+ <gd name="x3" fmla="+- r 0 x1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="r" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x2" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x1" t="y1" r="x3" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </notchedRightArrow>
+ <octagon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 29289" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="+- r 0 x1" />
+ <gd name="y2" fmla="+- b 0 x1" />
+ <gd name="il" fmla="*/ x1 1 2" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 il" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="x1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="x1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="x1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </octagon>
+ <parallelogram>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 100000 w ss" />
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="x1" fmla="*/ ss a 200000" />
+ <gd name="x2" fmla="*/ ss a 100000" />
+ <gd name="x6" fmla="+- r 0 x1" />
+ <gd name="x5" fmla="+- r 0 x2" />
+ <gd name="x3" fmla="*/ x5 1 2" />
+ <gd name="x4" fmla="+- r 0 x3" />
+ <gd name="il" fmla="*/ wd2 a maxAdj" />
+ <gd name="q1" fmla="*/ 5 a maxAdj" />
+ <gd name="q2" fmla="+/ 1 q1 12" />
+ <gd name="il" fmla="*/ q2 w 1" />
+ <gd name="it" fmla="*/ q2 h 1" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 it" />
+ <gd name="q3" fmla="*/ h hc x2" />
+ <gd name="y1" fmla="pin 0 q3 h" />
+ <gd name="y2" fmla="+- b 0 y1" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="maxAdj">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x4" y="t" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </parallelogram>
+ <pentagon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="hf" fmla="val 105146" />
+ <gd name="vf" fmla="val 110557" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="swd2" fmla="*/ wd2 hf 100000" />
+ <gd name="shd2" fmla="*/ hd2 vf 100000" />
+ <gd name="svc" fmla="*/ vc vf 100000" />
+ <gd name="dx1" fmla="cos swd2 1080000" />
+ <gd name="dx2" fmla="cos swd2 18360000" />
+ <gd name="dy1" fmla="sin shd2 1080000" />
+ <gd name="dy2" fmla="sin shd2 18360000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- svc 0 dy1" />
+ <gd name="y2" fmla="+- svc 0 dy2" />
+ <gd name="it" fmla="*/ y1 dx2 dx1" />
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="it" r="x3" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </pentagon>
+ <pie>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 0" />
+ <gd name="adj2" fmla="val 16200000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="stAng" fmla="pin 0 adj1 21599999" />
+ <gd name="enAng" fmla="pin 0 adj2 21599999" />
+ <gd name="sw1" fmla="+- enAng 0 stAng" />
+ <gd name="sw2" fmla="+- sw1 21600000 0" />
+ <gd name="swAng" fmla="?: sw1 sw1 sw2" />
+ <gd name="wt1" fmla="sin wd2 stAng" />
+ <gd name="ht1" fmla="cos hd2 stAng" />
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1" />
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc dy1 0" />
+ <gd name="wt2" fmla="sin wd2 enAng" />
+ <gd name="ht2" fmla="cos hd2 enAng" />
+ <gd name="dx2" fmla="cat2 wd2 ht2 wt2" />
+ <gd name="dy2" fmla="sat2 hd2 ht2 wt2" />
+ <gd name="x2" fmla="+- hc dx2 0" />
+ <gd name="y2" fmla="+- vc dy2 0" />
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="x1" y="y1" />
+ </ahPolar>
+ <ahPolar gdRefAng="adj2" minAng="0" maxAng="21599999">
+ <pos x="x2" y="y2" />
+ </ahPolar>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="ir" r="it" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng" swAng="swAng" />
+ <lnTo>
+ <pt x="hc" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </pie>
+ <pieWedge>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="g1" fmla="cos w 13500000" />
+ <gd name="g2" fmla="sin h 13500000" />
+ <gd name="x1" fmla="+- r g1 0" />
+ <gd name="y1" fmla="+- b g2 0" />
+ </gdLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ </cxnLst>
+ <rect l="x1" t="y1" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <arcTo wR="w" hR="h" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </pieWedge>
+ <plaque>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 16667" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="+- r 0 x1" />
+
+ <gd name="y2" fmla="+- b 0 x1" />
+ <gd name="il" fmla="*/ x1 70711 100000" />
+
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 il" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="x1" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="-5400000" />
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="-5400000" />
+ <close />
+ </path>
+ </pathLst>
+
+ </plaque>
+ <plaqueTabs>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="md" fmla="mod w h 0" />
+ <gd name="dx" fmla="*/ 1 md 20" />
+
+ <gd name="y1" fmla="+- 0 b dx" />
+
+ <gd name="x1" fmla="+- 0 r dx" />
+
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd2">
+ <pos x="l" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="dx" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="dx" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="t" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="dx" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="t" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="dx" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="b" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="dx" t="dx" r="x1" b="y1" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="dx" y="t" />
+ </lnTo>
+ <arcTo wR="dx" hR="dx" stAng="0" swAng="cd4" />
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <arcTo wR="dx" hR="dx" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="r" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="dx" />
+ </lnTo>
+ <arcTo wR="dx" hR="dx" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x1" y="b" />
+ </moveTo>
+ <arcTo wR="dx" hR="dx" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </plaqueTabs>
+ <plus>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="+- r 0 x1" />
+ <gd name="y2" fmla="+- b 0 x1" />
+ <gd name="d" fmla="+- w 0 h" />
+ <gd name="il" fmla="?: d l x1" />
+ <gd name="ir" fmla="?: d r x2" />
+ <gd name="it" fmla="?: d x1 t" />
+ <gd name="ib" fmla="?: d y2 b" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="x1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </plus>
+ <quadArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 22500" />
+
+ <gd name="adj2" fmla="val 22500" />
+
+ <gd name="adj3" fmla="val 22500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="q1" fmla="+- 100000 0 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ q1 1 2" />
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="x1" fmla="*/ ss a3 100000" />
+ <gd name="dx2" fmla="*/ ss a2 100000" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x5" fmla="+- hc dx2 0" />
+ <gd name="dx3" fmla="*/ ss a1 200000" />
+
+ <gd name="x3" fmla="+- hc 0 dx3" />
+ <gd name="x4" fmla="+- hc dx3 0" />
+ <gd name="x6" fmla="+- r 0 x1" />
+
+ <gd name="y2" fmla="+- vc 0 dx2" />
+ <gd name="y5" fmla="+- vc dx2 0" />
+ <gd name="y3" fmla="+- vc 0 dx3" />
+ <gd name="y4" fmla="+- vc dx3 0" />
+ <gd name="y6" fmla="+- b 0 x1" />
+ <gd name="il" fmla="*/ dx3 x1 dx2" />
+ <gd name="ir" fmla="+- r 0 il" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="x3" y="x1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="x1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="y3" r="ir" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="x1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y5" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </quadArrow>
+ <quadArrowCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 18515" />
+
+ <gd name="adj2" fmla="val 18515" />
+
+ <gd name="adj3" fmla="val 18515" />
+
+ <gd name="adj4" fmla="val 48123" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="+- 50000 0 a2" />
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q2" fmla="*/ a3 2 1" />
+
+ <gd name="maxAdj4" fmla="+- 100000 0 q2" />
+
+ <gd name="a4" fmla="pin a1 adj4 maxAdj4" />
+ <gd name="dx2" fmla="*/ ss a2 100000" />
+
+ <gd name="dx3" fmla="*/ ss a1 200000" />
+
+ <gd name="ah" fmla="*/ ss a3 100000" />
+
+ <gd name="dx1" fmla="*/ w a4 200000" />
+
+ <gd name="dy1" fmla="*/ h a4 200000" />
+
+
+ <gd name="x8" fmla="+- r 0 ah" />
+ <gd name="x2" fmla="+- hc 0 dx1" />
+ <gd name="x7" fmla="+- hc dx1 0" />
+ <gd name="x3" fmla="+- hc 0 dx2" />
+ <gd name="x6" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc 0 dx3" />
+ <gd name="x5" fmla="+- hc dx3 0" />
+
+ <gd name="y8" fmla="+- b 0 ah" />
+ <gd name="y2" fmla="+- vc 0 dy1" />
+ <gd name="y7" fmla="+- vc dy1 0" />
+ <gd name="y3" fmla="+- vc 0 dx2" />
+ <gd name="y6" fmla="+- vc dx2 0" />
+ <gd name="y4" fmla="+- vc 0 dx3" />
+ <gd name="y5" fmla="+- vc dx3 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="x4" y="ah" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="x3" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="ah" />
+ </ahXY>
+ <ahXY gdRefY="adj4" minY="a1" maxY="maxAdj4">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="y2" r="x7" b="y7" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="ah" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="ah" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="ah" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="ah" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="ah" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="ah" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="ah" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="ah" y="y6" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </quadArrowCallout>
+ <rect>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </rect>
+ <ribbon>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 16667" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 33333" />
+ <gd name="a2" fmla="pin 25000 adj2 75000" />
+
+
+ <gd name="x10" fmla="+- r 0 wd8" />
+
+ <gd name="dx2" fmla="*/ w a2 200000" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+
+ <gd name="x9" fmla="+- hc dx2 0" />
+
+ <gd name="x3" fmla="+- x2 wd32 0" />
+ <gd name="x8" fmla="+- x9 0 wd32" />
+ <gd name="x5" fmla="+- x2 wd8 0" />
+
+ <gd name="x6" fmla="+- x9 0 wd8" />
+
+ <gd name="x4" fmla="+- x5 0 wd32" />
+ <gd name="x7" fmla="+- x6 wd32 0" />
+ <gd name="y1" fmla="*/ h a1 200000" />
+
+ <gd name="y2" fmla="*/ h a1 100000" />
+
+ <gd name="y4" fmla="+- b 0 y2" />
+
+ <gd name="y3" fmla="*/ y4 1 2" />
+
+ <gd name="hR" fmla="*/ h a1 400000" />
+
+ <gd name="y5" fmla="+- b 0 hR" />
+ <gd name="y6" fmla="+- y2 0 hR" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="33333">
+ <pos x="hc" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="25000" maxX="75000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd8" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x10" y="y3" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="y2" r="x9" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="t" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x8" y="y2" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x7" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y5" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="x3" y="b" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="wd8" y="y3" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x5" y="hR" />
+ </moveTo>
+ <arcTo wR="wd32" hR="hR" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x5" y="y2" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x6" y="hR" />
+ </moveTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd2" swAng="-5400000" />
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="t" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x8" y="y2" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x7" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y5" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="x3" y="b" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="wd8" y="y3" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x5" y="hR" />
+ </moveTo>
+ <lnTo>
+ <pt x="x5" y="y2" />
+ </lnTo>
+ <moveTo>
+ <pt x="x6" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x6" y="hR" />
+ </lnTo>
+ <moveTo>
+ <pt x="x2" y="y4" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y6" />
+ </lnTo>
+ <moveTo>
+ <pt x="x9" y="y6" />
+ </moveTo>
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </ribbon>
+ <ribbon2>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 16667" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 33333" />
+ <gd name="a2" fmla="pin 25000 adj2 75000" />
+
+
+ <gd name="x10" fmla="+- r 0 wd8" />
+
+ <gd name="dx2" fmla="*/ w a2 200000" />
+
+ <gd name="x2" fmla="+- hc 0 dx2" />
+
+ <gd name="x9" fmla="+- hc dx2 0" />
+
+ <gd name="x3" fmla="+- x2 wd32 0" />
+ <gd name="x8" fmla="+- x9 0 wd32" />
+ <gd name="x5" fmla="+- x2 wd8 0" />
+
+ <gd name="x6" fmla="+- x9 0 wd8" />
+
+ <gd name="x4" fmla="+- x5 0 wd32" />
+ <gd name="x7" fmla="+- x6 wd32 0" />
+ <gd name="dy1" fmla="*/ h a1 200000" />
+
+ <gd name="y1" fmla="+- b 0 dy1" />
+ <gd name="dy2" fmla="*/ h a1 100000" />
+
+ <gd name="y2" fmla="+- b 0 dy2" />
+ <gd name="y4" fmla="+- t dy2 0" />
+
+ <gd name="y3" fmla="+/ y4 b 2" />
+
+ <gd name="hR" fmla="*/ h a1 400000" />
+
+
+ <gd name="y6" fmla="+- b 0 hR" />
+ <gd name="y7" fmla="+- y1 0 hR" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="33333">
+ <pos x="hc" y="y2" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="25000" maxX="75000">
+ <pos x="x2" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="wd8" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x10" y="y3" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x2" t="t" r="x9" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x4" y="b" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x8" y="y2" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x7" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="hR" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="0" swAng="-5400000" />
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="wd8" y="y3" />
+ </lnTo>
+ <close />
+ </path>
+ <path stroke="false" fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x5" y="y6" />
+ </moveTo>
+ <arcTo wR="wd32" hR="hR" stAng="0" swAng="-5400000" />
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x5" y="y2" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x6" y="y6" />
+ </moveTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="wd8" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="hR" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x8" y="t" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="b" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <arcTo wR="wd32" hR="hR" stAng="3cd4" swAng="cd2" />
+ <close />
+ <moveTo>
+ <pt x="x5" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x5" y="y6" />
+ </lnTo>
+ <moveTo>
+ <pt x="x6" y="y6" />
+ </moveTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <moveTo>
+ <pt x="x2" y="y7" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <moveTo>
+ <pt x="x9" y="y4" />
+ </moveTo>
+ <lnTo>
+ <pt x="x9" y="y7" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </ribbon2>
+ <rightArrow>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 100000 w ss" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="dx1" fmla="*/ ss a2 100000" />
+ <gd name="x1" fmla="+- r 0 dx1" />
+ <gd name="dy1" fmla="*/ h a1 200000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc dy1 0" />
+ <gd name="dx2" fmla="*/ y1 dx1 hd2" />
+ <gd name="x2" fmla="+- x1 dx2 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x1" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="y1" r="x2" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </rightArrow>
+ <rightArrowCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 64977" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 h ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ 100000 w ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q2" fmla="*/ a3 ss w" />
+
+ <gd name="maxAdj4" fmla="+- 100000 0 q2" />
+
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+ <gd name="dy1" fmla="*/ ss a2 100000" />
+
+ <gd name="dy2" fmla="*/ ss a1 200000" />
+
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc dy2 0" />
+ <gd name="y4" fmla="+- vc dy1 0" />
+ <gd name="dx3" fmla="*/ ss a3 100000" />
+
+ <gd name="x3" fmla="+- r 0 dx3" />
+ <gd name="x2" fmla="*/ w a4 100000" />
+
+ <gd name="x1" fmla="*/ x2 1 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="x3" y="y2" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="r" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj3" minX="0" maxX="maxAdj3">
+ <pos x="x3" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="0" maxX="maxAdj4">
+ <pos x="x2" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x1" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="x2" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </rightArrowCallout>
+ <rightBrace>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 8333" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 100000" />
+ <gd name="q1" fmla="+- 100000 0 a2" />
+ <gd name="q2" fmla="min q1 a2" />
+ <gd name="q3" fmla="*/ q2 1 2" />
+ <gd name="maxAdj1" fmla="*/ q3 h ss" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="y1" fmla="*/ ss a1 100000" />
+ <gd name="y3" fmla="*/ h a2 100000" />
+ <gd name="y2" fmla="+- y3 0 y1" />
+ <gd name="y4" fmla="+- b 0 y1" />
+ <gd name="dx1" fmla="cos wd2 2700000" />
+ <gd name="dy1" fmla="sin y1 2700000" />
+ <gd name="ir" fmla="+- l dx1 0" />
+ <gd name="it" fmla="+- y1 0 dy1" />
+ <gd name="ib" fmla="+- b dy1 y1" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="maxAdj1">
+ <pos x="hc" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="100000">
+ <pos x="r" y="y3" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="l" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="r" y="y3" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="l" y="b" />
+ </cxn>
+ </cxnLst>
+ <rect l="l" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <arcTo wR="wd2" hR="y1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="hc" y="y2" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd2" swAng="-5400000" />
+ <arcTo wR="wd2" hR="y1" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="hc" y="y4" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <arcTo wR="wd2" hR="y1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="hc" y="y2" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="cd2" swAng="-5400000" />
+ <arcTo wR="wd2" hR="y1" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="hc" y="y4" />
+ </lnTo>
+ <arcTo wR="wd2" hR="y1" stAng="0" swAng="cd4" />
+ </path>
+ </pathLst>
+ </rightBrace>
+ <rightBracket>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 8333" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 50000 h ss" />
+
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="y1" fmla="*/ ss a 100000" />
+
+ <gd name="y2" fmla="+- b 0 y1" />
+
+ <gd name="dx1" fmla="cos w 2700000" />
+ <gd name="dy1" fmla="sin y1 2700000" />
+ <gd name="ir" fmla="+- l dx1 0" />
+ <gd name="it" fmla="+- y1 0 dy1" />
+ <gd name="ib" fmla="+- b dy1 y1" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="maxAdj">
+ <pos x="r" y="y1" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="l" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <arcTo wR="w" hR="y1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <arcTo wR="w" hR="y1" stAng="0" swAng="cd4" />
+ <close />
+ </path>
+ <path fill="none">
+
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <arcTo wR="w" hR="y1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <arcTo wR="w" hR="y1" stAng="0" swAng="cd4" />
+ </path>
+ </pathLst>
+
+ </rightBracket>
+ <round1Rect>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 16667" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dx1" fmla="*/ ss a 100000" />
+ <gd name="x1" fmla="+- r 0 dx1" />
+ <gd name="idx" fmla="*/ dx1 29289 100000" />
+ <gd name="ir" fmla="+- r 0 idx" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <arcTo wR="dx1" hR="dx1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </round1Rect>
+ <round2DiagRect>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 16667" />
+ <gd name="adj2" fmla="val 0" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="x1" fmla="*/ ss a1 100000" />
+ <gd name="y1" fmla="+- b 0 x1" />
+ <gd name="a" fmla="*/ ss a2 100000" />
+ <gd name="x2" fmla="+- r 0 a" />
+ <gd name="y2" fmla="+- b 0 a" />
+ <gd name="dx1" fmla="*/ x1 29289 100000" />
+ <gd name="dx2" fmla="*/ a 29289 100000" />
+ <gd name="d" fmla="+- dx1 0 dx2" />
+ <gd name="dx" fmla="?: d dx1 dx2" />
+ <gd name="ir" fmla="+- r 0 dx" />
+ <gd name="ib" fmla="+- b 0 dx" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="dx" t="dx" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <arcTo wR="a" hR="a" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="a" y="b" />
+ </lnTo>
+ <arcTo wR="a" hR="a" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="l" y="x1" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </round2DiagRect>
+ <round2SameRect>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 16667" />
+ <gd name="adj2" fmla="val 0" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+
+ <gd name="tx1" fmla="*/ ss a1 100000" />
+ <gd name="tx2" fmla="+- r 0 tx1" />
+
+ <gd name="bx1" fmla="*/ ss a2 100000" />
+ <gd name="bx2" fmla="+- r 0 bx1" />
+ <gd name="by1" fmla="+- b 0 bx1" />
+ <gd name="d" fmla="+- tx1 0 bx1" />
+ <gd name="tdx" fmla="*/ tx1 29289 100000" />
+ <gd name="bdx" fmla="*/ bx1 29289 100000" />
+ <gd name="il" fmla="?: d tdx bdx" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 bdx" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="50000">
+ <pos x="tx2" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="bx1" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="tdx" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="tx1" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="tx2" y="t" />
+ </lnTo>
+ <arcTo wR="tx1" hR="tx1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="by1" />
+ </lnTo>
+ <arcTo wR="bx1" hR="bx1" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="bx1" y="b" />
+ </lnTo>
+ <arcTo wR="bx1" hR="bx1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="l" y="tx1" />
+ </lnTo>
+ <arcTo wR="tx1" hR="tx1" stAng="cd2" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </round2SameRect>
+ <roundRect>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 16667" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="x1" fmla="*/ ss a 100000" />
+ <gd name="x2" fmla="+- r 0 x1" />
+ <gd name="y2" fmla="+- b 0 x1" />
+ <gd name="il" fmla="*/ x1 29289 100000" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 il" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="x1" />
+ </moveTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+ </roundRect>
+ <rtTriangle>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="it" fmla="*/ h 7 12" />
+ <gd name="ir" fmla="*/ w 7 12" />
+ <gd name="ib" fmla="*/ h 11 12" />
+ </gdLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="l" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="r" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="hc" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="wd12" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="l" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </rtTriangle>
+ <smileyFace>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 4653" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin -4653 adj 4653" />
+ <gd name="x1" fmla="*/ w 4969 21699" />
+
+ <gd name="x2" fmla="*/ w 6215 21600" />
+
+ <gd name="x3" fmla="*/ w 13135 21600" />
+
+ <gd name="x4" fmla="*/ w 16640 21600" />
+
+ <gd name="y1" fmla="*/ h 7570 21600" />
+
+ <gd name="y3" fmla="*/ h 16515 21600" />
+
+ <gd name="dy2" fmla="*/ h a 100000" />
+
+ <gd name="y2" fmla="+- y3 0 dy2" />
+
+ <gd name="y4" fmla="+- y3 dy2 0" />
+
+ <gd name="dy3" fmla="*/ h a 50000" />
+
+ <gd name="y5" fmla="+- y4 dy3 0" />
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ <gd name="wR" fmla="*/ w 1125 21600" />
+ <gd name="hR" fmla="*/ h 1125 21600" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="-4653" maxY="4653">
+ <pos x="hc" y="y4" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="21600000" />
+ <close />
+ </path>
+ <path fill="darkenLess" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x2" y="y1" />
+ </moveTo>
+ <arcTo wR="wR" hR="hR" stAng="cd2" swAng="21600000" />
+ <moveTo>
+ <pt x="x3" y="y1" />
+ </moveTo>
+ <arcTo wR="wR" hR="hR" stAng="cd2" swAng="21600000" />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x1" y="y2" />
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="y5" />
+ <pt x="x4" y="y2" />
+ </quadBezTo>
+ </path>
+ <path fill="none">
+
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="21600000" />
+ <close />
+ </path>
+ </pathLst>
+
+ </smileyFace>
+ <snip1Rect>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 16667" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dx1" fmla="*/ ss a 100000" />
+ <gd name="x1" fmla="+- r 0 dx1" />
+ <gd name="it" fmla="*/ dx1 1 2" />
+ <gd name="ir" fmla="+/ x1 r 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="it" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="dx1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </snip1Rect>
+ <snip2DiagRect>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 0" />
+ <gd name="adj2" fmla="val 16667" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="lx1" fmla="*/ ss a1 100000" />
+ <gd name="lx2" fmla="+- r 0 lx1" />
+ <gd name="ly1" fmla="+- b 0 lx1" />
+ <gd name="rx1" fmla="*/ ss a2 100000" />
+ <gd name="rx2" fmla="+- r 0 rx1" />
+ <gd name="ry1" fmla="+- b 0 rx1" />
+ <gd name="d" fmla="+- lx1 0 rx1" />
+ <gd name="dx" fmla="?: d lx1 rx1" />
+ <gd name="il" fmla="*/ dx 1 2" />
+
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 il" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="50000">
+ <pos x="lx1" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="rx2" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="lx1" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="rx2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="rx1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="ly1" />
+ </lnTo>
+ <lnTo>
+ <pt x="lx2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="rx1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="ry1" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="lx1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </snip2DiagRect>
+ <snip2SameRect>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 16667" />
+ <gd name="adj2" fmla="val 0" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="tx1" fmla="*/ ss a1 100000" />
+ <gd name="tx2" fmla="+- r 0 tx1" />
+ <gd name="bx1" fmla="*/ ss a2 100000" />
+ <gd name="bx2" fmla="+- r 0 bx1" />
+ <gd name="by1" fmla="+- b 0 bx1" />
+ <gd name="d" fmla="+- tx1 0 bx1" />
+ <gd name="dx" fmla="?: d tx1 bx1" />
+ <gd name="il" fmla="*/ dx 1 2" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="it" fmla="*/ tx1 1 2" />
+ <gd name="ib" fmla="+/ by1 b 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="50000">
+ <pos x="tx2" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="bx1" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="tx1" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="tx2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="tx1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="by1" />
+ </lnTo>
+ <lnTo>
+ <pt x="bx2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="bx1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="by1" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="tx1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </snip2SameRect>
+ <snipRoundRect>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 16667" />
+ <gd name="adj2" fmla="val 16667" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 50000" />
+ <gd name="a2" fmla="pin 0 adj2 50000" />
+ <gd name="x1" fmla="*/ ss a1 100000" />
+ <gd name="dx2" fmla="*/ ss a2 100000" />
+ <gd name="x2" fmla="+- r 0 dx2" />
+ <gd name="il" fmla="*/ x1 29289 100000" />
+
+ <gd name="ir" fmla="+/ x2 r 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="50000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="50000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="il" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="dx2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="x1" />
+ </lnTo>
+ <arcTo wR="x1" hR="x1" stAng="cd2" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </snipRoundRect>
+ <squareTabs>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="md" fmla="mod w h 0" />
+ <gd name="dx" fmla="*/ 1 md 20" />
+
+ <gd name="y1" fmla="+- 0 b dx" />
+
+ <gd name="x1" fmla="+- 0 r dx" />
+
+ </gdLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd2">
+ <pos x="l" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="dx" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="dx" y="dx" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="dx" y="x1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="dx" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="t" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="dx" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="t" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="dx" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x1" y="dx" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x1" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="dx" t="dx" r="x1" b="y1" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="dx" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="dx" y="dx" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="dx" />
+ </lnTo>
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="dx" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="dx" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x1" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="dx" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="dx" />
+ </lnTo>
+ <close />
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </squareTabs>
+ <star10>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 42533" />
+ <gd name="hf" fmla="val 105146" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="swd2" fmla="*/ wd2 hf 100000" />
+ <gd name="dx1" fmla="*/ swd2 95106 100000" />
+ <gd name="dx2" fmla="*/ swd2 58779 100000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="dy1" fmla="*/ hd2 80902 100000" />
+ <gd name="dy2" fmla="*/ hd2 30902 100000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc dy2 0" />
+ <gd name="y4" fmla="+- vc dy1 0" />
+ <gd name="iwd2" fmla="*/ swd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx1" fmla="*/ iwd2 80902 100000" />
+ <gd name="sdx2" fmla="*/ iwd2 30902 100000" />
+ <gd name="sdy1" fmla="*/ ihd2 95106 100000" />
+ <gd name="sdy2" fmla="*/ ihd2 58779 100000" />
+ <gd name="sx1" fmla="+- hc 0 iwd2" />
+ <gd name="sx2" fmla="+- hc 0 sdx1" />
+ <gd name="sx3" fmla="+- hc 0 sdx2" />
+ <gd name="sx4" fmla="+- hc sdx2 0" />
+ <gd name="sx5" fmla="+- hc sdx1 0" />
+ <gd name="sx6" fmla="+- hc iwd2 0" />
+ <gd name="sy1" fmla="+- vc 0 sdy1" />
+ <gd name="sy2" fmla="+- vc 0 sdy2" />
+ <gd name="sy3" fmla="+- vc sdy2 0" />
+ <gd name="sy4" fmla="+- vc sdy1 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x4" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="y4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x3" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="sx2" t="sy2" r="sx5" b="sy3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx2" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star10>
+ <star12>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 37500" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dx1" fmla="cos wd2 1800000" />
+
+ <gd name="dy1" fmla="sin hd2 3600000" />
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x3" fmla="*/ w 3 4" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y3" fmla="*/ h 3 4" />
+ <gd name="y4" fmla="+- vc dy1 0" />
+ <gd name="iwd2" fmla="*/ wd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx1" fmla="cos iwd2 900000" />
+ <gd name="sdx2" fmla="cos iwd2 2700000" />
+ <gd name="sdx3" fmla="cos iwd2 4500000" />
+ <gd name="sdy1" fmla="sin ihd2 4500000" />
+ <gd name="sdy2" fmla="sin ihd2 2700000" />
+ <gd name="sdy3" fmla="sin ihd2 900000" />
+ <gd name="sx1" fmla="+- hc 0 sdx1" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc 0 sdx3" />
+ <gd name="sx4" fmla="+- hc sdx3 0" />
+ <gd name="sx5" fmla="+- hc sdx2 0" />
+ <gd name="sx6" fmla="+- hc sdx1 0" />
+ <gd name="sy1" fmla="+- vc 0 sdy1" />
+ <gd name="sy2" fmla="+- vc 0 sdy2" />
+ <gd name="sy3" fmla="+- vc 0 sdy3" />
+ <gd name="sy4" fmla="+- vc sdy3 0" />
+ <gd name="sy5" fmla="+- vc sdy2 0" />
+ <gd name="sy6" fmla="+- vc sdy1 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x4" y="hd4" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="wd4" y="y4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="hd4" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="wd4" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x3" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="sx2" t="sy2" r="sx5" b="sy5" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx1" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="hd4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="wd4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="hd4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="wd4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="sy4" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star12>
+ <star16>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 37500" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dx1" fmla="*/ wd2 92388 100000" />
+ <gd name="dx2" fmla="*/ wd2 70711 100000" />
+ <gd name="dx3" fmla="*/ wd2 38268 100000" />
+ <gd name="dy1" fmla="*/ hd2 92388 100000" />
+ <gd name="dy2" fmla="*/ hd2 70711 100000" />
+ <gd name="dy3" fmla="*/ hd2 38268 100000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc 0 dx3" />
+ <gd name="x4" fmla="+- hc dx3 0" />
+ <gd name="x5" fmla="+- hc dx2 0" />
+ <gd name="x6" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc 0 dy3" />
+ <gd name="y4" fmla="+- vc dy3 0" />
+ <gd name="y5" fmla="+- vc dy2 0" />
+ <gd name="y6" fmla="+- vc dy1 0" />
+ <gd name="iwd2" fmla="*/ wd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx1" fmla="*/ iwd2 98079 100000" />
+ <gd name="sdx2" fmla="*/ iwd2 83147 100000" />
+ <gd name="sdx3" fmla="*/ iwd2 55557 100000" />
+ <gd name="sdx4" fmla="*/ iwd2 19509 100000" />
+ <gd name="sdy1" fmla="*/ ihd2 98079 100000" />
+ <gd name="sdy2" fmla="*/ ihd2 83147 100000" />
+ <gd name="sdy3" fmla="*/ ihd2 55557 100000" />
+ <gd name="sdy4" fmla="*/ ihd2 19509 100000" />
+ <gd name="sx1" fmla="+- hc 0 sdx1" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc 0 sdx3" />
+ <gd name="sx4" fmla="+- hc 0 sdx4" />
+ <gd name="sx5" fmla="+- hc sdx4 0" />
+ <gd name="sx6" fmla="+- hc sdx3 0" />
+ <gd name="sx7" fmla="+- hc sdx2 0" />
+ <gd name="sx8" fmla="+- hc sdx1 0" />
+ <gd name="sy1" fmla="+- vc 0 sdy1" />
+ <gd name="sy2" fmla="+- vc 0 sdy2" />
+ <gd name="sy3" fmla="+- vc 0 sdy3" />
+ <gd name="sy4" fmla="+- vc 0 sdy4" />
+ <gd name="sy5" fmla="+- vc sdy4 0" />
+ <gd name="sy6" fmla="+- vc sdy3 0" />
+ <gd name="sy7" fmla="+- vc sdy2 0" />
+ <gd name="sy8" fmla="+- vc sdy1 0" />
+ <gd name="idx" fmla="cos iwd2 2700000" />
+ <gd name="idy" fmla="sin ihd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x5" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="y3" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="y4" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x5" y="y5" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x4" y="y6" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y6" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x2" y="y5" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y4" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x3" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x4" y="y1" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx1" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx7" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx8" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx8" y="sy5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx7" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy8" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="sy5" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </star16>
+ <star24>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 37500" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dx1" fmla="cos wd2 900000" />
+ <gd name="dx2" fmla="cos wd2 1800000" />
+ <gd name="dx3" fmla="cos wd2 2700000" />
+ <gd name="dx4" fmla="val wd4" />
+ <gd name="dx5" fmla="cos wd2 4500000" />
+ <gd name="dy1" fmla="sin hd2 4500000" />
+ <gd name="dy2" fmla="sin hd2 3600000" />
+ <gd name="dy3" fmla="sin hd2 2700000" />
+ <gd name="dy4" fmla="val hd4" />
+ <gd name="dy5" fmla="sin hd2 900000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc 0 dx3" />
+ <gd name="x4" fmla="+- hc 0 dx4" />
+ <gd name="x5" fmla="+- hc 0 dx5" />
+ <gd name="x6" fmla="+- hc dx5 0" />
+ <gd name="x7" fmla="+- hc dx4 0" />
+ <gd name="x8" fmla="+- hc dx3 0" />
+ <gd name="x9" fmla="+- hc dx2 0" />
+ <gd name="x10" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc 0 dy3" />
+ <gd name="y4" fmla="+- vc 0 dy4" />
+ <gd name="y5" fmla="+- vc 0 dy5" />
+ <gd name="y6" fmla="+- vc dy5 0" />
+ <gd name="y7" fmla="+- vc dy4 0" />
+ <gd name="y8" fmla="+- vc dy3 0" />
+ <gd name="y9" fmla="+- vc dy2 0" />
+ <gd name="y10" fmla="+- vc dy1 0" />
+ <gd name="iwd2" fmla="*/ wd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx1" fmla="*/ iwd2 99144 100000" />
+ <gd name="sdx2" fmla="*/ iwd2 92388 100000" />
+ <gd name="sdx3" fmla="*/ iwd2 79335 100000" />
+ <gd name="sdx4" fmla="*/ iwd2 60876 100000" />
+ <gd name="sdx5" fmla="*/ iwd2 38268 100000" />
+ <gd name="sdx6" fmla="*/ iwd2 13053 100000" />
+ <gd name="sdy1" fmla="*/ ihd2 99144 100000" />
+ <gd name="sdy2" fmla="*/ ihd2 92388 100000" />
+ <gd name="sdy3" fmla="*/ ihd2 79335 100000" />
+ <gd name="sdy4" fmla="*/ ihd2 60876 100000" />
+ <gd name="sdy5" fmla="*/ ihd2 38268 100000" />
+ <gd name="sdy6" fmla="*/ ihd2 13053 100000" />
+ <gd name="sx1" fmla="+- hc 0 sdx1" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc 0 sdx3" />
+ <gd name="sx4" fmla="+- hc 0 sdx4" />
+ <gd name="sx5" fmla="+- hc 0 sdx5" />
+ <gd name="sx6" fmla="+- hc 0 sdx6" />
+ <gd name="sx7" fmla="+- hc sdx6 0" />
+ <gd name="sx8" fmla="+- hc sdx5 0" />
+ <gd name="sx9" fmla="+- hc sdx4 0" />
+ <gd name="sx10" fmla="+- hc sdx3 0" />
+ <gd name="sx11" fmla="+- hc sdx2 0" />
+ <gd name="sx12" fmla="+- hc sdx1 0" />
+ <gd name="sy1" fmla="+- vc 0 sdy1" />
+ <gd name="sy2" fmla="+- vc 0 sdy2" />
+ <gd name="sy3" fmla="+- vc 0 sdy3" />
+ <gd name="sy4" fmla="+- vc 0 sdy4" />
+ <gd name="sy5" fmla="+- vc 0 sdy5" />
+ <gd name="sy6" fmla="+- vc 0 sdy6" />
+ <gd name="sy7" fmla="+- vc sdy6 0" />
+ <gd name="sy8" fmla="+- vc sdy5 0" />
+ <gd name="sy9" fmla="+- vc sdy4 0" />
+ <gd name="sy10" fmla="+- vc sdy3 0" />
+ <gd name="sy11" fmla="+- vc sdy2 0" />
+ <gd name="sy12" fmla="+- vc sdy1 0" />
+ <gd name="idx" fmla="cos iwd2 2700000" />
+ <gd name="idy" fmla="sin ihd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="ssd2">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx1" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx7" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx8" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx9" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx10" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx11" y="sy5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx12" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx12" y="sy7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx11" y="sy8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx10" y="sy9" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx9" y="sy10" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y9" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx8" y="sy11" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y10" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx7" y="sy12" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy12" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y10" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy11" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y9" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy10" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy9" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="sy7" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star24>
+ <star32>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 37500" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dx1" fmla="*/ wd2 98079 100000" />
+ <gd name="dx2" fmla="*/ wd2 92388 100000" />
+ <gd name="dx3" fmla="*/ wd2 83147 100000" />
+ <gd name="dx4" fmla="cos wd2 2700000" />
+ <gd name="dx5" fmla="*/ wd2 55557 100000" />
+ <gd name="dx6" fmla="*/ wd2 38268 100000" />
+ <gd name="dx7" fmla="*/ wd2 19509 100000" />
+ <gd name="dy1" fmla="*/ hd2 98079 100000" />
+ <gd name="dy2" fmla="*/ hd2 92388 100000" />
+ <gd name="dy3" fmla="*/ hd2 83147 100000" />
+ <gd name="dy4" fmla="sin hd2 2700000" />
+ <gd name="dy5" fmla="*/ hd2 55557 100000" />
+ <gd name="dy6" fmla="*/ hd2 38268 100000" />
+ <gd name="dy7" fmla="*/ hd2 19509 100000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc 0 dx3" />
+ <gd name="x4" fmla="+- hc 0 dx4" />
+ <gd name="x5" fmla="+- hc 0 dx5" />
+ <gd name="x6" fmla="+- hc 0 dx6" />
+ <gd name="x7" fmla="+- hc 0 dx7" />
+ <gd name="x8" fmla="+- hc dx7 0" />
+ <gd name="x9" fmla="+- hc dx6 0" />
+ <gd name="x10" fmla="+- hc dx5 0" />
+ <gd name="x11" fmla="+- hc dx4 0" />
+ <gd name="x12" fmla="+- hc dx3 0" />
+ <gd name="x13" fmla="+- hc dx2 0" />
+ <gd name="x14" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc 0 dy2" />
+ <gd name="y3" fmla="+- vc 0 dy3" />
+ <gd name="y4" fmla="+- vc 0 dy4" />
+ <gd name="y5" fmla="+- vc 0 dy5" />
+ <gd name="y6" fmla="+- vc 0 dy6" />
+ <gd name="y7" fmla="+- vc 0 dy7" />
+ <gd name="y8" fmla="+- vc dy7 0" />
+ <gd name="y9" fmla="+- vc dy6 0" />
+ <gd name="y10" fmla="+- vc dy5 0" />
+ <gd name="y11" fmla="+- vc dy4 0" />
+ <gd name="y12" fmla="+- vc dy3 0" />
+ <gd name="y13" fmla="+- vc dy2 0" />
+ <gd name="y14" fmla="+- vc dy1 0" />
+ <gd name="iwd2" fmla="*/ wd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx1" fmla="*/ iwd2 99518 100000" />
+ <gd name="sdx2" fmla="*/ iwd2 95694 100000" />
+ <gd name="sdx3" fmla="*/ iwd2 88192 100000" />
+ <gd name="sdx4" fmla="*/ iwd2 77301 100000" />
+ <gd name="sdx5" fmla="*/ iwd2 63439 100000" />
+ <gd name="sdx6" fmla="*/ iwd2 47140 100000" />
+ <gd name="sdx7" fmla="*/ iwd2 29028 100000" />
+ <gd name="sdx8" fmla="*/ iwd2 9802 100000" />
+ <gd name="sdy1" fmla="*/ ihd2 99518 100000" />
+ <gd name="sdy2" fmla="*/ ihd2 95694 100000" />
+ <gd name="sdy3" fmla="*/ ihd2 88192 100000" />
+ <gd name="sdy4" fmla="*/ ihd2 77301 100000" />
+ <gd name="sdy5" fmla="*/ ihd2 63439 100000" />
+ <gd name="sdy6" fmla="*/ ihd2 47140 100000" />
+ <gd name="sdy7" fmla="*/ ihd2 29028 100000" />
+ <gd name="sdy8" fmla="*/ ihd2 9802 100000" />
+ <gd name="sx1" fmla="+- hc 0 sdx1" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc 0 sdx3" />
+ <gd name="sx4" fmla="+- hc 0 sdx4" />
+ <gd name="sx5" fmla="+- hc 0 sdx5" />
+ <gd name="sx6" fmla="+- hc 0 sdx6" />
+ <gd name="sx7" fmla="+- hc 0 sdx7" />
+ <gd name="sx8" fmla="+- hc 0 sdx8" />
+ <gd name="sx9" fmla="+- hc sdx8 0" />
+ <gd name="sx10" fmla="+- hc sdx7 0" />
+ <gd name="sx11" fmla="+- hc sdx6 0" />
+ <gd name="sx12" fmla="+- hc sdx5 0" />
+ <gd name="sx13" fmla="+- hc sdx4 0" />
+ <gd name="sx14" fmla="+- hc sdx3 0" />
+ <gd name="sx15" fmla="+- hc sdx2 0" />
+ <gd name="sx16" fmla="+- hc sdx1 0" />
+ <gd name="sy1" fmla="+- vc 0 sdy1" />
+ <gd name="sy2" fmla="+- vc 0 sdy2" />
+ <gd name="sy3" fmla="+- vc 0 sdy3" />
+ <gd name="sy4" fmla="+- vc 0 sdy4" />
+ <gd name="sy5" fmla="+- vc 0 sdy5" />
+ <gd name="sy6" fmla="+- vc 0 sdy6" />
+ <gd name="sy7" fmla="+- vc 0 sdy7" />
+ <gd name="sy8" fmla="+- vc 0 sdy8" />
+ <gd name="sy9" fmla="+- vc sdy8 0" />
+ <gd name="sy10" fmla="+- vc sdy7 0" />
+ <gd name="sy11" fmla="+- vc sdy6 0" />
+ <gd name="sy12" fmla="+- vc sdy5 0" />
+ <gd name="sy13" fmla="+- vc sdy4 0" />
+ <gd name="sy14" fmla="+- vc sdy3 0" />
+ <gd name="sy15" fmla="+- vc sdy2 0" />
+ <gd name="sy16" fmla="+- vc sdy1 0" />
+ <gd name="idx" fmla="cos iwd2 2700000" />
+ <gd name="idy" fmla="sin ihd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="ssd2">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx1" y="sy8" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx7" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx8" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx9" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx10" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx11" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx12" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x11" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx13" y="sy5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x12" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx14" y="sy6" />
+ </lnTo>
+ <lnTo>
+ <pt x="x13" y="y6" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx15" y="sy7" />
+ </lnTo>
+ <lnTo>
+ <pt x="x14" y="y7" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx16" y="sy8" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx16" y="sy9" />
+ </lnTo>
+ <lnTo>
+ <pt x="x14" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx15" y="sy10" />
+ </lnTo>
+ <lnTo>
+ <pt x="x13" y="y9" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx14" y="sy11" />
+ </lnTo>
+ <lnTo>
+ <pt x="x12" y="y10" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx13" y="sy12" />
+ </lnTo>
+ <lnTo>
+ <pt x="x11" y="y11" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx12" y="sy13" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y12" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx11" y="sy14" />
+ </lnTo>
+ <lnTo>
+ <pt x="x9" y="y13" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx10" y="sy15" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y14" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx9" y="sy16" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx8" y="sy16" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y14" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx7" y="sy15" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y13" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy14" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y12" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy13" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y11" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy12" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y10" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy11" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y9" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy10" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y8" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="sy9" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star32>
+ <star4>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 12500" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="iwd2" fmla="*/ wd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx" fmla="cos iwd2 2700000" />
+ <gd name="sdy" fmla="sin ihd2 2700000" />
+ <gd name="sx1" fmla="+- hc 0 sdx" />
+ <gd name="sx2" fmla="+- hc sdx 0" />
+ <gd name="sy1" fmla="+- vc 0 sdy" />
+ <gd name="sy2" fmla="+- vc sdy 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="sx1" t="sy1" r="sx2" b="sy2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx1" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="sy2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star4>
+ <star5>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 19098" />
+ <gd name="hf" fmla="val 105146" />
+ <gd name="vf" fmla="val 110557" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="swd2" fmla="*/ wd2 hf 100000" />
+ <gd name="shd2" fmla="*/ hd2 vf 100000" />
+ <gd name="svc" fmla="*/ vc vf 100000" />
+ <gd name="dx1" fmla="cos swd2 1080000" />
+ <gd name="dx2" fmla="cos swd2 18360000" />
+ <gd name="dy1" fmla="sin shd2 1080000" />
+ <gd name="dy2" fmla="sin shd2 18360000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- svc 0 dy1" />
+ <gd name="y2" fmla="+- svc 0 dy2" />
+ <gd name="iwd2" fmla="*/ swd2 a 50000" />
+ <gd name="ihd2" fmla="*/ shd2 a 50000" />
+ <gd name="sdx1" fmla="cos iwd2 20520000" />
+ <gd name="sdx2" fmla="cos iwd2 3240000" />
+ <gd name="sdy1" fmla="sin ihd2 3240000" />
+ <gd name="sdy2" fmla="sin ihd2 20520000" />
+ <gd name="sx1" fmla="+- hc 0 sdx1" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc sdx2 0" />
+ <gd name="sx4" fmla="+- hc sdx1 0" />
+ <gd name="sy1" fmla="+- svc 0 sdy1" />
+ <gd name="sy2" fmla="+- svc 0 sdy2" />
+ <gd name="sy3" fmla="+- svc ihd2 0" />
+ <gd name="yAdj" fmla="+- svc 0 ihd2" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y2" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="y1" />
+ </cxn>
+ </cxnLst>
+ <rect l="sx1" t="sy1" r="sx4" b="sy3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx2" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="sy2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </star5>
+ <star6>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 28868" />
+ <gd name="hf" fmla="val 115470" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="swd2" fmla="*/ wd2 hf 100000" />
+ <gd name="dx1" fmla="cos swd2 1800000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc dx1 0" />
+ <gd name="y2" fmla="+- vc hd4 0" />
+ <gd name="iwd2" fmla="*/ swd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx2" fmla="*/ iwd2 1 2" />
+ <gd name="sx1" fmla="+- hc 0 iwd2" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc sdx2 0" />
+ <gd name="sx4" fmla="+- hc iwd2 0" />
+ <gd name="sdy1" fmla="sin ihd2 3600000" />
+ <gd name="sy1" fmla="+- vc 0 sdy1" />
+ <gd name="sy2" fmla="+- vc sdy1 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x2" y="hd4" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="hd4" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="sx1" t="sy1" r="sx4" b="sy2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="hd4" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx2" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="hd4" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="vc" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star6>
+ <star7>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 34601" />
+ <gd name="hf" fmla="val 102572" />
+ <gd name="vf" fmla="val 105210" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="swd2" fmla="*/ wd2 hf 100000" />
+ <gd name="shd2" fmla="*/ hd2 vf 100000" />
+ <gd name="svc" fmla="*/ vc vf 100000" />
+ <gd name="dx1" fmla="*/ swd2 97493 100000" />
+ <gd name="dx2" fmla="*/ swd2 78183 100000" />
+ <gd name="dx3" fmla="*/ swd2 43388 100000" />
+ <gd name="dy1" fmla="*/ shd2 62349 100000" />
+ <gd name="dy2" fmla="*/ shd2 22252 100000" />
+ <gd name="dy3" fmla="*/ shd2 90097 100000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc 0 dx3" />
+ <gd name="x4" fmla="+- hc dx3 0" />
+ <gd name="x5" fmla="+- hc dx2 0" />
+ <gd name="x6" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- svc 0 dy1" />
+ <gd name="y2" fmla="+- svc dy2 0" />
+ <gd name="y3" fmla="+- svc dy3 0" />
+ <gd name="iwd2" fmla="*/ swd2 a 50000" />
+ <gd name="ihd2" fmla="*/ shd2 a 50000" />
+ <gd name="sdx1" fmla="*/ iwd2 97493 100000" />
+ <gd name="sdx2" fmla="*/ iwd2 78183 100000" />
+ <gd name="sdx3" fmla="*/ iwd2 43388 100000" />
+ <gd name="sx1" fmla="+- hc 0 sdx1" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc 0 sdx3" />
+ <gd name="sx4" fmla="+- hc sdx3 0" />
+ <gd name="sx5" fmla="+- hc sdx2 0" />
+ <gd name="sx6" fmla="+- hc sdx1 0" />
+ <gd name="sdy1" fmla="*/ ihd2 90097 100000" />
+ <gd name="sdy2" fmla="*/ ihd2 22252 100000" />
+ <gd name="sdy3" fmla="*/ ihd2 62349 100000" />
+ <gd name="sy1" fmla="+- svc 0 sdy1" />
+ <gd name="sy2" fmla="+- svc 0 sdy2" />
+ <gd name="sy3" fmla="+- svc sdy3 0" />
+ <gd name="sy4" fmla="+- svc ihd2 0" />
+ <gd name="yAdj" fmla="+- svc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="x5" y="y1" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x6" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x4" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x3" y="y3" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x2" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="sx2" t="sy1" r="sx5" b="sy3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx1" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx6" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx5" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy3" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star7>
+ <star8>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 37500" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000" />
+ <gd name="dx1" fmla="cos wd2 2700000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc dx1 0" />
+ <gd name="dy1" fmla="sin hd2 2700000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc dy1 0" />
+ <gd name="iwd2" fmla="*/ wd2 a 50000" />
+ <gd name="ihd2" fmla="*/ hd2 a 50000" />
+ <gd name="sdx1" fmla="*/ iwd2 92388 100000" />
+ <gd name="sdx2" fmla="*/ iwd2 38268 100000" />
+ <gd name="sdy1" fmla="*/ ihd2 92388 100000" />
+ <gd name="sdy2" fmla="*/ ihd2 38268 100000" />
+ <gd name="sx1" fmla="+- hc 0 sdx1" />
+ <gd name="sx2" fmla="+- hc 0 sdx2" />
+ <gd name="sx3" fmla="+- hc sdx2 0" />
+ <gd name="sx4" fmla="+- hc sdx1 0" />
+ <gd name="sy1" fmla="+- vc 0 sdy1" />
+ <gd name="sy2" fmla="+- vc 0 sdy2" />
+ <gd name="sy3" fmla="+- vc sdy2 0" />
+ <gd name="sy4" fmla="+- vc sdy1 0" />
+ <gd name="yAdj" fmla="+- vc 0 ihd2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="hc" y="yAdj" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x1" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="y1" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x2" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="sx1" t="sy1" r="sx4" b="sy4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="sx1" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx4" y="sy3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx3" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx2" y="sy4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="sx1" y="sy3" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </star8>
+ <straightConnector1>
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path fill="none">
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ </path>
+ </pathLst>
+ </straightConnector1>
+ <stripedRightArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+
+ <gd name="adj2" fmla="val 50000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 84375 w ss" />
+
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="x4" fmla="*/ ss 5 32" />
+ <gd name="dx5" fmla="*/ ss a2 100000" />
+ <gd name="x5" fmla="+- r 0 dx5" />
+ <gd name="dy1" fmla="*/ h a1 200000" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="y2" fmla="+- vc dy1 0" />
+ <gd name="dx6" fmla="*/ dy1 dx5 hd2" />
+ <gd name="x6" fmla="+- r 0 dx6" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="100000">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x5" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x5" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x5" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x4" t="y1" r="x6" b="y2" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="ssd32" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="ssd32" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="ssd16" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="ssd8" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="ssd8" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="ssd16" y="y2" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x4" y="y1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x5" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="vc" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x5" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </stripedRightArrow>
+ <sun>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 12500 adj 46875" />
+ <gd name="g0" fmla="+- 50000 0 a" />
+ <gd name="g1" fmla="*/ g0 30274 32768" />
+ <gd name="g2" fmla="*/ g0 12540 32768" />
+ <gd name="g3" fmla="+- g1 50000 0" />
+ <gd name="g4" fmla="+- g2 50000 0" />
+ <gd name="g5" fmla="+- 50000 0 g1" />
+ <gd name="g6" fmla="+- 50000 0 g2" />
+ <gd name="g7" fmla="*/ g0 23170 32768" />
+ <gd name="g8" fmla="+- 50000 g7 0" />
+ <gd name="g9" fmla="+- 50000 0 g7" />
+ <gd name="g10" fmla="*/ g5 3 4" />
+ <gd name="g11" fmla="*/ g6 3 4" />
+ <gd name="g12" fmla="+- g10 3662 0" />
+ <gd name="g13" fmla="+- g11 3662 0" />
+ <gd name="g14" fmla="+- g11 12500 0" />
+ <gd name="g15" fmla="+- 100000 0 g10" />
+ <gd name="g16" fmla="+- 100000 0 g12" />
+ <gd name="g17" fmla="+- 100000 0 g13" />
+ <gd name="g18" fmla="+- 100000 0 g14" />
+ <gd name="ox1" fmla="*/ w 18436 21600" />
+ <gd name="oy1" fmla="*/ h 3163 21600" />
+ <gd name="ox2" fmla="*/ w 3163 21600" />
+ <gd name="oy2" fmla="*/ h 18436 21600" />
+ <gd name="x8" fmla="*/ w g8 100000" />
+ <gd name="x9" fmla="*/ w g9 100000" />
+ <gd name="x10" fmla="*/ w g10 100000" />
+ <gd name="x12" fmla="*/ w g12 100000" />
+ <gd name="x13" fmla="*/ w g13 100000" />
+ <gd name="x14" fmla="*/ w g14 100000" />
+ <gd name="x15" fmla="*/ w g15 100000" />
+ <gd name="x16" fmla="*/ w g16 100000" />
+ <gd name="x17" fmla="*/ w g17 100000" />
+ <gd name="x18" fmla="*/ w g18 100000" />
+ <gd name="x19" fmla="*/ w a 100000" />
+ <gd name="wR" fmla="*/ w g0 100000" />
+ <gd name="hR" fmla="*/ h g0 100000" />
+ <gd name="y8" fmla="*/ h g8 100000" />
+ <gd name="y9" fmla="*/ h g9 100000" />
+ <gd name="y10" fmla="*/ h g10 100000" />
+ <gd name="y12" fmla="*/ h g12 100000" />
+ <gd name="y13" fmla="*/ h g13 100000" />
+ <gd name="y14" fmla="*/ h g14 100000" />
+ <gd name="y15" fmla="*/ h g15 100000" />
+ <gd name="y16" fmla="*/ h g16 100000" />
+ <gd name="y17" fmla="*/ h g17 100000" />
+ <gd name="y18" fmla="*/ h g18 100000" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="12500" maxX="46875">
+ <pos x="x19" y="vc" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="x9" t="y9" r="x8" b="y8" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="r" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x15" y="y18" />
+ </lnTo>
+ <lnTo>
+ <pt x="x15" y="y14" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="ox1" y="oy1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x16" y="y13" />
+ </lnTo>
+ <lnTo>
+ <pt x="x17" y="y12" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="hc" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x18" y="y10" />
+ </lnTo>
+ <lnTo>
+ <pt x="x14" y="y10" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="ox2" y="oy1" />
+ </moveTo>
+ <lnTo>
+ <pt x="x13" y="y12" />
+ </lnTo>
+ <lnTo>
+ <pt x="x12" y="y13" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <lnTo>
+ <pt x="x10" y="y14" />
+ </lnTo>
+ <lnTo>
+ <pt x="x10" y="y18" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="ox2" y="oy2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x12" y="y17" />
+ </lnTo>
+ <lnTo>
+ <pt x="x13" y="y16" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="hc" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x14" y="y15" />
+ </lnTo>
+ <lnTo>
+ <pt x="x18" y="y15" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="ox1" y="oy2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x17" y="y16" />
+ </lnTo>
+ <lnTo>
+ <pt x="x16" y="y17" />
+ </lnTo>
+ <close />
+ <moveTo>
+ <pt x="x19" y="vc" />
+ </moveTo>
+ <arcTo wR="wR" hR="hR" stAng="cd2" swAng="21600000" />
+ <close />
+ </path>
+ </pathLst>
+
+ </sun>
+ <swooshArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 16667" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+
+
+ <gd name="a1" fmla="pin 1 adj1 75000" />
+
+ <gd name="maxAdj2" fmla="*/ 70000 w ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="ad1" fmla="*/ h a1 100000" />
+ <gd name="ad2" fmla="*/ ss a2 100000" />
+
+ <gd name="xB" fmla="+- r 0 ad2" />
+ <gd name="yB" fmla="+- t ssd8 0" />
+
+ <gd name="alfa" fmla="*/ cd4 1 14" />
+
+ <gd name="dx0" fmla="tan ssd8 alfa" />
+ <gd name="xC" fmla="+- xB 0 dx0" />
+
+ <gd name="dx1" fmla="tan ad1 alfa" />
+
+ <gd name="yF" fmla="+- yB ad1 0" />
+ <gd name="xF" fmla="+- xB dx1 0" />
+
+ <gd name="xE" fmla="+- xF dx0 0" />
+ <gd name="yE" fmla="+- yF ssd8 0" />
+
+ <gd name="dy2" fmla="+- yE 0 t" />
+ <gd name="dy22" fmla="*/ dy2 1 2" />
+ <gd name="dy3" fmla="*/ h 1 20" />
+ <gd name="yD" fmla="+- t dy22 dy3" />
+
+
+ <gd name="dy4" fmla="*/ hd6 1 1" />
+ <gd name="yP1" fmla="+- hd6 dy4 0" />
+ <gd name="xP1" fmla="val wd6" />
+
+
+ <gd name="dy5" fmla="*/ hd6 1 2" />
+ <gd name="yP2" fmla="+- yF dy5 0" />
+ <gd name="xP2" fmla="val wd4" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="1" maxY="75000">
+ <pos x="xF" y="yF" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="xB" y="yB" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="xC" y="t" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="yD" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="xE" y="yE" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <quadBezTo>
+ <pt x="xP1" y="yP1" />
+ <pt x="xB" y="yB" />
+ </quadBezTo>
+ <lnTo>
+ <pt x="xC" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="yD" />
+ </lnTo>
+ <lnTo>
+ <pt x="xE" y="yE" />
+ </lnTo>
+ <lnTo>
+ <pt x="xF" y="yF" />
+ </lnTo>
+ <quadBezTo>
+ <pt x="xP2" y="yP2" />
+ <pt x="l" y="b" />
+ </quadBezTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </swooshArrow>
+ <teardrop>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 100000" />
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 200000" />
+ <gd name="r2" fmla="sqrt 2" />
+ <gd name="tw" fmla="*/ wd2 r2 1" />
+ <gd name="th" fmla="*/ hd2 r2 1" />
+ <gd name="sw" fmla="*/ tw a 100000" />
+ <gd name="sh" fmla="*/ th a 100000" />
+ <gd name="dx1" fmla="cos sw 2700000" />
+ <gd name="dy1" fmla="sin sh 2700000" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc 0 dy1" />
+ <gd name="x2" fmla="+/ hc x1 2" />
+ <gd name="y2" fmla="+/ vc y1 2" />
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="200000">
+ <pos x="x1" y="t" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="x1" y="y1" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="vc" />
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="cd2" swAng="cd4" />
+ <quadBezTo>
+ <pt x="x2" y="t" />
+ <pt x="x1" y="y1" />
+ </quadBezTo>
+ <quadBezTo>
+ <pt x="r" y="y2" />
+ <pt x="r" y="vc" />
+ </quadBezTo>
+ <arcTo wR="wd2" hR="hd2" stAng="0" swAng="cd4" />
+ <arcTo wR="wd2" hR="hd2" stAng="cd4" swAng="cd4" />
+ <close />
+ </path>
+ </pathLst>
+
+ </teardrop>
+ <trapezoid>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj" fmla="*/ 50000 w ss" />
+ <gd name="a" fmla="pin 0 adj maxAdj" />
+ <gd name="x1" fmla="*/ ss a 200000" />
+ <gd name="x2" fmla="*/ ss a 100000" />
+ <gd name="x3" fmla="+- r 0 x2" />
+ <gd name="x4" fmla="+- r 0 x1" />
+ <gd name="il" fmla="*/ wd3 a maxAdj" />
+ <gd name="it" fmla="*/ hd3 a maxAdj" />
+ <gd name="ir" fmla="+- r 0 il" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="maxAdj">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x4" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </trapezoid>
+ <triangle>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 100000" />
+ <gd name="x1" fmla="*/ w a 200000" />
+ <gd name="x2" fmla="*/ w a 100000" />
+ <gd name="x3" fmla="+- x1 wd2 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="100000">
+ <pos x="x2" y="t" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="x2" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="l" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x2" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="r" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x3" y="vc" />
+ </cxn>
+ </cxnLst>
+ <rect l="x1" t="vc" r="x3" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </triangle>
+ <upArrowCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 64977" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 w ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ 100000 h ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q2" fmla="*/ a3 ss h" />
+
+ <gd name="maxAdj4" fmla="+- 100000 0 q2" />
+
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+ <gd name="dx1" fmla="*/ ss a2 100000" />
+
+ <gd name="dx2" fmla="*/ ss a1 200000" />
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="*/ ss a3 100000" />
+
+ <gd name="dy2" fmla="*/ h a4 100000" />
+
+ <gd name="y2" fmla="+- b 0 dy2" />
+ <gd name="y3" fmla="+/ y2 b 2" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="x2" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj4" minY="0" maxY="maxAdj4">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y2" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y2" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="y2" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </upArrowCallout>
+ <upDownArrow>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 h ss" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="y2" fmla="*/ ss a2 100000" />
+ <gd name="y3" fmla="+- b 0 y2" />
+ <gd name="dx1" fmla="*/ w a1 200000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc dx1 0" />
+ <gd name="dy1" fmla="*/ x1 y2 wd2" />
+ <gd name="y1" fmla="+- y2 0 dy1" />
+ <gd name="y4" fmla="+- y3 dy1 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="100000">
+ <pos x="x1" y="y3" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y3" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y2" />
+ </cxn>
+ </cxnLst>
+ <rect l="x1" t="y1" r="x2" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </upDownArrow>
+ <upDownArrow>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 50000" />
+ <gd name="adj2" fmla="val 50000" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 h ss" />
+ <gd name="a1" fmla="pin 0 adj1 100000" />
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="y2" fmla="*/ ss a2 100000" />
+ <gd name="y3" fmla="+- b 0 y2" />
+ <gd name="dx1" fmla="*/ w a1 200000" />
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc dx1 0" />
+ <gd name="dy1" fmla="*/ x1 y2 wd2" />
+ <gd name="y1" fmla="+- y2 0 dy1" />
+ <gd name="y4" fmla="+- y3 dy1 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="100000">
+ <pos x="x1" y="y3" />
+ </ahXY>
+ <ahXY gdRefY="adj2" minY="0" maxY="maxAdj2">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y2" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="y3" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y3" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x2" y="vc" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y2" />
+ </cxn>
+ </cxnLst>
+ <rect l="x1" t="y1" r="x2" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y2" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </upDownArrow>
+ <upDownArrowCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 48123" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="maxAdj2" fmla="*/ 50000 w ss" />
+
+ <gd name="a2" fmla="pin 0 adj2 maxAdj2" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="maxAdj3" fmla="*/ 50000 h ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q2" fmla="*/ a3 ss hd2" />
+
+ <gd name="maxAdj4" fmla="+- 100000 0 q2" />
+
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+ <gd name="dx1" fmla="*/ ss a2 100000" />
+
+ <gd name="dx2" fmla="*/ ss a1 200000" />
+
+ <gd name="x1" fmla="+- hc 0 dx1" />
+ <gd name="x2" fmla="+- hc 0 dx2" />
+ <gd name="x3" fmla="+- hc dx2 0" />
+ <gd name="x4" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="*/ ss a3 100000" />
+
+ <gd name="y4" fmla="+- b 0 y1" />
+
+ <gd name="dy2" fmla="*/ h a4 200000" />
+
+ <gd name="y2" fmla="+- vc 0 dy2" />
+
+ <gd name="y3" fmla="+- vc dy2 0" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="x2" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="maxAdj2">
+ <pos x="x1" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="r" y="y1" />
+ </ahXY>
+ <ahXY gdRefY="adj4" minY="0" maxY="maxAdj4">
+ <pos x="l" y="y2" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="y2" r="r" b="y3" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2" />
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="x3" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x4" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="hc" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y3" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </upDownArrowCallout>
+ <uturnArrow>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 25000" />
+
+ <gd name="adj2" fmla="val 25000" />
+
+ <gd name="adj3" fmla="val 25000" />
+
+ <gd name="adj4" fmla="val 43750" />
+
+ <gd name="adj5" fmla="val 75000" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a2" fmla="pin 0 adj2 25000" />
+ <gd name="maxAdj1" fmla="*/ a2 2 1" />
+ <gd name="a1" fmla="pin 0 adj1 maxAdj1" />
+ <gd name="q2" fmla="*/ a1 ss h" />
+
+ <gd name="q3" fmla="+- 100000 0 q2" />
+
+ <gd name="maxAdj3" fmla="*/ q3 h ss" />
+
+ <gd name="a3" fmla="pin 0 adj3 maxAdj3" />
+ <gd name="q1" fmla="+- a3 a1 0" />
+ <gd name="minAdj5" fmla="*/ q1 ss h" />
+ <gd name="a5" fmla="pin minAdj5 adj5 100000" />
+ <gd name="th" fmla="*/ ss a1 100000" />
+
+ <gd name="aw2" fmla="*/ ss a2 100000" />
+
+ <gd name="th2" fmla="*/ th 1 2" />
+ <gd name="dh2" fmla="+- aw2 0 th2" />
+
+ <gd name="y5" fmla="*/ h a5 100000" />
+
+ <gd name="ah" fmla="*/ ss a3 100000" />
+
+ <gd name="y4" fmla="+- y5 0 ah" />
+ <gd name="x9" fmla="+- r 0 dh2" />
+
+ <gd name="bw" fmla="*/ x9 1 2" />
+ <gd name="bs" fmla="min bw y4" />
+ <gd name="maxAdj4" fmla="*/ bs 100000 ss" />
+ <gd name="a4" fmla="pin 0 adj4 maxAdj4" />
+
+
+ <gd name="bd" fmla="*/ ss a4 100000" />
+
+
+
+ <gd name="bd3" fmla="+- bd 0 th" />
+ <gd name="bd2" fmla="max bd3 0" />
+ <gd name="x3" fmla="+- th bd2 0" />
+
+ <gd name="x8" fmla="+- r 0 aw2" />
+
+ <gd name="x6" fmla="+- x8 0 aw2" />
+
+ <gd name="x7" fmla="+- x6 dh2 0" />
+
+ <gd name="x4" fmla="+- x9 0 bd" />
+
+ <gd name="x5" fmla="+- x7 0 bd2" />
+
+ <gd name="cx" fmla="+/ th x7 2" />
+
+
+
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="0" maxX="maxAdj1">
+ <pos x="th" y="b" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="0" maxX="25000">
+ <pos x="x6" y="b" />
+ </ahXY>
+ <ahXY gdRefY="adj3" minY="0" maxY="maxAdj3">
+ <pos x="x6" y="y4" />
+ </ahXY>
+ <ahXY gdRefX="adj4" minX="0" maxX="maxAdj4">
+ <pos x="bd" y="t" />
+ </ahXY>
+ <ahXY gdRefY="adj5" minY="minAdj5" maxY="100000">
+ <pos x="r" y="y5" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="x6" y="y4" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="x8" y="y5" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="y4" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="cx" y="t" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="th2" y="b" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="b" />
+ </moveTo>
+ <lnTo>
+ <pt x="l" y="bd" />
+ </lnTo>
+ <arcTo wR="bd" hR="bd" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x4" y="t" />
+ </lnTo>
+ <arcTo wR="bd" hR="bd" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="x9" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x8" y="y5" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="y4" />
+ </lnTo>
+ <lnTo>
+ <pt x="x7" y="x3" />
+ </lnTo>
+ <arcTo wR="bd2" hR="bd2" stAng="0" swAng="-5400000" />
+ <lnTo>
+ <pt x="x3" y="th" />
+ </lnTo>
+ <arcTo wR="bd2" hR="bd2" stAng="3cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="th" y="b" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </uturnArrow>
+ <verticalScroll>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 12500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 25000" />
+ <gd name="ch" fmla="*/ ss a 100000" />
+
+ <gd name="ch2" fmla="*/ ch 1 2" />
+
+ <gd name="ch4" fmla="*/ ch 1 4" />
+
+
+
+
+
+ <gd name="x3" fmla="+- ch ch2 0" />
+
+ <gd name="x4" fmla="+- ch ch 0" />
+
+ <gd name="x6" fmla="+- r 0 ch" />
+
+ <gd name="x7" fmla="+- r 0 ch2" />
+
+ <gd name="x5" fmla="+- x6 0 ch2" />
+
+
+
+
+
+ <gd name="y3" fmla="+- b 0 ch" />
+
+ <gd name="y4" fmla="+- b 0 ch2" />
+
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="25000">
+ <pos x="l" y="ch" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="ch" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x6" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="ch" t="ch" r="x6" b="y4" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="ch2" y="b" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="ch2" y="y4" />
+ </lnTo>
+ <arcTo wR="ch4" hR="ch4" stAng="cd4" swAng="-10800000" />
+ <lnTo>
+ <pt x="ch" y="y3" />
+ </lnTo>
+ <lnTo>
+ <pt x="ch" y="ch2" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x7" y="t" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x6" y="ch" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y4" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd4" />
+ <close />
+ <moveTo>
+ <pt x="x4" y="ch2" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd4" />
+ <arcTo wR="ch4" hR="ch4" stAng="cd4" swAng="cd2" />
+ <close />
+ </path>
+ <path fill="darkenLess" stroke="false" extrusionOk="false">
+
+ <moveTo>
+ <pt x="x4" y="ch2" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd4" />
+ <arcTo wR="ch4" hR="ch4" stAng="cd4" swAng="cd2" />
+ <close />
+ <moveTo>
+ <pt x="ch" y="y4" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="3cd4" />
+ <arcTo wR="ch4" hR="ch4" stAng="3cd4" swAng="cd2" />
+ <close />
+ </path>
+ <path fill="none" extrusionOk="false">
+
+ <moveTo>
+ <pt x="ch" y="y3" />
+ </moveTo>
+ <lnTo>
+ <pt x="ch" y="ch2" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x7" y="t" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x6" y="ch" />
+ </lnTo>
+ <lnTo>
+ <pt x="x6" y="y4" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="ch2" y="b" />
+ </lnTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="cd2" />
+ <close />
+ <moveTo>
+ <pt x="x3" y="t" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="3cd4" swAng="cd2" />
+ <arcTo wR="ch4" hR="ch4" stAng="cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="x4" y="ch2" />
+ </lnTo>
+ <moveTo>
+ <pt x="x6" y="ch" />
+ </moveTo>
+ <lnTo>
+ <pt x="x3" y="ch" />
+ </lnTo>
+ <moveTo>
+ <pt x="ch2" y="y3" />
+ </moveTo>
+ <arcTo wR="ch4" hR="ch4" stAng="3cd4" swAng="cd2" />
+ <lnTo>
+ <pt x="ch" y="y4" />
+ </lnTo>
+ <moveTo>
+ <pt x="ch2" y="b" />
+ </moveTo>
+ <arcTo wR="ch2" hR="ch2" stAng="cd4" swAng="-5400000" />
+ <lnTo>
+ <pt x="ch" y="y3" />
+ </lnTo>
+ </path>
+ </pathLst>
+
+ </verticalScroll>
+ <wave>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 12500" />
+
+ <gd name="adj2" fmla="val 0" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 20000" />
+ <gd name="a2" fmla="pin -10000 adj2 10000" />
+ <gd name="y1" fmla="*/ h a1 100000" />
+
+ <gd name="dy2" fmla="*/ y1 10 3" />
+ <gd name="y2" fmla="+- y1 0 dy2" />
+
+ <gd name="y3" fmla="+- y1 dy2 0" />
+
+ <gd name="y4" fmla="+- b 0 y1" />
+
+ <gd name="y5" fmla="+- y4 0 dy2" />
+
+ <gd name="y6" fmla="+- y4 dy2 0" />
+
+ <gd name="dx1" fmla="*/ w a2 100000" />
+
+ <gd name="of2" fmla="*/ w a2 50000" />
+
+ <gd name="x1" fmla="abs dx1" />
+
+ <gd name="dx2" fmla="?: of2 0 of2" />
+ <gd name="x2" fmla="+- l 0 dx2" />
+
+ <gd name="dx5" fmla="?: of2 of2 0" />
+ <gd name="x5" fmla="+- r 0 dx5" />
+
+ <gd name="dx3" fmla="+/ dx2 x5 3" />
+
+ <gd name="x3" fmla="+- x2 dx3 0" />
+
+ <gd name="x4" fmla="+/ x3 x5 2" />
+
+ <gd name="x6" fmla="+- l dx5 0" />
+
+ <gd name="x10" fmla="+- r dx2 0" />
+
+ <gd name="x7" fmla="+- x6 dx3 0" />
+
+ <gd name="x8" fmla="+/ x7 x10 2" />
+
+ <gd name="x9" fmla="+- r 0 x1" />
+
+ <gd name="xAdj" fmla="+- hc dx1 0" />
+ <gd name="xAdj2" fmla="+- hc 0 dx1" />
+ <gd name="il" fmla="max x2 x6" />
+ <gd name="ir" fmla="min x5 x10" />
+ <gd name="it" fmla="*/ h a1 50000" />
+ <gd name="ib" fmla="+- b 0 it" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="20000">
+ <pos x="l" y="y1" />
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="-10000" maxX="10000">
+ <pos x="xAdj" y="b" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="cd4">
+ <pos x="xAdj2" y="y1" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="x1" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="xAdj" y="y4" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="x9" y="vc" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x2" y="y1" />
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x3" y="y2" />
+ <pt x="x4" y="y3" />
+ <pt x="x5" y="y1" />
+ </cubicBezTo>
+ <lnTo>
+ <pt x="x10" y="y4" />
+ </lnTo>
+ <cubicBezTo>
+ <pt x="x8" y="y6" />
+ <pt x="x7" y="y5" />
+ <pt x="x6" y="y4" />
+ </cubicBezTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </wave>
+ <wedgeEllipseCallout>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val -20833" />
+ <gd name="adj2" fmla="val 62500" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dxPos" fmla="*/ w adj1 100000" />
+ <gd name="dyPos" fmla="*/ h adj2 100000" />
+ <gd name="xPos" fmla="+- hc dxPos 0" />
+ <gd name="yPos" fmla="+- vc dyPos 0" />
+ <gd name="sdx" fmla="*/ dxPos h 1" />
+ <gd name="sdy" fmla="*/ dyPos w 1" />
+ <gd name="pang" fmla="at2 sdx sdy" />
+ <gd name="stAng" fmla="+- pang 660000 0" />
+ <gd name="enAng" fmla="+- pang 0 660000" />
+ <gd name="dx1" fmla="cos wd2 stAng" />
+ <gd name="dy1" fmla="sin hd2 stAng" />
+ <gd name="x1" fmla="+- hc dx1 0" />
+ <gd name="y1" fmla="+- vc dy1 0" />
+ <gd name="dx2" fmla="cos wd2 enAng" />
+ <gd name="dy2" fmla="sin hd2 enAng" />
+ <gd name="x2" fmla="+- hc dx2 0" />
+ <gd name="y2" fmla="+- vc dy2 0" />
+ <gd name="stAng1" fmla="at2 dx1 dy1" />
+ <gd name="enAng1" fmla="at2 dx2 dy2" />
+ <gd name="swAng1" fmla="+- enAng1 0 stAng1" />
+ <gd name="swAng2" fmla="+- swAng1 21600000 0" />
+ <gd name="swAng" fmla="?: swAng1 swAng1 swAng2" />
+ <gd name="idx" fmla="cos wd2 2700000" />
+ <gd name="idy" fmla="sin hd2 2700000" />
+ <gd name="il" fmla="+- hc 0 idx" />
+ <gd name="ir" fmla="+- hc idx 0" />
+ <gd name="it" fmla="+- vc 0 idy" />
+ <gd name="ib" fmla="+- vc idy 0" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647" gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="xPos" y="yPos" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="il" y="it" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="il" y="ib" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="ir" y="ib" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="3cd4">
+ <pos x="ir" y="it" />
+ </cxn>
+ <cxn ang="pang">
+ <pos x="xPos" y="yPos" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="it" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="xPos" y="yPos" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="y1" />
+ </lnTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng1" swAng="swAng" />
+ <close />
+ </path>
+ </pathLst>
+ </wedgeEllipseCallout>
+ <wedgeRectCallout>
+
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val -20833" />
+
+ <gd name="adj2" fmla="val 62500" />
+
+ </avLst>
+
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dxPos" fmla="*/ w adj1 100000" />
+ <gd name="dyPos" fmla="*/ h adj2 100000" />
+ <gd name="xPos" fmla="+- hc dxPos 0" />
+ <gd name="yPos" fmla="+- vc dyPos 0" />
+ <gd name="dx" fmla="+- xPos 0 hc" />
+ <gd name="dy" fmla="+- yPos 0 vc" />
+ <gd name="dq" fmla="*/ dxPos h w" />
+ <gd name="ady" fmla="abs dyPos" />
+ <gd name="adq" fmla="abs dq" />
+ <gd name="dz" fmla="+- ady 0 adq" />
+ <gd name="xg1" fmla="?: dxPos 7 2" />
+ <gd name="xg2" fmla="?: dxPos 10 5" />
+ <gd name="x1" fmla="*/ w xg1 12" />
+ <gd name="x2" fmla="*/ w xg2 12" />
+ <gd name="yg1" fmla="?: dyPos 7 2" />
+ <gd name="yg2" fmla="?: dyPos 10 5" />
+ <gd name="y1" fmla="*/ h yg1 12" />
+ <gd name="y2" fmla="*/ h yg2 12" />
+ <gd name="t1" fmla="?: dxPos l xPos" />
+ <gd name="xl" fmla="?: dz l t1" />
+ <gd name="t2" fmla="?: dyPos x1 xPos" />
+ <gd name="xt" fmla="?: dz t2 x1" />
+ <gd name="t3" fmla="?: dxPos xPos r" />
+ <gd name="xr" fmla="?: dz r t3" />
+ <gd name="t4" fmla="?: dyPos xPos x1" />
+ <gd name="xb" fmla="?: dz t4 x1" />
+ <gd name="t5" fmla="?: dxPos y1 yPos" />
+ <gd name="yl" fmla="?: dz y1 t5" />
+ <gd name="t6" fmla="?: dyPos t yPos" />
+ <gd name="yt" fmla="?: dz t6 t" />
+ <gd name="t7" fmla="?: dxPos yPos y1" />
+ <gd name="yr" fmla="?: dz y1 t7" />
+ <gd name="t8" fmla="?: dyPos yPos b" />
+ <gd name="yb" fmla="?: dz t8 b" />
+ </gdLst>
+
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647" gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="xPos" y="yPos" />
+ </ahXY>
+ </ahLst>
+
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="xPos" y="yPos" />
+ </cxn>
+ </cxnLst>
+
+ <rect l="l" t="t" r="r" b="b" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t" />
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="xt" y="yt" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xr" y="yr" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="xb" y="yb" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xl" y="yl" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+
+ </wedgeRectCallout>
+ <wedgeRoundRectCallout>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val -20833" />
+ <gd name="adj2" fmla="val 62500" />
+ <gd name="adj3" fmla="val 16667" />
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="dxPos" fmla="*/ w adj1 100000" />
+ <gd name="dyPos" fmla="*/ h adj2 100000" />
+ <gd name="xPos" fmla="+- hc dxPos 0" />
+ <gd name="yPos" fmla="+- vc dyPos 0" />
+ <gd name="dq" fmla="*/ dxPos h w" />
+ <gd name="ady" fmla="abs dyPos" />
+ <gd name="adq" fmla="abs dq" />
+ <gd name="dz" fmla="+- ady 0 adq" />
+ <gd name="xg1" fmla="?: dxPos 7 2" />
+ <gd name="xg2" fmla="?: dxPos 10 5" />
+ <gd name="x1" fmla="*/ w xg1 12" />
+ <gd name="x2" fmla="*/ w xg2 12" />
+ <gd name="yg1" fmla="?: dyPos 7 2" />
+ <gd name="yg2" fmla="?: dyPos 10 5" />
+ <gd name="y1" fmla="*/ h yg1 12" />
+ <gd name="y2" fmla="*/ h yg2 12" />
+ <gd name="t1" fmla="?: dxPos l xPos" />
+ <gd name="xl" fmla="?: dz l t1" />
+ <gd name="t2" fmla="?: dyPos x1 xPos" />
+ <gd name="xt" fmla="?: dz t2 x1" />
+ <gd name="t3" fmla="?: dxPos xPos r" />
+ <gd name="xr" fmla="?: dz r t3" />
+ <gd name="t4" fmla="?: dyPos xPos x1" />
+ <gd name="xb" fmla="?: dz t4 x1" />
+ <gd name="t5" fmla="?: dxPos y1 yPos" />
+ <gd name="yl" fmla="?: dz y1 t5" />
+ <gd name="t6" fmla="?: dyPos t yPos" />
+ <gd name="yt" fmla="?: dz t6 t" />
+ <gd name="t7" fmla="?: dxPos yPos y1" />
+ <gd name="yr" fmla="?: dz y1 t7" />
+ <gd name="t8" fmla="?: dyPos yPos b" />
+ <gd name="yb" fmla="?: dz t8 b" />
+ <gd name="u1" fmla="*/ ss adj3 100000" />
+ <gd name="u2" fmla="+- r 0 u1" />
+ <gd name="v2" fmla="+- b 0 u1" />
+ <gd name="il" fmla="*/ u1 29289 100000" />
+ <gd name="ir" fmla="+- r 0 il" />
+ <gd name="ib" fmla="+- b 0 il" />
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj1" minX="-2147483647" maxX="2147483647" gdRefY="adj2" minY="-2147483647" maxY="2147483647">
+ <pos x="xPos" y="yPos" />
+ </ahXY>
+ </ahLst>
+ <cxnLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <cxn ang="3cd4">
+ <pos x="hc" y="t" />
+ </cxn>
+ <cxn ang="cd2">
+ <pos x="l" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="hc" y="b" />
+ </cxn>
+ <cxn ang="0">
+ <pos x="r" y="vc" />
+ </cxn>
+ <cxn ang="cd4">
+ <pos x="xPos" y="yPos" />
+ </cxn>
+ </cxnLst>
+ <rect l="il" t="il" r="ir" b="ib" xmlns="http://schemas.openxmlformats.org/drawingml/2006/main" />
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="u1" />
+ </moveTo>
+ <arcTo wR="u1" hR="u1" stAng="cd2" swAng="cd4" />
+ <lnTo>
+ <pt x="x1" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="xt" y="yt" />
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t" />
+ </lnTo>
+ <lnTo>
+ <pt x="u2" y="t" />
+ </lnTo>
+ <arcTo wR="u1" hR="u1" stAng="3cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="r" y="y1" />
+ </lnTo>
+ <lnTo>
+ <pt x="xr" y="yr" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="v2" />
+ </lnTo>
+ <arcTo wR="u1" hR="u1" stAng="0" swAng="cd4" />
+ <lnTo>
+ <pt x="x2" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="xb" y="yb" />
+ </lnTo>
+ <lnTo>
+ <pt x="x1" y="b" />
+ </lnTo>
+ <lnTo>
+ <pt x="u1" y="b" />
+ </lnTo>
+ <arcTo wR="u1" hR="u1" stAng="cd4" swAng="cd4" />
+ <lnTo>
+ <pt x="l" y="y2" />
+ </lnTo>
+ <lnTo>
+ <pt x="xl" y="yl" />
+ </lnTo>
+ <lnTo>
+ <pt x="l" y="y1" />
+ </lnTo>
+ <close />
+ </path>
+ </pathLst>
+ </wedgeRoundRectCallout>
+</presetShapeDefinitons>
diff --git a/oox/source/export/presetTextWarpDefinitions.xml b/oox/source/export/presetTextWarpDefinitions.xml
new file mode 100644
index 000000000000..c701c8f82b1c
--- /dev/null
+++ b/oox/source/export/presetTextWarpDefinitions.xml
@@ -0,0 +1,1885 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<presetTextWarpDefinitions>
+ <textArchDown>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 0"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj 21599999"/>
+ <gd name="v1" fmla="+- 10800000 0 adval"/>
+ <gd name="v2" fmla="+- 32400000 0 adval"/>
+ <gd name="nv1" fmla="+- 0 0 v1"/>
+ <gd name="stAng" fmla="?: nv1 v2 v1"/>
+ <gd name="w1" fmla="+- 5400000 0 adval"/>
+ <gd name="w2" fmla="+- 16200000 0 adval"/>
+ <gd name="d1" fmla="+- adval 0 stAng"/>
+ <gd name="d2" fmla="+- d1 0 21600000"/>
+ <gd name="v3" fmla="+- 0 0 10800000"/>
+ <gd name="c2" fmla="?: w2 d1 d2"/>
+ <gd name="c1" fmla="?: v1 d2 c2"/>
+ <gd name="c0" fmla="?: w1 d1 c1"/>
+ <gd name="swAng" fmla="?: stAng c0 v3"/>
+ <gd name="wt1" fmla="sin wd2 adj"/>
+ <gd name="ht1" fmla="cos hd2 adj"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ <gd name="wt2" fmla="sin wd2 stAng"/>
+ <gd name="ht2" fmla="cos hd2 stAng"/>
+ <gd name="dx2" fmla="cat2 wd2 ht2 wt2"/>
+ <gd name="dy2" fmla="sat2 hd2 ht2 wt2"/>
+ <gd name="x2" fmla="+- hc dx2 0"/>
+ <gd name="y2" fmla="+- vc dy2 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj" minAng="0" maxAng="21599999">
+ <pos x="x1" y="y1"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x2" y="y2"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng" swAng="swAng"/>
+ </path>
+ </pathLst>
+ </textArchDown>
+ <textArchDownPour>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 0"/>
+ <gd name="adj2" fmla="val 25000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj1 21599999"/>
+ <gd name="v1" fmla="+- 10800000 0 adval"/>
+ <gd name="v2" fmla="+- 32400000 0 adval"/>
+ <gd name="nv1" fmla="+- 0 0 v1"/>
+ <gd name="stAng" fmla="?: nv1 v2 v1"/>
+ <gd name="w1" fmla="+- 5400000 0 adval"/>
+ <gd name="w2" fmla="+- 16200000 0 adval"/>
+ <gd name="d1" fmla="+- adval 0 stAng"/>
+ <gd name="d2" fmla="+- d1 0 21600000"/>
+ <gd name="v3" fmla="+- 0 0 10800000"/>
+ <gd name="c2" fmla="?: w2 d1 d2"/>
+ <gd name="c1" fmla="?: v1 d2 c2"/>
+ <gd name="c0" fmla="?: w1 d1 c1"/>
+ <gd name="swAng" fmla="?: stAng c0 v3"/>
+ <gd name="wt1" fmla="sin wd2 stAng"/>
+ <gd name="ht1" fmla="cos hd2 stAng"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ <gd name="adval2" fmla="pin 0 adj2 99000"/>
+ <gd name="ratio" fmla="*/ adval2 1 100000"/>
+ <gd name="iwd2" fmla="*/ wd2 ratio 1"/>
+ <gd name="ihd2" fmla="*/ hd2 ratio 1"/>
+ <gd name="wt2" fmla="sin iwd2 adval"/>
+ <gd name="ht2" fmla="cos ihd2 adval"/>
+ <gd name="dx2" fmla="cat2 iwd2 ht2 wt2"/>
+ <gd name="dy2" fmla="sat2 ihd2 ht2 wt2"/>
+ <gd name="x2" fmla="+- hc dx2 0"/>
+ <gd name="y2" fmla="+- vc dy2 0"/>
+ <gd name="wt3" fmla="sin iwd2 stAng"/>
+ <gd name="ht3" fmla="cos ihd2 stAng"/>
+ <gd name="dx3" fmla="cat2 iwd2 ht3 wt3"/>
+ <gd name="dy3" fmla="sat2 ihd2 ht3 wt3"/>
+ <gd name="x3" fmla="+- hc dx3 0"/>
+ <gd name="y3" fmla="+- vc dy3 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefR="adj2" minR="0" maxR="100000" gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="x2" y="y2"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x3" y="y3"/>
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="stAng" swAng="swAng"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stAng" swAng="swAng"/>
+ </path>
+ </pathLst>
+ </textArchDownPour>
+ <textArchUp>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val cd2"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj 21599999"/>
+ <gd name="v1" fmla="+- 10800000 0 adval"/>
+ <gd name="v2" fmla="+- 32400000 0 adval"/>
+ <gd name="end" fmla="?: v1 v1 v2"/>
+ <gd name="w1" fmla="+- 5400000 0 adval"/>
+ <gd name="w2" fmla="+- 16200000 0 adval"/>
+ <gd name="d1" fmla="+- end 0 adval"/>
+ <gd name="d2" fmla="+- 21600000 d1 0"/>
+ <gd name="c2" fmla="?: w2 d1 d2"/>
+ <gd name="c1" fmla="?: v1 d2 c2"/>
+ <gd name="swAng" fmla="?: w1 d1 c1"/>
+ <gd name="wt1" fmla="sin wd2 adj"/>
+ <gd name="ht1" fmla="cos hd2 adj"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj" minAng="0" maxAng="21599999">
+ <pos x="x1" y="y1"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="adval" swAng="swAng"/>
+ </path>
+ </pathLst>
+ </textArchUp>
+ <textArchUpPour>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val cd2"/>
+ <gd name="adj2" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj1 21599999"/>
+ <gd name="v1" fmla="+- 10800000 0 adval"/>
+ <gd name="v2" fmla="+- 32400000 0 adval"/>
+ <gd name="end" fmla="?: v1 v1 v2"/>
+ <gd name="w1" fmla="+- 5400000 0 adval"/>
+ <gd name="w2" fmla="+- 16200000 0 adval"/>
+ <gd name="d1" fmla="+- end 0 adval"/>
+ <gd name="d2" fmla="+- 21600000 d1 0"/>
+ <gd name="c2" fmla="?: w2 d1 d2"/>
+ <gd name="c1" fmla="?: v1 d2 c2"/>
+ <gd name="swAng" fmla="?: w1 d1 c1"/>
+ <gd name="wt1" fmla="sin wd2 adval"/>
+ <gd name="ht1" fmla="cos hd2 adval"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ <gd name="adval2" fmla="pin 0 adj2 99000"/>
+ <gd name="ratio" fmla="*/ adval2 1 100000"/>
+ <gd name="iwd2" fmla="*/ wd2 ratio 1"/>
+ <gd name="ihd2" fmla="*/ hd2 ratio 1"/>
+ <gd name="wt2" fmla="sin iwd2 adval"/>
+ <gd name="ht2" fmla="cos ihd2 adval"/>
+ <gd name="dx2" fmla="cat2 iwd2 ht2 wt2"/>
+ <gd name="dy2" fmla="sat2 ihd2 ht2 wt2"/>
+ <gd name="x2" fmla="+- hc dx2 0"/>
+ <gd name="y2" fmla="+- vc dy2 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefR="adj2" minR="0" maxR="100000" gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="x2" y="y2"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="adval" swAng="swAng"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x2" y="y2"/>
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="adval" swAng="swAng"/>
+ </path>
+ </pathLst>
+ </textArchUpPour>
+ <textButton>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 10800000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj 21599999"/>
+ <gd name="bot" fmla="+- 5400000 0 adval"/>
+ <gd name="lef" fmla="+- 10800000 0 adval"/>
+ <gd name="top" fmla="+- 16200000 0 adval"/>
+ <gd name="rig" fmla="+- 21600000 0 adval"/>
+ <gd name="c3" fmla="?: top adval 0"/>
+ <gd name="c2" fmla="?: lef 10800000 c3"/>
+ <gd name="c1" fmla="?: bot rig c2"/>
+ <gd name="stAng" fmla="?: adval c1 0"/>
+ <gd name="w1" fmla="+- 21600000 0 stAng"/>
+ <gd name="stAngB" fmla="?: stAng w1 0"/>
+ <gd name="td1" fmla="*/ bot 2 1"/>
+ <gd name="td2" fmla="*/ top 2 1"/>
+ <gd name="ntd2" fmla="+- 0 0 td2"/>
+ <gd name="w2" fmla="+- 0 0 10800000"/>
+ <gd name="c6" fmla="?: top ntd2 w2"/>
+ <gd name="c5" fmla="?: lef 10800000 c6"/>
+ <gd name="c4" fmla="?: bot td1 c5"/>
+ <gd name="v1" fmla="?: adval c4 10800000"/>
+ <gd name="swAngT" fmla="+- 0 0 v1"/>
+ <gd name="stT" fmla="?: lef stAngB stAng"/>
+ <gd name="stB" fmla="?: lef stAng stAngB"/>
+ <gd name="swT" fmla="?: lef v1 swAngT"/>
+ <gd name="swB" fmla="?: lef swAngT v1"/>
+ <gd name="wt1" fmla="sin wd2 stT"/>
+ <gd name="ht1" fmla="cos hd2 stT"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ <gd name="wt2" fmla="sin wd2 stB"/>
+ <gd name="ht2" fmla="cos hd2 stB"/>
+ <gd name="dx2" fmla="cat2 wd2 ht2 wt2"/>
+ <gd name="dy2" fmla="sat2 hd2 ht2 wt2"/>
+ <gd name="x2" fmla="+- hc dx2 0"/>
+ <gd name="y2" fmla="+- vc dy2 0"/>
+ <gd name="wt3" fmla="sin wd2 adj"/>
+ <gd name="ht3" fmla="cos hd2 adj"/>
+ <gd name="dx3" fmla="cat2 wd2 ht3 wt3"/>
+ <gd name="dy3" fmla="sat2 hd2 ht3 wt3"/>
+ <gd name="x3" fmla="+- hc dx3 0"/>
+ <gd name="y3" fmla="+- vc dy3 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj" minAng="0" maxAng="21599999">
+ <pos x="x3" y="y3"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stT" swAng="swT"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="vc"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="vc"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x2" y="y2"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stB" swAng="swB"/>
+ </path>
+ </pathLst>
+ </textButton>
+ <textButtonPour>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val cd2"/>
+ <gd name="adj2" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj1 21599999"/>
+ <gd name="bot" fmla="+- 5400000 0 adval"/>
+ <gd name="lef" fmla="+- 10800000 0 adval"/>
+ <gd name="top" fmla="+- 16200000 0 adval"/>
+ <gd name="rig" fmla="+- 21600000 0 adval"/>
+ <gd name="c3" fmla="?: top adval 0"/>
+ <gd name="c2" fmla="?: lef 10800000 c3"/>
+ <gd name="c1" fmla="?: bot rig c2"/>
+ <gd name="stAng" fmla="?: adval c1 0"/>
+ <gd name="w1" fmla="+- 21600000 0 stAng"/>
+ <gd name="stAngB" fmla="?: stAng w1 0"/>
+ <gd name="td1" fmla="*/ bot 2 1"/>
+ <gd name="td2" fmla="*/ top 2 1"/>
+ <gd name="ntd2" fmla="+- 0 0 td2"/>
+ <gd name="w2" fmla="+- 0 0 10800000"/>
+ <gd name="c6" fmla="?: top ntd2 w2"/>
+ <gd name="c5" fmla="?: lef 10800000 c6"/>
+ <gd name="c4" fmla="?: bot td1 c5"/>
+ <gd name="v1" fmla="?: adval c4 10800000"/>
+ <gd name="swAngT" fmla="+- 0 0 v1"/>
+ <gd name="stT" fmla="?: lef stAngB stAng"/>
+ <gd name="stB" fmla="?: lef stAng stAngB"/>
+ <gd name="swT" fmla="?: lef v1 swAngT"/>
+ <gd name="swB" fmla="?: lef swAngT v1"/>
+ <gd name="wt1" fmla="sin wd2 stT"/>
+ <gd name="ht1" fmla="cos hd2 stT"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ <gd name="wt6" fmla="sin wd2 stB"/>
+ <gd name="ht6" fmla="cos hd2 stB"/>
+ <gd name="dx6" fmla="cat2 wd2 ht6 wt6"/>
+ <gd name="dy6" fmla="sat2 hd2 ht6 wt6"/>
+ <gd name="x6" fmla="+- hc dx6 0"/>
+ <gd name="y6" fmla="+- vc dy6 0"/>
+ <gd name="adval2" fmla="pin 40000 adj2 99000"/>
+ <gd name="ratio" fmla="*/ adval2 1 100000"/>
+ <gd name="iwd2" fmla="*/ wd2 ratio 1"/>
+ <gd name="ihd2" fmla="*/ hd2 ratio 1"/>
+ <gd name="wt2" fmla="sin iwd2 stT"/>
+ <gd name="ht2" fmla="cos ihd2 stT"/>
+ <gd name="dx2" fmla="cat2 iwd2 ht2 wt2"/>
+ <gd name="dy2" fmla="sat2 ihd2 ht2 wt2"/>
+ <gd name="x2" fmla="+- hc dx2 0"/>
+ <gd name="y2" fmla="+- vc dy2 0"/>
+ <gd name="wt5" fmla="sin iwd2 stB"/>
+ <gd name="ht5" fmla="cos ihd2 stB"/>
+ <gd name="dx5" fmla="cat2 iwd2 ht5 wt5"/>
+ <gd name="dy5" fmla="sat2 ihd2 ht5 wt5"/>
+ <gd name="x5" fmla="+- hc dx5 0"/>
+ <gd name="y5" fmla="+- vc dy5 0"/>
+ <gd name="d1" fmla="+- hd2 0 ihd2"/>
+ <gd name="d12" fmla="*/ d1 1 2"/>
+ <gd name="yu" fmla="+- vc 0 d12"/>
+ <gd name="yd" fmla="+- vc d12 0"/>
+ <gd name="v1" fmla="*/ d12 d12 1"/>
+ <gd name="v2" fmla="*/ ihd2 ihd2 1"/>
+ <gd name="v3" fmla="*/ v1 1 v2"/>
+ <gd name="v4" fmla="+- 1 0 v3"/>
+ <gd name="v5" fmla="*/ iwd2 iwd2 1"/>
+ <gd name="v6" fmla="*/ v4 v5 1"/>
+ <gd name="v7" fmla="sqrt v6"/>
+ <gd name="xl" fmla="+- hc 0 v7"/>
+ <gd name="xr" fmla="+- hc v7 0"/>
+ <gd name="wtadj" fmla="sin iwd2 adj1"/>
+ <gd name="htadj" fmla="cos ihd2 adj1"/>
+ <gd name="dxadj" fmla="cat2 iwd2 htadj wtadj"/>
+ <gd name="dyadj" fmla="sat2 ihd2 htadj wtadj"/>
+ <gd name="xadj" fmla="+- hc dxadj 0"/>
+ <gd name="yadj" fmla="+- vc dyadj 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefR="adj2" minR="0" maxR="100000" gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="xadj" y="yadj"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stT" swAng="swT"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x2" y="y2"/>
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="stT" swAng="swT"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="xl" y="yu"/>
+ </moveTo>
+ <lnTo>
+ <pt x="xr" y="yu"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="xl" y="yd"/>
+ </moveTo>
+ <lnTo>
+ <pt x="xr" y="yd"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x5" y="y5"/>
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="stB" swAng="swB"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x6" y="y6"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="stB" swAng="swB"/>
+ </path>
+ </pathLst>
+ </textButtonPour>
+ <textCanDown>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 14286"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 33333"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y0" fmla="+- t dy 0"/>
+ <gd name="y1" fmla="+- b 0 dy"/>
+ <gd name="ncd2" fmla="*/ cd2 -1 1"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="33333">
+ <pos x="hc" y="y0"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="dy" stAng="cd2" swAng="ncd2"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="dy" stAng="cd2" swAng="ncd2"/>
+ </path>
+ </pathLst>
+ </textCanDown>
+ <textCanUp>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 85714"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 66667 adj 100000"/>
+ <gd name="dy1" fmla="*/ a h 100000"/>
+ <gd name="dy" fmla="+- h 0 dy1"/>
+ <gd name="y0" fmla="+- t dy1 0"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="66667" maxY="100000">
+ <pos x="hc" y="y0"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="dy" stAng="cd2" swAng="cd2"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="dy" stAng="cd2" swAng="cd2"/>
+ </path>
+ </pathLst>
+ </textCanUp>
+ <textCascadeDown>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 44444"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 28570 adj 100000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="dy2" fmla="+- h 0 dy"/>
+ <gd name="dy3" fmla="*/ dy2 1 4"/>
+ <gd name="y2" fmla="+- t dy3 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="28570" maxY="100000">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="y2"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textCascadeDown>
+ <textCascadeUp>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 44444"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 28570 adj 100000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="dy2" fmla="+- h 0 dy"/>
+ <gd name="dy3" fmla="*/ dy2 1 4"/>
+ <gd name="y2" fmla="+- t dy3 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="28570" maxY="100000">
+ <pos x="r" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y2"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="y1"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textCascadeUp>
+ <textChevron>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000"/>
+ <gd name="y" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t b y"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="l" y="y"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y"/>
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="t"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="y1"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textChevron>
+ <textChevronInverted>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 75000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 50000 adj 100000"/>
+ <gd name="y" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- b 0 y"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="50000" maxY="100000">
+ <pos x="l" y="y"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="y1"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y"/>
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="b"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textChevronInverted>
+ <textCircle>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 10800000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj 21599999"/>
+ <gd name="d0" fmla="+- adval 0 10800000"/>
+ <gd name="d1" fmla="+- 10800000 0 adval"/>
+ <gd name="d2" fmla="+- 21600000 0 adval"/>
+ <gd name="d3" fmla="?: d1 d1 10799999"/>
+ <gd name="d4" fmla="?: d0 d2 d3"/>
+ <gd name="swAng" fmla="*/ d4 2 1"/>
+ <gd name="wt1" fmla="sin wd2 adj"/>
+ <gd name="ht1" fmla="cos hd2 adj"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefAng="adj" minAng="0" maxAng="21599999">
+ <pos x="x1" y="y1"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="adval" swAng="swAng"/>
+ </path>
+ </pathLst>
+ </textCircle>
+ <textCirclePour>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val cd2"/>
+ <gd name="adj2" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adval" fmla="pin 0 adj1 21599999"/>
+ <gd name="d0" fmla="+- adval 0 10800000"/>
+ <gd name="d1" fmla="+- 10800000 0 adval"/>
+ <gd name="d2" fmla="+- 21600000 0 adval"/>
+ <gd name="d3" fmla="?: d1 d1 10799999"/>
+ <gd name="d4" fmla="?: d0 d2 d3"/>
+ <gd name="swAng" fmla="*/ d4 2 1"/>
+ <gd name="wt1" fmla="sin wd2 adval"/>
+ <gd name="ht1" fmla="cos hd2 adval"/>
+ <gd name="dx1" fmla="cat2 wd2 ht1 wt1"/>
+ <gd name="dy1" fmla="sat2 hd2 ht1 wt1"/>
+ <gd name="x1" fmla="+- hc dx1 0"/>
+ <gd name="y1" fmla="+- vc dy1 0"/>
+ <gd name="adval2" fmla="pin 0 adj2 99000"/>
+ <gd name="ratio" fmla="*/ adval2 1 100000"/>
+ <gd name="iwd2" fmla="*/ wd2 ratio 1"/>
+ <gd name="ihd2" fmla="*/ hd2 ratio 1"/>
+ <gd name="wt2" fmla="sin iwd2 adval"/>
+ <gd name="ht2" fmla="cos ihd2 adval"/>
+ <gd name="dx2" fmla="cat2 iwd2 ht2 wt2"/>
+ <gd name="dy2" fmla="sat2 ihd2 ht2 wt2"/>
+ <gd name="x2" fmla="+- hc dx2 0"/>
+ <gd name="y2" fmla="+- vc dy2 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahPolar gdRefR="adj2" minR="0" maxR="100000" gdRefAng="adj1" minAng="0" maxAng="21599999">
+ <pos x="x2" y="y2"/>
+ </ahPolar>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="hd2" stAng="adval" swAng="swAng"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x2" y="y2"/>
+ </moveTo>
+ <arcTo wR="iwd2" hR="ihd2" stAng="adval" swAng="swAng"/>
+ </path>
+ </pathLst>
+ </textCirclePour>
+ <textCurveDown>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 45977"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 56338"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="gd1" fmla="*/ dy 3 4"/>
+ <gd name="gd2" fmla="*/ dy 5 4"/>
+ <gd name="gd3" fmla="*/ dy 3 8"/>
+ <gd name="gd4" fmla="*/ dy 1 8"/>
+ <gd name="gd5" fmla="+- h 0 gd3"/>
+ <gd name="gd6" fmla="+- gd4 h 0"/>
+ <gd name="y0" fmla="+- t dy 0"/>
+ <gd name="y1" fmla="+- t gd1 0"/>
+ <gd name="y2" fmla="+- t gd2 0"/>
+ <gd name="y3" fmla="+- t gd3 0"/>
+ <gd name="y4" fmla="+- t gd4 0"/>
+ <gd name="y5" fmla="+- t gd5 0"/>
+ <gd name="y6" fmla="+- t gd6 0"/>
+ <gd name="x1" fmla="+- l wd3 0"/>
+ <gd name="x2" fmla="+- r 0 wd3"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="56338">
+ <pos x="r" y="y0"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x1" y="y1"/>
+ <pt x="x2" y="y2"/>
+ <pt x="r" y="y0"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y5"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x1" y="y6"/>
+ <pt x="x2" y="y6"/>
+ <pt x="r" y="y5"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textCurveDown>
+ <textCurveUp>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 45977"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 56338"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="gd1" fmla="*/ dy 3 4"/>
+ <gd name="gd2" fmla="*/ dy 5 4"/>
+ <gd name="gd3" fmla="*/ dy 3 8"/>
+ <gd name="gd4" fmla="*/ dy 1 8"/>
+ <gd name="gd5" fmla="+- h 0 gd3"/>
+ <gd name="gd6" fmla="+- gd4 h 0"/>
+ <gd name="y0" fmla="+- t dy 0"/>
+ <gd name="y1" fmla="+- t gd1 0"/>
+ <gd name="y2" fmla="+- t gd2 0"/>
+ <gd name="y3" fmla="+- t gd3 0"/>
+ <gd name="y4" fmla="+- t gd4 0"/>
+ <gd name="y5" fmla="+- t gd5 0"/>
+ <gd name="y6" fmla="+- t gd6 0"/>
+ <gd name="x1" fmla="+- l wd3 0"/>
+ <gd name="x2" fmla="+- r 0 wd3"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="56338">
+ <pos x="l" y="y0"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y0"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x1" y="y2"/>
+ <pt x="x2" y="y1"/>
+ <pt x="r" y="t"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y5"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x1" y="y6"/>
+ <pt x="x2" y="y6"/>
+ <pt x="r" y="y5"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textCurveUp>
+ <textDeflate>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 18750"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 37500"/>
+ <gd name="dy" fmla="*/ a ss 100000"/>
+ <gd name="gd0" fmla="*/ dy 4 3"/>
+ <gd name="gd1" fmla="+- h 0 gd0"/>
+ <gd name="adjY" fmla="+- t dy 0"/>
+ <gd name="y0" fmla="+- t gd0 0"/>
+ <gd name="y1" fmla="+- t gd1 0"/>
+ <gd name="x0" fmla="+- l wd3 0"/>
+ <gd name="x1" fmla="+- r 0 wd3"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="37500">
+ <pos x="hc" y="adjY"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x0" y="y0"/>
+ <pt x="x1" y="y0"/>
+ <pt x="r" y="t"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x0" y="y1"/>
+ <pt x="x1" y="y1"/>
+ <pt x="r" y="b"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textDeflate>
+ <textDeflateBottom>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 6250 adj 100000"/>
+ <gd name="dy" fmla="*/ a ss 100000"/>
+ <gd name="dy2" fmla="+- h 0 dy"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="cp" fmla="+- y1 0 dy2"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="6250" maxY="100000">
+ <pos x="hc" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="cp"/>
+ <pt x="r" y="b"/>
+ </quadBezTo>
+ </path>
+ </pathLst>
+ </textDeflateBottom>
+ <textDeflateInflate>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 35000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 5000 adj 95000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="del" fmla="*/ h 5 100"/>
+ <gd name="dh1" fmla="*/ h 45 100"/>
+ <gd name="dh2" fmla="*/ h 55 100"/>
+ <gd name="yh" fmla="+- dy 0 del"/>
+ <gd name="yl" fmla="+- dy del 0"/>
+ <gd name="y3" fmla="+- yh yh dh1"/>
+ <gd name="y4" fmla="+- yl yl dh2"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="5000" maxY="95000">
+ <pos x="hc" y="dy"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="dh1"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="y3"/>
+ <pt x="r" y="dh1"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="dh2"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="y4"/>
+ <pt x="r" y="dh2"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textDeflateInflate>
+ <textDeflateInflateDeflate>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 3000 adj 47000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="del" fmla="*/ h 3 100"/>
+ <gd name="ey1" fmla="*/ h 30 100"/>
+ <gd name="ey2" fmla="*/ h 36 100"/>
+ <gd name="ey3" fmla="*/ h 63 100"/>
+ <gd name="ey4" fmla="*/ h 70 100"/>
+ <gd name="by" fmla="+- b 0 dy"/>
+ <gd name="yh1" fmla="+- dy 0 del"/>
+ <gd name="yl1" fmla="+- dy del 0"/>
+ <gd name="yh2" fmla="+- by 0 del"/>
+ <gd name="yl2" fmla="+- by del 0"/>
+ <gd name="y1" fmla="+- yh1 yh1 ey1"/>
+ <gd name="y2" fmla="+- yl1 yl1 ey2"/>
+ <gd name="y3" fmla="+- yh2 yh2 ey3"/>
+ <gd name="y4" fmla="+- yl2 yl2 ey4"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="3000" maxY="47000">
+ <pos x="hc" y="dy"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="ey1"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="y1"/>
+ <pt x="r" y="ey1"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="ey2"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="y2"/>
+ <pt x="r" y="ey2"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="ey3"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="y3"/>
+ <pt x="r" y="ey3"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="ey4"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="y4"/>
+ <pt x="r" y="ey4"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textDeflateInflateDeflate>
+ <textDeflateTop>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 93750"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="cp" fmla="+- y1 dy 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="93750">
+ <pos x="hc" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="cp"/>
+ <pt x="r" y="t"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textDeflateTop>
+ <textDoubleWave1>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 6250"/>
+ <gd name="adj2" fmla="val 0"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 12500"/>
+ <gd name="a2" fmla="pin -10000 adj2 10000"/>
+ <gd name="y1" fmla="*/ h a1 100000"/>
+ <gd name="dy2" fmla="*/ y1 10 3"/>
+ <gd name="y2" fmla="+- y1 0 dy2"/>
+ <gd name="y3" fmla="+- y1 dy2 0"/>
+ <gd name="y4" fmla="+- b 0 y1"/>
+ <gd name="y5" fmla="+- y4 0 dy2"/>
+ <gd name="y6" fmla="+- y4 dy2 0"/>
+ <gd name="of" fmla="*/ w a2 100000"/>
+ <gd name="of2" fmla="*/ w a2 50000"/>
+ <gd name="x1" fmla="abs of"/>
+ <gd name="dx2" fmla="?: of2 0 of2"/>
+ <gd name="x2" fmla="+- l 0 dx2"/>
+ <gd name="dx8" fmla="?: of2 of2 0"/>
+ <gd name="x8" fmla="+- r 0 dx8"/>
+ <gd name="dx3" fmla="+/ dx2 x8 6"/>
+ <gd name="x3" fmla="+- x2 dx3 0"/>
+ <gd name="dx4" fmla="+/ dx2 x8 3"/>
+ <gd name="x4" fmla="+- x2 dx4 0"/>
+ <gd name="x5" fmla="+/ x2 x8 2"/>
+ <gd name="x6" fmla="+- x5 dx3 0"/>
+ <gd name="x7" fmla="+/ x6 x8 2"/>
+ <gd name="x9" fmla="+- l dx8 0"/>
+ <gd name="x15" fmla="+- r dx2 0"/>
+ <gd name="x10" fmla="+- x9 dx3 0"/>
+ <gd name="x11" fmla="+- x9 dx4 0"/>
+ <gd name="x12" fmla="+/ x9 x15 2"/>
+ <gd name="x13" fmla="+- x12 dx3 0"/>
+ <gd name="x14" fmla="+/ x13 x15 2"/>
+ <gd name="x16" fmla="+- r 0 x1"/>
+ <gd name="xAdj" fmla="+- hc of 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="12500">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="-10000" maxX="10000">
+ <pos x="xAdj" y="b"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x2" y="y1"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x3" y="y2"/>
+ <pt x="x4" y="y3"/>
+ <pt x="x5" y="y1"/>
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x6" y="y2"/>
+ <pt x="x7" y="y3"/>
+ <pt x="x8" y="y1"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x9" y="y4"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x10" y="y5"/>
+ <pt x="x11" y="y6"/>
+ <pt x="x12" y="y4"/>
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x13" y="y5"/>
+ <pt x="x14" y="y6"/>
+ <pt x="x15" y="y4"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textDoubleWave1>
+ <textFadeDown>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 33333"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 49999"/>
+ <gd name="dx" fmla="*/ a w 100000"/>
+ <gd name="x1" fmla="+- l dx 0"/>
+ <gd name="x2" fmla="+- r 0 dx"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="49999">
+ <pos x="x1" y="b"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x1" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textFadeDown>
+ <textFadeLeft>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 33333"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 49999"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="y2" fmla="+- b 0 dy"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="49999">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y2"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textFadeLeft>
+ <textFadeRight>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 33333"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 49999"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="y2" fmla="+- b 0 dy"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="49999">
+ <pos x="r" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="y1"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="y2"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textFadeRight>
+ <textFadeUp>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 33333"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 49999"/>
+ <gd name="dx" fmla="*/ a w 100000"/>
+ <gd name="x1" fmla="+- l dx 0"/>
+ <gd name="x2" fmla="+- r 0 dx"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="0" maxX="49999">
+ <pos x="x1" y="t"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x1" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="x2" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textFadeUp>
+ <textInflate>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 18750"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 20000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="gd" fmla="*/ dy 1 3"/>
+ <gd name="gd0" fmla="+- 0 0 gd"/>
+ <gd name="gd1" fmla="+- h 0 gd0"/>
+ <gd name="ty" fmla="+- t dy 0"/>
+ <gd name="by" fmla="+- b 0 dy"/>
+ <gd name="y0" fmla="+- t gd0 0"/>
+ <gd name="y1" fmla="+- t gd1 0"/>
+ <gd name="x0" fmla="+- l wd3 0"/>
+ <gd name="x1" fmla="+- r 0 wd3"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="20000">
+ <pos x="l" y="ty"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="ty"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x0" y="y0"/>
+ <pt x="x1" y="y0"/>
+ <pt x="r" y="ty"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="by"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x0" y="y1"/>
+ <pt x="x1" y="y1"/>
+ <pt x="r" y="by"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textInflate>
+ <textInflateBottom>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 60000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 60000 adj 100000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="ty" fmla="+- t dy 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="60000" maxY="100000">
+ <pos x="l" y="ty"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="ty"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="b"/>
+ <pt x="r" y="ty"/>
+ </quadBezTo>
+ </path>
+ </pathLst>
+ </textInflateBottom>
+ <textInflateTop>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 40000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 50000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="ty" fmla="+- t dy 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="50000">
+ <pos x="l" y="ty"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="ty"/>
+ </moveTo>
+ <quadBezTo>
+ <pt x="hc" y="t"/>
+ <pt x="r" y="ty"/>
+ </quadBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textInflateTop>
+ <textPlain>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 30000 adj 70000"/>
+ <gd name="mid" fmla="*/ a w 100000"/>
+ <gd name="midDir" fmla="+- mid 0 hc"/>
+ <gd name="dl" fmla="+- mid 0 l"/>
+ <gd name="dr" fmla="+- r 0 mid"/>
+ <gd name="dl2" fmla="*/ dl 2 1"/>
+ <gd name="dr2" fmla="*/ dr 2 1"/>
+ <gd name="dx" fmla="?: midDir dr2 dl2"/>
+ <gd name="xr" fmla="+- l dx 0"/>
+ <gd name="xl" fmla="+- r 0 dx"/>
+ <gd name="tlx" fmla="?: midDir l xl"/>
+ <gd name="trx" fmla="?: midDir xr r"/>
+ <gd name="blx" fmla="?: midDir xl l"/>
+ <gd name="brx" fmla="?: midDir r xr"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefX="adj" minX="30000" maxX="70000">
+ <pos x="mid" y="b"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="tlx" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="trx" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="blx" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="brx" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textPlain>
+ <textRingInside>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 60000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 50000 adj 99000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y" fmla="+- t dy 0"/>
+ <gd name="r" fmla="*/ dy 1 2"/>
+ <gd name="y1" fmla="+- t r 0"/>
+ <gd name="y2" fmla="+- b 0 r"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="50000" maxY="99000">
+ <pos x="hc" y="y"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="r" stAng="10800000" swAng="21599999"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y2"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="r" stAng="10800000" swAng="21599999"/>
+ </path>
+ </pathLst>
+ </textRingInside>
+ <textRingOutside>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 60000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 50000 adj 99000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y" fmla="+- t dy 0"/>
+ <gd name="r" fmla="*/ dy 1 2"/>
+ <gd name="y1" fmla="+- t r 0"/>
+ <gd name="y2" fmla="+- b 0 r"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="50000" maxY="99000">
+ <pos x="hc" y="y"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="r" stAng="10800000" swAng="-21599999"/>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y2"/>
+ </moveTo>
+ <arcTo wR="wd2" hR="r" stAng="10800000" swAng="-21599999"/>
+ </path>
+ </pathLst>
+ </textRingOutside>
+ <textSlantDown>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 44445"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 28569 adj 100000"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="y2" fmla="+- b 0 dy"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="28569" maxY="100000">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="y2"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textSlantDown>
+ <textSlantUp>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 55555"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 71431"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="y2" fmla="+- b 0 dy"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="71431">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="y2"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textSlantUp>
+ <textStop>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 25000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 14286 adj 50000"/>
+ <gd name="dx" fmla="*/ w 1 3"/>
+ <gd name="dy" fmla="*/ a h 100000"/>
+ <gd name="x1" fmla="+- l dx 0"/>
+ <gd name="x2" fmla="+- r 0 dx"/>
+ <gd name="y1" fmla="+- t dy 0"/>
+ <gd name="y2" fmla="+- b 0 dy"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="14286" maxY="50000">
+ <pos x="l" y="dy"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y1"/>
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="t"/>
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="t"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y1"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y2"/>
+ </moveTo>
+ <lnTo>
+ <pt x="x1" y="b"/>
+ </lnTo>
+ <lnTo>
+ <pt x="x2" y="b"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y2"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textStop>
+ <textTriangle>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 100000"/>
+ <gd name="y" fmla="*/ a h 100000"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="100000">
+ <pos x="l" y="y"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="y"/>
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="t"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="b"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="b"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textTriangle>
+ <textTriangleInverted>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj" fmla="val 50000"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a" fmla="pin 0 adj 100000"/>
+ <gd name="y" fmla="*/ a h 100000"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj" minY="0" maxY="100000">
+ <pos x="l" y="y"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="l" y="t"/>
+ </moveTo>
+ <lnTo>
+ <pt x="r" y="t"/>
+ </lnTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="l" y="y"/>
+ </moveTo>
+ <lnTo>
+ <pt x="hc" y="b"/>
+ </lnTo>
+ <lnTo>
+ <pt x="r" y="y"/>
+ </lnTo>
+ </path>
+ </pathLst>
+ </textTriangleInverted>
+ <textWave1>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 12500"/>
+ <gd name="adj2" fmla="val 0"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 20000"/>
+ <gd name="a2" fmla="pin -10000 adj2 10000"/>
+ <gd name="y1" fmla="*/ h a1 100000"/>
+ <gd name="dy2" fmla="*/ y1 10 3"/>
+ <gd name="y2" fmla="+- y1 0 dy2"/>
+ <gd name="y3" fmla="+- y1 dy2 0"/>
+ <gd name="y4" fmla="+- b 0 y1"/>
+ <gd name="y5" fmla="+- y4 0 dy2"/>
+ <gd name="y6" fmla="+- y4 dy2 0"/>
+ <gd name="of" fmla="*/ w a2 100000"/>
+ <gd name="of2" fmla="*/ w a2 50000"/>
+ <gd name="x1" fmla="abs of"/>
+ <gd name="dx2" fmla="?: of2 0 of2"/>
+ <gd name="x2" fmla="+- l 0 dx2"/>
+ <gd name="dx5" fmla="?: of2 of2 0"/>
+ <gd name="x5" fmla="+- r 0 dx5"/>
+ <gd name="dx3" fmla="+/ dx2 x5 3"/>
+ <gd name="x3" fmla="+- x2 dx3 0"/>
+ <gd name="x4" fmla="+/ x3 x5 2"/>
+ <gd name="x6" fmla="+- l dx5 0"/>
+ <gd name="x10" fmla="+- r dx2 0"/>
+ <gd name="x7" fmla="+- x6 dx3 0"/>
+ <gd name="x8" fmla="+/ x7 x10 2"/>
+ <gd name="x9" fmla="+- r 0 x1"/>
+ <gd name="xAdj" fmla="+- hc of 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="20000">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="-10000" maxX="10000">
+ <pos x="xAdj" y="b"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x2" y="y1"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x3" y="y2"/>
+ <pt x="x4" y="y3"/>
+ <pt x="x5" y="y1"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x6" y="y4"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x7" y="y5"/>
+ <pt x="x8" y="y6"/>
+ <pt x="x10" y="y4"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textWave1>
+ <textWave2>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 12500"/>
+ <gd name="adj2" fmla="val 0"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 20000"/>
+ <gd name="a2" fmla="pin -10000 adj2 10000"/>
+ <gd name="y1" fmla="*/ h a1 100000"/>
+ <gd name="dy2" fmla="*/ y1 10 3"/>
+ <gd name="y2" fmla="+- y1 0 dy2"/>
+ <gd name="y3" fmla="+- y1 dy2 0"/>
+ <gd name="y4" fmla="+- b 0 y1"/>
+ <gd name="y5" fmla="+- y4 0 dy2"/>
+ <gd name="y6" fmla="+- y4 dy2 0"/>
+ <gd name="of" fmla="*/ w a2 100000"/>
+ <gd name="of2" fmla="*/ w a2 50000"/>
+ <gd name="x1" fmla="abs of"/>
+ <gd name="dx2" fmla="?: of2 0 of2"/>
+ <gd name="x2" fmla="+- l 0 dx2"/>
+ <gd name="dx5" fmla="?: of2 of2 0"/>
+ <gd name="x5" fmla="+- r 0 dx5"/>
+ <gd name="dx3" fmla="+/ dx2 x5 3"/>
+ <gd name="x3" fmla="+- x2 dx3 0"/>
+ <gd name="x4" fmla="+/ x3 x5 2"/>
+ <gd name="x6" fmla="+- l dx5 0"/>
+ <gd name="x10" fmla="+- r dx2 0"/>
+ <gd name="x7" fmla="+- x6 dx3 0"/>
+ <gd name="x8" fmla="+/ x7 x10 2"/>
+ <gd name="x9" fmla="+- r 0 x1"/>
+ <gd name="xAdj" fmla="+- hc of 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="20000">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="-10000" maxX="10000">
+ <pos x="xAdj" y="b"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x2" y="y1"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x3" y="y3"/>
+ <pt x="x4" y="y2"/>
+ <pt x="x5" y="y1"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x6" y="y4"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x7" y="y6"/>
+ <pt x="x8" y="y5"/>
+ <pt x="x10" y="y4"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textWave2>
+ <textWave4>
+ <avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="adj1" fmla="val 6250"/>
+ <gd name="adj2" fmla="val 0"/>
+ </avLst>
+ <gdLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <gd name="a1" fmla="pin 0 adj1 12500"/>
+ <gd name="a2" fmla="pin -10000 adj2 10000"/>
+ <gd name="y1" fmla="*/ h a1 100000"/>
+ <gd name="dy2" fmla="*/ y1 10 3"/>
+ <gd name="y2" fmla="+- y1 0 dy2"/>
+ <gd name="y3" fmla="+- y1 dy2 0"/>
+ <gd name="y4" fmla="+- b 0 y1"/>
+ <gd name="y5" fmla="+- y4 0 dy2"/>
+ <gd name="y6" fmla="+- y4 dy2 0"/>
+ <gd name="of" fmla="*/ w a2 100000"/>
+ <gd name="of2" fmla="*/ w a2 50000"/>
+ <gd name="x1" fmla="abs of"/>
+ <gd name="dx2" fmla="?: of2 0 of2"/>
+ <gd name="x2" fmla="+- l 0 dx2"/>
+ <gd name="dx8" fmla="?: of2 of2 0"/>
+ <gd name="x8" fmla="+- r 0 dx8"/>
+ <gd name="dx3" fmla="+/ dx2 x8 6"/>
+ <gd name="x3" fmla="+- x2 dx3 0"/>
+ <gd name="dx4" fmla="+/ dx2 x8 3"/>
+ <gd name="x4" fmla="+- x2 dx4 0"/>
+ <gd name="x5" fmla="+/ x2 x8 2"/>
+ <gd name="x6" fmla="+- x5 dx3 0"/>
+ <gd name="x7" fmla="+/ x6 x8 2"/>
+ <gd name="x9" fmla="+- l dx8 0"/>
+ <gd name="x15" fmla="+- r dx2 0"/>
+ <gd name="x10" fmla="+- x9 dx3 0"/>
+ <gd name="x11" fmla="+- x9 dx4 0"/>
+ <gd name="x12" fmla="+/ x9 x15 2"/>
+ <gd name="x13" fmla="+- x12 dx3 0"/>
+ <gd name="x14" fmla="+/ x13 x15 2"/>
+ <gd name="x16" fmla="+- r 0 x1"/>
+ <gd name="xAdj" fmla="+- hc of 0"/>
+ </gdLst>
+ <ahLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <ahXY gdRefY="adj1" minY="0" maxY="12500">
+ <pos x="l" y="y1"/>
+ </ahXY>
+ <ahXY gdRefX="adj2" minX="-10000" maxX="10000">
+ <pos x="xAdj" y="b"/>
+ </ahXY>
+ </ahLst>
+ <pathLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
+ <path>
+ <moveTo>
+ <pt x="x2" y="y1"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x3" y="y3"/>
+ <pt x="x4" y="y2"/>
+ <pt x="x5" y="y1"/>
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x6" y="y3"/>
+ <pt x="x7" y="y2"/>
+ <pt x="x8" y="y1"/>
+ </cubicBezTo>
+ </path>
+ <path>
+ <moveTo>
+ <pt x="x9" y="y4"/>
+ </moveTo>
+ <cubicBezTo>
+ <pt x="x10" y="y6"/>
+ <pt x="x11" y="y5"/>
+ <pt x="x12" y="y4"/>
+ </cubicBezTo>
+ <cubicBezTo>
+ <pt x="x13" y="y6"/>
+ <pt x="x14" y="y5"/>
+ <pt x="x15" y="y4"/>
+ </cubicBezTo>
+ </path>
+ </pathLst>
+ </textWave4>
+</presetTextWarpDefinitions>
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
new file mode 100644
index 000000000000..0d07e6cf5226
--- /dev/null
+++ b/oox/source/export/shapes.cxx
@@ -0,0 +1,994 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/export/shapes.hxx"
+#include "oox/export/utils.hxx"
+
+#include <cstdio>
+#include <com/sun/star/awt/CharSet.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <tools/stream.hxx>
+#include <tools/string.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <unotools/fontcvt.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/outdev.hxx>
+#include <svtools/grfmgr.hxx>
+#include <rtl/strbuf.hxx>
+#include <sfx2/app.hxx>
+#include <svl/languageoptions.hxx>
+#include <svx/escherex.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svxenum.hxx>
+#include <svx/unoapi.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::i18n;
+using ::com::sun::star::beans::PropertyState;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::XPropertyState;
+using ::com::sun::star::container::XEnumeration;
+using ::com::sun::star::container::XEnumerationAccess;
+using ::com::sun::star::container::XIndexAccess;
+using ::com::sun::star::drawing::FillStyle;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::text::XSimpleText;
+using ::com::sun::star::text::XText;
+using ::com::sun::star::text::XTextContent;
+using ::com::sun::star::text::XTextField;
+using ::com::sun::star::text::XTextRange;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::sax_fastparser::FSHelperPtr;
+
+DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
+
+#define IDS(x) (OString(#x " ") + OString::valueOf( mnShapeIdMax++ )).getStr()
+
+struct CustomShapeTypeTranslationTable
+{
+ const char* sOOo;
+ const char* sMSO;
+};
+
+static const CustomShapeTypeTranslationTable pCustomShapeTypeTranslationTable[] =
+{
+ // { "non-primitive", mso_sptMin },
+ { "rectangle", "rect" },
+ { "round-rectangle", "roundRect" },
+ { "ellipse", "ellipse" },
+ { "diamond", "diamond" },
+ { "isosceles-triangle", "triangle" },
+ { "right-triangle", "rtTriangle" },
+ { "parallelogram", "parallelogram" },
+ { "trapezoid", "trapezoid" },
+ { "hexagon", "hexagon" },
+ { "octagon", "octagon" },
+ { "cross", "plus" },
+ { "star5", "star5" },
+ { "right-arrow", "rightArrow" },
+ // { "mso-spt14", mso_sptThickArrow },
+ { "pentagon-right", "homePlate" },
+ { "cube", "cube" },
+ // { "mso-spt17", mso_sptBalloon },
+ // { "mso-spt18", mso_sptSeal },
+ { "mso-spt19", "arc" },
+ { "mso-spt20", "line" },
+ { "mso-spt21", "plaque" },
+ { "can", "can" },
+ { "ring", "donut" },
+ { "mso-spt24", "textSimple" },
+ { "mso-spt25", "textOctagon" },
+ { "mso-spt26", "textHexagon" },
+ { "mso-spt27", "textCurve" },
+ { "mso-spt28", "textWave" },
+ { "mso-spt29", "textRing" },
+ { "mso-spt30", "textOnCurve" },
+ { "mso-spt31", "textOnRing" },
+ { "mso-spt32", "straightConnector1" },
+ { "mso-spt33", "bentConnector2" },
+ { "mso-spt34", "bentConnector3" },
+ { "mso-spt35", "bentConnector4" },
+ { "mso-spt36", "bentConnector5" },
+ { "mso-spt37", "curvedConnector2" },
+ { "mso-spt38", "curvedConnector3" },
+ { "mso-spt39", "curvedConnector4" },
+ { "mso-spt40", "curvedConnector5" },
+ { "mso-spt41", "callout1" },
+ { "mso-spt42", "callout2" },
+ { "mso-spt43", "callout3" },
+ { "mso-spt44", "accentCallout1" },
+ { "mso-spt45", "accentCallout2" },
+ { "mso-spt46", "accentCallout3" },
+ { "line-callout-1", "borderCallout1" },
+ { "line-callout-2", "borderCallout2" },
+ { "line-callout-3", "borderCallout3" },
+ { "mso-spt49", "accentBorderCallout90" },
+ { "mso-spt50", "accentBorderCallout1" },
+ { "mso-spt51", "accentBorderCallout2" },
+ { "mso-spt52", "accentBorderCallout3" },
+ { "mso-spt53", "ribbon" },
+ { "mso-spt54", "ribbon2" },
+ { "chevron", "chevron" },
+ { "pentagon", "pentagon" },
+ { "forbidden", "noSmoking" },
+ { "star8", "seal8" },
+ { "mso-spt59", "seal16" },
+ { "mso-spt60", "seal32" },
+ { "rectangular-callout", "wedgeRectCallout" },
+ { "round-rectangular-callout", "wedgeRoundRectCallout" },
+ { "round-callout", "wedgeEllipseCallout" },
+ { "mso-spt64", "wave" },
+ { "paper", "foldedCorner" },
+ { "left-arrow", "leftArrow" },
+ { "down-arrow", "downArrow" },
+ { "up-arrow", "upArrow" },
+ { "left-right-arrow", "leftRightArrow" },
+ { "up-down-arrow", "upDownArrow" },
+ { "mso-spt71", "irregularSeal1" },
+ { "bang", "irregularSeal2" },
+ { "lightning", "lightningBolt" },
+ { "heart", "heart" },
+ { "mso-spt75", "pictureFrame" },
+ { "quad-arrow", "quadArrow" },
+ { "left-arrow-callout", "leftArrowCallout" },
+ { "right-arrow-callout", "rightArrowCallout" },
+ { "up-arrow-callout", "upArrowCallout" },
+ { "down-arrow-callout", "downArrowCallout" },
+ { "left-right-arrow-callout", "leftRightArrowCallout" },
+ { "up-down-arrow-callout", "upDownArrowCallout" },
+ { "quad-arrow-callout", "quadArrowCallout" },
+ { "quad-bevel", "bevel" },
+ { "left-bracket", "leftBracket" },
+ { "right-bracket", "rightBracket" },
+ { "left-brace", "leftBrace" },
+ { "right-brace", "rightBrace" },
+ { "mso-spt89", "leftUpArrow" },
+ { "mso-spt90", "bentUpArrow" },
+ { "mso-spt91", "bentArrow" },
+ { "star24", "seal24" },
+ { "striped-right-arrow", "stripedRightArrow" },
+ { "notched-right-arrow", "notchedRightArrow" },
+ { "block-arc", "blockArc" },
+ { "smiley", "smileyFace" },
+ { "vertical-scroll", "verticalScroll" },
+ { "horizontal-scroll", "horizontalScroll" },
+ { "circular-arrow", "circularArrow" },
+ { "mso-spt100", "pie" }, // looks like MSO_SPT is wrong here
+ { "mso-spt101", "uturnArrow" },
+ { "mso-spt102", "curvedRightArrow" },
+ { "mso-spt103", "curvedLeftArrow" },
+ { "mso-spt104", "curvedUpArrow" },
+ { "mso-spt105", "curvedDownArrow" },
+ { "cloud-callout", "cloudCallout" },
+ { "mso-spt107", "ellipseRibbon" },
+ { "mso-spt108", "ellipseRibbon2" },
+ { "flowchart-process", "flowChartProcess" },
+ { "flowchart-decision", "flowChartDecision" },
+ { "flowchart-data", "flowChartInputOutput" },
+ { "flowchart-predefined-process", "flowChartPredefinedProcess" },
+ { "flowchart-internal-storage", "flowChartInternalStorage" },
+ { "flowchart-document", "flowChartDocument" },
+ { "flowchart-multidocument", "flowChartMultidocument" },
+ { "flowchart-terminator", "flowChartTerminator" },
+ { "flowchart-preparation", "flowChartPreparation" },
+ { "flowchart-manual-input", "flowChartManualInput" },
+ { "flowchart-manual-operation", "flowChartManualOperation" },
+ { "flowchart-connector", "flowChartConnector" },
+ { "flowchart-card", "flowChartPunchedCard" },
+ { "flowchart-punched-tape", "flowChartPunchedTape" },
+ { "flowchart-summing-junction", "flowChartSummingJunction" },
+ { "flowchart-or", "flowChartOr" },
+ { "flowchart-collate", "flowChartCollate" },
+ { "flowchart-sort", "flowChartSort" },
+ { "flowchart-extract", "flowChartExtract" },
+ { "flowchart-merge", "flowChartMerge" },
+ { "mso-spt129", "flowChartOfflineStorage" },
+ { "flowchart-stored-data", "flowChartOnlineStorage" },
+ { "flowchart-sequential-access", "flowChartMagneticTape" },
+ { "flowchart-magnetic-disk", "flowChartMagneticDisk" },
+ { "flowchart-direct-access-storage", "flowChartMagneticDrum" },
+ { "flowchart-display", "flowChartDisplay" },
+ { "flowchart-delay", "flowChartDelay" },
+ { "fontwork-plain-text", "textPlainText" },
+ { "fontwork-stop", "textStop" },
+ { "fontwork-triangle-up", "textTriangle" },
+ { "fontwork-triangle-down", "textTriangleInverted" },
+ { "fontwork-chevron-up", "textChevron" },
+ { "fontwork-chevron-down", "textChevronInverted" },
+ { "mso-spt142", "textRingInside" },
+ { "mso-spt143", "textRingOutside" },
+ { "fontwork-arch-up-curve", "textArchUpCurve" },
+ { "fontwork-arch-down-curve", "textArchDownCurve" },
+ { "fontwork-circle-curve", "textCircleCurve" },
+ { "fontwork-open-circle-curve", "textButtonCurve" },
+ { "fontwork-arch-up-pour", "textArchUpPour" },
+ { "fontwork-arch-down-pour", "textArchDownPour" },
+ { "fontwork-circle-pour", "textCirclePour" },
+ { "fontwork-open-circle-pour", "textButtonPour" },
+ { "fontwork-curve-up", "textCurveUp" },
+ { "fontwork-curve-down", "textCurveDown" },
+ { "fontwork-fade-up-and-right", "textCascadeUp" },
+ { "fontwork-fade-up-and-left", "textCascadeDown" },
+ { "fontwork-wave", "textWave1" },
+ { "mso-spt157", "textWave2" },
+ { "mso-spt158", "textWave3" },
+ { "mso-spt159", "textWave4" },
+ { "fontwork-inflate", "textInflate" },
+ { "mso-spt161", "textDeflate" },
+ { "mso-spt162", "textInflateBottom" },
+ { "mso-spt163", "textDeflateBottom" },
+ { "mso-spt164", "textInflateTop" },
+ { "mso-spt165", "textDeflateTop" },
+ { "mso-spt166", "textDeflateInflate" },
+ { "mso-spt167", "textDeflateInflateDeflate" },
+ { "fontwork-fade-right", "textFadeRight" },
+ { "fontwork-fade-left", "textFadeLeft" },
+ { "fontwork-fade-up", "textFadeUp" },
+ { "fontwork-fade-down", "textFadeDown" },
+ { "fontwork-slant-up", "textSlantUp" },
+ { "fontwork-slant-down", "textSlantDown" },
+ { "mso-spt174", "textCanUp" },
+ { "mso-spt175", "textCanDown" },
+ { "flowchart-alternate-process", "flowChartAlternateProcess" },
+ { "flowchart-off-page-connector", "flowChartOffpageConnector" },
+ { "mso-spt178", "callout90" },
+ { "mso-spt179", "accentCallout90" },
+ { "mso-spt180", "borderCallout90" },
+ { "mso-spt182", "leftRightUpArrow" },
+ { "sun", "sun" },
+ { "moon", "moon" },
+ { "bracket-pair", "bracketPair" },
+ { "brace-pair", "bracePair" },
+ { "star4", "seal4" },
+ { "mso-spt188", "doubleWave" },
+ { "mso-spt189", "actionButtonBlank" },
+ { "mso-spt190", "actionButtonHome" },
+ { "mso-spt191", "actionButtonHelp" },
+ { "mso-spt192", "actionButtonInformation" },
+ { "mso-spt193", "actionButtonForwardNext" },
+ { "mso-spt194", "actionButtonBackPrevious" },
+ { "mso-spt195", "actionButtonEnd" },
+ { "mso-spt196", "actionButtonBeginning" },
+ { "mso-spt197", "actionButtonReturn" },
+ { "mso-spt198", "actionButtonDocument" },
+ { "mso-spt199", "actionButtonSound" },
+ { "mso-spt200", "actionButtonMovie" },
+ { "mso-spt201", "hostControl" },
+ { "mso-spt202", "rect" }
+};
+
+struct StringCheck
+{
+ bool operator()( const char* s1, const char* s2 ) const
+ {
+ return strcmp( s1, s2 ) == 0;
+ }
+};
+
+typedef std::hash_map< const char*, const char*, std::hash<const char*>, StringCheck> CustomShapeTypeTranslationHashMap;
+static CustomShapeTypeTranslationHashMap* pCustomShapeTypeTranslationHashMap = NULL;
+
+static const char* lcl_GetPresetGeometry( const char* sShapeType )
+{
+ const char* sPresetGeo;
+
+ if( pCustomShapeTypeTranslationHashMap == NULL )
+ {
+ pCustomShapeTypeTranslationHashMap = new CustomShapeTypeTranslationHashMap ();
+ for( unsigned int i = 0; i < sizeof( pCustomShapeTypeTranslationTable )/sizeof( CustomShapeTypeTranslationTable ); i ++ )
+ {
+ (*pCustomShapeTypeTranslationHashMap)[ pCustomShapeTypeTranslationTable[ i ].sOOo ] = pCustomShapeTypeTranslationTable[ i ].sMSO;
+ //DBG(printf("type OOo: %s MSO: %s\n", pCustomShapeTypeTranslationTable[ i ].sOOo, pCustomShapeTypeTranslationTable[ i ].sMSO));
+ }
+ }
+
+ sPresetGeo = (*pCustomShapeTypeTranslationHashMap)[ sShapeType ];
+
+ if( sPresetGeo == NULL )
+ sPresetGeo = "rect";
+
+ return sPresetGeo;
+}
+
+namespace oox { namespace drawingml {
+
+#define GETA(propName) \
+ GetProperty( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ) )
+
+#define GETAD(propName) \
+ ( GetPropertyAndState( rXPropSet, rXPropState, String( RTL_CONSTASCII_USTRINGPARAM( #propName ) ), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
+
+#define GET(variable, propName) \
+ if ( GETA(propName) ) \
+ mAny >>= variable;
+
+ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ::oox::core::XmlFilterBase* pFB, DocumentType eDocumentType )
+ : DrawingML( pFS, pFB, eDocumentType )
+ , mnXmlNamespace( nXmlNamespace )
+ , mnShapeIdMax( 1 )
+ , mnPictureIdMax( 1 )
+ , maFraction( 1, 576 )
+ , maMapModeSrc( MAP_100TH_MM )
+ , maMapModeDest( MAP_INCH, Point(), maFraction, maFraction )
+{
+}
+
+sal_Int32 ShapeExport::GetXmlNamespace() const
+{
+ return mnXmlNamespace;
+}
+
+ShapeExport& ShapeExport::SetXmlNamespace( sal_Int32 nXmlNamespace )
+{
+ mnXmlNamespace = nXmlNamespace;
+ return *this;
+}
+
+awt::Size ShapeExport::MapSize( const awt::Size& rSize ) const
+{
+ Size aRetSize( OutputDevice::LogicToLogic( Size( rSize.Width, rSize.Height ), maMapModeSrc, maMapModeDest ) );
+
+ if ( !aRetSize.Width() )
+ aRetSize.Width()++;
+ if ( !aRetSize.Height() )
+ aRetSize.Height()++;
+ return awt::Size( aRetSize.Width(), aRetSize.Height() );
+}
+
+sal_Bool ShapeExport::NonEmptyText( Reference< XShape > xShape )
+{
+ Reference< XSimpleText > xText( xShape, UNO_QUERY );
+
+ return ( xText.is() && xText->getString().getLength() );
+}
+
+ShapeExport& ShapeExport::WriteBezierShape( Reference< XShape > xShape, sal_Bool bClosed )
+{
+ DBG(printf("write open bezier shape\n"));
+
+ FSHelperPtr pFS = GetFS();
+ pFS->startElementNS( mnXmlNamespace, XML_sp, FSEND );
+
+ PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
+ Rectangle aRect( aPolyPolygon.GetBoundRect() );
+ awt::Size size = MapSize( awt::Size( aRect.GetWidth(), aRect.GetHeight() ) );
+
+ DBG(printf("poly count %d\nsize: %d x %d", aPolyPolygon.Count(), int( size.Width ), int( size.Height )));
+
+ // non visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, IDS( Freeform ),
+ FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
+ WriteNonVisualProperties( xShape );
+ pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteTransformation( aRect );
+ WritePolyPolygon( aPolyPolygon );
+ Reference< XPropertySet > xProps( xShape, UNO_QUERY );
+ if( xProps.is() ) {
+ if( bClosed )
+ WriteFill( xProps );
+ WriteOutline( xProps );
+ }
+
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ // write text
+ WriteTextBox( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_sp );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteClosedBezierShape( Reference< XShape > xShape )
+{
+ return WriteBezierShape( xShape, TRUE );
+}
+
+ShapeExport& ShapeExport::WriteOpenBezierShape( Reference< XShape > xShape )
+{
+ return WriteBezierShape( xShape, FALSE );
+}
+
+ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
+{
+ DBG(printf("write custom shape\n"));
+
+ Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
+ SdrObjCustomShape* pShape = (SdrObjCustomShape*) GetSdrObjectFromXShape( xShape );
+ sal_Bool bIsDefaultObject = EscherPropertyContainer::IsDefaultObject( pShape );
+ sal_Bool bPredefinedHandlesUsed = TRUE;
+ OUString sShapeType;
+ sal_uInt32 nMirrorFlags = 0;
+ MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( xShape, nMirrorFlags, sShapeType );
+ const char* sPresetShape = lcl_GetPresetGeometry( USS( sShapeType ) );
+ DBG(printf("custom shape type: %s ==> %s\n", USS( sShapeType ), sPresetShape));
+ Sequence< PropertyValue > aGeometrySeq;
+ sal_Int32 nAdjustmentValuesIndex = -1;
+ sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
+
+ if( GETA( CustomShapeGeometry ) ) {
+ DBG(printf("got custom shape geometry\n"));
+ if( mAny >>= aGeometrySeq ) {
+
+ DBG(printf("got custom shape geometry sequence\n"));
+ for( int i = 0; i < aGeometrySeq.getLength(); i++ ) {
+ const PropertyValue& rProp = aGeometrySeq[ i ];
+ DBG(printf("geometry property: %s\n", USS( rProp.Name )));
+
+ if( rProp.Name.equalsAscii( "AdjustmentValues" ))
+ nAdjustmentValuesIndex = i;
+ else if( rProp.Name.equalsAscii( "Handles" )) {
+ if( !bIsDefaultObject )
+ bPredefinedHandlesUsed = FALSE;
+ // TODO: update nAdjustmentsWhichNeedsToBeConverted here
+ }
+ }
+ }
+ }
+
+ FSHelperPtr pFS = GetFS();
+ pFS->startElementNS( mnXmlNamespace, XML_sp, FSEND );
+
+ // non visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, IDS( CustomShape ),
+ FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
+ WriteNonVisualProperties( xShape );
+ pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteShapeTransformation( xShape );
+ if( nAdjustmentValuesIndex != -1 )
+ WritePresetShape( sPresetShape, eShapeType, bPredefinedHandlesUsed, nAdjustmentsWhichNeedsToBeConverted, aGeometrySeq[ nAdjustmentValuesIndex ] );
+ else
+ WritePresetShape( sPresetShape );
+ if( rXPropSet.is() )
+ {
+ WriteFill( rXPropSet );
+ WriteOutline( rXPropSet );
+ }
+
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ // write text
+ WriteTextBox( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_sp );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteEllipseShape( Reference< XShape > xShape )
+{
+ DBG(printf("write ellipse shape\n"));
+
+ FSHelperPtr pFS = GetFS();
+
+ pFS->startElementNS( mnXmlNamespace, XML_sp, FSEND );
+
+ // TODO: arc, section, cut, connector
+
+ // non visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, IDS( Ellipse ),
+ FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
+ WriteNonVisualProperties( xShape );
+ pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteShapeTransformation( xShape );
+ WritePresetShape( "ellipse" );
+ Reference< XPropertySet > xProps( xShape, UNO_QUERY );
+ if( xProps.is() )
+ {
+ WriteFill( xProps );
+ WriteOutline( xProps );
+ }
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ // write text
+ WriteTextBox( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_sp );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteFill( Reference< XPropertySet > xPropSet )
+{
+ FillStyle aFillStyle( FillStyle_NONE );
+ xPropSet->getPropertyValue( S( "FillStyle" ) ) >>= aFillStyle;
+
+ if( aFillStyle == FillStyle_BITMAP )
+ {
+ //DBG(printf ("FillStyle_BITMAP properties\n"));
+ //DBG(dump_pset(rXPropSet));
+ }
+
+ if( aFillStyle == FillStyle_NONE ||
+ aFillStyle == FillStyle_HATCH )
+ return *this;
+
+ switch( aFillStyle )
+ {
+ case ::com::sun::star::drawing::FillStyle_SOLID :
+ WriteSolidFill( xPropSet );
+ break;
+ case ::com::sun::star::drawing::FillStyle_GRADIENT :
+ WriteGradientFill( xPropSet );
+ break;
+ case ::com::sun::star::drawing::FillStyle_BITMAP :
+ WriteBlipFill( xPropSet, S( "FillBitmapURL" ) );
+ break;
+ default:
+ ;
+ }
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape )
+{
+ DBG(printf("write graphic object shape\n"));
+
+ if( NonEmptyText( xShape ) )
+ {
+ WriteTextShape( xShape );
+
+ //DBG(dump_pset(mXPropSet));
+
+ return *this;
+ }
+
+ DBG(printf("graphicObject without text\n"));
+
+ OUString sGraphicURL;
+ Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
+ if( !xShapeProps.is() || !( xShapeProps->getPropertyValue( S( "GraphicURL" ) ) >>= sGraphicURL ) )
+ {
+ DBG(printf("no graphic URL found\n"));
+ return *this;
+ }
+
+ FSHelperPtr pFS = GetFS();
+
+ pFS->startElementNS( mnXmlNamespace, XML_pic, FSEND );
+
+ pFS->startElementNS( mnXmlNamespace, XML_nvPicPr, FSEND );
+
+ OUString sName, sDescr;
+ bool bHaveName = xShapeProps->getPropertyValue( S( "Name" ) ) >>= sName;
+ bool bHaveDesc = xShapeProps->getPropertyValue( S( "Description" ) ) >>= sDescr;
+
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, bHaveName ? USS( sName ) : (OString("Picture ") + OString::valueOf( mnPictureIdMax++ )).getStr(),
+ XML_descr, bHaveDesc ? USS( sDescr ) : NULL,
+ FSEND );
+ // OOXTODO: //cNvPr children: XML_extLst, XML_hlinkClick, XML_hlinkHover
+
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPicPr,
+ // OOXTODO: XML_preferRelativeSize
+ FSEND );
+
+ WriteNonVisualProperties( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_nvPicPr );
+
+ pFS->startElementNS( mnXmlNamespace, XML_blipFill, FSEND );
+
+ WriteBlip( sGraphicURL );
+
+ bool bStretch = false;
+ if( ( xShapeProps->getPropertyValue( S( "FillBitmapStretch" ) ) >>= bStretch ) && bStretch )
+ {
+ WriteStretch();
+ }
+
+ pFS->endElementNS( mnXmlNamespace, XML_blipFill );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteShapeTransformation( xShape );
+ WritePresetShape( "rect" );
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ pFS->endElementNS( mnXmlNamespace, XML_pic );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteConnectorShape( Reference< XShape > xShape )
+{
+ sal_Bool bFlipH = false;
+ sal_Bool bFlipV = false;
+
+ DBG(printf("write connector shape\n"));
+
+ FSHelperPtr pFS = GetFS();
+
+ const char* sGeometry = "line";
+ Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
+ Reference< XPropertyState > rXPropState( xShape, UNO_QUERY );
+ awt::Point aStartPoint, aEndPoint;
+ Reference< XShape > rXShapeA;
+ Reference< XShape > rXShapeB;
+ PropertyState eState;
+ ConnectorType eConnectorType;
+ if( GETAD( EdgeKind ) ) {
+ mAny >>= eConnectorType;
+
+ switch( eConnectorType ) {
+ case ConnectorType_CURVE:
+ sGeometry = "curvedConnector3";
+ break;
+ case ConnectorType_STANDARD:
+ sGeometry = "bentConnector3";
+ break;
+ default:
+ case ConnectorType_LINE:
+ case ConnectorType_LINES:
+ sGeometry = "straightConnector1";
+ break;
+ }
+
+ if( GETAD( EdgeStartPoint ) ) {
+ mAny >>= aStartPoint;
+ if( GETAD( EdgeEndPoint ) ) {
+ mAny >>= aEndPoint;
+ }
+ }
+ GET( rXShapeA, EdgeStartConnection );
+ GET( rXShapeB, EdgeEndConnection );
+ }
+ EscherConnectorListEntry aConnectorEntry( xShape, aStartPoint, rXShapeA, aEndPoint, rXShapeB );
+
+ Rectangle aRect( Point( aStartPoint.X, aStartPoint.Y ), Point( aEndPoint.X, aEndPoint.Y ) );
+ if( aRect.getWidth() < 0 ) {
+ bFlipH = TRUE;
+ aRect.setX( aEndPoint.X );
+ aRect.setWidth( aStartPoint.X - aEndPoint.X );
+ }
+
+ if( aRect.getHeight() < 0 ) {
+ bFlipV = TRUE;
+ aRect.setY( aEndPoint.Y );
+ aRect.setHeight( aStartPoint.Y - aEndPoint.Y );
+ }
+
+ pFS->startElementNS( mnXmlNamespace, XML_cxnSp, FSEND );
+
+ // non visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_nvCxnSpPr, FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, IDS( Line ),
+ FSEND );
+ // non visual connector shape drawing properties
+ pFS->startElementNS( mnXmlNamespace, XML_cNvCxnSpPr, FSEND );
+ WriteConnectorConnections( aConnectorEntry, GetShapeID( rXShapeA ), GetShapeID( rXShapeB ) );
+ pFS->endElementNS( mnXmlNamespace, XML_cNvCxnSpPr );
+ pFS->singleElementNS( mnXmlNamespace, XML_nvPr, FSEND );
+ pFS->endElementNS( mnXmlNamespace, XML_nvCxnSpPr );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteTransformation( aRect, bFlipH, bFlipV );
+ // TODO: write adjustments (ppt export doesn't work well there either)
+ WritePresetShape( sGeometry );
+ Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
+ if( xShapeProps.is() )
+ WriteOutline( xShapeProps );
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ // write text
+ WriteTextBox( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_cxnSp );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteLineShape( Reference< XShape > xShape )
+{
+ sal_Bool bFlipH = false;
+ sal_Bool bFlipV = false;
+
+ DBG(printf("write line shape\n"));
+
+ FSHelperPtr pFS = GetFS();
+
+ pFS->startElementNS( mnXmlNamespace, XML_sp, FSEND );
+
+ PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
+ if( aPolyPolygon.Count() == 1 && aPolyPolygon[ 0 ].GetSize() == 2)
+ {
+ const Polygon& rPoly = aPolyPolygon[ 0 ];
+
+ bFlipH = ( rPoly[ 0 ].X() > rPoly[ 1 ].X() );
+ bFlipV = ( rPoly[ 0 ].Y() > rPoly[ 1 ].Y() );
+ }
+
+ // non visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, IDS( Line ),
+ FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
+ WriteNonVisualProperties( xShape );
+ pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteShapeTransformation( xShape, bFlipH, bFlipV );
+ WritePresetShape( "line" );
+ Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
+ if( xShapeProps.is() )
+ WriteOutline( xShapeProps );
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ // write text
+ WriteTextBox( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_sp );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteNonVisualDrawingProperties( Reference< XShape > xShape, const char* pName )
+{
+ GetFS()->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, pName,
+ FSEND );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteNonVisualProperties( Reference< XShape > )
+{
+ // Override to generate //nvPr elements.
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteRectangleShape( Reference< XShape > xShape )
+{
+ DBG(printf("write rectangle shape\n"));
+
+ FSHelperPtr pFS = GetFS();
+
+ pFS->startElementNS( mnXmlNamespace, XML_sp, FSEND );
+
+ sal_Int32 nRadius = 0;
+
+ Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
+ if( xShapeProps.is() )
+ {
+ xShapeProps->getPropertyValue( S( "CornerRadius" ) ) >>= nRadius;
+ }
+
+ if( nRadius )
+ {
+ nRadius = MapSize( awt::Size( nRadius, 0 ) ).Width;
+ }
+
+ // non visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+ XML_id, I32S( GetNewShapeID( xShape ) ),
+ XML_name, IDS( Rectangle ),
+ FSEND );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
+ WriteNonVisualProperties( xShape );
+ pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteShapeTransformation( xShape );
+ WritePresetShape( "rect" );
+ Reference< XPropertySet > xProps( xShape, UNO_QUERY );
+ if( xProps.is() )
+ {
+ WriteFill( xProps );
+ WriteOutline( xProps );
+ }
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ // write text
+ WriteTextBox( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_sp );
+
+ return *this;
+}
+
+typedef ShapeExport& (ShapeExport::*ShapeConverter)( Reference< XShape > );
+typedef std::hash_map< const char*, ShapeConverter, std::hash<const char*>, StringCheck> NameToConvertMapType;
+
+static const NameToConvertMapType& lcl_GetConverters()
+{
+ static bool shape_map_inited = false;
+ static NameToConvertMapType shape_converters;
+ if( shape_map_inited )
+ {
+ return shape_converters;
+ }
+
+ shape_converters[ "com.sun.star.drawing.ClosedBezierShape" ] = &ShapeExport::WriteClosedBezierShape;
+ shape_converters[ "com.sun.star.drawing.ConnectorShape" ] = &ShapeExport::WriteConnectorShape;
+ shape_converters[ "com.sun.star.drawing.CustomShape" ] = &ShapeExport::WriteCustomShape;
+ shape_converters[ "com.sun.star.drawing.EllipseShape" ] = &ShapeExport::WriteEllipseShape;
+ shape_converters[ "com.sun.star.drawing.GraphicObjectShape" ] = &ShapeExport::WriteGraphicObjectShape;
+ shape_converters[ "com.sun.star.drawing.LineShape" ] = &ShapeExport::WriteLineShape;
+ shape_converters[ "com.sun.star.drawing.OpenBezierShape" ] = &ShapeExport::WriteOpenBezierShape;
+ shape_converters[ "com.sun.star.drawing.RectangleShape" ] = &ShapeExport::WriteRectangleShape;
+ shape_converters[ "com.sun.star.drawing.TextShape" ] = &ShapeExport::WriteTextShape;
+ shape_converters[ "com.sun.star.presentation.DateTimeShape" ] = &ShapeExport::WriteTextShape;
+ shape_converters[ "com.sun.star.presentation.FooterShape" ] = &ShapeExport::WriteTextShape;
+ shape_converters[ "com.sun.star.presentation.HeaderShape" ] = &ShapeExport::WriteTextShape;
+ shape_converters[ "com.sun.star.presentation.NotesShape" ] = &ShapeExport::WriteTextShape;
+ shape_converters[ "com.sun.star.presentation.OutlinerShape" ] = &ShapeExport::WriteTextShape;
+ shape_converters[ "com.sun.star.presentation.SlideNumberShape" ] = &ShapeExport::WriteTextShape;
+ shape_converters[ "com.sun.star.presentation.TitleTextShape" ] = &ShapeExport::WriteTextShape;
+ shape_map_inited = true;
+
+ return shape_converters;
+}
+
+ShapeExport& ShapeExport::WriteShape( Reference< XShape > xShape )
+{
+ OUString sShapeType = xShape->getShapeType();
+ DBG( printf( "write shape: %s\n", USS( sShapeType ) ) );
+ NameToConvertMapType::const_iterator aConverter = lcl_GetConverters().find( USS( sShapeType ) );
+ if( aConverter == lcl_GetConverters().end() )
+ {
+ DBG( printf( "unknown shape\n" ) );
+ return WriteUnknownShape( xShape );
+ }
+ (this->*(aConverter->second))( xShape );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteTextBox( Reference< XShape > xShape )
+{
+ if( NonEmptyText( xShape ) )
+ {
+ FSHelperPtr pFS = GetFS();
+
+ pFS->startElementNS( mnXmlNamespace, XML_txBody, FSEND );
+ WriteText( xShape );
+ pFS->endElementNS( mnXmlNamespace, XML_txBody );
+ }
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteTextShape( Reference< XShape > xShape )
+{
+ FSHelperPtr pFS = GetFS();
+
+ pFS->startElementNS( mnXmlNamespace, XML_sp, FSEND );
+
+ // non visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
+ WriteNonVisualDrawingProperties( xShape, IDS( TextShape ) );
+ pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, XML_txBox, "1", FSEND );
+ WriteNonVisualProperties( xShape );
+ pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
+
+ // visual shape properties
+ pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
+ WriteShapeTransformation( xShape );
+ WritePresetShape( "rect" );
+ WriteBlipFill( Reference< XPropertySet >(xShape, UNO_QUERY ), S( "GraphicURL" ) );
+ pFS->endElementNS( mnXmlNamespace, XML_spPr );
+
+ WriteTextBox( xShape );
+
+ pFS->endElementNS( mnXmlNamespace, XML_sp );
+
+ return *this;
+}
+
+ShapeExport& ShapeExport::WriteUnknownShape( Reference< XShape > )
+{
+ // Override this method to do something useful.
+ return *this;
+}
+
+size_t ShapeExport::ShapeHash::operator()( const ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShape > rXShape ) const
+{
+ return maHashFunction( USS( rXShape->getShapeType() ) );
+}
+
+sal_Int32 ShapeExport::GetNewShapeID( const Reference< XShape > rXShape )
+{
+ sal_Int32 nID = GetFB()->GetUniqueId();
+
+ maShapeMap[ rXShape ] = nID;
+
+ return nID;
+}
+
+sal_Int32 ShapeExport::GetShapeID( const Reference< XShape > rXShape )
+{
+ ShapeHashMap::const_iterator aIter = maShapeMap.find( rXShape );
+
+ if( aIter == maShapeMap.end() )
+ return -1;
+
+ return aIter->second;
+}
+
+} }
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
new file mode 100644
index 000000000000..a629d89639fa
--- /dev/null
+++ b/oox/source/export/vmlexport.cxx
@@ -0,0 +1,837 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <oox/export/vmlexport.hxx>
+
+#include <tokens.hxx>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustring.hxx>
+
+#include <tools/stream.hxx>
+
+#include <cstdio>
+
+using rtl::OString;
+using rtl::OStringBuffer;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+
+using namespace sax_fastparser;
+using namespace oox::vml;
+
+/// Implementation of an empty stream that silently succeeds, but does nothing.
+///
+/// In fact, this is a hack. The right solution is to abstract EscherEx to be
+/// able to work without SvStream; but at the moment it is better to live with
+/// this I guess.
+class SvNullStream : public SvStream
+{
+protected:
+ virtual sal_Size GetData( void* pData, sal_Size nSize ) { memset( pData, 0, nSize ); return nSize; }
+ virtual sal_Size PutData( const void*, sal_Size nSize ) { return nSize; }
+ virtual sal_Size SeekPos( sal_Size nPos ) { return nPos; }
+ virtual void SetSize( sal_Size ) {}
+ virtual void FlushData() {}
+
+public:
+ SvNullStream() : SvStream() {}
+ virtual ~SvNullStream() {}
+};
+
+VMLExport::VMLExport( ::sax_fastparser::FSHelperPtr pSerializer )
+ : EscherEx( *( new SvNullStream ), 0 ),
+ m_pSerializer( pSerializer ),
+ m_pShapeAttrList( NULL ),
+ m_nShapeType( ESCHER_ShpInst_Nil ),
+ m_pShapeStyle( new OStringBuffer( 200 ) ),
+ m_pShapeTypeWritten( new bool[ ESCHER_ShpInst_COUNT ] )
+{
+ mnGroupLevel = 1;
+ memset( m_pShapeTypeWritten, 0, ESCHER_ShpInst_COUNT * sizeof( bool ) );
+}
+
+VMLExport::~VMLExport()
+{
+ delete mpOutStrm, mpOutStrm = NULL;
+ delete m_pShapeStyle, m_pShapeStyle = NULL;
+ delete[] m_pShapeTypeWritten, m_pShapeTypeWritten = NULL;
+}
+
+void VMLExport::OpenContainer( UINT16 nEscherContainer, int nRecInstance )
+{
+ EscherEx::OpenContainer( nEscherContainer, nRecInstance );
+
+ if ( nEscherContainer == ESCHER_SpContainer )
+ {
+ // opening a shape container
+#if OSL_DEBUG_LEVEL > 0
+ if ( m_nShapeType != ESCHER_ShpInst_Nil )
+ fprintf( stderr, "Warning! VMLExport::OpenContainer(): opening shape inside a shape.\n" );
+#endif
+ m_nShapeType = ESCHER_ShpInst_Nil;
+ m_pShapeAttrList = m_pSerializer->createAttrList();
+
+ if ( m_pShapeStyle->getLength() )
+ m_pShapeStyle->makeStringAndClear();
+
+ m_pShapeStyle->ensureCapacity( 200 );
+
+ // postpone the ouput so that we are able to write even the elements
+ // that we learn inside Commit()
+ m_pSerializer->mark();
+ }
+}
+
+void VMLExport::CloseContainer()
+{
+ if ( mRecTypes.back() == ESCHER_SpContainer )
+ {
+ // write the shape now when we have all the info
+ sal_Int32 nShapeElement = StartShape();
+
+ m_pSerializer->mergeTopMarks();
+
+ EndShape( nShapeElement );
+
+ // cleanup
+ m_nShapeType = ESCHER_ShpInst_Nil;
+ m_pShapeAttrList = NULL;
+ }
+
+ EscherEx::CloseContainer();
+}
+
+UINT32 VMLExport::EnterGroup( const String& rShapeName, const Rectangle* pRect )
+{
+ UINT32 nShapeId = GetShapeID();
+
+ OStringBuffer aStyle( 200 );
+ FastAttributeList *pAttrList = m_pSerializer->createAttrList();
+
+ pAttrList->add( XML_id, ShapeIdString( nShapeId ) );
+
+ if ( rShapeName.Len() )
+ pAttrList->add( XML_alt, OUStringToOString( OUString( rShapeName ), RTL_TEXTENCODING_UTF8 ) );
+
+ // style
+ if ( pRect )
+ AddRectangleDimensions( aStyle, *pRect );
+
+ if ( aStyle.getLength() )
+ pAttrList->add( XML_style, aStyle.makeStringAndClear() );
+
+ // coordorigin/coordsize
+ if ( pRect && ( mnGroupLevel == 1 ) )
+ {
+ pAttrList->add( XML_coordorigin,
+ OStringBuffer( 20 ).append( sal_Int32( pRect->Left() ) )
+ .append( "," ).append( sal_Int32( pRect->Top() ) )
+ .makeStringAndClear() );
+
+ pAttrList->add( XML_coordsize,
+ OStringBuffer( 20 ).append( sal_Int32( pRect->Right() ) - sal_Int32( pRect->Left() ) )
+ .append( "," ).append( sal_Int32( pRect->Bottom() ) - sal_Int32( pRect->Top() ) )
+ .makeStringAndClear() );
+ }
+
+ m_pSerializer->startElementNS( XML_v, XML_group, XFastAttributeListRef( pAttrList ) );
+
+ mnGroupLevel++;
+ return nShapeId;
+}
+
+void VMLExport::LeaveGroup()
+{
+ --mnGroupLevel;
+ m_pSerializer->endElementNS( XML_v, XML_group );
+}
+
+void VMLExport::AddShape( UINT32 nShapeType, UINT32 nShapeFlags, UINT32 nShapeId )
+{
+ m_nShapeType = nShapeType;
+ m_nShapeFlags = nShapeFlags;
+
+ m_pShapeAttrList->add( XML_id, ShapeIdString( nShapeId ) );
+}
+
+static void impl_AddArrowHead( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
+{
+ if ( !pAttrList )
+ return;
+
+ const char *pArrowHead = NULL;
+ switch ( nValue )
+ {
+ case ESCHER_LineNoEnd: pArrowHead = "none"; break;
+ case ESCHER_LineArrowEnd: pArrowHead = "block"; break;
+ case ESCHER_LineArrowStealthEnd: pArrowHead = "classic"; break;
+ case ESCHER_LineArrowDiamondEnd: pArrowHead = "diamond"; break;
+ case ESCHER_LineArrowOvalEnd: pArrowHead = "oval"; break;
+ case ESCHER_LineArrowOpenEnd: pArrowHead = "open"; break;
+ }
+
+ if ( pArrowHead )
+ pAttrList->add( nElement, pArrowHead );
+}
+
+static void impl_AddArrowLength( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
+{
+ if ( !pAttrList )
+ return;
+
+ const char *pArrowLength = NULL;
+ switch ( nValue )
+ {
+ case ESCHER_LineShortArrow: pArrowLength = "short"; break;
+ case ESCHER_LineMediumLenArrow: pArrowLength = "medium"; break;
+ case ESCHER_LineLongArrow: pArrowLength = "long"; break;
+ }
+
+ if ( pArrowLength )
+ pAttrList->add( nElement, pArrowLength );
+}
+
+static void impl_AddArrowWidth( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
+{
+ if ( !pAttrList )
+ return;
+
+ const char *pArrowWidth = NULL;
+ switch ( nValue )
+ {
+ case ESCHER_LineNarrowArrow: pArrowWidth = "narrow"; break;
+ case ESCHER_LineMediumWidthArrow: pArrowWidth = "medium"; break;
+ case ESCHER_LineWideArrow: pArrowWidth = "wide"; break;
+ }
+
+ if ( pArrowWidth )
+ pAttrList->add( nElement, pArrowWidth );
+}
+
+static void impl_AddBool( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, bool bValue )
+{
+ if ( !pAttrList )
+ return;
+
+ pAttrList->add( nElement, bValue? "t": "f" );
+}
+
+static void impl_AddColor( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nColor )
+{
+#if OSL_DEBUG_LEVEL > 0
+ if ( nColor & 0xFF000000 )
+ fprintf( stderr, "TODO: this is not a RGB value!\n" );
+#endif
+
+ if ( !pAttrList || ( nColor & 0xFF000000 ) )
+ return;
+
+ nColor = ( ( nColor & 0xFF ) << 16 ) + ( nColor & 0xFF00 ) + ( ( nColor & 0xFF0000 ) >> 16 );
+
+ const char *pColor = NULL;
+ char pRgbColor[10];
+ switch ( nColor )
+ {
+ case 0x000000: pColor = "black"; break;
+ case 0xC0C0C0: pColor = "silver"; break;
+ case 0x808080: pColor = "gray"; break;
+ case 0xFFFFFF: pColor = "white"; break;
+ case 0x800000: pColor = "maroon"; break;
+ case 0xFF0000: pColor = "red"; break;
+ case 0x800080: pColor = "purple"; break;
+ case 0xFF00FF: pColor = "fuchsia"; break;
+ case 0x008000: pColor = "green"; break;
+ case 0x00FF00: pColor = "lime"; break;
+ case 0x808000: pColor = "olive"; break;
+ case 0xFFFF00: pColor = "yellow"; break;
+ case 0x000080: pColor = "navy"; break;
+ case 0x0000FF: pColor = "blue"; break;
+ case 0x008080: pColor = "teal"; break;
+ case 0x00FFFF: pColor = "aqua"; break;
+ default:
+ {
+ snprintf( pRgbColor, sizeof( pRgbColor ), "#%06x", static_cast< unsigned int >( nColor ) ); // not too handy to use OString::valueOf() here :-(
+ pColor = pRgbColor;
+ }
+ break;
+ }
+
+ pAttrList->add( nElement, pColor );
+}
+
+static void impl_AddInt( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
+{
+ if ( !pAttrList )
+ return;
+
+ pAttrList->add( nElement, OString::valueOf( static_cast< sal_Int32 >( nValue ) ).getStr() );
+}
+
+inline sal_uInt16 impl_GetUInt16( const sal_uInt8* &pVal )
+{
+ sal_uInt16 nRet = *pVal++;
+ nRet += ( *pVal++ ) << 8;
+ return nRet;
+}
+
+inline sal_Int32 impl_GetPointComponent( const sal_uInt8* &pVal, sal_uInt16 nPointSize )
+{
+ sal_Int32 nRet = 0;
+ if ( ( nPointSize == 0xfff0 ) || ( nPointSize == 4 ) )
+ {
+ sal_uInt16 nUnsigned = *pVal++;
+ nUnsigned += ( *pVal++ ) << 8;
+
+ nRet = sal_Int16( nUnsigned );
+ }
+ else if ( nPointSize == 8 )
+ {
+ sal_uInt32 nUnsigned = *pVal++;
+ nUnsigned += ( *pVal++ ) << 8;
+ nUnsigned += ( *pVal++ ) << 16;
+ nUnsigned += ( *pVal++ ) << 24;
+
+ nRet = nUnsigned;
+ }
+
+ return nRet;
+}
+
+void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect )
+{
+ if ( m_nShapeType == ESCHER_ShpInst_Nil )
+ return;
+
+ // postpone the output of the embedded elements so that they are written
+ // inside the shapes
+ m_pSerializer->mark();
+
+ // dimensions
+ if ( m_nShapeType == ESCHER_ShpInst_Line )
+ AddLineDimensions( rRect );
+ else
+ AddRectangleDimensions( *m_pShapeStyle, rRect );
+
+ // properties
+ bool bAlreadyWritten[ 0xFFF ];
+ memset( bAlreadyWritten, 0, sizeof( bAlreadyWritten ) );
+ const EscherProperties &rOpts = rProps.GetOpts();
+ for ( EscherProperties::const_iterator it = rOpts.begin(); it != rOpts.end(); ++it )
+ {
+ sal_uInt16 nId = ( it->nPropId & 0x0FFF );
+
+ if ( bAlreadyWritten[ nId ] )
+ continue;
+
+ switch ( nId )
+ {
+ case ESCHER_Prop_WrapText: // 133
+ {
+ const char *pWrapType = NULL;
+ switch ( it->nPropValue )
+ {
+ case ESCHER_WrapSquare:
+ case ESCHER_WrapByPoints: pWrapType = "square"; break; // these two are equivalent according to the docu
+ case ESCHER_WrapNone: pWrapType = "none"; break;
+ case ESCHER_WrapTopBottom: pWrapType = "topAndBottom"; break;
+ case ESCHER_WrapThrough: pWrapType = "through"; break;
+ }
+ if ( pWrapType )
+ m_pSerializer->singleElementNS( XML_w10, XML_wrap,
+ FSNS( XML_w10, XML_type ), pWrapType,
+ FSEND );
+ }
+ bAlreadyWritten[ ESCHER_Prop_WrapText ] = true;
+ break;
+
+ // coordorigin
+ case ESCHER_Prop_geoLeft: // 320
+ case ESCHER_Prop_geoTop: // 321
+ {
+ sal_uInt32 nLeft = 0, nTop = 0;
+
+ if ( nId == ESCHER_Prop_geoLeft )
+ {
+ nLeft = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
+ }
+ else
+ {
+ nTop = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
+ }
+
+ m_pShapeAttrList->add( XML_coordorigin,
+ OStringBuffer( 20 ).append( sal_Int32( nLeft ) )
+ .append( "," ).append( sal_Int32( nTop ) )
+ .makeStringAndClear() );
+ }
+ bAlreadyWritten[ ESCHER_Prop_geoLeft ] = true;
+ bAlreadyWritten[ ESCHER_Prop_geoTop ] = true;
+ break;
+
+ // coordsize
+ case ESCHER_Prop_geoRight: // 322
+ case ESCHER_Prop_geoBottom: // 323
+ {
+ sal_uInt32 nLeft = 0, nRight = 0, nTop = 0, nBottom = 0;
+ rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
+ rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
+
+ if ( nId == ESCHER_Prop_geoRight )
+ {
+ nRight = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoBottom, nBottom );
+ }
+ else
+ {
+ nBottom = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoRight, nRight );
+ }
+
+ m_pShapeAttrList->add( XML_coordsize,
+ OStringBuffer( 20 ).append( sal_Int32( nRight ) - sal_Int32( nLeft ) )
+ .append( "," ).append( sal_Int32( nBottom ) - sal_Int32( nTop ) )
+ .makeStringAndClear() );
+ }
+ bAlreadyWritten[ ESCHER_Prop_geoRight ] = true;
+ bAlreadyWritten[ ESCHER_Prop_geoBottom ] = true;
+ break;
+
+ case ESCHER_Prop_pVertices: // 325
+ case ESCHER_Prop_pSegmentInfo: // 326
+ {
+ EscherPropSortStruct aVertices;
+ EscherPropSortStruct aSegments;
+
+ if ( rProps.GetOpt( ESCHER_Prop_pVertices, aVertices ) &&
+ rProps.GetOpt( ESCHER_Prop_pSegmentInfo, aSegments ) )
+ {
+ const sal_uInt8 *pVerticesIt = aVertices.pBuf + 6;
+ const sal_uInt8 *pSegmentIt = aSegments.pBuf;
+ OStringBuffer aPath( 512 );
+
+ sal_uInt16 nPointSize = aVertices.pBuf[4] + ( aVertices.pBuf[5] << 8 );
+
+ // number of segments
+ sal_uInt16 nSegments = impl_GetUInt16( pSegmentIt );
+ pSegmentIt += 4;
+
+ for ( ; nSegments; --nSegments )
+ {
+ sal_uInt16 nSeg = impl_GetUInt16( pSegmentIt );
+ switch ( nSeg )
+ {
+ case 0x4000: // moveto
+ {
+ sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
+ aPath.append( "m" ).append( nX ).append( "," ).append( nY );
+ }
+ break;
+ case 0xb300:
+ case 0xac00:
+ break;
+ case 0x0001: // lineto
+ {
+ sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
+ aPath.append( "l" ).append( nX ).append( "," ).append( nY );
+ }
+ break;
+ case 0x2001: // curveto
+ {
+ sal_Int32 nX1 = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nY1 = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nX2 = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nY2 = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nX3 = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nY3 = impl_GetPointComponent( pVerticesIt, nPointSize );
+ aPath.append( "c" ).append( nX1 ).append( "," ).append( nY1 ).append( "," )
+ .append( nX2 ).append( "," ).append( nY2 ).append( "," )
+ .append( nX3 ).append( "," ).append( nY3 );
+ }
+ break;
+ case 0xaa00: // nofill
+ aPath.append( "nf" );
+ break;
+ case 0xab00: // nostroke
+ aPath.append( "ns" );
+ break;
+ case 0x6001: // close
+ aPath.append( "x" );
+ break;
+ case 0x8000: // end
+ aPath.append( "e" );
+ break;
+ default:
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO: unhandled segment '%x' in the path\n", nSeg );
+#endif
+ break;
+ }
+ }
+
+ if ( aPath.getLength() )
+ m_pShapeAttrList->add( XML_path, aPath.getStr() );
+ }
+#if OSL_DEBUG_LEVEL > 0
+ else
+ fprintf( stderr, "TODO: unhandled shape path, missing either pVertices or pSegmentInfo.\n" );
+#endif
+ }
+ bAlreadyWritten[ ESCHER_Prop_pVertices ] = true;
+ bAlreadyWritten[ ESCHER_Prop_pSegmentInfo ] = true;
+ break;
+
+ case ESCHER_Prop_fillType: // 384
+ case ESCHER_Prop_fillColor: // 385
+ case ESCHER_Prop_fillBackColor: // 387
+ case ESCHER_Prop_fNoFillHitTest: // 447
+ {
+ sal_uInt32 nValue;
+ sax_fastparser::FastAttributeList *pAttrList = m_pSerializer->createAttrList();
+
+ if ( rProps.GetOpt( ESCHER_Prop_fillType, nValue ) )
+ {
+ const char *pFillType = NULL;
+ switch ( nValue )
+ {
+ case ESCHER_FillSolid: pFillType = "solid"; break;
+ // TODO case ESCHER_FillPattern: pFillType = ""; break;
+ // TODO case ESCHER_FillTexture: pFillType = ""; break;
+ // TODO case ESCHER_FillPicture: pFillType = ""; break;
+ // TODO case ESCHER_FillShade: pFillType = ""; break;
+ // TODO case ESCHER_FillShadeCenter: pFillType = ""; break;
+ // TODO case ESCHER_FillShadeShape: pFillType = ""; break;
+ // TODO case ESCHER_FillShadeScale: pFillType = ""; break;
+ // TODO case ESCHER_FillShadeTitle: pFillType = ""; break;
+ // TODO case ESCHER_FillBackground: pFillType = ""; break;
+ default:
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO: unhandled fill type\n" );
+#endif
+ break;
+ }
+ if ( pFillType )
+ pAttrList->add( XML_type, pFillType );
+ }
+
+ if ( rProps.GetOpt( ESCHER_Prop_fillColor, nValue ) )
+ impl_AddColor( pAttrList, XML_color, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_fillBackColor, nValue ) )
+ impl_AddColor( pAttrList, XML_color2, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ) )
+ impl_AddBool( pAttrList, XML_detectmouseclick, nValue );
+
+ m_pSerializer->singleElementNS( XML_v, XML_fill, XFastAttributeListRef( pAttrList ) );
+ }
+ bAlreadyWritten[ ESCHER_Prop_fillType ] = true;
+ bAlreadyWritten[ ESCHER_Prop_fillColor ] = true;
+ bAlreadyWritten[ ESCHER_Prop_fillBackColor ] = true;
+ bAlreadyWritten[ ESCHER_Prop_fNoFillHitTest ] = true;
+ break;
+
+ case ESCHER_Prop_lineColor: // 448
+ case ESCHER_Prop_lineWidth: // 459
+ case ESCHER_Prop_lineDashing: // 462
+ case ESCHER_Prop_lineStartArrowhead: // 464
+ case ESCHER_Prop_lineEndArrowhead: // 465
+ case ESCHER_Prop_lineStartArrowWidth: // 466
+ case ESCHER_Prop_lineStartArrowLength: // 467
+ case ESCHER_Prop_lineEndArrowWidth: // 468
+ case ESCHER_Prop_lineEndArrowLength: // 469
+ case ESCHER_Prop_lineJoinStyle: // 470
+ case ESCHER_Prop_lineEndCapStyle: // 471
+ {
+ sal_uInt32 nValue;
+ sax_fastparser::FastAttributeList *pAttrList = m_pSerializer->createAttrList();
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineColor, nValue ) )
+ impl_AddColor( pAttrList, XML_color, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineWidth, nValue ) )
+ impl_AddInt( pAttrList, XML_weight, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineDashing, nValue ) )
+ {
+ const char *pDashStyle = NULL;
+ switch ( nValue )
+ {
+ case ESCHER_LineSolid: pDashStyle = "solid"; break;
+ case ESCHER_LineDashSys: pDashStyle = "shortdash"; break;
+ case ESCHER_LineDotSys: pDashStyle = "shortdot"; break;
+ case ESCHER_LineDashDotSys: pDashStyle = "shortdashdot"; break;
+ case ESCHER_LineDashDotDotSys: pDashStyle = "shortdashdotdot"; break;
+ case ESCHER_LineDotGEL: pDashStyle = "dot"; break;
+ case ESCHER_LineDashGEL: pDashStyle = "dash"; break;
+ case ESCHER_LineLongDashGEL: pDashStyle = "longdash"; break;
+ case ESCHER_LineDashDotGEL: pDashStyle = "dashdot"; break;
+ case ESCHER_LineLongDashDotGEL: pDashStyle = "longdashdot"; break;
+ case ESCHER_LineLongDashDotDotGEL: pDashStyle = "longdashdotdot"; break;
+ }
+ if ( pDashStyle )
+ pAttrList->add( XML_dashstyle, pDashStyle );
+ }
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowhead, nValue ) )
+ impl_AddArrowHead( pAttrList, XML_startarrow, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowhead, nValue ) )
+ impl_AddArrowHead( pAttrList, XML_endarrow, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowWidth, nValue ) )
+ impl_AddArrowWidth( pAttrList, XML_startarrowwidth, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowLength, nValue ) )
+ impl_AddArrowLength( pAttrList, XML_startarrowlength, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowWidth, nValue ) )
+ impl_AddArrowWidth( pAttrList, XML_endarrowwidth, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowLength, nValue ) )
+ impl_AddArrowLength( pAttrList, XML_endarrowlength, nValue );
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineJoinStyle, nValue ) )
+ {
+ const char *pJoinStyle = NULL;
+ switch ( nValue )
+ {
+ case ESCHER_LineJoinBevel: pJoinStyle = "bevel"; break;
+ case ESCHER_LineJoinMiter: pJoinStyle = "miter"; break;
+ case ESCHER_LineJoinRound: pJoinStyle = "round"; break;
+ }
+ if ( pJoinStyle )
+ pAttrList->add( XML_joinstyle, pJoinStyle );
+ }
+
+ if ( rProps.GetOpt( ESCHER_Prop_lineEndCapStyle, nValue ) )
+ {
+ const char *pEndCap = NULL;
+ switch ( nValue )
+ {
+ case ESCHER_LineEndCapRound: pEndCap = "round"; break;
+ case ESCHER_LineEndCapSquare: pEndCap = "square"; break;
+ case ESCHER_LineEndCapFlat: pEndCap = "flat"; break;
+ }
+ if ( pEndCap )
+ pAttrList->add( XML_endcap, pEndCap );
+ }
+
+ m_pSerializer->singleElementNS( XML_v, XML_stroke, XFastAttributeListRef( pAttrList ) );
+ }
+ bAlreadyWritten[ ESCHER_Prop_lineColor ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineWidth ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineDashing ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineStartArrowhead ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineEndArrowhead ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineStartArrowWidth ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineStartArrowLength ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineEndArrowWidth ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineEndArrowLength ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineJoinStyle ] = true;
+ bAlreadyWritten[ ESCHER_Prop_lineEndCapStyle ] = true;
+ break;
+
+ case ESCHER_Prop_fHidden:
+ m_pShapeStyle->append( ";visibility:hidden" );
+ break;
+ default:
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "TODO VMLExport::Commit(), unimplemented id: %d, value: %d, data: [%d, %p]\n",
+ it->nPropId, it->nPropValue, it->nPropSize, it->pBuf );
+ if ( it->nPropSize )
+ {
+ const sal_uInt8 *pIt = it->pBuf;
+ fprintf( stderr, " ( " );
+ for ( int nCount = it->nPropSize; nCount; --nCount )
+ {
+ fprintf( stderr, "%02x ", *pIt );
+ ++pIt;
+ }
+ fprintf( stderr, ")\n" );
+ }
+#endif
+ break;
+ }
+ }
+
+ m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE );
+}
+
+OString VMLExport::ShapeIdString( sal_uInt32 nId )
+{
+ return OStringBuffer( 20 ).append( "shape_" ).append( sal_Int64( nId ) ).makeStringAndClear();
+}
+
+void VMLExport::AddLineDimensions( const Rectangle& rRectangle )
+{
+ // style
+ if ( m_pShapeStyle->getLength() )
+ m_pShapeStyle->append( ";" );
+
+ m_pShapeStyle->append( "position:absolute" );
+
+ switch ( m_nShapeFlags & 0xC0 )
+ {
+ case 0x40: m_pShapeStyle->append( ";flip:y" ); break;
+ case 0x80: m_pShapeStyle->append( ";flip:x" ); break;
+ case 0xC0: m_pShapeStyle->append( ";flip:xy" ); break;
+ }
+
+ // the actual dimensions
+ OString aLeft, aTop, aRight, aBottom;
+
+ if ( mnGroupLevel == 1 )
+ {
+ const OString aPt( "pt" );
+ aLeft = OString::valueOf( double( rRectangle.Left() ) / 20 ) + aPt;
+ aTop = OString::valueOf( double( rRectangle.Top() ) / 20 ) + aPt;
+ aRight = OString::valueOf( double( rRectangle.Right() ) / 20 ) + aPt;
+ aBottom = OString::valueOf( double( rRectangle.Bottom() ) / 20 ) + aPt;
+ }
+ else
+ {
+ aLeft = OString::valueOf( rRectangle.Left() );
+ aTop = OString::valueOf( rRectangle.Top() );
+ aRight = OString::valueOf( rRectangle.Right() );
+ aBottom = OString::valueOf( rRectangle.Bottom() );
+ }
+
+ m_pShapeAttrList->add( XML_from,
+ OStringBuffer( 20 ).append( aLeft )
+ .append( "," ).append( aTop )
+ .makeStringAndClear() );
+
+ m_pShapeAttrList->add( XML_to,
+ OStringBuffer( 20 ).append( aRight )
+ .append( "," ).append( aBottom )
+ .makeStringAndClear() );
+}
+
+void VMLExport::AddRectangleDimensions( rtl::OStringBuffer& rBuffer, const Rectangle& rRectangle )
+{
+ if ( rBuffer.getLength() )
+ rBuffer.append( ";" );
+
+ rBuffer.append( "position:absolute;" );
+
+ if ( mnGroupLevel == 1 )
+ {
+ rBuffer.append( "margin-left:" ).append( double( rRectangle.Left() ) / 20 )
+ .append( "pt;margin-top:" ).append( double( rRectangle.Top() ) / 20 )
+ .append( "pt;width:" ).append( double( rRectangle.Right() - rRectangle.Left() ) / 20 )
+ .append( "pt;height:" ).append( double( rRectangle.Bottom() - rRectangle.Top() ) / 20 )
+ .append( "pt" );
+ }
+ else
+ {
+ rBuffer.append( "left:" ).append( rRectangle.Left() )
+ .append( ";top:" ).append( rRectangle.Top() )
+ .append( ";width:" ).append( rRectangle.Right() - rRectangle.Left() )
+ .append( ";height:" ).append( rRectangle.Bottom() - rRectangle.Top() );
+ }
+}
+
+void VMLExport::AddShapeAttribute( sal_Int32 nAttribute, const rtl::OString& rValue )
+{
+ m_pShapeAttrList->add( nAttribute, rValue );
+}
+
+extern const char* pShapeTypes[];
+
+sal_Int32 VMLExport::StartShape()
+{
+ if ( m_nShapeType == ESCHER_ShpInst_Nil )
+ return -1;
+
+ // some of the shapes have their own name ;-)
+ sal_Int32 nShapeElement = -1;
+ bool bReferToShapeType = false;
+ switch ( m_nShapeType )
+ {
+ case ESCHER_ShpInst_NotPrimitive: nShapeElement = XML_shape; break;
+ case ESCHER_ShpInst_Rectangle: nShapeElement = XML_rect; break;
+ case ESCHER_ShpInst_RoundRectangle: nShapeElement = XML_roundrect; break;
+ case ESCHER_ShpInst_Ellipse: nShapeElement = XML_oval; break;
+ case ESCHER_ShpInst_Arc: nShapeElement = XML_arc; break;
+ case ESCHER_ShpInst_Line: nShapeElement = XML_line; break;
+ default:
+ if ( m_nShapeType < ESCHER_ShpInst_COUNT )
+ {
+ nShapeElement = XML_shape;
+
+ // a predefined shape?
+ const char* pShapeType = pShapeTypes[ m_nShapeType ];
+ if ( pShapeType )
+ {
+ bReferToShapeType = true;
+ if ( !m_pShapeTypeWritten[ m_nShapeType ] )
+ {
+ m_pSerializer->write( pShapeType );
+ m_pShapeTypeWritten[ m_nShapeType ] = true;
+ }
+ }
+ else
+ {
+ // rectangle is probably the best fallback...
+ nShapeElement = XML_rect;
+ }
+ }
+ break;
+ }
+
+ // add style
+ m_pShapeAttrList->add( XML_style, m_pShapeStyle->makeStringAndClear() );
+
+ if ( nShapeElement >= 0 )
+ {
+ if ( bReferToShapeType )
+ {
+ m_pShapeAttrList->add( XML_type, OStringBuffer( 20 )
+ .append( "shapetype_" ).append( sal_Int32( m_nShapeType ) )
+ .makeStringAndClear() );
+ }
+
+ // start of the shape
+ m_pSerializer->startElementNS( XML_v, nShapeElement, XFastAttributeListRef( m_pShapeAttrList ) );
+ }
+
+ return nShapeElement;
+}
+
+void VMLExport::EndShape( sal_Int32 nShapeElement )
+{
+ if ( nShapeElement >= 0 )
+ {
+ // end of the shape
+ m_pSerializer->endElementNS( XML_v, nShapeElement );
+ }
+}
diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx
new file mode 100644
index 000000000000..ae10c290b425
--- /dev/null
+++ b/oox/source/helper/attributelist.cxx
@@ -0,0 +1,325 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/attributelist.hxx"
+
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include "oox/token/tokenmap.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::xml::sax;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 XSTRING_ENCCHAR_LEN = 7;
+
+bool lclAddHexDigit( sal_Unicode& orcChar, sal_Unicode cDigit, int nBitShift )
+{
+ if( ('0' <= cDigit) && (cDigit <= '9') ) { orcChar |= ((cDigit - '0') << nBitShift); return true; }
+ if( ('a' <= cDigit) && (cDigit <= 'f') ) { orcChar |= ((cDigit - 'a' + 10) << nBitShift); return true; }
+ if( ('A' <= cDigit) && (cDigit <= 'F') ) { orcChar |= ((cDigit - 'A' + 10) << nBitShift); return true; }
+ return false;
+}
+
+sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd )
+{
+ sal_Unicode cChar = 0;
+ if( (pcEnd - rpcStr >= XSTRING_ENCCHAR_LEN) &&
+ (rpcStr[ 0 ] == '_') &&
+ (rpcStr[ 1 ] == 'x') &&
+ (rpcStr[ 6 ] == '_') &&
+ lclAddHexDigit( cChar, rpcStr[ 2 ], 12 ) &&
+ lclAddHexDigit( cChar, rpcStr[ 3 ], 8 ) &&
+ lclAddHexDigit( cChar, rpcStr[ 4 ], 4 ) &&
+ lclAddHexDigit( cChar, rpcStr[ 5 ], 0 ) )
+ {
+ rpcStr += XSTRING_ENCCHAR_LEN;
+ return cChar;
+ }
+ return *rpcStr++;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+sal_Int32 AttributeConversion::decodeToken( const OUString& rValue )
+{
+ return StaticTokenMap::get().getTokenFromUnicode( rValue );
+}
+
+OUString AttributeConversion::decodeXString( const OUString& rValue )
+{
+ // string shorter than one encoded character - no need to decode
+ if( rValue.getLength() < XSTRING_ENCCHAR_LEN )
+ return rValue;
+ OUStringBuffer aBuffer;
+ const sal_Unicode* pcStr = rValue.getStr();
+ const sal_Unicode* pcEnd = pcStr + rValue.getLength();
+ while( pcStr < pcEnd )
+ aBuffer.append( lclGetXChar( pcStr, pcEnd ) );
+ return aBuffer.makeStringAndClear();
+}
+
+double AttributeConversion::decodeDouble( const OUString& rValue )
+{
+ return rValue.toDouble();
+}
+
+sal_Int32 AttributeConversion::decodeInteger( const OUString& rValue )
+{
+ return rValue.toInt32();
+}
+
+sal_uInt32 AttributeConversion::decodeUnsigned( const OUString& rValue )
+{
+ return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64(), 0, SAL_MAX_UINT32 );
+}
+
+sal_Int64 AttributeConversion::decodeHyper( const OUString& rValue )
+{
+ return rValue.toInt64();
+}
+
+sal_Int32 AttributeConversion::decodeIntegerHex( const OUString& rValue )
+{
+ return rValue.toInt32( 16 );
+}
+
+sal_uInt32 AttributeConversion::decodeUnsignedHex( const OUString& rValue )
+{
+ return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64( 16 ), 0, SAL_MAX_UINT32 );
+}
+
+sal_Int64 AttributeConversion::decodeHyperHex( const OUString& rValue )
+{
+ return rValue.toInt64( 16 );
+}
+
+// ============================================================================
+
+AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) :
+ mxAttribs( rxAttribs )
+{
+ OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" );
+}
+
+bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const
+{
+ return mxAttribs->hasAttribute( nAttrToken );
+}
+
+// optional return values -----------------------------------------------------
+
+OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const
+{
+ sal_Int32 nToken = mxAttribs->getOptionalValueToken( nAttrToken, XML_TOKEN_INVALID );
+ return OptValue< sal_Int32 >( nToken != XML_TOKEN_INVALID, nToken );
+}
+
+OptValue< OUString > AttributeList::getString( sal_Int32 nAttrToken ) const
+{
+ // check if the attribute exists (empty string may be different to missing attribute)
+ if( mxAttribs->hasAttribute( nAttrToken ) )
+ return OptValue< OUString >( mxAttribs->getOptionalValue( nAttrToken ) );
+ return OptValue< OUString >();
+}
+
+OptValue< OUString > AttributeList::getXString( sal_Int32 nAttrToken ) const
+{
+ // check if the attribute exists (empty string may be different to missing attribute)
+ if( mxAttribs->hasAttribute( nAttrToken ) )
+ return OptValue< OUString >( AttributeConversion::decodeXString( mxAttribs->getOptionalValue( nAttrToken ) ) );
+ return OptValue< OUString >();
+}
+
+OptValue< double > AttributeList::getDouble( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ bool bValid = aValue.getLength() > 0;
+ return OptValue< double >( bValid, bValid ? AttributeConversion::decodeDouble( aValue ) : 0.0 );
+}
+
+OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ bool bValid = aValue.getLength() > 0;
+ return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeInteger( aValue ) : 0 );
+}
+
+OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ bool bValid = aValue.getLength() > 0;
+ return OptValue< sal_uInt32 >( bValid, AttributeConversion::decodeUnsigned( aValue ) );
+}
+
+OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ bool bValid = aValue.getLength() > 0;
+ return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyper( aValue ) : 0 );
+}
+
+OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ bool bValid = aValue.getLength() > 0;
+ return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeIntegerHex( aValue ) : 0 );
+}
+
+OptValue< sal_uInt32 > AttributeList::getUnsignedHex( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ bool bValid = aValue.getLength() > 0;
+ return OptValue< sal_uInt32 >( bValid, bValid ? AttributeConversion::decodeUnsignedHex( aValue ) : 0 );
+}
+
+OptValue< sal_Int64 > AttributeList::getHyperHex( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ bool bValid = aValue.getLength() > 0;
+ return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyperHex( aValue ) : 0 );
+}
+
+OptValue< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const
+{
+ // boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0"
+ switch( getToken( nAttrToken, XML_TOKEN_INVALID ) )
+ {
+ case XML_t: return OptValue< bool >( true ); // used in VML
+ case XML_true: return OptValue< bool >( true );
+ case XML_on: return OptValue< bool >( true );
+ case XML_f: return OptValue< bool >( false ); // used in VML
+ case XML_false: return OptValue< bool >( false );
+ case XML_off: return OptValue< bool >( false );
+ }
+ OptValue< sal_Int32 > onValue = getInteger( nAttrToken );
+ return OptValue< bool >( onValue.has(), onValue.get() != 0 );
+}
+
+OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nAttrToken ) const
+{
+ OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
+ DateTime aDateTime;
+ bool bValid = (aValue.getLength() == 19) && (aValue[ 4 ] == '-') && (aValue[ 7 ] == '-') &&
+ (aValue[ 10 ] == 'T') && (aValue[ 13 ] == ':') && (aValue[ 16 ] == ':');
+ if( bValid )
+ {
+ aDateTime.Year = static_cast< sal_uInt16 >( aValue.copy( 0, 4 ).toInt32() );
+ aDateTime.Month = static_cast< sal_uInt16 >( aValue.copy( 5, 2 ).toInt32() );
+ aDateTime.Day = static_cast< sal_uInt16 >( aValue.copy( 8, 2 ).toInt32() );
+ aDateTime.Hours = static_cast< sal_uInt16 >( aValue.copy( 11, 2 ).toInt32() );
+ aDateTime.Minutes = static_cast< sal_uInt16 >( aValue.copy( 14, 2 ).toInt32() );
+ aDateTime.Seconds = static_cast< sal_uInt16 >( aValue.copy( 17, 2 ).toInt32() );
+ }
+ return OptValue< DateTime >( bValid, aDateTime );
+}
+
+// defaulted return values ----------------------------------------------------
+
+sal_Int32 AttributeList::getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
+{
+ return mxAttribs->getOptionalValueToken( nAttrToken, nDefault );
+}
+
+OUString AttributeList::getString( sal_Int32 nAttrToken, const OUString& rDefault ) const
+{
+ try
+ {
+ return mxAttribs->getValue( nAttrToken );
+ }
+ catch( Exception& )
+ {
+ }
+ return rDefault;
+}
+
+OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const
+{
+ return getXString( nAttrToken ).get( rDefault );
+}
+
+double AttributeList::getDouble( sal_Int32 nAttrToken, double fDefault ) const
+{
+ return getDouble( nAttrToken ).get( fDefault );
+}
+
+sal_Int32 AttributeList::getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
+{
+ return getInteger( nAttrToken ).get( nDefault );
+}
+
+sal_uInt32 AttributeList::getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const
+{
+ return getUnsigned( nAttrToken ).get( nDefault );
+}
+
+sal_Int64 AttributeList::getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const
+{
+ return getHyper( nAttrToken ).get( nDefault );
+}
+
+sal_Int32 AttributeList::getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
+{
+ return getIntegerHex( nAttrToken ).get( nDefault );
+}
+
+sal_uInt32 AttributeList::getUnsignedHex( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const
+{
+ return getUnsignedHex( nAttrToken ).get( nDefault );
+}
+
+sal_Int64 AttributeList::getHyperHex( sal_Int32 nAttrToken, sal_Int64 nDefault ) const
+{
+ return getHyperHex( nAttrToken ).get( nDefault );
+}
+
+bool AttributeList::getBool( sal_Int32 nAttrToken, bool bDefault ) const
+{
+ return getBool( nAttrToken ).get( bDefault );
+}
+
+DateTime AttributeList::getDateTime( sal_Int32 nAttrToken, const DateTime& rDefault ) const
+{
+ return getDateTime( nAttrToken ).get( rDefault );
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx
new file mode 100644
index 000000000000..2d547cdbf724
--- /dev/null
+++ b/oox/source/helper/binaryinputstream.cxx
@@ -0,0 +1,337 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/binaryinputstream.hxx"
+
+#include <string.h>
+#include <vector>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/binaryoutputstream.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace {
+
+const sal_Int32 INPUTSTREAM_BUFFERSIZE = 0x8000;
+
+} // namespace
+
+// ============================================================================
+
+OString BinaryInputStream::readNulCharArray()
+{
+ OStringBuffer aBuffer;
+ for( sal_uInt8 nChar = readuInt8(); !mbEof && (nChar > 0); readValue( nChar ) )
+ aBuffer.append( static_cast< sal_Char >( nChar ) );
+ return aBuffer.makeStringAndClear();
+}
+
+OUString BinaryInputStream::readNulCharArrayUC( rtl_TextEncoding eTextEnc )
+{
+ return OStringToOUString( readNulCharArray(), eTextEnc );
+}
+
+OUString BinaryInputStream::readNulUnicodeArray()
+{
+ OUStringBuffer aBuffer;
+ for( sal_uInt16 nChar = readuInt16(); !mbEof && (nChar > 0); readValue( nChar ) )
+ aBuffer.append( static_cast< sal_Unicode >( nChar ) );
+ return aBuffer.makeStringAndClear();
+}
+
+OString BinaryInputStream::readCharArray( sal_Int32 nChars, bool bAllowNulChars )
+{
+ if( nChars <= 0 )
+ return OString();
+
+ ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nChars ) );
+ size_t nCharsRead = static_cast< size_t >( readMemory( &aBuffer.front(), nChars ) );
+ if( !bAllowNulChars )
+ ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' );
+ return OString( &aBuffer.front(), nCharsRead );
+}
+
+OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars )
+{
+ return OStringToOUString( readCharArray( nChars, bAllowNulChars ), eTextEnc );
+}
+
+OUString BinaryInputStream::readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars )
+{
+ OUStringBuffer aBuffer;
+ if( nChars > 0 )
+ {
+ aBuffer.ensureCapacity( nChars );
+ sal_uInt16 nChar;
+ for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx )
+ {
+ readValue( nChar );
+ aBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) );
+ }
+ }
+ return aBuffer.makeStringAndClear();
+}
+
+void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes )
+{
+ if( nBytes > 0 )
+ {
+ sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, INPUTSTREAM_BUFFERSIZE );
+ StreamDataSequence aBuffer( nBufferSize );
+ while( nBytes > 0 )
+ {
+ sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, nBufferSize );
+ sal_Int32 nBytesRead = readData( aBuffer, nReadSize );
+ rOutStrm.writeData( aBuffer );
+ if( nReadSize == nBytesRead )
+ nBytes -= nReadSize;
+ else
+ nBytes = 0;
+ }
+ }
+}
+
+void BinaryInputStream::readAtom( void* opMem, sal_uInt8 nSize )
+{
+ readMemory( opMem, nSize );
+}
+
+// ============================================================================
+
+BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStrm, bool bAutoClose ) :
+ BinaryXSeekableStream( Reference< XSeekable >( rxInStrm, UNO_QUERY ) ),
+ maBuffer( INPUTSTREAM_BUFFERSIZE ),
+ mxInStrm( rxInStrm ),
+ mbAutoClose( bAutoClose )
+{
+ mbEof = !mxInStrm.is();
+}
+
+BinaryXInputStream::~BinaryXInputStream()
+{
+ if( mbAutoClose )
+ close();
+}
+
+sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = 0;
+ if( !mbEof && (nBytes > 0) ) try
+ {
+ OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::readData - invalid call" );
+ nRet = mxInStrm->readBytes( orData, nBytes );
+ mbEof = nRet != nBytes;
+ }
+ catch( Exception& )
+ {
+ mbEof = true;
+ }
+ return nRet;
+}
+
+sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = 0;
+ if( !mbEof && (nBytes > 0) )
+ {
+ sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, INPUTSTREAM_BUFFERSIZE );
+ sal_uInt8* opnMem = reinterpret_cast< sal_uInt8* >( opMem );
+ while( !mbEof && (nBytes > 0) )
+ {
+ sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize );
+ sal_Int32 nBytesRead = readData( maBuffer, nReadSize );
+ if( nBytesRead > 0 )
+ memcpy( opnMem, maBuffer.getConstArray(), static_cast< size_t >( nBytesRead ) );
+ opnMem += nBytesRead;
+ nBytes -= nBytesRead;
+ nRet += nBytesRead;
+ }
+ }
+ return nRet;
+}
+
+void BinaryXInputStream::skip( sal_Int32 nBytes )
+{
+ if( !mbEof ) try
+ {
+ OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::skip - invalid call" );
+ mxInStrm->skipBytes( nBytes );
+ }
+ catch( Exception& )
+ {
+ mbEof = true;
+ }
+}
+
+void BinaryXInputStream::close()
+{
+ if( mxInStrm.is() ) try
+ {
+ mxInStrm->closeInput();
+ mxInStrm.clear();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" );
+ }
+}
+
+// ============================================================================
+
+SequenceInputStream::SequenceInputStream( const StreamDataSequence& rData ) :
+ SequenceSeekableStream( rData )
+{
+}
+
+sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
+{
+ sal_Int32 nReadBytes = 0;
+ if( !mbEof )
+ {
+ nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos );
+ orData.realloc( nReadBytes );
+ if( nReadBytes > 0 )
+ memcpy( orData.getArray(), mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) );
+ mnPos += nReadBytes;
+ mbEof = nReadBytes < nBytes;
+ }
+ return nReadBytes;
+}
+
+sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes )
+{
+ sal_Int32 nReadBytes = 0;
+ if( !mbEof )
+ {
+ nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos );
+ if( nReadBytes > 0 )
+ memcpy( opMem, mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) );
+ mnPos += nReadBytes;
+ mbEof = nReadBytes < nBytes;
+ }
+ return nReadBytes;
+}
+
+void SequenceInputStream::skip( sal_Int32 nBytes )
+{
+ if( !mbEof )
+ {
+ sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos );
+ mnPos += nSkipBytes;
+ mbEof = nSkipBytes < nBytes;
+ }
+}
+
+// ============================================================================
+
+RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nLength ) :
+ mrInStrm( rInStrm ),
+ mnStartPos( rInStrm.tell() ),
+ mnRelPos( 0 )
+{
+ sal_Int64 nRemaining = rInStrm.getRemaining();
+ mnLength = (nRemaining >= 0) ? ::std::min( nLength, nRemaining ) : nLength;
+ mbEof = mnLength < 0;
+}
+
+bool RelativeInputStream::isSeekable() const
+{
+ return mrInStrm.isSeekable();
+}
+
+sal_Int64 RelativeInputStream::getLength() const
+{
+ return mnLength;
+}
+
+sal_Int64 RelativeInputStream::tell() const
+{
+ return mnRelPos;
+}
+
+void RelativeInputStream::seek( sal_Int64 nPos )
+{
+ if( mrInStrm.isSeekable() && (mnStartPos >= 0) )
+ {
+ mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnLength );
+ mrInStrm.seek( mnStartPos + mnRelPos );
+ mbEof = (mnRelPos != nPos) || mrInStrm.isEof();
+ }
+}
+
+sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
+{
+ sal_Int32 nReadBytes = 0;
+ if( !mbEof )
+ {
+ sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos );
+ nReadBytes = mrInStrm.readData( orData, nRealBytes );
+ mnRelPos += nReadBytes;
+ mbEof = (nRealBytes < nBytes) || mrInStrm.isEof();
+ }
+ return nReadBytes;
+}
+
+sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes )
+{
+ sal_Int32 nReadBytes = 0;
+ if( !mbEof )
+ {
+ sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos );
+ nReadBytes = mrInStrm.readMemory( opMem, nRealBytes );
+ mnRelPos += nReadBytes;
+ mbEof = (nRealBytes < nBytes) || mrInStrm.isEof();
+ }
+ return nReadBytes;
+}
+
+void RelativeInputStream::skip( sal_Int32 nBytes )
+{
+ if( !mbEof )
+ {
+ sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos );
+ mrInStrm.skip( nSkipBytes );
+ mnRelPos += nSkipBytes;
+ mbEof = nSkipBytes < nBytes;
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx
new file mode 100644
index 000000000000..f4ea9378aa90
--- /dev/null
+++ b/oox/source/helper/binaryoutputstream.cxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/binaryoutputstream.hxx"
+
+#include <osl/diagnose.h>
+#include <string.h>
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+namespace {
+
+const sal_Int32 OUTPUTSTREAM_BUFFERSIZE = 0x8000;
+
+} // namespace
+
+// ============================================================================
+
+void BinaryOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize )
+{
+ writeMemory( pMem, nSize );
+}
+
+// ============================================================================
+
+BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOutStrm, bool bAutoClose ) :
+ BinaryXSeekableStream( Reference< XSeekable >( rxOutStrm, UNO_QUERY ) ),
+ maBuffer( OUTPUTSTREAM_BUFFERSIZE ),
+ mxOutStrm( rxOutStrm ),
+ mbAutoClose( bAutoClose )
+{
+ mbEof = !mxOutStrm.is();
+}
+
+BinaryXOutputStream::~BinaryXOutputStream()
+{
+ if( mbAutoClose )
+ close();
+}
+
+void BinaryXOutputStream::writeData( const StreamDataSequence& rData )
+{
+ try
+ {
+ OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::writeData - invalid call" );
+ mxOutStrm->writeBytes( rData );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryXOutputStream::writeData - stream read error" );
+ }
+}
+
+void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
+{
+ if( nBytes > 0 )
+ {
+ sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, OUTPUTSTREAM_BUFFERSIZE );
+ const sal_uInt8* pnMem = reinterpret_cast< const sal_uInt8* >( pMem );
+ while( nBytes > 0 )
+ {
+ sal_Int32 nWriteSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize );
+ maBuffer.realloc( nWriteSize );
+ memcpy( maBuffer.getArray(), pnMem, static_cast< size_t >( nWriteSize ) );
+ writeData( maBuffer );
+ pnMem += nWriteSize;
+ nBytes -= nWriteSize;
+ }
+ }
+}
+
+void BinaryXOutputStream::close()
+{
+ if( mxOutStrm.is() ) try
+ {
+ mxOutStrm->flush();
+ mxOutStrm->closeOutput();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" );
+ }
+}
+
+// ============================================================================
+
+SequenceOutputStream::SequenceOutputStream( StreamDataSequence& rData ) :
+ SequenceSeekableStream( rData )
+{
+}
+
+void SequenceOutputStream::writeData( const StreamDataSequence& rData )
+{
+ if( rData.hasElements() )
+ writeMemory( rData.getConstArray(), rData.getLength() );
+}
+
+void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
+{
+ if( nBytes > 0 )
+ {
+ if( mrData.getLength() - mnPos < nBytes )
+ const_cast< StreamDataSequence& >( mrData ).realloc( mnPos + nBytes );
+ memcpy( const_cast< StreamDataSequence& >( mrData ).getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) );
+ mnPos += nBytes;
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
+
diff --git a/oox/source/helper/binarystreambase.cxx b/oox/source/helper/binarystreambase.cxx
new file mode 100644
index 000000000000..d1e11850a68c
--- /dev/null
+++ b/oox/source/helper/binarystreambase.cxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/binarystreambase.hxx"
+
+#include <osl/diagnose.h>
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+// ============================================================================
+
+BinaryStreamBase::~BinaryStreamBase()
+{
+}
+
+bool BinaryStreamBase::isSeekable() const
+{
+ return false;
+}
+
+sal_Int64 BinaryStreamBase::getLength() const
+{
+ return -1;
+}
+
+sal_Int64 BinaryStreamBase::tell() const
+{
+ return -1;
+}
+
+void BinaryStreamBase::seek( sal_Int64 )
+{
+}
+
+sal_Int64 BinaryStreamBase::getRemaining() const
+{
+ // do not use isSeekable(), implementations may provide stream position and size even if not seekable
+ sal_Int64 nPos = tell();
+ sal_Int64 nLen = getLength();
+ return ((nPos >= 0) && (nLen >= 0)) ? ::std::max< sal_Int64 >( nLen - nPos, 0 ) : -1;
+}
+
+void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos )
+{
+ sal_Int64 nStrmPos = tell();
+ // nothing to do, if stream is at anchor position
+ if( isSeekable() && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) )
+ {
+ // prevent modulo with negative arguments...
+ sal_Int64 nSkipSize = (nAnchorPos < nStrmPos) ?
+ (nBlockSize - ((nStrmPos - nAnchorPos - 1) % nBlockSize) - 1) :
+ ((nAnchorPos - nStrmPos) % nBlockSize);
+ seek( nStrmPos + nSkipSize );
+ }
+}
+
+// ============================================================================
+
+BinaryXSeekableStream::BinaryXSeekableStream( const Reference< XSeekable >& rxSeekable ) :
+ mxSeekable( rxSeekable )
+{
+}
+
+bool BinaryXSeekableStream::isSeekable() const
+{
+ return mxSeekable.is();
+}
+
+sal_Int64 BinaryXSeekableStream::getLength() const
+{
+ if( mxSeekable.is() ) try
+ {
+ return mxSeekable->getLength();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryXSeekableStream::getLength - exception caught" );
+ }
+ return -1;
+}
+
+sal_Int64 BinaryXSeekableStream::tell() const
+{
+ if( mxSeekable.is() ) try
+ {
+ return mxSeekable->getPosition();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "BinaryXSeekableStream::tell - exception caught" );
+ }
+ return -1;
+}
+
+void BinaryXSeekableStream::seek( sal_Int64 nPos )
+{
+ if( mxSeekable.is() ) try
+ {
+ mbEof = false;
+ mxSeekable->seek( nPos );
+ }
+ catch( Exception& )
+ {
+ mbEof = true;
+ }
+}
+
+// ============================================================================
+
+bool SequenceSeekableStream::isSeekable() const
+{
+ return true;
+}
+
+sal_Int64 SequenceSeekableStream::getLength() const
+{
+ return mrData.getLength();
+}
+
+sal_Int64 SequenceSeekableStream::tell() const
+{
+ return mnPos;
+}
+
+void SequenceSeekableStream::seek( sal_Int64 nPos )
+{
+ mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mrData.getLength() );
+ mbEof = mnPos != nPos;
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx
new file mode 100644
index 000000000000..e7f322ff10e3
--- /dev/null
+++ b/oox/source/helper/containerhelper.cxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/containerhelper.hxx"
+
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XMultiServiceFactory >& rxFactory )
+{
+ Reference< XIndexContainer > xContainer;
+ if( rxFactory.is() ) try
+ {
+ xContainer.set( rxFactory->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( const Reference< XMultiServiceFactory >& rxFactory )
+{
+ Reference< XNameContainer > xContainer;
+ if( rxFactory.is() ) try
+ {
+ xContainer.set( rxFactory->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, bool bReplaceOldExisting )
+{
+ OSL_ENSURE( rxNameContainer.is(), "ContainerHelper::insertByName - missing XNameContainer interface" );
+ bool bRet = false;
+ try
+ {
+ if( bReplaceOldExisting && rxNameContainer->hasByName( rName ) )
+ rxNameContainer->replaceByName( rName, rObject );
+ else
+ 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 OUString& rSuggestedName, sal_Unicode cSeparator,
+ const Any& rObject, 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/graphichelper.cxx b/oox/source/helper/graphichelper.cxx
new file mode 100755
index 000000000000..2e5a612699e2
--- /dev/null
+++ b/oox/source/helper/graphichelper.cxx
@@ -0,0 +1,366 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/graphichelper.hxx"
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XUnitConversion.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/graphic/GraphicObject.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/util/MeasureUnit.hpp>
+#include <comphelper/seqstream.hxx>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/token/tokens.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+inline sal_Int32 lclConvertScreenPixelToHmm( double fPixel, double fPixelPerHmm )
+{
+ return static_cast< sal_Int32 >( (fPixelPerHmm > 0.0) ? (fPixel / fPixelPerHmm + 0.5) : 0.0 );
+}
+
+} // namespace
+
+// ============================================================================
+
+GraphicHelper::GraphicHelper( const Reference< XComponentContext >& rxContext, const Reference< XFrame >& rxTargetFrame, const StorageRef& rxStorage ) :
+ mxCompContext( rxContext ),
+ mxStorage( rxStorage ),
+ maGraphicObjScheme( CREATE_OUSTRING( "vnd.sun.star.GraphicObject:" ) )
+{
+ OSL_ENSURE( mxCompContext.is(), "GraphicHelper::GraphicHelper - missing component context" );
+ Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW );
+ OSL_ENSURE( xFactory.is(), "GraphicHelper::GraphicHelper - missing service factory" );
+
+ if( xFactory.is() )
+ mxGraphicProvider.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY );
+
+ //! TODO: get colors from system
+ maSystemPalette[ XML_3dDkShadow ] = 0x716F64;
+ maSystemPalette[ XML_3dLight ] = 0xF1EFE2;
+ maSystemPalette[ XML_activeBorder ] = 0xD4D0C8;
+ maSystemPalette[ XML_activeCaption ] = 0x0054E3;
+ maSystemPalette[ XML_appWorkspace ] = 0x808080;
+ maSystemPalette[ XML_background ] = 0x004E98;
+ maSystemPalette[ XML_btnFace ] = 0xECE9D8;
+ maSystemPalette[ XML_btnHighlight ] = 0xFFFFFF;
+ maSystemPalette[ XML_btnShadow ] = 0xACA899;
+ maSystemPalette[ XML_btnText ] = 0x000000;
+ maSystemPalette[ XML_captionText ] = 0xFFFFFF;
+ maSystemPalette[ XML_gradientActiveCaption ] = 0x3D95FF;
+ maSystemPalette[ XML_gradientInactiveCaption ] = 0xD8E4F8;
+ maSystemPalette[ XML_grayText ] = 0xACA899;
+ maSystemPalette[ XML_highlight ] = 0x316AC5;
+ maSystemPalette[ XML_highlightText ] = 0xFFFFFF;
+ maSystemPalette[ XML_hotLight ] = 0x000080;
+ maSystemPalette[ XML_inactiveBorder ] = 0xD4D0C8;
+ maSystemPalette[ XML_inactiveCaption ] = 0x7A96DF;
+ maSystemPalette[ XML_inactiveCaptionText ] = 0xD8E4F8;
+ maSystemPalette[ XML_infoBk ] = 0xFFFFE1;
+ maSystemPalette[ XML_infoText ] = 0x000000;
+ maSystemPalette[ XML_menu ] = 0xFFFFFF;
+ maSystemPalette[ XML_menuBar ] = 0xECE9D8;
+ maSystemPalette[ XML_menuHighlight ] = 0x316AC5;
+ maSystemPalette[ XML_menuText ] = 0x000000;
+ maSystemPalette[ XML_scrollBar ] = 0xD4D0C8;
+ maSystemPalette[ XML_window ] = 0xFFFFFF;
+ maSystemPalette[ XML_windowFrame ] = 0x000000;
+ maSystemPalette[ XML_windowText ] = 0x000000;
+
+ // if no target frame has been passed (e.g. OLE objects), try to fallback to the active frame
+ // TODO: we need some mechanism to keep and pass the parent frame
+ Reference< XFrame > xFrame = rxTargetFrame;
+ if( !xFrame.is() && xFactory.is() ) try
+ {
+ Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW );
+ xFrame = xFramesSupp->getActiveFrame();
+ }
+ catch( Exception& )
+ {
+ }
+
+ // get the metric of the output device
+ OSL_ENSURE( xFrame.is(), "GraphicHelper::GraphicHelper - cannot get target frame" );
+ maDeviceInfo.PixelPerMeterX = maDeviceInfo.PixelPerMeterY = 3500.0; // some default just in case
+ if( xFrame.is() ) try
+ {
+ Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
+ mxUnitConversion.set( xDevice, UNO_QUERY );
+ OSL_ENSURE( mxUnitConversion.is(), "GraphicHelper::GraphicHelper - cannot get unit converter" );
+ maDeviceInfo = xDevice->getInfo();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "GraphicHelper::GraphicHelper - cannot get output device info" );
+ }
+ mfPixelPerHmmX = maDeviceInfo.PixelPerMeterX / 100000.0;
+ mfPixelPerHmmY = maDeviceInfo.PixelPerMeterY / 100000.0;
+}
+
+GraphicHelper::~GraphicHelper()
+{
+}
+
+// System colors and predefined colors ----------------------------------------
+
+sal_Int32 GraphicHelper::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) const
+{
+ return ContainerHelper::getMapElement( maSystemPalette, nToken, nDefaultRgb );
+}
+
+sal_Int32 GraphicHelper::getSchemeColor( sal_Int32 /*nToken*/ ) const
+{
+ OSL_ENSURE( false, "GraphicHelper::getSchemeColor - scheme colors not implemented" );
+ return API_RGB_TRANSPARENT;
+}
+
+sal_Int32 GraphicHelper::getPaletteColor( sal_Int32 /*nPaletteIdx*/ ) const
+{
+ OSL_ENSURE( false, "GraphicHelper::getPaletteColor - palette colors not implemented" );
+ return API_RGB_TRANSPARENT;
+}
+
+// Device info and device dependent unit conversion ---------------------------
+
+const DeviceInfo& GraphicHelper::getDeviceInfo() const
+{
+ return maDeviceInfo;
+}
+
+sal_Int32 GraphicHelper::convertScreenPixelXToHmm( double fPixelX ) const
+{
+ return lclConvertScreenPixelToHmm( fPixelX, mfPixelPerHmmX );
+}
+
+sal_Int32 GraphicHelper::convertScreenPixelYToHmm( double fPixelY ) const
+{
+ return lclConvertScreenPixelToHmm( fPixelY, mfPixelPerHmmY );
+}
+
+Point GraphicHelper::convertScreenPixelToHmm( const Point& rPixel ) const
+{
+ return Point( convertScreenPixelXToHmm( rPixel.X ), convertScreenPixelYToHmm( rPixel.Y ) );
+}
+
+Size GraphicHelper::convertScreenPixelToHmm( const Size& rPixel ) const
+{
+ return Size( convertScreenPixelXToHmm( rPixel.Width ), convertScreenPixelYToHmm( rPixel.Height ) );
+}
+
+double GraphicHelper::convertHmmToScreenPixelX( sal_Int32 nHmmX ) const
+{
+ return nHmmX * mfPixelPerHmmX;
+}
+
+double GraphicHelper::convertHmmToScreenPixelY( sal_Int32 nHmmY ) const
+{
+ return nHmmY * mfPixelPerHmmY;
+}
+
+Point GraphicHelper::convertHmmToScreenPixel( const Point& rHmm ) const
+{
+ return Point(
+ static_cast< sal_Int32 >( convertHmmToScreenPixelX( rHmm.X ) + 0.5 ),
+ static_cast< sal_Int32 >( convertHmmToScreenPixelY( rHmm.Y ) + 0.5 ) );
+}
+
+Size GraphicHelper::convertHmmToScreenPixel( const Size& rHmm ) const
+{
+ return Size(
+ static_cast< sal_Int32 >( convertHmmToScreenPixelX( rHmm.Width ) + 0.5 ),
+ static_cast< sal_Int32 >( convertHmmToScreenPixelY( rHmm.Height ) + 0.5 ) );
+}
+
+Point GraphicHelper::convertAppFontToHmm( const Point& rAppFont ) const
+{
+ if( mxUnitConversion.is() ) try
+ {
+ Point aPixel = mxUnitConversion->convertPointToPixel( rAppFont, ::com::sun::star::util::MeasureUnit::APPFONT );
+ return convertScreenPixelToHmm( aPixel );
+ }
+ catch( Exception& )
+ {
+ }
+ return Point( 0, 0 );
+}
+
+Size GraphicHelper::convertAppFontToHmm( const Size& rAppFont ) const
+{
+ if( mxUnitConversion.is() ) try
+ {
+ Size aPixel = mxUnitConversion->convertSizeToPixel( rAppFont, ::com::sun::star::util::MeasureUnit::APPFONT );
+ return convertScreenPixelToHmm( aPixel );
+ }
+ catch( Exception& )
+ {
+ }
+ return Size( 0, 0 );
+}
+
+Point GraphicHelper::convertHmmToAppFont( const Point& rHmm ) const
+{
+ if( mxUnitConversion.is() ) try
+ {
+ Point aPixel = convertHmmToScreenPixel( rHmm );
+ return mxUnitConversion->convertPointToLogic( aPixel, ::com::sun::star::util::MeasureUnit::APPFONT );
+ }
+ catch( Exception& )
+ {
+ }
+ return Point( 0, 0 );
+}
+
+Size GraphicHelper::convertHmmToAppFont( const Size& rHmm ) const
+{
+ if( mxUnitConversion.is() ) try
+ {
+ Size aPixel = convertHmmToScreenPixel( rHmm );
+ return mxUnitConversion->convertSizeToLogic( aPixel, ::com::sun::star::util::MeasureUnit::APPFONT );
+ }
+ catch( Exception& )
+ {
+ }
+ return Size( 0, 0 );
+}
+
+// Graphics and graphic objects ----------------------------------------------
+
+Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm ) const
+{
+ Reference< XGraphic > xGraphic;
+ if( rxInStrm.is() && mxGraphicProvider.is() ) try
+ {
+ Sequence< PropertyValue > aArgs( 1 );
+ aArgs[ 0 ].Name = CREATE_OUSTRING( "InputStream" );
+ aArgs[ 0 ].Value <<= rxInStrm;
+ xGraphic = mxGraphicProvider->queryGraphic( aArgs );
+ }
+ catch( Exception& )
+ {
+ }
+ return xGraphic;
+}
+
+Reference< XGraphic > GraphicHelper::importGraphic( const StreamDataSequence& rGraphicData ) const
+{
+ Reference< XGraphic > xGraphic;
+ if( rGraphicData.hasElements() )
+ {
+ Reference< XInputStream > xInStrm( new ::comphelper::SequenceInputStream( rGraphicData ) );
+ xGraphic = importGraphic( xInStrm );
+ }
+ return xGraphic;
+}
+
+Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName ) const
+{
+ Reference< XGraphic > xGraphic;
+ OSL_ENSURE( rStreamName.getLength() > 0, "GraphicHelper::importEmbeddedGraphic - empty stream name" );
+ if( rStreamName.getLength() > 0 )
+ {
+ EmbeddedGraphicMap::const_iterator aIt = maEmbeddedGraphics.find( rStreamName );
+ if( aIt == maEmbeddedGraphics.end() )
+ {
+ xGraphic = importGraphic( mxStorage->openInputStream( rStreamName ) );
+ if( xGraphic.is() )
+ maEmbeddedGraphics[ rStreamName ] = xGraphic;
+ }
+ else
+ xGraphic = aIt->second;
+ }
+ return xGraphic;
+}
+
+OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) const
+{
+ OUString aGraphicObjUrl;
+ if( mxCompContext.is() && rxGraphic.is() ) try
+ {
+ Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxCompContext ), UNO_SET_THROW );
+ xGraphicObj->setGraphic( rxGraphic );
+ maGraphicObjects.push_back( xGraphicObj );
+ aGraphicObjUrl = maGraphicObjScheme + xGraphicObj->getUniqueID();
+ }
+ catch( Exception& )
+ {
+ }
+ return aGraphicObjUrl;
+}
+
+OUString GraphicHelper::importGraphicObject( const Reference< XInputStream >& rxInStrm ) const
+{
+ return createGraphicObject( importGraphic( rxInStrm ) );
+}
+
+OUString GraphicHelper::importGraphicObject( const StreamDataSequence& rGraphicData ) const
+{
+ return createGraphicObject( importGraphic( rGraphicData ) );
+}
+
+OUString GraphicHelper::importEmbeddedGraphicObject( const OUString& rStreamName ) const
+{
+ Reference< XGraphic > xGraphic = importEmbeddedGraphic( rStreamName );
+ return xGraphic.is() ? createGraphicObject( xGraphic ) : OUString();
+}
+
+Size GraphicHelper::getOriginalSize( const Reference< XGraphic >& xGraphic ) const
+{
+ Size aSizeHmm;
+ PropertySet aPropSet( xGraphic );
+ if( aPropSet.getProperty( aSizeHmm, PROP_Size100thMM ) && (aSizeHmm.Width == 0) && (aSizeHmm.Height == 0) ) // MAPMODE_PIXEL used?
+ {
+ Size aSizePixel( 0, 0 );
+ if( aPropSet.getProperty( aSizePixel, PROP_SizePixel ) )
+ aSizeHmm = convertScreenPixelToHmm( aSizePixel );
+ }
+ return aSizeHmm;
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/makefile.mk b/oox/source/helper/makefile.mk
new file mode 100644
index 000000000000..f31736faac8d
--- /dev/null
+++ b/oox/source/helper/makefile.mk
@@ -0,0 +1,60 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+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)$/graphichelper.obj \
+ $(SLO)$/modelobjecthelper.obj \
+ $(SLO)$/progressbar.obj \
+ $(SLO)$/propertymap.obj \
+ $(SLO)$/propertyset.obj \
+ $(SLO)$/storagebase.obj \
+ $(SLO)$/textinputstream.obj \
+ $(SLO)$/zipstorage.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx
new file mode 100644
index 000000000000..7fdbe4b38134
--- /dev/null
+++ b/oox/source/helper/modelobjecthelper.cxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/modelobjecthelper.hxx"
+
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rServiceName ) :
+ mxFactory( rxFactory ),
+ maServiceName( rServiceName ),
+ mnIndex( 0 )
+{
+ OSL_ENSURE( mxFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" );
+}
+
+ObjectContainer::~ObjectContainer()
+{
+}
+
+bool ObjectContainer::hasObject( const OUString& rObjName ) const
+{
+ createContainer();
+ return mxContainer.is() && mxContainer->hasByName( rObjName );
+}
+
+Any ObjectContainer::getObject( const OUString& rObjName ) const
+{
+ createContainer();
+ if( mxContainer.is() ) try
+ {
+ return mxContainer->getByName( rObjName );
+ }
+ catch( Exception& )
+ {
+ }
+ return Any();
+}
+
+OUString ObjectContainer::insertObject( const OUString& rObjName, const Any& rObj, bool bInsertByUnusedName )
+{
+ createContainer();
+ if( mxContainer.is() )
+ {
+ if( bInsertByUnusedName )
+ return ContainerHelper::insertByUnusedName( mxContainer, rObjName + OUString::valueOf( ++mnIndex ), ' ', rObj );
+ if( ContainerHelper::insertByName( mxContainer, rObjName, rObj ) )
+ return rObjName;
+ }
+ return OUString();
+}
+
+void ObjectContainer::createContainer() const
+{
+ if( !mxContainer.is() && mxFactory.is() ) try
+ {
+ mxContainer.set( mxFactory->createInstance( maServiceName ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( mxContainer.is(), "ObjectContainer::createContainer - container not found" );
+}
+
+// ============================================================================
+
+ModelObjectHelper::ModelObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) :
+ maMarkerContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.MarkerTable" ) ),
+ maDashContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.DashTable" ) ),
+ maGradientContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.GradientTable" ) ),
+ maBitmapContainer( rxModelFactory, CREATE_OUSTRING( "com.sun.star.drawing.BitmapTable" ) ),
+ maDashNameBase( CREATE_OUSTRING( "msLineDash " ) ),
+ maGradientNameBase( CREATE_OUSTRING( "msFillGradient " ) ),
+ maBitmapNameBase( CREATE_OUSTRING( "msFillBitmap " ) )
+{
+}
+
+bool ModelObjectHelper::hasLineMarker( const OUString& rMarkerName ) const
+{
+ return maMarkerContainer.hasObject( rMarkerName );
+}
+
+bool ModelObjectHelper::insertLineMarker( const OUString& rMarkerName, const PolyPolygonBezierCoords& rMarker )
+{
+ OSL_ENSURE( rMarker.Coordinates.hasElements(), "ModelObjectHelper::insertLineMarker - line marker without coordinates" );
+ if( rMarker.Coordinates.hasElements() )
+ return maMarkerContainer.insertObject( rMarkerName, Any( rMarker ), false ).getLength() > 0;
+ return false;
+}
+
+OUString ModelObjectHelper::insertLineDash( const LineDash& rDash )
+{
+ return maDashContainer.insertObject( maDashNameBase, Any( rDash ), true );
+}
+
+OUString ModelObjectHelper::insertFillGradient( const Gradient& rGradient )
+{
+ return maGradientContainer.insertObject( maGradientNameBase, Any( rGradient ), true );
+}
+
+OUString ModelObjectHelper::insertFillBitmap( const OUString& rGraphicUrl )
+{
+ if( rGraphicUrl.getLength() > 0 )
+ return maBitmapContainer.insertObject( maBitmapNameBase, Any( rGraphicUrl ), true );
+ return OUString();
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/progressbar.cxx b/oox/source/helper/progressbar.cxx
new file mode 100644
index 000000000000..1ef6531d3fb0
--- /dev/null
+++ b/oox/source/helper/progressbar.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/progressbar.hxx"
+
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+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..0c4e2cb07549
--- /dev/null
+++ b/oox/source/helper/propertymap.cxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/propertymap.hxx"
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <osl/mutex.hxx>
+#include "oox/token/propertynames.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OString;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+typedef ::cppu::WeakImplHelper2< XPropertySet, XPropertySetInfo > GenericPropertySetBase;
+
+/** 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 GenericPropertySetBase, private ::osl::Mutex
+{
+public:
+ explicit GenericPropertySet();
+ explicit GenericPropertySet( const PropertyMap& rPropMap );
+
+ // 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);
+
+private:
+ typedef ::std::map< OUString, Any > PropertyNameMap;
+ PropertyNameMap maPropMap;
+};
+
+// ----------------------------------------------------------------------------
+
+GenericPropertySet::GenericPropertySet()
+{
+}
+
+GenericPropertySet::GenericPropertySet( const PropertyMap& rPropMap )
+{
+ const PropertyNameVector& rPropNames = StaticPropertyNameVector::get();
+ for( PropertyMap::const_iterator aIt = rPropMap.begin(), aEnd = rPropMap.end(); aIt != aEnd; ++aIt )
+ maPropMap[ rPropNames[ aIt->first ] ] = aIt->second;
+}
+
+Reference< XPropertySetInfo > SAL_CALL GenericPropertySet::getPropertySetInfo() throw (RuntimeException)
+{
+ return this;
+}
+
+void SAL_CALL GenericPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *this );
+ maPropMap[ rPropertyName ] = rValue;
+}
+
+Any SAL_CALL GenericPropertySet::getPropertyValue( const OUString& rPropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
+{
+ PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName );
+ if( aIt == maPropMap.end() )
+ throw UnknownPropertyException();
+ return aIt->second;
+}
+
+// listeners are not supported by this implementation
+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 > aSeq( static_cast< sal_Int32 >( maPropMap.size() ) );
+ Property* pProperty = aSeq.getArray();
+ for( PropertyNameMap::iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt, ++pProperty )
+ {
+ pProperty->Name = aIt->first;
+ pProperty->Handle = 0;
+ pProperty->Type = aIt->second.getValueType();
+ pProperty->Attributes = 0;
+ }
+ return aSeq;
+}
+
+Property SAL_CALL GenericPropertySet::getPropertyByName( const OUString& rPropertyName ) throw (UnknownPropertyException, RuntimeException)
+{
+ PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName );
+ if( aIt == maPropMap.end() )
+ throw UnknownPropertyException();
+ Property aProperty;
+ aProperty.Name = aIt->first;
+ aProperty.Handle = 0;
+ aProperty.Type = aIt->second.getValueType();
+ aProperty.Attributes = 0;
+ return aProperty;
+}
+
+sal_Bool SAL_CALL GenericPropertySet::hasPropertyByName( const OUString& rPropertyName ) throw (RuntimeException)
+{
+ return maPropMap.find( rPropertyName ) != maPropMap.end();
+}
+
+} // namespace
+
+// ============================================================================
+
+PropertyMap::PropertyMap() :
+ mpPropNames( &StaticPropertyNameVector::get() ) // pointer instead reference to get compiler generated copy c'tor and operator=
+{
+}
+
+PropertyMap::~PropertyMap()
+{
+}
+
+/*static*/ const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId )
+{
+ OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" );
+ return StaticPropertyNameVector::get()[ nPropId ];
+}
+
+const Any* PropertyMap::getProperty( sal_Int32 nPropId ) const
+{
+ const_iterator aIt = find( nPropId );
+ return (aIt == end()) ? 0 : &aIt->second;
+}
+
+Sequence< PropertyValue > PropertyMap::makePropertyValueSequence() const
+{
+ Sequence< PropertyValue > aSeq( static_cast< sal_Int32 >( size() ) );
+ if( !empty() )
+ {
+ PropertyValue* pValues = aSeq.getArray();
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pValues )
+ {
+ OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::makePropertyValueSequence - invalid property identifier" );
+ pValues->Name = (*mpPropNames)[ aIt->first ];
+ pValues->Value = aIt->second;
+ pValues->State = ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ return aSeq;
+}
+
+void PropertyMap::fillSequences( Sequence< OUString >& rNames, Sequence< Any >& rValues ) const
+{
+ rNames.realloc( static_cast< sal_Int32 >( size() ) );
+ rValues.realloc( static_cast< sal_Int32 >( size() ) );
+ if( !empty() )
+ {
+ OUString* pNames = rNames.getArray();
+ Any* pValues = rValues.getArray();
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pNames, ++pValues )
+ {
+ OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::fillSequences - invalid property identifier" );
+ *pNames = (*mpPropNames)[ aIt->first ];
+ *pValues = aIt->second;
+ }
+ }
+}
+
+Reference< XPropertySet > PropertyMap::makePropertySet() const
+{
+ return new GenericPropertySet( *this );
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx
new file mode 100644
index 000000000000..4812fdf35aa5
--- /dev/null
+++ b/oox/source/helper/propertyset.cxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/propertyset.hxx"
+
+#include <osl/diagnose.h>
+#include <rtl/strbuf.hxx>
+#include "oox/helper/propertymap.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringToOString;
+
+// ============================================================================
+
+void PropertySet::set( const Reference< XPropertySet >& rxPropSet )
+{
+ mxPropSet = rxPropSet;
+ mxMultiPropSet.set( mxPropSet, UNO_QUERY );
+}
+
+// Get properties -------------------------------------------------------------
+
+bool PropertySet::getAnyProperty( Any& orValue, sal_Int32 nPropId ) const
+{
+ return getAnyProperty( orValue, PropertyMap::getPropertyName( nPropId ) );
+}
+
+Any PropertySet::getAnyProperty( sal_Int32 nPropId ) const
+{
+ Any aValue;
+ return getAnyProperty( aValue, nPropId ) ? aValue : Any();
+}
+
+bool PropertySet::getBoolProperty( sal_Int32 nPropId ) const
+{
+ Any aAny;
+ bool bValue = false;
+ return getAnyProperty( aAny, nPropId ) && (aAny >>= bValue) && bValue;
+}
+
+void PropertySet::getProperties( Sequence< Any >& orValues, const Sequence< OUString >& rPropNames ) const
+{
+ if( mxMultiPropSet.is() ) try
+ {
+ orValues = mxMultiPropSet->getPropertyValues( rPropNames );
+ return;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "PropertySet::getProperties - cannot get all property values - fallback to single mode" );
+ }
+
+ 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 )
+ getAnyProperty( *pValue, *pPropName );
+ }
+}
+
+// Set properties -------------------------------------------------------------
+
+void PropertySet::setAnyProperty( sal_Int32 nPropId, const Any& rValue )
+{
+ setAnyProperty( PropertyMap::getPropertyName( nPropId ), rValue );
+}
+
+void PropertySet::setProperties( const Sequence< OUString >& rPropNames, const Sequence< Any >& rValues )
+{
+ OSL_ENSURE( rPropNames.getLength() == rValues.getLength(),
+ "PropertySet::setProperties - length of sequences different" );
+
+ if( mxMultiPropSet.is() ) try
+ {
+ mxMultiPropSet->setPropertyValues( rPropNames, rValues );
+ return;
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "PropertySet::setProperties - cannot set all property values, fallback to single mode" );
+ }
+
+ if( mxPropSet.is() )
+ {
+ const OUString* pPropName = rPropNames.getConstArray();
+ const OUString* pPropNameEnd = pPropName + rPropNames.getLength();
+ const Any* pValue = rValues.getConstArray();
+ for( ; pPropName != pPropNameEnd; ++pPropName, ++pValue )
+ setAnyProperty( *pPropName, *pValue );
+ }
+}
+
+void PropertySet::setProperties( const PropertyMap& rPropertyMap )
+{
+ if( !rPropertyMap.empty() )
+ {
+ Sequence< OUString > aPropNames;
+ Sequence< Any > aValues;
+ rPropertyMap.fillSequences( aPropNames, aValues );
+ setProperties( aPropNames, aValues );
+ }
+}
+
+// private --------------------------------------------------------------------
+
+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;
+}
+
+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() );
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/storagebase.cxx b/oox/source/helper/storagebase.cxx
new file mode 100644
index 000000000000..eee2b5c5d9b2
--- /dev/null
+++ b/oox/source/helper/storagebase.cxx
@@ -0,0 +1,273 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/storagebase.hxx"
+
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+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 ),
+ mbBaseStreamAccess( bBaseStreamAccess ),
+ mbReadOnly( true )
+{
+ OSL_ENSURE( mxInStream.is(), "StorageBase::StorageBase - missing base input stream" );
+}
+
+StorageBase::StorageBase( const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) :
+ mxOutStream( rxOutStream ),
+ mbBaseStreamAccess( bBaseStreamAccess ),
+ mbReadOnly( false )
+{
+ OSL_ENSURE( mxOutStream.is(), "StorageBase::StorageBase - missing base output stream" );
+}
+
+StorageBase::StorageBase( const StorageBase& rParentStorage, const OUString& rStorageName, bool bReadOnly ) :
+ maParentPath( rParentStorage.getPath() ),
+ maStorageName( rStorageName ),
+ mbBaseStreamAccess( false ),
+ mbReadOnly( bReadOnly )
+{
+}
+
+StorageBase::~StorageBase()
+{
+}
+
+bool StorageBase::isStorage() const
+{
+ return implIsStorage();
+}
+
+bool StorageBase::isRootStorage() const
+{
+ return implIsStorage() && (maStorageName.getLength() == 0);
+}
+
+bool StorageBase::isReadOnly() const
+{
+ return mbReadOnly;
+}
+
+Reference< XStorage > StorageBase::getXStorage() const
+{
+ return implGetXStorage();
+}
+
+const OUString& StorageBase::getName() const
+{
+ return maStorageName;
+}
+
+OUString StorageBase::getPath() const
+{
+ OUStringBuffer aBuffer( maParentPath );
+ 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 bCreateMissing )
+{
+ StorageRef xSubStorage;
+ OSL_ENSURE( !bCreateMissing || !mbReadOnly, "StorageBase::openSubStorage - cannot create substorage in read-only mode" );
+ if( !bCreateMissing || !mbReadOnly )
+ {
+ OUString aElement, aRemainder;
+ lclSplitFirstElement( aElement, aRemainder, rStorageName );
+ if( aElement.getLength() > 0 )
+ xSubStorage = getSubStorage( aElement, bCreateMissing );
+ if( xSubStorage.get() && (aRemainder.getLength() > 0) )
+ xSubStorage = xSubStorage->openSubStorage( aRemainder, bCreateMissing );
+ }
+ 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;
+ OSL_ENSURE( !mbReadOnly, "StorageBase::openOutputStream - cannot create output stream in read-only mode" );
+ if( !mbReadOnly )
+ {
+ 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->getOutputStream();
+ }
+ }
+ return xOutStream;
+}
+
+void StorageBase::copyToStorage( StorageBase& rDestStrg, const OUString& rElementName )
+{
+ OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
+ OSL_ENSURE( rElementName.getLength() > 0, "StorageBase::copyToStorage - invalid element name" );
+ if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() && (rElementName.getLength() > 0) )
+ {
+ StorageRef xSubStrg = openSubStorage( rElementName, false );
+ if( xSubStrg.get() )
+ {
+ StorageRef xDestSubStrg = rDestStrg.openSubStorage( rElementName, true );
+ if( xDestSubStrg.get() )
+ xSubStrg->copyStorageToStorage( *xDestSubStrg );
+ }
+ else
+ {
+ Reference< XInputStream > xInStrm = openInputStream( rElementName );
+ if( xInStrm.is() )
+ {
+ Reference< XOutputStream > xOutStrm = rDestStrg.openOutputStream( rElementName );
+ if( xOutStrm.is() )
+ {
+ BinaryXInputStream aInStrm( xInStrm, true );
+ BinaryXOutputStream aOutStrm( xOutStrm, true );
+ aInStrm.copyToStream( aOutStrm );
+ }
+ }
+ }
+ }
+}
+
+void StorageBase::copyStorageToStorage( StorageBase& rDestStrg )
+{
+ OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
+ if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() )
+ {
+ ::std::vector< OUString > aElements;
+ getElementNames( aElements );
+ for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt )
+ copyToStorage( rDestStrg, *aIt );
+ }
+}
+
+void StorageBase::commit()
+{
+ OSL_ENSURE( !mbReadOnly, "StorageBase::commit - cannot commit in read-only mode" );
+ if( !mbReadOnly )
+ {
+ // commit all open substorages
+ maSubStorages.forEachMem( &StorageBase::commit );
+ // commit this storage
+ implCommit();
+ }
+}
+
+// private --------------------------------------------------------------------
+
+StorageRef StorageBase::getSubStorage( const OUString& rElementName, bool bCreateMissing )
+{
+ StorageRef& rxSubStrg = maSubStorages[ rElementName ];
+ if( !rxSubStrg )
+ rxSubStrg = implOpenSubStorage( rElementName, bCreateMissing );
+ return rxSubStrg;
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/textinputstream.cxx b/oox/source/helper/textinputstream.cxx
new file mode 100644
index 000000000000..d590781c6fd3
--- /dev/null
+++ b/oox/source/helper/textinputstream.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/textinputstream.hxx"
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+/** Reads a text line from stream. First, tries to skip the second character of
+ a two-character line end sequence. Returns the new line-end character. */
+template< typename BufferType, typename CharType, typename StreamDataType >
+sal_Unicode lclReadLine( BufferType& orBuffer, BinaryInputStream& rInStrm, sal_Unicode cLastEolChar )
+{
+ // try to skip LF following CR, or CR following LF
+ if( !rInStrm.isEof() && (cLastEolChar != 0) )
+ {
+ CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() );
+ // return on EOF after line-end
+ if( rInStrm.isEof() )
+ return 0;
+ // return on sequence of equal line-end characters
+ bool bIsEolChar = (cChar == 10) || (cChar == 13);
+ if( bIsEolChar && (cChar == cLastEolChar) )
+ return cChar;
+ // append the character, if it is not the other line-end charcter
+ if( !bIsEolChar )
+ orBuffer.append( cChar );
+ }
+
+ // read chars until EOF or line end character (LF or CR)
+ while( true )
+ {
+ CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() );
+ if( rInStrm.isEof() )
+ return 0;
+ if( (cChar == 10) || (cChar == 13) )
+ return cChar;
+ orBuffer.append( cChar );
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+TextInputStream::TextInputStream( BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) :
+ mrInStrm( rInStrm ),
+ meTextEnc( eTextEnc ),
+ mcLastEolChar( 0 )
+{
+}
+
+bool TextInputStream::isEof() const
+{
+ // do not return EOF, if last text line missed line-end character (see below)
+ return mrInStrm.isEof() && (mcLastEolChar == 0);
+}
+
+OUString TextInputStream::readLine()
+{
+ if( mrInStrm.isEof() )
+ {
+ mcLastEolChar = 0;
+ return OUString();
+ }
+
+ OUString aLine;
+ if( meTextEnc == RTL_TEXTENCODING_UCS2 )
+ {
+ // read 16-bit characters for UCS2 encoding
+ OUStringBuffer aBuffer;
+ mcLastEolChar = lclReadLine< OUStringBuffer, sal_Unicode, sal_uInt16 >( aBuffer, mrInStrm, mcLastEolChar );
+ aLine = aBuffer.makeStringAndClear();
+ }
+ else
+ {
+ // otherwise, read 8-bit characters and convert according to text encoding
+ OStringBuffer aBuffer;
+ mcLastEolChar = lclReadLine< OStringBuffer, sal_Char, sal_uInt8 >( aBuffer, mrInStrm, mcLastEolChar );
+ aLine = OStringToOUString( aBuffer.makeStringAndClear(), meTextEnc );
+ }
+
+ // if last line is not empty but line-end character is missing, do not return EOF
+ if( mrInStrm.isEof() && (aLine.getLength() > 0) )
+ mcLastEolChar = 10;
+
+ return aLine;
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/helper/zipstorage.cxx b/oox/source/helper/zipstorage.cxx
new file mode 100644
index 000000000000..fecad5ab40e7
--- /dev/null
+++ b/oox/source/helper/zipstorage.cxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/zipstorage.hxx"
+
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/storagehelper.hxx>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+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
+ {
+ /* #i105325# ::comphelper::OStorageHelper::GetStorageFromInputStream()
+ cannot be used here as it will open a storage with format type
+ 'PackageFormat' that will not work with OOXML packages.
+
+ #161971# The MS-document storages should always be opened in Repair-Mode to
+ ignore the format errors and get so much info as possible. I hate this
+ solution, but it seems to be the only consistent way to handle the MS-documents.
+
+ TODO: #i105410# switch to 'OFOPXMLFormat' and use its
+ implementation of relations handling. */
+
+ mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
+ ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory,
+ sal_False /* DEV300_m80: Was sal_True, but DOCX and others did not load */ );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+ZipStorage::ZipStorage(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XStream >& rxStream ) :
+ StorageBase( rxStream, false )
+{
+ OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" );
+ // create base storage object
+ try
+ {
+ using namespace ::com::sun::star::embed::ElementModes;
+ mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream(
+ OFOPXML_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory, sal_True );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "ZipStorage::ZipStorage - cannot open output storage" );
+ }
+}
+
+ZipStorage::ZipStorage( const ZipStorage& rParentStorage, const Reference< XStorage >& rxStorage, const OUString& rElementName ) :
+ StorageBase( rParentStorage, rElementName, rParentStorage.isReadOnly() ),
+ 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 bCreateMissing )
+{
+ Reference< XStorage > xSubXStorage;
+ bool bMissing = false;
+ if( mxStorage.is() ) try
+ {
+ // XStorage::isStorageElement may throw various exceptions...
+ if( mxStorage->isStorageElement( rElementName ) )
+ xSubXStorage = mxStorage->openStorageElement(
+ rElementName, ::com::sun::star::embed::ElementModes::READ );
+ }
+ catch( NoSuchElementException& )
+ {
+ bMissing = true;
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( bMissing && bCreateMissing ) try
+ {
+ xSubXStorage = mxStorage->openStorageElement(
+ rElementName, ::com::sun::star::embed::ElementModes::READWRITE );
+ }
+ 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
+ {
+ xOutStream.set( mxStorage->openStreamElement( rElementName, ::com::sun::star::embed::ElementModes::READWRITE ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xOutStream;
+}
+
+void ZipStorage::implCommit() const
+{
+ try
+ {
+ Reference< XTransactedObject >( mxStorage, UNO_QUERY_THROW )->commit();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/ole/axbinaryreader.cxx b/oox/source/ole/axbinaryreader.cxx
new file mode 100644
index 000000000000..493d6b68c6ff
--- /dev/null
+++ b/oox/source/ole/axbinaryreader.cxx
@@ -0,0 +1,348 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/axbinaryreader.hxx"
+
+#include "oox/ole/olehelper.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 AX_STRING_SIZEMASK = 0x7FFFFFFF;
+const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000;
+
+} // namespace
+
+// ============================================================================
+
+AxAlignedInputStream::AxAlignedInputStream( BinaryInputStream& rInStrm ) :
+ mrInStrm( rInStrm ),
+ mnStrmPos( 0 )
+{
+}
+
+sal_Int64 AxAlignedInputStream::tell() const
+{
+ return mnStrmPos;
+}
+
+void AxAlignedInputStream::seek( sal_Int64 nPos )
+{
+ mbEof = mbEof || (nPos < mnStrmPos);
+ if( !mbEof )
+ skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) );
+}
+
+sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
+{
+ sal_Int32 nReadSize = mrInStrm.readData( orData, nBytes );
+ mnStrmPos += nReadSize;
+ return nReadSize;
+}
+
+sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes )
+{
+ sal_Int32 nReadSize = mrInStrm.readMemory( opMem, nBytes );
+ mnStrmPos += nReadSize;
+ return nReadSize;
+}
+
+void AxAlignedInputStream::skip( sal_Int32 nBytes )
+{
+ mrInStrm.skip( nBytes );
+ mnStrmPos += nBytes;
+}
+
+void AxAlignedInputStream::align( size_t nSize )
+{
+ skip( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) );
+}
+
+// ============================================================================
+
+AxFontData::AxFontData() :
+ mnFontEffects( 0 ),
+ mnFontHeight( 160 ),
+ mnFontCharSet( WINDOWS_CHARSET_DEFAULT ),
+ mnHorAlign( AX_FONTDATA_LEFT ),
+ mbDblUnderline( false )
+{
+}
+
+sal_Int16 AxFontData::getHeightPoints() const
+{
+ /* MSO uses weird font sizes:
+ 1pt->30, 2pt->45, 3pt->60, 4pt->75, 5pt->105, 6pt->120, 7pt->135,
+ 8pt->165, 9pt->180, 10pt->195, 11pt->225, ... */
+ return getLimitedValue< sal_Int16, sal_Int32 >( (mnFontHeight + 10) / 20, 1, SAL_MAX_INT16 );
+}
+
+void AxFontData::setHeightPoints( sal_Int16 nPoints )
+{
+ mnFontHeight = getLimitedValue< sal_Int32, sal_Int32 >( ((nPoints * 4 + 1) / 3) * 15, 30, 4294967 );
+}
+
+bool AxFontData::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readStringProperty( maFontName );
+ aReader.readIntProperty< sal_uInt32 >( mnFontEffects );
+ aReader.readIntProperty< sal_Int32 >( mnFontHeight );
+ aReader.skipIntProperty< sal_Int32 >(); // font offset
+ aReader.readIntProperty< sal_uInt8 >( mnFontCharSet );
+ aReader.skipIntProperty< sal_uInt8 >(); // font pitch/family
+ aReader.readIntProperty< sal_uInt8 >( mnHorAlign );
+ aReader.skipIntProperty< sal_uInt16 >(); // font weight
+ mbDblUnderline = false;
+ return aReader.finalizeImport();
+}
+
+bool AxFontData::importStdFont( BinaryInputStream& rInStrm )
+{
+ StdFontInfo aFontInfo;
+ if( OleHelper::importStdFont( aFontInfo, rInStrm, false ) )
+ {
+ maFontName = aFontInfo.maName;
+ mnFontEffects = 0;
+ setFlag( mnFontEffects, AX_FONTDATA_BOLD, aFontInfo.mnWeight >= OLE_STDFONT_BOLD );
+ setFlag( mnFontEffects, AX_FONTDATA_ITALIC, getFlag( aFontInfo.mnFlags, OLE_STDFONT_ITALIC ) );
+ setFlag( mnFontEffects, AX_FONTDATA_UNDERLINE, getFlag( aFontInfo.mnFlags, OLE_STDFONT_UNDERLINE ) );
+ setFlag( mnFontEffects, AX_FONTDATA_STRIKEOUT, getFlag( aFontInfo.mnFlags,OLE_STDFONT_STRIKE ) );
+ mbDblUnderline = false;
+ // StdFont stores font height in 1/10,000 of points
+ setHeightPoints( getLimitedValue< sal_Int16, sal_Int32 >( aFontInfo.mnHeight / 10000, 0, SAL_MAX_INT16 ) );
+ mnFontCharSet = aFontInfo.mnCharSet;
+ mnHorAlign = AX_FONTDATA_LEFT;
+ return true;
+ }
+ return false;
+}
+
+bool AxFontData::importGuidAndFont( BinaryInputStream& rInStrm )
+{
+ OUString aGuid = OleHelper::importGuid( rInStrm );
+ if( aGuid.equalsAscii( AX_GUID_CFONT ) )
+ return importBinaryModel( rInStrm );
+ if( aGuid.equalsAscii( OLE_GUID_STDFONT ) )
+ return importStdFont( rInStrm );
+ return false;
+}
+
+// ============================================================================
+
+namespace {
+
+bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString )
+{
+ bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
+ sal_uInt32 nBufSize = nSize & AX_STRING_SIZEMASK;
+ // Unicode: simple strings store byte count, array strings store char count
+ sal_Int32 nChars = static_cast< sal_Int32 >( nBufSize / ((bCompressed || bArrayString) ? 1 : 2) );
+ bool bValidChars = nChars <= 65536;
+ OSL_ENSURE( bValidChars, "lclReadString - string too long" );
+ sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2);
+ nChars = ::std::min< sal_Int32 >( nChars, 65536 );
+ rValue = bCompressed ?
+ // ISO-8859-1 maps all byte values xx to the same Unicode code point U+00xx
+ rInStrm.readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1 ) :
+ rInStrm.readUnicodeArray( nChars );
+ rInStrm.seek( nEndPos );
+ return bValidChars;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+AxBinaryPropertyReader::ComplexProperty::~ComplexProperty()
+{
+}
+
+bool AxBinaryPropertyReader::PairProperty::readProperty( AxAlignedInputStream& rInStrm )
+{
+ rInStrm >> mrPairData.first >> mrPairData.second;
+ return true;
+}
+
+bool AxBinaryPropertyReader::StringProperty::readProperty( AxAlignedInputStream& rInStrm )
+{
+ return lclReadString( rInStrm, mrValue, mnSize, false );
+}
+
+bool AxBinaryPropertyReader::StringArrayProperty::readProperty( AxAlignedInputStream& rInStrm )
+{
+ sal_Int64 nEndPos = rInStrm.tell() + mnSize;
+ while( rInStrm.tell() < nEndPos )
+ {
+ OUString aString;
+ if( !lclReadString( rInStrm, aString, rInStrm.readuInt32(), true ) )
+ return false;
+ mrArray.push_back( aString );
+ // every array string is aligned on 4 byte boundries
+ rInStrm.align( 4 );
+ }
+ return true;
+}
+
+bool AxBinaryPropertyReader::GuidProperty::readProperty( AxAlignedInputStream& rInStrm )
+{
+ mrGuid = OleHelper::importGuid( rInStrm );
+ return true;
+}
+
+bool AxBinaryPropertyReader::FontProperty::readProperty( AxAlignedInputStream& rInStrm )
+{
+ return mrFontData.importGuidAndFont( rInStrm );
+}
+
+bool AxBinaryPropertyReader::PictureProperty::readProperty( AxAlignedInputStream& rInStrm )
+{
+ return OleHelper::importStdPic( mrPicData, rInStrm, true );
+}
+
+// ----------------------------------------------------------------------------
+
+AxBinaryPropertyReader::AxBinaryPropertyReader( BinaryInputStream& rInStrm, bool b64BitPropFlags ) :
+ maInStrm( rInStrm ),
+ mbValid( true )
+{
+ // version and size of property block
+ maInStrm.skip( 2 );
+ sal_uInt16 nBlockSize = maInStrm.readValue< sal_uInt16 >();
+ mnPropsEnd = maInStrm.tell() + nBlockSize;
+ // flagfield containing existing properties
+ if( b64BitPropFlags )
+ maInStrm >> mnPropFlags;
+ else
+ mnPropFlags = maInStrm.readuInt32();
+ mnNextProp = 1;
+}
+
+void AxBinaryPropertyReader::readBoolProperty( bool& orbValue, bool bReverse )
+{
+ // there is no data, the boolean value is equivalent to the property flag itself
+ orbValue = startNextProperty() != bReverse;
+}
+
+void AxBinaryPropertyReader::readPairProperty( AxPairData& orPairData )
+{
+ if( startNextProperty() )
+ maLargeProps.push_back( ComplexPropVector::value_type( new PairProperty( orPairData ) ) );
+}
+
+void AxBinaryPropertyReader::readStringProperty( OUString& orValue )
+{
+ if( startNextProperty() )
+ {
+ sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
+ maLargeProps.push_back( ComplexPropVector::value_type( new StringProperty( orValue, nSize ) ) );
+ }
+}
+
+void AxBinaryPropertyReader::readStringArrayProperty( AxStringArray& orArray )
+{
+ if( startNextProperty() )
+ {
+ sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
+ maLargeProps.push_back( ComplexPropVector::value_type( new StringArrayProperty( orArray, nSize ) ) );
+ }
+}
+
+void AxBinaryPropertyReader::readGuidProperty( ::rtl::OUString& orGuid )
+{
+ if( startNextProperty() )
+ maLargeProps.push_back( ComplexPropVector::value_type( new GuidProperty( orGuid ) ) );
+}
+
+void AxBinaryPropertyReader::readFontProperty( AxFontData& orFontData )
+{
+ if( startNextProperty() )
+ {
+ sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
+ if( ensureValid( nData == -1 ) )
+ maStreamProps.push_back( ComplexPropVector::value_type( new FontProperty( orFontData ) ) );
+ }
+}
+
+void AxBinaryPropertyReader::readPictureProperty( StreamDataSequence& orPicData )
+{
+ if( startNextProperty() )
+ {
+ sal_Int16 nData = maInStrm.readAligned< sal_Int16 >();
+ if( ensureValid( nData == -1 ) )
+ maStreamProps.push_back( ComplexPropVector::value_type( new PictureProperty( orPicData ) ) );
+ }
+}
+
+bool AxBinaryPropertyReader::finalizeImport()
+{
+ // read large properties
+ maInStrm.align( 4 );
+ if( ensureValid( mnPropFlags == 0 ) && !maLargeProps.empty() )
+ {
+ for( ComplexPropVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
+ {
+ ensureValid( (*aIt)->readProperty( maInStrm ) );
+ maInStrm.align( 4 );
+ }
+ }
+ maInStrm.seek( mnPropsEnd );
+
+ // read stream properties (no stream alignment between properties!)
+ if( ensureValid() && !maStreamProps.empty() )
+ for( ComplexPropVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
+ ensureValid( (*aIt)->readProperty( maInStrm ) );
+
+ return mbValid;
+}
+
+bool AxBinaryPropertyReader::ensureValid( bool bCondition )
+{
+ mbValid = mbValid && bCondition && !maInStrm.isEof();
+ return mbValid;
+}
+
+bool AxBinaryPropertyReader::startNextProperty()
+{
+ bool bHasProp = getFlag( mnPropFlags, mnNextProp );
+ setFlag( mnPropFlags, mnNextProp, false );
+ mnNextProp <<= 1;
+ return ensureValid() && bHasProp;
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx
new file mode 100644
index 000000000000..86cc55df3127
--- /dev/null
+++ b/oox/source/ole/axcontrol.cxx
@@ -0,0 +1,1865 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/axcontrol.hxx"
+
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/ImagePosition.hpp>
+#include <com/sun/star/awt/ImageScaleMode.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/ScrollBarOrientation.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/TextAlign.hpp>
+#include <com/sun/star/awt/VisualEffect.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XFormComponent.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <rtl/tencinfo.h>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/propertymap.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::form::binding;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 COMCTL_ID_SIZE = 0x12344321;
+
+const sal_uInt32 COMCTL_ID_COMMONDATA = 0xABCDEF01;
+const sal_uInt32 COMCTL_COMMON_FLATBORDER = 0x00000001;
+const sal_uInt32 COMCTL_COMMON_ENABLED = 0x00000002;
+const sal_uInt32 COMCTL_COMMON_3DBORDER = 0x00000004;
+const sal_uInt32 COMCTL_COMMON_OLEDROPMAN = 0x00002000;
+
+const sal_uInt32 COMCTL_ID_COMPLEXDATA = 0xBDECDE1F;
+const sal_uInt32 COMCTL_COMPLEX_FONT = 0x00000001;
+const sal_uInt32 COMCTL_COMPLEX_MOUSEICON = 0x00000002;
+
+const sal_uInt32 COMCTL_ID_SCROLLBAR_60 = 0x99470A83;
+const sal_uInt32 COMCTL_SCROLLBAR_HOR = 0x00000010;
+const sal_Int32 COMCTL_SCROLLBAR_3D = 0;
+const sal_Int32 COMCTL_SCROLLBAR_FLAT = 1;
+const sal_Int32 COMCTL_SCROLLBAR_TRACK3D = 2;
+
+const sal_uInt32 COMCTL_ID_PROGRESSBAR_50 = 0xE6E17E84;
+const sal_uInt32 COMCTL_ID_PROGRESSBAR_60 = 0x97AB8A01;
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt32 AX_CMDBUTTON_DEFFLAGS = 0x0000001B;
+const sal_uInt32 AX_LABEL_DEFFLAGS = 0x0080001B;
+const sal_uInt32 AX_IMAGE_DEFFLAGS = 0x0000001B;
+const sal_uInt32 AX_MORPHDATA_DEFFLAGS = 0x2C80081B;
+const sal_uInt32 AX_SPINBUTTON_DEFFLAGS = 0x0000001B;
+const sal_uInt32 AX_SCROLLBAR_DEFFLAGS = 0x0000001B;
+const sal_uInt32 AX_TABSTRIP_DEFFLAGS = 0x0000001B;
+
+const sal_uInt16 AX_POS_TOPLEFT = 0;
+const sal_uInt16 AX_POS_TOP = 1;
+const sal_uInt16 AX_POS_TOPRIGHT = 2;
+const sal_uInt16 AX_POS_LEFT = 3;
+const sal_uInt16 AX_POS_CENTER = 4;
+const sal_uInt16 AX_POS_RIGHT = 5;
+const sal_uInt16 AX_POS_BOTTOMLEFT = 6;
+const sal_uInt16 AX_POS_BOTTOM = 7;
+const sal_uInt16 AX_POS_BOTTOMRIGHT = 8;
+
+#define AX_PICPOS_IMPL( label, image ) ((AX_POS_##label << 16) | AX_POS_##image)
+const sal_uInt32 AX_PICPOS_LEFTTOP = AX_PICPOS_IMPL( TOPRIGHT, TOPLEFT );
+const sal_uInt32 AX_PICPOS_LEFTCENTER = AX_PICPOS_IMPL( RIGHT, LEFT );
+const sal_uInt32 AX_PICPOS_LEFTBOTTOM = AX_PICPOS_IMPL( BOTTOMRIGHT, BOTTOMLEFT );
+const sal_uInt32 AX_PICPOS_RIGHTTOP = AX_PICPOS_IMPL( TOPLEFT, TOPRIGHT );
+const sal_uInt32 AX_PICPOS_RIGHTCENTER = AX_PICPOS_IMPL( LEFT, RIGHT );
+const sal_uInt32 AX_PICPOS_RIGHTBOTTOM = AX_PICPOS_IMPL( BOTTOMLEFT, BOTTOMRIGHT );
+const sal_uInt32 AX_PICPOS_ABOVELEFT = AX_PICPOS_IMPL( BOTTOMLEFT, TOPLEFT );
+const sal_uInt32 AX_PICPOS_ABOVECENTER = AX_PICPOS_IMPL( BOTTOM, TOP );
+const sal_uInt32 AX_PICPOS_ABOVERIGHT = AX_PICPOS_IMPL( BOTTOMRIGHT, TOPRIGHT );
+const sal_uInt32 AX_PICPOS_BELOWLEFT = AX_PICPOS_IMPL( TOPLEFT, BOTTOMLEFT );
+const sal_uInt32 AX_PICPOS_BELOWCENTER = AX_PICPOS_IMPL( TOP, BOTTOM );
+const sal_uInt32 AX_PICPOS_BELOWRIGHT = AX_PICPOS_IMPL( TOPRIGHT, BOTTOMRIGHT );
+const sal_uInt32 AX_PICPOS_CENTER = AX_PICPOS_IMPL( CENTER, CENTER );
+#undef AX_PICPOS_IMPL
+
+const sal_Int32 AX_MATCHENTRY_FIRSTLETTER = 0;
+const sal_Int32 AX_MATCHENTRY_COMPLETE = 1;
+const sal_Int32 AX_MATCHENTRY_NONE = 2;
+
+const sal_Int32 AX_ORIENTATION_AUTO = -1;
+const sal_Int32 AX_ORIENTATION_VERTICAL = 0;
+const sal_Int32 AX_ORIENTATION_HORIZONTAL = 1;
+
+const sal_Int32 AX_PROPTHUMB_ON = -1;
+const sal_Int32 AX_PROPTHUMB_OFF = 0;
+
+const sal_uInt32 AX_TABSTRIP_TABS = 0;
+const sal_uInt32 AX_TABSTRIP_BUTTONS = 1;
+const sal_uInt32 AX_TABSTRIP_NONE = 2;
+
+const sal_uInt32 AX_CONTAINER_ENABLED = 0x00000004;
+const sal_uInt32 AX_CONTAINER_HASDESIGNEXT = 0x00004000;
+const sal_uInt32 AX_CONTAINER_NOCLASSTABLE = 0x00008000;
+
+const sal_uInt32 AX_CONTAINER_DEFFLAGS = 0x00000004;
+
+const sal_Int32 AX_CONTAINER_DEFWIDTH = 4000;
+const sal_Int32 AX_CONTAINER_DEFHEIGHT = 3000;
+
+const sal_Int32 AX_CONTAINER_CYCLEALL = 0;
+const sal_Int32 AX_CONTAINER_CYCLECURRENT = 2;
+
+const sal_Int32 AX_CONTAINER_SCR_NONE = 0x00;
+const sal_Int32 AX_CONTAINER_SCR_HOR = 0x01;
+const sal_Int32 AX_CONTAINER_SCR_VER = 0x02;
+const sal_Int32 AX_CONTAINER_SCR_KEEP_HOR = 0x04;
+const sal_Int32 AX_CONTAINER_SCR_KEEP_VER = 0x08;
+const sal_Int32 AX_CONTAINER_SCR_SHOW_LEFT = 0x10;
+
+// ----------------------------------------------------------------------------
+
+const sal_Int16 API_BORDER_NONE = 0;
+const sal_Int16 API_BORDER_SUNKEN = 1;
+const sal_Int16 API_BORDER_FLAT = 2;
+
+const sal_Int16 API_STATE_UNCHECKED = 0;
+const sal_Int16 API_STATE_CHECKED = 1;
+const sal_Int16 API_STATE_DONTKNOW = 2;
+
+// ----------------------------------------------------------------------------
+
+/** Tries to extract a range address from a defined name. */
+bool lclExtractRangeFromName( CellRangeAddress& orRangeAddr, const Reference< XModel >& rxDocModel, const OUString& rAddressString )
+{
+ try
+ {
+ PropertySet aPropSet( rxDocModel );
+ Reference< XNameAccess > xRangesNA( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY_THROW );
+ Reference< XCellRangeReferrer > xReferrer( xRangesNA->getByName( rAddressString ), UNO_QUERY_THROW );
+ Reference< XCellRangeAddressable > xAddressable( xReferrer->getReferredCells(), UNO_QUERY_THROW );
+ orRangeAddr = xAddressable->getRangeAddress();
+ return true;
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+bool lclExtractAddressFromName( CellAddress& orAddress, const Reference< XModel >& rxDocModel, const OUString& rAddressString )
+{
+ CellRangeAddress aRangeAddr;
+ if( lclExtractRangeFromName( aRangeAddr, rxDocModel, rAddressString ) &&
+ (aRangeAddr.StartColumn == aRangeAddr.EndColumn) &&
+ (aRangeAddr.StartRow == aRangeAddr.EndRow) )
+ {
+ orAddress.Sheet = aRangeAddr.Sheet;
+ orAddress.Column = aRangeAddr.StartColumn;
+ orAddress.Row = aRangeAddr.StartRow;
+ return true;
+ }
+ return false;
+}
+
+void lclPrepareConverter( PropertySet& rConverter, const Reference< XModel >& rxDocModel,
+ const OUString& rAddressString, sal_Int32 nRefSheet, bool bRange )
+{
+ if( !rConverter.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory( rxDocModel, UNO_QUERY_THROW );
+ OUString aServiceName = bRange ?
+ CREATE_OUSTRING( "com.sun.star.table.CellRangeAddressConversion" ) :
+ CREATE_OUSTRING( "com.sun.star.table.CellAddressConversion" );
+ rConverter.set( xFactory->createInstance( aServiceName ) );
+ }
+ catch( Exception& )
+ {
+ }
+ rConverter.setProperty( PROP_XLA1Representation, rAddressString );
+ rConverter.setProperty( PROP_ReferenceSheet, nRefSheet );
+}
+
+} // namespace
+
+// ============================================================================
+
+ControlConverter::ControlConverter( const Reference< XModel >& rxDocModel,
+ const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
+ mxDocModel( rxDocModel ),
+ mrGraphicHelper( rGraphicHelper ),
+ mbDefaultColorBgr( bDefaultColorBgr )
+{
+ OSL_ENSURE( mxDocModel.is(), "ControlConverter::ControlConverter - missing document model" );
+}
+
+ControlConverter::~ControlConverter()
+{
+}
+
+// Generic conversion ---------------------------------------------------------
+
+void ControlConverter::convertPosition( PropertyMap& rPropMap, const AxPairData& rPos ) const
+{
+ // position is given in 1/100 mm, UNO needs AppFont units
+ Point aAppFontPos = mrGraphicHelper.convertHmmToAppFont( Point( rPos.first, rPos.second ) );
+ rPropMap.setProperty( PROP_PositionX, aAppFontPos.X );
+ rPropMap.setProperty( PROP_PositionY, aAppFontPos.Y );
+}
+
+void ControlConverter::convertSize( PropertyMap& rPropMap, const AxPairData& rSize ) const
+{
+ // size is given in 1/100 mm, UNO needs AppFont units
+ Size aAppFontSize = mrGraphicHelper.convertHmmToAppFont( Size( rSize.first, rSize.second ) );
+ rPropMap.setProperty( PROP_Width, aAppFontSize.Width );
+ rPropMap.setProperty( PROP_Height, aAppFontSize.Height );
+}
+
+void ControlConverter::convertColor( PropertyMap& rPropMap, sal_Int32 nPropId, sal_uInt32 nOleColor ) const
+{
+ rPropMap.setProperty( nPropId, OleHelper::decodeOleColor( mrGraphicHelper, nOleColor, mbDefaultColorBgr ) );
+}
+
+void ControlConverter::convertPicture( PropertyMap& rPropMap, const StreamDataSequence& rPicData ) const
+{
+ if( rPicData.hasElements() )
+ {
+ OUString aGraphicUrl = mrGraphicHelper.importGraphicObject( rPicData );
+ if( aGraphicUrl.getLength() > 0 )
+ rPropMap.setProperty( PROP_ImageURL, aGraphicUrl );
+ }
+}
+
+void ControlConverter::convertOrientation( PropertyMap& rPropMap, bool bHorizontal ) const
+{
+ sal_Int32 nScrollOrient = bHorizontal ? ScrollBarOrientation::HORIZONTAL : ScrollBarOrientation::VERTICAL;
+ rPropMap.setProperty( PROP_Orientation, nScrollOrient );
+}
+
+void ControlConverter::convertVerticalAlign( PropertyMap& rPropMap, sal_Int32 nVerticalAlign ) const
+{
+ VerticalAlignment eAlign = VerticalAlignment_TOP;
+ switch( nVerticalAlign )
+ {
+ case XML_Top: eAlign = VerticalAlignment_TOP; break;
+ case XML_Center: eAlign = VerticalAlignment_MIDDLE; break;
+ case XML_Bottom: eAlign = VerticalAlignment_BOTTOM; break;
+ }
+ rPropMap.setProperty( PROP_VerticalAlign, eAlign );
+}
+
+void ControlConverter::convertScrollBar( PropertyMap& rPropMap,
+ sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nPosition,
+ sal_Int32 nSmallChange, sal_Int32 nLargeChange, bool bAwtModel ) const
+{
+ rPropMap.setProperty( PROP_ScrollValueMin, ::std::min( nMin, nMax ) );
+ rPropMap.setProperty( PROP_ScrollValueMax, ::std::max( nMin, nMax ) );
+ rPropMap.setProperty( PROP_LineIncrement, nSmallChange );
+ rPropMap.setProperty( PROP_BlockIncrement, nLargeChange );
+ rPropMap.setProperty( bAwtModel ? PROP_ScrollValue : PROP_DefaultScrollValue, nPosition );
+}
+
+void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlModel,
+ const OUString& rCtrlSource, const OUString& rRowSource, sal_Int32 nRefSheet ) const
+{
+ // value binding
+ if( rCtrlSource.getLength() > 0 ) try
+ {
+ // first check if the XBindableValue interface is supported
+ Reference< XBindableValue > xBindable( rxCtrlModel, UNO_QUERY_THROW );
+
+ // convert address string to cell address struct
+ CellAddress aAddress;
+ if( !lclExtractAddressFromName( aAddress, mxDocModel, rCtrlSource ) )
+ {
+ lclPrepareConverter( maAddressConverter, mxDocModel, rCtrlSource, nRefSheet, false );
+ if( !maAddressConverter.getProperty( aAddress, PROP_Address ) )
+ throw RuntimeException();
+ }
+
+ // create argument sequence
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( "BoundCell" );
+ aValue.Value <<= aAddress;
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the CellValueBinding instance and set at the control model
+ Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW );
+ Reference< XValueBinding > xBinding( xFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.table.CellValueBinding" ), aArgs ), UNO_QUERY_THROW );
+ xBindable->setValueBinding( xBinding );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // list entry source
+ if( rRowSource.getLength() > 0 ) try
+ {
+ // first check if the XListEntrySink interface is supported
+ Reference< XListEntrySink > xEntrySink( rxCtrlModel, UNO_QUERY_THROW );
+
+ // convert address string to cell range address struct
+ CellRangeAddress aRangeAddr;
+ if( !lclExtractRangeFromName( aRangeAddr, mxDocModel, rRowSource ) )
+ {
+ lclPrepareConverter( maRangeConverter, mxDocModel, rRowSource, nRefSheet, true );
+ if( !maRangeConverter.getProperty( aRangeAddr, PROP_Address ) )
+ throw RuntimeException();
+ }
+
+ // create argument sequence
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( "CellRange" );
+ aValue.Value <<= aRangeAddr;
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the EntrySource instance and set at the control model
+ Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW );
+ Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.table.CellRangeListSource" ), aArgs ), UNO_QUERY_THROW );
+ xEntrySink->setListEntrySource( xEntrySource );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ActiveX (Forms 2.0) specific conversion ------------------------------------
+
+void ControlConverter::convertAxBackground( PropertyMap& rPropMap,
+ sal_uInt32 nBackColor, sal_uInt32 nFlags, ApiTransparencyMode eTranspMode ) const
+{
+ bool bOpaque = getFlag( nFlags, AX_FLAGS_OPAQUE );
+ switch( eTranspMode )
+ {
+ case API_TRANSPARENCY_NOTSUPPORTED:
+ // fake transparency by using system window background if needed
+ convertColor( rPropMap, PROP_BackgroundColor, bOpaque ? nBackColor : AX_SYSCOLOR_WINDOWBACK );
+ break;
+ case API_TRANSPARENCY_PAINTTRANSPARENT:
+ rPropMap.setProperty( PROP_PaintTransparent, !bOpaque );
+ // run-through intended!
+ case API_TRANSPARENCY_VOID:
+ // keep transparency by leaving the (void) default property value
+ if( bOpaque )
+ convertColor( rPropMap, PROP_BackgroundColor, nBackColor );
+ break;
+ }
+}
+
+void ControlConverter::convertAxBorder( PropertyMap& rPropMap,
+ sal_uInt32 nBorderColor, sal_Int32 nBorderStyle, sal_Int32 nSpecialEffect ) const
+{
+ sal_Int16 nBorder = (nBorderStyle == AX_BORDERSTYLE_SINGLE) ? API_BORDER_FLAT :
+ ((nSpecialEffect == AX_SPECIALEFFECT_FLAT) ? API_BORDER_NONE : API_BORDER_SUNKEN);
+ rPropMap.setProperty( PROP_Border, nBorder );
+ convertColor( rPropMap, PROP_BorderColor, nBorderColor );
+}
+
+void ControlConverter::convertAxVisualEffect( PropertyMap& rPropMap, sal_Int32 nSpecialEffect ) const
+{
+ sal_Int16 nVisualEffect = (nSpecialEffect == AX_SPECIALEFFECT_FLAT) ? VisualEffect::FLAT : VisualEffect::LOOK3D;
+ rPropMap.setProperty( PROP_VisualEffect, nVisualEffect );
+}
+
+void ControlConverter::convertAxPicture( PropertyMap& rPropMap, const StreamDataSequence& rPicData, sal_uInt32 nPicPos ) const
+{
+ // the picture
+ convertPicture( rPropMap, rPicData );
+
+ // picture position
+ sal_Int16 nImagePos = ImagePosition::LeftCenter;
+ switch( nPicPos )
+ {
+ case AX_PICPOS_LEFTTOP: nImagePos = ImagePosition::LeftTop; break;
+ case AX_PICPOS_LEFTCENTER: nImagePos = ImagePosition::LeftCenter; break;
+ case AX_PICPOS_LEFTBOTTOM: nImagePos = ImagePosition::LeftBottom; break;
+ case AX_PICPOS_RIGHTTOP: nImagePos = ImagePosition::RightTop; break;
+ case AX_PICPOS_RIGHTCENTER: nImagePos = ImagePosition::RightCenter; break;
+ case AX_PICPOS_RIGHTBOTTOM: nImagePos = ImagePosition::RightBottom; break;
+ case AX_PICPOS_ABOVELEFT: nImagePos = ImagePosition::AboveLeft; break;
+ case AX_PICPOS_ABOVECENTER: nImagePos = ImagePosition::AboveCenter; break;
+ case AX_PICPOS_ABOVERIGHT: nImagePos = ImagePosition::AboveRight; break;
+ case AX_PICPOS_BELOWLEFT: nImagePos = ImagePosition::BelowLeft; break;
+ case AX_PICPOS_BELOWCENTER: nImagePos = ImagePosition::BelowCenter; break;
+ case AX_PICPOS_BELOWRIGHT: nImagePos = ImagePosition::BelowRight; break;
+ case AX_PICPOS_CENTER: nImagePos = ImagePosition::Centered; break;
+ default: OSL_ENSURE( false, "ControlConverter::convertAxPicture - unknown picture position" );
+ }
+ rPropMap.setProperty( PROP_ImagePosition, nImagePos );
+}
+
+void ControlConverter::convertAxPicture( PropertyMap& rPropMap, const StreamDataSequence& rPicData,
+ sal_Int32 nPicSizeMode, sal_Int32 /*nPicAlign*/, bool /*bPicTiling*/ ) const
+{
+ // the picture
+ convertPicture( rPropMap, rPicData );
+
+ // picture scale mode
+ sal_Int16 nScaleMode = ImageScaleMode::None;
+ switch( nPicSizeMode )
+ {
+ case AX_PICSIZE_CLIP: nScaleMode = ImageScaleMode::None; break;
+ case AX_PICSIZE_STRETCH: nScaleMode = ImageScaleMode::Anisotropic; break;
+ case AX_PICSIZE_ZOOM: nScaleMode = ImageScaleMode::Isotropic; break;
+ default: OSL_ENSURE( false, "ControlConverter::convertAxPicture - unknown picture size mode" );
+ }
+ rPropMap.setProperty( PROP_ScaleMode, nScaleMode );
+}
+
+void ControlConverter::convertAxState( PropertyMap& rPropMap,
+ const OUString& rValue, sal_Int32 nMultiSelect, ApiDefaultStateMode eDefStateMode, bool bAwtModel ) const
+{
+ bool bBooleanState = eDefStateMode == API_DEFAULTSTATE_BOOLEAN;
+ bool bSupportsTriState = eDefStateMode == API_DEFAULTSTATE_TRISTATE;
+
+ // state
+ sal_Int16 nState = bSupportsTriState ? API_STATE_DONTKNOW : API_STATE_UNCHECKED;
+ if( rValue.getLength() == 1 ) switch( rValue[ 0 ] )
+ {
+ case '0': nState = API_STATE_UNCHECKED; break;
+ case '1': nState = API_STATE_CHECKED; break;
+ // any other string (also empty) means 'dontknow'
+ }
+ sal_Int32 nPropId = bAwtModel ? PROP_State : PROP_DefaultState;
+ if( bBooleanState )
+ rPropMap.setProperty( nPropId, nState != API_STATE_UNCHECKED );
+ else
+ rPropMap.setProperty( nPropId, nState );
+
+ // tristate
+ if( bSupportsTriState )
+ rPropMap.setProperty( PROP_TriState, nMultiSelect == AX_SELCTION_MULTI );
+}
+
+void ControlConverter::convertAxOrientation( PropertyMap& rPropMap,
+ const AxPairData& rSize, sal_Int32 nOrientation ) const
+{
+ bool bHorizontal = true;
+ switch( nOrientation )
+ {
+ case AX_ORIENTATION_AUTO: bHorizontal = rSize.first > rSize.second; break;
+ case AX_ORIENTATION_VERTICAL: bHorizontal = false; break;
+ case AX_ORIENTATION_HORIZONTAL: bHorizontal = true; break;
+ default: OSL_ENSURE( false, "ControlConverter::convertAxOrientation - unknown orientation" );
+ }
+ convertOrientation( rPropMap, bHorizontal );
+}
+
+// ============================================================================
+
+ControlModelBase::ControlModelBase() :
+ maSize( 0, 0 ),
+ mbAwtModel( false )
+{
+}
+
+ControlModelBase::~ControlModelBase()
+{
+}
+
+OUString ControlModelBase::getServiceName() const
+{
+ ApiControlType eCtrlType = getControlType();
+ if( mbAwtModel ) switch( eCtrlType )
+ {
+ case API_CONTROL_BUTTON: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlButtonModel" );
+ case API_CONTROL_FIXEDTEXT: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlFixedTextModel" );
+ case API_CONTROL_IMAGE: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlImageControlModel" );
+ case API_CONTROL_CHECKBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlCheckBoxModel" );
+ case API_CONTROL_RADIOBUTTON: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlRadioButtonModel" );
+ case API_CONTROL_EDIT: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlEditModel" );
+ case API_CONTROL_NUMERIC: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlNumericFieldModel" );
+ case API_CONTROL_LISTBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlListBoxModel" );
+ case API_CONTROL_COMBOBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlComboBoxModel" );
+ case API_CONTROL_SPINBUTTON: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlSpinButtonModel" );
+ case API_CONTROL_SCROLLBAR: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlScrollBarModel" );
+ case API_CONTROL_PROGRESSBAR: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlProgressBarModel" );
+ case API_CONTROL_GROUPBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlGroupBoxModel" );
+ case API_CONTROL_DIALOG: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlDialogModel" );
+ default: OSL_ENSURE( false, "ControlModelBase::getServiceName - no AWT model service supported" );
+ }
+ else switch( eCtrlType )
+ {
+ case API_CONTROL_BUTTON: return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" );
+ case API_CONTROL_FIXEDTEXT: return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" );
+ case API_CONTROL_IMAGE: return CREATE_OUSTRING( "com.sun.star.form.component.DatabaseImageControl" );
+ case API_CONTROL_CHECKBOX: return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" );
+ case API_CONTROL_RADIOBUTTON: return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
+ case API_CONTROL_EDIT: return CREATE_OUSTRING( "com.sun.star.form.component.TextField" );
+ case API_CONTROL_NUMERIC: return CREATE_OUSTRING( "com.sun.star.form.component.NumericField" );
+ case API_CONTROL_LISTBOX: return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
+ case API_CONTROL_COMBOBOX: return CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" );
+ case API_CONTROL_SPINBUTTON: return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
+ case API_CONTROL_SCROLLBAR: return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
+ case API_CONTROL_GROUPBOX: return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
+ default: OSL_ENSURE( false, "ControlModelBase::getServiceName - no form component service supported" );
+ }
+ return OUString();
+}
+
+void ControlModelBase::importProperty( sal_Int32 /*nPropId*/, const OUString& /*rValue*/ )
+{
+}
+
+void ControlModelBase::importPictureData( sal_Int32 /*nPropId*/, BinaryInputStream& /*rInStrm*/ )
+{
+}
+
+void ControlModelBase::convertProperties( PropertyMap& /*rPropMap*/, const ControlConverter& /*rConv*/ ) const
+{
+}
+
+void ControlModelBase::convertSize( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rConv.convertSize( rPropMap, maSize );
+}
+
+// ============================================================================
+
+ComCtlModelBase::ComCtlModelBase( sal_uInt32 nDataPartId5, sal_uInt32 nDataPartId6,
+ sal_uInt16 nVersion, bool bCommonPart, bool bComplexPart ) :
+ maFontData( CREATE_OUSTRING( "Tahoma" ), 82500 ),
+ mnFlags( 0 ),
+ mnVersion( nVersion ),
+ mnDataPartId5( nDataPartId5 ),
+ mnDataPartId6( nDataPartId6 ),
+ mbCommonPart( bCommonPart ),
+ mbComplexPart( bComplexPart )
+{
+}
+
+bool ComCtlModelBase::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ // read initial size part and header of the control data part
+ if( importSizePart( rInStrm ) && readPartHeader( rInStrm, getDataPartId(), mnVersion ) )
+ {
+ // if flags part exists, the first int32 of the data part contains its size
+ sal_uInt32 nCommonPartSize = mbCommonPart ? rInStrm.readuInt32() : 0;
+ // implementations must read the exact amount of data, stream must point to its end afterwards
+ importControlData( rInStrm );
+ // read following parts
+ if( !rInStrm.isEof() &&
+ (!mbCommonPart || importCommonPart( rInStrm, nCommonPartSize )) &&
+ (!mbComplexPart || importComplexPart( rInStrm )) )
+ {
+ return !rInStrm.isEof();
+ }
+ }
+ return false;
+}
+
+void ComCtlModelBase::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ if( mbCommonPart )
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, COMCTL_COMMON_ENABLED ) );
+ ControlModelBase::convertProperties( rPropMap, rConv );
+}
+
+void ComCtlModelBase::importCommonExtraData( BinaryInputStream& /*rInStrm*/ )
+{
+}
+
+void ComCtlModelBase::importCommonTrailingData( BinaryInputStream& /*rInStrm*/ )
+{
+}
+
+sal_uInt32 ComCtlModelBase::getDataPartId() const
+{
+ switch( mnVersion )
+ {
+ case COMCTL_VERSION_50: return mnDataPartId5;
+ case COMCTL_VERSION_60: return mnDataPartId6;
+ }
+ OSL_ENSURE( false, "ComCtlObjectBase::getDataPartId - unxpected version" );
+ return SAL_MAX_UINT32;
+}
+
+bool ComCtlModelBase::readPartHeader( BinaryInputStream& rInStrm, sal_uInt32 nExpPartId, sal_uInt16 nExpMajor, sal_uInt16 nExpMinor )
+{
+ // no idea if all this is correct...
+ sal_uInt32 nPartId;
+ sal_uInt16 nMajor, nMinor;
+ rInStrm >> nPartId >> nMinor >> nMajor;
+ bool bPartId = nPartId == nExpPartId;
+ OSL_ENSURE( bPartId, "ComCtlObjectBase::readPartHeader - unexpected part identifier" );
+ bool bVersion = ((nExpMajor == SAL_MAX_UINT16) || (nExpMajor == nMajor)) && ((nExpMinor == SAL_MAX_UINT16) || (nExpMinor == nMinor));
+ OSL_ENSURE( bVersion, "ComCtlObjectBase::readPartHeader - unexpected part version" );
+ return !rInStrm.isEof() && bPartId && bVersion;
+}
+
+bool ComCtlModelBase::importSizePart( BinaryInputStream& rInStrm )
+{
+ if( readPartHeader( rInStrm, COMCTL_ID_SIZE, 0, 8 ) )
+ {
+ rInStrm >> maSize.first >> maSize.second;
+ return !rInStrm.isEof();
+ }
+ return false;
+}
+
+bool ComCtlModelBase::importCommonPart( BinaryInputStream& rInStrm, sal_uInt32 nPartSize )
+{
+ sal_Int64 nEndPos = rInStrm.tell() + nPartSize;
+ if( (nPartSize >= 16) && readPartHeader( rInStrm, COMCTL_ID_COMMONDATA, 5, 0 ) )
+ {
+ rInStrm.skip( 4 );
+ rInStrm >> mnFlags;
+ // implementations may read less than the exact amount of data
+ importCommonExtraData( rInStrm );
+ rInStrm.seek( nEndPos );
+ // implementations must read the exact amount of data, stream must point to its end afterwards
+ importCommonTrailingData( rInStrm );
+ return !rInStrm.isEof();
+ }
+ return false;
+}
+
+bool ComCtlModelBase::importComplexPart( BinaryInputStream& rInStrm )
+{
+ if( readPartHeader( rInStrm, COMCTL_ID_COMPLEXDATA, 5, 1 ) )
+ {
+ sal_uInt32 nContFlags;
+ rInStrm >> nContFlags;
+ bool bReadOk =
+ (!getFlag( nContFlags, COMCTL_COMPLEX_FONT ) || OleHelper::importStdFont( maFontData, rInStrm, true )) &&
+ (!getFlag( nContFlags, COMCTL_COMPLEX_MOUSEICON ) || OleHelper::importStdPic( maMouseIcon, rInStrm, true ));
+ return bReadOk && !rInStrm.isEof();
+ }
+ return false;
+}
+
+// ============================================================================
+
+ComCtlScrollBarModel::ComCtlScrollBarModel( sal_uInt16 nVersion ) :
+ ComCtlModelBase( SAL_MAX_UINT32, COMCTL_ID_SCROLLBAR_60, nVersion, true, true ),
+ mnScrollBarFlags( 0x00000011 ),
+ mnLargeChange( 1 ),
+ mnSmallChange( 1 ),
+ mnMin( 0 ),
+ mnMax( 32767 ),
+ mnPosition( 0 )
+{
+}
+
+ApiControlType ComCtlScrollBarModel::getControlType() const
+{
+ return API_CONTROL_SCROLLBAR;
+}
+
+void ComCtlScrollBarModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Border, API_BORDER_NONE );
+ rConv.convertOrientation( rPropMap, getFlag( mnScrollBarFlags, COMCTL_SCROLLBAR_HOR ) );
+ rConv.convertScrollBar( rPropMap, mnMin, mnMax, mnPosition, mnSmallChange, mnLargeChange, mbAwtModel );
+ ComCtlModelBase::convertProperties( rPropMap, rConv );
+}
+
+void ComCtlScrollBarModel::importControlData( BinaryInputStream& rInStrm )
+{
+ rInStrm >> mnScrollBarFlags >> mnLargeChange >> mnSmallChange >> mnMin >> mnMax >> mnPosition;
+}
+
+// ============================================================================
+
+ComCtlProgressBarModel::ComCtlProgressBarModel( sal_uInt16 nVersion ) :
+ ComCtlModelBase( COMCTL_ID_PROGRESSBAR_50, COMCTL_ID_PROGRESSBAR_60, nVersion, true, true ),
+ mfMin( 0.0 ),
+ mfMax( 100.0 ),
+ mnVertical( 0 ),
+ mnSmooth( 0 )
+{
+}
+
+ApiControlType ComCtlProgressBarModel::getControlType() const
+{
+ return API_CONTROL_PROGRESSBAR;
+}
+
+void ComCtlProgressBarModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ sal_uInt16 nBorder = getFlag( mnFlags, COMCTL_COMMON_3DBORDER ) ? API_BORDER_SUNKEN :
+ (getFlag( mnFlags, COMCTL_COMMON_FLATBORDER ) ? API_BORDER_FLAT : API_BORDER_NONE);
+ rPropMap.setProperty( PROP_Border, nBorder );
+ rPropMap.setProperty( PROP_ProgressValueMin, getLimitedValue< sal_Int32, double >( ::std::min( mfMin, mfMax ), 0.0, SAL_MAX_INT32 ) );
+ rPropMap.setProperty( PROP_ProgressValueMax, getLimitedValue< sal_Int32, double >( ::std::max( mfMin, mfMax ), 0.0, SAL_MAX_INT32 ) );
+ // ComCtl model does not provide current value?
+ ComCtlModelBase::convertProperties( rPropMap, rConv );
+}
+
+void ComCtlProgressBarModel::importControlData( BinaryInputStream& rInStrm )
+{
+ rInStrm >> mfMin >> mfMax;
+ if( mnVersion == COMCTL_VERSION_60 )
+ rInStrm >> mnVertical >> mnSmooth;
+}
+
+// ============================================================================
+
+AxControlModelBase::AxControlModelBase()
+{
+}
+
+void AxControlModelBase::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ // size of the control shape: format is "width;height"
+ case XML_Size:
+ {
+ sal_Int32 nSepPos = rValue.indexOf( ';' );
+ OSL_ENSURE( nSepPos >= 0, "AxControlModelBase::importProperty - missing separator in 'Size' property" );
+ if( nSepPos >= 0 )
+ {
+ maSize.first = rValue.copy( 0, nSepPos ).toInt32();
+ maSize.second = rValue.copy( nSepPos + 1 ).toInt32();
+ }
+ }
+ break;
+ }
+}
+
+// ============================================================================
+
+AxFontDataModel::AxFontDataModel( bool bSupportsAlign ) :
+ mbSupportsAlign( bSupportsAlign )
+{
+}
+
+void AxFontDataModel::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_FontName: maFontData.maFontName = rValue; break;
+ case XML_FontEffects: maFontData.mnFontEffects = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_FontHeight: maFontData.mnFontHeight = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_FontCharSet: maFontData.mnFontCharSet = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_ParagraphAlign: maFontData.mnHorAlign = AttributeConversion::decodeInteger( rValue ); break;
+ default: AxControlModelBase::importProperty( nPropId, rValue );
+ }
+}
+
+bool AxFontDataModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ return maFontData.importBinaryModel( rInStrm );
+}
+
+void AxFontDataModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ // font name
+ if( maFontData.maFontName.getLength() > 0 )
+ rPropMap.setProperty( PROP_FontName, maFontData.maFontName );
+
+ // font effects
+ rPropMap.setProperty( PROP_FontWeight, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_BOLD, FontWeight::BOLD, FontWeight::NORMAL ) );
+ rPropMap.setProperty( PROP_FontSlant, getFlagValue< sal_Int16 >( maFontData.mnFontEffects, AX_FONTDATA_ITALIC, FontSlant_ITALIC, FontSlant_NONE ) );
+ rPropMap.setProperty( PROP_FontUnderline, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_UNDERLINE, maFontData.mbDblUnderline ? FontUnderline::DOUBLE : FontUnderline::SINGLE, FontUnderline::NONE ) );
+ rPropMap.setProperty( PROP_FontStrikeout, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_STRIKEOUT, FontStrikeout::SINGLE, FontStrikeout::NONE ) );
+ rPropMap.setProperty( PROP_FontHeight, maFontData.getHeightPoints() );
+
+ // font character set
+ rtl_TextEncoding eFontEnc = RTL_TEXTENCODING_DONTKNOW;
+ if( (0 <= maFontData.mnFontCharSet) && (maFontData.mnFontCharSet <= SAL_MAX_UINT8) )
+ eFontEnc = rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maFontData.mnFontCharSet ) );
+ if( eFontEnc != RTL_TEXTENCODING_DONTKNOW )
+ rPropMap.setProperty( PROP_FontCharset, static_cast< sal_Int16 >( eFontEnc ) );
+
+ // text alignment
+ if( mbSupportsAlign )
+ {
+ sal_Int32 nAlign = TextAlign::LEFT;
+ switch( maFontData.mnHorAlign )
+ {
+ case AX_FONTDATA_LEFT: nAlign = TextAlign::LEFT; break;
+ case AX_FONTDATA_RIGHT: nAlign = TextAlign::RIGHT; break;
+ case AX_FONTDATA_CENTER: nAlign = TextAlign::CENTER; break;
+ default: OSL_ENSURE( false, "AxFontDataModel::convertProperties - unknown text alignment" );
+ }
+ // form controls expect short value
+ rPropMap.setProperty( PROP_Align, static_cast< sal_Int16 >( nAlign ) );
+ }
+
+ // process base class properties
+ AxControlModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxCommandButtonModel::AxCommandButtonModel() :
+ mnTextColor( AX_SYSCOLOR_BUTTONTEXT ),
+ mnBackColor( AX_SYSCOLOR_BUTTONFACE ),
+ mnFlags( AX_CMDBUTTON_DEFFLAGS ),
+ mnPicturePos( AX_PICPOS_ABOVECENTER ),
+ mnVerticalAlign( XML_Center ),
+ mbFocusOnClick( true )
+{
+}
+
+void AxCommandButtonModel::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_Caption: maCaption = rValue; break;
+ case XML_ForeColor: mnTextColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_PicturePosition: mnPicturePos = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_TakeFocusOnClick: mbFocusOnClick = AttributeConversion::decodeInteger( rValue ) != 0; break;
+ default: AxFontDataModel::importProperty( nPropId, rValue );
+ }
+}
+
+void AxCommandButtonModel::importPictureData( sal_Int32 nPropId, BinaryInputStream& rInStrm )
+{
+ switch( nPropId )
+ {
+ case XML_Picture: OleHelper::importStdPic( maPictureData, rInStrm, true ); break;
+ default: AxFontDataModel::importPictureData( nPropId, rInStrm );
+ }
+}
+
+bool AxCommandButtonModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readIntProperty< sal_uInt32 >( mnTextColor );
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.readStringProperty( maCaption );
+ aReader.readIntProperty< sal_uInt32 >( mnPicturePos );
+ aReader.readPairProperty( maSize );
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ aReader.readPictureProperty( maPictureData );
+ aReader.skipIntProperty< sal_uInt16 >(); // accelerator
+ aReader.readBoolProperty( mbFocusOnClick, true ); // binary flag means "do not take focus"
+ aReader.skipPictureProperty(); // mouse icon
+ return aReader.finalizeImport() && AxFontDataModel::importBinaryModel( rInStrm );
+}
+
+ApiControlType AxCommandButtonModel::getControlType() const
+{
+ return API_CONTROL_BUTTON;
+}
+
+void AxCommandButtonModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Label, maCaption );
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) );
+ rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) );
+ rPropMap.setProperty( PROP_FocusOnClick, mbFocusOnClick );
+ rConv.convertColor( rPropMap, PROP_TextColor, mnTextColor );
+ rConv.convertVerticalAlign( rPropMap, mnVerticalAlign );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_NOTSUPPORTED );
+ rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos );
+ AxFontDataModel::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxLabelModel::AxLabelModel() :
+ mnTextColor( AX_SYSCOLOR_BUTTONTEXT ),
+ mnBackColor( AX_SYSCOLOR_BUTTONFACE ),
+ mnFlags( AX_LABEL_DEFFLAGS ),
+ mnBorderColor( AX_SYSCOLOR_WINDOWFRAME ),
+ mnBorderStyle( AX_BORDERSTYLE_NONE ),
+ mnSpecialEffect( AX_SPECIALEFFECT_FLAT ),
+ mnVerticalAlign( XML_Top )
+{
+}
+
+void AxLabelModel::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_Caption: maCaption = rValue; break;
+ case XML_ForeColor: mnTextColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BorderColor: mnBorderColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BorderStyle: mnBorderStyle = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_SpecialEffect: mnSpecialEffect = AttributeConversion::decodeInteger( rValue ); break;
+ default: AxFontDataModel::importProperty( nPropId, rValue );
+ }
+}
+
+bool AxLabelModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readIntProperty< sal_uInt32 >( mnTextColor );
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.readStringProperty( maCaption );
+ aReader.skipIntProperty< sal_uInt32 >(); // picture position
+ aReader.readPairProperty( maSize );
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ aReader.readIntProperty< sal_uInt32 >( mnBorderColor );
+ aReader.readIntProperty< sal_uInt16 >( mnBorderStyle );
+ aReader.readIntProperty< sal_uInt16 >( mnSpecialEffect );
+ aReader.skipPictureProperty(); // picture
+ aReader.skipIntProperty< sal_uInt16 >(); // accelerator
+ aReader.skipPictureProperty(); // mouse icon
+ return aReader.finalizeImport() && AxFontDataModel::importBinaryModel( rInStrm );
+}
+
+ApiControlType AxLabelModel::getControlType() const
+{
+ return API_CONTROL_FIXEDTEXT;
+}
+
+void AxLabelModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Label, maCaption );
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) );
+ rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) );
+ rConv.convertColor( rPropMap, PROP_TextColor, mnTextColor );
+ rConv.convertVerticalAlign( rPropMap, mnVerticalAlign );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect );
+ AxFontDataModel::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxImageModel::AxImageModel() :
+ mnBackColor( AX_SYSCOLOR_BUTTONFACE ),
+ mnFlags( AX_IMAGE_DEFFLAGS ),
+ mnBorderColor( AX_SYSCOLOR_WINDOWFRAME ),
+ mnBorderStyle( AX_BORDERSTYLE_SINGLE ),
+ mnSpecialEffect( AX_SPECIALEFFECT_FLAT ),
+ mnPicSizeMode( AX_PICSIZE_CLIP ),
+ mnPicAlign( AX_PICALIGN_CENTER ),
+ mbPicTiling( false )
+{
+}
+
+void AxImageModel::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BorderColor: mnBorderColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BorderStyle: mnBorderStyle = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_SpecialEffect: mnSpecialEffect = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_SizeMode: mnPicSizeMode = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_PictureAlignment: mnPicAlign = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_PictureTiling: mbPicTiling = AttributeConversion::decodeInteger( rValue ) != 0; break;
+ default: AxControlModelBase::importProperty( nPropId, rValue );
+ }
+}
+
+void AxImageModel::importPictureData( sal_Int32 nPropId, BinaryInputStream& rInStrm )
+{
+ switch( nPropId )
+ {
+ case XML_Picture: OleHelper::importStdPic( maPictureData, rInStrm, true ); break;
+ default: AxControlModelBase::importPictureData( nPropId, rInStrm );
+ }
+}
+
+bool AxImageModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.skipUndefinedProperty();
+ aReader.skipUndefinedProperty();
+ aReader.skipBoolProperty(); // auto-size
+ aReader.readIntProperty< sal_uInt32 >( mnBorderColor );
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt8 >( mnBorderStyle );
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ aReader.readIntProperty< sal_uInt8 >( mnPicSizeMode );
+ aReader.readIntProperty< sal_uInt8 >( mnSpecialEffect );
+ aReader.readPairProperty( maSize );
+ aReader.readPictureProperty( maPictureData );
+ aReader.readIntProperty< sal_uInt8 >( mnPicAlign );
+ aReader.readBoolProperty( mbPicTiling );
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.skipPictureProperty(); // mouse icon
+ return aReader.finalizeImport();
+}
+
+ApiControlType AxImageModel::getControlType() const
+{
+ return API_CONTROL_IMAGE;
+}
+
+void AxImageModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect );
+ rConv.convertAxPicture( rPropMap, maPictureData, mnPicSizeMode, mnPicAlign, mbPicTiling );
+ AxControlModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxMorphDataModelBase::AxMorphDataModelBase() :
+ mnTextColor( AX_SYSCOLOR_WINDOWTEXT ),
+ mnBackColor( AX_SYSCOLOR_WINDOWBACK ),
+ mnFlags( AX_MORPHDATA_DEFFLAGS ),
+ mnPicturePos( AX_PICPOS_ABOVECENTER ),
+ mnBorderColor( AX_SYSCOLOR_WINDOWFRAME ),
+ mnBorderStyle( AX_BORDERSTYLE_NONE ),
+ mnSpecialEffect( AX_SPECIALEFFECT_SUNKEN ),
+ mnDisplayStyle( AX_DISPLAYSTYLE_TEXT ),
+ mnMultiSelect( AX_SELCTION_SINGLE ),
+ mnScrollBars( AX_SCROLLBAR_NONE ),
+ mnMatchEntry( AX_MATCHENTRY_NONE ),
+ mnShowDropButton( AX_SHOWDROPBUTTON_NEVER ),
+ mnMaxLength( 0 ),
+ mnPasswordChar( 0 ),
+ mnListRows( 8 ),
+ mnVerticalAlign( XML_Center )
+{
+}
+
+void AxMorphDataModelBase::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_Caption: maCaption = rValue; break;
+ case XML_Value: maValue = rValue; break;
+ case XML_GroupName: maGroupName = rValue; break;
+ case XML_ForeColor: mnTextColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_PicturePosition: mnPicturePos = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BorderColor: mnBorderColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BorderStyle: mnBorderStyle = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_SpecialEffect: mnSpecialEffect = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_DisplayStyle: mnDisplayStyle = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_MultiSelect: mnMultiSelect = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_ScrollBars: mnScrollBars = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_MatchEntry: mnMatchEntry = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_ShowDropButtonWhen: mnShowDropButton = AttributeConversion::decodeInteger( rValue );break;
+ case XML_MaxLength: mnMaxLength = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_PasswordChar: mnPasswordChar = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_ListRows: mnListRows = AttributeConversion::decodeInteger( rValue ); break;
+ default: AxFontDataModel::importProperty( nPropId, rValue );
+ }
+}
+
+void AxMorphDataModelBase::importPictureData( sal_Int32 nPropId, BinaryInputStream& rInStrm )
+{
+ switch( nPropId )
+ {
+ case XML_Picture: OleHelper::importStdPic( maPictureData, rInStrm, true ); break;
+ default: AxFontDataModel::importPictureData( nPropId, rInStrm );
+ }
+}
+
+bool AxMorphDataModelBase::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm, true );
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt32 >( mnTextColor );
+ aReader.readIntProperty< sal_Int32 >( mnMaxLength );
+ aReader.readIntProperty< sal_uInt8 >( mnBorderStyle );
+ aReader.readIntProperty< sal_uInt8 >( mnScrollBars );
+ aReader.readIntProperty< sal_uInt8 >( mnDisplayStyle );
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ aReader.readPairProperty( maSize );
+ aReader.readIntProperty< sal_uInt16 >( mnPasswordChar );
+ aReader.skipIntProperty< sal_uInt32 >(); // list width
+ aReader.skipIntProperty< sal_uInt16 >(); // bound column
+ aReader.skipIntProperty< sal_Int16 >(); // text column
+ aReader.skipIntProperty< sal_Int16 >(); // column count
+ aReader.readIntProperty< sal_uInt16 >( mnListRows );
+ aReader.skipIntProperty< sal_uInt16 >(); // column info count
+ aReader.readIntProperty< sal_uInt8 >( mnMatchEntry );
+ aReader.skipIntProperty< sal_uInt8 >(); // list style
+ aReader.readIntProperty< sal_uInt8 >( mnShowDropButton );
+ aReader.skipUndefinedProperty();
+ aReader.skipIntProperty< sal_uInt8 >(); // drop down style
+ aReader.readIntProperty< sal_uInt8 >( mnMultiSelect );
+ aReader.readStringProperty( maValue );
+ aReader.readStringProperty( maCaption );
+ aReader.readIntProperty< sal_uInt32 >( mnPicturePos );
+ aReader.readIntProperty< sal_uInt32 >( mnBorderColor );
+ aReader.readIntProperty< sal_uInt32 >( mnSpecialEffect );
+ aReader.skipPictureProperty(); // mouse icon
+ aReader.readPictureProperty( maPictureData );
+ aReader.skipIntProperty< sal_uInt16 >(); // accelerator
+ aReader.skipUndefinedProperty();
+ aReader.skipBoolProperty();
+ aReader.readStringProperty( maGroupName );
+ return aReader.finalizeImport() && AxFontDataModel::importBinaryModel( rInStrm );
+}
+
+void AxMorphDataModelBase::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) );
+ rConv.convertColor( rPropMap, PROP_TextColor, mnTextColor );
+ AxFontDataModel::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxToggleButtonModel::AxToggleButtonModel()
+{
+ mnDisplayStyle = AX_DISPLAYSTYLE_TOGGLE;
+}
+
+ApiControlType AxToggleButtonModel::getControlType() const
+{
+ OSL_ENSURE( mnDisplayStyle == AX_DISPLAYSTYLE_TOGGLE, "AxToggleButtonModel::getControlType - invalid control type" );
+ return API_CONTROL_BUTTON;
+}
+
+void AxToggleButtonModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Label, maCaption );
+ rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) );
+ rPropMap.setProperty( PROP_Toggle, true );
+ rConv.convertVerticalAlign( rPropMap, mnVerticalAlign );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_NOTSUPPORTED );
+ rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos );
+ rConv.convertAxState( rPropMap, maValue, mnMultiSelect, API_DEFAULTSTATE_BOOLEAN, mbAwtModel );
+ AxMorphDataModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxCheckBoxModel::AxCheckBoxModel()
+{
+ mnDisplayStyle = AX_DISPLAYSTYLE_CHECKBOX;
+}
+
+ApiControlType AxCheckBoxModel::getControlType() const
+{
+ OSL_ENSURE( mnDisplayStyle == AX_DISPLAYSTYLE_CHECKBOX, "AxCheckBoxModel::getControlType - invalid control type" );
+ return API_CONTROL_CHECKBOX;
+}
+
+void AxCheckBoxModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Label, maCaption );
+ rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) );
+ rConv.convertVerticalAlign( rPropMap, mnVerticalAlign );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxVisualEffect( rPropMap, mnSpecialEffect );
+ rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos );
+ rConv.convertAxState( rPropMap, maValue, mnMultiSelect, API_DEFAULTSTATE_TRISTATE, mbAwtModel );
+ AxMorphDataModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxOptionButtonModel::AxOptionButtonModel()
+{
+ mnDisplayStyle = AX_DISPLAYSTYLE_OPTBUTTON;
+}
+
+ApiControlType AxOptionButtonModel::getControlType() const
+{
+ OSL_ENSURE( mnDisplayStyle == AX_DISPLAYSTYLE_OPTBUTTON, "AxOptionButtonModel::getControlType - invalid control type" );
+ return API_CONTROL_RADIOBUTTON;
+}
+
+void AxOptionButtonModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Label, maCaption );
+ rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) );
+ rConv.convertVerticalAlign( rPropMap, mnVerticalAlign );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxVisualEffect( rPropMap, mnSpecialEffect );
+ rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos );
+ rConv.convertAxState( rPropMap, maValue, mnMultiSelect, API_DEFAULTSTATE_SHORT, mbAwtModel );
+ AxMorphDataModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxTextBoxModel::AxTextBoxModel()
+{
+ mnDisplayStyle = AX_DISPLAYSTYLE_TEXT;
+}
+
+ApiControlType AxTextBoxModel::getControlType() const
+{
+ OSL_ENSURE( mnDisplayStyle == AX_DISPLAYSTYLE_TEXT, "AxTextBoxModel::getControlType - invalid control type" );
+ return API_CONTROL_EDIT;
+}
+
+void AxTextBoxModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_MULTILINE ) );
+ rPropMap.setProperty( PROP_HideInactiveSelection, getFlag( mnFlags, AX_FLAGS_HIDESELECTION ) );
+ rPropMap.setProperty( mbAwtModel ? PROP_Text : PROP_DefaultText, maValue );
+ rPropMap.setProperty( PROP_MaxTextLen, getLimitedValue< sal_Int16, sal_Int32 >( mnMaxLength, 0, SAL_MAX_INT16 ) );
+ if( (0 < mnPasswordChar) && (mnPasswordChar <= SAL_MAX_INT16) )
+ rPropMap.setProperty( PROP_EchoChar, static_cast< sal_Int16 >( mnPasswordChar ) );
+ rPropMap.setProperty( PROP_HScroll, getFlag( mnScrollBars, AX_SCROLLBAR_HORIZONTAL ) );
+ rPropMap.setProperty( PROP_VScroll, getFlag( mnScrollBars, AX_SCROLLBAR_VERTICAL ) );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect );
+ AxMorphDataModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxNumericFieldModel::AxNumericFieldModel()
+{
+ mnDisplayStyle = AX_DISPLAYSTYLE_TEXT;
+}
+
+ApiControlType AxNumericFieldModel::getControlType() const
+{
+ OSL_ENSURE( mnDisplayStyle == AX_DISPLAYSTYLE_TEXT, "AxNumericFieldModel::getControlType - invalid control type" );
+ return API_CONTROL_NUMERIC;
+}
+
+void AxNumericFieldModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_HideInactiveSelection, getFlag( mnFlags, AX_FLAGS_HIDESELECTION ) );
+ // TODO: OUString::toDouble() does not handle local decimal separator
+ rPropMap.setProperty( mbAwtModel ? PROP_Value : PROP_DefaultValue, maValue.toDouble() );
+ rPropMap.setProperty( PROP_Spin, getFlag( mnScrollBars, AX_SCROLLBAR_VERTICAL ) );
+ rPropMap.setProperty( PROP_Repeat, true );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect );
+ AxMorphDataModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxListBoxModel::AxListBoxModel()
+{
+ mnDisplayStyle = AX_DISPLAYSTYLE_LISTBOX;
+}
+
+ApiControlType AxListBoxModel::getControlType() const
+{
+ OSL_ENSURE( mnDisplayStyle == AX_DISPLAYSTYLE_LISTBOX, "AxListBoxModel::getControlType - invalid control type" );
+ return API_CONTROL_LISTBOX;
+}
+
+void AxListBoxModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ bool bMultiSelect = (mnMultiSelect == AX_SELCTION_MULTI) || (mnMultiSelect == AX_SELCTION_EXTENDED);
+ rPropMap.setProperty( PROP_MultiSelection, bMultiSelect );
+ rPropMap.setProperty( PROP_Dropdown, false );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect );
+ AxMorphDataModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxComboBoxModel::AxComboBoxModel()
+{
+ mnDisplayStyle = AX_DISPLAYSTYLE_COMBOBOX;
+}
+
+ApiControlType AxComboBoxModel::getControlType() const
+{
+ OSL_ENSURE( (mnDisplayStyle == AX_DISPLAYSTYLE_COMBOBOX) || (mnDisplayStyle == AX_DISPLAYSTYLE_DROPDOWN), "AxComboBoxModel::getControlType - invalid control type" );
+ return (mnDisplayStyle == AX_DISPLAYSTYLE_DROPDOWN) ? API_CONTROL_LISTBOX : API_CONTROL_COMBOBOX;
+}
+
+void AxComboBoxModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ if( mnDisplayStyle != AX_DISPLAYSTYLE_DROPDOWN )
+ {
+ rPropMap.setProperty( PROP_HideInactiveSelection, getFlag( mnFlags, AX_FLAGS_HIDESELECTION ) );
+ rPropMap.setProperty( mbAwtModel ? PROP_Text : PROP_DefaultText, maValue );
+ rPropMap.setProperty( PROP_MaxTextLen, getLimitedValue< sal_Int16, sal_Int32 >( mnMaxLength, 0, SAL_MAX_INT16 ) );
+ bool bAutoComplete = (mnMatchEntry == AX_MATCHENTRY_FIRSTLETTER) || (mnMatchEntry == AX_MATCHENTRY_COMPLETE);
+ rPropMap.setProperty( PROP_Autocomplete, bAutoComplete );
+ }
+ bool bShowDropdown = (mnShowDropButton == AX_SHOWDROPBUTTON_FOCUS) || (mnShowDropButton == AX_SHOWDROPBUTTON_ALWAYS);
+ rPropMap.setProperty( PROP_Dropdown, bShowDropdown );
+ rPropMap.setProperty( PROP_LineCount, getLimitedValue< sal_Int16, sal_Int32 >( mnListRows, 1, SAL_MAX_INT16 ) );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID );
+ rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect );
+ AxMorphDataModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxSpinButtonModel::AxSpinButtonModel() :
+ mnArrowColor( AX_SYSCOLOR_BUTTONTEXT ),
+ mnBackColor( AX_SYSCOLOR_BUTTONFACE ),
+ mnFlags( AX_SPINBUTTON_DEFFLAGS ),
+ mnOrientation( AX_ORIENTATION_AUTO ),
+ mnMin( 0 ),
+ mnMax( 100 ),
+ mnPosition( 0 ),
+ mnSmallChange( 1 ),
+ mnDelay( 50 )
+{
+}
+
+ApiControlType AxSpinButtonModel::getControlType() const
+{
+ return API_CONTROL_SPINBUTTON;
+}
+
+void AxSpinButtonModel::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_ForeColor: mnArrowColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_Orientation: mnOrientation = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Min: mnMin = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Max: mnMax = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Position: mnPosition = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_SmallChange: mnSmallChange = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Delay: mnDelay = AttributeConversion::decodeInteger( rValue ); break;
+ default: AxControlModelBase::importProperty( nPropId, rValue );
+ }
+}
+
+bool AxSpinButtonModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readIntProperty< sal_uInt32 >( mnArrowColor );
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.readPairProperty( maSize );
+ aReader.skipIntProperty< sal_uInt32 >(); // unused
+ aReader.readIntProperty< sal_Int32 >( mnMin );
+ aReader.readIntProperty< sal_Int32 >( mnMax );
+ aReader.readIntProperty< sal_Int32 >( mnPosition );
+ aReader.skipIntProperty< sal_uInt32 >(); // prev enabled
+ aReader.skipIntProperty< sal_uInt32 >(); // next enabled
+ aReader.readIntProperty< sal_Int32 >( mnSmallChange );
+ aReader.readIntProperty< sal_Int32 >( mnOrientation );
+ aReader.readIntProperty< sal_Int32 >( mnDelay );
+ aReader.skipPictureProperty(); // mouse icon
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ return aReader.finalizeImport();
+}
+
+void AxSpinButtonModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ sal_Int32 nMin = ::std::min( mnMin, mnMax );
+ sal_Int32 nMax = ::std::max( mnMin, mnMax );
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) );
+ rPropMap.setProperty( PROP_SpinValueMin, nMin );
+ rPropMap.setProperty( PROP_SpinValueMax, nMax );
+ rPropMap.setProperty( PROP_SpinIncrement, mnSmallChange );
+ rPropMap.setProperty( mbAwtModel ? PROP_SpinValue : PROP_DefaultSpinValue, mnPosition );
+ rPropMap.setProperty( PROP_Repeat, true );
+ rPropMap.setProperty( PROP_RepeatDelay, mnDelay );
+ rPropMap.setProperty( PROP_Border, API_BORDER_NONE );
+ rConv.convertColor( rPropMap, PROP_SymbolColor, mnArrowColor );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_NOTSUPPORTED );
+ rConv.convertAxOrientation( rPropMap, maSize, mnOrientation );
+ AxControlModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxScrollBarModel::AxScrollBarModel() :
+ mnArrowColor( AX_SYSCOLOR_BUTTONTEXT ),
+ mnBackColor( AX_SYSCOLOR_BUTTONFACE ),
+ mnFlags( AX_SCROLLBAR_DEFFLAGS ),
+ mnOrientation( AX_ORIENTATION_AUTO ),
+ mnPropThumb( AX_PROPTHUMB_ON ),
+ mnMin( 0 ),
+ mnMax( 32767 ),
+ mnPosition( 0 ),
+ mnSmallChange( 1 ),
+ mnLargeChange( 1 ),
+ mnDelay( 50 )
+{
+}
+
+ApiControlType AxScrollBarModel::getControlType() const
+{
+ return API_CONTROL_SCROLLBAR;
+}
+
+void AxScrollBarModel::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_ForeColor: mnArrowColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break;
+ case XML_Orientation: mnOrientation = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_ProportionalThumb: mnPropThumb = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Min: mnMin = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Max: mnMax = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Position: mnPosition = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_SmallChange: mnSmallChange = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_LargeChange: mnLargeChange = AttributeConversion::decodeInteger( rValue ); break;
+ case XML_Delay: mnDelay = AttributeConversion::decodeInteger( rValue ); break;
+ default: AxControlModelBase::importProperty( nPropId, rValue );
+ }
+}
+
+bool AxScrollBarModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readIntProperty< sal_uInt32 >( mnArrowColor );
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.readPairProperty( maSize );
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ aReader.readIntProperty< sal_Int32 >( mnMin );
+ aReader.readIntProperty< sal_Int32 >( mnMax );
+ aReader.readIntProperty< sal_Int32 >( mnPosition );
+ aReader.skipIntProperty< sal_uInt32 >(); // unused
+ aReader.skipIntProperty< sal_uInt32 >(); // prev enabled
+ aReader.skipIntProperty< sal_uInt32 >(); // next enabled
+ aReader.readIntProperty< sal_Int32 >( mnSmallChange );
+ aReader.readIntProperty< sal_Int32 >( mnLargeChange );
+ aReader.readIntProperty< sal_Int32 >( mnOrientation );
+ aReader.readIntProperty< sal_Int16 >( mnPropThumb );
+ aReader.readIntProperty< sal_Int32 >( mnDelay );
+ aReader.skipPictureProperty(); // mouse icon
+ return aReader.finalizeImport();
+}
+
+void AxScrollBarModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) );
+ rPropMap.setProperty( PROP_RepeatDelay, mnDelay );
+ rPropMap.setProperty( PROP_Border, API_BORDER_NONE );
+ if( (mnPropThumb == AX_PROPTHUMB_ON) && (mnMin != mnMax) && (mnLargeChange > 0) )
+ {
+ // use double to prevent integer overflow in division (fInterval+mnLargeChange may become 0 when performed as int)
+ double fInterval = fabs( static_cast< double >( mnMax - mnMin ) );
+ sal_Int32 nThumbLen = getLimitedValue< sal_Int32, double >( (fInterval * mnLargeChange) / (fInterval + mnLargeChange), 1, SAL_MAX_INT32 );
+ rPropMap.setProperty( PROP_VisibleSize, nThumbLen );
+ }
+ rConv.convertColor( rPropMap, PROP_SymbolColor, mnArrowColor );
+ rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_NOTSUPPORTED );
+ rConv.convertAxOrientation( rPropMap, maSize, mnOrientation );
+ rConv.convertScrollBar( rPropMap, mnMin, mnMax, mnPosition, mnSmallChange, mnLargeChange, mbAwtModel );
+ AxControlModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxTabStripModel::AxTabStripModel() :
+ AxFontDataModel( false ), // no support for alignment properties
+ mnBackColor( AX_SYSCOLOR_BUTTONFACE ),
+ mnTextColor( AX_SYSCOLOR_BUTTONTEXT ),
+ mnFlags( AX_TABSTRIP_DEFFLAGS ),
+ mnSelectedTab( -1 ),
+ mnTabStyle( AX_TABSTRIP_TABS ),
+ mnTabFlagCount( 0 )
+{
+}
+
+bool AxTabStripModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readIntProperty< sal_Int32 >( mnSelectedTab );
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt32 >( mnTextColor );
+ aReader.skipUndefinedProperty();
+ aReader.readPairProperty( maSize );
+ aReader.readStringArrayProperty( maCaptions );
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ aReader.skipUndefinedProperty();
+ aReader.skipIntProperty< sal_uInt32 >(); // tab orientation
+ aReader.readIntProperty< sal_uInt32 >( mnTabStyle );
+ aReader.skipBoolProperty(); // multiple rows
+ aReader.skipIntProperty< sal_uInt32 >(); // fixed width
+ aReader.skipIntProperty< sal_uInt32 >(); // fixed height
+ aReader.skipBoolProperty(); // tooltips
+ aReader.skipUndefinedProperty();
+ aReader.skipStringArrayProperty(); // tooltip strings
+ aReader.skipUndefinedProperty();
+ aReader.skipStringArrayProperty(); // tab names
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.skipBoolProperty(); // new version
+ aReader.skipIntProperty< sal_uInt32 >(); // tabs allocated
+ aReader.skipStringArrayProperty(); // tags
+ aReader.readIntProperty< sal_uInt32 >( mnTabFlagCount );
+ aReader.skipStringArrayProperty(); // accelerators
+ aReader.skipPictureProperty(); // mouse icon
+ return aReader.finalizeImport() && AxFontDataModel::importBinaryModel( rInStrm );
+}
+
+ApiControlType AxTabStripModel::getControlType() const
+{
+ return API_CONTROL_TABSTRIP;
+}
+
+void AxTabStripModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Decoration, mnTabStyle != AX_TABSTRIP_NONE );
+ rPropMap.setProperty( PROP_MultiPageValue, mnSelectedTab );
+ rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor );
+ AxFontDataModel::convertProperties( rPropMap, rConv );
+}
+
+OUString AxTabStripModel::getCaption( sal_Int32 nIndex ) const
+{
+ return ContainerHelper::getVectorElement( maCaptions, nIndex, OUString() );
+}
+
+// ============================================================================
+
+AxContainerModelBase::AxContainerModelBase( bool bFontSupport ) :
+ AxFontDataModel( false ), // no support for alignment properties
+ maLogicalSize( AX_CONTAINER_DEFWIDTH, AX_CONTAINER_DEFHEIGHT ),
+ maScrollPos( 0, 0 ),
+ mnBackColor( AX_SYSCOLOR_BUTTONFACE ),
+ mnTextColor( AX_SYSCOLOR_BUTTONTEXT ),
+ mnFlags( AX_CONTAINER_DEFFLAGS ),
+ mnBorderColor( AX_SYSCOLOR_BUTTONTEXT ),
+ mnBorderStyle( AX_BORDERSTYLE_NONE ),
+ mnScrollBars( AX_CONTAINER_SCR_NONE ),
+ mnCycleType( AX_CONTAINER_CYCLEALL ),
+ mnSpecialEffect( AX_SPECIALEFFECT_FLAT ),
+ mnPicAlign( AX_PICALIGN_CENTER ),
+ mnPicSizeMode( AX_PICSIZE_CLIP ),
+ mbPicTiling( false ),
+ mbFontSupport( bFontSupport )
+{
+ setAwtModelMode();
+ // different default size for frame
+ maSize = AxPairData( AX_CONTAINER_DEFWIDTH, AX_CONTAINER_DEFHEIGHT );
+}
+
+void AxContainerModelBase::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ if( nPropId == XML_Caption )
+ maCaption = rValue;
+}
+
+bool AxContainerModelBase::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.skipUndefinedProperty();
+ aReader.readIntProperty< sal_uInt32 >( mnBackColor );
+ aReader.readIntProperty< sal_uInt32 >( mnTextColor );
+ aReader.skipIntProperty< sal_uInt32 >(); // next availbale control ID
+ aReader.skipUndefinedProperty();
+ aReader.skipUndefinedProperty();
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.readIntProperty< sal_uInt8 >( mnBorderStyle );
+ aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer
+ aReader.readIntProperty< sal_uInt8 >( mnScrollBars );
+ aReader.readPairProperty( maSize );
+ aReader.readPairProperty( maLogicalSize );
+ aReader.readPairProperty( maScrollPos );
+ aReader.skipIntProperty< sal_uInt32 >(); // number of control groups
+ aReader.skipUndefinedProperty();
+ aReader.skipPictureProperty(); // mouse icon
+ aReader.readIntProperty< sal_uInt8 >( mnCycleType );
+ aReader.readIntProperty< sal_uInt8 >( mnSpecialEffect );
+ aReader.readIntProperty< sal_uInt32 >( mnBorderColor );
+ aReader.readStringProperty( maCaption );
+ aReader.readFontProperty( maFontData );
+ aReader.readPictureProperty( maPictureData );
+ aReader.skipIntProperty< sal_Int32 >(); // zoom
+ aReader.readIntProperty< sal_uInt8 >( mnPicAlign );
+ aReader.readBoolProperty( mbPicTiling );
+ aReader.readIntProperty< sal_uInt8 >( mnPicSizeMode );
+ aReader.skipIntProperty< sal_uInt32 >(); // shape cookie
+ aReader.skipIntProperty< sal_uInt32 >(); // draw buffer size
+ return aReader.finalizeImport();
+}
+
+void AxContainerModelBase::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ if( mbFontSupport )
+ {
+ rConv.convertColor( rPropMap, PROP_TextColor, mnTextColor );
+ AxFontDataModel::convertProperties( rPropMap, rConv );
+ }
+}
+
+bool AxContainerModelBase::importClassTable( BinaryInputStream& rInStrm, AxClassTable& orClassTable )
+{
+ bool bValid = true;
+ orClassTable.clear();
+ if( !getFlag( mnFlags, AX_CONTAINER_NOCLASSTABLE ) )
+ {
+ sal_uInt16 nCount = rInStrm.readuInt16();
+ for( sal_uInt16 nIndex = 0; bValid && (nIndex < nCount); ++nIndex )
+ {
+ orClassTable.push_back( OUString() );
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readGuidProperty( orClassTable.back() );
+ aReader.skipGuidProperty(); // source interface GUID
+ aReader.skipUndefinedProperty();
+ aReader.skipGuidProperty(); // default interface GUID
+ aReader.skipIntProperty< sal_uInt32 >(); // class table and var flags
+ aReader.skipIntProperty< sal_uInt32 >(); // method count
+ aReader.skipIntProperty< sal_Int32 >(); // IDispatch identifier for linked cell access
+ aReader.skipIntProperty< sal_uInt16 >(); // get function index for linked cell access
+ aReader.skipIntProperty< sal_uInt16 >(); // put function index for linked cell access
+ aReader.skipIntProperty< sal_uInt16 >(); // linked cell access property type
+ aReader.skipIntProperty< sal_uInt16 >(); // get function index of value
+ aReader.skipIntProperty< sal_uInt16 >(); // put function index of value
+ aReader.skipIntProperty< sal_uInt16 >(); // value type
+ aReader.skipIntProperty< sal_Int32 >(); // IDispatch identifier for source range access
+ aReader.skipIntProperty< sal_uInt16 >(); // get function index for source range access
+ bValid = aReader.finalizeImport();
+ }
+ }
+ return bValid;
+}
+
+// ============================================================================
+
+AxFrameModel::AxFrameModel() :
+ AxContainerModelBase( true )
+{
+}
+
+ApiControlType AxFrameModel::getControlType() const
+{
+ return API_CONTROL_GROUPBOX;
+}
+
+void AxFrameModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Label, maCaption );
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_CONTAINER_ENABLED ) );
+ AxContainerModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxFormPageModel::AxFormPageModel()
+{
+}
+
+ApiControlType AxFormPageModel::getControlType() const
+{
+ return API_CONTROL_PAGE;
+}
+
+void AxFormPageModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Title, maCaption );
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_CONTAINER_ENABLED ) );
+ rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor );
+ AxContainerModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+AxMultiPageModel::AxMultiPageModel()
+{
+}
+
+ApiControlType AxMultiPageModel::getControlType() const
+{
+ return API_CONTROL_MULTIPAGE;
+}
+
+void AxMultiPageModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_CONTAINER_ENABLED ) );
+ if( mxTabStrip.get() )
+ mxTabStrip->convertProperties( rPropMap, rConv );
+ AxContainerModelBase::convertProperties( rPropMap, rConv );
+}
+
+void AxMultiPageModel::setTabStripModel( const AxTabStripModelRef& rxTabStrip )
+{
+ mxTabStrip = rxTabStrip;
+}
+
+// ============================================================================
+
+AxUserFormModel::AxUserFormModel()
+{
+}
+
+ApiControlType AxUserFormModel::getControlType() const
+{
+ return API_CONTROL_DIALOG;
+}
+
+void AxUserFormModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+ rPropMap.setProperty( PROP_Title, maCaption );
+ rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor );
+ AxContainerModelBase::convertProperties( rPropMap, rConv );
+}
+
+// ============================================================================
+
+EmbeddedControl::EmbeddedControl( const OUString& rName ) :
+ maName( rName )
+{
+}
+
+EmbeddedControl::~EmbeddedControl()
+{
+}
+
+ControlModelBase* EmbeddedControl::createModelFromGuid( const OUString& rClassId )
+{
+ OUString aClassId = rClassId.toAsciiUpperCase();
+
+ if( aClassId.equalsAscii( AX_GUID_COMMANDBUTTON ) ) return &createModel< AxCommandButtonModel >();
+ if( aClassId.equalsAscii( AX_GUID_LABEL ) ) return &createModel< AxLabelModel >();
+ if( aClassId.equalsAscii( AX_GUID_IMAGE ) ) return &createModel< AxImageModel >();
+ if( aClassId.equalsAscii( AX_GUID_TOGGLEBUTTON ) ) return &createModel< AxToggleButtonModel >();
+ if( aClassId.equalsAscii( AX_GUID_CHECKBOX ) ) return &createModel< AxCheckBoxModel >();
+ if( aClassId.equalsAscii( AX_GUID_OPTIONBUTTON ) ) return &createModel< AxOptionButtonModel >();
+ if( aClassId.equalsAscii( AX_GUID_TEXTBOX ) ) return &createModel< AxTextBoxModel >();
+ if( aClassId.equalsAscii( AX_GUID_LISTBOX ) ) return &createModel< AxListBoxModel >();
+ if( aClassId.equalsAscii( AX_GUID_COMBOBOX ) ) return &createModel< AxComboBoxModel >();
+ if( aClassId.equalsAscii( AX_GUID_SPINBUTTON ) ) return &createModel< AxSpinButtonModel >();
+ if( aClassId.equalsAscii( AX_GUID_SCROLLBAR ) ) return &createModel< AxScrollBarModel >();
+ if( aClassId.equalsAscii( AX_GUID_FRAME ) ) return &createModel< AxFrameModel >();
+ if( aClassId.equalsAscii( COMCTL_GUID_SCROLLBAR_60 ) ) return &createModel< ComCtlScrollBarModel >( COMCTL_VERSION_60 );
+
+ mxModel.reset();
+ return 0;
+}
+
+OUString EmbeddedControl::getServiceName() const
+{
+ return mxModel.get() ? mxModel->getServiceName() : OUString();
+}
+
+bool EmbeddedControl::convertProperties( const Reference< XControlModel >& rxCtrlModel, const ControlConverter& rConv ) const
+{
+ if( mxModel.get() && rxCtrlModel.is() && (maName.getLength() > 0) )
+ {
+ PropertyMap aPropMap;
+ aPropMap.setProperty( PROP_Name, maName );
+ mxModel->convertProperties( aPropMap, rConv );
+ PropertySet aPropSet( rxCtrlModel );
+ aPropSet.setProperties( aPropMap );
+ return true;
+ }
+ return false;
+}
+
+// ============================================================================
+
+EmbeddedForm::EmbeddedForm( const Reference< XModel >& rxDocModel,
+ const Reference< XDrawPage >& rxDrawPage, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
+ maControlConv( rxDocModel, rGraphicHelper, bDefaultColorBgr ),
+ mxModelFactory( rxDocModel, UNO_QUERY ),
+ mxFormsSupp( rxDrawPage, UNO_QUERY )
+{
+ OSL_ENSURE( mxModelFactory.is(), "EmbeddedForm::EmbeddedForm - missing service factory" );
+}
+
+Reference< XControlModel > EmbeddedForm::convertAndInsert( const EmbeddedControl& rControl, sal_Int32& rnCtrlIndex )
+{
+ if( mxModelFactory.is() && rControl.hasModel() ) try
+ {
+ // create the UNO control model
+ OUString aServiceName = rControl.getServiceName();
+ Reference< XFormComponent > xFormComp( mxModelFactory->createInstance( aServiceName ), UNO_QUERY_THROW );
+ Reference< XControlModel > xCtrlModel( xFormComp, UNO_QUERY_THROW );
+
+ // insert the control into the form
+ Reference< XIndexContainer > xFormIC( createXForm(), UNO_SET_THROW );
+ rnCtrlIndex = xFormIC->getCount();
+ xFormIC->insertByIndex( rnCtrlIndex, Any( xFormComp ) );
+
+ // convert the control properties
+ if( rControl.convertProperties( xCtrlModel, maControlConv ) )
+ return xCtrlModel;
+ }
+ catch( Exception& )
+ {
+ }
+ return Reference< XControlModel >();
+}
+
+Reference< XIndexContainer > EmbeddedForm::createXForm()
+{
+ if( mxFormsSupp.is() )
+ {
+ try
+ {
+ Reference< XNameContainer > xFormsNC( mxFormsSupp->getForms(), UNO_SET_THROW );
+ OUString aFormName = CREATE_OUSTRING( "Standard" );
+ if( xFormsNC->hasByName( aFormName ) )
+ {
+ mxFormIC.set( xFormsNC->getByName( aFormName ), UNO_QUERY_THROW );
+ }
+ else if( mxModelFactory.is() )
+ {
+ Reference< XForm > xForm( mxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW );
+ xFormsNC->insertByName( aFormName, Any( xForm ) );
+ mxFormIC.set( xForm, UNO_QUERY_THROW );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ // always clear the forms supplier to not try to create the form again
+ mxFormsSupp.clear();
+ }
+ return mxFormIC;
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/axcontrolfragment.cxx b/oox/source/ole/axcontrolfragment.cxx
new file mode 100644
index 000000000000..f45e8e2590c9
--- /dev/null
+++ b/oox/source/ole/axcontrolfragment.cxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/axcontrolfragment.hxx"
+
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/ole/axcontrol.hxx"
+#include "oox/ole/olehelper.hxx"
+#include "oox/ole/olestorage.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::ContextHandler2;
+using ::oox::core::ContextHandlerRef;
+using ::oox::core::FragmentHandler2;
+using ::oox::core::XmlFilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
+AxControlPropertyContext::AxControlPropertyContext( FragmentHandler2& rFragment, ControlModelBase& rModel ) :
+ ContextHandler2( rFragment ),
+ mrModel( rModel ),
+ mnPropId( XML_TOKEN_INVALID )
+{
+}
+
+ContextHandlerRef AxControlPropertyContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case AX_TOKEN( ocx ):
+ if( nElement == AX_TOKEN( ocxPr ) )
+ {
+ mnPropId = rAttribs.getToken( AX_TOKEN( name ), XML_TOKEN_INVALID );
+ switch( mnPropId )
+ {
+ case XML_TOKEN_INVALID:
+ return 0;
+ case XML_Picture:
+ case XML_MouseIcon:
+ return this; // import picture path from ax:picture child element
+ default:
+ mrModel.importProperty( mnPropId, rAttribs.getString( AX_TOKEN( value ), OUString() ) );
+ }
+ }
+ break;
+
+ case AX_TOKEN( ocxPr ):
+ if( nElement == AX_TOKEN( picture ) )
+ {
+ OUString aPicturePath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ if( aPicturePath.getLength() > 0 )
+ {
+ BinaryXInputStream aInStrm( getFilter().openInputStream( aPicturePath ), true );
+ mrModel.importPictureData( mnPropId, aInStrm );
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+AxControlFragment::AxControlFragment( XmlFilterBase& rFilter, const OUString& rFragmentPath, EmbeddedControl& rControl ) :
+ FragmentHandler2( rFilter, rFragmentPath, true ),
+ mrControl( rControl )
+{
+}
+
+ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() && (nElement == AX_TOKEN( ocx )) )
+ {
+ OUString aClassId = rAttribs.getString( AX_TOKEN( classid ), OUString() );
+ switch( rAttribs.getToken( AX_TOKEN( persistence ), XML_TOKEN_INVALID ) )
+ {
+ case XML_persistPropertyBag:
+ if( ControlModelBase* pModel = mrControl.createModelFromGuid( aClassId ) )
+ return new AxControlPropertyContext( *this, *pModel );
+ break;
+
+ case XML_persistStreamInit:
+ {
+ OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ if( aFragmentPath.getLength() > 0 )
+ {
+ BinaryXInputStream aInStrm( getFilter().openInputStream( aFragmentPath ), true );
+ if( !aInStrm.isEof() )
+ {
+ // binary stream contains a copy of the class ID, must be equal to attribute value
+ OUString aStrmClassId = OleHelper::importGuid( aInStrm );
+ OSL_ENSURE( aClassId.equalsIgnoreAsciiCase( aStrmClassId ),
+ "AxControlFragment::importBinaryControl - form control class ID mismatch" );
+ if( ControlModelBase* pModel = mrControl.createModelFromGuid( aStrmClassId ) )
+ pModel->importBinaryModel( aInStrm );
+ }
+ }
+ }
+ break;
+
+ case XML_persistStorage:
+ {
+ OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ if( aFragmentPath.getLength() > 0 )
+ {
+ Reference< XInputStream > xStrgStrm = getFilter().openInputStream( aFragmentPath );
+ if( xStrgStrm.is() )
+ {
+ OleStorage aStorage( getFilter().getServiceFactory(), xStrgStrm, false );
+ BinaryXInputStream aInStrm( aStorage.openInputStream( CREATE_OUSTRING( "f" ) ), true );
+ if( !aInStrm.isEof() )
+ if( AxContainerModelBase* pModel = dynamic_cast< AxContainerModelBase* >( mrControl.createModelFromGuid( aClassId ) ) )
+ pModel->importBinaryModel( aInStrm );
+ }
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/makefile.mk b/oox/source/ole/makefile.mk
new file mode 100644
index 000000000000..a5232247cfa5
--- /dev/null
+++ b/oox/source/ole/makefile.mk
@@ -0,0 +1,60 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=ole
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/axbinaryreader.obj \
+ $(SLO)$/axcontrol.obj \
+ $(SLO)$/axcontrolfragment.obj \
+ $(SLO)$/olehelper.obj \
+ $(SLO)$/oleobjecthelper.obj \
+ $(SLO)$/olestorage.obj \
+ $(SLO)$/vbacontrol.obj \
+ $(SLO)$/vbahelper.obj \
+ $(SLO)$/vbainputstream.obj \
+ $(SLO)$/vbamodule.obj \
+ $(SLO)$/vbaproject.obj \
+ $(SLO)$/vbaprojectfilter.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/oox/source/ole/olehelper.cxx b/oox/source/ole/olehelper.cxx
new file mode 100644
index 000000000000..8dfe02283cb0
--- /dev/null
+++ b/oox/source/ole/olehelper.cxx
@@ -0,0 +1,313 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/olehelper.hxx"
+
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/token/tokens.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 OLE_COLORTYPE_MASK = 0xFF000000;
+const sal_uInt32 OLE_COLORTYPE_CLIENT = 0x00000000;
+const sal_uInt32 OLE_COLORTYPE_PALETTE = 0x01000000;
+const sal_uInt32 OLE_COLORTYPE_BGR = 0x02000000;
+const sal_uInt32 OLE_COLORTYPE_SYSCOLOR = 0x80000000;
+
+const sal_uInt32 OLE_PALETTECOLOR_MASK = 0x0000FFFF;
+const sal_uInt32 OLE_BGRCOLOR_MASK = 0x00FFFFFF;
+const sal_uInt32 OLE_SYSTEMCOLOR_MASK = 0x0000FFFF;
+
+/** Swaps the red and blue component of the passed color. */
+inline sal_uInt32 lclSwapRedBlue( sal_uInt32 nColor )
+{
+ return static_cast< sal_uInt32 >( (nColor & 0xFF00FF00) | ((nColor & 0x0000FF) << 16) | ((nColor & 0xFF0000) >> 16) );
+}
+
+/** Returns the UNO RGB color from the passed encoded OLE BGR color. */
+inline sal_Int32 lclDecodeBgrColor( sal_uInt32 nOleColor )
+{
+ return static_cast< sal_Int32 >( lclSwapRedBlue( nOleColor ) & 0xFFFFFF );
+}
+
+// ----------------------------------------------------------------------------
+
+const sal_Char* const OLE_GUID_URLMONIKER = "{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}";
+const sal_Char* const OLE_GUID_FILEMONIKER = "{00000303-0000-0000-C000-000000000046}";
+
+const sal_uInt32 OLE_STDPIC_ID = 0x0000746C;
+
+const sal_uInt32 OLE_STDHLINK_VERSION = 2;
+const sal_uInt32 OLE_STDHLINK_HASTARGET = 0x00000001; /// Has hyperlink moniker.
+const sal_uInt32 OLE_STDHLINK_ABSOLUTE = 0x00000002; /// Absolute path.
+const sal_uInt32 OLE_STDHLINK_HASLOCATION = 0x00000008; /// Has target location.
+const sal_uInt32 OLE_STDHLINK_HASDISPLAY = 0x00000010; /// Has display string.
+const sal_uInt32 OLE_STDHLINK_HASGUID = 0x00000020; /// Has identification GUID.
+const sal_uInt32 OLE_STDHLINK_HASTIME = 0x00000040; /// Has creation time.
+const sal_uInt32 OLE_STDHLINK_HASFRAME = 0x00000080; /// Has frame.
+const sal_uInt32 OLE_STDHLINK_ASSTRING = 0x00000100; /// Hyperlink as simple string.
+
+// ----------------------------------------------------------------------------
+
+template< typename Type >
+void lclAppendHex( OUStringBuffer& orBuffer, Type nValue )
+{
+ const sal_Int32 nWidth = 2 * sizeof( Type );
+ static const sal_Unicode spcHexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ orBuffer.setLength( orBuffer.getLength() + nWidth );
+ for( sal_Int32 nCharIdx = orBuffer.getLength() - 1, nCharEnd = nCharIdx - nWidth; nCharIdx > nCharEnd; --nCharIdx, nValue >>= 4 )
+ orBuffer.setCharAt( nCharIdx, spcHexChars[ nValue & 0xF ] );
+}
+
+OUString lclReadStdHlinkString( BinaryInputStream& rInStrm, bool bUnicode )
+{
+ OUString aRet;
+ sal_Int32 nChars = rInStrm.readInt32();
+ if( nChars > 0 )
+ {
+ sal_Int32 nReadChars = getLimitedValue< sal_Int32, sal_Int32 >( nChars, 0, SAL_MAX_UINT16 );
+ // byte strings are always in ANSI (Windows 1252) encoding
+ aRet = bUnicode ? rInStrm.readUnicodeArray( nReadChars, true ) : rInStrm.readCharArrayUC( nReadChars, RTL_TEXTENCODING_MS_1252, true );
+ // strings are NUL terminated, remove trailing NUL and possible other garbage
+ sal_Int32 nNulPos = aRet.indexOf( '\0' );
+ if( nNulPos >= 0 )
+ aRet = aRet.copy( 0, nNulPos );
+ // skip remaining chars
+ rInStrm.skip( (bUnicode ? 2 : 1) * (nChars - nReadChars) );
+ }
+ return aRet;
+}
+
+} // namespace
+
+// ============================================================================
+
+StdFontInfo::StdFontInfo() :
+ mnHeight( 0 ),
+ mnWeight( OLE_STDFONT_NORMAL ),
+ mnCharSet( WINDOWS_CHARSET_ANSI ),
+ mnFlags( 0 )
+{
+}
+
+StdFontInfo::StdFontInfo( const ::rtl::OUString& rName, sal_uInt32 nHeight,
+ sal_uInt16 nWeight, sal_uInt16 nCharSet, sal_uInt8 nFlags ) :
+ maName( rName ),
+ mnHeight( nHeight ),
+ mnWeight( nWeight ),
+ mnCharSet( nCharSet ),
+ mnFlags( nFlags )
+{
+}
+
+// ============================================================================
+
+/*static*/ sal_Int32 OleHelper::decodeOleColor(
+ const GraphicHelper& rGraphicHelper, sal_uInt32 nOleColor, bool bDefaultColorBgr )
+{
+ static const sal_Int32 spnSystemColors[] =
+ {
+ XML_scrollBar, XML_background, XML_activeCaption, XML_inactiveCaption,
+ XML_menu, XML_window, XML_windowFrame, XML_menuText,
+ XML_windowText, XML_captionText, XML_activeBorder, XML_inactiveBorder,
+ XML_appWorkspace, XML_highlight, XML_highlightText, XML_btnFace,
+ XML_btnShadow, XML_grayText, XML_btnText, XML_inactiveCaptionText,
+ XML_btnHighlight, XML_3dDkShadow, XML_3dLight, XML_infoText,
+ XML_infoBk
+ };
+
+ switch( nOleColor & OLE_COLORTYPE_MASK )
+ {
+ case OLE_COLORTYPE_CLIENT:
+ return bDefaultColorBgr ? lclDecodeBgrColor( nOleColor ) : rGraphicHelper.getPaletteColor( nOleColor & OLE_PALETTECOLOR_MASK );
+
+ case OLE_COLORTYPE_PALETTE:
+ return rGraphicHelper.getPaletteColor( nOleColor & OLE_PALETTECOLOR_MASK );
+
+ case OLE_COLORTYPE_BGR:
+ return lclDecodeBgrColor( nOleColor );
+
+ case OLE_COLORTYPE_SYSCOLOR:
+ return rGraphicHelper.getSystemColor( STATIC_ARRAY_SELECT( spnSystemColors, nOleColor & OLE_SYSTEMCOLOR_MASK, XML_TOKEN_INVALID ), API_RGB_WHITE );
+ }
+ OSL_ENSURE( false, "OleHelper::decodeOleColor - unknown color type" );
+ return API_RGB_BLACK;
+}
+
+/*static*/ sal_uInt32 OleHelper::encodeOleColor( sal_Int32 nRgbColor )
+{
+ return OLE_COLORTYPE_BGR | lclSwapRedBlue( static_cast< sal_uInt32 >( nRgbColor & 0xFFFFFF ) );
+}
+
+/*static*/ OUString OleHelper::importGuid( BinaryInputStream& rInStrm )
+{
+ OUStringBuffer aBuffer;
+ aBuffer.append( sal_Unicode( '{' ) );
+ lclAppendHex( aBuffer, rInStrm.readuInt32() );
+ aBuffer.append( sal_Unicode( '-' ) );
+ lclAppendHex( aBuffer, rInStrm.readuInt16() );
+ aBuffer.append( sal_Unicode( '-' ) );
+ lclAppendHex( aBuffer, rInStrm.readuInt16() );
+ aBuffer.append( sal_Unicode( '-' ) );
+ lclAppendHex( aBuffer, rInStrm.readuInt8() );
+ lclAppendHex( aBuffer, rInStrm.readuInt8() );
+ aBuffer.append( sal_Unicode( '-' ) );
+ for( int nIndex = 0; nIndex < 6; ++nIndex )
+ lclAppendHex( aBuffer, rInStrm.readuInt8() );
+ aBuffer.append( sal_Unicode( '}' ) );
+ return aBuffer.makeStringAndClear();
+}
+
+/*static*/ bool OleHelper::importStdFont( StdFontInfo& orFontInfo, BinaryInputStream& rInStrm, bool bWithGuid )
+{
+ if( bWithGuid )
+ {
+ bool bIsStdFont = importGuid( rInStrm ).equalsAscii( OLE_GUID_STDFONT );
+ OSL_ENSURE( bIsStdFont, "OleHelper::importStdFont - unexpected header GUID, expected StdFont" );
+ if( !bIsStdFont )
+ return false;
+ }
+
+ sal_uInt8 nVersion, nNameLen;
+ rInStrm >> nVersion >> orFontInfo.mnCharSet >> orFontInfo.mnFlags >> orFontInfo.mnWeight >> orFontInfo.mnHeight >> nNameLen;
+ // according to spec the name is ASCII
+ orFontInfo.maName = rInStrm.readCharArrayUC( nNameLen, RTL_TEXTENCODING_ASCII_US );
+ OSL_ENSURE( nVersion <= 1, "OleHelper::importStdFont - wrong version" );
+ return !rInStrm.isEof() && (nVersion <= 1);
+}
+
+/*static*/ bool OleHelper::importStdPic( StreamDataSequence& orGraphicData, BinaryInputStream& rInStrm, bool bWithGuid )
+{
+ if( bWithGuid )
+ {
+ bool bIsStdPic = importGuid( rInStrm ).equalsAscii( OLE_GUID_STDPIC );
+ OSL_ENSURE( bIsStdPic, "OleHelper::importStdPic - unexpected header GUID, expected StdPic" );
+ if( !bIsStdPic )
+ return false;
+ }
+
+ sal_uInt32 nStdPicId;
+ sal_Int32 nBytes;
+ rInStrm >> nStdPicId >> nBytes;
+ OSL_ENSURE( nStdPicId == OLE_STDPIC_ID, "OleHelper::importStdPic - unexpected header version" );
+ return !rInStrm.isEof() && (nStdPicId == OLE_STDPIC_ID) && (nBytes > 0) && (rInStrm.readData( orGraphicData, nBytes ) == nBytes);
+}
+
+/*static*/ bool OleHelper::importStdHlink( StdHlinkInfo& orHlinkInfo, BinaryInputStream& rInStrm, bool bWithGuid )
+{
+ if( bWithGuid )
+ {
+ bool bIsStdHlink = importGuid( rInStrm ).equalsAscii( OLE_GUID_STDHLINK );
+ OSL_ENSURE( bIsStdHlink, "OleHelper::importStdHlink - unexpected header GUID, expected StdHlink" );
+ if( !bIsStdHlink )
+ return false;
+ }
+
+ sal_uInt32 nVersion, nFlags;
+ rInStrm >> nVersion >> nFlags;
+ OSL_ENSURE( nVersion == OLE_STDHLINK_VERSION, "OleHelper::importStdHlink - unexpected header version" );
+ if( rInStrm.isEof() || (nVersion != OLE_STDHLINK_VERSION) )
+ return false;
+
+ // display string
+ if( getFlag( nFlags, OLE_STDHLINK_HASDISPLAY ) )
+ orHlinkInfo.maDisplay = lclReadStdHlinkString( rInStrm, true );
+ // frame string
+ if( getFlag( nFlags, OLE_STDHLINK_HASFRAME ) )
+ orHlinkInfo.maFrame = lclReadStdHlinkString( rInStrm, true );
+
+ // target
+ if( getFlag( nFlags, OLE_STDHLINK_HASTARGET ) )
+ {
+ if( getFlag( nFlags, OLE_STDHLINK_ASSTRING ) )
+ {
+ OSL_ENSURE( getFlag( nFlags, OLE_STDHLINK_ABSOLUTE ), "OleHelper::importStdHlink - link not absolute" );
+ orHlinkInfo.maTarget = lclReadStdHlinkString( rInStrm, true );
+ }
+ else // hyperlink moniker
+ {
+ OUString aGuid = importGuid( rInStrm );
+ if( aGuid.equalsAscii( OLE_GUID_FILEMONIKER ) )
+ {
+ // file name, maybe relative and with directory up-count
+ sal_Int16 nUpLevels;
+ rInStrm >> nUpLevels;
+ OSL_ENSURE( (nUpLevels == 0) || !getFlag( nFlags, OLE_STDHLINK_ABSOLUTE ), "OleHelper::importStdHlink - absolute filename with upcount" );
+ orHlinkInfo.maTarget = lclReadStdHlinkString( rInStrm, false );
+ rInStrm.skip( 24 );
+ sal_Int32 nBytes = rInStrm.readInt32();
+ if( nBytes > 0 )
+ {
+ sal_Int64 nEndPos = rInStrm.tell() + ::std::max< sal_Int32 >( nBytes, 0 );
+ sal_uInt16 nChars = getLimitedValue< sal_uInt16, sal_Int32 >( rInStrm.readInt32() / 2, 0, SAL_MAX_UINT16 );
+ rInStrm.skip( 2 ); // key value
+ orHlinkInfo.maTarget = rInStrm.readUnicodeArray( nChars ); // NOT null terminated
+ rInStrm.seek( nEndPos );
+ }
+ if( !getFlag( nFlags, OLE_STDHLINK_ABSOLUTE ) )
+ for( sal_Int16 nLevel = 0; nLevel < nUpLevels; ++nLevel )
+ orHlinkInfo.maTarget = CREATE_OUSTRING( "../" ) + orHlinkInfo.maTarget;
+ }
+ else if( aGuid.equalsAscii( OLE_GUID_URLMONIKER ) )
+ {
+ // URL, maybe relative and with leading '../'
+ sal_Int32 nBytes = rInStrm.readInt32();
+ sal_Int64 nEndPos = rInStrm.tell() + ::std::max< sal_Int32 >( nBytes, 0 );
+ orHlinkInfo.maTarget = rInStrm.readNulUnicodeArray();
+ rInStrm.seek( nEndPos );
+ }
+ else
+ {
+ OSL_ENSURE( false, "OleHelper::importStdHlink - unsupported hyperlink moniker" );
+ return false;
+ }
+ }
+ }
+
+ // target location
+ if( getFlag( nFlags, OLE_STDHLINK_HASLOCATION ) )
+ orHlinkInfo.maLocation = lclReadStdHlinkString( rInStrm, true );
+
+ return !rInStrm.isEof();
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/oleobjecthelper.cxx b/oox/source/ole/oleobjecthelper.cxx
new file mode 100644
index 000000000000..396cd6b53874
--- /dev/null
+++ b/oox/source/ole/oleobjecthelper.cxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/oleobjecthelper.hxx"
+
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include "oox/helper/propertymap.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+OleObjectInfo::OleObjectInfo() :
+ mbLinked( false ),
+ mbShowAsIcon( false ),
+ mbAutoUpdate( false )
+{
+}
+
+// ============================================================================
+
+OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxFactory ) :
+ maEmbeddedObjScheme( CREATE_OUSTRING( "vnd.sun.star.EmbeddedObject:" ) ),
+ mnObjectId( 100 )
+{
+ if( rxFactory.is() )
+ mxResolver.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY );
+}
+
+OleObjectHelper::~OleObjectHelper()
+{
+ try
+ {
+ Reference< XComponent > xResolverComp( mxResolver, UNO_QUERY_THROW );
+ xResolverComp->dispose();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInfo& rOleObject, const Size& rObjSize )
+{
+ bool bRet = false;
+
+ if( rOleObject.mbLinked )
+ {
+ // linked OLE object - set target URL
+ if( rOleObject.maTargetLink.getLength() > 0 )
+ {
+ rPropMap[ PROP_LinkURL ] <<= rOleObject.maTargetLink;
+ bRet = true;
+ }
+ }
+ else
+ {
+ // embedded OLE object - import the embedded data
+ if( rOleObject.maEmbeddedData.hasElements() && mxResolver.is() ) try
+ {
+ OUString aObjectId = CREATE_OUSTRING( "Obj" ) + OUString::valueOf( mnObjectId++ );
+
+ Reference< XNameAccess > xResolverNA( mxResolver, UNO_QUERY_THROW );
+ Reference< XOutputStream > xOutStrm( xResolverNA->getByName( aObjectId ), UNO_QUERY_THROW );
+ xOutStrm->writeBytes( rOleObject.maEmbeddedData );
+ xOutStrm->closeOutput();
+
+ OUString aUrl = mxResolver->resolveEmbeddedObjectURL( aObjectId );
+ OSL_ENSURE( aUrl.match( maEmbeddedObjScheme ), "OleObjectHelper::importOleObject - unexpected URL scheme" );
+ OUString aPersistName = aUrl.copy( maEmbeddedObjScheme.getLength() );
+ if( aPersistName.getLength() > 0 )
+ {
+ rPropMap[ PROP_PersistName ] <<= aPersistName;
+ bRet = true;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ if( bRet )
+ {
+ // aspect mode
+ using namespace ::com::sun::star::embed::Aspects;
+ sal_Int64 nAspect = rOleObject.mbShowAsIcon ? MSOLE_ICON : MSOLE_CONTENT;
+ rPropMap[ PROP_Aspect ] <<= nAspect;
+ // visual area
+ rPropMap[ PROP_VisualArea ] <<= Rectangle( 0, 0, rObjSize.Width, rObjSize.Height );
+ }
+ return bRet;
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/olestorage.cxx b/oox/source/ole/olestorage.cxx
new file mode 100644
index 000000000000..cf55d6463778
--- /dev/null
+++ b/oox/source/ole/olestorage.cxx
@@ -0,0 +1,413 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/olestorage.hxx"
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+typedef ::cppu::WeakImplHelper2< XSeekable, XOutputStream > OleOutputStreamBase;
+
+/** Implementation of an OLE storage output stream that inserts itself into the
+ storage when it is closed.
+ */
+class OleOutputStream : public OleOutputStreamBase
+{
+public:
+ explicit OleOutputStream(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XNameContainer >& rxStorage,
+ const OUString& rElementName );
+ virtual ~OleOutputStream();
+
+ virtual void SAL_CALL seek( sal_Int64 nPos ) throw( IllegalArgumentException, IOException, RuntimeException );
+ virtual sal_Int64 SAL_CALL getPosition() throw( IOException, RuntimeException );
+ virtual sal_Int64 SAL_CALL getLength() throw( IOException, RuntimeException );
+
+ virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& rData ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException );
+ virtual void SAL_CALL flush() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException );
+ virtual void SAL_CALL closeOutput() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException );
+
+private:
+ void ensureSeekable() const throw( IOException );
+ void ensureConnected() const throw( NotConnectedException );
+
+private:
+ Reference< XNameContainer > mxStorage;
+ Reference< XStream > mxTempFile;
+ Reference< XOutputStream > mxOutStrm;
+ Reference< XSeekable > mxSeekable;
+ OUString maElementName;
+};
+
+// ----------------------------------------------------------------------------
+
+OleOutputStream::OleOutputStream( const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XNameContainer >& rxStorage, const OUString& rElementName ) :
+ mxStorage( rxStorage ),
+ maElementName( rElementName )
+{
+ try
+ {
+ mxTempFile.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
+ mxOutStrm = mxTempFile->getOutputStream();
+ mxSeekable.set( mxOutStrm, UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+OleOutputStream::~OleOutputStream()
+{
+}
+
+void SAL_CALL OleOutputStream::seek( sal_Int64 nPos ) throw( IllegalArgumentException, IOException, RuntimeException )
+{
+ ensureSeekable();
+ mxSeekable->seek( nPos );
+}
+
+sal_Int64 SAL_CALL OleOutputStream::getPosition() throw( IOException, RuntimeException )
+{
+ ensureSeekable();
+ return mxSeekable->getPosition();
+}
+
+sal_Int64 SAL_CALL OleOutputStream::getLength() throw( IOException, RuntimeException )
+{
+ ensureSeekable();
+ return mxSeekable->getLength();
+}
+
+void SAL_CALL OleOutputStream::writeBytes( const Sequence< sal_Int8 >& rData ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+{
+ ensureConnected();
+ mxOutStrm->writeBytes( rData );
+}
+
+void SAL_CALL OleOutputStream::flush() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+{
+ ensureConnected();
+ mxOutStrm->flush();
+}
+
+void SAL_CALL OleOutputStream::closeOutput() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+{
+ ensureConnected();
+ ensureSeekable();
+ // remember the class members
+ Reference< XOutputStream > xOutStrm = mxOutStrm;
+ Reference< XSeekable > xSeekable = mxSeekable;
+ // reset all class members
+ mxOutStrm.clear();
+ mxSeekable.clear();
+ // close stream (and let it throw something if needed)
+ xOutStrm->closeOutput();
+ // on success, insert the stream into the OLE storage (must be seeked back before)
+ xSeekable->seek( 0 );
+ if( !ContainerHelper::insertByName( mxStorage, maElementName, Any( mxTempFile ) ) )
+ throw IOException();
+}
+
+void OleOutputStream::ensureSeekable() const throw( IOException )
+{
+ if( !mxSeekable.is() )
+ throw IOException();
+}
+
+void OleOutputStream::ensureConnected() const throw( NotConnectedException )
+{
+ if( !mxOutStrm.is() )
+ throw NotConnectedException();
+}
+
+} // namespace
+
+// ============================================================================
+
+OleStorage::OleStorage(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XInputStream >& rxInStream,
+ bool bBaseStreamAccess ) :
+ StorageBase( rxInStream, bBaseStreamAccess ),
+ mxFactory( rxFactory ),
+ mpParentStorage( 0 )
+{
+ OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" );
+ initStorage( rxInStream );
+}
+
+OleStorage::OleStorage(
+ const Reference< XMultiServiceFactory >& rxFactory,
+ const Reference< XStream >& rxOutStream,
+ bool bBaseStreamAccess ) :
+ StorageBase( rxOutStream, bBaseStreamAccess ),
+ mxFactory( rxFactory ),
+ mpParentStorage( 0 )
+{
+ OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" );
+ initStorage( rxOutStream );
+}
+
+OleStorage::OleStorage(
+ const OleStorage& rParentStorage,
+ const Reference< XNameContainer >& rxStorage,
+ const OUString& rElementName,
+ bool bReadOnly ) :
+ StorageBase( rParentStorage, rElementName, bReadOnly ),
+ mxFactory( rParentStorage.mxFactory ),
+ mxStorage( rxStorage ),
+ mpParentStorage( &rParentStorage )
+{
+ OSL_ENSURE( mxStorage.is(), "OleStorage::OleStorage - missing substorage elements" );
+}
+
+OleStorage::OleStorage(
+ const OleStorage& rParentStorage,
+ const Reference< XStream >& rxOutStream,
+ const OUString& rElementName ) :
+ StorageBase( rParentStorage, rElementName, false ),
+ mxFactory( rParentStorage.mxFactory ),
+ mpParentStorage( &rParentStorage )
+{
+ initStorage( rxOutStream );
+}
+
+OleStorage::~OleStorage()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+void OleStorage::initStorage( const Reference< XInputStream >& rxInStream )
+{
+ // if stream is not seekable, create temporary copy
+ Reference< XInputStream > xInStrm = rxInStream;
+ if( !Reference< XSeekable >( xInStrm, UNO_QUERY ).is() ) try
+ {
+ Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
+ {
+ Reference< XOutputStream > xOutStrm( xTempFile->getOutputStream(), UNO_SET_THROW );
+ /* Pass false to both binary stream objects to keep the UNO
+ streams alive. Life time of these streams is controlled by the
+ tempfile implementation. */
+ BinaryXOutputStream aOutStrm( xOutStrm, false );
+ BinaryXInputStream aInStrm( xInStrm, false );
+ aInStrm.copyToStream( aOutStrm );
+ } // scope closes output stream of tempfile
+ xInStrm = xTempFile->getInputStream();
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "OleStorage::initStorage - cannot create temporary copy of input stream" );
+ }
+
+ // create base storage object
+ if( xInStrm.is() ) try
+ {
+ Sequence< Any > aArgs( 2 );
+ aArgs[ 0 ] <<= xInStrm;
+ aArgs[ 1 ] <<= true; // true = do not create a copy of the input stream
+ mxStorage.set( mxFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void OleStorage::initStorage( const Reference< XStream >& rxOutStream )
+{
+ // create base storage object
+ if( rxOutStream.is() ) try
+ {
+ Sequence< Any > aArgs( 2 );
+ aArgs[ 0 ] <<= rxOutStream;
+ aArgs[ 1 ] <<= true; // true = do not create a copy of the stream
+ mxStorage.set( mxFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// StorageBase interface ------------------------------------------------------
+
+bool OleStorage::implIsStorage() const
+{
+ if( mxStorage.is() ) try
+ {
+ /* If this is not an OLE storage, hasElements() of the OLESimpleStorage
+ implementation throws an exception. But we do not return the result
+ of hasElements(), because an empty storage is a valid storage too. */
+ mxStorage->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 = mxStorage->getElementNames();
+ if( aNames.getLength() > 0 )
+ orElementNames.insert( orElementNames.end(), aNames.getConstArray(), aNames.getConstArray() + aNames.getLength() );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+StorageRef OleStorage::implOpenSubStorage( const OUString& rElementName, bool bCreateMissing )
+{
+ StorageRef xSubStorage;
+ if( mxStorage.is() && (rElementName.getLength() > 0) )
+ {
+ try
+ {
+ Reference< XNameContainer > xSubElements( mxStorage->getByName( rElementName ), UNO_QUERY_THROW );
+ xSubStorage.reset( new OleStorage( *this, xSubElements, rElementName, true ) );
+ }
+ catch( Exception& )
+ {
+ }
+
+ /* The OLESimpleStorage API implementation seems to be buggy in the
+ area of writable inplace substorage (sometimes it overwrites other
+ unrelated streams with zero bytes). We go the save way and create a
+ new OLE storage based on a temporary file. All operations are
+ performed on this clean storage. On committing, the storage will be
+ completely re-inserted into the parent storage. */
+ if( !isReadOnly() && (bCreateMissing || xSubStorage.get()) ) try
+ {
+ // create new storage based on a temp file
+ Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
+ StorageRef xTempStorage( new OleStorage( *this, xTempFile, rElementName ) );
+ // copy existing substorage into temp storage
+ if( xSubStorage.get() )
+ xSubStorage->copyStorageToStorage( *xTempStorage );
+ // return the temp storage to caller
+ xSubStorage = xTempStorage;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ return xSubStorage;
+}
+
+Reference< XInputStream > OleStorage::implOpenInputStream( const OUString& rElementName )
+{
+ Reference< XInputStream > xInStream;
+ if( mxStorage.is() ) try
+ {
+ xInStream.set( mxStorage->getByName( rElementName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xInStream;
+}
+
+Reference< XOutputStream > OleStorage::implOpenOutputStream( const OUString& rElementName )
+{
+ Reference< XOutputStream > xOutStream;
+ if( mxStorage.is() && (rElementName.getLength() > 0) )
+ xOutStream.set( new OleOutputStream( mxFactory, mxStorage, rElementName ) );
+ return xOutStream;
+}
+
+void OleStorage::implCommit() const
+{
+ try
+ {
+ // commit this storage (finalizes the file this storage is based on)
+ Reference< XTransactedObject >( mxStorage, UNO_QUERY_THROW )->commit();
+ // re-insert this storage into the parent storage
+ if( mpParentStorage )
+ {
+ if( mpParentStorage->mxStorage->hasByName( getName() ) )
+ {
+ // replaceByName() does not work (#i109539#)
+ mpParentStorage->mxStorage->removeByName( getName() );
+ Reference< XTransactedObject >( mpParentStorage->mxStorage, UNO_QUERY_THROW )->commit();
+ }
+ mpParentStorage->mxStorage->insertByName( getName(), Any( mxStorage ) );
+ // this requires another commit(), which will be performed by the parent storage
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx
new file mode 100644
index 000000000000..39deb77576d9
--- /dev/null
+++ b/oox/source/ole/vbacontrol.cxx
@@ -0,0 +1,850 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/vbacontrol.hxx"
+
+#include <algorithm>
+#include <set>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/io/XInputStreamProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <xmlscript/xmldlg_imexp.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/storagebase.hxx"
+#include "oox/helper/textinputstream.hxx"
+#include "oox/ole/vbahelper.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 VBA_SITE_CLASSIDINDEX = 0x8000;
+const sal_uInt16 VBA_SITE_INDEXMASK = 0x7FFF;
+const sal_uInt16 VBA_SITE_FORM = 7;
+const sal_uInt16 VBA_SITE_IMAGE = 12;
+const sal_uInt16 VBA_SITE_FRAME = 14;
+const sal_uInt16 VBA_SITE_SPINBUTTON = 16;
+const sal_uInt16 VBA_SITE_COMMANDBUTTON = 17;
+const sal_uInt16 VBA_SITE_TABSTRIP = 18;
+const sal_uInt16 VBA_SITE_LABEL = 21;
+const sal_uInt16 VBA_SITE_TEXTBOX = 23;
+const sal_uInt16 VBA_SITE_LISTBOX = 24;
+const sal_uInt16 VBA_SITE_COMBOBOX = 25;
+const sal_uInt16 VBA_SITE_CHECKBOX = 26;
+const sal_uInt16 VBA_SITE_OPTIONBUTTON = 27;
+const sal_uInt16 VBA_SITE_TOGGLEBUTTON = 28;
+const sal_uInt16 VBA_SITE_SCROLLBAR = 47;
+const sal_uInt16 VBA_SITE_MULTIPAGE = 57;
+const sal_uInt16 VBA_SITE_UNKNOWN = 0x7FFF;
+
+const sal_uInt32 VBA_SITE_TABSTOP = 0x00000001;
+const sal_uInt32 VBA_SITE_VISIBLE = 0x00000002;
+const sal_uInt32 VBA_SITE_DEFAULTBUTTON = 0x00000004;
+const sal_uInt32 VBA_SITE_CANCELBUTTON = 0x00000008;
+const sal_uInt32 VBA_SITE_OSTREAM = 0x00000010;
+const sal_uInt32 VBA_SITE_DEFFLAGS = 0x00000033;
+
+const sal_uInt8 VBA_SITEINFO_COUNT = 0x80;
+const sal_uInt8 VBA_SITEINFO_MASK = 0x7F;
+
+// ----------------------------------------------------------------------------
+
+/** Collects names of all controls in a user form or container control. Allows
+ to generate unused names for dummy controls separating option groups.
+ */
+class VbaControlNamesSet
+{
+public:
+ explicit VbaControlNamesSet();
+
+ /** Inserts the name of the passed control. */
+ void insertName( const VbaFormControl& rControl );
+ /** Returns a name that is not contained in this set. */
+ OUString generateDummyName();
+
+private:
+ typedef ::std::set< OUString > OUStringSet;
+ OUStringSet maCtrlNames;
+ const OUString maDummyBaseName;
+ sal_Int32 mnIndex;
+};
+
+VbaControlNamesSet::VbaControlNamesSet() :
+ maDummyBaseName( CREATE_OUSTRING( "DummyGroupSep" ) ),
+ mnIndex( 0 )
+{
+}
+
+void VbaControlNamesSet::insertName( const VbaFormControl& rControl )
+{
+ OUString aName = rControl.getControlName();
+ if( aName.getLength() > 0 )
+ maCtrlNames.insert( aName );
+}
+
+OUString VbaControlNamesSet::generateDummyName()
+{
+ OUString aCtrlName;
+ do
+ {
+ aCtrlName = OUStringBuffer( maDummyBaseName ).append( ++mnIndex ).makeStringAndClear();
+ }
+ while( maCtrlNames.count( aCtrlName ) > 0 );
+ maCtrlNames.insert( aCtrlName );
+ return aCtrlName;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Functor that inserts the name of a control into a VbaControlNamesSet. */
+struct VbaControlNameInserter
+{
+public:
+ VbaControlNamesSet& mrCtrlNames;
+ inline explicit VbaControlNameInserter( VbaControlNamesSet& rCtrlNames ) : mrCtrlNames( rCtrlNames ) {}
+ inline void operator()( const VbaFormControl& rControl ) { mrCtrlNames.insertName( rControl ); }
+};
+
+// ----------------------------------------------------------------------------
+
+/** A dummy invisible form control (fixed label without text) that is used to
+ separate two groups of option buttons.
+ */
+class VbaDummyFormControl : public VbaFormControl
+{
+public:
+ explicit VbaDummyFormControl( const OUString& rName );
+};
+
+VbaDummyFormControl::VbaDummyFormControl( const OUString& rName )
+{
+ mxSiteModel.reset( new VbaSiteModel );
+ mxSiteModel->importProperty( XML_Name, rName );
+ mxSiteModel->importProperty( XML_VariousPropertyBits, OUString( sal_Unicode( '0' ) ) );
+
+ mxCtrlModel.reset( new AxLabelModel );
+ mxCtrlModel->setAwtModelMode();
+ mxCtrlModel->importProperty( XML_Size, CREATE_OUSTRING( "10;10" ) );
+}
+
+} // namespace
+
+// ============================================================================
+
+VbaSiteModel::VbaSiteModel() :
+ maPos( 0, 0 ),
+ mnId( 0 ),
+ mnHelpContextId( 0 ),
+ mnFlags( VBA_SITE_DEFFLAGS ),
+ mnStreamLen( 0 ),
+ mnTabIndex( -1 ),
+ mnClassIdOrCache( VBA_SITE_UNKNOWN ),
+ mnGroupId( 0 )
+{
+}
+
+VbaSiteModel::~VbaSiteModel()
+{
+}
+
+void VbaSiteModel::importProperty( sal_Int32 nPropId, const OUString& rValue )
+{
+ switch( nPropId )
+ {
+ case XML_Name: maName = rValue; break;
+ case XML_Tag: maTag = rValue; break;
+ case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break;
+ }
+}
+
+bool VbaSiteModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+ AxBinaryPropertyReader aReader( rInStrm );
+ aReader.readStringProperty( maName );
+ aReader.readStringProperty( maTag );
+ aReader.readIntProperty< sal_Int32 >( mnId );
+ aReader.readIntProperty< sal_Int32 >( mnHelpContextId );
+ aReader.readIntProperty< sal_uInt32 >( mnFlags );
+ aReader.readIntProperty< sal_uInt32 >( mnStreamLen );
+ aReader.readIntProperty< sal_Int16 >( mnTabIndex );
+ aReader.readIntProperty< sal_uInt16 >( mnClassIdOrCache );
+ aReader.readPairProperty( maPos );
+ aReader.readIntProperty< sal_uInt16 >( mnGroupId );
+ aReader.skipUndefinedProperty();
+ aReader.readStringProperty( maToolTip );
+ aReader.skipStringProperty(); // license key
+ aReader.readStringProperty( maControlSource );
+ aReader.readStringProperty( maRowSource );
+ return aReader.finalizeImport();
+}
+
+void VbaSiteModel::moveRelative( const AxPairData& rDistance )
+{
+ maPos.first += rDistance.first;
+ maPos.second += rDistance.second;
+}
+
+bool VbaSiteModel::isVisible() const
+{
+ return getFlag( mnFlags, VBA_SITE_VISIBLE );
+}
+
+bool VbaSiteModel::isContainer() const
+{
+ return !getFlag( mnFlags, VBA_SITE_OSTREAM );
+}
+
+sal_uInt32 VbaSiteModel::getStreamLength() const
+{
+ return isContainer() ? 0 : mnStreamLen;
+}
+
+OUString VbaSiteModel::getSubStorageName() const
+{
+ if( mnId >= 0 )
+ {
+ OUStringBuffer aBuffer;
+ aBuffer.append( sal_Unicode( 'i' ) );
+ if( mnId < 10 )
+ aBuffer.append( sal_Unicode( '0' ) );
+ aBuffer.append( mnId );
+ return aBuffer.makeStringAndClear();
+ }
+ return OUString();
+}
+
+ControlModelRef VbaSiteModel::createControlModel( const AxClassTable& rClassTable ) const
+{
+ ControlModelRef xCtrlModel;
+
+ sal_Int32 nTypeIndex = static_cast< sal_Int32 >( mnClassIdOrCache & VBA_SITE_INDEXMASK );
+ if( !getFlag( mnClassIdOrCache, VBA_SITE_CLASSIDINDEX ) )
+ {
+ switch( nTypeIndex )
+ {
+ case VBA_SITE_COMMANDBUTTON: xCtrlModel.reset( new AxCommandButtonModel ); break;
+ case VBA_SITE_LABEL: xCtrlModel.reset( new AxLabelModel ); break;
+ case VBA_SITE_IMAGE: xCtrlModel.reset( new AxImageModel ); break;
+ case VBA_SITE_TOGGLEBUTTON: xCtrlModel.reset( new AxToggleButtonModel ); break;
+ case VBA_SITE_CHECKBOX: xCtrlModel.reset( new AxCheckBoxModel ); break;
+ case VBA_SITE_OPTIONBUTTON: xCtrlModel.reset( new AxOptionButtonModel ); break;
+ case VBA_SITE_TEXTBOX: xCtrlModel.reset( new AxTextBoxModel ); break;
+ case VBA_SITE_LISTBOX: xCtrlModel.reset( new AxListBoxModel ); break;
+ case VBA_SITE_COMBOBOX: xCtrlModel.reset( new AxComboBoxModel ); break;
+ case VBA_SITE_SPINBUTTON: /*xCtrlModel.reset( new AxSpinButtonModel );*/ break; // not supported (?)
+ case VBA_SITE_SCROLLBAR: xCtrlModel.reset( new AxScrollBarModel ); break;
+ case VBA_SITE_TABSTRIP: break; // not supported
+ case VBA_SITE_FRAME: xCtrlModel.reset( new AxFrameModel ); break;
+ case VBA_SITE_MULTIPAGE: break; // not supported
+ case VBA_SITE_FORM: break; // not supported
+ default: OSL_ENSURE( false, "VbaSiteModel::createControlModel - unknown type index" );
+ }
+ }
+ else
+ {
+ const OUString* pGuid = ContainerHelper::getVectorElement( rClassTable, nTypeIndex );
+ OSL_ENSURE( pGuid, "VbaSiteModel::createControlModel - invalid class table index" );
+ if( pGuid )
+ {
+ if( pGuid->equalsAscii( COMCTL_GUID_SCROLLBAR_60 ) )
+ xCtrlModel.reset( new ComCtlScrollBarModel( 6 ) );
+ else if( pGuid->equalsAscii( COMCTL_GUID_PROGRESSBAR_50 ) )
+ xCtrlModel.reset( new ComCtlProgressBarModel( 5 ) );
+ else if( pGuid->equalsAscii( COMCTL_GUID_PROGRESSBAR_60 ) )
+ xCtrlModel.reset( new ComCtlProgressBarModel( 6 ) );
+ }
+ }
+
+ if( xCtrlModel.get() )
+ {
+ // user form controls are AWT models
+ xCtrlModel->setAwtModelMode();
+
+ // check that container model matches container flag in site data
+ bool bModelIsContainer = dynamic_cast< const AxContainerModelBase* >( xCtrlModel.get() ) != 0;
+ bool bTypeMatch = bModelIsContainer == isContainer();
+ OSL_ENSURE( bTypeMatch, "VbaSiteModel::createControlModel - container type does not match container flag" );
+ if( !bTypeMatch )
+ xCtrlModel.reset();
+ }
+ return xCtrlModel;
+}
+
+void VbaSiteModel::convertProperties( PropertyMap& rPropMap,
+ const ControlConverter& rConv, ApiControlType eCtrlType, sal_Int32 nCtrlIndex ) const
+{
+ rPropMap.setProperty( PROP_Name, maName );
+ rPropMap.setProperty( PROP_Tag, maTag );
+
+ if( eCtrlType != API_CONTROL_DIALOG )
+ {
+ rPropMap.setProperty( PROP_HelpText, maToolTip );
+ rPropMap.setProperty( PROP_EnableVisible, getFlag( mnFlags, VBA_SITE_VISIBLE ) );
+ // we need to set the passed control index to make option button groups work
+ if( (0 <= nCtrlIndex) && (nCtrlIndex <= SAL_MAX_INT16) )
+ rPropMap.setProperty( PROP_TabIndex, static_cast< sal_Int16 >( nCtrlIndex ) );
+ // progress bar and group box support TabIndex, but not Tabstop...
+ if( (eCtrlType != API_CONTROL_PROGRESSBAR) && (eCtrlType != API_CONTROL_GROUPBOX) && (eCtrlType != API_CONTROL_FRAME) && (eCtrlType != API_CONTROL_PAGE) )
+ rPropMap.setProperty( PROP_Tabstop, getFlag( mnFlags, VBA_SITE_TABSTOP ) );
+ rConv.convertPosition( rPropMap, maPos );
+ }
+}
+
+void VbaSiteModel::bindToSources( const Reference< XControlModel >& rxCtrlModel, const ControlConverter& rConv ) const
+{
+ rConv.bindToSources( rxCtrlModel, maControlSource, maRowSource );
+}
+
+// ============================================================================
+
+VbaFormControl::VbaFormControl()
+{
+}
+
+VbaFormControl::~VbaFormControl()
+{
+}
+
+void VbaFormControl::importModelOrStorage( BinaryInputStream& rInStrm, StorageBase& rStrg, const AxClassTable& rClassTable )
+{
+ if( mxSiteModel.get() )
+ {
+ if( mxSiteModel->isContainer() )
+ {
+ StorageRef xSubStrg = rStrg.openSubStorage( mxSiteModel->getSubStorageName(), false );
+ OSL_ENSURE( xSubStrg.get(), "VbaFormControl::importModelOrStorage - cannot find storage for embedded control" );
+ if( xSubStrg.get() )
+ importStorage( *xSubStrg, rClassTable );
+ }
+ else if( !rInStrm.isEof() )
+ {
+ sal_Int64 nNextStrmPos = rInStrm.tell() + mxSiteModel->getStreamLength();
+ importControlModel( rInStrm, rClassTable );
+ rInStrm.seek( nNextStrmPos );
+ }
+ }
+}
+
+OUString VbaFormControl::getControlName() const
+{
+ return mxSiteModel.get() ? mxSiteModel->getName() : OUString();
+}
+
+sal_Int32 VbaFormControl::getControlId() const
+{
+ return mxSiteModel.get() ? mxSiteModel->getId() : -1;
+}
+
+void VbaFormControl::createAndConvert( sal_Int32 nCtrlIndex,
+ const Reference< XNameContainer >& rxParentNC, const ControlConverter& rConv ) const
+{
+ if( rxParentNC.is() && mxSiteModel.get() && mxCtrlModel.get() ) try
+ {
+ // create the control model
+ OUString aServiceName = mxCtrlModel->getServiceName();
+ Reference< XMultiServiceFactory > xModelFactory( rxParentNC, UNO_QUERY_THROW );
+ Reference< XControlModel > xCtrlModel( xModelFactory->createInstance( aServiceName ), UNO_QUERY_THROW );
+
+ // convert all properties and embedded controls
+ if( convertProperties( xCtrlModel, rConv, nCtrlIndex ) )
+ {
+ // insert into parent container
+ const OUString& rCtrlName = mxSiteModel->getName();
+ OSL_ENSURE( !rxParentNC->hasByName( rCtrlName ), "VbaFormControl::createAndConvert - multiple controls with equal name" );
+ ContainerHelper::insertByName( rxParentNC, rCtrlName, Any( xCtrlModel ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// protected ------------------------------------------------------------------
+
+void VbaFormControl::importControlModel( BinaryInputStream& rInStrm, const AxClassTable& rClassTable )
+{
+ createControlModel( rClassTable );
+ if( mxCtrlModel.get() )
+ mxCtrlModel->importBinaryModel( rInStrm );
+}
+
+void VbaFormControl::importStorage( StorageBase& rStrg, const AxClassTable& rClassTable )
+{
+ createControlModel( rClassTable );
+ AxContainerModelBase* pContainerModel = dynamic_cast< AxContainerModelBase* >( mxCtrlModel.get() );
+ OSL_ENSURE( pContainerModel, "VbaFormControl::importStorage - missing container control model" );
+ if( pContainerModel )
+ {
+ /* Open the 'f' stream containing the model of this control and a list
+ of site models for all child controls. */
+ BinaryXInputStream aFStrm( rStrg.openInputStream( CREATE_OUSTRING( "f" ) ), true );
+ OSL_ENSURE( !aFStrm.isEof(), "VbaFormControl::importStorage - missing 'f' stream" );
+
+ /* Read the properties of this container control and the class table
+ (into the maClassTable vector) containing a list of GUIDs for
+ exotic embedded controls. */
+ if( !aFStrm.isEof() && pContainerModel->importBinaryModel( aFStrm ) && pContainerModel->importClassTable( aFStrm, maClassTable ) )
+ {
+ /* Read the site models of all embedded controls (this fills the
+ maControls vector). Ignore failure of importSiteModels() but
+ try to import as much controls as possible. */
+ importEmbeddedSiteModels( aFStrm );
+
+ /* Open the 'o' stream containing models of embedded simple
+ controls. Stream may be empty or missing, if this control
+ contains no controls or only container controls. */
+ BinaryXInputStream aOStrm( rStrg.openInputStream( CREATE_OUSTRING( "o" ) ), true );
+
+ /* Iterate over all embedded controls, import model from 'o'
+ stream (for embedded simple controls) or from the substorage
+ (for embedded container controls). */
+ maControls.forEachMem( &VbaFormControl::importModelOrStorage,
+ ::boost::ref( aOStrm ), ::boost::ref( rStrg ), ::boost::cref( maClassTable ) );
+
+ /* Reorder the controls (sorts all option buttons of an option
+ group together), and move all children of all embedded frames
+ (group boxes) to this control (UNO group boxes cannot contain
+ other controls). */
+ finalizeEmbeddedControls();
+ }
+ }
+}
+
+bool VbaFormControl::convertProperties( const Reference< XControlModel >& rxCtrlModel,
+ const ControlConverter& rConv, sal_Int32 nCtrlIndex ) const
+{
+ if( rxCtrlModel.is() && mxSiteModel.get() && mxCtrlModel.get() )
+ {
+ const OUString& rCtrlName = mxSiteModel->getName();
+ OSL_ENSURE( rCtrlName.getLength() > 0, "VbaFormControl::convertProperties - control without name" );
+ if( rCtrlName.getLength() > 0 )
+ {
+ // convert all properties
+ PropertyMap aPropMap;
+ mxSiteModel->convertProperties( aPropMap, rConv, mxCtrlModel->getControlType(), nCtrlIndex );
+ mxCtrlModel->convertProperties( aPropMap, rConv );
+ mxCtrlModel->convertSize( aPropMap, rConv );
+ PropertySet aPropSet( rxCtrlModel );
+ aPropSet.setProperties( aPropMap );
+
+ // create and convert all embedded controls
+ if( !maControls.empty() ) try
+ {
+ Reference< XNameContainer > xCtrlModelNC( rxCtrlModel, UNO_QUERY_THROW );
+ /* Call conversion for all controls. Pass vector index as new
+ tab order to make option button groups work correctly. */
+ maControls.forEachMemWithIndex( &VbaFormControl::createAndConvert,
+ ::boost::cref( xCtrlModelNC ), ::boost::cref( rConv ) );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "VbaFormControl::convertProperties - cannot get control container interface" );
+ }
+
+ return true;
+ }
+ }
+ return false;
+}
+
+// private --------------------------------------------------------------------
+
+void VbaFormControl::createControlModel( const AxClassTable& rClassTable )
+{
+ // derived classes may have created their own control model
+ if( !mxCtrlModel && mxSiteModel.get() )
+ mxCtrlModel = mxSiteModel->createControlModel( rClassTable );
+}
+
+bool VbaFormControl::importSiteModel( BinaryInputStream& rInStrm )
+{
+ mxSiteModel.reset( new VbaSiteModel );
+ return mxSiteModel->importBinaryModel( rInStrm );
+}
+
+bool VbaFormControl::importEmbeddedSiteModels( BinaryInputStream& rInStrm )
+{
+ sal_uInt64 nAnchorPos = rInStrm.tell();
+ sal_uInt32 nSiteCount, nSiteDataSize;
+ rInStrm >> nSiteCount >> nSiteDataSize;
+ sal_Int64 nSiteEndPos = rInStrm.tell() + nSiteDataSize;
+
+ // skip the site info structure
+ sal_uInt32 nSiteIndex = 0;
+ while( !rInStrm.isEof() && (nSiteIndex < nSiteCount) )
+ {
+ rInStrm.skip( 1 ); // site depth
+ sal_uInt8 nTypeCount = rInStrm.readuInt8(); // 'type-or-count' byte
+ if( getFlag( nTypeCount, VBA_SITEINFO_COUNT ) )
+ {
+ /* Count flag is set: the 'type-or-count' byte contains the number
+ of controls in the lower bits, the type specifier follows in
+ the next byte. The type specifier should always be 1 according
+ to the specification. */
+ rInStrm.skip( 1 );
+ nSiteIndex += (nTypeCount & VBA_SITEINFO_MASK);
+ }
+ else
+ {
+ /* Count flag is not set: the 'type-or-count' byte contains the
+ type specifier of *one* control in the lower bits (this type
+ should be 1, see above). */
+ ++nSiteIndex;
+ }
+ }
+ // align the stream to 32bit, relative to start of entire site info
+ rInStrm.alignToBlock( 4, nAnchorPos );
+
+ // import the site models for all embedded controls
+ maControls.clear();
+ bool bValid = !rInStrm.isEof();
+ for( nSiteIndex = 0; bValid && (nSiteIndex < nSiteCount); ++nSiteIndex )
+ {
+ VbaFormControlRef xControl( new VbaFormControl );
+ maControls.push_back( xControl );
+ bValid = xControl->importSiteModel( rInStrm );
+ }
+
+ rInStrm.seek( nSiteEndPos );
+ return bValid;
+}
+
+void VbaFormControl::finalizeEmbeddedControls()
+{
+ /* This function performs two tasks:
+
+ 1) Reorder the controls appropriately (sort all option buttons of an
+ option group together to make grouping work).
+ 2) Move all children of all embedded frames (group boxes) to this
+ control (UNO group boxes cannot contain other controls).
+ */
+
+ // first, sort all controls by original tab index
+ ::std::sort( maControls.begin(), maControls.end(), &compareByTabIndex );
+
+ /* Collect the programmatical names of all embedded controls (needed to be
+ able to set unused names to new dummy controls created below). Also
+ collect the names of all children of embedded frames (group boxes).
+ Luckily, names of controls must be unique in the entire form, not just
+ in the current container. */
+ VbaControlNamesSet aControlNames;
+ VbaControlNameInserter aInserter( aControlNames );
+ maControls.forEach( aInserter );
+ for( VbaFormControlVector::iterator aIt = maControls.begin(), aEnd = maControls.end(); aIt != aEnd; ++aIt )
+ if( (*aIt)->mxCtrlModel.get() && ((*aIt)->mxCtrlModel->getControlType() == API_CONTROL_GROUPBOX) )
+ (*aIt)->maControls.forEach( aInserter );
+
+ /* Reprocess the sorted list and collect all option button controls that
+ are part of the same option group (determined by group name). All
+ controls will be stored in a vector of vectors, that collects every
+ option button group in one vector element, and other controls between
+ these option groups (or leading or trailing controls) in other vector
+ elements. If an option button group follows another group, a dummy
+ separator control has to be inserted. */
+ typedef RefVector< VbaFormControlVector > VbaFormControlVectorVector;
+ VbaFormControlVectorVector aControlGroups;
+
+ typedef RefMap< OUString, VbaFormControlVector > VbaFormControlVectorMap;
+ VbaFormControlVectorMap aOptionGroups;
+
+ typedef VbaFormControlVectorMap::mapped_type VbaFormControlVectorRef;
+ bool bLastWasOptionButton = false;
+ for( VbaFormControlVector::iterator aIt = maControls.begin(), aEnd = maControls.end(); aIt != aEnd; ++aIt )
+ {
+ VbaFormControlRef xControl = *aIt;
+ const ControlModelBase* pCtrlModel = xControl->mxCtrlModel.get();
+
+ if( const AxOptionButtonModel* pOptButtonModel = dynamic_cast< const AxOptionButtonModel* >( pCtrlModel ) )
+ {
+ // check if a new option group needs to be created
+ const OUString& rGroupName = pOptButtonModel->getGroupName();
+ VbaFormControlVectorRef& rxOptionGroup = aOptionGroups[ rGroupName ];
+ if( !rxOptionGroup )
+ {
+ /* If last control was an option button too, we have two
+ option groups following each other, so a dummy separator
+ control is needed. */
+ if( bLastWasOptionButton )
+ {
+ VbaFormControlVectorRef xDummyGroup( new VbaFormControlVector );
+ aControlGroups.push_back( xDummyGroup );
+ OUString aName = aControlNames.generateDummyName();
+ VbaFormControlRef xDummyControl( new VbaDummyFormControl( aName ) );
+ xDummyGroup->push_back( xDummyControl );
+ }
+ rxOptionGroup.reset( new VbaFormControlVector );
+ aControlGroups.push_back( rxOptionGroup );
+ }
+ /* Append the option button to the control group (which is now
+ referred by the vector aControlGroups and by the map
+ aOptionGroups). */
+ rxOptionGroup->push_back( xControl );
+ bLastWasOptionButton = true;
+ }
+ else
+ {
+ // open a new control group, if the last group is an option group
+ if( bLastWasOptionButton || aControlGroups.empty() )
+ {
+ VbaFormControlVectorRef xControlGroup( new VbaFormControlVector );
+ aControlGroups.push_back( xControlGroup );
+ }
+ // append the control to the last control group
+ VbaFormControlVector& rLastGroup = *aControlGroups.back();
+ rLastGroup.push_back( xControl );
+ bLastWasOptionButton = false;
+
+ // if control is a group box, move all its children to this control
+ if( pCtrlModel && (pCtrlModel->getControlType() == API_CONTROL_GROUPBOX) )
+ {
+ /* Move all embedded controls of the group box relative to the
+ position of the group box. */
+ xControl->moveEmbeddedToAbsoluteParent();
+ /* Insert all children of the group box into the last control
+ group (following the group box). */
+ rLastGroup.insert( rLastGroup.end(), xControl->maControls.begin(), xControl->maControls.end() );
+ xControl->maControls.clear();
+ // check if last control of the group box is an option button
+ bLastWasOptionButton = dynamic_cast< const AxOptionButtonModel* >( rLastGroup.back()->mxCtrlModel.get() ) != 0;
+ }
+ }
+ }
+
+ // flatten the vector of vectors of form controls to a single vector
+ maControls.clear();
+ for( VbaFormControlVectorVector::iterator aIt = aControlGroups.begin(), aEnd = aControlGroups.end(); aIt != aEnd; ++aIt )
+ maControls.insert( maControls.end(), (*aIt)->begin(), (*aIt)->end() );
+}
+
+void VbaFormControl::moveRelative( const AxPairData& rDistance )
+{
+ if( mxSiteModel.get() )
+ mxSiteModel->moveRelative( rDistance );
+}
+
+void VbaFormControl::moveEmbeddedToAbsoluteParent()
+{
+ if( mxSiteModel.get() && !maControls.empty() )
+ {
+ // distance to move is equal to position of this control in its parent
+ AxPairData aDistance = mxSiteModel->getPosition();
+
+ /* For group boxes: add half of the font height to Y position (VBA
+ positions relative to frame border line, not to 'top' of frame). */
+ const AxFontDataModel* pFontModel = dynamic_cast< const AxFontDataModel* >( mxCtrlModel.get() );
+ if( pFontModel && (pFontModel->getControlType() == API_CONTROL_GROUPBOX) )
+ {
+ // convert points to 1/100 mm (1 pt = 1/72 inch = 2.54/72 cm = 2540/72 1/100 mm)
+ sal_Int32 nFontHeight = static_cast< sal_Int32 >( pFontModel->getFontHeight() * 2540 / 72 );
+ aDistance.second += nFontHeight / 2;
+ }
+
+ // move the embedded controls
+ maControls.forEachMem( &VbaFormControl::moveRelative, ::boost::cref( aDistance ) );
+ }
+}
+
+/*static*/ bool VbaFormControl::compareByTabIndex( const VbaFormControlRef& rxLeft, const VbaFormControlRef& rxRight )
+{
+ // sort controls without model to the end
+ sal_Int32 nLeftTabIndex = rxLeft->mxSiteModel.get() ? rxLeft->mxSiteModel->getTabIndex() : SAL_MAX_INT32;
+ sal_Int32 nRightTabIndex = rxRight->mxSiteModel.get() ? rxRight->mxSiteModel->getTabIndex() : SAL_MAX_INT32;
+ return nLeftTabIndex < nRightTabIndex;
+}
+
+// ============================================================================
+
+namespace {
+
+OUString lclGetQuotedString( const OUString& rCodeLine )
+{
+ OUStringBuffer aBuffer;
+ sal_Int32 nLen = rCodeLine.getLength();
+ if( (nLen > 0) && (rCodeLine[ 0 ] == '"') )
+ {
+ bool bExitLoop = false;
+ for( sal_Int32 nIndex = 1; !bExitLoop && (nIndex < nLen); ++nIndex )
+ {
+ sal_Unicode cChar = rCodeLine[ nIndex ];
+ // exit on closing quote char (but check on double quote chars)
+ bExitLoop = (cChar == '"') && ((nIndex + 1 == nLen) || (rCodeLine[ nIndex + 1 ] != '"'));
+ if( !bExitLoop )
+ {
+ aBuffer.append( cChar );
+ // skip second quote char
+ if( cChar == '"' )
+ ++nIndex;
+ }
+ }
+ }
+ return aBuffer.makeStringAndClear();
+}
+
+bool lclEatWhitespace( OUString& rCodeLine )
+{
+ sal_Int32 nIndex = 0;
+ while( (nIndex < rCodeLine.getLength()) && ((rCodeLine[ nIndex ] == ' ') || (rCodeLine[ nIndex ] == '\t')) )
+ ++nIndex;
+ if( nIndex > 0 )
+ {
+ rCodeLine = rCodeLine.copy( nIndex );
+ return true;
+ }
+ return false;
+}
+
+bool lclEatKeyword( OUString& rCodeLine, const OUString& rKeyword )
+{
+ if( rCodeLine.matchIgnoreAsciiCase( rKeyword ) )
+ {
+ rCodeLine = rCodeLine.copy( rKeyword.getLength() );
+ // success, if code line ends after keyword, or if whitespace follows
+ return (rCodeLine.getLength() == 0) || lclEatWhitespace( rCodeLine );
+ }
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+VbaUserForm::VbaUserForm( const Reference< XComponentContext >& rxContext,
+ const Reference< XModel >& rxDocModel, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
+ mxCompContext( rxContext ),
+ mxDocModel( rxDocModel ),
+ maConverter( rxDocModel, rGraphicHelper, bDefaultColorBgr )
+{
+ OSL_ENSURE( mxCompContext.is(), "VbaUserForm::VbaUserForm - missing component context" );
+ OSL_ENSURE( mxDocModel.is(), "VbaUserForm::VbaUserForm - missing document model" );
+}
+
+void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib,
+ StorageBase& rVbaFormStrg, const OUString& rModuleName, rtl_TextEncoding eTextEnc )
+{
+ OSL_ENSURE( rxDialogLib.is(), "VbaUserForm::importForm - missing dialog library" );
+ if( !mxCompContext.is() || !mxDocModel.is() || !rxDialogLib.is() )
+ return;
+
+ // check that the '03VBFrame' stream exists, this is required for forms
+ BinaryXInputStream aInStrm( rVbaFormStrg.openInputStream( CREATE_OUSTRING( "\003VBFrame" ) ), true );
+ OSL_ENSURE( !aInStrm.isEof(), "VbaUserForm::importForm - missing \\003VBFrame stream" );
+ if( aInStrm.isEof() )
+ return;
+
+ // scan for the line 'Begin {GUID} <FormName>'
+ TextInputStream aFrameTextStrm( aInStrm, eTextEnc );
+ const OUString aBegin = CREATE_OUSTRING( "Begin" );
+ OUString aLine;
+ bool bBeginFound = false;
+ while( !bBeginFound && !aFrameTextStrm.isEof() )
+ {
+ aLine = aFrameTextStrm.readLine().trim();
+ bBeginFound = lclEatKeyword( aLine, aBegin );
+ }
+ // check for the specific GUID that represents VBA forms
+ if( !bBeginFound || !lclEatKeyword( aLine, CREATE_OUSTRING( "{C62A69F0-16DC-11CE-9E98-00AA00574A4F}" ) ) )
+ return;
+
+ // remaining line is the form name
+ OUString aFormName = aLine.trim();
+ OSL_ENSURE( aFormName.getLength() > 0, "VbaUserForm::importForm - missing form name" );
+ OSL_ENSURE( rModuleName.equalsIgnoreAsciiCase( aFormName ), "VbaUserForm::importFrameStream - form and module name mismatch" );
+ if( aFormName.getLength() == 0 )
+ aFormName = rModuleName;
+ if( aFormName.getLength() == 0 )
+ return;
+ mxSiteModel.reset( new VbaSiteModel );
+ mxSiteModel->importProperty( XML_Name, aFormName );
+
+ // read the form properties (caption is contained in this '03VBFrame' stream, not in the 'f' stream)
+ mxCtrlModel.reset( new AxUserFormModel );
+ OUString aKey, aValue;
+ bool bExitLoop = false;
+ while( !bExitLoop && !aFrameTextStrm.isEof() )
+ {
+ aLine = aFrameTextStrm.readLine().trim();
+ bExitLoop = aLine.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "End" ) );
+ if( !bExitLoop && VbaHelper::extractKeyValue( aKey, aValue, aLine ) )
+ {
+ if( aKey.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "Caption" ) ) )
+ mxCtrlModel->importProperty( XML_Caption, lclGetQuotedString( aValue ) );
+ else if( aKey.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "Tag" ) ) )
+ mxSiteModel->importProperty( XML_Tag, lclGetQuotedString( aValue ) );
+ }
+ }
+
+ // use generic container control functionality to import the embedded controls
+ importStorage( rVbaFormStrg, AxClassTable() );
+
+ try
+ {
+ // create the dialog model
+ OUString aServiceName = mxCtrlModel->getServiceName();
+ Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW );
+ Reference< XControlModel > xDialogModel( xFactory->createInstance( aServiceName ), UNO_QUERY_THROW );
+ Reference< XNameContainer > xDialogNC( xDialogModel, UNO_QUERY_THROW );
+
+ // convert properties and embedded controls
+ if( convertProperties( xDialogModel, maConverter, 0 ) )
+ {
+ // export the dialog to XML and insert it into the dialog library
+ Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxCompContext ), UNO_SET_THROW );
+ OSL_ENSURE( !rxDialogLib->hasByName( aFormName ), "VbaUserForm::importForm - multiple dialogs with equal name" );
+ ContainerHelper::insertByName( rxDialogLib, aFormName, Any( xDialogSource ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/vbahelper.cxx b/oox/source/ole/vbahelper.cxx
new file mode 100644
index 000000000000..82d38d83610c
--- /dev/null
+++ b/oox/source/ole/vbahelper.cxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/vbahelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+/*static*/ OUString VbaHelper::getBasicScriptUrl(
+ const OUString& rLibraryName, const OUString& rModuleName, const OUString& rMacroName )
+{
+ OSL_ENSURE( rLibraryName.getLength() > 0, "VbaHelper::getBasicScriptUrl - library name is empty" );
+ OSL_ENSURE( rModuleName.getLength() > 0, "VbaHelper::getBasicScriptUrl - module name is empty" );
+ OSL_ENSURE( rMacroName.getLength() > 0, "VbaHelper::getBasicScriptUrl - macro name is empty" );
+ const sal_Unicode cDot = '.';
+ return OUStringBuffer().
+ appendAscii( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.script:" ) ).
+ append( rLibraryName ).append( cDot ).append( rModuleName ).append( cDot ).append( rMacroName ).
+ appendAscii( RTL_CONSTASCII_STRINGPARAM( "?language=Basic&location=document" ) ).
+ makeStringAndClear();
+}
+
+/*static*/ bool VbaHelper::readDirRecord( sal_uInt16& rnRecId, StreamDataSequence& rRecData, BinaryInputStream& rInStrm )
+{
+ // read the record header
+ sal_Int32 nRecSize;
+ rInStrm >> rnRecId >> nRecSize;
+ // for no obvious reason, PROJECTVERSION record contains size field of 4, but is 6 bytes long
+ if( rnRecId == VBA_ID_PROJECTVERSION )
+ {
+ OSL_ENSURE( nRecSize == 4, "VbaHelper::readDirRecord - unexpected record size for PROJECTVERSION" );
+ nRecSize = 6;
+ }
+ // read the record contents into the passed sequence
+ return !rInStrm.isEof() && (rInStrm.readData( rRecData, nRecSize ) == nRecSize);
+}
+
+/*static*/ bool VbaHelper::extractKeyValue( OUString& rKey, OUString& rValue, const OUString& rKeyValue )
+{
+ sal_Int32 nEqSignPos = rKeyValue.indexOf( '=' );
+ if( nEqSignPos > 0 )
+ {
+ rKey = rKeyValue.copy( 0, nEqSignPos ).trim();
+ rValue = rKeyValue.copy( nEqSignPos + 1 ).trim();
+ return (rKey.getLength() > 0) && (rValue.getLength() > 0);
+ }
+ return false;
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/vbainputstream.cxx b/oox/source/ole/vbainputstream.cxx
new file mode 100644
index 000000000000..e56e8b5fbc89
--- /dev/null
+++ b/oox/source/ole/vbainputstream.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/vbainputstream.hxx"
+#include <osl/diagnose.h>
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt8 VBASTREAM_SIGNATURE = 1;
+
+const sal_uInt16 VBACHUNK_SIGMASK = 0x7000;
+const sal_uInt16 VBACHUNK_SIG = 0x3000;
+const sal_uInt16 VBACHUNK_COMPRESSED = 0x8000;
+const sal_uInt16 VBACHUNK_LENMASK = 0x0FFF;
+
+} // namespace
+
+// ============================================================================
+
+VbaInputStream::VbaInputStream( BinaryInputStream& rInStrm ) :
+ mrInStrm( rInStrm ),
+ mnChunkPos( 0 )
+{
+ maChunk.reserve( 4096 );
+
+ sal_uInt8 nSig = mrInStrm.readuInt8();
+ OSL_ENSURE( nSig == VBASTREAM_SIGNATURE, "VbaInputStream::VbaInputStream - wrong signature" );
+ mbEof = nSig != VBASTREAM_SIGNATURE;
+}
+
+sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = 0;
+ if( !mbEof )
+ {
+ orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) );
+ if( nBytes > 0 )
+ {
+ nRet = readMemory( orData.getArray(), nBytes );
+ if( nRet < nBytes )
+ orData.realloc( nRet );
+ }
+ }
+ return nRet;
+}
+
+sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = 0;
+ sal_uInt8* opnMem = reinterpret_cast< sal_uInt8* >( opMem );
+ while( (nBytes > 0) && updateChunk() )
+ {
+ sal_Int32 nChunkLeft = static_cast< sal_Int32 >( maChunk.size() - mnChunkPos );
+ sal_Int32 nReadBytes = ::std::min( nBytes, nChunkLeft );
+ memcpy( opnMem, &*(maChunk.begin() + mnChunkPos), nReadBytes );
+ opnMem += nReadBytes;
+ mnChunkPos += static_cast< size_t >( nReadBytes );
+ nBytes -= nReadBytes;
+ nRet += nReadBytes;
+ }
+ return nRet;
+}
+
+void VbaInputStream::skip( sal_Int32 nBytes )
+{
+ while( (nBytes > 0) && updateChunk() )
+ {
+ sal_Int32 nChunkLeft = static_cast< sal_Int32 >( maChunk.size() - mnChunkPos );
+ sal_Int32 nSkipBytes = ::std::min( nBytes, nChunkLeft );
+ mnChunkPos += static_cast< size_t >( nSkipBytes );
+ nBytes -= nSkipBytes;
+ }
+}
+
+// private --------------------------------------------------------------------
+
+bool VbaInputStream::updateChunk()
+{
+ if( mbEof || (mnChunkPos < maChunk.size()) ) return !mbEof;
+
+ // try to read next chunk header, this may trigger EOF
+ sal_uInt16 nHeader = mrInStrm.readuInt16();
+ mbEof = mrInStrm.isEof();
+ if( mbEof ) return false;
+
+ // check header signature
+ OSL_ENSURE( (nHeader & VBACHUNK_SIGMASK) == VBACHUNK_SIG, "VbaInputStream::updateChunk - invalid chunk signature" );
+ mbEof = (nHeader & VBACHUNK_SIGMASK) != VBACHUNK_SIG;
+ if( mbEof ) return false;
+
+ // decode length of chunk data and compression flag
+ bool bCompressed = getFlag( nHeader, VBACHUNK_COMPRESSED );
+ sal_uInt16 nChunkLen = (nHeader & VBACHUNK_LENMASK) + 1;
+ OSL_ENSURE( bCompressed || (nChunkLen == 4096), "VbaInputStream::updateChunk - invalid uncompressed chunk size" );
+ if( bCompressed )
+ {
+ maChunk.clear();
+ sal_uInt8 nBitCount = 4;
+ sal_uInt16 nChunkPos = 0;
+ while( !mbEof && !mrInStrm.isEof() && (nChunkPos < nChunkLen) )
+ {
+ sal_uInt8 nTokenFlags = mrInStrm.readuInt8();
+ ++nChunkPos;
+ for( int nBit = 0; !mbEof && !mrInStrm.isEof() && (nBit < 8) && (nChunkPos < nChunkLen); ++nBit, nTokenFlags >>= 1 )
+ {
+ if( nTokenFlags & 1 )
+ {
+ sal_uInt16 nCopyToken = mrInStrm.readuInt16();
+ nChunkPos = nChunkPos + 2;
+ // update bit count used for offset/length in the token
+ while( static_cast< size_t >( 1 << nBitCount ) < maChunk.size() ) ++nBitCount;
+ // extract length from lower (16-nBitCount) bits, plus 3
+ sal_uInt16 nLength = extractValue< sal_uInt16 >( nCopyToken, 0, 16 - nBitCount ) + 3;
+ // extract offset from high nBitCount bits, plus 1
+ sal_uInt16 nOffset = extractValue< sal_uInt16 >( nCopyToken, 16 - nBitCount, nBitCount ) + 1;
+ mbEof = (nOffset > maChunk.size()) || (maChunk.size() + nLength > 4096);
+ OSL_ENSURE( !mbEof, "VbaInputStream::updateChunk - invalid offset or size in copy token" );
+ if( !mbEof )
+ {
+ // append data to buffer
+ maChunk.resize( maChunk.size() + nLength );
+ sal_uInt8* pnTo = &*(maChunk.end() - nLength);
+ const sal_uInt8* pnEnd = pnTo + nLength;
+ const sal_uInt8* pnFrom = pnTo - nOffset;
+ // offset may be less than length, effectively duplicating source data several times
+ size_t nRunLen = ::std::min< size_t >( nLength, nOffset );
+ while( pnTo < pnEnd )
+ {
+ size_t nStepLen = ::std::min< size_t >( nRunLen, pnEnd - pnTo );
+ memcpy( pnTo, pnFrom, nStepLen );
+ pnTo += nStepLen;
+ }
+ }
+ }
+ else
+ {
+ maChunk.resize( maChunk.size() + 1 );
+ mrInStrm >> maChunk.back();
+ ++nChunkPos;
+ }
+ }
+ }
+ }
+ else
+ {
+ maChunk.resize( nChunkLen );
+ mrInStrm.readMemory( &maChunk.front(), nChunkLen );
+ }
+
+ mnChunkPos = 0;
+ return !mbEof;
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
+
diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx
new file mode 100644
index 000000000000..2da92b935004
--- /dev/null
+++ b/oox/source/ole/vbamodule.cxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/vbamodule.hxx"
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/storagebase.hxx"
+#include "oox/helper/textinputstream.hxx"
+#include "oox/ole/vbahelper.hxx"
+#include "oox/ole/vbainputstream.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::script::vba;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+VbaModule::VbaModule( const Reference< XModel >& rxDocModel, const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) :
+ mxDocModel( rxDocModel ),
+ maName( rName ),
+ meTextEnc( eTextEnc ),
+ mnType( ModuleType::UNKNOWN ),
+ mnOffset( SAL_MAX_UINT32 ),
+ mbReadOnly( false ),
+ mbPrivate( false ),
+ mbExecutable( bExecutable )
+{
+}
+
+void VbaModule::importDirRecords( BinaryInputStream& rDirStrm )
+{
+ sal_uInt16 nRecId = 0;
+ StreamDataSequence aRecData;
+ while( VbaHelper::readDirRecord( nRecId, aRecData, rDirStrm ) && (nRecId != VBA_ID_MODULEEND) )
+ {
+ SequenceInputStream aRecStrm( aRecData );
+ sal_Int32 nRecSize = aRecData.getLength();
+ switch( nRecId )
+ {
+#define OOX_ENSURE_RECORDSIZE( cond ) OSL_ENSURE( cond, "VbaModule::importDirRecords - invalid record size" )
+ case VBA_ID_MODULENAME:
+ OSL_ENSURE( false, "VbaModule::importDirRecords - unexpected MODULENAME record" );
+ maName = aRecStrm.readCharArrayUC( nRecSize, meTextEnc );
+ break;
+ case VBA_ID_MODULENAMEUNICODE:
+ break;
+ case VBA_ID_MODULESTREAMNAME:
+ maStreamName = aRecStrm.readCharArrayUC( nRecSize, meTextEnc );
+ break;
+ case VBA_ID_MODULESTREAMNAMEUNICODE:
+ break;
+ case VBA_ID_MODULEDOCSTRING:
+ maDocString = aRecStrm.readCharArrayUC( nRecSize, meTextEnc );
+ break;
+ case VBA_ID_MODULEDOCSTRINGUNICODE:
+ break;
+ case VBA_ID_MODULEOFFSET:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 4 );
+ aRecStrm >> mnOffset;
+ break;
+ case VBA_ID_MODULEHELPCONTEXT:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 4 );
+ break;
+ case VBA_ID_MODULECOOKIE:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 2 );
+ break;
+ case VBA_ID_MODULETYPEPROCEDURAL:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
+ OSL_ENSURE( mnType == ModuleType::UNKNOWN, "VbaModule::importDirRecords - multiple module type records" );
+ mnType = ModuleType::NORMAL;
+ break;
+ case VBA_ID_MODULETYPEDOCUMENT:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
+ OSL_ENSURE( mnType == ModuleType::UNKNOWN, "VbaModule::importDirRecords - multiple module type records" );
+ mnType = ModuleType::DOCUMENT;
+ break;
+ case VBA_ID_MODULEREADONLY:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
+ mbReadOnly = true;
+ break;
+ case VBA_ID_MODULEPRIVATE:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
+ mbPrivate = true;
+ break;
+ default:
+ OSL_ENSURE( false, "VbaModule::importDirRecords - unknown module record" );
+#undef OOX_ENSURE_RECORDSIZE
+ }
+ }
+ OSL_ENSURE( maName.getLength() > 0, "VbaModule::importDirRecords - missing module name" );
+ OSL_ENSURE( maStreamName.getLength() > 0, "VbaModule::importDirRecords - missing module stream name" );
+ OSL_ENSURE( mnType != ModuleType::UNKNOWN, "VbaModule::importDirRecords - missing module type" );
+ OSL_ENSURE( mnOffset < SAL_MAX_UINT32, "VbaModule::importDirRecords - missing module stream offset" );
+}
+
+void VbaModule::createAndImportModule( StorageBase& rVbaStrg, const Reference< XNameContainer >& rxBasicLib,
+ const Reference< XNameAccess >& rxDocObjectNA ) const
+{
+ OUString aVBASourceCode = readSourceCode( rVbaStrg );
+ createModule( aVBASourceCode, rxBasicLib, rxDocObjectNA );
+}
+
+void VbaModule::createEmptyModule( const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+{
+ createModule( OUString(), rxBasicLib, rxDocObjectNA );
+}
+
+// private --------------------------------------------------------------------
+
+OUString VbaModule::readSourceCode( StorageBase& rVbaStrg ) const
+{
+ OUStringBuffer aSourceCode;
+ if( (maStreamName.getLength() > 0) && (mnOffset != SAL_MAX_UINT32) )
+ {
+ BinaryXInputStream aInStrm( rVbaStrg.openInputStream( maStreamName ), true );
+ OSL_ENSURE( !aInStrm.isEof(), "VbaModule::readSourceCode - cannot open module stream" );
+ // skip the 'performance cache' stored before the actual source code
+ aInStrm.seek( mnOffset );
+ // if stream is still valid, load the source code
+ if( !aInStrm.isEof() )
+ {
+ // decompression starts at current stream position of aInStrm
+ VbaInputStream aVbaStrm( aInStrm );
+ // load the source code line-by-line, with some more processing
+ TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc );
+ while( !aVbaTextStrm.isEof() )
+ {
+ OUString aCodeLine = aVbaTextStrm.readLine();
+ if( !aCodeLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Attribute " ) ) )
+ {
+ // normal source code line
+ if( !mbExecutable )
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem " ) );
+ aSourceCode.append( aCodeLine ).append( sal_Unicode( '\n' ) );
+ }
+ }
+ }
+ }
+ return aSourceCode.makeStringAndClear();
+}
+
+void VbaModule::createModule( const OUString& rVBASourceCode,
+ const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+{
+ if( maName.getLength() == 0 )
+ return;
+
+ // prepare the Basic module
+ ModuleInfo aModuleInfo;
+ aModuleInfo.ModuleType = mnType;
+ OUStringBuffer aSourceCode;
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem Attribute VBA_ModuleType=" ) );
+ switch( mnType )
+ {
+ case ModuleType::NORMAL:
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAModule" ) );
+ break;
+ case ModuleType::CLASS:
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAClassModule" ) );
+ break;
+ case ModuleType::FORM:
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAFormModule" ) );
+ // hack from old filter, document Basic should know the XModel, but it doesn't
+ aModuleInfo.ModuleObject.set( mxDocModel, UNO_QUERY );
+ break;
+ case ModuleType::DOCUMENT:
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBADocumentModule" ) );
+ // get the VBA implementation object associated to the document module
+ if( rxDocObjectNA.is() ) try
+ {
+ aModuleInfo.ModuleObject.set( rxDocObjectNA->getByName( maName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ break;
+ default:
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAUnknown" ) );
+ }
+ aSourceCode.append( sal_Unicode( '\n' ) );
+ if( mbExecutable )
+ {
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Option VBASupport 1\n" ) );
+ if( mnType == ModuleType::CLASS )
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Option ClassModule\n" ) );
+ }
+ else
+ {
+ // add a subroutine named after the module itself
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Sub " ) ).
+ append( maName.replace( ' ', '_' ) ).append( sal_Unicode( '\n' ) );
+ }
+
+ // append passed VBA source code
+ aSourceCode.append( rVBASourceCode );
+
+ // close the subroutine named after the module
+ if( !mbExecutable )
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "End Sub\n" ) );
+
+ // insert extended module info
+ try
+ {
+ Reference< XVBAModuleInfo > xVBAModuleInfo( rxBasicLib, UNO_QUERY_THROW );
+ xVBAModuleInfo->insertModuleInfo( maName, aModuleInfo );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // insert the module into the passed Basic library
+ try
+ {
+ rxBasicLib->insertByName( maName, Any( aSourceCode.makeStringAndClear() ) );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "VbaModule::createModule - cannot insert module into library" );
+ }
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
new file mode 100644
index 000000000000..35e6b7911012
--- /dev/null
+++ b/oox/source/ole/vbaproject.cxx
@@ -0,0 +1,548 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/vbaproject.hxx"
+
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/script/vba/XVBAMacroResolver.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <comphelper/configurationhelper.hxx>
+#include <comphelper/string.hxx>
+#include <rtl/tencinfo.h>
+#include <rtl/ustrbuf.h>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/textinputstream.hxx"
+#include "oox/ole/olestorage.hxx"
+#include "oox/ole/vbacontrol.hxx"
+#include "oox/ole/vbahelper.hxx"
+#include "oox/ole/vbainputstream.hxx"
+#include "oox/ole/vbamodule.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::script::vba;
+using namespace ::com::sun::star::uno;
+
+using ::comphelper::ConfigurationHelper;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+bool lclReadConfigItem( const Reference< XInterface >& rxConfigAccess, const OUString& rItemName )
+{
+ // some applications do not support all configuration items, assume 'false' in this case
+ try
+ {
+ Any aItem = ConfigurationHelper::readRelativeKey( rxConfigAccess, CREATE_OUSTRING( "Filter/Import/VBA" ), rItemName );
+ return aItem.has< bool >() && aItem.get< bool >();
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+VbaFilterConfig::VbaFilterConfig( const Reference< XComponentContext >& rxContext, const OUString& rConfigCompName )
+{
+ OSL_ENSURE( rxContext.is(), "VbaFilterConfig::VbaFilterConfig - missing component context" );
+ if( rxContext.is() ) try
+ {
+ OSL_ENSURE( rConfigCompName.getLength() > 0, "VbaFilterConfig::VbaFilterConfig - invalid configuration component name" );
+ OUString aConfigPackage = CREATE_OUSTRING( "org.openoffice.Office." ) + rConfigCompName;
+ Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
+ mxConfigAccess = ConfigurationHelper::openConfig( xFactory, aConfigPackage, ConfigurationHelper::E_READONLY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( mxConfigAccess.is(), "VbaFilterConfig::VbaFilterConfig - cannot open configuration" );
+}
+
+VbaFilterConfig::~VbaFilterConfig()
+{
+}
+
+bool VbaFilterConfig::isImportVba() const
+{
+ return lclReadConfigItem( mxConfigAccess, CREATE_OUSTRING( "Load" ) );
+}
+
+bool VbaFilterConfig::isImportVbaExecutable() const
+{
+ return lclReadConfigItem( mxConfigAccess, CREATE_OUSTRING( "Executable" ) );
+}
+
+bool VbaFilterConfig::isExportVba() const
+{
+ return lclReadConfigItem( mxConfigAccess, CREATE_OUSTRING( "Save" ) );
+}
+
+// ============================================================================
+
+VbaMacroAttacherBase::VbaMacroAttacherBase( const OUString& rMacroName ) :
+ maMacroName( rMacroName )
+{
+ OSL_ENSURE( maMacroName.getLength() > 0, "VbaMacroAttacherBase::VbaMacroAttacherBase - empty macro name" );
+}
+
+VbaMacroAttacherBase::~VbaMacroAttacherBase()
+{
+}
+
+void VbaMacroAttacherBase::resolveAndAttachMacro( const Reference< XVBAMacroResolver >& rxResolver )
+{
+ try
+ {
+ attachMacro( rxResolver->resolveVBAMacroToScriptURL( maMacroName ) );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+VbaProject::VbaProject( const Reference< XComponentContext >& rxContext,
+ const Reference< XModel >& rxDocModel, const OUString& rConfigCompName ) :
+ VbaFilterConfig( rxContext, rConfigCompName ),
+ mxCompContext( rxContext ),
+ mxDocModel( rxDocModel ),
+ maPrjName( CREATE_OUSTRING( "Standard" ) )
+{
+ OSL_ENSURE( mxCompContext.is(), "VbaProject::VbaProject - missing component context" );
+ OSL_ENSURE( mxDocModel.is(), "VbaProject::VbaProject - missing document model" );
+ mxBasicLib = openLibrary( PROP_BasicLibraries, false );
+ mxDialogLib = openLibrary( PROP_DialogLibraries, false );
+}
+
+VbaProject::~VbaProject()
+{
+}
+
+void VbaProject::importVbaProject( StorageBase& rVbaPrjStrg, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr )
+{
+ if( rVbaPrjStrg.isStorage() )
+ {
+ // load the code modules and forms
+ if( isImportVba() )
+ importVba( rVbaPrjStrg, rGraphicHelper, bDefaultColorBgr );
+ // copy entire storage into model
+ if( isExportVba() )
+ copyStorage( rVbaPrjStrg );
+ }
+}
+
+void VbaProject::registerMacroAttacher( const VbaMacroAttacherRef& rxAttacher )
+{
+ OSL_ENSURE( rxAttacher.get(), "VbaProject::registerMacroAttacher - unexpected empty reference" );
+ maMacroAttachers.push_back( rxAttacher );
+}
+
+bool VbaProject::hasModules() const
+{
+ return mxBasicLib.is() && mxBasicLib->hasElements();
+}
+
+bool VbaProject::hasModule( const OUString& rModuleName ) const
+{
+ return mxBasicLib.is() && mxBasicLib->hasByName( rModuleName );
+}
+
+bool VbaProject::hasDialogs() const
+{
+ return mxDialogLib.is() && mxDialogLib->hasElements();
+}
+
+bool VbaProject::hasDialog( const OUString& rDialogName ) const
+{
+ return mxDialogLib.is() && mxDialogLib->hasByName( rDialogName );
+}
+
+// protected ------------------------------------------------------------------
+
+void VbaProject::addDummyModule( const OUString& rName, sal_Int32 nType )
+{
+ OSL_ENSURE( rName.getLength() > 0, "VbaProject::addDummyModule - missing module name" );
+ maDummyModules[ rName ] = nType;
+}
+
+void VbaProject::prepareImport()
+{
+}
+
+void VbaProject::finalizeImport()
+{
+}
+
+// private --------------------------------------------------------------------
+
+Reference< XLibraryContainer > VbaProject::getLibraryContainer( sal_Int32 nPropId )
+{
+ PropertySet aDocProp( mxDocModel );
+ Reference< XLibraryContainer > xLibContainer( aDocProp.getAnyProperty( nPropId ), UNO_QUERY );
+ return xLibContainer;
+}
+
+Reference< XNameContainer > VbaProject::openLibrary( sal_Int32 nPropId, bool bCreateMissing )
+{
+ Reference< XNameContainer > xLibrary;
+ try
+ {
+ Reference< XLibraryContainer > xLibContainer( getLibraryContainer( nPropId ), UNO_SET_THROW );
+ if( bCreateMissing && !xLibContainer->hasByName( CREATE_OUSTRING( "Standard" ) /*maPrjName*/ ) )
+ xLibContainer->createLibrary( CREATE_OUSTRING( "Standard" ) /*maPrjName*/ );
+ xLibrary.set( xLibContainer->getByName( CREATE_OUSTRING( "Standard" ) /*maPrjName*/ ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( !bCreateMissing || xLibrary.is(), "VbaProject::openLibrary - cannot create library" );
+ return xLibrary;
+}
+
+Reference< XNameContainer > VbaProject::createBasicLibrary()
+{
+ if( !mxBasicLib.is() )
+ mxBasicLib = openLibrary( PROP_BasicLibraries, true );
+ return mxBasicLib;
+}
+
+Reference< XNameContainer > VbaProject::createDialogLibrary()
+{
+ if( !mxDialogLib.is() )
+ mxDialogLib = openLibrary( PROP_DialogLibraries, true );
+ return mxDialogLib;
+}
+
+void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr )
+{
+ StorageRef xVbaStrg = rVbaPrjStrg.openSubStorage( CREATE_OUSTRING( "VBA" ), false );
+ OSL_ENSURE( xVbaStrg.get(), "VbaProject::importVba - cannot open 'VBA' substorage" );
+ if( !xVbaStrg )
+ return;
+
+ /* Read the 'VBA/dir' stream which contains general settings of the VBA
+ project such as the text encoding used throughout several streams, and
+ a list of all code modules.
+ */
+ BinaryXInputStream aInStrm( xVbaStrg->openInputStream( CREATE_OUSTRING( "dir" ) ), true );
+ // VbaInputStream implements decompression
+ VbaInputStream aDirStrm( aInStrm );
+ OSL_ENSURE( !aDirStrm.isEof(), "VbaProject::importVba - cannot open 'dir' stream" );
+ if( aDirStrm.isEof() )
+ return;
+
+ // virtual call, derived classes may do some preparations
+ prepareImport();
+
+ // read all records of the directory
+ rtl_TextEncoding eTextEnc = RTL_TEXTENCODING_MS_1252;
+ sal_uInt16 nModuleCount = 0;
+ bool bExecutable = isImportVbaExecutable();
+
+ typedef RefMap< OUString, VbaModule > VbaModuleMap;
+ VbaModuleMap aModules, aModulesByStrm;
+
+ sal_uInt16 nRecId = 0;
+ StreamDataSequence aRecData;
+ while( VbaHelper::readDirRecord( nRecId, aRecData, aDirStrm ) && (nRecId != VBA_ID_PROJECTEND) )
+ {
+ // create record stream object from imported record data
+ SequenceInputStream aRecStrm( aRecData );
+ sal_Int32 nRecSize = aRecData.getLength();
+ switch( nRecId )
+ {
+#define OOX_ENSURE_RECORDSIZE( cond ) OSL_ENSURE( cond, "VbaProject::importVba - invalid record size" )
+ case VBA_ID_PROJECTCODEPAGE:
+ {
+ OOX_ENSURE_RECORDSIZE( nRecSize == 2 );
+ OSL_ENSURE( aModules.empty(), "VbaProject::importVba - unexpected PROJECTCODEPAGE record" );
+ rtl_TextEncoding eNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( aRecStrm.readuInt16() );
+ OSL_ENSURE( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW, "VbaProject::importVba - unknown text encoding" );
+ if( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ eTextEnc = eNewTextEnc;
+ }
+ break;
+ case VBA_ID_PROJECTNAME:
+ {
+ OUString aPrjName = aRecStrm.readCharArrayUC( nRecSize, eTextEnc );
+ OSL_ENSURE( aPrjName.getLength() > 0, "VbaProject::importVba - invalid project name" );
+ if( aPrjName.getLength() > 0 )
+ maPrjName = aPrjName;
+ }
+ break;
+ case VBA_ID_PROJECTMODULES:
+ OOX_ENSURE_RECORDSIZE( nRecSize == 2 );
+ OSL_ENSURE( aModules.empty(), "VbaProject::importVba - unexpected PROJECTMODULES record" );
+ aRecStrm >> nModuleCount;
+ break;
+ case VBA_ID_MODULENAME:
+ {
+ OUString aName = aRecStrm.readCharArrayUC( nRecSize, eTextEnc );
+ OSL_ENSURE( aName.getLength() > 0, "VbaProject::importVba - invalid module name" );
+ OSL_ENSURE( !aModules.has( aName ), "VbaProject::importVba - multiple modules with the same name" );
+ VbaModuleMap::mapped_type& rxModule = aModules[ aName ];
+ rxModule.reset( new VbaModule( mxDocModel, aName, eTextEnc, bExecutable ) );
+ // read all remaining records until the MODULEEND record
+ rxModule->importDirRecords( aDirStrm );
+ OSL_ENSURE( !aModulesByStrm.has( rxModule->getStreamName() ), "VbaProject::importVba - multiple modules with the same stream name" );
+ aModulesByStrm[ rxModule->getStreamName() ] = rxModule;
+ }
+ break;
+#undef OOX_ENSURE_RECORDSIZE
+ }
+ }
+ OSL_ENSURE( nModuleCount == aModules.size(), "VbaProject::importVba - invalid module count" );
+
+ /* The directory does not contain the real type of the modules, it
+ distinguishes only between 'procedural' and 'document' (the latter
+ includes class and form modules). Now, the exact type of all modules
+ will be read from the 'PROJECT' stream. It consists of text lines in
+ 'key=value' format which list the code modules by type.
+
+ - The line 'document=<modulename>/&HXXXXXXXX' declares document
+ modules. These are attached to the Word document (usually called
+ 'ThisDocument'), the Excel workbook (usually called
+ 'ThisWorkbook'), or single Excel worksheets or chartsheets (usually
+ called 'SheetX' or 'ChartX', X being a decimal number). Of course,
+ users may rename all these modules. The slash character separates
+ an automation server version number (hexadecimal 'XXXXXXXX') from
+ the module name.
+ - The line 'Module=<modulename>' declares common procedural code
+ modules.
+ - The line 'Class=<modulename>' declares a class module.
+ - The line 'BaseClass=<modulename>' declares a code module attached
+ to a user form with the same name.
+ */
+ BinaryXInputStream aPrjStrm( rVbaPrjStrg.openInputStream( CREATE_OUSTRING( "PROJECT" ) ), true );
+ OSL_ENSURE( !aPrjStrm.isEof(), "VbaProject::importVba - cannot open 'PROJECT' stream" );
+ // do not exit if this stream does not exist, but proceed to load the modules below
+ if( !aPrjStrm.isEof() )
+ {
+ TextInputStream aPrjTextStrm( aPrjStrm, eTextEnc );
+ OUString aKey, aValue;
+ bool bExitLoop = false;
+ while( !bExitLoop && !aPrjTextStrm.isEof() )
+ {
+ // read a text line from the stream
+ OUString aLine = aPrjTextStrm.readLine().trim();
+ sal_Int32 nLineLen = aLine.getLength();
+ // exit if a subsection starts (section name is given in brackets)
+ bExitLoop = (nLineLen >= 2) && (aLine[ 0 ] == '[') && (aLine[ nLineLen - 1 ] == ']');
+ if( !bExitLoop && VbaHelper::extractKeyValue( aKey, aValue, aLine ) )
+ {
+ sal_Int32 nType = ModuleType::UNKNOWN;
+ if( aKey.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "Document" ) ) )
+ {
+ nType = ModuleType::DOCUMENT;
+ // strip automation server version from module names
+ sal_Int32 nSlashPos = aValue.indexOf( '/' );
+ if( nSlashPos >= 0 )
+ aValue = aValue.copy( 0, nSlashPos );
+ }
+ else if( aKey.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "Module" ) ) )
+ nType = ModuleType::NORMAL;
+ else if( aKey.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "Class" ) ) )
+ nType = ModuleType::CLASS;
+ else if( aKey.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "BaseClass" ) ) )
+ nType = ModuleType::FORM;
+
+ if( (nType != ModuleType::UNKNOWN) && (aValue.getLength() > 0) )
+ {
+ OSL_ENSURE( aModules.has( aValue ), "VbaProject::importVba - module not found" );
+ if( VbaModule* pModule = aModules.get( aValue ).get() )
+ pModule->setType( nType );
+ }
+ }
+ }
+ }
+
+ // create empty dummy modules
+ VbaModuleMap aDummyModules;
+ for( DummyModuleMap::iterator aIt = maDummyModules.begin(), aEnd = maDummyModules.end(); aIt != aEnd; ++aIt )
+ {
+ OSL_ENSURE( !aModules.has( aIt->first ) && !aDummyModules.has( aIt->first ), "VbaProject::importVba - multiple modules with the same name" );
+ VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ];
+ rxModule.reset( new VbaModule( mxDocModel, aIt->first, eTextEnc, bExecutable ) );
+ rxModule->setType( aIt->second );
+ }
+
+ /* Now it is time to load the source code. All modules will be inserted
+ into the Basic library of the document specified by the 'maPrjName'
+ member. Do not create the Basic library, if there are no modules
+ specified. */
+ if( !aModules.empty() || !aDummyModules.empty() ) try
+ {
+ // get the model factory and the basic library
+ Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW );
+ Reference< XNameContainer > xBasicLib( createBasicLibrary(), UNO_SET_THROW );
+
+ /* Set library container to VBA compatibility mode. This will create
+ the VBA Globals object and store it in the Basic manager of the
+ document. */
+ try
+ {
+ Reference< XVBACompatibility >( getLibraryContainer( PROP_BasicLibraries ), UNO_QUERY_THROW )->setVBACompatibilityMode( sal_True );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // try to get access to document objects related to code modules
+ Reference< XNameAccess > xDocObjectNA;
+ try
+ {
+ xDocObjectNA.set( xModelFactory->createInstance( CREATE_OUSTRING( "ooo.vba.VBAObjectModuleObjectProvider" ) ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ // not all documents support this
+ }
+
+ if( xBasicLib.is() )
+ {
+ // call Basic source code import for each module, boost::[c]ref enforces pass-by-ref
+ aModules.forEachMem( &VbaModule::createAndImportModule,
+ ::boost::ref( *xVbaStrg ), ::boost::cref( xBasicLib ),
+ ::boost::cref( xDocObjectNA ) );
+
+ // create empty dummy modules
+ aDummyModules.forEachMem( &VbaModule::createEmptyModule,
+ ::boost::cref( xBasicLib ), ::boost::cref( xDocObjectNA ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ /* Load the forms. The file format specification requires that a module
+ must exist for every form. We are a bit more tolerant and scan the
+ project storage for all form substorages. This may 'repair' broken VBA
+ storages that misses to mention a module for an existing form. */
+ ::std::vector< OUString > aElements;
+ rVbaPrjStrg.getElementNames( aElements );
+ for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt )
+ {
+ // try to open the element as storage
+ if( !aIt->equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VBA" ) ) )
+ {
+ StorageRef xSubStrg = rVbaPrjStrg.openSubStorage( *aIt, false );
+ if( xSubStrg.get() ) try
+ {
+ // resolve module name from storage name (which equals the module stream name)
+ VbaModule* pModule = aModulesByStrm.get( *aIt ).get();
+ OSL_ENSURE( pModule && (pModule->getType() == ModuleType::FORM),
+ "VbaProject::importVba - form substorage without form module" );
+ OUString aModuleName;
+ if( pModule )
+ aModuleName = pModule->getName();
+
+ // create and import the form
+ Reference< XNameContainer > xDialogLib( createDialogLibrary(), UNO_SET_THROW );
+ VbaUserForm aForm( mxCompContext, mxDocModel, rGraphicHelper, bDefaultColorBgr );
+ aForm.importForm( xDialogLib, *xSubStrg, aModuleName, eTextEnc );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+
+ // attach macros to registered objects
+ attachMacros();
+ // virtual call, derived classes may do some more processing
+ finalizeImport();
+}
+
+void VbaProject::attachMacros()
+{
+ if( !maMacroAttachers.empty() && mxCompContext.is() ) try
+ {
+ Reference< XMultiComponentFactory > xFactory( mxCompContext->getServiceManager(), UNO_SET_THROW );
+ Sequence< Any > aArgs( 2 );
+ aArgs[ 0 ] <<= mxDocModel;
+ aArgs[ 1 ] <<= maPrjName;
+ Reference< XVBAMacroResolver > xResolver( xFactory->createInstanceWithArgumentsAndContext(
+ CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs, mxCompContext ), UNO_QUERY_THROW );
+ maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::boost::cref( xResolver ) );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void VbaProject::copyStorage( StorageBase& rVbaPrjStrg )
+{
+ if( mxCompContext.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW );
+ Reference< XStorageBasedDocument > xStorageBasedDoc( mxDocModel, UNO_QUERY_THROW );
+ Reference< XStorage > xDocStorage( xStorageBasedDoc->getDocumentStorage(), UNO_QUERY_THROW );
+ {
+ using namespace ::com::sun::star::embed::ElementModes;
+ Reference< XStream > xDocStream( xDocStorage->openStreamElement( CREATE_OUSTRING( "_MS_VBA_Macros" ), SEEKABLE | WRITE | TRUNCATE ), UNO_SET_THROW );
+ OleStorage aDestStorage( xFactory, xDocStream, false );
+ rVbaPrjStrg.copyStorageToStorage( aDestStorage );
+ aDestStorage.commit();
+ }
+ Reference< XTransactedObject >( xDocStorage, UNO_QUERY_THROW )->commit();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ole/vbaprojectfilter.cxx b/oox/source/ole/vbaprojectfilter.cxx
new file mode 100755
index 000000000000..ee5b3bf7a715
--- /dev/null
+++ b/oox/source/ole/vbaprojectfilter.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ole/vbaprojectfilter.hxx"
+
+#include "oox/ole/vbaproject.hxx"
+
+namespace oox {
+namespace ole {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+VbaProjectFilterBase::VbaProjectFilterBase( const Reference< XComponentContext >& rxContext,
+ const OUString& rAppName, const OUString& rStorageName ) throw( RuntimeException ) :
+ BinaryFilterBase( rxContext ),
+ maAppName( rAppName ),
+ maStorageName( rStorageName )
+{
+}
+
+bool VbaProjectFilterBase::importDocument() throw()
+{
+ StorageRef xVbaPrjStrg = openSubStorage( maStorageName, false );
+ if( !xVbaPrjStrg || !xVbaPrjStrg->isStorage() )
+ return false;
+
+ getVbaProject().importVbaProject( *xVbaPrjStrg, getGraphicHelper() );
+ return true;
+}
+
+bool VbaProjectFilterBase::exportDocument() throw()
+{
+ return false;
+}
+
+VbaProject* VbaProjectFilterBase::implCreateVbaProject() const
+{
+ return new VbaProject( getComponentContext(), getModel(), maAppName );
+}
+
+// ============================================================================
+
+OUString SAL_CALL WordVbaProjectFilter_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.WordVbaProjectFilter" );
+}
+
+Sequence< OUString > SAL_CALL WordVbaProjectFilter_getSupportedServiceNames() throw()
+{
+ Sequence< OUString > aSeq( 1 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL WordVbaProjectFilter_createInstance(
+ const Reference< XComponentContext >& rxContext ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new WordVbaProjectFilter( rxContext ) );
+}
+
+// ----------------------------------------------------------------------------
+
+WordVbaProjectFilter::WordVbaProjectFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ VbaProjectFilterBase( rxContext, CREATE_OUSTRING( "Writer" ), CREATE_OUSTRING( "Macros" ) )
+{
+}
+
+OUString WordVbaProjectFilter::implGetImplementationName() const
+{
+ return WordVbaProjectFilter_getImplementationName();
+}
+
+// ============================================================================
+
+} // namespace ole
+} // namespace oox
diff --git a/oox/source/ppt/animationspersist.cxx b/oox/source/ppt/animationspersist.cxx
new file mode 100644
index 000000000000..fdee865251af
--- /dev/null
+++ b/oox/source/ppt/animationspersist.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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"
+
+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..6346a8058c5d
--- /dev/null
+++ b/oox/source/ppt/animationtypes.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include "animationtypes.hxx"
+
+#include <com/sun/star/animations/Timing.hpp>
+
+#include "oox/helper/attributelist.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..a2c57b53267f
--- /dev/null
+++ b/oox/source/ppt/animationtypes.hxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#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..449c4ef73d11
--- /dev/null
+++ b/oox/source/ppt/animvariantcontext.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/fragmenthandler.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "pptfilterhelpers.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( ContextHandler& rParent, sal_Int32 aElement, Any & aValue )
+ : ContextHandler( rParent )
+ , 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( getFilter().getGraphicHelper() ) );
+ }
+ }
+
+
+ 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 PPT_TOKEN( boolVal ):
+ {
+ bool val = attribs.getBool( XML_val, false );
+ maValue = makeAny( val );
+ break;
+ }
+ case PPT_TOKEN( clrVal ):
+ xRet.set( new ::oox::drawingml::ColorContext( *this, maColor ) );
+ // we'll defer setting the Any until the end.
+ break;
+ case PPT_TOKEN( fltVal ):
+ {
+ double val = attribs.getDouble( XML_val, 0.0 );
+ maValue = makeAny( val );
+ break;
+ }
+ case PPT_TOKEN( intVal ):
+ {
+ sal_Int32 val = attribs.getInteger( XML_val, 0 );
+ maValue = makeAny( val );
+ break;
+ }
+ case PPT_TOKEN( strVal ):
+ {
+ OUString val = attribs.getString( XML_val, OUString() );
+ 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..48fff797744f
--- /dev/null
+++ b/oox/source/ppt/animvariantcontext.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_ANIMVARIANTCONTEXT
+#define OOX_PPT_ANIMVERIANTCONTEXT
+
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/drawingml/color.hxx"
+
+namespace oox { namespace ppt {
+
+ /** context CT_TLAnimVariant */
+ class AnimVariantContext
+ : public ::oox::core::ContextHandler
+ {
+ public:
+ AnimVariantContext( ::oox::core::ContextHandler& rParent, ::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..65664bdd3691
--- /dev/null
+++ b/oox/source/ppt/backgroundproperties.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ppt/backgroundproperties.hxx"
+#include "oox/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/drawingmltypes.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 {
+// ---------------------------------------------------------------------
+
+BackgroundPropertiesContext::BackgroundPropertiesContext( ContextHandler& rParent, ::oox::drawingml::FillProperties& rFillProperties ) throw()
+: ContextHandler( rParent )
+, mrFillProperties( rFillProperties )
+{
+}
+
+Reference< XFastContextHandler > BackgroundPropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( fill ): // a:CT_FillEffect
+ break;
+ }
+
+ // FillPropertiesGroupContext
+ if( !xRet.is() )
+ xRet = ::oox::drawingml::FillPropertiesContext::createFillContext( *this, aElementToken, xAttribs, mrFillProperties );
+
+ return xRet;
+}
+
+} }
diff --git a/oox/source/ppt/buildlistcontext.cxx b/oox/source/ppt/buildlistcontext.cxx
new file mode 100644
index 000000000000..3352e202e057
--- /dev/null
+++ b/oox/source/ppt/buildlistcontext.cxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "buildlistcontext.hxx"
+#include <rtl/ustring.hxx>
+#include "oox/helper/attributelist.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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& /*xAttribs*/,
+ TimeNodePtrList & aTimeNodeList)
+ : ContextHandler( rParent )
+ , maTimeNodeList( aTimeNodeList )
+ , mbInBldGraphic( false )
+ , mbBuildAsOne( false )
+ {
+ }
+
+ BuildListContext::~BuildListContext( )
+ {
+ }
+
+ void SAL_CALL BuildListContext::endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException)
+ {
+ switch( aElement )
+ {
+ case PPT_TOKEN( 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 PPT_TOKEN( bldAsOne ):
+ if( mbInBldGraphic )
+ {
+ mbBuildAsOne = true;
+ }
+ break;
+ case PPT_TOKEN( bldSub ):
+ if( mbInBldGraphic )
+ {
+ }
+ break;
+ case PPT_TOKEN( 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 A_TOKEN( bldDgm ):
+ case A_TOKEN( bldOleChart ):
+ case A_TOKEN( 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..8b8d5c52b068
--- /dev/null
+++ b/oox/source/ppt/buildlistcontext.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_BUILDLISTCONTEXT
+#define OOX_PPT_BUILDLISTCONTEXT
+
+#include "oox/ppt/timenode.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace ppt {
+
+
+ /** CT_BuildList */
+ class BuildListContext
+ : public ::oox::core::ContextHandler
+ {
+ public:
+ BuildListContext( ::oox::core::ContextHandler& rParent,
+ 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..a4e3951228ae
--- /dev/null
+++ b/oox/source/ppt/commonbehaviorcontext.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.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/fragmenthandler.hxx"
+
+#include "commonbehaviorcontext.hxx"
+#include "commontimenodecontext.hxx"
+#include "timetargetelementcontext.hxx"
+#include "pptfilterhelpers.hxx"
+
+#include <string.h>
+
+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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, PPT_TOKEN( cBhvr ), xAttribs, pNode )
+ , mbInAttrList( false )
+ , mbIsInAttrName( false )
+ {
+ }
+
+
+ CommonBehaviorContext::~CommonBehaviorContext( ) throw( )
+ {
+ }
+
+
+
+ void SAL_CALL CommonBehaviorContext::endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ switch( aElement )
+ {
+ case PPT_TOKEN( 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 PPT_TOKEN( attrNameLst ):
+ mbInAttrList = false;
+ break;
+ case PPT_TOKEN( 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 PPT_TOKEN( cTn ):
+ xRet.set( new CommonTimeNodeContext( *this, aElementToken, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( tgtEl ):
+ xRet.set( new TimeTargetElementContext( *this, mpNode->getTarget() ) );
+ break;
+ case PPT_TOKEN( attrNameLst ):
+ mbInAttrList = true;
+ break;
+ case PPT_TOKEN( 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..95e47342a76e
--- /dev/null
+++ b/oox/source/ppt/commonbehaviorcontext.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#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( ::oox::core::ContextHandler& rParent,
+ 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..1057deb70c5d
--- /dev/null
+++ b/oox/source/ppt/commontimenodecontext.cxx
@@ -0,0 +1,708 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/fragmenthandler.hxx"
+#include "oox/ppt/pptimport.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+
+#include "animationtypes.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(
+ ContextHandler& rParent,
+ sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, xAttribs, pNode )
+ , mbIterate( false )
+ {
+ AttributeList attribs( xAttribs );
+ sal_Int32 nInt; // some temporary int value for float conversions
+
+ NodePropertyMap & aProps = pNode->getNodeProperties();
+ TimeNode::UserDataMap & 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.getUnsigned( XML_grpId, 0 );
+ }
+ // ST_TLTimeNodeID
+ if( attribs.hasAttribute( XML_id ) )
+ {
+ sal_uInt32 nId = attribs.getUnsigned( 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 == ( PPT_TOKEN( 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 PPT_TOKEN( childTnLst ):
+ case PPT_TOKEN( subTnLst ):
+ xRet.set( new TimeNodeListContext( *this, mpNode->getChildren() ) );
+ break;
+
+ case PPT_TOKEN( stCondLst ):
+ xRet.set( new CondListContext( *this, aElementToken, xAttribs, mpNode, mpNode->getStartCondition() ) );
+ break;
+ case PPT_TOKEN( endCondLst ):
+ xRet.set( new CondListContext( *this, aElementToken, xAttribs, mpNode, mpNode->getEndCondition() ) );
+ break;
+
+ case PPT_TOKEN( endSync ):
+ xRet.set( new CondContext( *this, xAttribs, mpNode, mpNode->getEndSyncValue() ) );
+ break;
+ case PPT_TOKEN( 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 PPT_TOKEN( tmAbs ):
+ if( mbIterate )
+ {
+ AttributeList attribs( xAttribs );
+ double fTime = attribs.getUnsigned( XML_val, 0 );
+ // time in ms. property is in % TODO
+ mpNode->getNodeProperties()[ NP_ITERATEINTERVAL ] <<= fTime;
+ }
+ break;
+ case PPT_TOKEN( tmPct ):
+ if( mbIterate )
+ {
+ AttributeList attribs( xAttribs );
+ double fPercent = (double)attribs.getUnsigned( 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..e8c55fa2d944
--- /dev/null
+++ b/oox/source/ppt/commontimenodecontext.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#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( ::oox::core::ContextHandler& rParent, 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..5b622b6ef602
--- /dev/null
+++ b/oox/source/ppt/conditioncontext.cxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/contexthandler.hxx"
+#include "oox/ppt/animationspersist.hxx"
+#include "animationtypes.hxx"
+
+#include "timetargetelementcontext.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( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode, AnimationCondition & aValue )
+ : TimeNodeContext( rParent, PPT_TOKEN( 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 PPT_TOKEN( 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 PPT_TOKEN( tn ):
+ {
+ maCond.mnType = aElementToken;
+ AttributeList attribs( xAttribs );
+ sal_uInt32 nId = attribs.getUnsigned( XML_val, 0 );
+ maCond.maValue = makeAny( nId );
+ break;
+ }
+ case PPT_TOKEN( tgtEl ):
+ // CT_TLTimeTargetElement
+ xRet.set( new TimeTargetElementContext( *this, maCond.getTarget() ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+
+ }
+
+
+
+ /** CT_TLTimeConditionList */
+ CondListContext::CondListContext(
+ ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode,
+ AnimationConditionList & aCond )
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cond ):
+ // add a condition to the list
+ maConditions.push_back( AnimationCondition() );
+ xRet.set( new CondContext( *this, 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..b89e587a9571
--- /dev/null
+++ b/oox/source/ppt/conditioncontext.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#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( ::oox::core::ContextHandler& rParent,
+ 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( ::oox::core::ContextHandler& rParent,
+ 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..f66ccb0f6084
--- /dev/null
+++ b/oox/source/ppt/customshowlistcontext.cxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "customshowlistcontext.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::ContextHandler
+{
+ CustomShow mrCustomShow;
+
+public:
+ CustomShowContext( ::oox::core::ContextHandler& rParent,
+ 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( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& rxAttribs,
+ CustomShow& rCustomShow )
+: ContextHandler( rParent )
+, 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 PPT_TOKEN( sld ) :
+ mrCustomShow.maSldLst.push_back( xAttribs->getOptionalValue( R_TOKEN( id ) ) );
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+}
+
+//---------------------------------------------------------------------------
+
+CustomShowListContext::CustomShowListContext( ContextHandler& rParent,
+ std::vector< CustomShow >& rCustomShowList )
+: ContextHandler( rParent )
+, 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 PPT_TOKEN( custShow ) :
+ {
+ CustomShow aCustomShow;
+ mrCustomShowList.push_back( aCustomShow );
+ xRet = new CustomShowContext( *this, 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..a423b18f2f5d
--- /dev/null
+++ b/oox/source/ppt/customshowlistcontext.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_POWERPOINT_CUSTOMSHOWLISTCONTEXT_HXX
+#define OOX_POWERPOINT_CUSTOMSHOWLISTCONTEXT_HXX
+
+#include "oox/core/contexthandler.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::ContextHandler
+ {
+ std::vector< CustomShow >& mrCustomShowList;
+
+ public:
+ CustomShowListContext( ::oox::core::ContextHandler& rParent,
+ 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/headerfootercontext.cxx b/oox/source/ppt/headerfootercontext.cxx
new file mode 100644
index 000000000000..2089b019c58c
--- /dev/null
+++ b/oox/source/ppt/headerfootercontext.cxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "headerfootercontext.hxx"
+#include "oox/helper/attributelist.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+ HeaderFooterContext::HeaderFooterContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& xAttribs, HeaderFooter& rHeaderFooter )
+ : ContextHandler( rParent )
+ {
+ AttributeList aAttribs( xAttribs );
+ if ( xAttribs->hasAttribute( XML_sldNum ) )
+ {
+ rHeaderFooter.mbSlideNumber = aAttribs.getBool( XML_sldNum, sal_True );
+ }
+ if ( xAttribs->hasAttribute( XML_hdr ) )
+ {
+ rHeaderFooter.mbHeader = aAttribs.getBool( XML_hdr, sal_True );
+ }
+ if ( xAttribs->hasAttribute( XML_ftr ) )
+ {
+ rHeaderFooter.mbFooter = aAttribs.getBool( XML_ftr, sal_True );
+ }
+ if ( xAttribs->hasAttribute( XML_dt ) )
+ {
+ rHeaderFooter.mbDateTime = aAttribs.getBool( XML_dt, sal_True );
+ }
+ }
+
+ HeaderFooterContext::~HeaderFooterContext( )
+ {
+ }
+
+} }
diff --git a/oox/source/ppt/headerfootercontext.hxx b/oox/source/ppt/headerfootercontext.hxx
new file mode 100644
index 000000000000..52e5bb9ab55e
--- /dev/null
+++ b/oox/source/ppt/headerfootercontext.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_HEADERFOOTERCONTEXT
+#define OOX_PPT_HEADERFOOTERCONTEXT
+
+#include "oox/ppt/headerfooter.hxx"
+#include "oox/core/contexthandler.hxx"
+
+namespace oox { namespace ppt {
+
+ /** CT_HeaderFooter */
+ class HeaderFooterContext : public ::oox::core::ContextHandler
+ {
+ public:
+ HeaderFooterContext( ::oox::core::ContextHandler& rParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs, HeaderFooter& rHeaderFooter );
+
+ ~HeaderFooterContext( );
+ };
+
+} }
+
+#endif
diff --git a/oox/source/ppt/layoutfragmenthandler.cxx b/oox/source/ppt/layoutfragmenthandler.cxx
new file mode 100644
index 000000000000..152beb280bd7
--- /dev/null
+++ b/oox/source/ppt/layoutfragmenthandler.cxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "headerfootercontext.hxx"
+#include "oox/ppt/layoutfragmenthandler.hxx"
+#include "oox/drawingml/shapegroupcontext.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( XmlFilterBase& rFilter, const OUString& rFragmentPath, SlidePersistPtr pMasterPersistPtr )
+ throw()
+: SlideFragmentHandler( rFilter, rFragmentPath, pMasterPersistPtr, Layout )
+{
+}
+
+LayoutFragmentHandler::~LayoutFragmentHandler()
+ throw()
+{
+
+}
+
+Reference< XFastContextHandler > LayoutFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet = getFastContextHandler();
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( sldLayout ): // CT_SlideLayout
+ mpSlidePersistPtr->setLayoutValueToken( xAttribs->getOptionalValueToken( XML_type, 0 ) ); // CT_SlideLayoutType
+ break;
+ case PPT_TOKEN( hf ): // CT_HeaderFooter
+ xRet.set( new HeaderFooterContext( *this, xAttribs, mpSlidePersistPtr->getHeaderFooter() ) );
+ 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..8d902ed51337
--- /dev/null
+++ b/oox/source/ppt/makefile.mk
@@ -0,0 +1,76 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=ppt
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/animationspersist.obj \
+ $(SLO)$/animationtypes.obj \
+ $(SLO)$/animvariantcontext.obj \
+ $(SLO)$/backgroundproperties.obj\
+ $(SLO)$/buildlistcontext.obj \
+ $(SLO)$/commonbehaviorcontext.obj \
+ $(SLO)$/commontimenodecontext.obj \
+ $(SLO)$/conditioncontext.obj \
+ $(SLO)$/customshowlistcontext.obj \
+ $(SLO)$/headerfootercontext.obj \
+ $(SLO)$/layoutfragmenthandler.obj\
+ $(SLO)$/pptfilterhelpers.obj\
+ $(SLO)$/pptimport.obj\
+ $(SLO)$/pptshape.obj \
+ $(SLO)$/pptshapecontext.obj \
+ $(SLO)$/pptshapegroupcontext.obj \
+ $(SLO)$/pptshapepropertiescontext.obj \
+ $(SLO)$/presentationfragmenthandler.obj\
+ $(SLO)$/slidefragmenthandler.obj\
+ $(SLO)$/slidemastertextstylescontext.obj \
+ $(SLO)$/slidepersist.obj\
+ $(SLO)$/slidetimingcontext.obj\
+ $(SLO)$/slidetransition.obj\
+ $(SLO)$/slidetransitioncontext.obj\
+ $(SLO)$/soundactioncontext.obj \
+ $(SLO)$/timeanimvaluecontext.obj \
+ $(SLO)$/timenode.obj\
+ $(SLO)$/timenodelistcontext.obj \
+ $(SLO)$/timetargetelementcontext.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..40040e985a4c
--- /dev/null
+++ b/oox/source/ppt/pptfilterhelpers.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#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..c36c66df5ae7
--- /dev/null
+++ b/oox/source/ppt/pptfilterhelpers.hxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#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..625e4e662e3c
--- /dev/null
+++ b/oox/source/ppt/pptimport.cxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ppt/pptimport.hxx"
+#include "oox/drawingml/chart/chartconverter.hxx"
+#include "oox/dump/pptxdumper.hxx"
+#include "oox/drawingml/table/tablestylelistfragmenthandler.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/ole/vbaproject.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.oox.ppt.PowerPointImport" );
+}
+
+uno::Sequence< OUString > SAL_CALL PowerPointImport_getSupportedServiceNames() throw()
+{
+ Sequence< OUString > aSeq( 2 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
+ aSeq[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL PowerPointImport_createInstance( const Reference< XComponentContext >& rxContext ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new PowerPointImport( rxContext ) );
+}
+
+PowerPointImport::PowerPointImport( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ XmlFilterBase( rxContext ),
+ mxChartConv( new ::oox::drawingml::chart::ChartConverter )
+{
+}
+
+PowerPointImport::~PowerPointImport()
+{
+}
+
+bool PowerPointImport::importDocument() throw()
+{
+ /* to activate the PPTX dumper, define the environment variable
+ OOO_PPTXDUMPER and insert the full path to the file
+ file:///<path-to-oox-module>/source/dump/pptxdumper.ini. */
+ OOX_DUMP_FILE( ::oox::dump::pptx::Dumper );
+
+ OUString aFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "officeDocument" ) );
+ FragmentHandlerRef xPresentationFragmentHandler( new PresentationFragmentHandler( *this, aFragmentPath ) );
+ maTableStyleListPath = xPresentationFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "tableStyles" ) );
+ return importFragment( xPresentationFragmentHandler );
+
+
+}
+
+bool PowerPointImport::exportDocument() throw()
+{
+ return false;
+}
+
+sal_Int32 PowerPointImport::getSchemeColor( sal_Int32 nToken ) const
+{
+ sal_Int32 nColor = 0;
+ if ( mpActualSlidePersist )
+ {
+ sal_Bool bColorMapped = sal_False;
+ oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() );
+ if ( pClrMapPtr )
+ bColorMapped = pClrMapPtr->getColorMap( nToken );
+
+ if ( !bColorMapped ) // try masterpage mapping
+ {
+ SlidePersistPtr pMasterPersist = mpActualSlidePersist->getMasterPersist();
+ if ( pMasterPersist )
+ {
+ pClrMapPtr = pMasterPersist->getClrMap();
+ if ( pClrMapPtr )
+ bColorMapped = pClrMapPtr->getColorMap( nToken );
+ }
+ }
+ oox::drawingml::ClrSchemePtr pClrSchemePtr( mpActualSlidePersist->getClrScheme() );
+ if ( pClrSchemePtr )
+ pClrSchemePtr->getColor( nToken, nColor );
+ else
+ {
+ ::oox::drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme();
+ if( pTheme )
+ {
+ pTheme->getClrScheme().getColor( nToken, nColor );
+ }
+ else
+ {
+ OSL_TRACE("OOX: PowerPointImport::mpThemePtr is NULL");
+ }
+ }
+ }
+ return nColor;
+}
+
+const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const
+{
+ return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : 0;
+}
+
+::oox::vml::Drawing* PowerPointImport::getVmlDrawing()
+{
+ return mpActualSlidePersist ? mpActualSlidePersist->getDrawing() : 0;
+}
+
+const oox::drawingml::table::TableStyleListPtr PowerPointImport::getTableStyles()
+{
+ if ( !mpTableStyleList && maTableStyleListPath.getLength() )
+ {
+ mpTableStyleList = oox::drawingml::table::TableStyleListPtr( new oox::drawingml::table::TableStyleList() );
+ importFragment( new oox::drawingml::table::TableStyleListFragmentHandler(
+ *this, maTableStyleListPath, *mpTableStyleList ) );
+ }
+ return mpTableStyleList;;
+}
+
+::oox::drawingml::chart::ChartConverter& PowerPointImport::getChartConverter()
+{
+ return *mxChartConv;
+}
+
+namespace {
+
+class PptGraphicHelper : public GraphicHelper
+{
+public:
+ explicit PptGraphicHelper( const PowerPointImport& rFilter );
+ virtual sal_Int32 getSchemeColor( sal_Int32 nToken ) const;
+private:
+ const PowerPointImport& mrFilter;
+};
+
+PptGraphicHelper::PptGraphicHelper( const PowerPointImport& rFilter ) :
+ GraphicHelper( rFilter.getComponentContext(), rFilter.getTargetFrame(), rFilter.getStorage() ),
+ mrFilter( rFilter )
+{
+}
+
+sal_Int32 PptGraphicHelper::getSchemeColor( sal_Int32 nToken ) const
+{
+ return mrFilter.getSchemeColor( nToken );
+}
+
+} // namespace
+
+GraphicHelper* PowerPointImport::implCreateGraphicHelper() const
+{
+ return new PptGraphicHelper( *this );
+}
+
+::oox::ole::VbaProject* PowerPointImport::implCreateVbaProject() const
+{
+ return new ::oox::ole::VbaProject( getComponentContext(), getModel(), CREATE_OUSTRING( "Impress" ) );
+}
+
+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..7437b378b324
--- /dev/null
+++ b/oox/source/ppt/pptshape.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ppt/pptshape.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/drawingml/textbody.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 ::oox::drawingml;
+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(
+ oox::core::XmlFilterBase& rFilterBase,
+ const SlidePersist& rSlidePersist,
+ const oox::drawingml::Theme* pTheme,
+ const Reference< XShapes >& rxShapes,
+ const awt::Rectangle* pShapeRect,
+ ::oox::drawingml::ShapeIdMap* pShapeMap )
+{
+ // 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( rFilterBase.getModel(), UNO_QUERY_THROW );
+ sal_Bool bClearText = sal_False;
+
+ if ( sServiceName != OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) )
+ {
+ 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_subTitle :
+ {
+ if ( ( meShapeLocation == Master ) || ( meShapeLocation == Layout ) )
+ sServiceName = rtl::OUString();
+ else {
+ const rtl::OUString sTitleShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.SubtitleShape" ) );
+ 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;
+ bClearText = sal_True;
+ }
+ break;
+ case XML_hdr :
+ {
+ const rtl::OUString sHeaderShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.HeaderShape" ) );
+ sServiceName = sHeaderShapeService;
+ bClearText = sal_True;
+ }
+ break;
+ case XML_ftr :
+ {
+ const rtl::OUString sFooterShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.FooterShape" ) );
+ sServiceName = sFooterShapeService;
+ bClearText = sal_True;
+ }
+ break;
+ case XML_sldNum :
+ {
+ const rtl::OUString sSlideNumberShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.SlideNumberShape" ) );
+ sServiceName = sSlideNumberShapeService;
+ bClearText = sal_True;
+ }
+ break;
+ case XML_sldImg :
+ {
+ const rtl::OUString sPageShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PageShape" ) );
+ sServiceName = sPageShapeService;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+/*
+ // use placeholder index if possible
+ if( mnSubType && getSubTypeIndex() && rSlidePersist.getMasterPersist().get() ) {
+ oox::drawingml::ShapePtr pPlaceholder = PPTShape::findPlaceholderByIndex( getSubTypeIndex(), rSlidePersist.getMasterPersist()->getShapes()->getChildren() );
+ if( pPlaceholder.get() && pPlaceholder->getTextBody() ) {
+ TextListStylePtr pNewTextListStyle ( new TextListStyle() );
+
+ pNewTextListStyle->apply( pPlaceholder->getTextBody()->getTextListStyle() );
+ if( pPlaceholder->getMasterTextListStyle().get() )
+ pNewTextListStyle->apply( *pPlaceholder->getMasterTextListStyle() );
+
+ aMasterTextListStyle = pNewTextListStyle;
+ }
+ }
+*/
+ if ( sServiceName.getLength() )
+ {
+ if ( !aMasterTextListStyle.get() )
+ aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getOtherTextStyle() : rSlidePersist.getOtherTextStyle();
+ setMasterTextListStyle( aMasterTextListStyle );
+
+ Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, bClearText ) );
+ if ( !rSlidePersist.isMasterPage() && rSlidePersist.getPage().is() && ( (sal_Int32)mnSubType == XML_title ) )
+ {
+ try
+ {
+ rtl::OUString aTitleText;
+ Reference< XTextRange > xText( xShape, UNO_QUERY_THROW );
+ aTitleText = xText->getString();
+ if ( aTitleText.getLength() && ( aTitleText.getLength() < 64 ) ) // just a magic value, but we don't want to set slide names which are too long
+ {
+ Reference< container::XNamed > xName( rSlidePersist.getPage(), UNO_QUERY_THROW );
+ xName->setName( aTitleText );
+ }
+ }
+ catch( uno::Exception& )
+ {
+
+ }
+ }
+ if( pShapeMap && msId.getLength() )
+ {
+ (*pShapeMap)[ 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() )
+ addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+}
+
+void PPTShape::applyShapeReference( const oox::drawingml::Shape& rReferencedShape )
+{
+ Shape::applyShapeReference( rReferencedShape );
+}
+
+oox::drawingml::ShapePtr PPTShape::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 >& rChildren = (*aRevIter)->getChildren();
+ aShapePtr = findPlaceholder( nMasterPlaceholder, rChildren );
+ if ( aShapePtr.get() )
+ break;
+ aRevIter++;
+ }
+ return aShapePtr;
+}
+
+oox::drawingml::ShapePtr PPTShape::findPlaceholderByIndex( const sal_Int32 nIdx, 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)->getSubTypeIndex() == nIdx )
+ {
+ aShapePtr = *aRevIter;
+ break;
+ }
+ std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
+ aShapePtr = findPlaceholderByIndex( nIdx, rChildren );
+ if ( aShapePtr.get() )
+ break;
+ aRevIter++;
+ }
+ return aShapePtr;
+}
+
+// if nFirstPlaceholder can't be found, it will be searched for nSecondPlaceholder
+oox::drawingml::ShapePtr PPTShape::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 );
+}
+
+} }
diff --git a/oox/source/ppt/pptshapecontext.cxx b/oox/source/ppt/pptshapecontext.cxx
new file mode 100644
index 000000000000..7df41ac3d714
--- /dev/null
+++ b/oox/source/ppt/pptshapecontext.cxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/helper/attributelist.hxx"
+#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/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.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( ContextHandler& rParent, const SlidePersistPtr pSlidePersistPtr, oox::drawingml::ShapePtr pMasterShapePtr, oox::drawingml::ShapePtr pShapePtr )
+: oox::drawingml::ShapeContext( rParent, pMasterShapePtr, pShapePtr )
+, mpSlidePersistPtr( pSlidePersistPtr )
+{
+}
+
+oox::drawingml::ShapePtr findPlaceholder( const sal_Int32 nMasterPlaceholder, sal_Int32 nSubTypeIndex, 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 )
+ {
+ if ( ( nSubTypeIndex == -1 ) || ( nSubTypeIndex == (*aRevIter)->getSubTypeIndex() ) )
+ {
+ aShapePtr = *aRevIter;
+ break;
+ }
+ }
+ std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
+ aShapePtr = findPlaceholder( nMasterPlaceholder, nSubTypeIndex, rChildren );
+ 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,
+ sal_Int32 nSubTypeIndex, std::vector< oox::drawingml::ShapePtr >& rShapes )
+{
+ oox::drawingml::ShapePtr pPlaceholder = findPlaceholder( nFirstPlaceholder, nSubTypeIndex, rShapes );
+ return !nSecondPlaceholder || pPlaceholder.get() ? pPlaceholder : findPlaceholder( nSecondPlaceholder, nSubTypeIndex, 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 PPT_TOKEN( drElemPr ):
+ // break;
+ case PPT_TOKEN( cNvPr ):
+ {
+ AttributeList aAttribs( xAttribs );
+ mpShapePtr->setHidden( aAttribs.getBool( XML_hidden, false ) );
+ mpShapePtr->setId( xAttribs->getOptionalValue( XML_id ) );
+ mpShapePtr->setName( xAttribs->getOptionalValue( XML_name ) );
+ break;
+ }
+ case PPT_TOKEN( ph ):
+ {
+ sal_Int32 nSubType( xAttribs->getOptionalValueToken( XML_type, XML_obj ) );
+ mpShapePtr->setSubType( nSubType );
+ mpShapePtr->setSubTypeIndex( 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_obj;
+ nSecondPlaceholder = 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, -1, mpSlidePersistPtr->getShapes()->getChildren() );
+ 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,
+ pPPTShapePtr->getSubTypeIndex(), pMasterPersist->getShapes()->getChildren() );
+ }
+ 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 PPT_TOKEN( spPr ):
+ xRet = new PPTShapePropertiesContext( *this, *mpShapePtr );
+ break;
+
+ case PPT_TOKEN( style ):
+ xRet = new oox::drawingml::ShapeStyleContext( *this, *mpShapePtr );
+ break;
+
+ case PPT_TOKEN( txBody ):
+ {
+ oox::drawingml::TextBodyPtr xTextBody( new oox::drawingml::TextBody );
+ xTextBody->getTextProperties().maPropertyMap[ PROP_FontIndependentLineSpacing ] <<= static_cast< sal_Bool >( sal_True );
+ mpShapePtr->setTextBody( xTextBody );
+ xRet = new oox::drawingml::TextBodyContext( *this, *xTextBody );
+ 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..0ba36ee99417
--- /dev/null
+++ b/oox/source/ppt/pptshapegroupcontext.cxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include "oox/helper/attributelist.hxx"
+#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"
+
+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(
+ ContextHandler& rParent,
+ const oox::ppt::SlidePersistPtr pSlidePersistPtr,
+ const ShapeLocation eShapeLocation,
+ oox::drawingml::ShapePtr pMasterShapePtr,
+ oox::drawingml::ShapePtr pGroupShapePtr )
+: ShapeGroupContext( rParent, 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 PPT_TOKEN( cNvPr ):
+ {
+ AttributeList aAttribs( xAttribs );
+ mpGroupShapePtr->setHidden( aAttribs.getBool( XML_hidden, false ) );
+ mpGroupShapePtr->setId( xAttribs->getOptionalValue( XML_id ) );
+ mpGroupShapePtr->setName( xAttribs->getOptionalValue( XML_name ) );
+ break;
+ }
+ case PPT_TOKEN( ph ):
+ mpGroupShapePtr->setSubType( xAttribs->getOptionalValueToken( XML_type, FastToken::DONTKNOW ) );
+ mpGroupShapePtr->setSubTypeIndex( xAttribs->getOptionalValue( XML_idx ).toInt32() );
+ break;
+ // nvSpPr CT_ShapeNonVisual end
+
+ case PPT_TOKEN( grpSpPr ):
+ xRet = new oox::drawingml::ShapePropertiesContext( *this, *mpGroupShapePtr );
+ break;
+ case PPT_TOKEN( spPr ):
+ xRet = new oox::drawingml::ShapePropertiesContext( *this, *mpGroupShapePtr );
+ break;
+/*
+ case PPT_TOKEN( style ):
+ xRet = new ShapeStyleContext( getParser() );
+ break;
+*/
+ case PPT_TOKEN( cxnSp ): // connector shape
+ xRet.set( new oox::drawingml::ConnectorShapeContext( *this, mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.ConnectorShape" ) ) ) );
+ break;
+ case PPT_TOKEN( grpSp ): // group shape
+ xRet.set( new PPTShapeGroupContext( *this, mpSlidePersistPtr, meShapeLocation, mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.GroupShape" ) ) ) );
+ break;
+ case PPT_TOKEN( sp ): // Shape
+ xRet.set( new PPTShapeContext( *this, mpSlidePersistPtr, mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.CustomShape" ) ) ) );
+ break;
+ case PPT_TOKEN( pic ): // CT_Picture
+ xRet.set( new oox::drawingml::GraphicShapeContext( *this, mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.GraphicObjectShape" ) ) ) );
+ break;
+ case PPT_TOKEN( graphicFrame ): // CT_GraphicalObjectFrame
+ xRet.set( new oox::drawingml::GraphicalObjectFrameContext( *this, mpGroupShapePtr, oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.OLE2Shape" ) ), true ) );
+ 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..bddd74f4837a
--- /dev/null
+++ b/oox/source/ppt/pptshapepropertiescontext.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/drawingml/fillpropertiesgroupcontext.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/customshapegeometry.hxx"
+#include "oox/drawingml/textbodycontext.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( ContextHandler& rParent, ::oox::drawingml::Shape& rShape )
+: ShapePropertiesContext( rParent, rShape )
+{
+}
+
+Reference< XFastContextHandler > PPTShapePropertiesContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
+ throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( xfrm ):
+ {
+ mrShape.getShapeProperties()[ PROP_IsPlaceholderDependent ] <<= 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..6976c965ad83
--- /dev/null
+++ b/oox/source/ppt/presentationfragmenthandler.cxx
@@ -0,0 +1,390 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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 <com/sun/star/task/XStatusIndicator.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"
+
+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( XmlFilterBase& rFilter, const OUString& rFragmentPath ) throw()
+: FragmentHandler( rFilter, rFragmentPath )
+, mpTextListStyle( new TextListStyle )
+{
+ TextParagraphPropertiesVector& rParagraphDefaulsVector( mpTextListStyle->getListStyle() );
+ TextParagraphPropertiesVector::iterator aParagraphDefaultIter( rParagraphDefaulsVector.begin() );
+ while( aParagraphDefaultIter != rParagraphDefaulsVector.end() )
+ {
+ // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
+ // so this attribute needs to be set always
+ (*aParagraphDefaultIter++)->getParaBottomMargin() = TextSpacing( 0 );
+ }
+}
+
+PresentationFragmentHandler::~PresentationFragmentHandler() throw()
+{
+
+}
+void PresentationFragmentHandler::startDocument() throw (SAXException, RuntimeException)
+{
+}
+
+void ResolveTextFields( XmlFilterBase& rFilter )
+{
+ const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
+ if ( rTextFields.size() )
+ {
+ Reference< frame::XModel > xModel( rFilter.getModel() );
+ oox::core::TextFieldStack::const_iterator aIter( rTextFields.begin() );
+ while( aIter != rTextFields.end() )
+ {
+ const OUString sURL = CREATE_OUSTRING( "URL" );
+ Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
+ Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );
+
+ const oox::core::TextField& rTextField( *aIter++ );
+ Reference< XPropertySet > xPropSet( rTextField.xTextField, UNO_QUERY );
+ Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+ if ( xPropSetInfo->hasPropertyByName( sURL ) )
+ {
+ rtl::OUString aURL;
+ if ( xPropSet->getPropertyValue( sURL ) >>= aURL )
+ {
+ const OUString sSlide = CREATE_OUSTRING( "#Slide " );
+ const OUString sNotes = CREATE_OUSTRING( "#Notes " );
+ sal_Bool bNotes = sal_False;
+ sal_Int32 nPageNumber = 0;
+ if ( aURL.match( sSlide ) )
+ nPageNumber = aURL.copy( sSlide.getLength() ).toInt32();
+ else if ( aURL.match( sNotes ) )
+ {
+ nPageNumber = aURL.copy( sNotes.getLength() ).toInt32();
+ bNotes = sal_True;
+ }
+ if ( nPageNumber )
+ {
+ try
+ {
+ Reference< XDrawPage > xDrawPage;
+ xDrawPages->getByIndex( nPageNumber - 1 ) >>= xDrawPage;
+ if ( bNotes )
+ {
+ Reference< ::com::sun::star::presentation::XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
+ xDrawPage = xPresentationPage->getNotesPage();
+ }
+ Reference< container::XNamed > xNamed( xDrawPage, UNO_QUERY_THROW );
+ aURL = CREATE_OUSTRING( "#" ).concat( xNamed->getName() );
+ xPropSet->setPropertyValue( sURL, Any( aURL ) );
+ Reference< text::XTextContent > xContent( rTextField.xTextField, UNO_QUERY);
+ Reference< text::XTextRange > xTextRange( rTextField.xTextCursor, UNO_QUERY );
+ rTextField.xText->insertTextContent( xTextRange, xContent, sal_True );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void PresentationFragmentHandler::endDocument() throw (SAXException, RuntimeException)
+{
+ // todo: localized progress bar text
+ const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
+ if ( rxStatusIndicator.is() )
+ rxStatusIndicator->start( rtl::OUString(), 10000 );
+
+ try
+ {
+ PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
+
+ Reference< frame::XModel > xModel( rFilter.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 ( rxStatusIndicator.is() )
+ rxStatusIndicator->setValue( ( nSlide * 10000 ) / maSlidesVector.size() );
+
+ 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( rFilter, sal_False, sal_False, xSlide,
+ ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
+
+ FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );
+
+ // importing the corresponding masterpage/layout
+ OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "slideLayout" ) );
+ if ( aLayoutFragmentPath.getLength() > 0 )
+ {
+ // importing layout
+ RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
+ OUString aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "slideMaster" ) );
+ if( aMasterFragmentPath.getLength() )
+ {
+ // check if the corresponding masterpage+layout has already been imported
+ std::vector< SlidePersistPtr >& rMasterPages( rFilter.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( !(rFilter.getMasterPages().size() ))
+ xMasterPages->getByIndex( 0 ) >>= xMasterPage;
+ else
+ xMasterPage = xMasterPages->insertNewByIndex( xMasterPages->getCount() );
+
+ pMasterPersistPtr = SlidePersistPtr( new SlidePersist( rFilter, sal_True, sal_False, xMasterPage,
+ ShapePtr( new PPTShape( Master, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
+ pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
+ rFilter.getMasterPages().push_back( pMasterPersistPtr );
+ rFilter.setActualSlidePersist( pMasterPersistPtr );
+ FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, aMasterFragmentPath, pMasterPersistPtr, Master ) );
+
+ // set the correct theme
+ OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) );
+ if( aThemeFragmentPath.getLength() > 0 )
+ {
+ std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.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 );
+ rFilter.importFragment( new ThemeFragmentHandler( rFilter, aThemeFragmentPath, *pThemePtr ) );
+ rThemes[ aThemeFragmentPath ] = pThemePtr;
+ }
+ else
+ {
+ pMasterPersistPtr->setTheme( (*aIter2).second );
+ }
+ }
+ importSlide( xMasterFragmentHandler, pMasterPersistPtr );
+ rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
+ pMasterPersistPtr->createBackground( rFilter );
+ pMasterPersistPtr->createXShapes( rFilter );
+ }
+ }
+ }
+
+ // 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() );
+ rFilter.getDrawPages().push_back( pSlidePersistPtr );
+ rFilter.setActualSlidePersist( pSlidePersistPtr );
+ importSlide( xSlideFragmentHandler, pSlidePersistPtr );
+ pSlidePersistPtr->createBackground( rFilter );
+ pSlidePersistPtr->createXShapes( rFilter );
+
+ // now importing the notes page
+ OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_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( rFilter, sal_False, sal_True, xNotesPage,
+ ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
+ FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
+ rFilter.getNotesPages().push_back( pNotesPersistPtr );
+ rFilter.setActualSlidePersist( pNotesPersistPtr );
+ importSlide( xNotesFragmentHandler, pNotesPersistPtr );
+ pNotesPersistPtr->createBackground( rFilter );
+ pNotesPersistPtr->createXShapes( rFilter );
+ }
+ }
+ }
+ }
+ }
+ ResolveTextFields( rFilter );
+ }
+ 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;
+ if ( rxStatusIndicator.is() )
+ rxStatusIndicator->end();
+}
+
+// CT_Presentation
+Reference< XFastContextHandler > PresentationFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( presentation ):
+ case PPT_TOKEN( sldMasterIdLst ):
+ case PPT_TOKEN( notesMasterIdLst ):
+ case PPT_TOKEN( sldIdLst ):
+ break;
+ case PPT_TOKEN( sldMasterId ):
+ maSlideMasterVector.push_back( xAttribs->getOptionalValue( R_TOKEN( id ) ) );
+ break;
+ case PPT_TOKEN( sldId ):
+ maSlidesVector.push_back( xAttribs->getOptionalValue( R_TOKEN( id ) ) );
+ break;
+ case PPT_TOKEN( notesMasterId ):
+ maNotesMasterVector.push_back( xAttribs->getOptionalValue(R_TOKEN( id ) ) );
+ break;
+ case PPT_TOKEN( sldSz ):
+ maSlideSize = GetSize2D( xAttribs );
+ break;
+ case PPT_TOKEN( notesSz ):
+ maNotesSize = GetSize2D( xAttribs );
+ break;
+ case PPT_TOKEN( custShowLst ):
+ xRet.set( new CustomShowListContext( *this, maCustomShowList ) );
+ break;
+ case PPT_TOKEN( defaultTextStyle ):
+ xRet.set( new TextListStyleContext( *this, *mpTextListStyle ) );
+ break;
+ }
+ if ( !xRet.is() )
+ xRet = getFastContextHandler();
+ 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 ) );
+
+ oox::ppt::HeaderFooter aHeaderFooter( pSlidePersistPtr->getHeaderFooter() );
+ if ( !pSlidePersistPtr->isMasterPage() )
+ aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = sal_False;
+ try
+ {
+ static const OUString sIsHeaderVisible = CREATE_OUSTRING( "IsHeaderVisible" );
+ static const OUString sIsFooterVisible = CREATE_OUSTRING( "IsFooterVisible" );
+ static const OUString sIsDateTimeVisible = CREATE_OUSTRING( "IsDateTimeVisible" );
+ static const OUString sIsPageNumberVisible = CREATE_OUSTRING( "IsPageNumberVisible" );
+
+ if ( pSlidePersistPtr->isNotesPage() )
+ xPropertySet->setPropertyValue( sIsHeaderVisible, Any( aHeaderFooter.mbHeader ) );
+ xPropertySet->setPropertyValue( sIsFooterVisible, Any( aHeaderFooter.mbFooter ) );
+ xPropertySet->setPropertyValue( sIsDateTimeVisible, Any( aHeaderFooter.mbDateTime ) );
+ xPropertySet->setPropertyValue( sIsPageNumberVisible, Any( aHeaderFooter.mbSlideNumber ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ 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..1d25abe5c941
--- /dev/null
+++ b/oox/source/ppt/slidefragmenthandler.cxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/helper/propertyset.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "headerfootercontext.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/vml/vmldrawing.hxx"
+#include "oox/vml/vmldrawingfragment.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( XmlFilterBase& rFilter, const OUString& rFragmentPath, SlidePersistPtr pPersistPtr, const ShapeLocation eShapeLocation ) throw()
+: FragmentHandler( rFilter, rFragmentPath )
+, mpSlidePersistPtr( pPersistPtr )
+, meShapeLocation( eShapeLocation )
+{
+ OUString aVMLDrawingFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "vmlDrawing" ) );
+ if( aVMLDrawingFragmentPath.getLength() > 0 )
+ getFilter().importFragment( new oox::vml::DrawingFragment(
+ getFilter(), aVMLDrawingFragmentPath, *pPersistPtr->getDrawing() ) );
+}
+
+SlideFragmentHandler::~SlideFragmentHandler() throw()
+{
+ // convert and insert all VML shapes (mostly form controls)
+ mpSlidePersistPtr->getDrawing()->convertAndInsert();
+}
+
+Reference< XFastContextHandler > SlideFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
+{
+ Reference< XFastContextHandler > xRet;
+ AttributeList aAttribs( xAttribs );
+
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( sldMaster ): // CT_SlideMaster
+ case PPT_TOKEN( handoutMaster ): // CT_HandoutMaster
+ case PPT_TOKEN( sld ): // CT_CommonSlideData
+ {
+ AttributeList attribs( xAttribs );
+
+ Reference< XDrawPage > xSlide( mpSlidePersistPtr->getPage() );
+ PropertyMap aPropMap;
+ PropertySet aSlideProp( xSlide );
+
+ aPropMap[ PROP_Visible ] = Any( attribs.getBool( XML_show, sal_True ) );
+ aSlideProp.setProperties( aPropMap );
+
+ break;
+ }
+ case PPT_TOKEN( notes ): // CT_NotesSlide
+ case PPT_TOKEN( notesMaster ): // CT_NotesMaster
+ break;
+ case PPT_TOKEN( cSld ): // CT_CommonSlideData
+ maSlideName = xAttribs->getOptionalValue(XML_name);
+ break;
+
+ case PPT_TOKEN( spTree ): // CT_GroupShape
+ {
+ xRet.set( new PPTShapeGroupContext(
+ *this, mpSlidePersistPtr, meShapeLocation, mpSlidePersistPtr->getShapes(),
+ oox::drawingml::ShapePtr( new PPTShape( meShapeLocation, "com.sun.star.drawing.GroupShape" ) ) ) );
+ }
+ break;
+
+ case PPT_TOKEN( controls ):
+ xRet = getFastContextHandler();
+ break;
+ case PPT_TOKEN( control ):
+ {
+ ::oox::vml::ControlInfo aInfo;
+ aInfo.setShapeId( aAttribs.getInteger( XML_spid, 0 ) );
+ aInfo.maFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) );
+ aInfo.maName = aAttribs.getXString( XML_name, OUString() );
+ mpSlidePersistPtr->getDrawing()->registerControl( aInfo );
+ }
+ return xRet;
+
+ case PPT_TOKEN( timing ): // CT_SlideTiming
+ xRet.set( new SlideTimingContext( *this, mpSlidePersistPtr->getTimeNodeList() ) );
+ break;
+ case PPT_TOKEN( transition ): // CT_SlideTransition
+ xRet.set( new SlideTransitionContext( *this, xAttribs, maSlideProperties ) );
+ break;
+ case PPT_TOKEN( hf ):
+ xRet.set( new HeaderFooterContext( *this, xAttribs, mpSlidePersistPtr->getHeaderFooter() ) );
+ break;
+
+ // BackgroundGroup
+ case PPT_TOKEN( bgPr ): // CT_BackgroundProperties
+ {
+ FillPropertiesPtr pFillPropertiesPtr( new FillProperties );
+ xRet.set( new BackgroundPropertiesContext( *this, *pFillPropertiesPtr ) );
+ mpSlidePersistPtr->setBackgroundProperties( pFillPropertiesPtr );
+ }
+ break;
+
+ case PPT_TOKEN( bgRef ): // a:CT_StyleMatrixReference
+ {
+ FillPropertiesPtr pFillPropertiesPtr( new FillProperties(
+ *mpSlidePersistPtr->getTheme()->getFillStyle( xAttribs->getOptionalValue( XML_idx ).toInt32() ) ) );
+ xRet.set( new ColorContext( *this, mpSlidePersistPtr->getBackgroundColorRef() ) );
+ mpSlidePersistPtr->setBackgroundProperties( pFillPropertiesPtr );
+ }
+ break;
+
+ case PPT_TOKEN( clrMap ): // CT_ColorMapping
+ {
+ oox::drawingml::ClrMapPtr pClrMapPtr( new oox::drawingml::ClrMap() );
+ xRet.set( new oox::drawingml::clrMapContext( *this, xAttribs, *pClrMapPtr ) );
+ mpSlidePersistPtr->setClrMap( pClrMapPtr );
+ }
+ break;
+ case PPT_TOKEN( clrMapOvr ): // CT_ColorMappingOverride
+ case PPT_TOKEN( sldLayoutIdLst ): // CT_SlideLayoutIdList
+ break;
+ case PPT_TOKEN( txStyles ): // CT_SlideMasterTextStyles
+ xRet.set( new SlideMasterTextStylesContext( *this, mpSlidePersistPtr ) );
+ break;
+ case PPT_TOKEN( custDataLst ): // CT_CustomerDataList
+ case PPT_TOKEN( tagLst ): // CT_TagList
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet = getFastContextHandler();
+
+ 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() );
+ PropertySet aSlideProp( xSlide );
+ aSlideProp.setProperties( maSlideProperties );
+ 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..d4c777102a0a
--- /dev/null
+++ b/oox/source/ppt/slidemastertextstylescontext.cxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/drawingml/textliststyle.hxx"
+#include "oox/drawingml/textliststylecontext.hxx"
+#include "oox/ppt/slidemastertextstylescontext.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( ContextHandler& rParent, SlidePersistPtr pSlidePersistPtr )
+: ContextHandler( rParent )
+, 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 PPT_TOKEN( titleStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getTitleTextStyle();
+ break;
+ }
+ case PPT_TOKEN( bodyStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getBodyTextStyle();
+ break;
+ }
+ case PPT_TOKEN( notesStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getNotesTextStyle();
+ break;
+ }
+ case PPT_TOKEN( otherStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getOtherTextStyle();
+ break;
+ }
+ }
+ if ( aTextListStylePtr ) // sj: the master list style is the last instance of from where properties
+ { // are obtained. i got some documents without having the textsize set at
+ for ( int i = 0; i < 9; i++ ) // any point, the master reference application is using 18pt then
+ aTextListStylePtr->getListStyle()[ i ]->getTextCharacterProperties().moHeight = 1800;
+ xRet.set( new oox::drawingml::TextListStyleContext( *this, *aTextListStylePtr ) );
+ }
+ 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..7f8fba345bd6
--- /dev/null
+++ b/oox/source/ppt/slidepersist.cxx
@@ -0,0 +1,317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/helper/propertyset.hxx"
+#include "oox/ppt/timenode.hxx"
+#include "oox/ppt/pptshape.hxx"
+#include "oox/ppt/slidepersist.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/core/xmlfilterbase.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( XmlFilterBase& rFilter, 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( rFilter, rxPage, oox::vml::VMLDRAWING_POWERPOINT ) )
+, 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 )
+{
+ if ( pDefaultTextStyle )
+ {
+ /*
+ maTitleTextStylePtr->apply( *pDefaultTextStyle.get() );
+ maBodyTextStylePtr->apply( *pDefaultTextStyle.get() );
+ maNotesTextStylePtr->apply( *pDefaultTextStyle.get() );
+ */
+ maOtherTextStylePtr->apply( *pDefaultTextStyle.get() );
+ }
+}
+
+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( XmlFilterBase& rFilterBase )
+{
+ applyTextStyles( rFilterBase );
+
+ Reference< XShapes > xShapes( getPage(), UNO_QUERY );
+
+ std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() );
+ std::vector< oox::drawingml::ShapePtr >::iterator aShapesIter( rShapes.begin() );
+ while( aShapesIter != rShapes.end() )
+ {
+ std::vector< oox::drawingml::ShapePtr >& rChildren( (*aShapesIter++)->getChildren() );
+ std::vector< oox::drawingml::ShapePtr >::iterator aChildIter( rChildren.begin() );
+ while( aChildIter != rChildren.end() )
+ {
+ PPTShape* pPPTShape = dynamic_cast< PPTShape* >( (*aChildIter).get() );
+ if ( pPPTShape )
+ pPPTShape->addShape( rFilterBase, *this, getTheme().get(), xShapes, 0, &getShapeMap() );
+ else
+ (*aChildIter)->addShape( rFilterBase, getTheme().get(), xShapes, 0, &getShapeMap() );
+ 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( rFilterBase, xNode, pSlidePtr );
+ }
+ }
+}
+
+void SlidePersist::createBackground( const XmlFilterBase& rFilterBase )
+{
+ if ( mpBackgroundPropertiesPtr )
+ {
+ try
+ {
+ sal_Int32 nPhClr = API_RGB_TRANSPARENT;
+ if ( maBackgroundColorRef.isUsed() )
+ nPhClr = maBackgroundColorRef.getColor( rFilterBase.getGraphicHelper() );
+
+ 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() );
+ PropertySet aPropSet( xPropertySet );
+ mpBackgroundPropertiesPtr->pushToPropSet( aPropSet, rFilterBase.getModelObjectHelper(),
+ rFilterBase.getGraphicHelper(), oox::drawingml::FillProperties::DEFAULT_IDS, 0, nPhClr );
+ xPagePropSet->setPropertyValue( sBackground, Any( xPropertySet ) );
+ }
+ catch( Exception )
+ {
+ }
+ }
+}
+
+void setTextStyle( Reference< beans::XPropertySet >& rxPropSet, const XmlFilterBase& rFilter,
+ oox::drawingml::TextListStylePtr& pTextListStylePtr, int nLevel )
+{
+ ::oox::drawingml::TextParagraphPropertiesPtr pTextParagraphPropertiesPtr( pTextListStylePtr->getListStyle()[ nLevel ] );
+ if( pTextParagraphPropertiesPtr == NULL )
+ {
+ // no properties. return
+ return;
+ }
+
+ PropertyMap& rTextParagraphPropertyMap( pTextParagraphPropertiesPtr->getTextParagraphPropertyMap() );
+
+ PropertySet aPropSet( rxPropSet );
+ aPropSet.setProperties( rTextParagraphPropertyMap );
+ pTextParagraphPropertiesPtr->getTextCharacterProperties().pushToPropSet( aPropSet, rFilter );
+}
+
+void SlidePersist::applyTextStyles( const XmlFilterBase& rFilterBase )
+{
+ if ( mbMaster )
+ {
+ try
+ {
+ Reference< style::XStyleFamiliesSupplier > aXStyleFamiliesSupplier( rFilterBase.getModel(), 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, rFilterBase, maDefaultTextStylePtr, 0 );
+ setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, 0 );
+ if ( i == 1 /* BodyStyle */ )
+ {
+ for ( int nLevel = 1; nLevel < 5; nLevel++ )
+ {
+ {
+ sal_Char pOutline[ 9 ] = "outline1";
+ pOutline[ 7 ] = static_cast< sal_Char >( '0' + nLevel );
+ 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, rFilterBase, maDefaultTextStylePtr, nLevel );
+ setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, nLevel );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+} }
+
diff --git a/oox/source/ppt/slidetimingcontext.cxx b/oox/source/ppt/slidetimingcontext.cxx
new file mode 100644
index 000000000000..4357e14ea08e
--- /dev/null
+++ b/oox/source/ppt/slidetimingcontext.cxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/ppt/timenodelistcontext.hxx"
+#include "buildlistcontext.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( ContextHandler& rParent, TimeNodePtrList & aTimeNodeList ) throw()
+ : ContextHandler( rParent )
+ , 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 PPT_TOKEN( bldLst ):
+ xRet.set( new BuildListContext( *this, xAttribs, maTimeNodeList ) );
+ break;
+ case PPT_TOKEN( extLst ):
+ return xRet;
+ case PPT_TOKEN( tnLst ):
+ // timing nodes
+ {
+ xRet.set( new TimeNodeListContext( *this, 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..a380a4d945e1
--- /dev/null
+++ b/oox/source/ppt/slidetransition.cxx
@@ -0,0 +1,418 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/token/namespaces.hxx"
+#include "oox/token/tokens.hxx"
+#include "pptfilterhelpers.hxx"
+
+using rtl::OUString;
+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[ PROP_TransitionType ] <<= mnTransitionType;
+ aProps[ PROP_TransitionSubtype ] <<= mnTransitionSubType;
+ aProps[ PROP_TransitionDirection ] <<= mbTransitionDirectionNormal;
+ aProps[ PROP_Speed ] <<= mnAnimationSpeed;
+ aProps[ PROP_TransitionFadeColor ] <<= 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::ooxToOdpSideDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ switch( nOoxType )
+ {
+ case XML_d:
+ case XML_u:
+ nOdpDirection = TransitionSubType::TOPTOBOTTOM;
+ break;
+ case XML_l:
+ case XML_r:
+ nOdpDirection = TransitionSubType::LEFTTORIGHT;
+ break;
+ default:
+ nOdpDirection= 0;
+ break;
+ }
+ return nOdpDirection;
+ }
+
+ sal_Bool SlideTransition::ooxToOdpSideDirectionsDirectionNormal( ::sal_Int32 nOoxType )
+ {
+ sal_Bool nOdpDirection = true;
+ switch( nOoxType )
+ {
+ case XML_u:
+ case XML_l:
+ nOdpDirection = false;
+ 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 PPT_TOKEN( blinds ):
+ mnTransitionType = TransitionType::BLINDSWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ break;
+ case PPT_TOKEN( checker ):
+ mnTransitionType = TransitionType::CHECKERBOARDWIPE;
+ switch ( param1 )
+ {
+ case XML_vert:
+ mnTransitionSubType = TransitionSubType::DOWN;
+ break;
+ case XML_horz:
+ mnTransitionSubType = TransitionSubType::ACROSS;
+ break;
+ default:
+ break;
+ }
+ break;
+ case PPT_TOKEN( comb ):
+ mnTransitionType = TransitionType::PUSHWIPE;
+ switch( param1 )
+ {
+ case XML_vert:
+ mnTransitionSubType = TransitionSubType::COMBVERTICAL;
+ break;
+ case XML_horz:
+ mnTransitionSubType = TransitionSubType::COMBHORIZONTAL;
+ break;
+ default:
+ break;
+ }
+ break;
+ case PPT_TOKEN( cover ):
+ mnTransitionType = TransitionType::SLIDEWIPE;
+ mnTransitionSubType = ooxToOdpEightDirections( param1 );
+ break;
+ case PPT_TOKEN( pull ): // uncover
+ mnTransitionType = TransitionType::SLIDEWIPE;
+ mnTransitionSubType = ooxToOdpEightDirections( param1 );
+ mbTransitionDirectionNormal = false;
+ break;
+ case PPT_TOKEN( 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 PPT_TOKEN( fade ):
+ mnTransitionType = TransitionType::FADE;
+ if( param1 )
+ {
+ mnTransitionSubType = TransitionSubType::FADEOVERCOLOR;
+ }
+ else
+ {
+ mnTransitionSubType = TransitionSubType::CROSSFADE;
+ }
+ break;
+ case PPT_TOKEN( push ):
+ mnTransitionType = TransitionType::PUSHWIPE;
+ mnTransitionSubType = ooxToOdpBorderDirections( param1 );
+ break;
+ case PPT_TOKEN( wipe ):
+ mnTransitionType = TransitionType::BARWIPE;
+ mnTransitionSubType = ooxToOdpSideDirections( param1 );
+ mbTransitionDirectionNormal = ooxToOdpSideDirectionsDirectionNormal( param1 );
+ break;
+ case PPT_TOKEN( split ):
+ mnTransitionType = TransitionType::BARNDOORWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ if( param2 == XML_in )
+ {
+ // reverse
+ mbTransitionDirectionNormal = false;
+ }
+ break;
+ case PPT_TOKEN( 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 PPT_TOKEN( randomBar ):
+ mnTransitionType = TransitionType::RANDOMBARWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ break;
+ case PPT_TOKEN( circle ):
+ mnTransitionType = TransitionType::ELLIPSEWIPE;
+ mnTransitionSubType = TransitionSubType::CIRCLE;
+ break;
+ case PPT_TOKEN( diamond ):
+ mnTransitionType = TransitionType::IRISWIPE;
+ mnTransitionSubType = TransitionSubType::DIAMOND;
+ break;
+ case PPT_TOKEN( dissolve ):
+ mnTransitionType = TransitionType::DISSOLVE;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ case PPT_TOKEN( newsflash ):
+ // this is what the PPT binary filter does.... not sure I agree.
+ mnTransitionType = TransitionType::FOURBOXWIPE;
+ mnTransitionSubType = TransitionSubType::CORNERSOUT;
+ break;
+ case PPT_TOKEN( plus ):
+ mnTransitionType = TransitionType::FOURBOXWIPE;
+ mnTransitionSubType = TransitionSubType::CORNERSOUT;
+ break;
+ case PPT_TOKEN( random ):
+ mnTransitionType = TransitionType::RANDOM;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ case PPT_TOKEN( wedge ):
+ mnTransitionType = TransitionType::FANWIPE;
+ mnTransitionSubType = TransitionSubType::CENTERTOP;
+ break;
+ case PPT_TOKEN( 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..4c5ae7dcc65f
--- /dev/null
+++ b/oox/source/ppt/slidetransitioncontext.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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"
+
+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( ContextHandler& rParent, const Reference< XFastAttributeList >& xAttribs, PropertyMap & aProperties ) throw()
+: ContextHandler( rParent )
+, 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 PPT_TOKEN( blinds ):
+ case PPT_TOKEN( checker ):
+ case PPT_TOKEN( comb ):
+ case PPT_TOKEN( randomBar ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, xAttribs->getOptionalValueToken( XML_dir, XML_horz ), 0);
+ // ST_Direction { XML_horz, XML_vert }
+ }
+ break;
+ case PPT_TOKEN( cover ):
+ case PPT_TOKEN( 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 PPT_TOKEN( cut ):
+ case PPT_TOKEN( fade ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ AttributeList attribs(xAttribs);
+ // CT_OptionalBlackTransition xdb:bool
+ maTransition.setOoxTransitionType( aElementToken, attribs.getBool( XML_thruBlk, false ), 0);
+ }
+ break;
+ case PPT_TOKEN( push ):
+ case PPT_TOKEN( 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 PPT_TOKEN( 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 PPT_TOKEN( zoom ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, xAttribs->getOptionalValueToken( XML_dir, XML_out ), 0 );
+ // ST_TransitionInOutDirectionType { XML_out, XML_in }
+ }
+ break;
+ case PPT_TOKEN( wheel ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ AttributeList attribs(xAttribs);
+ maTransition.setOoxTransitionType( aElementToken, attribs.getUnsigned( XML_spokes, 4 ), 0 );
+ // unsignedInt
+ }
+ break;
+ case PPT_TOKEN( circle ):
+ case PPT_TOKEN( diamond ):
+ case PPT_TOKEN( dissolve ):
+ case PPT_TOKEN( newsflash ):
+ case PPT_TOKEN( plus ):
+ case PPT_TOKEN( random ):
+ case PPT_TOKEN( wedge ):
+ // CT_Empty
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, 0, 0 );
+ }
+ break;
+
+
+ case PPT_TOKEN( sndAc ): // CT_TransitionSoundAction
+ //"Sound"
+ xRet.set( new SoundActionContext ( *this, maSlideProperties ) );
+ break;
+ case PPT_TOKEN( extLst ): // CT_OfficeArtExtensionList
+ return xRet;
+ 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 == (PPT_TOKEN( 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..e9b955a73e15
--- /dev/null
+++ b/oox/source/ppt/soundactioncontext.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/drawingml/embeddedwavaudiofile.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( ContextHandler& rParent, PropertyMap & aProperties ) throw()
+ : ContextHandler( rParent )
+ , maSlideProperties( aProperties )
+ , mbHasStartSound( false )
+ , mbLoopSound( false )
+ , mbStopSound( false )
+ {
+ }
+
+
+ SoundActionContext::~SoundActionContext() throw()
+ {
+ }
+
+
+ void SoundActionContext::endFastElement( sal_Int32 aElement ) throw (SAXException, RuntimeException)
+ {
+ if ( aElement == PPT_TOKEN( 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[ PROP_Sound ] <<= url;
+ maSlideProperties[ PROP_SoundOn ] <<= 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 PPT_TOKEN( snd ):
+ if( mbHasStartSound )
+ {
+ drawingml::EmbeddedWAVAudioFile aAudio;
+ drawingml::getEmbeddedWAVAudioFile( getRelations(), xAttribs, aAudio);
+
+ msSndName = ( aAudio.mbBuiltIn ? aAudio.msName : aAudio.msEmbed );
+ }
+ break;
+ case PPT_TOKEN( endSnd ):
+ // CT_Empty
+ mbStopSound = true;
+ break;
+ case PPT_TOKEN( 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..185897f2e101
--- /dev/null
+++ b/oox/source/ppt/timeanimvaluecontext.cxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "timeanimvaluecontext.hxx"
+
+#include "animvariantcontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox { namespace ppt {
+
+ TimeAnimValueListContext::TimeAnimValueListContext( ContextHandler& rParent,
+ const Reference< XFastAttributeList >& /*xAttribs*/,
+ TimeAnimationValueList & aTavList )
+ : ContextHandler( rParent )
+ , maTavList( aTavList )
+ , mbInValue( false )
+ {
+ }
+
+
+ TimeAnimValueListContext::~TimeAnimValueListContext( )
+ {
+ }
+
+
+ void SAL_CALL TimeAnimValueListContext::endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ if( aElement == PPT_TOKEN( 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 PPT_TOKEN( tav ):
+ {
+ mbInValue = true;
+ TimeAnimationValue val;
+ val.msFormula = xAttribs->getOptionalValue( XML_fmla );
+ val.msTime = xAttribs->getOptionalValue( XML_tm );
+ maTavList.push_back( val );
+ break;
+ }
+ case PPT_TOKEN( val ):
+ if( mbInValue )
+ {
+ // CT_TLAnimVariant
+ xRet.set( new AnimVariantContext( *this, 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..0c6391e4c175
--- /dev/null
+++ b/oox/source/ppt/timeanimvaluecontext.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+
+#ifndef OOX_PPT_TIMEANIMVALUELISTCONTEXT
+#define OOX_PPT_TIMEANIMVALUELISTCONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/ppt/animationspersist.hxx"
+
+namespace oox { namespace ppt {
+
+ /** CT_TLTimeAnimateValueList */
+ class TimeAnimValueListContext
+ : public ::oox::core::ContextHandler
+ {
+ public:
+ TimeAnimValueListContext( ::oox::core::ContextHandler& rParent,
+ 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..6887bcfdf3a3
--- /dev/null
+++ b/oox/source/ppt/timenode.cxx
@@ -0,0 +1,630 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ppt/timenode.hxx"
+
+#include <boost/bind.hpp>
+
+#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"
+#include "oox/core/xmlfilterbase.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 XmlFilterBase& rFilter, const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide )
+ {
+ try {
+ OUString sServiceName = getServiceName( mnNodeType );
+ Reference< XAnimationNode > xNode = createAndInsert( rFilter, sServiceName, rxNode );
+ setNode( rFilter, 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 XmlFilterBase& rFilter, 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);
+ }
+
+ if( !maUserData.empty() )
+ {
+ Sequence< NamedValue > aUserDataSeq( static_cast< sal_Int32 >( maUserData.size() ) );
+ NamedValue* pValues = aUserDataSeq.getArray();
+ for( UserDataMap::const_iterator aIt = maUserData.begin(), aEnd = maUserData.end(); aIt != aEnd; ++aIt, ++pValues )
+ {
+ pValues->Name = aIt->first;
+ pValues->Value = aIt->second;
+ }
+ maNodeProperties[ NP_USERDATA ] <<= 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( maChildren.begin(), maChildren.end(),
+ boost::bind(&TimeNode::addNode, _1, boost::cref(rFilter), 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 XmlFilterBase& rFilter,
+ const OUString& rServiceName,
+ const Reference< XAnimationNode >& rxNode )
+ {
+ try {
+ Reference< XAnimationNode > xNode ( rFilter.getServiceFactory()->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..6a82dc29c1de
--- /dev/null
+++ b/oox/source/ppt/timenodelistcontext.cxx
@@ -0,0 +1,1163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/ppt/timenodelistcontext.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.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/xmlfilterbase.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/colorchoicecontext.hxx"
+#include "oox/ppt/slidetransition.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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, xAttribs, pNode )
+ , mbIsNarration( false )
+ , mbFullScrn( false )
+ {
+ AttributeList attribs( xAttribs );
+
+ switch( aElement )
+ {
+ case PPT_TOKEN( audio ):
+ mbIsNarration = attribs.getBool( XML_isNarration, false );
+ break;
+ case PPT_TOKEN( video ):
+ mbFullScrn = attribs.getBool( XML_fullScrn, false );
+ break;
+ default:
+ break;
+ }
+ }
+
+ virtual void SAL_CALL endFastElement( sal_Int32 aElement )
+ throw ( SAXException, RuntimeException)
+ {
+ if( aElement == PPT_TOKEN( audio ) )
+ {
+ // TODO deal with mbIsNarration
+ }
+ else if( aElement == PPT_TOKEN( 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, 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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( to ):
+ // CT_TLAnimVariant
+ xRet.set( new AnimVariantContext( *this, aElementToken, maTo ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ private:
+ Any maTo;
+ };
+
+ /** CT_TLCommandBehavior
+ */
+ class CmdTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ CmdTimeNodeContext( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, xAttribs, pNode )
+ , maType(0)
+ {
+ switch ( aElement )
+ {
+ case PPT_TOKEN( 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 == PPT_TOKEN( 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, 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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cTn ):
+ xRet.set( new CommonTimeNodeContext( *this, aElementToken, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( nextCondLst ):
+ xRet.set( new CondListContext( *this, aElementToken, xAttribs, mpNode,
+ mpNode->getNextCondition() ) );
+ break;
+ case PPT_TOKEN( prevCondLst ):
+ xRet.set( new CondListContext( *this, 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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cTn ):
+ xRet.set( new CommonTimeNodeContext( *this, aElementToken, xAttribs, mpNode ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+
+ protected:
+
+ };
+
+
+ /** CT_TLAnimateColorBehavior */
+ class AnimColorContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimColorContext( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( rParent, 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 );
+ const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
+ if( maToClr.isUsed() )
+ mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
+ if( maFromClr.isUsed() )
+ mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
+ 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 PPT_TOKEN( 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 PPT_TOKEN( 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 PPT_TOKEN( by ):
+ // CT_TLByAnimateColorTransform
+ mbHasByColor = true;
+ xRet.set(this);
+ break;
+ case PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( to ):
+ // CT_Color
+ xRet.set( new ColorContext( *this, maToClr ) );
+ break;
+ case PPT_TOKEN( from ):
+ // CT_Color
+ xRet.set( new ColorContext( *this, 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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( tavLst ):
+ xRet.set( new TimeAnimValueListContext ( *this, 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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( to ):
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ maTo <<= p.X;
+ maTo <<= p.Y;
+ break;
+ }
+ case PPT_TOKEN( from ):
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ maFrom <<= p.X;
+ maFrom <<= p.Y;
+ break;
+ }
+ case PPT_TOKEN( 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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
+ break;
+ default:
+ break;
+ }
+
+ if( !xRet.is() )
+ xRet.set( this );
+
+ return xRet;
+ }
+ };
+
+
+
+ /** CT_TLAnimateMotionBehavior */
+ class AnimMotionContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimMotionContext( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( to ):
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setTo( rAny );
+ break;
+ }
+ case PPT_TOKEN( from ):
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setFrom( rAny );
+ break;
+ }
+ case PPT_TOKEN( by ):
+ {
+ // CT_TLPoint
+ Point p = GetPointPercent( xAttribs );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setBy( rAny );
+ break;
+ }
+ case PPT_TOKEN( 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( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) throw()
+ : TimeNodeContext( rParent, 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 PPT_TOKEN( cBhvr ):
+ xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
+ break;
+ case PPT_TOKEN( progress ):
+ xRet.set( new AnimVariantContext( *this, 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(
+ ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ {
+ TimeNodeContext *pCtx = NULL;
+ switch( aElement )
+ {
+ case PPT_TOKEN( animClr ):
+ pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( par ):
+ pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( seq ):
+ pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( excl ):
+ pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( anim ):
+ pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animEffect ):
+ pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animMotion ):
+ pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animRot ):
+ pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animScale ):
+ pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( cmd ):
+ pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( set ):
+ pCtx = new SetTimeNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( audio ):
+ case PPT_TOKEN( video ):
+ pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ default:
+ break;
+ }
+ return pCtx;
+ }
+
+
+ TimeNodeContext::TimeNodeContext( ContextHandler& rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& /*xAttribs*/,
+ const TimeNodePtr & pNode ) throw()
+ : ContextHandler( rParent )
+ , mnElement( aElement )
+ , mpNode( pNode )
+ {
+ }
+
+
+ TimeNodeContext::~TimeNodeContext( ) throw()
+ {
+
+ }
+
+
+ TimeNodeListContext::TimeNodeListContext( ContextHandler& rParent, TimeNodePtrList & aList )
+ throw()
+ : ContextHandler( rParent )
+ , 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 PPT_TOKEN( par ):
+ nNodeType = AnimationNodeType::PAR;
+ break;
+ case PPT_TOKEN( seq ):
+ nNodeType = AnimationNodeType::SEQ;
+ break;
+ case PPT_TOKEN( 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 PPT_TOKEN( anim ):
+ nNodeType = AnimationNodeType::ANIMATE;
+ break;
+ case PPT_TOKEN( animClr ):
+ nNodeType = AnimationNodeType::ANIMATECOLOR;
+ break;
+ case PPT_TOKEN( animEffect ):
+ nNodeType = AnimationNodeType::TRANSITIONFILTER;
+ break;
+ case PPT_TOKEN( animMotion ):
+ nNodeType = AnimationNodeType::ANIMATEMOTION;
+ break;
+ case PPT_TOKEN( animRot ):
+ case PPT_TOKEN( animScale ):
+ nNodeType = AnimationNodeType::ANIMATETRANSFORM;
+ break;
+ case PPT_TOKEN( cmd ):
+ nNodeType = AnimationNodeType::COMMAND;
+ break;
+ case PPT_TOKEN( set ):
+ nNodeType = AnimationNodeType::SET;
+ break;
+ case PPT_TOKEN( audio ):
+ nNodeType = AnimationNodeType::AUDIO;
+ break;
+ case PPT_TOKEN( 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 );
+ ContextHandler * pContext = TimeNodeContext::makeContext( *this, aElementToken, xAttribs, pNode );
+ xRet.set( pContext ? pContext : this );
+
+ return xRet;
+ }
+
+
+} }
diff --git a/oox/source/ppt/timetargetelementcontext.cxx b/oox/source/ppt/timetargetelementcontext.cxx
new file mode 100644
index 000000000000..81320bef5e89
--- /dev/null
+++ b/oox/source/ppt/timetargetelementcontext.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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/drawingml/embeddedwavaudiofile.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 ContextHandler
+ {
+ public:
+ ShapeTargetElementContext( ContextHandler& rParent, ShapeTargetElement & aValue )
+ : ContextHandler( rParent )
+ , 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 PPT_TOKEN( bg ):
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_bg;
+ break;
+ case PPT_TOKEN( txEl ):
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_txEl;
+ break;
+ case PPT_TOKEN( subSp ):
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_subSp;
+ maShapeTarget.msSubShapeId = xAttribs->getOptionalValue( XML_spid );
+ break;
+ case PPT_TOKEN( graphicEl ):
+ case PPT_TOKEN( oleChartEl ):
+ bTargetSet = true;
+ // TODO
+ break;
+ case PPT_TOKEN( charRg ):
+ case PPT_TOKEN( pRg ):
+ if( bTargetSet && maShapeTarget.mnType == XML_txEl )
+ {
+ maShapeTarget.mnRangeType = getBaseToken( aElementToken );
+ maShapeTarget.maRange = drawingml::GetIndexRange( xAttribs );
+ }
+ break;
+ default:
+ break;
+ }
+ if( !xRet.is() )
+ xRet.set( this );
+ return xRet;
+ }
+
+ private:
+ bool bTargetSet;
+ ShapeTargetElement & maShapeTarget;
+ };
+
+
+
+ TimeTargetElementContext::TimeTargetElementContext( ContextHandler& rParent, const AnimTargetElementPtr & pValue )
+ : ContextHandler( rParent ),
+ 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 PPT_TOKEN( inkTgt ):
+ {
+ mpTarget->mnType = XML_inkTgt;
+ OUString aId = xAttribs->getOptionalValue( XML_spid );
+ if( aId.getLength() )
+ {
+ mpTarget->msValue = aId;
+ }
+ break;
+ }
+ case PPT_TOKEN( sldTgt ):
+ mpTarget->mnType = XML_sldTgt;
+ break;
+ case PPT_TOKEN( sndTgt ):
+ {
+ mpTarget->mnType = XML_sndTgt;
+ drawingml::EmbeddedWAVAudioFile aAudio;
+ drawingml::getEmbeddedWAVAudioFile( getRelations(), xAttribs, aAudio);
+
+ OUString sSndName = ( aAudio.mbBuiltIn ? aAudio.msName : aAudio.msEmbed );
+ mpTarget->msValue = sSndName;
+ break;
+ }
+ case PPT_TOKEN( 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.", getBaseToken( aElementToken ) );
+ 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..05295e4298ea
--- /dev/null
+++ b/oox/source/ppt/timetargetelementcontext.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_PPT_TIMETARGETELEMENTCONTEXT
+#define OOX_PPT_TIMETARGETELEMENTCONTEXT
+
+#include "oox/core/contexthandler.hxx"
+#include "oox/ppt/animationspersist.hxx"
+
+namespace oox { namespace ppt {
+
+ /** context CT_TLTimeTargetElement */
+ class TimeTargetElementContext
+ : public ::oox::core::ContextHandler
+ {
+ public:
+ TimeTargetElementContext( ::oox::core::ContextHandler& rParent, 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/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
new file mode 100644
index 000000000000..31ab343e0ebc
--- /dev/null
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -0,0 +1,352 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "ShapeContextHandler.hxx"
+#include "oox/vml/vmldrawingfragment.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+
+namespace oox { namespace shape {
+
+using namespace ::com::sun::star;
+using namespace core;
+using namespace drawingml;
+
+::rtl::OUString SAL_CALL ShapeContextHandler_getImplementationName()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.ShapeContextHandler" );
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ShapeContextHandler_getSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > s(1);
+ s[0] = CREATE_OUSTRING( "com.sun.star.xml.sax.FastShapeContextHandler" );
+ return s;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL
+ShapeContextHandler_createInstance( const uno::Reference< uno::XComponentContext > & context)
+ SAL_THROW((uno::Exception))
+{
+ return static_cast< ::cppu::OWeakObject* >( new ShapeContextHandler(context) );
+}
+
+
+ShapeContextHandler::ShapeContextHandler
+(uno::Reference< uno::XComponentContext > const & context) :
+mnStartToken(0), m_xContext(context)
+{
+ try
+ {
+ mxFilterBase.set( new ShapeFilterBase(context) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+ShapeContextHandler::~ShapeContextHandler()
+{
+}
+
+uno::Reference<xml::sax::XFastContextHandler>
+ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element )
+{
+ if (! mxGraphicShapeContext.is())
+ {
+ FragmentHandlerRef rFragmentHandler
+ (new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
+ ShapePtr pMasterShape;
+
+ switch (Element & 0xffff)
+ {
+ case XML_graphic:
+ mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
+ mxGraphicShapeContext.set
+ (new GraphicalObjectFrameContext(*rFragmentHandler, pMasterShape, mpShape, true));
+ break;
+ case XML_pic:
+ mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
+ mxGraphicShapeContext.set
+ (new GraphicShapeContext(*rFragmentHandler, pMasterShape, mpShape));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return mxGraphicShapeContext;
+}
+
+uno::Reference<xml::sax::XFastContextHandler>
+ShapeContextHandler::getDrawingShapeContext()
+{
+ if (!mxDrawingFragmentHandler.is())
+ {
+ mpDrawing.reset( new oox::vml::Drawing( *mxFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD ) );
+ mxDrawingFragmentHandler.set
+ (dynamic_cast<ContextHandler *>
+ (new oox::vml::DrawingFragment
+ ( *mxFilterBase, msRelationFragmentPath, *mpDrawing )));
+ }
+
+ return mxDrawingFragmentHandler;
+}
+
+uno::Reference<xml::sax::XFastContextHandler>
+ShapeContextHandler::getContextHandler()
+{
+ uno::Reference<xml::sax::XFastContextHandler> xResult;
+
+ switch (getNamespace( mnStartToken ))
+ {
+ case NMSP_doc:
+ case NMSP_vml:
+ xResult.set(getDrawingShapeContext());
+ break;
+ default:
+ xResult.set(getGraphicShapeContext(mnStartToken));
+ break;
+ }
+
+ return xResult;
+}
+
+// ::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)
+{
+ static const ::rtl::OUString sInputStream
+ (RTL_CONSTASCII_USTRINGPARAM ("InputStream"));
+
+ uno::Sequence<beans::PropertyValue> aSeq(1);
+ aSeq[0].Name = sInputStream;
+ aSeq[0].Value <<= mxInputStream;
+ mxFilterBase->filter(aSeq);
+
+ mpThemePtr.reset(new Theme());
+
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->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)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->startUnknownElement(Namespace, Name, Attribs);
+}
+
+void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->endFastElement(Element);
+}
+
+void SAL_CALL ShapeContextHandler::endUnknownElement
+(const ::rtl::OUString & Namespace,
+ const ::rtl::OUString & Name)
+ throw (uno::RuntimeException, xml::sax::SAXException)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->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;
+ uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xResult.set(xContextHandler->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)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ return xContextHandler->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)
+{
+ uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
+
+ if (xContextHandler.is())
+ xContextHandler->characters(aChars);
+}
+
+// ::com::sun::star::xml::sax::XFastShapeContextHandler:
+uno::Reference< drawing::XShape > SAL_CALL
+ShapeContextHandler::getShape() throw (uno::RuntimeException)
+{
+ uno::Reference< drawing::XShape > xResult;
+ uno::Reference< drawing::XShapes > xShapes( mxDrawPage, uno::UNO_QUERY );
+
+ if (mxFilterBase.is() && xShapes.is())
+ {
+ if (mpDrawing.get() != NULL)
+ {
+ mpDrawing->finalizeFragmentImport();
+ if( const ::oox::vml::ShapeBase* pShape = mpDrawing->getShapes().getFirstShape() )
+ xResult = pShape->convertAndInsert( xShapes );
+ }
+ else if (mpShape.get() != NULL)
+ {
+ mpShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes);
+ xResult.set(mpShape->getXShape());
+ mxGraphicShapeContext.clear( );
+ }
+ }
+
+ return xResult;
+}
+
+css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
+ShapeContextHandler::getDrawPage() throw (css::uno::RuntimeException)
+{
+ return mxDrawPage;
+}
+
+void SAL_CALL ShapeContextHandler::setDrawPage
+(const css::uno::Reference< css::drawing::XDrawPage > & the_value)
+ throw (css::uno::RuntimeException)
+{
+ mxDrawPage = the_value;
+}
+
+css::uno::Reference< css::frame::XModel > SAL_CALL
+ShapeContextHandler::getModel() throw (css::uno::RuntimeException)
+{
+ if( !mxFilterBase.is() )
+ throw uno::RuntimeException();
+ return mxFilterBase->getModel();
+}
+
+void SAL_CALL ShapeContextHandler::setModel
+(const css::uno::Reference< css::frame::XModel > & the_value)
+ throw (css::uno::RuntimeException)
+{
+ if( !mxFilterBase.is() )
+ throw uno::RuntimeException();
+ uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW);
+ mxFilterBase->setTargetDocument(xComp);
+}
+
+uno::Reference< io::XInputStream > SAL_CALL
+ShapeContextHandler::getInputStream() throw (uno::RuntimeException)
+{
+ return mxInputStream;
+}
+
+void SAL_CALL ShapeContextHandler::setInputStream
+(const uno::Reference< io::XInputStream > & the_value)
+ throw (uno::RuntimeException)
+{
+ mxInputStream = the_value;
+}
+
+::rtl::OUString SAL_CALL ShapeContextHandler::getRelationFragmentPath()
+ throw (uno::RuntimeException)
+{
+ return msRelationFragmentPath;
+}
+
+void SAL_CALL ShapeContextHandler::setRelationFragmentPath
+(const ::rtl::OUString & the_value)
+ throw (uno::RuntimeException)
+{
+ msRelationFragmentPath = the_value;
+}
+
+::sal_Int32 SAL_CALL ShapeContextHandler::getStartToken() throw (::com::sun::star::uno::RuntimeException)
+{
+ return mnStartToken;
+}
+
+void SAL_CALL ShapeContextHandler::setStartToken( ::sal_Int32 _starttoken ) throw (::com::sun::star::uno::RuntimeException)
+{
+ mnStartToken = _starttoken;
+
+
+}
+
+::rtl::OUString ShapeContextHandler::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return ShapeContextHandler_getImplementationName();
+}
+
+uno::Sequence< ::rtl::OUString > ShapeContextHandler::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return ShapeContextHandler_getSupportedServiceNames();
+}
+
+::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;
+}
+
+}}
diff --git a/oox/source/shape/ShapeContextHandler.hxx b/oox/source/shape/ShapeContextHandler.hxx
new file mode 100644
index 000000000000..b794c2f879c1
--- /dev/null
+++ b/oox/source/shape/ShapeContextHandler.hxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef OOX_SHAPE_SHAPE_CONTEXT_HANDLER_HXX
+#define OOX_SHAPE_SHAPE_CONTEXT_HANDLER_HXX
+
+#include <boost/shared_ptr.hpp>
+#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 "oox/core/fragmenthandler.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "ShapeFilterBase.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace oox { namespace shape {
+
+class ShapeFragmentHandler : public core::FragmentHandler
+{
+public:
+ typedef boost::shared_ptr<ShapeFragmentHandler> Pointer_t;
+
+ explicit ShapeFragmentHandler(core::XmlFilterBase& rFilter,
+ const ::rtl::OUString& rFragmentPath )
+ : FragmentHandler(rFilter, rFragmentPath)
+ {
+ }
+};
+
+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::XDrawPage > SAL_CALL getDrawPage()
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setDrawPage
+ (const css::uno::Reference< css::drawing::XDrawPage > & 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);
+
+ virtual css::uno::Reference< css::io::XInputStream > SAL_CALL
+ getInputStream() throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setInputStream
+ (const css::uno::Reference< css::io::XInputStream > & the_value)
+ throw (css::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getRelationFragmentPath()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setRelationFragmentPath
+ (const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+
+ virtual ::sal_Int32 SAL_CALL getStartToken() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setStartToken( ::sal_Int32 _starttoken ) throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ ShapeContextHandler(ShapeContextHandler &); // not defined
+ void operator =(ShapeContextHandler &); // not defined
+
+ ::sal_uInt32 mnStartToken;
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ drawingml::ShapePtr mpShape;
+ ::boost::shared_ptr< vml::Drawing > mpDrawing;
+
+ typedef boost::shared_ptr<drawingml::GraphicShapeContext>
+ GraphicShapeContextPtr;
+ css::uno::Reference<XFastContextHandler> mxDrawingFragmentHandler;
+ css::uno::Reference<XFastContextHandler> mxGraphicShapeContext;
+
+ core::XmlFilterRef mxFilterBase;
+ drawingml::ThemePtr mpThemePtr;
+ css::uno::Reference<css::drawing::XDrawPage> mxDrawPage;
+ css::uno::Reference<css::io::XInputStream> mxInputStream;
+ ::rtl::OUString msRelationFragmentPath;
+
+ css::uno::Reference<XFastContextHandler> getGraphicShapeContext(::sal_Int32 Element);
+ css::uno::Reference<XFastContextHandler> getDrawingShapeContext();
+ css::uno::Reference<XFastContextHandler> getContextHandler();
+};
+
+}}
+
+#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..68e0d0002392
--- /dev/null
+++ b/oox/source/shape/ShapeFilterBase.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "ShapeFilterBase.hxx"
+#include "oox/drawingml/chart/chartconverter.hxx"
+#include "oox/ole/vbaproject.hxx"
+
+namespace oox {
+namespace shape {
+
+using namespace ::com::sun::star;
+
+ShapeFilterBase::ShapeFilterBase( const uno::Reference< uno::XComponentContext >& rxContext ) throw( uno::RuntimeException ) :
+ XmlFilterBase( rxContext ),
+ mxChartConv( new ::oox::drawingml::chart::ChartConverter )
+{
+}
+
+ShapeFilterBase::~ShapeFilterBase()
+{
+}
+
+const ::oox::drawingml::Theme* ShapeFilterBase::getCurrentTheme() const
+{
+ return 0;
+}
+
+::oox::vml::Drawing* ShapeFilterBase::getVmlDrawing()
+{
+ return 0;
+}
+
+const ::oox::drawingml::table::TableStyleListPtr ShapeFilterBase::getTableStyles()
+{
+ return ::oox::drawingml::table::TableStyleListPtr();
+}
+
+::oox::drawingml::chart::ChartConverter& ShapeFilterBase::getChartConverter()
+{
+ return *mxChartConv;
+}
+
+::oox::ole::VbaProject* ShapeFilterBase::implCreateVbaProject() const
+{
+ return new ::oox::ole::VbaProject( getComponentContext(), getModel(), CREATE_OUSTRING( "Writer" ) );
+}
+
+::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..a21357c16079
--- /dev/null
+++ b/oox/source/shape/ShapeFilterBase.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_SHAPE_SHAPEFILTERBASE_HXX
+#define OOX_SHAPE_SHAPEFILTERBASE_HXX
+
+#include <boost/shared_ptr.hpp>
+#include <rtl/ref.hxx>
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/drawingml/table/tablestylelist.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+
+namespace oox {
+namespace shape {
+
+// ============================================================================
+
+class ShapeFilterBase : public core::XmlFilterBase
+{
+public:
+ typedef boost::shared_ptr<ShapeFilterBase> Pointer_t;
+
+ explicit ShapeFilterBase(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ~ShapeFilterBase();
+
+ /** Has to be implemented by each filter, returns the current theme. */
+ virtual const ::oox::drawingml::Theme* getCurrentTheme() const;
+
+ /** Has to be implemented by each filter to return the collection of VML shapes. */
+ virtual ::oox::vml::Drawing* getVmlDrawing();
+
+ /** Has to be implemented by each filter to return TableStyles. */
+ virtual const ::oox::drawingml::table::TableStyleListPtr getTableStyles();
+
+ virtual ::oox::drawingml::chart::ChartConverter& getChartConverter();
+
+ virtual bool importDocument() { return true; }
+ virtual bool exportDocument() { return true; }
+
+private:
+ virtual ::oox::ole::VbaProject* implCreateVbaProject() const;
+ virtual rtl::OUString implGetImplementationName() const;
+
+ ::boost::shared_ptr< ::oox::drawingml::chart::ChartConverter > mxChartConv;
+};
+
+// ============================================================================
+
+} // 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..c6534b3a8a6f
--- /dev/null
+++ b/oox/source/shape/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+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
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/oox/source/token/makefile.mk b/oox/source/token/makefile.mk
new file mode 100644
index 000000000000..ff42967f0bb1
--- /dev/null
+++ b/oox/source/token/makefile.mk
@@ -0,0 +1,78 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=token
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/namespacemap.obj \
+ $(SLO)$/propertynames.obj \
+ $(SLO)$/tokenmap.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+GENHEADERPATH = $(INCCOM)$/oox$/token
+
+$(MISC)$/tokenhash.gperf $(INCCOM)$/tokennames.inc $(GENHEADERPATH)$/tokens.hxx $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx :
+ @@noop $(assign do_phony:=.PHONY)
+
+$(SLO)$/tokenmap.obj : $(INCCOM)$/tokenhash.inc $(INCCOM)$/tokennames.inc $(GENHEADERPATH)$/tokens.hxx $(MISC)$/do_tokens
+
+$(INCCOM)$/tokenhash.inc : $(MISC)$/tokenhash.gperf $(MISC)$/do_tokens
+ $(AUGMENT_LIBRARY_PATH) gperf --compare-strncmp $(MISC)$/tokenhash.gperf | $(SED) -e "s/(char\*)0/(char\*)0, 0/g" | $(GREP) -v "^#line" >$(INCCOM)$/tokenhash.inc
+
+$(MISC)$/do_tokens $(do_phony) : tokens.txt tokens.pl tokens.hxx.head tokens.hxx.tail $(GENHEADERPATH)$/tokens.hxx $(INCCOM)$/tokennames.inc $(MISC)$/tokenhash.gperf
+ @@-$(RM) $@
+ $(MKDIRHIER) $(GENHEADERPATH)
+ $(PERL) tokens.pl tokens.txt $(MISC)$/tokenids.inc $(INCCOM)$/tokennames.inc $(MISC)$/tokenhash.gperf && $(TYPE) tokens.hxx.head $(MISC)$/tokenids.inc tokens.hxx.tail > $(GENHEADERPATH)$/tokens.hxx && $(TOUCH) $@
+
+$(SLO)$/namespacemap.obj : $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx $(MISC)$/do_namespaces
+
+$(MISC)$/do_namespaces $(do_phony) : namespaces.txt namespaces.pl namespaces.hxx.head namespaces.hxx.tail $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt $(GENHEADERPATH)$/namespaces.hxx
+ @@-$(RM) $@
+ $(MKDIRHIER) $(GENHEADERPATH)
+ $(PERL) namespaces.pl namespaces.txt $(MISC)$/namespaceids.inc $(INCCOM)$/namespacenames.inc $(MISC)$/namespaces.txt && $(TYPE) namespaces.hxx.head $(MISC)$/namespaceids.inc namespaces.hxx.tail > $(GENHEADERPATH)$/namespaces.hxx && $(TOUCH) $@
+
+$(SLO)$/propertynames.obj : $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx $(MISC)$/do_properties
+
+$(MISC)$/do_properties $(do_phony) : properties.txt properties.pl properties.hxx.head properties.hxx.tail $(INCCOM)$/propertynames.inc $(GENHEADERPATH)$/properties.hxx
+ @@-$(RM) $@
+ $(MKDIRHIER) $(GENHEADERPATH)
+ $(PERL) properties.pl properties.txt $(MISC)$/propertyids.inc $(INCCOM)$/propertynames.inc && $(TYPE) properties.hxx.head $(MISC)$/propertyids.inc properties.hxx.tail > $(GENHEADERPATH)$/properties.hxx && $(TOUCH) $@
diff --git a/oox/source/token/namespacemap.cxx b/oox/source/token/namespacemap.cxx
new file mode 100755
index 000000000000..0f4373d2dc59
--- /dev/null
+++ b/oox/source/token/namespacemap.cxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/token/namespacemap.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+NamespaceMap::NamespaceMap()
+{
+ static const struct NamespaceUrl { sal_Int32 mnId; const sal_Char* mpcUrl; } spNamespaceUrls[] =
+ {
+// include auto-generated C array with namespace URLs as C strings
+#include "namespacenames.inc"
+ { -1, "" }
+ };
+
+ for( const NamespaceUrl* pNamespaceUrl = spNamespaceUrls; pNamespaceUrl->mnId != -1; ++pNamespaceUrl )
+ operator[]( pNamespaceUrl->mnId ) = ::rtl::OUString::createFromAscii( pNamespaceUrl->mpcUrl );
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/token/namespaces.hxx.head b/oox/source/token/namespaces.hxx.head
new file mode 100755
index 000000000000..351bf2558303
--- /dev/null
+++ b/oox/source/token/namespaces.hxx.head
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_TOKEN_NAMESPACES_HXX
+#define OOX_TOKEN_NAMESPACES_HXX
+
+#include <sal/types.h>
+
+namespace oox {
+
+// ============================================================================
+
diff --git a/oox/source/token/namespaces.hxx.tail b/oox/source/token/namespaces.hxx.tail
new file mode 100755
index 000000000000..651fc38511d4
--- /dev/null
+++ b/oox/source/token/namespaces.hxx.tail
@@ -0,0 +1,35 @@
+
+// ============================================================================
+
+const sal_Int32 TOKEN_MASK = static_cast< sal_Int32 >( (1 << NMSP_SHIFT) - 1 );
+const sal_Int32 NMSP_MASK = static_cast< sal_Int32 >( SAL_MAX_INT16 & ~TOKEN_MASK );
+
+/** Returns the raw token identifier without namespace of the passed token. */
+inline sal_Int32 getBaseToken( sal_Int32 nToken ) { return nToken & TOKEN_MASK; }
+
+/** Returns the namespace without token identifier of the passed token. */
+inline sal_Int32 getNamespace( sal_Int32 nToken ) { return nToken & NMSP_MASK; }
+
+// defines for tokens with specific namespaces
+#define A_TOKEN( token ) (::oox::NMSP_dml | XML_##token)
+#define AX_TOKEN( token ) (::oox::NMSP_ax | XML_##token)
+#define C_TOKEN( token ) (::oox::NMSP_dmlChart | XML_##token)
+#define CDR_TOKEN( token ) (::oox::NMSP_dmlChartDr | XML_##token)
+#define DGM_TOKEN( token ) (::oox::NMSP_dmlDiagram | XML_##token)
+#define O_TOKEN( token ) (::oox::NMSP_vmlOffice | XML_##token)
+#define PC_TOKEN( token ) (::oox::NMSP_packageContentTypes | XML_##token)
+#define PPT_TOKEN( token ) (::oox::NMSP_ppt | XML_##token)
+#define PR_TOKEN( token ) (::oox::NMSP_packageRel | XML_##token)
+#define R_TOKEN( token ) (::oox::NMSP_officeRel | XML_##token)
+#define VML_TOKEN( token ) (::oox::NMSP_vml | XML_##token)
+#define VMLX_TOKEN( token ) (::oox::NMSP_vmlExcel | XML_##token)
+#define XDR_TOKEN( token ) (::oox::NMSP_dmlSpreadDr | XML_##token)
+#define XLS_TOKEN( token ) (::oox::NMSP_xls | XML_##token)
+#define XM_TOKEN( token ) (::oox::NMSP_xm | XML_##token)
+#define XML_TOKEN( token ) (::oox::NMSP_xml | XML_##token)
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/source/token/namespaces.pl b/oox/source/token/namespaces.pl
new file mode 100644
index 000000000000..3c741fa7b2af
--- /dev/null
+++ b/oox/source/token/namespaces.pl
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+$ARGV0 = shift @ARGV;
+$ARGV1 = shift @ARGV;
+$ARGV2 = shift @ARGV;
+$ARGV3 = shift @ARGV;
+
+# parse input file
+
+open( INFILE, $ARGV0 ) or die "cannot open input file: $!";
+my %namespaces;
+while( <INFILE> )
+{
+ # trim newline
+ chomp( $_ );
+ # trim leading/trailing whitespace
+ $_ =~ s/^\s*//g;
+ $_ =~ s/\s*$//g;
+ # trim comments
+ $_ =~ s/^#.*//;
+ # skip empty lines
+ if( $_ )
+ {
+ # check for valid characters
+ $_ =~ /^([a-zA-Z]+)\s+([a-zA-Z0-9-.:\/]+)\s*$/ or die "Error: invalid character in input data";
+ $namespaces{$1} = $2;
+ }
+}
+close( INFILE );
+
+# generate output files
+
+open( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!";
+open( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!";
+open( TXTFILE, ">$ARGV3" ) or die "Error: cannot open output file: $!";
+
+# number of bits to shift the namespace identifier
+$shift = 16;
+
+print ( IDFILE "const size_t NMSP_SHIFT = $shift;\n" );
+
+$i = 1;
+foreach( keys( %namespaces ) )
+{
+ print( IDFILE "const sal_Int32 NMSP_$_ = $i << NMSP_SHIFT;\n" );
+ $id = $i << $shift;
+ print( NAMEFILE "{ $id, \"$namespaces{$_}\" },\n" );
+ print( TXTFILE "$id $_ $namespaces{$_}\n" );
+ ++$i;
+}
+
+close( IDFILE );
+close( nameFILE );
+close( TXTFILE );
diff --git a/oox/source/token/namespaces.txt b/oox/source/token/namespaces.txt
new file mode 100644
index 000000000000..81b568067470
--- /dev/null
+++ b/oox/source/token/namespaces.txt
@@ -0,0 +1,52 @@
+
+# generic XML -----------------------------------------------------------------
+
+xml http://www.w3.org/XML/1998/namespace
+schema http://schemas.openxmlformats.org/schemaLibrary/2006/main
+
+# package ---------------------------------------------------------------------
+
+packageContentTypes http://schemas.openxmlformats.org/package/2006/content-types
+packageMetaCorePr http://schemas.openxmlformats.org/package/2006/metadata/core-properties
+packageRel http://schemas.openxmlformats.org/package/2006/relationships
+
+# office shared ---------------------------------------------------------------
+
+officeCustomPr http://schemas.openxmlformats.org/officeDocument/2006/custom-properties
+officeDocPropsVT http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes
+officeExtPr http://schemas.openxmlformats.org/officeDocument/2006/extended-properties
+officeMath http://schemas.openxmlformats.org/officeDocument/2006/math
+officeRel http://schemas.openxmlformats.org/officeDocument/2006/relationships
+officeRelTheme http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme
+
+# applications ----------------------------------------------------------------
+
+doc http://schemas.openxmlformats.org/wordprocessingml/2006/main
+xls http://schemas.openxmlformats.org/spreadsheetml/2006/main
+ppt http://schemas.openxmlformats.org/presentationml/2006/main
+
+# drawing ---------------------------------------------------------------------
+
+dml http://schemas.openxmlformats.org/drawingml/2006/main
+dmlChart http://schemas.openxmlformats.org/drawingml/2006/chart
+dmlChartDr http://schemas.openxmlformats.org/drawingml/2006/chartDrawing
+dmlDiagram http://schemas.openxmlformats.org/drawingml/2006/diagram
+dmlPicture http://schemas.openxmlformats.org/drawingml/2006/picture
+dmlSpreadDr http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing
+dmlWordDr http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing
+
+# VML -------------------------------------------------------------------------
+
+vml urn:schemas-microsoft-com:vml
+vmlExcel urn:schemas-microsoft-com:office:excel
+vmlOffice urn:schemas-microsoft-com:office:office
+vmlPowerpoint urn:schemas-microsoft-com:office:powerpoint
+vmlWord urn:schemas-microsoft-com:office:word
+
+# other -----------------------------------------------------------------------
+
+ax http://schemas.microsoft.com/office/2006/activeX
+dc http://purl.org/dc/elements/1.1/
+dcTerms http://purl.org/dc/terms/
+xm http://schemas.microsoft.com/office/excel/2006/main
+sprm http://sprm
diff --git a/oox/source/token/parsexsd.pl b/oox/source/token/parsexsd.pl
new file mode 100644
index 000000000000..8fed059bbc44
--- /dev/null
+++ b/oox/source/token/parsexsd.pl
@@ -0,0 +1,75 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+$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/properties.hxx.head b/oox/source/token/properties.hxx.head
new file mode 100755
index 000000000000..25817b5e72f3
--- /dev/null
+++ b/oox/source/token/properties.hxx.head
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_TOKEN_PROPERTIES_HXX
+#define OOX_TOKEN_PROPERTIES_HXX
+
+#include <sal/types.h>
+
+namespace oox {
+
+// ============================================================================
+
diff --git a/oox/source/token/properties.hxx.tail b/oox/source/token/properties.hxx.tail
new file mode 100755
index 000000000000..f647337e529c
--- /dev/null
+++ b/oox/source/token/properties.hxx.tail
@@ -0,0 +1,6 @@
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/source/token/properties.pl b/oox/source/token/properties.pl
new file mode 100644
index 000000000000..f341924bbb90
--- /dev/null
+++ b/oox/source/token/properties.pl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+$ARGV0 = shift @ARGV;
+$ARGV1 = shift @ARGV;
+$ARGV2 = shift @ARGV;
+
+# parse input file
+
+open( INFILE, $ARGV0 ) or die "Error: cannot open input file: $!";
+my %props;
+while( <INFILE> )
+{
+ # trim newline
+ chomp( $_ );
+ # trim leading/trailing whitespace
+ $_ =~ s/^\s*//g;
+ $_ =~ s/\s*$//g;
+ # check for valid characters
+ $_ =~ /^[A-Z][a-zA-Z0-9]*$/ or die "Error: invalid character in property '$_'";
+ $id = "PROP_$_";
+ $props{$_} = $id;
+}
+close( INFILE );
+
+# generate output files
+
+open( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!";
+open( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!";
+
+$i = 0;
+foreach( sort( keys( %props ) ) )
+{
+ print( IDFILE "const sal_Int32 $props{$_} = $i;\n" );
+ print( NAMEFILE "/* $i */ \"$_\",\n" );
+ ++$i;
+}
+
+print( IDFILE "const sal_Int32 PROP_COUNT = $i;\n" );
+print( IDFILE "const sal_Int32 PROP_INVALID = -1;\n" );
+
+close( IDFILE );
+close( NAMEFILE );
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
new file mode 100644
index 000000000000..b0726f86657e
--- /dev/null
+++ b/oox/source/token/properties.txt
@@ -0,0 +1,485 @@
+AbsoluteName
+Action
+ActiveSplitRange
+ActiveTable
+Address
+Adjust
+AdjustContrast
+AdjustLuminance
+AdjustmentValues
+Align
+AnchorPosition
+ApplyFormDesignMode
+AreaLinks
+ArrangeOrder
+Aspect
+AttachedAxisIndex
+AutoFilter
+AutoShowInfo
+Autocomplete
+BackGraphicLocation
+BackGraphicURL
+BackgroundColor
+BasicLibraries
+BlackDay
+BlockIncrement
+Border
+BorderColor
+BorderDashName
+BorderStyle
+BorderTransparency
+BorderWidth
+BottomBorder
+BottomMargin
+BulletChar
+BulletColor
+BulletFont
+BulletFontName
+BulletRelSize
+CLSID
+CalcAsShown
+CellBackColor
+CellProtection
+CellStyle
+CenterHorizontally
+CenterVertically
+CharCaseMap
+CharColor
+CharContoured
+CharEscapement
+CharEscapementHeight
+CharFontCharSet
+CharFontCharSetAsian
+CharFontCharSetComplex
+CharFontFamily
+CharFontFamilyAsian
+CharFontFamilyComplex
+CharFontName
+CharFontNameAsian
+CharFontNameComplex
+CharFontPitch
+CharFontPitchAsian
+CharFontPitchComplex
+CharHeight
+CharHeightAsian
+CharHeightComplex
+CharKerning
+CharLocale
+CharLocaleAsian
+CharLocaleComplex
+CharPosture
+CharPostureAsian
+CharPostureComplex
+CharShadowed
+CharStrikeout
+CharStyleName
+CharUnderline
+CharUnderlineColor
+CharUnderlineHasColor
+CharWeight
+CharWeightAsian
+CharWeightComplex
+CodeName
+Color
+ColumnGrand
+ColumnLabelRanges
+CompileEnglish
+ConditionalFormat
+ConnectBars
+ContainsHeader
+Coordinates
+CopyBack
+CopyFormulas
+CopyOutputData
+CopyStyles
+CrossoverPosition
+CrossoverValue
+CursorPositionX
+CursorPositionY
+CurveStyle
+CustomShapeGeometry
+D3DSceneAmbientColor
+D3DSceneLightColor2
+D3DSceneLightDirection2
+D3DSceneLightOn1
+D3DSceneLightOn2
+D3DScenePerspective
+D3DSceneShadeMode
+DDELinks
+DatabaseRanges
+Decoration
+DefaultScrollValue
+DefaultSpinValue
+DefaultState
+DefaultText
+DefaultValue
+DiagonalBLTR
+DiagonalTLBR
+DialogLibraries
+DisableComplexChartTypes
+DisableDataTableDialog
+DisplayLabels
+DrillDownOnDoubleClick
+Dropdown
+EchoChar
+EnableVisible
+Enabled
+EndPosition
+Equations
+ErrorAlertStyle
+ErrorBarStyle
+ErrorBarX
+ErrorBarY
+ErrorMessage
+ErrorTitle
+Expansion
+ExternalDocLinks
+ExternalLinks
+FileFormat
+FillBitmapMode
+FillBitmapName
+FillBitmapPositionOffsetX
+FillBitmapPositionOffsetY
+FillBitmapRectanglePoint
+FillBitmapSizeX
+FillBitmapSizeY
+FillBitmapURL
+FillColor
+FillGradient
+FillGradientName
+FillStyle
+FillTransparence
+Filter
+FilterCriteriaSource
+FilterOptions
+FirstLineOffset
+FirstPageNumber
+FocusOnClick
+FontCharset
+FontHeight
+FontIndependentLineSpacing
+FontName
+FontSlant
+FontStrikeout
+FontUnderline
+FontWeight
+FooterBodyDistance
+FooterHeight
+FooterIsDynamicHeight
+FooterIsOn
+FooterIsShared
+FormulaConvention
+Function
+GapwidthSequence
+Geometry3D
+GradientName
+Graphic
+GraphicColorMode
+GraphicCrop
+GraphicSize
+GraphicURL
+GridColor
+GroupInfo
+HScroll
+Handles
+HasAutoShowInfo
+HasColumnRowHeaders
+HasHorizontalScrollBar
+HasLayoutInfo
+HasMainTitle
+HasReference
+HasSecondaryXAxisTitle
+HasSecondaryYAxisTitle
+HasSheetTabs
+HasSortInfo
+HasVerticalScrollBar
+HasXAxisTitle
+HasYAxisTitle
+HasZAxisTitle
+HeaderBodyDistance
+HeaderHeight
+HeaderIsDynamicHeight
+HeaderIsOn
+HeaderIsShared
+Height
+HelpText
+HideInactiveSelection
+HoriJustify
+HorizontalSplitMode
+HorizontalSplitPositionTwips
+IgnoreBlankCells
+IgnoreCase
+IgnoreLeadingSpaces
+ImagePosition
+ImageURL
+IncludeHiddenCells
+InputMessage
+InputTitle
+IsActive
+IsAdjustHeightEnabled
+IsCaseSensitive
+IsCellBackgroundTransparent
+IsChangeReadOnlyEnabled
+IsDate
+IsExecuteLinkEnabled
+IsHidden
+IsIterationEnabled
+IsLandscape
+IsLoaded
+IsNumbering
+IsOutlineSymbolsSet
+IsPlaceholderDependent
+IsSharedFormula
+IsStartOfNewPage
+IsTextWrapped
+IsUndoEnabled
+IsVisible
+IterationCount
+IterationEpsilon
+Japanese
+Label
+LabelPlacement
+LabelPosition
+LabelSeparator
+LayoutInfo
+LeftBorder
+LeftMargin
+LeftPageFooterContent
+LeftPageHeaderContent
+LineColor
+LineCount
+LineDash
+LineDashName
+LineEndCenter
+LineEndName
+LineEndWidth
+LineIncrement
+LineJoint
+LineStartCenter
+LineStartName
+LineStartWidth
+LineStyle
+LineTransparence
+LineWidth
+LinkURL
+LoadReadonly
+LookUpLabels
+MajorTickmarks
+MarkPosition
+MaxFieldCount
+MaxTextLen
+MediaType
+MinorTickmarks
+MirroredX
+MirroredY
+MissingValueTreatment
+Model
+ModifyPasswordHash
+MultiLine
+MultiPageValue
+MultiSelection
+Name
+NamedRanges
+NegativeError
+NullDate
+NumberFormat
+NumberingIsNumber
+NumberingLevel
+NumberingRules
+NumberingType
+Offset
+OpCodeMap
+Orientation
+OutputPosition
+OverlapSequence
+PageScale
+PageStyle
+PageViewZoomValue
+PaintTransparent
+ParaAdjust
+ParaBottomMargin
+ParaFirstLineIndent
+ParaIndent
+ParaIsHangingPunctuation
+ParaIsHyphenation
+ParaLeftMargin
+ParaLineSpacing
+ParaRightMargin
+ParaTabStops
+ParaTopMargin
+Path
+PercentageNumberFormat
+PersistName
+Perspective
+PolyPolygon
+Position
+PositionBottom
+PositionLeft
+PositionRight
+PositionTop
+PositionX
+PositionY
+PositiveError
+Prefix
+PrintAnnotations
+PrintBorder
+PrintDownFirst
+PrintGrid
+PrintHeaders
+Printable
+ProgressValueMax
+ProgressValueMin
+Protected
+RadiusRangeMaximum
+RadiusRangeMinimum
+RangeXMaximum
+RangeXMinimum
+RangeYMaximum
+RangeYMinimum
+RefAngle
+RefR
+RefX
+RefY
+Reference
+ReferenceDevice
+ReferenceSheet
+RefreshPeriod
+RegularExpressions
+RelId
+RelativeHorizontalTabbarWidth
+RelativePosition
+RelativeSize
+Repeat
+RepeatDelay
+Representation
+RightAngledAxes
+RightBorder
+RightMargin
+RightPageFooterContent
+RightPageHeaderContent
+Role
+RotateAngle
+RotateReference
+RotationHorizontal
+RotationVertical
+RowGrand
+RowLabelRanges
+SaveOutputPosition
+ScaleMode
+ScaleToPages
+ScaleToPagesX
+ScaleToPagesY
+ScrollValue
+ScrollValueMax
+ScrollValueMin
+Segments
+SelectedPage
+Show
+ShowBorder
+ShowCharts
+ShowCorrelationCoefficient
+ShowDetail
+ShowDrawing
+ShowEmpty
+ShowEquation
+ShowErrorMessage
+ShowFilterButton
+ShowFirst
+ShowFormulas
+ShowGrid
+ShowHighLow
+ShowInputMessage
+ShowList
+ShowNegativeError
+ShowObjects
+ShowPageBreakPreview
+ShowPositiveError
+ShowZeroValues
+ShrinkToFit
+Size
+Size100thMM
+SizePixel
+SkipDuplicates
+SortInfo
+Sound
+SoundOn
+Speed
+Spin
+SpinIncrement
+SpinValue
+SpinValueMax
+SpinValueMin
+StackCharacters
+StackingDirection
+StartPosition
+StartWith
+StartingAngle
+State
+Subtotals
+Suffix
+SwapXAndYAxis
+Symbol
+SymbolColor
+TabColor
+TabIndex
+TableBorder
+TableLayout
+TableSelected
+Tables
+Tabstop
+Tag
+TargetFrame
+Text
+TextAutoGrowHeight
+TextBreak
+TextColor
+TextFitToSize
+TextHorizontalAdjust
+TextLeftDistance
+TextLowerDistance
+TextOverlap
+TextRightDistance
+TextRotation
+TextUpperDistance
+TextVerticalAdjust
+TextWordWrap
+TextWritingMode
+Title
+Toggle
+TokenIndex
+TopBorder
+TopMargin
+Transformation
+TransitionDirection
+TransitionFadeColor
+TransitionSubtype
+TransitionType
+Transparency
+TriState
+Type
+URL
+Url
+UseFilterCriteriaSource
+UseRegularExpressions
+UseRings
+UseSelectedPage
+VScroll
+Validation
+Value
+VaryColorsByPoint
+VertJustify
+VerticalAlign
+VerticalSplitMode
+VerticalSplitPositionTwips
+ViewBox
+Visible
+VisibleSize
+VisualArea
+VisualEffect
+Weight
+WhiteDay
+Width
+WritingMode
+XLA1Representation
+ZoomType
+ZoomValue
diff --git a/oox/source/token/propertynames.cxx b/oox/source/token/propertynames.cxx
new file mode 100644
index 000000000000..401d168fe696
--- /dev/null
+++ b/oox/source/token/propertynames.cxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/token/propertynames.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+PropertyNameVector::PropertyNameVector()
+{
+ static const sal_Char* sppcPropertyNames[] =
+ {
+ // include auto-generated C array with property names as C strings
+#include "propertynames.inc"
+ ""
+ };
+
+ size_t nArraySize = (sizeof( sppcPropertyNames ) / sizeof( *sppcPropertyNames )) - 1;
+ reserve( nArraySize );
+ for( size_t nIndex = 0; nIndex < nArraySize; ++nIndex )
+ push_back( ::rtl::OUString::createFromAscii( sppcPropertyNames[ nIndex ] ) );
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx
new file mode 100644
index 000000000000..a5189269c3c8
--- /dev/null
+++ b/oox/source/token/tokenmap.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/token/tokenmap.hxx"
+
+#include <string.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/string.hxx>
+#include "oox/token/tokens.hxx"
+
+namespace oox {
+
+// ============================================================================
+
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OString;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+// include auto-generated Perfect_Hash
+#include "tokenhash.inc"
+} // namespace
+
+// ============================================================================
+
+TokenMap::TokenMap() :
+ maTokenNames( static_cast< size_t >( XML_TOKEN_COUNT ) )
+{
+ static const sal_Char* sppcTokenNames[] =
+ {
+// include auto-generated C array with token names as C strings
+#include "tokennames.inc"
+ ""
+ };
+
+ const sal_Char* const* ppcTokenName = sppcTokenNames;
+ for( TokenNameVector::iterator aIt = maTokenNames.begin(), aEnd = maTokenNames.end(); aIt != aEnd; ++aIt, ++ppcTokenName )
+ {
+ OString aUtf8Token( *ppcTokenName );
+ aIt->maUniName = OStringToOUString( aUtf8Token, RTL_TEXTENCODING_UTF8 );
+ aIt->maUtf8Name = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUtf8Token.getStr() ), aUtf8Token.getLength() );
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ // check that the perfect_hash is in sync with the token name list
+ bool bOk = true;
+ for( sal_Int32 nToken = 0; bOk && (nToken < XML_TOKEN_COUNT); ++nToken )
+ {
+ // check that the getIdentifier <-> getToken roundtrip works
+ OString aUtf8Name = OUStringToOString( maTokenNames[ nToken ].maUniName, RTL_TEXTENCODING_UTF8 );
+ struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() );
+ bOk = pToken && (pToken->nToken == nToken);
+ OSL_ENSURE( bOk, ::rtl::OStringBuffer( "TokenMap::TokenMap - token list broken, #" ).
+ append( nToken ).append( ", '" ).append( aUtf8Name ).append( '\'' ).getStr() );
+ }
+#endif
+}
+
+TokenMap::~TokenMap()
+{
+}
+
+OUString TokenMap::getUnicodeTokenName( sal_Int32 nToken ) const
+{
+ if( (0 <= nToken) && (static_cast< size_t >( nToken ) < maTokenNames.size()) )
+ return maTokenNames[ static_cast< size_t >( nToken ) ].maUniName;
+ return OUString();
+}
+
+sal_Int32 TokenMap::getTokenFromUnicode( const OUString& rUnicodeName ) const
+{
+ OString aUtf8Name = OUStringToOString( rUnicodeName, RTL_TEXTENCODING_UTF8 );
+ struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() );
+ return pToken ? pToken->nToken : XML_TOKEN_INVALID;
+}
+
+Sequence< sal_Int8 > TokenMap::getUtf8TokenName( sal_Int32 nToken ) const
+{
+ if( (0 <= nToken) && (static_cast< size_t >( nToken ) < maTokenNames.size()) )
+ return maTokenNames[ static_cast< size_t >( nToken ) ].maUtf8Name;
+ return Sequence< sal_Int8 >();
+}
+
+sal_Int32 TokenMap::getTokenFromUtf8( const Sequence< sal_Int8 >& rUtf8Name ) const
+{
+ struct xmltoken* pToken = Perfect_Hash::in_word_set(
+ reinterpret_cast< const char* >( rUtf8Name.getConstArray() ), rUtf8Name.getLength() );
+ return pToken ? pToken->nToken : XML_TOKEN_INVALID;
+}
+
+// ============================================================================
+
+} // namespace oox
diff --git a/oox/source/token/tokens.hxx.head b/oox/source/token/tokens.hxx.head
new file mode 100755
index 000000000000..dd201caeb1d9
--- /dev/null
+++ b/oox/source/token/tokens.hxx.head
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_TOKEN_TOKENS_HXX
+#define OOX_TOKEN_TOKENS_HXX
+
+#include <com/sun/star/xml/sax/FastToken.hpp>
+
+namespace oox {
+
+// ============================================================================
+
diff --git a/oox/source/token/tokens.hxx.tail b/oox/source/token/tokens.hxx.tail
new file mode 100755
index 000000000000..df4b5ef1a955
--- /dev/null
+++ b/oox/source/token/tokens.hxx.tail
@@ -0,0 +1,8 @@
+
+const sal_Int32 XML_TOKEN_INVALID = ::com::sun::star::xml::sax::FastToken::DONTKNOW;
+
+// ============================================================================
+
+} // namespace oox
+
+#endif
diff --git a/oox/source/token/tokens.pl b/oox/source/token/tokens.pl
new file mode 100644
index 000000000000..a951cee80db2
--- /dev/null
+++ b/oox/source/token/tokens.pl
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+$ARGV0 = shift @ARGV;
+$ARGV1 = shift @ARGV;
+$ARGV2 = shift @ARGV;
+$ARGV3 = shift @ARGV;
+
+open( INFILE, $ARGV0 ) or die "Error: cannot open input file: $!";
+my %tokens;
+while ( <INFILE> )
+{
+ # trim newline
+ chomp( $_ );
+ # trim leading/trailing whitespace
+ $_ =~ s/^\s*//g;
+ $_ =~ s/\s*$//g;
+ # check for valid characters
+ $_ =~ /^[a-zA-Z0-9-_]+$/ or die "Error: invalid character in token '$_'";
+ $id = "XML_$_";
+ $id =~ s/-/_/g;
+ $tokens{$_} = $id;
+}
+close ( INFILE );
+
+# generate output files
+
+open ( IDFILE, ">$ARGV1" ) or die "Error: cannot open output file: $!";
+open ( NAMEFILE, ">$ARGV2" ) or die "Error: cannot open output file: $!";
+open ( GPERFFILE, ">$ARGV3" ) or die "Error: cannot open output file: $!";
+
+print( GPERFFILE "%language=C++\n" );
+print( GPERFFILE "%global-table\n" );
+print( GPERFFILE "%null-strings\n" );
+print( GPERFFILE "%struct-type\n" );
+print( GPERFFILE "struct xmltoken {\n" );
+print( GPERFFILE " const sal_Char *name;\n" );
+print( GPERFFILE " sal_Int32 nToken;\n" );
+print( GPERFFILE "};\n" );
+print( GPERFFILE "%%\n" );
+
+$i = 0;
+foreach( sort( keys( %tokens ) ) )
+{
+ print( IDFILE "const sal_Int32 $tokens{$_} = $i;\n" );
+ print( NAMEFILE "\"$_\",\n" );
+ print( GPERFFILE "$_,$tokens{$_}\n" );
+ ++$i;
+}
+
+print( IDFILE "const sal_Int32 XML_TOKEN_COUNT = $i;\n" );
+print( GPERFFILE "%%\n" );
+
+close( IDFILE );
+close( NAMEFILE );
+close( GPERFFILE );
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
new file mode 100644
index 000000000000..13c1a10ff9b4
--- /dev/null
+++ b/oox/source/token/tokens.txt
@@ -0,0 +1,5680 @@
+1D
+1pic
+1picTitle
+2D
+2pic
+2picTitle
+35mm
+3Arrows
+3ArrowsGray
+3Flags
+3Signs
+3Symbols
+3Symbols2
+3TrafficLights1
+3TrafficLights2
+3cd4
+3cd8
+5cd8
+7cd8
+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
+BackColor
+Bitmap
+Book
+BookAuthor
+BookSection
+BookTitle
+BorderColor
+BorderStyle
+Bottom
+BroadcastTitle
+Broadcaster
+Button
+CF
+Camera
+Cancel
+Caption
+Case
+CaseNumber
+Center
+ChapterNumber
+Characters
+CharactersWithSpaces
+Checkbox
+Checked
+City
+ClientData
+ColHidden
+Colored
+Column
+Combo
+ComboEdit
+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
+Delay
+Department
+Dialog
+DigSig
+Director
+Disabled
+Dismiss
+DisplayStyle
+Distributed
+Distributor
+DocSecurity
+DocumentFromInternetSite
+DrawAspect
+Drop
+DropButtonStyle
+DropLines
+DropStyle
+Dx
+EMD
+ENTITIES
+ENTITY
+Edit
+Edition
+Editor
+ElectronicSource
+Embed
+EnhancedMetaFile
+Extend
+Extension
+External
+False
+FieldCodes
+FileBinding
+FileBindingName
+Film
+First
+FirstButton
+FmlaGroup
+FmlaLink
+FmlaMacro
+FmlaPict
+FmlaRange
+FmlaTxbx
+FontCharSet
+FontEffects
+FontHeight
+FontName
+FontPitchAndFamily
+FontWeight
+ForeColor
+Format
+Formula
+GBox
+Group
+GroupName
+Guid
+HLinks
+HTMLInset
+HTMLOutset
+HeadingPairs
+Help
+HiddenSlides
+Hiragana
+Horiz
+HyperlinkBase
+HyperlinksChanged
+ID
+IDREF
+IDREFS
+Icon
+Id
+Inc
+Institution
+Internal
+InternetSite
+InternetSiteTitle
+Interview
+Interviewee
+Interviewer
+Inventor
+Issue
+JournalArticle
+JournalName
+JustLastX
+Justify
+LCID
+LCT
+Label
+LargeChange
+Last
+Left
+LineA
+Lines
+Link
+LinkType
+LinksUpToDate
+List
+ListItem
+ListRows
+ListStyle
+LockText
+Locked
+LockedField
+M1
+M10
+M11
+M12
+M2
+M3
+M4
+M5
+M6
+M7
+M8
+M9
+MDY
+MMClips
+MYD
+Manager
+Map
+MapInfo
+MapOCX
+MatchEntry
+Max
+MaxLength
+Medium
+Middle
+Min
+Misc
+Month
+MonthAccessed
+MouseIcon
+MousePointer
+MoveWithCells
+Movie
+Multi
+MultiLine
+MultiSel
+MultiSelect
+NA
+NCName
+NMTOKEN
+NMTOKENS
+NOTATION
+Name
+NameList
+Namespace
+NextEnabled
+NoThreeD
+NoThreeD2
+Note
+Notes
+NumberVolumes
+OLEObject
+OLEUPDATE_ALWAYS
+OLEUPDATE_ONCALL
+ObjectID
+ObjectType
+OnCall
+Orientation
+Override
+Page
+Pages
+ParagraphAlign
+Paragraphs
+PartName
+PasswordChar
+Patent
+PatentNumber
+Performance
+Performer
+PeriodicalTitle
+Person
+Pict
+PictOld
+PictPrint
+PictScreen
+Picture
+PictureAlignment
+PicturePosition
+PictureTiling
+Position
+PresentationFormat
+PreserveFormat
+PreserveSortAFLayout
+PrevEnabled
+PrintObject
+ProducerName
+ProductionCompany
+ProgID
+Properties
+ProportionalThumb
+PublicationTitle
+Publisher
+Q1
+Q2
+Q3
+Q4
+QName
+R1C1
+Radio
+RecalcAlways
+RecordingNumber
+Rect
+RectA
+RefOrder
+Relationship
+RelationshipReference
+Relationships
+RelationshipsGroupReference
+Report
+Reporter
+Right
+RootElement
+Row
+RowHidden
+ScaleCrop
+Schema
+SchemaID
+SchemaRef
+ScriptExtended
+ScriptLanguage
+ScriptLocation
+ScriptText
+Scroll
+ScrollBars
+SecretEdit
+Sel
+SelType
+SelectedStyle
+SelectionNamespaces
+Shape
+ShapeID
+SharedDoc
+ShortTitle
+ShowDropButtonWhen
+ShowImportExportValidationErrors
+SignatureTime
+Simple
+Single
+Size
+SizeMode
+SizeWithCells
+Slides
+SmallChange
+SoundRecording
+Source
+SourceId
+SourceType
+Sources
+SpecialEffect
+Spin
+StandardNumber
+StateProvince
+Station
+StyleName
+Tag
+TakeFocusOnClick
+Target
+TargetMode
+Template
+TextHAlign
+TextVAlign
+Theater
+ThesisType
+Title
+TitlesOfParts
+Top
+TotalTime
+Translator
+True
+Type
+Types
+UIObj
+URI
+URL
+UpdateMode
+VScroll
+VTEdit
+Val
+ValidIds
+Value
+VariousPropertyBits
+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
+cd2
+cd4
+cd8
+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
+classid
+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
+dc
+dcmitype
+dcterms
+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
+dashdot
+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
+element
+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
+face
+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
+font4
+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
+hc
+hd2
+hd4
+hd5
+hd6
+hd8
+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
+license
+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
+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
+longdash
+longdashdot
+longdashdotdot
+loop
+low
+lowKashida
+lowerLetter
+lowerRoman
+lowestEdited
+lpstr
+lpwstr
+lrTb
+lrTbV
+ls
+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
+macrosheet
+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
+ocx
+ocxPr
+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
+persistPropertyBag
+persistStorage
+persistStream
+persistStreamInit
+persistence
+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
+shortdash
+shortdashdot
+shortdashdotdot
+shortdot
+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
+ss
+ssd2
+ssd4
+ssd6
+ssd8
+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
+vc
+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
+vt
+w
+w10
+wAfter
+wArH
+wBefore
+wMode
+wOff
+wR
+warmMatte
+warning
+watermarks
+wavAudioFile
+wave
+waveline
+wavy
+wavyDbl
+wavyDouble
+wavyHeavy
+wd
+wd10
+wd2
+wd4
+wd5
+wd6
+wd8
+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
+wp
+wpJustification
+wpSpaceWidth
+wrap
+wrapIndent
+wrapNone
+wrapPolygon
+wrapRight
+wrapSquare
+wrapText
+wrapThrough
+wrapTight
+wrapTopAndBottom
+wrapTrailSpaces
+wrapcoords
+writeProtection
+wsDr
+x
+xAlign
+xIllusions
+xMode
+xSplit
+xVal
+xWindow
+xdr
+xf
+xfDxf
+xfId
+xfrm
+xfrmType
+xl2000
+xl97
+xlm
+xml
+xmlBased
+xmlCellPr
+xmlColumnPr
+xmlDataType
+xmlPr
+xmlns
+xpath
+xrange
+xscale
+xsi
+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
diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk
new file mode 100644
index 000000000000..094d37cd8c1c
--- /dev/null
+++ b/oox/source/vml/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=oox
+TARGET=vml
+AUTOSEG=true
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/vmldrawing.obj \
+ $(SLO)$/vmldrawingfragment.obj \
+ $(SLO)$/vmlformatting.obj \
+ $(SLO)$/vmlinputstream.obj \
+ $(SLO)$/vmlshape.obj \
+ $(SLO)$/vmlshapecontainer.obj \
+ $(SLO)$/vmlshapecontext.obj \
+ $(SLO)$/vmltextbox.obj \
+ $(SLO)$/vmltextboxcontext.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..ccf0fe567235
--- /dev/null
+++ b/oox/source/vml/vmldrawing.cxx
@@ -0,0 +1,281 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmldrawing.hxx"
+
+#include <algorithm>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/ole/axcontrol.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::XmlFilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+/** Returns the textual representation of a numeric VML shape identifier. */
+OUString lclGetShapeId( sal_Int32 nShapeId )
+{
+ // identifier consists of a literal NUL character, a lowercase 's', and the id
+ return CREATE_OUSTRING( "\0s" ) + OUString::valueOf( nShapeId );
+}
+
+/** Returns the numeric VML shape identifier from its textual representation. */
+sal_Int32 lclGetShapeId( const OUString& rShapeId )
+{
+ // identifier consists of a literal NUL character, a lowercase 's', and the id
+ return ((rShapeId.getLength() >= 3) && (rShapeId[ 0 ] == '\0') && (rShapeId[ 1 ] == 's')) ? rShapeId.copy( 2 ).toInt32() : -1;
+}
+
+} // namespace
+
+// ============================================================================
+
+OleObjectInfo::OleObjectInfo( bool bDmlShape ) :
+ mbAutoLoad( false ),
+ mbDmlShape( bDmlShape )
+{
+}
+
+void OleObjectInfo::setShapeId( sal_Int32 nShapeId )
+{
+ maShapeId = lclGetShapeId( nShapeId );
+}
+
+// ============================================================================
+
+ControlInfo::ControlInfo()
+{
+}
+
+void ControlInfo::setShapeId( sal_Int32 nShapeId )
+{
+ maShapeId = lclGetShapeId( nShapeId );
+}
+
+// ============================================================================
+
+Drawing::Drawing( XmlFilterBase& rFilter, const Reference< XDrawPage >& rxDrawPage, DrawingType eType ) :
+ mrFilter( rFilter ),
+ mxDrawPage( rxDrawPage ),
+ mxShapes( new ShapeContainer( *this ) ),
+ meType( eType )
+{
+ OSL_ENSURE( mxDrawPage.is(), "Drawing::Drawing - missing UNO draw page" );
+}
+
+Drawing::~Drawing()
+{
+}
+
+::oox::ole::EmbeddedForm& Drawing::getControlForm() const
+{
+ if( !mxCtrlForm.get() )
+ mxCtrlForm.reset( new ::oox::ole::EmbeddedForm(
+ mrFilter.getModel(), mxDrawPage, mrFilter.getGraphicHelper() ) );
+ return *mxCtrlForm;
+}
+
+void Drawing::registerBlockId( sal_Int32 nBlockId )
+{
+ OSL_ENSURE( nBlockId > 0, "Drawing::registerBlockId - invalid block index" );
+ if( nBlockId > 0 )
+ {
+ // lower_bound() returns iterator pointing to element equal to nBlockId, if existing
+ BlockIdVector::iterator aIt = ::std::lower_bound( maBlockIds.begin(), maBlockIds.end(), nBlockId );
+ if( (aIt == maBlockIds.end()) || (nBlockId != *aIt) )
+ maBlockIds.insert( aIt, nBlockId );
+ }
+}
+
+void Drawing::registerOleObject( const OleObjectInfo& rOleObject )
+{
+ OSL_ENSURE( rOleObject.maShapeId.getLength() > 0, "Drawing::registerOleObject - missing OLE object shape id" );
+ OSL_ENSURE( maOleObjects.count( rOleObject.maShapeId ) == 0, "Drawing::registerOleObject - OLE object already registered" );
+ maOleObjects.insert( OleObjectInfoMap::value_type( rOleObject.maShapeId, rOleObject ) );
+}
+
+void Drawing::registerControl( const ControlInfo& rControl )
+{
+ OSL_ENSURE( rControl.maShapeId.getLength() > 0, "Drawing::registerControl - missing form control shape id" );
+ OSL_ENSURE( rControl.maName.getLength() > 0, "Drawing::registerControl - missing form control name" );
+ OSL_ENSURE( maControls.count( rControl.maShapeId ) == 0, "Drawing::registerControl - form control already registered" );
+ maControls.insert( ControlInfoMap::value_type( rControl.maShapeId, rControl ) );
+}
+
+void Drawing::finalizeFragmentImport()
+{
+ mxShapes->finalizeFragmentImport();
+}
+
+void Drawing::convertAndInsert() const
+{
+ Reference< XShapes > xShapes( mxDrawPage, UNO_QUERY );
+ mxShapes->convertAndInsert( xShapes );
+}
+
+sal_Int32 Drawing::getLocalShapeIndex( const OUString& rShapeId ) const
+{
+ sal_Int32 nShapeId = lclGetShapeId( rShapeId );
+ if( nShapeId <= 0 ) return -1;
+
+ /* Shapes in a drawing are counted per registered shape identifier blocks
+ as stored in the o:idmap element. The contents of this element have
+ been stored in our member maBlockIds. Each block represents 1024 shape
+ identifiers, starting with identifier 1 for the block #0. This means,
+ block #0 represents the identifiers 1-1024, block #1 represents the
+ identifiers 1025-2048, and so on. The local shape index has to be
+ calculated according to all blocks registered for this drawing.
+
+ Example:
+ Registered for this drawing are blocks #1 and #3 (shape identifiers
+ 1025-2048 and 3073-4096).
+ Shape identifier 1025 -> local shape index 1.
+ Shape identifier 1026 -> local shape index 2.
+ ...
+ Shape identifier 2048 -> local shape index 1024.
+ Shape identifier 3073 -> local shape index 1025.
+ ...
+ Shape identifier 4096 -> local shape index 2048.
+ */
+
+ // get block id from shape id and find its index in the list of used blocks
+ sal_Int32 nBlockId = (nShapeId - 1) / 1024;
+ BlockIdVector::iterator aIt = ::std::lower_bound( maBlockIds.begin(), maBlockIds.end(), nBlockId );
+ sal_Int32 nIndex = static_cast< sal_Int32 >( aIt - maBlockIds.begin() );
+
+ // block id not found in set -> register it now (value of nIndex remains valid)
+ if( (aIt == maBlockIds.end()) || (*aIt != nBlockId) )
+ maBlockIds.insert( aIt, nBlockId );
+
+ // get one-based offset of shape id in its block
+ sal_Int32 nBlockOffset = (nShapeId - 1) % 1024 + 1;
+
+ // calculate the local shape index
+ return 1024 * nIndex + nBlockOffset;
+}
+
+const OleObjectInfo* Drawing::getOleObjectInfo( const OUString& rShapeId ) const
+{
+ return ContainerHelper::getMapElement( maOleObjects, rShapeId );
+}
+
+const ControlInfo* Drawing::getControlInfo( const OUString& rShapeId ) const
+{
+ return ContainerHelper::getMapElement( maControls, rShapeId );
+}
+
+Reference< XShape > Drawing::createAndInsertXShape( const OUString& rService,
+ const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ OSL_ENSURE( rService.getLength() > 0, "Drawing::createAndInsertXShape - missing UNO shape service name" );
+ OSL_ENSURE( rxShapes.is(), "Drawing::createAndInsertXShape - missing XShapes container" );
+ Reference< XShape > xShape;
+ if( (rService.getLength() > 0) && rxShapes.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory( mrFilter.getModelFactory(), UNO_SET_THROW );
+ xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW );
+ // insert shape into passed shape collection (maybe drawpage or group shape)
+ rxShapes->add( xShape );
+ xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) );
+ xShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xShape.is(), "Drawing::createAndInsertXShape - cannot instanciate shape object" );
+ return xShape;
+}
+
+Reference< XShape > Drawing::createAndInsertXControlShape( const ::oox::ole::EmbeddedControl& rControl,
+ const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect, sal_Int32& rnCtrlIndex ) const
+{
+ Reference< XShape > xShape;
+ try
+ {
+ // create control model and insert it into the form of the draw page
+ Reference< XControlModel > xCtrlModel( getControlForm().convertAndInsert( rControl, rnCtrlIndex ), UNO_SET_THROW );
+
+ // create the control shape
+ xShape = createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ), rxShapes, rShapeRect );
+
+ // set the control model at the shape
+ Reference< XControlShape >( xShape, UNO_QUERY_THROW )->setControl( xCtrlModel );
+ }
+ catch( Exception& )
+ {
+ }
+ return xShape;
+}
+
+bool Drawing::isShapeSupported( const ShapeBase& /*rShape*/ ) const
+{
+ return true;
+}
+
+OUString Drawing::getShapeBaseName( const ShapeBase& /*rShape*/ ) const
+{
+ return OUString();
+}
+
+bool Drawing::convertClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const
+{
+ return false;
+}
+
+Reference< XShape > Drawing::createAndInsertClientXShape( const ShapeBase& /*rShape*/,
+ const Reference< XShapes >& /*rxShapes*/, const Rectangle& /*rShapeRect*/ ) const
+{
+ return Reference< XShape >();
+}
+
+void Drawing::notifyXShapeInserted( const Reference< XShape >& /*rxShape*/,
+ const Rectangle& /*rShapeRect*/, const ShapeBase& /*rShape*/, bool /*bGroupChild*/ )
+{
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespave oox
diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx
new file mode 100644
index 000000000000..dc5c82515691
--- /dev/null
+++ b/oox/source/vml/vmldrawingfragment.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmldrawingfragment.hxx"
+
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlinputstream.hxx"
+#include "oox/vml/vmlshapecontext.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragmentPath, Drawing& rDrawing ) :
+ FragmentHandler2( rFilter, rFragmentPath, false ), // do not trim whitespace, has been preprocessed by the input stream
+ mrDrawing( rDrawing )
+{
+}
+
+Reference< XInputStream > DrawingFragment::openFragmentStream() const
+{
+ // #i104719# create an input stream that preprocesses the VML data
+ return new InputStream( FragmentHandler2::openFragmentStream() );
+}
+
+ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( mrDrawing.getType() )
+ {
+ // DOCX filter handles plain shape elements with this fragment handler
+ case VMLDRAWING_WORD:
+ if( isRootElement() )
+ return ShapeContextBase::createShapeContext( *this, mrDrawing.getShapes(), nElement, rAttribs );
+ break;
+
+ // XLSX and PPTX filters load the entire VML fragment
+ case VMLDRAWING_EXCEL:
+ case VMLDRAWING_POWERPOINT:
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XML_xml ) return this;
+ break;
+ case XML_xml:
+ return ShapeContextBase::createShapeContext( *this, mrDrawing.getShapes(), nElement, rAttribs );
+ }
+ break;
+ }
+ return 0;
+}
+
+void DrawingFragment::finalizeImport()
+{
+ // resolve shape template references for all shapes
+ mrDrawing.finalizeFragmentImport();
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx
new file mode 100644
index 000000000000..cd280d041eb9
--- /dev/null
+++ b/oox/source/vml/vmlformatting.cxx
@@ -0,0 +1,587 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlformatting.hxx"
+
+#include <rtl/strbuf.hxx>
+#include "oox/drawingml/color.hxx"
+#include "oox/drawingml/drawingmltypes.hxx"
+#include "oox/drawingml/fillproperties.hxx"
+#include "oox/drawingml/lineproperties.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/propertymap.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using namespace ::com::sun::star::geometry;
+
+using ::oox::drawingml::Color;
+using ::oox::drawingml::FillProperties;
+using ::oox::drawingml::LineArrowProperties;
+using ::oox::drawingml::LineProperties;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& rValue )
+{
+ // extract the double value and find start position of unit characters
+ rtl_math_ConversionStatus eConvStatus = rtl_math_ConversionStatus_Ok;
+ orfValue = ::rtl::math::stringToDouble( rValue, '.', '\0', &eConvStatus, &ornEndPos );
+ return eConvStatus == rtl_math_ConversionStatus_Ok;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+/*static*/ bool ConversionHelper::separatePair( OUString& orValue1, OUString& orValue2,
+ const OUString& rValue, sal_Unicode cSep )
+{
+ sal_Int32 nSepPos = rValue.indexOf( cSep );
+ if( nSepPos >= 0 )
+ {
+ orValue1 = rValue.copy( 0, nSepPos ).trim();
+ orValue2 = rValue.copy( nSepPos + 1 ).trim();
+ }
+ else
+ {
+ orValue1 = rValue.trim();
+ }
+ return (orValue1.getLength() > 0) && (orValue2.getLength() > 0);
+}
+
+/*static*/ bool ConversionHelper::decodeBool( const OUString& rValue )
+{
+ sal_Int32 nToken = AttributeConversion::decodeToken( rValue );
+ // anything else than 't' or 'true' is considered to be false, as specified
+ return (nToken == XML_t) || (nToken == XML_true);
+}
+
+/*static*/ double ConversionHelper::decodePercent( const OUString& rValue, double fDefValue )
+{
+ if( rValue.getLength() == 0 )
+ return fDefValue;
+
+ double fValue = 0.0;
+ sal_Int32 nEndPos = 0;
+ if( !lclExtractDouble( fValue, nEndPos, rValue ) )
+ return fDefValue;
+
+ if( nEndPos == rValue.getLength() )
+ return fValue;
+
+ if( (nEndPos + 1 == rValue.getLength()) && (rValue[ nEndPos ] == '%') )
+ return fValue / 100.0;
+
+ OSL_ENSURE( false, "ConversionHelper::decodePercent - unknown measure unit" );
+ return fDefValue;
+}
+
+/*static*/ sal_Int32 ConversionHelper::decodeMeasureToEmu( const GraphicHelper& rGraphicHelper,
+ const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel )
+{
+ // default for missing values is 0
+ if( rValue.getLength() == 0 )
+ return 0;
+
+ // TODO: according to spec, value may contain "auto"
+ if( rValue.equalsAscii( "auto" ) )
+ {
+ OSL_ENSURE( false, "ConversionHelper::decodeMeasureToEmu - special value 'auto' must be handled by caller" );
+ return nRefValue;
+ }
+
+ // extract the double value and find start position of unit characters
+ double fValue = 0.0;
+ sal_Int32 nEndPos = 0;
+ if( !lclExtractDouble( fValue, nEndPos, rValue ) || (fValue == 0.0) )
+ return 0;
+
+ // process trailing unit, convert to EMU
+ static const OUString saPx = CREATE_OUSTRING( "px" );
+ OUString aUnit;
+ if( (0 < nEndPos) && (nEndPos < rValue.getLength()) )
+ aUnit = rValue.copy( nEndPos );
+ else if( bDefaultAsPixel )
+ aUnit = saPx;
+ // else default is EMU
+
+ if( aUnit.getLength() == 2 )
+ {
+ sal_Unicode cChar1 = aUnit[ 0 ];
+ sal_Unicode cChar2 = aUnit[ 1 ];
+ if( (cChar1 == 'i') && (cChar2 == 'n') ) // 1 inch = 914,400 EMU
+ fValue *= 914400.0;
+ else if( (cChar1 == 'c') && (cChar2 == 'm') ) // 1 cm = 360,000 EMU
+ fValue *= 360000.0;
+ else if( (cChar1 == 'm') && (cChar2 == 'm') ) // 1 mm = 36,000 EMU
+ fValue *= 36000.0;
+ else if( (cChar1 == 'p') && (cChar2 == 't') ) // 1 point = 1/72 inch = 12,700 MEU
+ fValue *= 12700.0;
+ else if( (cChar1 == 'p') && (cChar2 == 'c') ) // 1 pica = 1/6 inch = 152,400 EMU
+ fValue *= 152400.0;
+ else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device, factor 360 to convert 1/100mm to EMU
+ fValue = bPixelX ?
+ rGraphicHelper.convertScreenPixelXToHmm( 360.0 * fValue ) :
+ rGraphicHelper.convertScreenPixelYToHmm( 360.0 * fValue );
+ }
+ else if( (aUnit.getLength() == 1) && (aUnit[ 0 ] == '%') )
+ {
+ fValue *= nRefValue / 100.0;
+ }
+ else if( bDefaultAsPixel || (aUnit.getLength() > 0) ) // default as EMU and no unit -> do nothing
+ {
+ OSL_ENSURE( false, "ConversionHelper::decodeMeasureToEmu - unknown measure unit" );
+ fValue = nRefValue;
+ }
+ return static_cast< sal_Int32 >( fValue + 0.5 );
+}
+
+/*static*/ sal_Int32 ConversionHelper::decodeMeasureToHmm( const GraphicHelper& rGraphicHelper,
+ const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel )
+{
+ return (decodeMeasureToEmu( rGraphicHelper, rValue, nRefValue, bPixelX, bDefaultAsPixel ) + 180) / 360;
+}
+
+/*static*/ Color ConversionHelper::decodeColor( const GraphicHelper& rGraphicHelper,
+ const OptValue< OUString >& roVmlColor, const OptValue< double >& roVmlOpacity,
+ sal_Int32 nDefaultRgb, sal_Int32 nPrimaryRgb )
+{
+ Color aDmlColor;
+
+ // convert opacity
+ const sal_Int32 DML_FULL_OPAQUE = ::oox::drawingml::MAX_PERCENT;
+ double fOpacity = roVmlOpacity.get( 1.0 );
+ sal_Int32 nOpacity = getLimitedValue< sal_Int32, double >( fOpacity * DML_FULL_OPAQUE, 0, DML_FULL_OPAQUE );
+ if( nOpacity < DML_FULL_OPAQUE )
+ aDmlColor.addTransformation( XML_alpha, nOpacity );
+
+ // color attribute not present - set passed default color
+ if( !roVmlColor.has() )
+ {
+ aDmlColor.setSrgbClr( nDefaultRgb );
+ return aDmlColor;
+ }
+
+ // separate leading color name or RGB value from following palette index
+ OUString aColorName, aColorIndex;
+ separatePair( aColorName, aColorIndex, roVmlColor.get(), ' ' );
+
+ // RGB colors in the format '#RRGGBB'
+ if( (aColorName.getLength() == 7) && (aColorName[ 0 ] == '#') )
+ {
+ aDmlColor.setSrgbClr( aColorName.copy( 1 ).toInt32( 16 ) );
+ return aDmlColor;
+ }
+
+ // RGB colors in the format '#RGB'
+ if( (aColorName.getLength() == 4) && (aColorName[ 0 ] == '#') )
+ {
+ sal_Int32 nR = aColorName.copy( 1, 1 ).toInt32( 16 ) * 0x11;
+ sal_Int32 nG = aColorName.copy( 2, 1 ).toInt32( 16 ) * 0x11;
+ sal_Int32 nB = aColorName.copy( 3, 1 ).toInt32( 16 ) * 0x11;
+ aDmlColor.setSrgbClr( (nR << 16) | (nG << 8) | nB );
+ return aDmlColor;
+ }
+
+ /* Predefined color names or system color names (resolve to RGB to detect
+ valid color name). */
+ sal_Int32 nColorToken = AttributeConversion::decodeToken( aColorName );
+ sal_Int32 nRgbValue = Color::getVmlPresetColor( nColorToken, API_RGB_TRANSPARENT );
+ if( nRgbValue == API_RGB_TRANSPARENT )
+ nRgbValue = rGraphicHelper.getSystemColor( nColorToken, API_RGB_TRANSPARENT );
+ if( nRgbValue != API_RGB_TRANSPARENT )
+ {
+ aDmlColor.setSrgbClr( nRgbValue );
+ return aDmlColor;
+ }
+
+ // try palette colors enclosed in brackets
+ if( (aColorIndex.getLength() >= 3) && (aColorIndex[ 0 ] == '[') && (aColorIndex[ aColorIndex.getLength() - 1 ] == ']') )
+ {
+ aDmlColor.setPaletteClr( aColorIndex.copy( 1, aColorIndex.getLength() - 2 ).toInt32() );
+ return aDmlColor;
+ }
+
+ // try fill gradient modificator 'fill <modifier>(<amount>)'
+ if( (nPrimaryRgb != API_RGB_TRANSPARENT) && (nColorToken == XML_fill) )
+ {
+ sal_Int32 nOpenParen = aColorIndex.indexOf( '(' );
+ sal_Int32 nCloseParen = aColorIndex.indexOf( ')' );
+ if( (2 <= nOpenParen) && (nOpenParen + 1 < nCloseParen) && (nCloseParen + 1 == aColorIndex.getLength()) )
+ {
+ sal_Int32 nModToken = XML_TOKEN_INVALID;
+ switch( AttributeConversion::decodeToken( aColorIndex.copy( 0, nOpenParen ) ) )
+ {
+ case XML_darken: nModToken = XML_shade;
+ case XML_lighten: nModToken = XML_tint;
+ }
+ sal_Int32 nValue = aColorIndex.copy( nOpenParen + 1, nCloseParen - nOpenParen - 1 ).toInt32();
+ if( (nModToken != XML_TOKEN_INVALID) && (0 <= nValue) && (nValue < 255) )
+ {
+ /* Simulate this modifier color by a color with related transformation.
+ The modifier amount has to be converted from the range [0;255] to
+ percentage [0;100000] used by DrawingML. */
+ aDmlColor.setSrgbClr( nPrimaryRgb );
+ aDmlColor.addTransformation( nModToken, static_cast< sal_Int32 >( nValue * ::oox::drawingml::MAX_PERCENT / 255 ) );
+ return aDmlColor;
+ }
+ }
+ }
+
+ OSL_ENSURE( false, OStringBuffer( "ConversionHelper::decodeColor - invalid VML color name '" ).
+ append( OUStringToOString( roVmlColor.get(), RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() );
+ aDmlColor.setSrgbClr( nDefaultRgb );
+ return aDmlColor;
+}
+
+// ============================================================================
+
+namespace {
+
+sal_Int32 lclGetEmu( const GraphicHelper& rGraphicHelper, const OptValue< OUString >& roValue, sal_Int32 nDefValue )
+{
+ return roValue.has() ? ConversionHelper::decodeMeasureToEmu( rGraphicHelper, roValue.get(), 0, false, false ) : nDefValue;
+}
+
+void lclGetDmlLineDash( OptValue< sal_Int32 >& oroPresetDash, LineProperties::DashStopVector& orCustomDash, const OptValue< OUString >& roDashStyle )
+{
+ if( roDashStyle.has() )
+ {
+ const OUString& rDashStyle = roDashStyle.get();
+ switch( AttributeConversion::decodeToken( rDashStyle ) )
+ {
+ case XML_solid: oroPresetDash = XML_solid; return;
+ case XML_shortdot: oroPresetDash = XML_sysDot; return;
+ case XML_shortdash: oroPresetDash = XML_sysDash; return;
+ case XML_shortdashdot: oroPresetDash = XML_sysDashDot; return;
+ case XML_shortdashdotdot: oroPresetDash = XML_sysDashDotDot; return;
+ case XML_dot: oroPresetDash = XML_dot; return;
+ case XML_dash: oroPresetDash = XML_dash; return;
+ case XML_dashdot: oroPresetDash = XML_dashDot; return;
+ case XML_longdash: oroPresetDash = XML_lgDash; return;
+ case XML_longdashdot: oroPresetDash = XML_lgDashDot; return;
+ case XML_longdashdotdot: oroPresetDash = XML_lgDashDotDot; return;
+
+ // try to convert user-defined dash style
+ default:
+ {
+ ::std::vector< sal_Int32 > aValues;
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ aValues.push_back( rDashStyle.getToken( 0, ' ', nIndex ).toInt32() );
+ size_t nPairs = aValues.size() / 2; // ignore last value if size is odd
+ for( size_t nPairIdx = 0; nPairIdx < nPairs; ++nPairIdx )
+ orCustomDash.push_back( LineProperties::DashStop( aValues[ 2 * nPairIdx ], aValues[ 2 * nPairIdx + 1 ] ) );
+ }
+ }
+ }
+}
+
+sal_Int32 lclGetDmlArrowType( const OptValue< sal_Int32 >& roArrowType )
+{
+ if( roArrowType.has() ) switch( roArrowType.get() )
+ {
+ case XML_none: return XML_none;
+ case XML_block: return XML_triangle;
+ case XML_classic: return XML_stealth;
+ case XML_diamond: return XML_diamond;
+ case XML_oval: return XML_oval;
+ case XML_open: return XML_arrow;
+ }
+ return XML_none;
+}
+
+sal_Int32 lclGetDmlArrowWidth( const OptValue< sal_Int32 >& roArrowWidth )
+{
+ if( roArrowWidth.has() ) switch( roArrowWidth.get() )
+ {
+ case XML_narrow: return XML_sm;
+ case XML_medium: return XML_med;
+ case XML_wide: return XML_lg;
+ }
+ return XML_med;
+}
+
+sal_Int32 lclGetDmlArrowLength( const OptValue< sal_Int32 >& roArrowLength )
+{
+ if( roArrowLength.has() ) switch( roArrowLength.get() )
+ {
+ case XML_short: return XML_sm;
+ case XML_medium: return XML_med;
+ case XML_long: return XML_lg;
+ }
+ return XML_med;
+}
+
+void lclConvertArrow( LineArrowProperties& orArrowProp, const StrokeArrowModel& rStrokeArrow )
+{
+ orArrowProp.moArrowType = lclGetDmlArrowType( rStrokeArrow.moArrowType );
+ orArrowProp.moArrowWidth = lclGetDmlArrowWidth( rStrokeArrow.moArrowWidth );
+ orArrowProp.moArrowLength = lclGetDmlArrowLength( rStrokeArrow.moArrowLength );
+}
+
+sal_Int32 lclGetDmlLineCompound( const OptValue< sal_Int32 >& roLineStyle )
+{
+ if( roLineStyle.has() ) switch( roLineStyle.get() )
+ {
+ case XML_single: return XML_sng;
+ case XML_thinThin: return XML_dbl;
+ case XML_thinThick: return XML_thinThick;
+ case XML_thickThin: return XML_thickThin;
+ case XML_thickBetweenThin: return XML_tri;
+ }
+ return XML_sng;
+}
+
+sal_Int32 lclGetDmlLineCap( const OptValue< sal_Int32 >& roEndCap )
+{
+ if( roEndCap.has() ) switch( roEndCap.get() )
+ {
+ case XML_flat: return XML_flat;
+ case XML_square: return XML_sq;
+ case XML_round: return XML_rnd;
+ }
+ return XML_flat; // different defaults in VML (flat) and DrawingML (square)
+}
+
+sal_Int32 lclGetDmlLineJoint( const OptValue< sal_Int32 >& roJoinStyle )
+{
+ if( roJoinStyle.has() ) switch( roJoinStyle.get() )
+ {
+ case XML_round: return XML_round;
+ case XML_bevel: return XML_bevel;
+ case XML_miter: return XML_miter;
+ }
+ return XML_round;
+}
+
+} // namespace
+
+// ============================================================================
+
+void StrokeArrowModel::assignUsed( const StrokeArrowModel& rSource )
+{
+ moArrowType.assignIfUsed( rSource.moArrowType );
+ moArrowWidth.assignIfUsed( rSource.moArrowWidth );
+ moArrowLength.assignIfUsed( rSource.moArrowLength );
+}
+
+// ============================================================================
+
+void StrokeModel::assignUsed( const StrokeModel& rSource )
+{
+ moStroked.assignIfUsed( rSource.moStroked );
+ maStartArrow.assignUsed( rSource.maStartArrow );
+ maEndArrow.assignUsed( rSource.maEndArrow );
+ moColor.assignIfUsed( rSource.moColor );
+ moOpacity.assignIfUsed( rSource.moOpacity );
+ moWeight.assignIfUsed( rSource.moWeight );
+ moDashStyle.assignIfUsed( rSource.moDashStyle );
+ moLineStyle.assignIfUsed( rSource.moLineStyle );
+ moEndCap.assignIfUsed( rSource.moEndCap );
+ moJoinStyle.assignIfUsed( rSource.moJoinStyle );
+}
+
+void StrokeModel::pushToPropMap( PropertyMap& rPropMap,
+ ModelObjectHelper& rModelObjectHelper, const GraphicHelper& rGraphicHelper ) const
+{
+ /* Convert VML line formatting to DrawingML line formatting and let the
+ DrawingML code do the hard work. */
+ LineProperties aLineProps;
+
+ if( moStroked.get( true ) )
+ {
+ aLineProps.maLineFill.moFillType = XML_solidFill;
+ lclConvertArrow( aLineProps.maStartArrow, maStartArrow );
+ lclConvertArrow( aLineProps.maEndArrow, maEndArrow );
+ aLineProps.maLineFill.maFillColor = ConversionHelper::decodeColor( rGraphicHelper, moColor, moOpacity, API_RGB_BLACK );
+ aLineProps.moLineWidth = lclGetEmu( rGraphicHelper, moWeight, 1 );
+ lclGetDmlLineDash( aLineProps.moPresetDash, aLineProps.maCustomDash, moDashStyle );
+ aLineProps.moLineCompound = lclGetDmlLineCompound( moLineStyle );
+ aLineProps.moLineCap = lclGetDmlLineCap( moEndCap );
+ aLineProps.moLineJoint = lclGetDmlLineJoint( moJoinStyle );
+ }
+ else
+ {
+ aLineProps.maLineFill.moFillType = XML_noFill;
+ }
+
+ aLineProps.pushToPropMap( rPropMap, rModelObjectHelper, rGraphicHelper );
+}
+
+// ============================================================================
+
+void FillModel::assignUsed( const FillModel& rSource )
+{
+ moFilled.assignIfUsed( rSource.moFilled );
+ moColor.assignIfUsed( rSource.moColor );
+ moOpacity.assignIfUsed( rSource.moOpacity );
+ moColor2.assignIfUsed( rSource.moColor2 );
+ moOpacity2.assignIfUsed( rSource.moOpacity2 );
+ moType.assignIfUsed( rSource.moType );
+ moAngle.assignIfUsed( rSource.moAngle );
+ moFocus.assignIfUsed( rSource.moFocus );
+ moFocusPos.assignIfUsed( rSource.moFocusPos );
+ moFocusSize.assignIfUsed( rSource.moFocusSize );
+ moBitmapPath.assignIfUsed( rSource.moBitmapPath );
+ moRotate.assignIfUsed( rSource.moRotate );
+}
+
+void FillModel::pushToPropMap( PropertyMap& rPropMap,
+ ModelObjectHelper& rModelObjectHelper, const GraphicHelper& rGraphicHelper ) const
+{
+ /* Convert VML fill formatting to DrawingML fill formatting and let the
+ DrawingML code do the hard work. */
+ FillProperties aFillProps;
+
+ if( moFilled.get( true ) )
+ {
+ sal_Int32 nFillType = moType.get( XML_solid );
+ switch( nFillType )
+ {
+ case XML_gradient:
+ case XML_gradientRadial:
+ {
+ aFillProps.moFillType = XML_gradFill;
+ aFillProps.maGradientProps.moRotateWithShape = moRotate.get( false );
+ double fFocus = moFocus.get( 0.0 );
+
+ // prepare colors
+ Color aColor1 = ConversionHelper::decodeColor( rGraphicHelper, moColor, moOpacity, API_RGB_WHITE );
+ Color aColor2 = ConversionHelper::decodeColor( rGraphicHelper, moColor2, moOpacity2, API_RGB_WHITE, aColor1.getColor( rGraphicHelper ) );
+
+ // type XML_gradient is linear or axial gradient
+ if( nFillType == XML_gradient )
+ {
+ // normalize angle to range [0;360) degrees
+ sal_Int32 nVmlAngle = getIntervalValue< sal_Int32, sal_Int32 >( moAngle.get( 0 ), 0, 360 );
+
+ // focus of -50% or 50% is axial gradient
+ if( ((-0.75 <= fFocus) && (fFocus <= -0.25)) || ((0.25 <= fFocus) && (fFocus <= 0.75)) )
+ {
+ /* According to spec, focus of 50% is outer-to-inner,
+ and -50% is inner-to-outer (color to color2).
+ BUT: For angles >= 180 deg., the behaviour is
+ reversed... that's not spec'ed of course. So,
+ [0;180) deg. and 50%, or [180;360) deg. and -50% is
+ outer-to-inner in fact. */
+ bool bOuterToInner = (fFocus > 0.0) == (nVmlAngle < 180);
+ // simulate axial gradient by 3-step DrawingML gradient
+ const Color& rOuterColor = bOuterToInner ? aColor1 : aColor2;
+ const Color& rInnerColor = bOuterToInner ? aColor2 : aColor1;
+ aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aFillProps.maGradientProps.maGradientStops[ 1.0 ] = rOuterColor;
+ aFillProps.maGradientProps.maGradientStops[ 0.5 ] = rInnerColor;
+ }
+ else // focus of -100%, 0%, and 100% is linear gradient
+ {
+ /* According to spec, focus of -100% or 100% swaps the
+ start and stop colors, effectively reversing the
+ gradient. BUT: For angles >= 180 deg., the
+ behaviour is reversed. This means that in this case
+ a focus of 0% swaps the gradient. */
+ if( ((fFocus < -0.75) || (fFocus > 0.75)) == (nVmlAngle < 180) )
+ (nVmlAngle += 180) %= 360;
+ // set the start and stop colors
+ aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aColor1;
+ aFillProps.maGradientProps.maGradientStops[ 1.0 ] = aColor2;
+ }
+
+ // VML counts counterclockwise from bottom, DrawingML clockwise from left
+ sal_Int32 nDmlAngle = (630 - nVmlAngle) % 360;
+ aFillProps.maGradientProps.moShadeAngle = nDmlAngle * ::oox::drawingml::PER_DEGREE;
+ }
+ else // XML_gradientRadial is rectangular gradient
+ {
+ aFillProps.maGradientProps.moGradientPath = XML_rect;
+ // convert VML focus position and size to DrawingML fill-to-rect
+ DoublePair aFocusPos = moFocusPos.get( DoublePair( 0.0, 0.0 ) );
+ DoublePair aFocusSize = moFocusSize.get( DoublePair( 0.0, 0.0 ) );
+ double fLeft = getLimitedValue< double, double >( aFocusPos.first, 0.0, 1.0 );
+ double fTop = getLimitedValue< double, double >( aFocusPos.second, 0.0, 1.0 );
+ double fRight = getLimitedValue< double, double >( fLeft + aFocusSize.first, fLeft, 1.0 );
+ double fBottom = getLimitedValue< double, double >( fTop + aFocusSize.second, fTop, 1.0 );
+ aFillProps.maGradientProps.moFillToRect = IntegerRectangle2D(
+ static_cast< sal_Int32 >( fLeft * ::oox::drawingml::MAX_PERCENT ),
+ static_cast< sal_Int32 >( fTop * ::oox::drawingml::MAX_PERCENT ),
+ static_cast< sal_Int32 >( (1.0 - fRight) * ::oox::drawingml::MAX_PERCENT ),
+ static_cast< sal_Int32 >( (1.0 - fBottom) * ::oox::drawingml::MAX_PERCENT ) );
+
+ // set the start and stop colors (focus of 0% means outer-to-inner)
+ bool bOuterToInner = (-0.5 <= fFocus) && (fFocus <= 0.5);
+ aFillProps.maGradientProps.maGradientStops[ 0.0 ] = bOuterToInner ? aColor2 : aColor1;
+ aFillProps.maGradientProps.maGradientStops[ 1.0 ] = bOuterToInner ? aColor1 : aColor2;
+ }
+ }
+ break;
+
+ case XML_pattern:
+ case XML_tile:
+ case XML_frame:
+ {
+ if( moBitmapPath.has() && moBitmapPath.get().getLength() > 0 )
+ {
+ aFillProps.maBlipProps.mxGraphic = rGraphicHelper.importEmbeddedGraphic( moBitmapPath.get() );
+ if( aFillProps.maBlipProps.mxGraphic.is() )
+ {
+ aFillProps.moFillType = XML_blipFill;
+ aFillProps.maBlipProps.moBitmapMode = (nFillType == XML_frame) ? XML_stretch : XML_tile;
+ break; // do not break if bitmap is missing, but run to XML_solid instead
+ }
+ }
+ }
+ // run-through to XML_solid in case of missing bitmap path intended!
+
+ case XML_solid:
+ default:
+ {
+ aFillProps.moFillType = XML_solidFill;
+ // fill color (default is white)
+ aFillProps.maFillColor = ConversionHelper::decodeColor( rGraphicHelper, moColor, moOpacity, API_RGB_WHITE );
+ }
+ }
+ }
+ else
+ {
+ aFillProps.moFillType = XML_noFill;
+ }
+
+ aFillProps.pushToPropMap( rPropMap, rModelObjectHelper, rGraphicHelper );
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx
new file mode 100644
index 000000000000..fb2443aba4c4
--- /dev/null
+++ b/oox/source/vml/vmlinputstream.cxx
@@ -0,0 +1,325 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlinputstream.hxx"
+
+#include <map>
+#include <rtl/strbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include "oox/helper/helper.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+inline const sal_Char* lclFindCharacter( const sal_Char* pcBeg, const sal_Char* pcEnd, sal_Char cChar )
+{
+ sal_Int32 nIndex = rtl_str_indexOfChar_WithLength( pcBeg, static_cast< sal_Int32 >( pcEnd - pcBeg ), cChar );
+ return (nIndex < 0) ? pcEnd : (pcBeg + nIndex);
+}
+
+inline bool lclIsWhiteSpace( sal_Char cChar )
+{
+ return (cChar == ' ') || (cChar == '\t') || (cChar == '\n') || (cChar == '\r');
+}
+
+const sal_Char* lclFindWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd )
+{
+ for( ; pcBeg < pcEnd; ++pcBeg )
+ if( lclIsWhiteSpace( *pcBeg ) )
+ return pcBeg;
+ return pcEnd;
+}
+
+const sal_Char* lclFindNonWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd )
+{
+ for( ; pcBeg < pcEnd; ++pcBeg )
+ if( !lclIsWhiteSpace( *pcBeg ) )
+ return pcBeg;
+ return pcEnd;
+}
+
+const sal_Char* lclTrimWhiteSpaceFromEnd( const sal_Char* pcBeg, const sal_Char* pcEnd )
+{
+ while( (pcBeg < pcEnd) && lclIsWhiteSpace( pcEnd[ -1 ] ) )
+ --pcEnd;
+ return pcEnd;
+}
+
+inline void lclAppendToBuffer( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd )
+{
+ rBuffer.append( pcBeg, static_cast< sal_Int32 >( pcEnd - pcBeg ) );
+}
+
+// ----------------------------------------------------------------------------
+
+void lclProcessAttribs( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd )
+{
+ /* Map attribute names to char-pointer of all attributes. This map is used
+ to find multiple occurences of attributes with the same name. The
+ mapped pointers are used as map key in the next map below. */
+ typedef ::std::map< OString, const sal_Char* > AttributeNameMap;
+ AttributeNameMap aAttributeNames;
+
+ /* Map the char-pointers of all attributes to the full attribute definition
+ string. This preserves the original order of the used attributes. */
+ typedef ::std::map< const sal_Char*, OString > AttributeDataMap;
+ AttributeDataMap aAttributes;
+
+ bool bOk = true;
+ const sal_Char* pcNameBeg = pcBeg;
+ while( bOk && (pcNameBeg < pcEnd) )
+ {
+ // pcNameBeg points to begin of attribute name, find equality sign
+ const sal_Char* pcEqualSign = lclFindCharacter( pcNameBeg, pcEnd, '=' );
+ if( (bOk = pcEqualSign < pcEnd) == true )
+ {
+ // find end of attribute name (ignore whitespace between name and equality sign)
+ const sal_Char* pcNameEnd = lclTrimWhiteSpaceFromEnd( pcNameBeg, pcEqualSign );
+ if( (bOk = pcNameBeg < pcNameEnd) == true )
+ {
+ // find begin of attribute value (must be single or double quote)
+ const sal_Char* pcValueBeg = lclFindNonWhiteSpace( pcEqualSign + 1, pcEnd );
+ if( (bOk = (pcValueBeg < pcEnd) && ((*pcValueBeg == '\'') || (*pcValueBeg == '"'))) == true )
+ {
+ // find end of attribute value (matching quote character)
+ const sal_Char* pcValueEnd = lclFindCharacter( pcValueBeg + 1, pcEnd, *pcValueBeg );
+ if( (bOk = pcValueEnd < pcEnd) == true )
+ {
+ ++pcValueEnd;
+ OString aAttribName( pcNameBeg, static_cast< sal_Int32 >( pcNameEnd - pcNameBeg ) );
+ OString aAttribData( pcNameBeg, static_cast< sal_Int32 >( pcValueEnd - pcNameBeg ) );
+ // search for an existing attribute with the same name
+ AttributeNameMap::iterator aIt = aAttributeNames.find( aAttribName );
+ // remove its definition from the data map
+ if( aIt != aAttributeNames.end() )
+ aAttributes.erase( aIt->second );
+ // insert the attribute into both maps
+ aAttributeNames[ aAttribName ] = pcNameBeg;
+ aAttributes[ pcNameBeg ] = aAttribData;
+ // continue with next attribute (skip whitespace after this attribute)
+ pcNameBeg = pcValueEnd;
+ if( (pcNameBeg < pcEnd) && ((bOk = lclIsWhiteSpace( *pcNameBeg )) == true) )
+ pcNameBeg = lclFindNonWhiteSpace( pcNameBeg + 1, pcEnd );
+ }
+ }
+ }
+ }
+ }
+
+ // if no error has occured, build the resulting attribute list
+ if( bOk )
+ for( AttributeDataMap::iterator aIt = aAttributes.begin(), aEnd = aAttributes.end(); aIt != aEnd; ++aIt )
+ rBuffer.append( ' ' ).append( aIt->second );
+ // on error, just append the complete passed string
+ else
+ lclAppendToBuffer( rBuffer, pcBeg, pcEnd );
+}
+
+void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd )
+{
+ /* MSO has a very weird way to store and handle whitespaces. The stream
+ may contain lots of spaces, tabs, and newlines which have to be handled
+ as single space character. This will be done in this function.
+
+ If the element text contains a literal line break, it will be stored as
+ <br> tag (without matching closing </br> element).
+
+ A single space character following another character is stored
+ literally and must not be stipped away here. Example: The element
+ <font>abc </font>
+ contains the three letters a, b, and c, followed by a space character.
+
+ Consecutive space characters, or a leading single space character, are
+ stored in a <span> element. If there are N space characters (N > 1),
+ then the <span> element contains exactly (N-1) NBSP characters
+ (non-breaking space), followed by a regular space character. Example:
+ The element
+ <font><span style='mso-spacerun:yes'>\xA0\xA0\xA0 </span></font>
+ represents 4 consecutive space characters. Has to be handled by the
+ implementation.
+
+ A single space character for its own is stored in an empty element.
+ Example: The element
+ <font></font>
+ represents a single space character. Has to be handled by the
+ implementation.
+ */
+
+ // skip leading whitespace
+ const sal_Char* pcContentsBeg = lclFindNonWhiteSpace( pcBeg, pcEnd );
+ while( pcContentsBeg < pcEnd )
+ {
+ const sal_Char* pcWhitespaceBeg = lclFindWhiteSpace( pcContentsBeg + 1, pcEnd );
+ lclAppendToBuffer( rBuffer, pcContentsBeg, pcWhitespaceBeg );
+ if( pcWhitespaceBeg < pcEnd )
+ rBuffer.append( ' ' );
+ pcContentsBeg = lclFindNonWhiteSpace( pcWhitespaceBeg, pcEnd );
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInStrm )
+{
+ if( rxInStrm.is() ) try
+ {
+ // read all bytes we can read
+ rxInStrm->readBytes( maDataSeq, SAL_MAX_INT32 );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( maDataSeq.hasElements() )
+ {
+ const OString aCDataOpen = CREATE_OSTRING( "<![CDATA[" );
+ const OString aCDataClose = CREATE_OSTRING( "]]>" );
+
+ OStringBuffer aBuffer;
+ aBuffer.ensureCapacity( maDataSeq.getLength() + 256 );
+ const sal_Char* pcCurr = reinterpret_cast< const sal_Char* >( maDataSeq.getConstArray() );
+ const sal_Char* pcEnd = pcCurr + maDataSeq.getLength();
+ while( pcCurr < pcEnd )
+ {
+ // look for the next opening angle bracket
+ const sal_Char* pcOpen = lclFindCharacter( pcCurr, pcEnd, '<' );
+
+ // copy all characters from current position to opening bracket
+ lclProcessContents( aBuffer, pcCurr, pcOpen );
+
+ // nothing to do if no opening bracket has been found
+ if( pcOpen < pcEnd )
+ {
+ // string length from opening bracket to end
+ sal_Int32 nLengthToEnd = static_cast< sal_Int32 >( pcEnd - pcOpen );
+
+ // check for CDATA part, starting with '<![CDATA['
+ if( rtl_str_compare_WithLength( pcOpen, nLengthToEnd, aCDataOpen.getStr(), aCDataOpen.getLength() ) == 0 )
+ {
+ // search the position after the end tag ']]>'
+ sal_Int32 nClosePos = rtl_str_indexOfStr_WithLength( pcOpen, nLengthToEnd, aCDataClose.getStr(), aCDataClose.getLength() );
+ pcCurr = (nClosePos < 0) ? pcEnd : (pcOpen + nClosePos + aCDataClose.getLength());
+ // copy the entire CDATA part
+ lclAppendToBuffer( aBuffer, pcOpen, pcCurr );
+ }
+
+ // no CDATA part - process the element starting at pcOpen
+ else
+ {
+ // look for the next closing angle bracket
+ const sal_Char* pcClose = lclFindCharacter( pcOpen + 1, pcEnd, '>' );
+ // complete element found?
+ if( pcClose < pcEnd )
+ {
+ // continue after closing bracket
+ pcCurr = pcClose + 1;
+ // length of entire element with angle brackets
+ sal_Int32 nElementLen = static_cast< sal_Int32 >( pcCurr - pcOpen );
+
+ // skip parser instructions: '<![...]>'
+ if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') )
+ {
+ // do nothing
+ }
+
+ // replace '<br>' element with newline
+ else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) )
+ {
+ aBuffer.append( '\n' );
+ }
+
+ // check start elements and empty elements for repeated attributes
+ else if( pcOpen[ 1 ] != '/' )
+ {
+ // find positions of text content inside brackets, exclude '/' in '<emptyelement/>'
+ const sal_Char* pcContentBeg = pcOpen + 1;
+ bool bIsEmptyElement = pcClose[ -1 ] == '/';
+ const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose;
+ // append element name to buffer
+ const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd );
+ lclAppendToBuffer( aBuffer, pcOpen, pcWhiteSpace );
+ // find begin of attributes, and process all attributes
+ const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd );
+ if( pcAttribBeg < pcContentEnd )
+ lclProcessAttribs( aBuffer, pcAttribBeg, pcContentEnd );
+ // close the element
+ if( bIsEmptyElement )
+ aBuffer.append( '/' );
+ aBuffer.append( '>' );
+ }
+
+ // append end elements without further processing
+ else
+ {
+ lclAppendToBuffer( aBuffer, pcOpen, pcCurr );
+ }
+ }
+ else
+ {
+ // no complete element found, copy all from opening bracket to end
+ lclAppendToBuffer( aBuffer, pcOpen, pcEnd );
+ pcCurr = pcEnd;
+ }
+ }
+ }
+ }
+
+ // set the final data sequence
+ maDataSeq = ::comphelper::ByteSequence( reinterpret_cast< const sal_Int8* >( aBuffer.getStr() ), aBuffer.getLength() );
+ }
+}
+
+// ============================================================================
+
+InputStream::InputStream( const Reference< XInputStream >& rxInStrm ) :
+ StreamDataContainer( rxInStrm ),
+ ::comphelper::SequenceInputStream( maDataSeq )
+{
+}
+
+InputStream::~InputStream()
+{
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespave oox
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
new file mode 100644
index 000000000000..db12f3d91e0b
--- /dev/null
+++ b/oox/source/vml/vmlshape.cxx
@@ -0,0 +1,570 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlshape.hxx"
+
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/ole/axcontrol.hxx"
+#include "oox/ole/axcontrolfragment.hxx"
+#include "oox/ole/oleobjecthelper.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+#include "oox/vml/vmltextbox.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::XmlFilterBase;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 VML_SHAPETYPE_PICTUREFRAME = 75;
+const sal_Int32 VML_SHAPETYPE_HOSTCONTROL = 201;
+
+// ----------------------------------------------------------------------------
+
+Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
+{
+ double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
+ double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
+ Point aAbsPoint;
+ aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
+ aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
+ return aAbsPoint;
+}
+
+Rectangle lclGetAbsRect( const Rectangle& rRelRect, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
+{
+ double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
+ double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
+ Rectangle aAbsRect;
+ aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
+ aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
+ aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
+ aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
+ return aAbsRect;
+}
+
+} // namespace
+
+// ============================================================================
+
+ShapeTypeModel::ShapeTypeModel()
+{
+}
+
+void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
+{
+ moShapeType.assignIfUsed( rSource.moShapeType );
+ moCoordPos.assignIfUsed( rSource.moCoordPos );
+ moCoordSize.assignIfUsed( rSource.moCoordSize );
+ /* The style properties position, left, top, width, height, margin-left,
+ margin-top are not derived from shape template to shape. */
+ maStrokeModel.assignUsed( rSource.maStrokeModel );
+ maFillModel.assignUsed( rSource.maFillModel );
+ moGraphicPath.assignIfUsed( rSource.moGraphicPath );
+ moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
+}
+
+// ----------------------------------------------------------------------------
+
+ShapeType::ShapeType( Drawing& rDrawing ) :
+ mrDrawing( rDrawing )
+{
+}
+
+ShapeType::~ShapeType()
+{
+}
+
+sal_Int32 ShapeType::getShapeType() const
+{
+ return maTypeModel.moShapeType.get( 0 );
+}
+
+OUString ShapeType::getGraphicPath() const
+{
+ return maTypeModel.moGraphicPath.get( OUString() );
+}
+
+Rectangle ShapeType::getCoordSystem() const
+{
+ Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) );
+ Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) );
+ return Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second );
+}
+
+Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
+{
+ return pParentAnchor ?
+ lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
+ getAbsRectangle();
+}
+
+Rectangle ShapeType::getAbsRectangle() const
+{
+ const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
+ return Rectangle(
+ ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true ),
+ ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ),
+ ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true ),
+ ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true ) );
+}
+
+Rectangle ShapeType::getRelRectangle() const
+{
+ return Rectangle(
+ maTypeModel.maLeft.toInt32(),
+ maTypeModel.maTop.toInt32(),
+ maTypeModel.maWidth.toInt32(),
+ maTypeModel.maHeight.toInt32() );
+}
+
+// ============================================================================
+
+ClientData::ClientData() :
+ mnObjType( XML_TOKEN_INVALID ),
+ mnTextHAlign( XML_Left ),
+ mnTextVAlign( XML_Top ),
+ mnCol( -1 ),
+ mnRow( -1 ),
+ mnChecked( VML_CLIENTDATA_UNCHECKED ),
+ mnDropStyle( XML_Combo ),
+ mnDropLines( 1 ),
+ mnVal( 0 ),
+ mnMin( 0 ),
+ mnMax( 0 ),
+ mnInc( 0 ),
+ mnPage( 0 ),
+ mnSelType( XML_Single ),
+ mnVTEdit( VML_CLIENTDATA_TEXT ),
+ mbPrintObject( true ),
+ mbVisible( false ),
+ mbDde( false ),
+ mbNo3D( false ),
+ mbNo3D2( false ),
+ mbMultiLine( false ),
+ mbVScroll( false ),
+ mbSecretEdit( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ShapeModel::ShapeModel()
+{
+}
+
+ShapeModel::~ShapeModel()
+{
+}
+
+TextBox& ShapeModel::createTextBox()
+{
+ mxTextBox.reset( new TextBox );
+ return *mxTextBox;
+}
+
+ClientData& ShapeModel::createClientData()
+{
+ mxClientData.reset( new ClientData );
+ return *mxClientData;
+}
+
+// ----------------------------------------------------------------------------
+
+ShapeBase::ShapeBase( Drawing& rDrawing ) :
+ ShapeType( rDrawing )
+{
+}
+
+void ShapeBase::finalizeFragmentImport()
+{
+ // resolve shape template reference
+ if( (maShapeModel.maType.getLength() > 1) && (maShapeModel.maType[ 0 ] == '#') )
+ if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( maShapeModel.maType.copy( 1 ), true ) )
+ maTypeModel.assignUsed( pShapeType->getTypeModel() );
+}
+
+OUString ShapeBase::getShapeName() const
+{
+ if( maTypeModel.maShapeName.getLength() > 0 )
+ return maTypeModel.maShapeName;
+
+ OUString aBaseName = mrDrawing.getShapeBaseName( *this );
+ if( aBaseName.getLength() > 0 )
+ {
+ sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() );
+ if( nShapeIdx > 0 )
+ return OUStringBuffer( aBaseName ).append( sal_Unicode( ' ' ) ).append( nShapeIdx ).makeStringAndClear();
+ }
+
+ return OUString();
+}
+
+const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
+{
+ return 0;
+}
+
+const ShapeBase* ShapeBase::getChildById( const OUString& ) const
+{
+ return 0;
+}
+
+Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
+{
+ Reference< XShape > xShape;
+ if( mrDrawing.isShapeSupported( *this ) )
+ {
+ /* Calculate shape rectangle. Applications may do something special
+ according to some imported shape client data (e.g. Excel cell anchor). */
+ Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
+
+ // convert the shape, if the calculated rectangle is not empty
+ if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
+ {
+ xShape = implConvertAndInsert( rxShapes, aShapeRect );
+ if( xShape.is() )
+ {
+ // set shape name (imported or generated)
+ PropertySet aShapeProp( xShape );
+ aShapeProp.setProperty( PROP_Name, getShapeName() );
+
+ /* Notify the drawing that a new shape has been inserted. For
+ convenience, pass the rectangle that contains position and
+ size of the shape. */
+ bool bGroupChild = pParentAnchor != 0;
+ mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild );
+ }
+ }
+ }
+ return xShape;
+}
+
+void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const
+{
+ if( rxShape.is() )
+ {
+ /* Calculate shape rectangle. Applications may do something special
+ according to some imported shape client data (e.g. Excel cell anchor). */
+ Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
+
+ // convert the shape, if the calculated rectangle is not empty
+ if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
+ {
+ rxShape->setPosition( Point( aShapeRect.X, aShapeRect.Y ) );
+ rxShape->setSize( Size( aShapeRect.Width, aShapeRect.Height ) );
+ convertShapeProperties( rxShape );
+ }
+ }
+}
+
+// protected ------------------------------------------------------------------
+
+Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
+{
+ /* Calculate shape rectangle. Applications may do something special
+ according to some imported shape client data (e.g. Excel cell anchor). */
+ Rectangle aShapeRect;
+ const ClientData* pClientData = getClientData();
+ if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) )
+ aShapeRect = getRectangle( pParentAnchor );
+ return aShapeRect;
+}
+
+void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
+{
+ ModelObjectHelper& rModelObjectHelper = mrDrawing.getFilter().getModelObjectHelper();
+ const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
+
+ PropertyMap aPropMap;
+ maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rModelObjectHelper, rGraphicHelper );
+ maTypeModel.maFillModel.pushToPropMap( aPropMap, rModelObjectHelper, rGraphicHelper );
+
+ PropertySet aPropSet( rxShape );
+ aPropSet.setProperties( aPropMap );
+}
+
+// ============================================================================
+
+SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :
+ ShapeBase( rDrawing ),
+ maService( rService )
+{
+}
+
+Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, rShapeRect );
+ convertShapeProperties( xShape );
+ return xShape;
+}
+
+// ============================================================================
+
+RectangleShape::RectangleShape( Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ) )
+{
+}
+
+// ============================================================================
+
+EllipseShape::EllipseShape( Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ) )
+{
+}
+
+// ============================================================================
+
+PolyLineShape::PolyLineShape( Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ) )
+{
+}
+
+Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
+ // polygon path
+ Rectangle aCoordSys = getCoordSystem();
+ if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
+ {
+ ::std::vector< Point > aAbsPoints;
+ for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
+ aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
+ PointSequenceSequence aPointSeq( 1 );
+ aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
+ PropertySet aPropSet( xShape );
+ aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
+ }
+ return xShape;
+}
+
+// ============================================================================
+
+CustomShape::CustomShape( Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.CustomShape" ) )
+{
+}
+
+Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ // try to create a custom shape
+ Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
+ if( xShape.is() ) try
+ {
+ // create the custom shape geometry
+ Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
+ xDefaulter->createCustomShapeDefaults( OUString::valueOf( getShapeType() ) );
+ // convert common properties
+ convertShapeProperties( xShape );
+ }
+ catch( Exception& )
+ {
+ }
+ return xShape;
+}
+
+// ============================================================================
+
+ComplexShape::ComplexShape( Drawing& rDrawing ) :
+ CustomShape( rDrawing )
+{
+}
+
+Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ XmlFilterBase& rFilter = mrDrawing.getFilter();
+ sal_Int32 nShapeType = getShapeType();
+ OUString aGraphicPath = getGraphicPath();
+
+ // try to find registered OLE object info
+ if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
+ {
+ OSL_ENSURE( nShapeType == VML_SHAPETYPE_PICTUREFRAME, "ComplexShape::implConvertAndInsert - unexpected shape type" );
+
+ // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
+ if( pOleObjectInfo->mbDmlShape )
+ return Reference< XShape >();
+
+ PropertyMap aOleProps;
+ Size aOleSize( rShapeRect.Width, rShapeRect.Height );
+ if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
+ {
+ Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rxShapes, rShapeRect );
+ if( xShape.is() )
+ {
+ // set the replacement graphic
+ if( aGraphicPath.getLength() > 0 )
+ {
+ Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
+ if( xGraphic.is() )
+ aOleProps[ PROP_Graphic ] <<= xGraphic;
+ }
+
+ PropertySet aPropSet( xShape );
+ aPropSet.setProperties( aOleProps );
+
+ return xShape;
+ }
+ }
+ }
+
+ // try to find registered form control info
+ const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
+ if( pControlInfo && (pControlInfo->maFragmentPath.getLength() > 0) )
+ {
+ OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
+ OUString aShapeName = getShapeName();
+ if( aShapeName.getLength() > 0 )
+ {
+ OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
+ // load the control properties from fragment
+ ::oox::ole::EmbeddedControl aControl( aShapeName );
+ if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
+ {
+ // create and return the control shape (including control model)
+ sal_Int32 nCtrlIndex = -1;
+ Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
+ // on error, proceed and try to create picture from replacement image
+ if( xShape.is() )
+ return xShape;
+ }
+ }
+ }
+
+ // host application wants to create the shape (do not try failed OLE controls again)
+ if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo )
+ {
+ OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" );
+ Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect );
+ if( xShape.is() )
+ return xShape;
+ }
+
+ // try to create a picture object
+ if( aGraphicPath.getLength() > 0 )
+ {
+ Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rxShapes, rShapeRect );
+ if( xShape.is() )
+ {
+ OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( aGraphicPath );
+ if( aGraphicUrl.getLength() > 0 )
+ {
+ PropertySet aPropSet( xShape );
+ aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
+ }
+ }
+ return xShape;
+ }
+
+ // default: try to create a custom shape
+ return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
+}
+
+// ============================================================================
+
+GroupShape::GroupShape( Drawing& rDrawing ) :
+ ShapeBase( rDrawing ),
+ mxChildren( new ShapeContainer( rDrawing ) )
+{
+}
+
+GroupShape::~GroupShape()
+{
+}
+
+void GroupShape::finalizeFragmentImport()
+{
+ // basic shape processing
+ ShapeBase::finalizeFragmentImport();
+ // finalize all child shapes
+ mxChildren->finalizeFragmentImport();
+}
+
+const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
+{
+ return mxChildren->getShapeTypeById( rShapeId, true );
+}
+
+const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
+{
+ return mxChildren->getShapeById( rShapeId, true );
+}
+
+Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ Reference< XShape > xGroupShape;
+ // check that this shape contains children and a valid coordinate system
+ ShapeParentAnchor aParentAnchor;
+ aParentAnchor.maShapeRect = rShapeRect;
+ aParentAnchor.maCoordSys = getCoordSystem();
+ if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
+ {
+ xGroupShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rxShapes, rShapeRect );
+ Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
+ mxChildren->convertAndInsert( xChildShapes, &aParentAnchor );
+ // no child shape has been created - delete the group shape
+ if( !xChildShapes->hasElements() )
+ {
+ rxShapes->remove( xGroupShape );
+ xGroupShape.clear();
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ return xGroupShape;
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx
new file mode 100644
index 000000000000..9589549be0d9
--- /dev/null
+++ b/oox/source/vml/vmlshapecontainer.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlshapecontainer.hxx"
+
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlshape.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+template< typename ShapeType >
+void lclMapShapesById( RefMap< OUString, ShapeType >& orMap, const RefVector< ShapeType >& rVector )
+{
+ for( typename RefVector< ShapeType >::const_iterator aIt = rVector.begin(), aEnd = rVector.end(); aIt != aEnd; ++aIt )
+ {
+ const OUString& rShapeId = (*aIt)->getShapeId();
+ OSL_ENSURE( rShapeId.getLength() > 0, "lclMapShapesById - missing shape identifier" );
+ if( rShapeId.getLength() > 0 )
+ {
+ OSL_ENSURE( orMap.find( rShapeId ) == orMap.end(), "lclMapShapesById - shape identifier already used" );
+ orMap[ rShapeId ] = *aIt;
+ }
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+ShapeContainer::ShapeContainer( Drawing& rDrawing ) :
+ mrDrawing( rDrawing )
+{
+}
+
+ShapeContainer::~ShapeContainer()
+{
+}
+
+ShapeType& ShapeContainer::createShapeType()
+{
+ ::boost::shared_ptr< ShapeType > xShape( new ShapeType( mrDrawing ) );
+ maTypes.push_back( xShape );
+ return *xShape;
+}
+
+void ShapeContainer::finalizeFragmentImport()
+{
+ // map all shape templates by shape identifier
+ lclMapShapesById( maTypesById, maTypes );
+ // map all shapes by shape identifier
+ lclMapShapesById( maShapesById, maShapes );
+ /* process all shapes (map all children templates/shapes in group shapes,
+ resolve template references in all shapes) */
+ maShapes.forEachMem( &ShapeBase::finalizeFragmentImport );
+}
+
+const ShapeType* ShapeContainer::getShapeTypeById( const OUString& rShapeId, bool bDeep ) const
+{
+ // search in own shape template list
+ if( const ShapeType* pType = maTypesById.get( rShapeId ).get() )
+ return pType;
+ // search deep in child shapes
+ if( bDeep )
+ for( ShapeVector::const_iterator aVIt = maShapes.begin(), aVEnd = maShapes.end(); aVIt != aVEnd; ++aVIt )
+ if( const ShapeType* pType = (*aVIt)->getChildTypeById( rShapeId ) )
+ return pType;
+ return 0;
+}
+
+const ShapeBase* ShapeContainer::getShapeById( const OUString& rShapeId, bool bDeep ) const
+{
+ // search in own shape list
+ if( const ShapeBase* pShape = maShapesById.get( rShapeId ).get() )
+ return pShape;
+ // search deep in child shapes
+ if( bDeep )
+ for( ShapeVector::const_iterator aVIt = maShapes.begin(), aVEnd = maShapes.end(); aVIt != aVEnd; ++aVIt )
+ if( const ShapeBase* pShape = (*aVIt)->getChildById( rShapeId ) )
+ return pShape;
+ return 0;
+}
+
+const ShapeBase* ShapeContainer::getFirstShape() const
+{
+ OSL_ENSURE( mrDrawing.getType() == VMLDRAWING_WORD, "ShapeContainer::getFirstShape - illegal call, Word filter only" );
+ OSL_ENSURE( maShapes.size() == 1, "ShapeContainer::getFirstShape - single shape expected" );
+ return maShapes.get( 0 ).get();
+}
+
+void ShapeContainer::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
+{
+ for( ShapeVector::const_iterator aIt = maShapes.begin(), aEnd = maShapes.end(); aIt != aEnd; ++aIt )
+ (*aIt)->convertAndInsert( rxShapes, pParentAnchor );
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
new file mode 100644
index 000000000000..54e0d1ac70bc
--- /dev/null
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlshapecontext.hxx"
+
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+#include "oox/vml/vmltextboxcontext.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+
+using ::oox::core::ContextHandler2;
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+/** Returns the boolean value from the specified VML attribute (if present).
+ */
+OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nToken )
+{
+ OptValue< OUString > oValue = rAttribs.getString( nToken );
+ if( oValue.has() ) return OptValue< bool >( ConversionHelper::decodeBool( oValue.get() ) );
+ return OptValue< bool >();
+}
+
+/** Returns the percentage value from the specified VML attribute (if present).
+ The value will be normalized (1.0 is returned for 100%).
+ */
+OptValue< double > lclDecodePercent( const AttributeList& rAttribs, sal_Int32 nToken, double fDefValue )
+{
+ OptValue< OUString > oValue = rAttribs.getString( nToken );
+ if( oValue.has() ) return OptValue< double >( ConversionHelper::decodePercent( oValue.get(), fDefValue ) );
+ return OptValue< double >();
+}
+
+/** Returns the integer value pair from the specified VML attribute (if present).
+ */
+OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int32 nToken )
+{
+ OptValue< OUString > oValue = rAttribs.getString( nToken );
+ OptValue< Int32Pair > oRetValue;
+ if( oValue.has() )
+ {
+ OUString aValue1, aValue2;
+ ConversionHelper::separatePair( aValue1, aValue2, oValue.get(), ',' );
+ oRetValue = Int32Pair( aValue1.toInt32(), aValue2.toInt32() );
+ }
+ return oRetValue;
+}
+
+/** Returns the percentage pair from the specified VML attribute (if present).
+ */
+OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_Int32 nToken )
+{
+ OptValue< OUString > oValue = rAttribs.getString( nToken );
+ OptValue< DoublePair > oRetValue;
+ if( oValue.has() )
+ {
+ OUString aValue1, aValue2;
+ ConversionHelper::separatePair( aValue1, aValue2, oValue.get(), ',' );
+ oRetValue = DoublePair(
+ ConversionHelper::decodePercent( aValue1, 0.0 ),
+ ConversionHelper::decodePercent( aValue2, 0.0 ) );
+ }
+ return oRetValue;
+}
+
+/** Returns the boolean value from the passed string of an attribute in the x:
+ namespace (VML for spreadsheets). Supported values: f, t, False, True.
+ @param bDefaultForEmpty Default value for the empty string.
+ */
+bool lclDecodeVmlxBool( const OUString& rValue, bool bDefaultForEmpty )
+{
+ if( rValue.getLength() == 0 ) return bDefaultForEmpty;
+ sal_Int32 nToken = AttributeConversion::decodeToken( rValue );
+ // anything else than 't' or 'True' is considered to be false, as specified
+ return (nToken == XML_t) || (nToken == XML_True);
+}
+
+} // namespace
+
+// ============================================================================
+
+ShapeLayoutContext::ShapeLayoutContext( ContextHandler2Helper& rParent, Drawing& rDrawing ) :
+ ContextHandler2( rParent ),
+ mrDrawing( rDrawing )
+{
+}
+
+
+ContextHandlerRef ShapeLayoutContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( nElement )
+ {
+ case O_TOKEN( idmap ):
+ {
+ OUString aBlockIds = rAttribs.getString( XML_data, OUString() );
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ {
+ OUString aToken = aBlockIds.getToken( 0, ' ', nIndex ).trim();
+ if( aToken.getLength() > 0 )
+ mrDrawing.registerBlockId( aToken.toInt32() );
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ClientDataContext::ClientDataContext( ContextHandler2Helper& rParent,
+ ClientData& rClientData, const AttributeList& rAttribs ) :
+ ContextHandler2( rParent ),
+ mrClientData( rClientData )
+{
+ mrClientData.mnObjType = rAttribs.getToken( XML_ObjectType, XML_TOKEN_INVALID );
+}
+
+ContextHandlerRef ClientDataContext::onCreateContext( sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ )
+{
+ if( isRootElement() )
+ {
+ maElementText = OUString();
+ return this;
+ }
+ return 0;
+}
+
+void ClientDataContext::onCharacters( const OUString& rChars )
+{
+ /* Empty but existing elements have special meaning, e.g. 'true'. Collect
+ existing text and convert it in onEndElement(). */
+ maElementText = rChars;
+}
+
+void ClientDataContext::onEndElement()
+{
+ switch( getCurrentElement() )
+ {
+ case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = maElementText; break;
+ case VMLX_TOKEN( FmlaMacro ): mrClientData.maFmlaMacro = maElementText; break;
+ case VMLX_TOKEN( FmlaPict ): mrClientData.maFmlaPict = maElementText; break;
+ case VMLX_TOKEN( FmlaLink ): mrClientData.maFmlaLink = maElementText; break;
+ case VMLX_TOKEN( FmlaRange ): mrClientData.maFmlaRange = maElementText; break;
+ case VMLX_TOKEN( FmlaGroup ): mrClientData.maFmlaGroup = maElementText; break;
+ case VMLX_TOKEN( TextHAlign ): mrClientData.mnTextHAlign = AttributeConversion::decodeToken( maElementText ); break;
+ case VMLX_TOKEN( TextVAlign ): mrClientData.mnTextVAlign = AttributeConversion::decodeToken( maElementText ); break;
+ case VMLX_TOKEN( Column ): mrClientData.mnCol = maElementText.toInt32(); break;
+ case VMLX_TOKEN( Row ): mrClientData.mnRow = maElementText.toInt32(); break;
+ case VMLX_TOKEN( Checked ): mrClientData.mnChecked = maElementText.toInt32(); break;
+ case VMLX_TOKEN( DropStyle ): mrClientData.mnDropStyle = AttributeConversion::decodeToken( maElementText ); break;
+ case VMLX_TOKEN( DropLines ): mrClientData.mnDropLines = maElementText.toInt32(); break;
+ case VMLX_TOKEN( Val ): mrClientData.mnVal = maElementText.toInt32(); break;
+ case VMLX_TOKEN( Min ): mrClientData.mnMin = maElementText.toInt32(); break;
+ case VMLX_TOKEN( Max ): mrClientData.mnMax = maElementText.toInt32(); break;
+ case VMLX_TOKEN( Inc ): mrClientData.mnInc = maElementText.toInt32(); break;
+ case VMLX_TOKEN( Page ): mrClientData.mnPage = maElementText.toInt32(); break;
+ case VMLX_TOKEN( SelType ): mrClientData.mnSelType = AttributeConversion::decodeToken( maElementText ); break;
+ case VMLX_TOKEN( VTEdit ): mrClientData.mnVTEdit = maElementText.toInt32(); break;
+ case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeVmlxBool( maElementText, true ); break;
+ case VMLX_TOKEN( Visible ): mrClientData.mbVisible = lclDecodeVmlxBool( maElementText, true ); break;
+ case VMLX_TOKEN( DDE ): mrClientData.mbDde = lclDecodeVmlxBool( maElementText, true ); break;
+ case VMLX_TOKEN( NoThreeD ): mrClientData.mbNo3D = lclDecodeVmlxBool( maElementText, true ); break;
+ case VMLX_TOKEN( NoThreeD2 ): mrClientData.mbNo3D2 = lclDecodeVmlxBool( maElementText, true ); break;
+ case VMLX_TOKEN( MultiLine ): mrClientData.mbMultiLine = lclDecodeVmlxBool( maElementText, true ); break;
+ case VMLX_TOKEN( VScroll ): mrClientData.mbVScroll = lclDecodeVmlxBool( maElementText, true ); break;
+ case VMLX_TOKEN( SecretEdit ): mrClientData.mbSecretEdit = lclDecodeVmlxBool( maElementText, true ); break;
+ }
+}
+
+// ============================================================================
+
+ShapeContextBase::ShapeContextBase( ContextHandler2Helper& rParent ) :
+ ContextHandler2( rParent )
+{
+}
+
+/*static*/ ContextHandlerRef ShapeContextBase::createShapeContext( ContextHandler2Helper& rParent,
+ ShapeContainer& rShapes, sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( nElement )
+ {
+ case O_TOKEN( shapelayout ):
+ return new ShapeLayoutContext( rParent, rShapes.getDrawing() );
+
+ case VML_TOKEN( shapetype ):
+ return new ShapeTypeContext( rParent, rShapes.createShapeType(), rAttribs );
+ case VML_TOKEN( group ):
+ return new GroupShapeContext( rParent, rShapes.createShape< GroupShape >(), rAttribs );
+ case VML_TOKEN( shape ):
+ return new ShapeContext( rParent, rShapes.createShape< ComplexShape >(), rAttribs );
+ case VML_TOKEN( rect ):
+ case VML_TOKEN( roundrect ):
+ return new ShapeContext( rParent, rShapes.createShape< RectangleShape >(), rAttribs );
+ case VML_TOKEN( oval ):
+ return new ShapeContext( rParent, rShapes.createShape< EllipseShape >(), rAttribs );
+ case VML_TOKEN( polyline ):
+ return new ShapeContext( rParent, rShapes.createShape< PolyLineShape >(), rAttribs );
+
+ // TODO:
+ case VML_TOKEN( arc ):
+ case VML_TOKEN( curve ):
+ case VML_TOKEN( line ):
+ case VML_TOKEN( diagram ):
+ case VML_TOKEN( image ):
+ return new ShapeContext( rParent, rShapes.createShape< ComplexShape >(), rAttribs );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, ShapeType& rShapeType, const AttributeList& rAttribs ) :
+ ShapeContextBase( rParent ),
+ mrTypeModel( rShapeType.getTypeModel() )
+{
+ // shape identifier and shape name
+ bool bHasOspid = rAttribs.hasAttribute( O_TOKEN( spid ) );
+ mrTypeModel.maShapeId = rAttribs.getXString( bHasOspid ? O_TOKEN( spid ) : XML_id, OUString() );
+ OSL_ENSURE( mrTypeModel.maShapeId.getLength() > 0, "ShapeTypeContext::ShapeTypeContext - missing shape identifier" );
+ // if the o:spid attribute exists, the id attribute contains the user-defined shape name
+ if( bHasOspid )
+ mrTypeModel.maShapeName = rAttribs.getXString( XML_id, OUString() );
+ // builtin shape type identifier
+ mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) );
+
+ // coordinate system position/size, CSS style
+ mrTypeModel.moCoordPos = lclDecodeInt32Pair( rAttribs, XML_coordorigin );
+ mrTypeModel.moCoordSize = lclDecodeInt32Pair( rAttribs, XML_coordsize );
+ setStyle( rAttribs.getString( XML_style, OUString() ) );
+
+ // stroke settings (may be overridden by v:stroke element later)
+ mrTypeModel.maStrokeModel.moStroked = lclDecodeBool( rAttribs, XML_stroked );
+ mrTypeModel.maStrokeModel.moColor = rAttribs.getString( XML_strokecolor );
+ mrTypeModel.maStrokeModel.moWeight = rAttribs.getString( XML_strokeweight );
+
+ // fill settings (may be overridden by v:fill element later)
+ mrTypeModel.maFillModel.moFilled = lclDecodeBool( rAttribs, XML_filled );
+ mrTypeModel.maFillModel.moColor = rAttribs.getString( XML_fillcolor );
+}
+
+ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case VML_TOKEN( stroke ):
+ mrTypeModel.maStrokeModel.moStroked.assignIfUsed( lclDecodeBool( rAttribs, XML_on ) );
+ mrTypeModel.maStrokeModel.maStartArrow.moArrowType = rAttribs.getToken( XML_startarrow );
+ mrTypeModel.maStrokeModel.maStartArrow.moArrowWidth = rAttribs.getToken( XML_startarrowwidth );
+ mrTypeModel.maStrokeModel.maStartArrow.moArrowLength = rAttribs.getToken( XML_startarrowlength );
+ mrTypeModel.maStrokeModel.maEndArrow.moArrowType = rAttribs.getToken( XML_endarrow );
+ mrTypeModel.maStrokeModel.maEndArrow.moArrowWidth = rAttribs.getToken( XML_endarrowwidth );
+ mrTypeModel.maStrokeModel.maEndArrow.moArrowLength = rAttribs.getToken( XML_endarrowlength );
+ mrTypeModel.maStrokeModel.moColor.assignIfUsed( rAttribs.getString( XML_color ) );
+ mrTypeModel.maStrokeModel.moOpacity = lclDecodePercent( rAttribs, XML_opacity, 1.0 );
+ mrTypeModel.maStrokeModel.moWeight.assignIfUsed( rAttribs.getString( XML_weight ) );
+ mrTypeModel.maStrokeModel.moDashStyle = rAttribs.getString( XML_dashstyle );
+ mrTypeModel.maStrokeModel.moLineStyle = rAttribs.getToken( XML_linestyle );
+ mrTypeModel.maStrokeModel.moEndCap = rAttribs.getToken( XML_endcap );
+ mrTypeModel.maStrokeModel.moJoinStyle = rAttribs.getToken( XML_joinstyle );
+ break;
+ case VML_TOKEN( fill ):
+ mrTypeModel.maFillModel.moFilled.assignIfUsed( lclDecodeBool( rAttribs, XML_on ) );
+ mrTypeModel.maFillModel.moColor.assignIfUsed( rAttribs.getString( XML_color ) );
+ mrTypeModel.maFillModel.moOpacity = lclDecodePercent( rAttribs, XML_opacity, 1.0 );
+ mrTypeModel.maFillModel.moColor2 = rAttribs.getString( XML_color2 );
+ mrTypeModel.maFillModel.moOpacity2 = lclDecodePercent( rAttribs, XML_opacity2, 1.0 );
+ mrTypeModel.maFillModel.moType = rAttribs.getToken( XML_type );
+ mrTypeModel.maFillModel.moAngle = rAttribs.getInteger( XML_angle );
+ mrTypeModel.maFillModel.moFocus = lclDecodePercent( rAttribs, XML_focus, 0.0 );
+ mrTypeModel.maFillModel.moFocusPos = lclDecodePercentPair( rAttribs, XML_focusposition );
+ mrTypeModel.maFillModel.moFocusSize = lclDecodePercentPair( rAttribs, XML_focussize );
+ mrTypeModel.maFillModel.moBitmapPath = decodeFragmentPath( rAttribs, O_TOKEN( relid ) );
+ mrTypeModel.maFillModel.moRotate = lclDecodeBool( rAttribs, XML_rotate );
+ break;
+ case VML_TOKEN( imagedata ):
+ mrTypeModel.moGraphicPath = decodeFragmentPath( rAttribs, O_TOKEN( relid ) );
+ mrTypeModel.moGraphicTitle = rAttribs.getString( O_TOKEN( title ) );
+ break;
+ }
+ return 0;
+}
+
+OptValue< OUString > ShapeTypeContext::decodeFragmentPath( const AttributeList& rAttribs, sal_Int32 nToken ) const
+{
+ OptValue< OUString > oFragmentPath;
+ OptValue< OUString > oRelId = rAttribs.getString( nToken );
+ if( oRelId.has() )
+ oFragmentPath = getFragmentPathFromRelId( oRelId.get() );
+ return oFragmentPath;
+}
+
+void ShapeTypeContext::setStyle( const OUString& rStyle )
+{
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ {
+ OUString aName, aValue;
+ if( ConversionHelper::separatePair( aName, aValue, rStyle.getToken( 0, ';', nIndex ), ':' ) )
+ {
+ if( aName.equalsAscii( "position" ) ) mrTypeModel.maPosition = aValue;
+ else if( aName.equalsAscii( "left" ) ) mrTypeModel.maLeft = aValue;
+ else if( aName.equalsAscii( "top" ) ) mrTypeModel.maTop = aValue;
+ else if( aName.equalsAscii( "width" ) ) mrTypeModel.maWidth = aValue;
+ else if( aName.equalsAscii( "height" ) ) mrTypeModel.maHeight = aValue;
+ else if( aName.equalsAscii( "margin-left" ) ) mrTypeModel.maMarginLeft = aValue;
+ else if( aName.equalsAscii( "margin-top" ) ) mrTypeModel.maMarginTop = aValue;
+ }
+ }
+}
+
+// ============================================================================
+
+ShapeContext::ShapeContext( ContextHandler2Helper& rParent, ShapeBase& rShape, const AttributeList& rAttribs ) :
+ ShapeTypeContext( rParent, rShape, rAttribs ),
+ mrShapeModel( rShape.getShapeModel() )
+{
+ // collect shape specific attributes
+ mrShapeModel.maType = rAttribs.getXString( XML_type, OUString() );
+ // polyline path
+ setPoints( rAttribs.getString( XML_points, OUString() ) );
+}
+
+ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ // Excel specific shape client data
+ if( isRootElement() ) switch( nElement )
+ {
+ case VML_TOKEN( textbox ):
+ return new TextBoxContext( *this, mrShapeModel.createTextBox(), rAttribs );
+ case VMLX_TOKEN( ClientData ):
+ return new ClientDataContext( *this, mrShapeModel.createClientData(), rAttribs );
+ }
+ // handle remaining stuff in base class
+ return ShapeTypeContext::onCreateContext( nElement, rAttribs );
+}
+
+void ShapeContext::setPoints( const OUString& rPoints )
+{
+ mrShapeModel.maPoints.clear();
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ {
+ sal_Int32 nX = rPoints.getToken( 0, ',', nIndex ).toInt32();
+ sal_Int32 nY = rPoints.getToken( 0, ',', nIndex ).toInt32();
+ mrShapeModel.maPoints.push_back( Point( nX, nY ) );
+ }
+}
+
+// ============================================================================
+
+GroupShapeContext::GroupShapeContext( ContextHandler2Helper& rParent, GroupShape& rShape, const AttributeList& rAttribs ) :
+ ShapeContext( rParent, rShape, rAttribs ),
+ mrShapes( rShape.getChildren() )
+{
+}
+
+ContextHandlerRef GroupShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ // try to create a context of an embedded shape
+ ContextHandlerRef xContext = createShapeContext( *this, mrShapes, nElement, rAttribs );
+ // handle remaining stuff of this shape in base class
+ return xContext.get() ? xContext : ShapeContext::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx
new file mode 100755
index 000000000000..f56eb387d5b2
--- /dev/null
+++ b/oox/source/vml/vmltextbox.cxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmltextbox.hxx"
+
+#include <rtl/ustrbuf.hxx>
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+TextFontModel::TextFontModel()
+{
+}
+
+// ============================================================================
+
+TextPortionModel::TextPortionModel( const TextFontModel& rFont, const OUString& rText ) :
+ maFont( rFont ),
+ maText( rText )
+{
+}
+
+// ============================================================================
+
+TextBox::TextBox()
+{
+}
+
+void TextBox::appendPortion( const TextFontModel& rFont, const OUString& rText )
+{
+ maPortions.push_back( TextPortionModel( rFont, rText ) );
+}
+
+const TextFontModel* TextBox::getFirstFont() const
+{
+ return maPortions.empty() ? 0 : &maPortions.front().maFont;
+}
+
+OUString TextBox::getText() const
+{
+ OUStringBuffer aBuffer;
+ for( PortionVector::const_iterator aIt = maPortions.begin(), aEnd = maPortions.end(); aIt != aEnd; ++aIt )
+ aBuffer.append( aIt->maText );
+ return aBuffer.makeStringAndClear();
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx
new file mode 100755
index 000000000000..4b57656b4f78
--- /dev/null
+++ b/oox/source/vml/vmltextboxcontext.cxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmltextboxcontext.hxx"
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+using ::oox::core::ContextHandler2;
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
+ TextBox& rTextBox, const TextFontModel& rParentFont,
+ sal_Int32 nElement, const AttributeList& rAttribs ) :
+ ContextHandler2( rParent ),
+ mrTextBox( rTextBox ),
+ maFont( rParentFont ),
+ mnInitialPortions( rTextBox.getPortionCount() )
+{
+ switch( nElement )
+ {
+ case XML_font:
+ maFont.moName = rAttribs.getXString( XML_face );
+ maFont.moColor = rAttribs.getXString( XML_color );
+ maFont.monSize = rAttribs.getInteger( XML_size );
+ break;
+ case XML_u:
+ OSL_ENSURE( !maFont.monUnderline, "TextPortionContext::TextPortionContext - nested <u> elements" );
+ maFont.monUnderline = (rAttribs.getToken( XML_class, XML_TOKEN_INVALID ) == XML_font4) ? XML_double : XML_single;
+ break;
+ case XML_sub:
+ case XML_sup:
+ OSL_ENSURE( !maFont.monEscapement, "TextPortionContext::TextPortionContext - nested <sub> or <sup> elements" );
+ maFont.monEscapement = nElement;
+ break;
+ case XML_b:
+ OSL_ENSURE( !maFont.mobBold, "TextPortionContext::TextPortionContext - nested <b> elements" );
+ maFont.mobBold = true;
+ break;
+ case XML_i:
+ OSL_ENSURE( !maFont.mobItalic, "TextPortionContext::TextPortionContext - nested <i> elements" );
+ maFont.mobItalic = true;
+ break;
+ case XML_s:
+ OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" );
+ maFont.mobStrikeout = true;
+ break;
+ default:
+ OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" );
+ }
+}
+
+ContextHandlerRef TextPortionContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ OSL_ENSURE( nElement != XML_font, "TextPortionContext::onCreateContext - nested <font> elements" );
+ return new TextPortionContext( *this, mrTextBox, maFont, nElement, rAttribs );
+}
+
+void TextPortionContext::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_span:
+ // replace all NBSP characters with SP
+ mrTextBox.appendPortion( maFont, rChars.replace( 160, ' ' ) );
+ break;
+ default:
+ mrTextBox.appendPortion( maFont, rChars );
+ }
+}
+
+void TextPortionContext::onEndElement()
+{
+ /* An empty child element without own child elements represents a single
+ space character, for example:
+
+ <font>
+ <i>abc</i>
+ <font></font>
+ <b>def</b>
+ </font>
+
+ represents the italic text 'abc', an unformatted space character, and
+ the bold text 'def'.
+ */
+ if( (mnInitialPortions > 0) && (mrTextBox.getPortionCount() == mnInitialPortions) )
+ mrTextBox.appendPortion( maFont, OUString( sal_Unicode( ' ' ) ) );
+}
+
+// ============================================================================
+
+TextBoxContext::TextBoxContext( ContextHandler2Helper& rParent, TextBox& rTextBox, const AttributeList& /*rAttribs*/ ) :
+ ContextHandler2( rParent ),
+ mrTextBox( rTextBox )
+{
+}
+
+ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case VML_TOKEN( textbox ):
+ if( nElement == XML_div ) return this;
+ break;
+ case XML_div:
+ if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs );
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
diff --git a/oox/source/xls/addressconverter.cxx b/oox/source/xls/addressconverter.cxx
new file mode 100644
index 000000000000..6d53be0c155b
--- /dev/null
+++ b/oox/source/xls/addressconverter.cxx
@@ -0,0 +1,783 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/addressconverter.hxx"
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <osl/diagnose.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/biffoutputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OUStringToOString;
+
+// ============================================================================
+
+namespace {
+
+//! TODO: this limit may change, is there a way to obtain it via API?
+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_LIBRARY = '\x08'; /// Library directory in application installation.
+const sal_Unicode BIFF4_URL_SHEET = '\x09'; /// BIFF4 internal sheet.
+const sal_Unicode BIFF_URL_UNC = '@'; /// UNC path root.
+
+const sal_Unicode BIFF_DCON_ENCODED = '\x01'; /// First character of an encoded path from DCON* records.
+const sal_Unicode BIFF_DCON_INTERN = '\x02'; /// First character of an encoded sheet name from DCON* records.
+
+
+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( SequenceInputStream& 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( SequenceInputStream& 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( SequenceInputStream& rStrm )
+{
+ sal_Int32 nCount = rStrm.readInt32();
+ resize( getLimitedValue< size_t, sal_Int64 >( nCount, 0, rStrm.getRemaining() / 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_Int64 >( nCount, 0, rStrm.getRemaining() / 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 ),
+ mbColOverflow( false ),
+ mbRowOverflow( false ),
+ mbTabOverflow( false )
+{
+ maDConChars.set( 0xFFFF, '\x01', 0xFFFF, '\x02', 0xFFFF );
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ initializeMaxPos( OOX_MAXTAB, OOX_MAXCOL, OOX_MAXROW );
+ break;
+ case FILTER_BIFF: switch( getBiff() )
+ {
+ case BIFF2:
+ initializeMaxPos( BIFF2_MAXTAB, BIFF2_MAXCOL, BIFF2_MAXROW );
+ maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, 0xFFFF );
+ break;
+ case BIFF3:
+ initializeMaxPos( BIFF3_MAXTAB, BIFF3_MAXCOL, BIFF3_MAXROW );
+ maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, 0xFFFF );
+ break;
+ case BIFF4:
+ initializeMaxPos( BIFF4_MAXTAB, BIFF4_MAXCOL, BIFF4_MAXROW );
+ maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, '\x00' );
+ break;
+ case BIFF5:
+ initializeMaxPos( BIFF5_MAXTAB, BIFF5_MAXCOL, BIFF5_MAXROW );
+ maLinkChars.set( '\x04', '\x01', '\x02', '\x03', '\x00' );
+ break;
+ case BIFF8:
+ initializeMaxPos( BIFF8_MAXTAB, BIFF8_MAXCOL, BIFF8_MAXROW );
+ maLinkChars.set( '\x04', '\x01', 0xFFFF, '\x02', '\x00' );
+ 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
+
+BiffTargetType AddressConverter::parseBiffTargetUrl(
+ OUString& orClassName, OUString& orTargetUrl, OUString& orSheetName,
+ const OUString& rBiffTargetUrl, bool bFromDConRec )
+{
+ OUStringBuffer aTargetUrl;
+ OUStringBuffer aSheetName;
+ // default target type: some URL with/without sheet name, may be overridden below
+ BiffTargetType eTargetType = BIFF_TARGETTYPE_URL;
+ const ControlCharacters& rCChars = bFromDConRec ? maDConChars : maLinkChars;
+
+ 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 )
+ {
+ sal_Unicode cChar = *pcChar;
+ switch( eState )
+ {
+ case STATE_START:
+ if( (cChar == rCChars.mcThisWorkbook) || (cChar == rCChars.mcThisSheet) || (cChar == rCChars.mcSameSheet) )
+ {
+ if( pcChar + 1 < pcEnd )
+ eState = STATE_ERROR;
+ if( cChar == rCChars.mcSameSheet )
+ eTargetType = BIFF_TARGETTYPE_SAMESHEET;
+ }
+ else if( cChar == rCChars.mcExternal )
+ eState = (pcChar + 1 < pcEnd) ? STATE_ENCODED_PATH_START : STATE_ERROR;
+ else if( cChar == rCChars.mcInternal )
+ 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_LIBRARY )
+ {
+ eState = STATE_ENCODED_PATH;
+ eTargetType = BIFF_TARGETTYPE_LIBRARY;
+ }
+ 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 = bFromDConRec ? STATE_ERROR : STATE_DDE_OLE;
+ eTargetType = BIFF_TARGETTYPE_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;
+ }
+ }
+
+ OSL_ENSURE( (eState != STATE_ERROR) && (pcChar == pcEnd),
+ OStringBuffer( "AddressConverter::parseBiffTargetUrl - parser error in target \"" ).
+ append( OUStringToOString( rBiffTargetUrl, RTL_TEXTENCODING_UTF8 ) ).append( '"' ).getStr() );
+ bool bParserOk = (eState != STATE_ERROR) && (eState != STATE_UNSUPPORTED) && (pcChar == pcEnd);
+
+ if( bParserOk )
+ {
+ orTargetUrl = aTargetUrl.makeStringAndClear();
+ orSheetName = aSheetName.makeStringAndClear();
+ }
+ else
+ {
+ orClassName = orTargetUrl = orSheetName = OUString();
+ }
+
+ return bParserOk ? eTargetType : BIFF_TARGETTYPE_UNKNOWN;
+}
+
+// ----------------------------------------------------------------------------
+
+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::convertToCellAddressUnchecked( 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
+ convertToCellAddressUnchecked( 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::convertToCellAddressUnchecked( 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 )
+{
+ convertToCellAddressUnchecked( 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 bAllowOverflow, bool bTrackOverflow )
+{
+ return
+ (checkCol( rRange.EndColumn, bTrackOverflow ) || bAllowOverflow) && // bAllowOverflow after checkCol to track overflow!
+ (checkRow( rRange.EndRow, bTrackOverflow ) || bAllowOverflow) && // bAllowOverflow after checkRow to track overflow!
+ checkTab( rRange.Sheet, bTrackOverflow ) &&
+ checkCol( rRange.StartColumn, bTrackOverflow ) &&
+ checkRow( rRange.StartRow, bTrackOverflow );
+}
+
+bool AddressConverter::validateCellRange( CellRangeAddress& orRange, bool bAllowOverflow, 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, bAllowOverflow, 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 bAllowOverflow, bool bTrackOverflow )
+{
+ return
+ convertToCellRangeUnchecked( orRange, rString, nSheet ) &&
+ validateCellRange( orRange, bAllowOverflow, 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 bAllowOverflow, bool bTrackOverflow )
+{
+ convertToCellRangeUnchecked( orRange, rBinRange, nSheet );
+ return validateCellRange( orRange, bAllowOverflow, bTrackOverflow );
+}
+
+// ----------------------------------------------------------------------------
+
+bool AddressConverter::checkCellRangeList( const ApiCellRangeList& rRanges, bool bAllowOverflow, bool bTrackOverflow )
+{
+ for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt )
+ if( !checkCellRange( *aIt, bAllowOverflow, 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 ], true, 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, true, 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, true, bTrackOverflow ) )
+ orRanges.push_back( aRange );
+}
+
+// private --------------------------------------------------------------------
+
+void AddressConverter::ControlCharacters::set(
+ sal_Unicode cThisWorkbook, sal_Unicode cExternal,
+ sal_Unicode cThisSheet, sal_Unicode cInternal, sal_Unicode cSameSheet )
+{
+ mcThisWorkbook = cThisWorkbook;
+ mcExternal = cExternal;
+ mcThisSheet = cThisSheet;
+ mcInternal = cInternal;
+ mcSameSheet = cSameSheet;
+}
+
+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" );
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/autofilterbuffer.cxx b/oox/source/xls/autofilterbuffer.cxx
new file mode 100755
index 000000000000..7cf359f6d3c9
--- /dev/null
+++ b/oox/source/xls/autofilterbuffer.cxx
@@ -0,0 +1,853 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/autofilterbuffer.hxx"
+
+#include <com/sun/star/sheet/FilterConnection.hpp>
+#include <com/sun/star/sheet/FilterOperator2.hpp>
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt8 BIFF12_TOP10FILTER_TOP = 0x01;
+const sal_uInt8 BIFF12_TOP10FILTER_PERCENT = 0x02;
+
+const sal_uInt16 BIFF12_FILTERCOLUMN_HIDDENBUTTON = 0x0001;
+const sal_uInt16 BIFF12_FILTERCOLUMN_SHOWBUTTON = 0x0002;
+
+const sal_uInt16 BIFF_FILTERCOLUMN_OR = 0x0001;
+const sal_uInt16 BIFF_FILTERCOLUMN_TOP10FILTER = 0x0010;
+const sal_uInt16 BIFF_FILTERCOLUMN_TOP = 0x0020;
+const sal_uInt16 BIFF_FILTERCOLUMN_PERCENT = 0x0040;
+
+const sal_uInt8 BIFF_FILTER_DATATYPE_NONE = 0;
+const sal_uInt8 BIFF_FILTER_DATATYPE_RK = 2;
+const sal_uInt8 BIFF_FILTER_DATATYPE_DOUBLE = 4;
+const sal_uInt8 BIFF_FILTER_DATATYPE_STRING = 6;
+const sal_uInt8 BIFF_FILTER_DATATYPE_BOOLEAN = 8;
+const sal_uInt8 BIFF_FILTER_DATATYPE_EMPTY = 12;
+const sal_uInt8 BIFF_FILTER_DATATYPE_NOTEMPTY = 14;
+
+// ----------------------------------------------------------------------------
+
+bool lclGetApiOperatorFromToken( sal_Int32& rnApiOperator, sal_Int32 nToken )
+{
+ switch( nToken )
+ {
+ case XML_lessThan: rnApiOperator = FilterOperator2::NOT_EQUAL; return true;
+ case XML_equal: rnApiOperator = FilterOperator2::EQUAL; return true;
+ case XML_lessThanOrEqual: rnApiOperator = FilterOperator2::LESS_EQUAL; return true;
+ case XML_greaterThan: rnApiOperator = FilterOperator2::GREATER; return true;
+ case XML_notEqual: rnApiOperator = FilterOperator2::NOT_EQUAL; return true;
+ case XML_greaterThanOrEqual: rnApiOperator = FilterOperator2::GREATER_EQUAL; return true;
+ }
+ return false;
+}
+
+/** Removes leading asterisk characters from the passed string.
+ @return True = at least one asterisk character has been removed. */
+bool lclTrimLeadingAsterisks( OUString& rValue )
+{
+ sal_Int32 nLength = rValue.getLength();
+ sal_Int32 nPos = 0;
+ while( (nPos < nLength) && (rValue[ nPos ] == '*') )
+ ++nPos;
+ if( nPos > 0 )
+ {
+ rValue = rValue.copy( nPos );
+ return true;
+ }
+ return false;
+}
+
+/** Removes trailing asterisk characters from the passed string.
+ @return True = at least one asterisk character has been removed. */
+bool lclTrimTrailingAsterisks( OUString& rValue )
+{
+ sal_Int32 nLength = rValue.getLength();
+ sal_Int32 nPos = nLength;
+ while( (nPos > 0) && (rValue[ nPos - 1 ] == '*') )
+ --nPos;
+ if( nPos < nLength )
+ {
+ rValue = rValue.copy( 0, nPos );
+ return true;
+ }
+ return false;
+}
+
+/** Converts wildcard characters '*' and '?' to regular expressions and quotes
+ RE meta characters.
+ @return True = passed string has been changed (RE needs to be enabled). */
+bool lclConvertWildcardsToRegExp( OUString& rValue )
+{
+ // check existence of the wildcard characters '*' and '?'
+ if( (rValue.getLength() > 0) && ((rValue.indexOf( '*' ) >= 0) || (rValue.indexOf( '?' ) >= 0)) )
+ {
+ OUStringBuffer aBuffer;
+ aBuffer.ensureCapacity( rValue.getLength() + 5 );
+ const sal_Unicode* pcChar = rValue.getStr();
+ const sal_Unicode* pcEnd = pcChar + rValue.getLength();
+ for( ; pcChar < pcEnd; ++pcChar )
+ {
+ switch( *pcChar )
+ {
+ case '?':
+ aBuffer.append( sal_Unicode( '.' ) );
+ break;
+ case '*':
+ aBuffer.append( sal_Unicode( '.' ) ).append( sal_Unicode( '*' ) );
+ break;
+ case '\\': case '.': case '|': case '(': case ')': case '^': case '$':
+ // quote RE meta characters
+ aBuffer.append( sal_Unicode( '\\' ) ).append( *pcChar );
+ break;
+ default:
+ aBuffer.append( *pcChar );
+ }
+ }
+ rValue = aBuffer.makeStringAndClear();
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+// ============================================================================
+
+ApiFilterSettings::ApiFilterSettings()
+{
+}
+
+void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, double fValue )
+{
+ maFilterFields.resize( maFilterFields.size() + 1 );
+ TableFilterField2& rFilterField = maFilterFields.back();
+ rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
+ rFilterField.Operator = nOperator;
+ rFilterField.IsNumeric = sal_True;
+ rFilterField.NumericValue = fValue;
+}
+
+void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, const OUString& rValue )
+{
+ maFilterFields.resize( maFilterFields.size() + 1 );
+ TableFilterField2& rFilterField = maFilterFields.back();
+ rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
+ rFilterField.Operator = nOperator;
+ rFilterField.IsNumeric = sal_False;
+ rFilterField.StringValue = rValue;
+}
+
+// ============================================================================
+
+FilterSettingsBase::FilterSettingsBase( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void FilterSettingsBase::importAttribs( sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ )
+{
+}
+
+void FilterSettingsBase::importRecord( sal_Int32 /*nRecId*/, SequenceInputStream& /*rStrm*/ )
+{
+}
+
+void FilterSettingsBase::importBiffRecord( BiffInputStream& /*rStrm*/, sal_uInt16 /*nFlags*/ )
+{
+}
+
+ApiFilterSettings FilterSettingsBase::finalizeImport( sal_Int32 /*nMaxCount*/ )
+{
+ return ApiFilterSettings();
+}
+
+// ============================================================================
+
+DiscreteFilter::DiscreteFilter( const WorkbookHelper& rHelper ) :
+ FilterSettingsBase( rHelper ),
+ mnCalendarType( XML_none ),
+ mbShowBlank( false )
+{
+}
+
+void DiscreteFilter::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( filters ):
+ mnCalendarType = rAttribs.getToken( XML_calendarType, XML_none );
+ mbShowBlank = rAttribs.getBool( XML_blank, false );
+ break;
+
+ case XLS_TOKEN( filter ):
+ {
+ OUString aValue = rAttribs.getXString( XML_val, OUString() );
+ if( aValue.getLength() > 0 )
+ maValues.push_back( aValue );
+ }
+ break;
+ }
+}
+
+void DiscreteFilter::importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( nRecId )
+ {
+ case BIFF12_ID_DISCRETEFILTERS:
+ {
+ sal_Int32 nShowBlank, nCalendarType;
+ rStrm >> nShowBlank >> nCalendarType;
+
+ static const sal_Int32 spnCalendarTypes[] = {
+ XML_none, XML_gregorian, XML_gregorianUs, XML_japan, XML_taiwan, XML_korea, XML_hijri, XML_thai, XML_hebrew,
+ XML_gregorianMeFrench, XML_gregorianArabic, XML_gregorianXlitEnglish, XML_gregorianXlitFrench };
+ mnCalendarType = STATIC_ARRAY_SELECT( spnCalendarTypes, nCalendarType, XML_none );
+ mbShowBlank = nShowBlank != 0;
+ }
+ break;
+
+ case BIFF12_ID_DISCRETEFILTER:
+ {
+ OUString aValue = BiffHelper::readString( rStrm );
+ if( aValue.getLength() > 0 )
+ maValues.push_back( aValue );
+ }
+ break;
+ }
+}
+
+ApiFilterSettings DiscreteFilter::finalizeImport( sal_Int32 nMaxCount )
+{
+ ApiFilterSettings aSettings;
+ if( static_cast< sal_Int32 >( maValues.size() ) <= nMaxCount )
+ {
+ aSettings.maFilterFields.reserve( maValues.size() );
+
+ // insert all filter values
+ for( FilterValueVector::iterator aIt = maValues.begin(), aEnd = maValues.end(); aIt != aEnd; ++aIt )
+ aSettings.appendField( false, FilterOperator2::EQUAL, *aIt );
+
+ // extra field for 'show empty'
+ if( mbShowBlank )
+ aSettings.appendField( false, FilterOperator2::EMPTY, OUString() );
+
+ /* Require disabled regular expressions, filter entries may contain
+ any RE meta characters. */
+ if( !maValues.empty() )
+ aSettings.mobNeedsRegExp = false;
+ }
+ return aSettings;
+}
+
+// ============================================================================
+
+Top10Filter::Top10Filter( const WorkbookHelper& rHelper ) :
+ FilterSettingsBase( rHelper ),
+ mfValue( 0.0 ),
+ mbTop( true ),
+ mbPercent( false )
+{
+}
+
+void Top10Filter::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( nElement == XLS_TOKEN( top10 ) )
+ {
+ mfValue = rAttribs.getDouble( XML_val, 0.0 );
+ mbTop = rAttribs.getBool( XML_top, true );
+ mbPercent = rAttribs.getBool( XML_percent, false );
+ }
+}
+
+void Top10Filter::importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ if( nRecId == BIFF12_ID_TOP10FILTER )
+ {
+ sal_uInt8 nFlags;
+ rStrm >> nFlags >> mfValue;
+ mbTop = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
+ mbPercent = getFlag( nFlags, BIFF12_TOP10FILTER_PERCENT );
+ }
+}
+
+void Top10Filter::importBiffRecord( BiffInputStream& /*rStrm*/, sal_uInt16 nFlags )
+{
+ mfValue = extractValue< sal_uInt16 >( nFlags, 7, 9 );
+ mbTop = getFlag( nFlags, BIFF_FILTERCOLUMN_TOP );
+ mbPercent = getFlag( nFlags, BIFF_FILTERCOLUMN_PERCENT );
+}
+
+ApiFilterSettings Top10Filter::finalizeImport( sal_Int32 /*nMaxCount*/ )
+{
+ sal_Int32 nOperator = mbTop ?
+ (mbPercent ? FilterOperator2::TOP_PERCENT : FilterOperator2::TOP_VALUES) :
+ (mbPercent ? FilterOperator2::BOTTOM_PERCENT : FilterOperator2::BOTTOM_VALUES);
+ ApiFilterSettings aSettings;
+ aSettings.appendField( true, nOperator, mfValue );
+ return aSettings;
+}
+
+// ============================================================================
+
+FilterCriterionModel::FilterCriterionModel() :
+ mnOperator( XML_equal ),
+ mnDataType( BIFF_FILTER_DATATYPE_NONE ),
+ mnStrLen( 0 )
+{
+}
+
+void FilterCriterionModel::setBiffOperator( sal_uInt8 nOperator )
+{
+ static const sal_Int32 spnOperators[] = { XML_TOKEN_INVALID,
+ XML_lessThan, XML_equal, XML_lessThanOrEqual, XML_greaterThan, XML_notEqual, XML_greaterThanOrEqual };
+ mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
+}
+
+void FilterCriterionModel::readBiffData( SequenceInputStream& rStrm )
+{
+ sal_uInt8 nOperator;
+ rStrm >> mnDataType >> nOperator;
+ setBiffOperator( nOperator );
+
+ switch( mnDataType )
+ {
+ case BIFF_FILTER_DATATYPE_DOUBLE:
+ maValue <<= rStrm.readDouble();
+ break;
+ case BIFF_FILTER_DATATYPE_STRING:
+ {
+ rStrm.skip( 8 );
+ OUString aValue = BiffHelper::readString( rStrm ).trim();
+ if( aValue.getLength() > 0 )
+ maValue <<= aValue;
+ }
+ break;
+ case BIFF_FILTER_DATATYPE_BOOLEAN:
+ maValue <<= (rStrm.readuInt8() != 0);
+ rStrm.skip( 7 );
+ break;
+ case BIFF_FILTER_DATATYPE_EMPTY:
+ rStrm.skip( 8 );
+ if( mnOperator == XML_equal )
+ maValue <<= OUString();
+ break;
+ case BIFF_FILTER_DATATYPE_NOTEMPTY:
+ rStrm.skip( 8 );
+ if( mnOperator == XML_notEqual )
+ maValue <<= OUString();
+ break;
+ default:
+ OSL_ENSURE( false, "FilterCriterionModel::readBiffData - unexpected data type" );
+ rStrm.skip( 8 );
+ }
+}
+
+void FilterCriterionModel::readBiffData( BiffInputStream& rStrm )
+{
+ sal_uInt8 nOperator;
+ rStrm >> mnDataType >> nOperator;
+ setBiffOperator( nOperator );
+
+ switch( mnDataType )
+ {
+ case BIFF_FILTER_DATATYPE_NONE:
+ rStrm.skip( 8 );
+ break;
+ case BIFF_FILTER_DATATYPE_RK:
+ maValue <<= BiffHelper::calcDoubleFromRk( rStrm.readInt32() );
+ rStrm.skip( 4 );
+ break;
+ case BIFF_FILTER_DATATYPE_DOUBLE:
+ maValue <<= rStrm.readDouble();
+ break;
+ case BIFF_FILTER_DATATYPE_STRING:
+ rStrm.skip( 4 );
+ rStrm >> mnStrLen;
+ rStrm.skip( 3 );
+ break;
+ case BIFF_FILTER_DATATYPE_BOOLEAN:
+ {
+ sal_uInt8 nValue, nType;
+ rStrm >> nValue >> nType;
+ rStrm.skip( 6 );
+ switch( nType )
+ {
+ case BIFF_BOOLERR_BOOL: maValue <<= (nValue != 0); break;
+ case BIFF_BOOLERR_ERROR: maValue <<= BiffHelper::calcDoubleFromError( nValue ); break;
+ default: OSL_ENSURE( false, "FilterCriterionModel::readBiffData - unknown type" );
+ }
+ }
+ break;
+ case BIFF_FILTER_DATATYPE_EMPTY:
+ rStrm.skip( 8 );
+ if( mnOperator == XML_equal )
+ maValue <<= OUString();
+ break;
+ case BIFF_FILTER_DATATYPE_NOTEMPTY:
+ rStrm.skip( 8 );
+ if( mnOperator == XML_notEqual )
+ maValue <<= OUString();
+ break;
+ default:
+ OSL_ENSURE( false, "FilterCriterionModel::readBiffData - unexpected data type" );
+ rStrm.skip( 8 );
+ }
+}
+
+void FilterCriterionModel::readString( BiffInputStream& rStrm, BiffType eBiff, rtl_TextEncoding eTextEnc )
+{
+ if( (mnDataType == BIFF_FILTER_DATATYPE_STRING) && (mnStrLen > 0) )
+ {
+ OUString aValue = (eBiff == BIFF8) ?
+ rStrm.readUniStringBody( mnStrLen, true ) :
+ rStrm.readCharArrayUC( mnStrLen, eTextEnc, true );
+ aValue = aValue.trim();
+ if( aValue.getLength() > 0 )
+ maValue <<= aValue;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+CustomFilter::CustomFilter( const WorkbookHelper& rHelper ) :
+ FilterSettingsBase( rHelper ),
+ mbAnd( false )
+{
+}
+
+void CustomFilter::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( customFilters ):
+ mbAnd = rAttribs.getBool( XML_and, false );
+ break;
+
+ case XLS_TOKEN( customFilter ):
+ {
+ FilterCriterionModel aCriterion;
+ aCriterion.mnOperator = rAttribs.getToken( XML_operator, XML_equal );
+ OUString aValue = rAttribs.getXString( XML_val, OUString() ).trim();
+ if( (aCriterion.mnOperator == XML_equal) || (aCriterion.mnOperator == XML_notEqual) || (aValue.getLength() > 0) )
+ aCriterion.maValue <<= aValue;
+ appendCriterion( aCriterion );
+ }
+ break;
+ }
+}
+
+void CustomFilter::importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( nRecId )
+ {
+ case BIFF12_ID_CUSTOMFILTERS:
+ mbAnd = rStrm.readInt32() == 0;
+ break;
+
+ case BIFF12_ID_CUSTOMFILTER:
+ {
+ FilterCriterionModel aCriterion;
+ aCriterion.readBiffData( rStrm );
+ appendCriterion( aCriterion );
+ }
+ break;
+ }
+}
+
+void CustomFilter::importBiffRecord( BiffInputStream& rStrm, sal_uInt16 nFlags )
+{
+ mbAnd = !getFlag( nFlags, BIFF_FILTERCOLUMN_OR );
+
+ FilterCriterionModel aCriterion1, aCriterion2;
+ aCriterion1.readBiffData( rStrm );
+ aCriterion2.readBiffData( rStrm );
+ aCriterion1.readString( rStrm, getBiff(), getTextEncoding() );
+ aCriterion2.readString( rStrm, getBiff(), getTextEncoding() );
+ appendCriterion( aCriterion1 );
+ appendCriterion( aCriterion2 );
+}
+
+ApiFilterSettings CustomFilter::finalizeImport( sal_Int32 /*nMaxCount*/ )
+{
+ ApiFilterSettings aSettings;
+ OSL_ENSURE( maCriteria.size() <= 2, "CustomFilter::finalizeImport - too many filter criteria" );
+ for( FilterCriterionVector::iterator aIt = maCriteria.begin(), aEnd = maCriteria.end(); aIt != aEnd; ++aIt )
+ {
+ // first extract the filter operator
+ sal_Int32 nOperator = 0;
+ bool bValidOperator = lclGetApiOperatorFromToken( nOperator, aIt->mnOperator );
+ if( bValidOperator )
+ {
+ if( aIt->maValue.has< OUString >() )
+ {
+ // string argument
+ OUString aValue;
+ aIt->maValue >>= aValue;
+ // check for 'empty', 'contains', 'begins with', or 'ends with' text filters
+ bool bEqual = nOperator == FilterOperator2::EQUAL;
+ bool bNotEqual = nOperator == FilterOperator2::NOT_EQUAL;
+ if( bEqual || bNotEqual )
+ {
+ if( aValue.getLength() == 0 )
+ {
+ // empty comparison string: create empty/not empty filters
+ nOperator = bNotEqual ? FilterOperator2::NOT_EMPTY : FilterOperator2::EMPTY;
+ }
+ else
+ {
+ // compare to something: try to find begins/ends/contains
+ bool bHasLeadingAsterisk = lclTrimLeadingAsterisks( aValue );
+ bool bHasTrailingAsterisk = lclTrimTrailingAsterisks( aValue );
+ // just '***' matches everything, do not create a filter field
+ bValidOperator = aValue.getLength() > 0;
+ if( bValidOperator )
+ {
+ if( bHasLeadingAsterisk && bHasTrailingAsterisk )
+ nOperator = bNotEqual ? FilterOperator2::DOES_NOT_CONTAIN : FilterOperator2::CONTAINS;
+ else if( bHasLeadingAsterisk )
+ nOperator = bNotEqual ? FilterOperator2::DOES_NOT_END_WITH : FilterOperator2::ENDS_WITH;
+ else if( bHasTrailingAsterisk )
+ nOperator = bNotEqual ? FilterOperator2::DOES_NOT_BEGIN_WITH : FilterOperator2::BEGINS_WITH;
+ // else: no asterisks, stick to equal/not equal
+ }
+ }
+ }
+
+ if( bValidOperator )
+ {
+ // if wildcards are present, require RE mode, otherwise keep don't care state
+ if( lclConvertWildcardsToRegExp( aValue ) )
+ aSettings.mobNeedsRegExp = true;
+ // create a new UNO API filter field
+ aSettings.appendField( mbAnd, nOperator, aValue );
+ }
+ }
+ else if( aIt->maValue.has< double >() )
+ {
+ // floating-point argument
+ double fValue = 0.0;
+ aIt->maValue >>= fValue;
+ aSettings.appendField( mbAnd, nOperator, fValue );
+ }
+ }
+ }
+ return aSettings;
+}
+
+void CustomFilter::appendCriterion( const FilterCriterionModel& rCriterion )
+{
+ if( (rCriterion.mnOperator != XML_TOKEN_INVALID) && rCriterion.maValue.hasValue() )
+ maCriteria.push_back( rCriterion );
+}
+
+// ============================================================================
+
+FilterColumn::FilterColumn( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnColId( -1 ),
+ mbHiddenButton( false ),
+ mbShowButton( true )
+{
+}
+
+void FilterColumn::importFilterColumn( const AttributeList& rAttribs )
+{
+ mnColId = rAttribs.getInteger( XML_colId, -1 );
+ mbHiddenButton = rAttribs.getBool( XML_hiddenButton, false );
+ mbShowButton = rAttribs.getBool( XML_showButton, true );
+}
+
+void FilterColumn::importFilterColumn( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> mnColId >> nFlags;
+ mbHiddenButton = getFlag( nFlags, BIFF12_FILTERCOLUMN_HIDDENBUTTON );
+ mbShowButton = getFlag( nFlags, BIFF12_FILTERCOLUMN_SHOWBUTTON );
+}
+
+void FilterColumn::importFilterColumn( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ mnColId = rStrm.readuInt16();
+ rStrm >> nFlags;
+
+ // BIFF5/BIFF8 support top-10 filters and custom filters
+ if( getFlag( nFlags, BIFF_FILTERCOLUMN_TOP10FILTER ) )
+ createFilterSettings< Top10Filter >().importBiffRecord( rStrm, nFlags );
+ else
+ createFilterSettings< CustomFilter >().importBiffRecord( rStrm, nFlags );
+}
+
+ApiFilterSettings FilterColumn::finalizeImport( sal_Int32 nMaxCount )
+{
+ ApiFilterSettings aSettings;
+ if( (0 <= mnColId) && mxSettings.get() )
+ {
+ // filter settings object creates a sequence of filter fields
+ aSettings = mxSettings->finalizeImport( nMaxCount );
+ // add column index to all filter fields
+ for( ApiFilterSettings::FilterFieldVector::iterator aIt = aSettings.maFilterFields.begin(), aEnd = aSettings.maFilterFields.end(); aIt != aEnd; ++aIt )
+ aIt->Field = mnColId;
+ }
+ return aSettings;
+}
+
+// ============================================================================
+
+AutoFilter::AutoFilter( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void AutoFilter::importAutoFilter( const AttributeList& rAttribs, sal_Int16 nSheet )
+{
+ OUString aRangeStr = rAttribs.getString( XML_ref, OUString() );
+ getAddressConverter().convertToCellRangeUnchecked( maRange, aRangeStr, nSheet );
+}
+
+void AutoFilter::importAutoFilter( SequenceInputStream& rStrm, sal_Int16 nSheet )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ getAddressConverter().convertToCellRangeUnchecked( maRange, aBinRange, nSheet );
+}
+
+FilterColumn& AutoFilter::createFilterColumn()
+{
+ FilterColumnVector::value_type xFilterColumn( new FilterColumn( *this ) );
+ maFilterColumns.push_back( xFilterColumn );
+ return *xFilterColumn;
+}
+
+void AutoFilter::finalizeImport( const Reference< XSheetFilterDescriptor2 >& rxFilterDesc )
+{
+ if( rxFilterDesc.is() )
+ {
+ // set some common properties for the auto filter range
+ PropertySet aDescProps( rxFilterDesc );
+ aDescProps.setProperty( PROP_IsCaseSensitive, false );
+ aDescProps.setProperty( PROP_SkipDuplicates, false );
+ aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS );
+ aDescProps.setProperty( PROP_ContainsHeader, true );
+ aDescProps.setProperty( PROP_CopyOutputData, false );
+
+ // maximum number of UNO API filter fields
+ sal_Int32 nMaxCount = 0;
+ aDescProps.getProperty( nMaxCount, PROP_MaxFieldCount );
+ OSL_ENSURE( nMaxCount > 0, "AutoFilter::finalizeImport - invalid maximum filter field count" );
+
+ // resulting list of all UNO API filter fields
+ ::std::vector< TableFilterField2 > aFilterFields;
+
+ // track if columns require to enable or disable regular expressions
+ OptValue< bool > obNeedsRegExp;
+
+ /* Track whether the filter fields of the first filter column are
+ connected with 'or'. In this case, other filter fields cannot be
+ inserted without altering the result of the entire filter, due to
+ Calc's precedence for the 'and' connection operator. Example:
+ Excel's filter conditions 'A1 and (B1 or B2) and C1' where B1 and
+ B2 belong to filter column B, will be evaluated by Calc as
+ '(A1 and B1) or (B2 and C1)'. */
+ bool bHasOrConnection = false;
+
+ // process all filter column objects, exit when 'or' connection exists
+ for( FilterColumnVector::iterator aIt = maFilterColumns.begin(), aEnd = maFilterColumns.end(); !bHasOrConnection && (aIt != aEnd); ++aIt )
+ {
+ // the filter settings object creates a list of filter fields
+ ApiFilterSettings aSettings = (*aIt)->finalizeImport( nMaxCount );
+ ApiFilterSettings::FilterFieldVector& rColumnFields = aSettings.maFilterFields;
+
+ // new total number of filter fields
+ sal_Int32 nNewCount = static_cast< sal_Int32 >( aFilterFields.size() + rColumnFields.size() );
+
+ /* Check whether mode for regular expressions is compatible with
+ the global mode in obNeedsRegExp. If either one is still in
+ don't-care state, all is fine. If both are set, they must be
+ equal. */
+ bool bRegExpCompatible = !obNeedsRegExp || !aSettings.mobNeedsRegExp || (obNeedsRegExp.get() == aSettings.mobNeedsRegExp.get());
+
+ // check whether fields are connected by 'or' (see comments above).
+ if( rColumnFields.size() >= 2 )
+ for( ApiFilterSettings::FilterFieldVector::iterator aSIt = rColumnFields.begin() + 1, aSEnd = rColumnFields.end(); !bHasOrConnection && (aSIt != aSEnd); ++aSIt )
+ bHasOrConnection = aSIt->Connection == FilterConnection_OR;
+
+ /* Skip the column filter, if no filter fields have been created,
+ if the number of new filter fields would exceed the total limit
+ of filter fields, or if the mode for regular expressions of the
+ filter column does not fit. */
+ if( !rColumnFields.empty() && (nNewCount <= nMaxCount) && bRegExpCompatible )
+ {
+ /* Add 'and' connection to the first filter field to connect
+ it to the existing filter fields of other columns. */
+ rColumnFields[ 0 ].Connection = FilterConnection_AND;
+
+ // insert the new filter fields
+ aFilterFields.insert( aFilterFields.end(), rColumnFields.begin(), rColumnFields.end() );
+
+ // update the regular expressions mode
+ obNeedsRegExp.assignIfUsed( aSettings.mobNeedsRegExp );
+ }
+ }
+
+ // insert all filter fields to the filter descriptor
+ if( !aFilterFields.empty() )
+ rxFilterDesc->setFilterFields2( ContainerHelper::vectorToSequence( aFilterFields ) );
+
+ // regular expressions
+ bool bUseRegExp = obNeedsRegExp.get( false );
+ aDescProps.setProperty( PROP_UseRegularExpressions, bUseRegExp );
+ }
+}
+
+// ============================================================================
+
+AutoFilterBuffer::AutoFilterBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+AutoFilter& AutoFilterBuffer::createAutoFilter()
+{
+ AutoFilterVector::value_type xAutoFilter( new AutoFilter( *this ) );
+ maAutoFilters.push_back( xAutoFilter );
+ return *xAutoFilter;
+}
+
+void AutoFilterBuffer::finalizeImport( sal_Int16 nSheet )
+{
+ // rely on existence of the defined name '_FilterDatabase' containing the range address of the filtered area
+ if( const DefinedName* pFilterDBName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_FILTERDATABASE, nSheet ).get() )
+ {
+ CellRangeAddress aFilterRange;
+ if( pFilterDBName->getAbsoluteRange( aFilterRange ) && (aFilterRange.Sheet == nSheet) )
+ {
+ // use the same name for the database range as used for the defined name '_FilterDatabase'
+ OUString aDBRangeName = pFilterDBName->getCalcName();
+ Reference< XDatabaseRange > xDatabaseRange = createDatabaseRangeObject( aDBRangeName, aFilterRange );
+ // first, try to create an auto filter
+ bool bHasAutoFilter = finalizeImport( xDatabaseRange );
+ // no success: try to create an advanced filter
+ if( !bHasAutoFilter && xDatabaseRange.is() )
+ {
+ // the built-in defined name 'Criteria' must exist
+ if( const DefinedName* pCriteriaName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_CRITERIA, nSheet ).get() )
+ {
+ CellRangeAddress aCriteriaRange;
+ if( pCriteriaName->getAbsoluteRange( aCriteriaRange ) )
+ {
+ // set some common properties for the filter descriptor
+ PropertySet aDescProps( xDatabaseRange->getFilterDescriptor() );
+ aDescProps.setProperty( PROP_IsCaseSensitive, false );
+ aDescProps.setProperty( PROP_SkipDuplicates, false );
+ aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS );
+ aDescProps.setProperty( PROP_ContainsHeader, true );
+ // criteria range may contain wildcards, but these are incompatible with REs
+ aDescProps.setProperty( PROP_UseRegularExpressions, false );
+
+ // position of output data (if built-in defined name 'Extract' exists)
+ DefinedNameRef xExtractName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_EXTRACT, nSheet );
+ CellRangeAddress aOutputRange;
+ bool bHasOutputRange = xExtractName.get() && xExtractName->getAbsoluteRange( aOutputRange );
+ aDescProps.setProperty( PROP_CopyOutputData, bHasOutputRange );
+ if( bHasOutputRange )
+ {
+ aDescProps.setProperty( PROP_SaveOutputPosition, true );
+ aDescProps.setProperty( PROP_OutputPosition, CellAddress( aOutputRange.Sheet, aOutputRange.StartColumn, aOutputRange.StartRow ) );
+ }
+
+ /* Properties of the database range (must be set after
+ modifying properties of the filter descriptor,
+ otherwise the 'FilterCriteriaSource' property gets
+ deleted). */
+ PropertySet aRangeProps( xDatabaseRange );
+ aRangeProps.setProperty( PROP_AutoFilter, false );
+ aRangeProps.setProperty( PROP_FilterCriteriaSource, aCriteriaRange );
+ }
+ }
+ }
+ }
+ }
+}
+
+bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxDatabaseRange )
+{
+ AutoFilter* pAutoFilter = getActiveAutoFilter();
+ if( pAutoFilter && rxDatabaseRange.is() ) try
+ {
+ // the property 'AutoFilter' enables the drop-down buttons
+ PropertySet aRangeProps( rxDatabaseRange );
+ aRangeProps.setProperty( PROP_AutoFilter, true );
+ // convert filter settings using the filter descriptor of the database range
+ Reference< XSheetFilterDescriptor2 > xFilterDesc( rxDatabaseRange->getFilterDescriptor(), UNO_QUERY_THROW );
+ pAutoFilter->finalizeImport( xFilterDesc );
+ // return true to indicate enabled autofilter
+ return true;
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+AutoFilter* AutoFilterBuffer::getActiveAutoFilter()
+{
+ // Excel expects not more than one auto filter per sheet or table
+ OSL_ENSURE( maAutoFilters.size() == 1, "AutoFilterBuffer::getActiveAutoFilter - too many auto filters" );
+ // stick to the last imported auto filter
+ return maAutoFilters.empty() ? 0 : maAutoFilters.back().get();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/autofiltercontext.cxx b/oox/source/xls/autofiltercontext.cxx
new file mode 100644
index 000000000000..81327944fc05
--- /dev/null
+++ b/oox/source/xls/autofiltercontext.cxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/autofiltercontext.hxx"
+
+#include "oox/xls/autofilterbuffer.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+FilterSettingsContext::FilterSettingsContext( WorksheetContextBase& rParent, FilterSettingsBase& rFilterSettings ) :
+ WorksheetContextBase( rParent ),
+ mrFilterSettings( rFilterSettings )
+{
+}
+
+ContextHandlerRef FilterSettingsContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( filters ):
+ if( nElement == XLS_TOKEN( filter ) ) return this;
+ break;
+ case XLS_TOKEN( customFilters ):
+ if( nElement == XLS_TOKEN( customFilter ) ) return this;
+ break;
+ }
+ return 0;
+}
+
+void FilterSettingsContext::onStartElement( const AttributeList& rAttribs )
+{
+ mrFilterSettings.importAttribs( getCurrentElement(), rAttribs );
+}
+
+ContextHandlerRef FilterSettingsContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& /*rStrm*/ )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_DISCRETEFILTERS:
+ if( nRecId == BIFF12_ID_DISCRETEFILTER ) return this;
+ break;
+ case BIFF12_ID_CUSTOMFILTERS:
+ if( nRecId == BIFF12_ID_CUSTOMFILTER ) return this;
+ break;
+ }
+ return 0;
+}
+
+void FilterSettingsContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ mrFilterSettings.importRecord( getCurrentElement(), rStrm );
+}
+
+// ============================================================================
+
+FilterColumnContext::FilterColumnContext( WorksheetContextBase& rParent, FilterColumn& rFilterColumn ) :
+ WorksheetContextBase( rParent ),
+ mrFilterColumn( rFilterColumn )
+{
+}
+
+ContextHandlerRef FilterColumnContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
+{
+ if( getCurrentElement() == XLS_TOKEN( filterColumn ) ) switch( nElement )
+ {
+ case XLS_TOKEN( filters ):
+ return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< DiscreteFilter >() );
+ case XLS_TOKEN( top10 ):
+ return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< Top10Filter >() );
+ case XLS_TOKEN( customFilters ):
+ return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< CustomFilter >() );
+ }
+ return 0;
+}
+
+void FilterColumnContext::onStartElement( const AttributeList& rAttribs )
+{
+ mrFilterColumn.importFilterColumn( rAttribs );
+}
+
+ContextHandlerRef FilterColumnContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& /*rStrm*/ )
+{
+ if( getCurrentElement() == BIFF12_ID_FILTERCOLUMN ) switch( nRecId )
+ {
+ case BIFF12_ID_DISCRETEFILTERS:
+ return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< DiscreteFilter >() );
+ case BIFF12_ID_TOP10FILTER:
+ return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< Top10Filter >() );
+ case BIFF12_ID_CUSTOMFILTERS:
+ return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< CustomFilter >() );
+ }
+ return 0;
+}
+
+void FilterColumnContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ mrFilterColumn.importFilterColumn( rStrm );
+}
+
+// ============================================================================
+
+AutoFilterContext::AutoFilterContext( WorksheetFragmentBase& rFragment, AutoFilter& rAutoFilter ) :
+ WorksheetContextBase( rFragment ),
+ mrAutoFilter( rAutoFilter )
+{
+}
+
+ContextHandlerRef AutoFilterContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
+{
+ if( (getCurrentElement() == XLS_TOKEN( autoFilter )) && (nElement == XLS_TOKEN( filterColumn )) )
+ return new FilterColumnContext( *this, mrAutoFilter.createFilterColumn() );
+ return 0;
+}
+
+void AutoFilterContext::onStartElement( const AttributeList& rAttribs )
+{
+ mrAutoFilter.importAutoFilter( rAttribs, getSheetIndex() );
+}
+
+ContextHandlerRef AutoFilterContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& /*rStrm*/ )
+{
+ if( (getCurrentElement() == BIFF12_ID_AUTOFILTER) && (nRecId == BIFF12_ID_FILTERCOLUMN) )
+ return new FilterColumnContext( *this, mrAutoFilter.createFilterColumn() );
+ return 0;
+}
+
+void AutoFilterContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ mrAutoFilter.importAutoFilter( rStrm, getSheetIndex() );
+}
+
+// ============================================================================
+
+BiffAutoFilterContext::BiffAutoFilterContext( const WorksheetHelper& rHelper, AutoFilter& rAutoFilter ) :
+ BiffWorksheetContextBase( rHelper ),
+ mrAutoFilter( rAutoFilter )
+{
+}
+
+void BiffAutoFilterContext::importRecord( BiffInputStream& rStrm )
+{
+ switch( rStrm.getRecId() )
+ {
+ // nothing to read for BIFF_ID_AUTOFILTER
+ case BIFF_ID_FILTERCOLUMN: mrAutoFilter.createFilterColumn().importFilterColumn( rStrm ); break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/biffcodec.cxx b/oox/source/xls/biffcodec.cxx
new file mode 100644
index 000000000000..cb4829973fcc
--- /dev/null
+++ b/oox/source/xls/biffcodec.cxx
@@ -0,0 +1,379 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffcodec.hxx"
+
+#include <osl/thread.h>
+#include <string.h>
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::FilterBase;
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OStringToOUString;
+
+// ============================================================================
+
+BiffDecoderBase::BiffDecoderBase() :
+ mbValid( false )
+{
+}
+
+BiffDecoderBase::~BiffDecoderBase()
+{
+}
+
+::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword, Sequence< NamedValue >& o_rEncryptionData )
+{
+ o_rEncryptionData = implVerifyPassword( rPassword );
+ mbValid = o_rEncryptionData.hasElements();
+ return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData )
+{
+ mbValid = implVerifyEncryptionData( rEncryptionData );
+ return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
+{
+ if( pnDestData && pnSrcData && (nBytes > 0) )
+ {
+ if( mbValid )
+ implDecode( pnDestData, pnSrcData, nStreamPos, nBytes );
+ else
+ memcpy( pnDestData, pnSrcData, nBytes );
+ }
+}
+
+// ============================================================================
+
+BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) :
+ maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
+ mnKey( nKey ),
+ mnHash( nHash )
+{
+}
+
+BiffDecoder_XOR::BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ) :
+ BiffDecoderBase(), // must be called to prevent compiler warning
+ maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
+ maEncryptionData( rDecoder.maEncryptionData ),
+ mnKey( rDecoder.mnKey ),
+ mnHash( rDecoder.mnHash )
+{
+ if( isValid() )
+ maCodec.initCodec( maEncryptionData );
+}
+
+BiffDecoder_XOR* BiffDecoder_XOR::implClone()
+{
+ return new BiffDecoder_XOR( *this );
+}
+
+Sequence< NamedValue > BiffDecoder_XOR::implVerifyPassword( const OUString& rPassword )
+{
+ maEncryptionData.realloc( 0 );
+
+ /* Convert password to a byte string. TODO: this needs some finetuning
+ according to the spec... */
+ OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
+ sal_Int32 nLen = aBytePassword.getLength();
+ if( (0 < nLen) && (nLen < 16) )
+ {
+ // init codec
+ maCodec.initKey( reinterpret_cast< const sal_uInt8* >( aBytePassword.getStr() ) );
+
+ if( maCodec.verifyKey( mnKey, mnHash ) )
+ maEncryptionData = maCodec.getEncryptionData();
+ }
+
+ return maEncryptionData;
+}
+
+bool BiffDecoder_XOR::implVerifyEncryptionData( const Sequence< NamedValue >& rEncryptionData )
+{
+ maEncryptionData.realloc( 0 );
+
+ if( rEncryptionData.hasElements() )
+ {
+ // init codec
+ maCodec.initCodec( rEncryptionData );
+
+ if( maCodec.verifyKey( mnKey, mnHash ) )
+ maEncryptionData = rEncryptionData;
+ }
+
+ return maEncryptionData.hasElements();
+}
+
+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( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
+ maSalt( pnSalt, pnSalt + 16 ),
+ maVerifier( pnVerifier, pnVerifier + 16 ),
+ maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
+{
+}
+
+BiffDecoder_RCF::BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ) :
+ BiffDecoderBase(), // must be called to prevent compiler warning
+ maEncryptionData( rDecoder.maEncryptionData ),
+ maSalt( rDecoder.maSalt ),
+ maVerifier( rDecoder.maVerifier ),
+ maVerifierHash( rDecoder.maVerifierHash )
+{
+ if( isValid() )
+ maCodec.initCodec( maEncryptionData );
+}
+
+BiffDecoder_RCF* BiffDecoder_RCF::implClone()
+{
+ return new BiffDecoder_RCF( *this );
+}
+
+Sequence< NamedValue > BiffDecoder_RCF::implVerifyPassword( const OUString& rPassword )
+{
+ maEncryptionData.realloc( 0 );
+
+ sal_Int32 nLen = rPassword.getLength();
+ if( (0 < nLen) && (nLen < 16) )
+ {
+ // copy string to sal_uInt16 array
+ ::std::vector< sal_uInt16 > aPassVect( 16 );
+ const sal_Unicode* pcChar = rPassword.getStr();
+ const sal_Unicode* pcCharEnd = pcChar + nLen;
+ ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
+ for( ; pcChar < pcCharEnd; ++pcChar, ++aIt )
+ *aIt = static_cast< sal_uInt16 >( *pcChar );
+
+ // init codec
+ maCodec.initKey( &aPassVect.front(), &maSalt.front() );
+ if( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
+ maEncryptionData = maCodec.getEncryptionData();
+ }
+
+ return maEncryptionData;
+}
+
+bool BiffDecoder_RCF::implVerifyEncryptionData( const Sequence< NamedValue >& rEncryptionData )
+{
+ maEncryptionData.realloc( 0 );
+
+ if( rEncryptionData.hasElements() )
+ {
+ // init codec
+ maCodec.initCodec( rEncryptionData );
+
+ if( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
+ maEncryptionData = rEncryptionData;
+ }
+
+ return maEncryptionData.hasElements();
+}
+
+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 {
+
+const sal_uInt16 BIFF_FILEPASS_XOR = 0;
+const sal_uInt16 BIFF_FILEPASS_RCF = 1;
+
+const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF = 1;
+const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003 = 2;
+const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007 = 3;
+
+// ----------------------------------------------------------------------------
+
+BiffDecoderRef lclReadFilePass_XOR( BiffInputStream& rStrm )
+{
+ BiffDecoderRef xDecoder;
+ OSL_ENSURE( rStrm.getRemaining() == 4, "lclReadFilePass_XOR - wrong record size" );
+ if( rStrm.getRemaining() == 4 )
+ {
+ sal_uInt16 nBaseKey, nHash;
+ rStrm >> nBaseKey >> nHash;
+ xDecoder.reset( new BiffDecoder_XOR( nBaseKey, nHash ) );
+ }
+ return xDecoder;
+}
+
+BiffDecoderRef lclReadFilePass_RCF( BiffInputStream& rStrm )
+{
+ BiffDecoderRef xDecoder;
+ OSL_ENSURE( rStrm.getRemaining() == 48, "lclReadFilePass_RCF - wrong record size" );
+ if( rStrm.getRemaining() == 48 )
+ {
+ sal_uInt8 pnSalt[ 16 ];
+ sal_uInt8 pnVerifier[ 16 ];
+ sal_uInt8 pnVerifierHash[ 16 ];
+ rStrm.readMemory( pnSalt, 16 );
+ rStrm.readMemory( pnVerifier, 16 );
+ rStrm.readMemory( pnVerifierHash, 16 );
+ xDecoder.reset( new BiffDecoder_RCF( pnSalt, pnVerifier, pnVerifierHash ) );
+ }
+ return xDecoder;
+}
+
+BiffDecoderRef lclReadFilePass_CryptoApi( BiffInputStream& /*rStrm*/ )
+{
+ // not supported
+ return BiffDecoderRef();
+}
+
+BiffDecoderRef lclReadFilePassBiff8( BiffInputStream& rStrm )
+{
+ BiffDecoderRef xDecoder;
+ switch( rStrm.readuInt16() )
+ {
+ case BIFF_FILEPASS_XOR:
+ xDecoder = lclReadFilePass_XOR( rStrm );
+ break;
+
+ case BIFF_FILEPASS_RCF:
+ {
+ sal_uInt16 nMajor = rStrm.readuInt16();
+ rStrm.skip( 2 );
+ switch( nMajor )
+ {
+ case BIFF_FILEPASS_BIFF8_RCF:
+ xDecoder = lclReadFilePass_RCF( rStrm );
+ break;
+ case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003:
+ case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007:
+ xDecoder = lclReadFilePass_CryptoApi( rStrm );
+ break;
+ default:
+ OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown BIFF8 encryption sub mode" );
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown encryption mode" );
+ }
+ return xDecoder;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+/*static*/ BiffDecoderRef BiffCodecHelper::implReadFilePass( BiffInputStream& rStrm, BiffType eBiff )
+{
+ rStrm.enableDecoder( false );
+ BiffDecoderRef xDecoder = (eBiff == BIFF8) ? lclReadFilePassBiff8( rStrm ) : lclReadFilePass_XOR( rStrm );
+ rStrm.setDecoder( xDecoder );
+ return xDecoder;
+}
+
+bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !mxDecoder, "BiffCodecHelper::importFilePass - multiple FILEPASS records" );
+ mxDecoder = implReadFilePass( rStrm, getBiff() );
+ // request and verify a password (decoder implements IDocPasswordVerifier)
+ if( mxDecoder.get() )
+ getBaseFilter().requestEncryptionData( *mxDecoder );
+ // correct password is indicated by isValid() function of decoder
+ return mxDecoder.get() && mxDecoder->isValid();
+}
+
+void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm )
+{
+ if( mxDecoder.get() )
+ rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/biffdetector.cxx b/oox/source/xls/biffdetector.cxx
new file mode 100644
index 000000000000..038d7d732425
--- /dev/null
+++ b/oox/source/xls/biffdetector.cxx
@@ -0,0 +1,231 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffdetector.hxx"
+
+#include <algorithm>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include <rtl/strbuf.hxx>
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/ole/olestorage.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::comphelper::MediaDescriptor;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+
+// ============================================================================
+
+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.xls.BiffDetector" );
+}
+
+Reference< XInterface > SAL_CALL BiffDetector_createInstance( const Reference< XComponentContext >& rxContext ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new BiffDetector( rxContext ) );
+}
+
+// ============================================================================
+
+BiffDetector::BiffDetector( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ mxContext( rxContext, UNO_SET_THROW )
+{
+}
+
+BiffDetector::~BiffDetector()
+{
+}
+
+/*static*/ BiffType BiffDetector::detectStreamBiffVersion( BinaryInputStream& rInStream )
+{
+ BiffType eBiff = BIFF_UNKNOWN;
+ if( !rInStream.isEof() && rInStream.isSeekable() && (rInStream.getLength() > 4) )
+ {
+ sal_Int64 nOldPos = rInStream.tell();
+ rInStream.seekToStart();
+ 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;
+}
+
+/*static*/ BiffType BiffDetector::detectStorageBiffVersion( OUString& orWorkbookStreamName, const StorageRef& rxStorage )
+{
+ static const OUString saBookName = CREATE_OUSTRING( "Book" );
+ static const OUString saWorkbookName = CREATE_OUSTRING( "Workbook" );
+
+ BiffType eBiff = BIFF_UNKNOWN;
+ if( rxStorage.get() )
+ {
+ if( rxStorage->isStorage() )
+ {
+ // try to open the "Book" stream
+ BinaryXInputStream aBookStrm5( rxStorage->openInputStream( saBookName ), true );
+ BiffType eBookStrm5Biff = detectStreamBiffVersion( aBookStrm5 );
+
+ // try to open the "Workbook" stream
+ BinaryXInputStream aBookStrm8( rxStorage->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+)
+ BinaryXInputStream aStrm( rxStorage->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< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
+ Reference< XInputStream > xInStrm( aDescriptor[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY_THROW );
+ StorageRef xStorage( new ::oox::ole::OleStorage( xFactory, xInStrm, true ) );
+
+ OUString aWorkbookName;
+ 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/biffhelper.cxx b/oox/source/xls/biffhelper.cxx
new file mode 100644
index 000000000000..55839043865e
--- /dev/null
+++ b/oox/source/xls/biffhelper.cxx
@@ -0,0 +1,338 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffhelper.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/tencinfo.h>
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/biffoutputstream.hxx"
+#include "oox/xls/worksheethelper.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 BIFF_RK_100FLAG = 0x00000001;
+const sal_Int32 BIFF_RK_INTFLAG = 0x00000002;
+const sal_Int32 BIFF_RK_VALUEMASK = 0xFFFFFFFC;
+
+const sal_Int32 BITMAPFILEHEADER_SIZE = 14;
+const sal_Int32 BITMAPCOREHEADER_SIZE = 12;
+const sal_Int32 BITMAPINFOHEADER_SIZE = 40;
+
+const sal_uInt16 BIFF_IMGDATA_WMF = 2;
+const sal_uInt16 BIFF_IMGDATA_DIB = 9;
+const sal_uInt16 BIFF_IMGDATA_NATIVE = 14;
+
+// ----------------------------------------------------------------------------
+
+union DecodedDouble
+{
+ double mfValue;
+ sal_math_Double maStruct;
+
+ inline explicit DecodedDouble() {}
+ inline explicit DecodedDouble( double fValue ) : mfValue( fValue ) {}
+};
+
+bool lclCalcRkFromDouble( sal_Int32& ornRkValue, const DecodedDouble& rDecDbl )
+{
+ // double
+ if( (rDecDbl.maStruct.w32_parts.lsw == 0) && ((rDecDbl.maStruct.w32_parts.msw & 0x3) == 0) )
+ {
+ ornRkValue = static_cast< sal_Int32 >( rDecDbl.maStruct.w32_parts.msw );
+ return true;
+ }
+
+ // integer
+ double fInt = 0.0;
+ double fFrac = modf( rDecDbl.mfValue, &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;
+}
+
+bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue )
+{
+ DecodedDouble aDecDbl( fValue );
+ if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) )
+ return true;
+
+ aDecDbl.mfValue *= 100.0;
+ if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) )
+ {
+ ornRkValue |= BIFF_RK_100FLAG;
+ return true;
+ }
+
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, sal_Int32 nBytes, BiffType eBiff )
+{
+ /* The IMGDATA record for bitmap format contains a Windows DIB (a bitmap
+ file without the 'BITMAPFILEHEADER' header structure). Usually, the DIB
+ header consists of 12 bytes (called 'OS/2 V1 header' or
+ 'BITMAPCOREHEADER', see http://en.wikipedia.org/wiki/BMP_file_format)
+ followed by the remaining pixel data, but the 'Windows V3' or
+ 'BITMAPINFOHEADER' is also supported here. This function creates a
+ complete 'BMP file' that can be read by the OOo graphic provider used
+ to import graphic objects. For that, the BITMAPFILEHEADER has to be
+ inserted before the DIB data, and it has to contain the correct offset
+ to the pixel data. Currently, in real life there are only 24-bit and
+ 32-bit DIBs (without color palette) in use. This code relies on this
+ fact and calculates the offset to the pixel data according to the size
+ of the DIB header.
+ Remaining tasks are (if really used somewhere):
+ - Support of DIBs with color palette,
+ - Support of 'Windows V4' and 'Windows V5' DIB header. */
+
+ // read and check validity of DIB header
+ sal_Int64 nInStrmPos = rStrm.tell();
+ sal_Int32 nDibHdrSize = rStrm.readInt32();
+ sal_uInt16 nPlanes = 0, nDepth = 0;
+ switch( nDibHdrSize )
+ {
+ case BITMAPCOREHEADER_SIZE:
+ rStrm.skip( 4 ); // width/height as 16-bit integer
+ rStrm >> nPlanes >> nDepth;
+ break;
+ case BITMAPINFOHEADER_SIZE:
+ rStrm.skip( 8 ); // width/height as 32-bit integer
+ rStrm >> nPlanes >> nDepth;
+ break;
+ }
+ rStrm.seek( nInStrmPos );
+
+ if( (nPlanes == 1) && ((nDepth == 24) || (nDepth == 32)) )
+ {
+ // allocate enough space for the BITMAPFILEHEADER and the DIB data
+ orDataSeq.realloc( BITMAPFILEHEADER_SIZE + nBytes );
+ SequenceOutputStream aOutStrm( orDataSeq );
+
+ // write the BITMAPFILEHEADER of a regular BMP file
+ sal_Int32 nBmpSize = BITMAPFILEHEADER_SIZE + nBytes;
+ sal_Int32 nOffset = BITMAPFILEHEADER_SIZE + nDibHdrSize;
+ aOutStrm << sal_uInt16( 0x4D42 ) << nBmpSize << sal_Int32( 0 ) << nOffset;
+
+ // copy the DIB header
+ rStrm.copyToStream( aOutStrm, nDibHdrSize );
+ nBytes -= nDibHdrSize;
+
+ /* Excel 3.x and Excel 4.x seem to write broken or out-dated DIB data.
+ Usually they write a BITMAPCOREHEADER containing width, height,
+ planes as usual. The pixel depth field is set to 32 bit (though
+ this is not allowed according to documentation). Between that
+ header and the actual pixel data, 3 unused bytes are inserted. This
+ does even confuse Excel 5.x and later, which cannot read the image
+ data correctly. */
+ if( (eBiff <= BIFF4) && (nDibHdrSize == BITMAPCOREHEADER_SIZE) && (nDepth == 32) )
+ {
+ // skip the dummy bytes in input stream
+ rStrm.skip( 3 );
+ nBytes -= 3;
+ // correct the total BMP file size in output stream
+ sal_Int64 nOutStrmPos = aOutStrm.tell();
+ aOutStrm.seek( 2 );
+ aOutStrm << sal_Int32( nBmpSize - 3 );
+ aOutStrm.seek( nOutStrmPos );
+ }
+
+ // copy remaining pixel data to output stream
+ rStrm.copyToStream( aOutStrm, nBytes );
+ }
+ rStrm.seek( nInStrmPos + nBytes );
+}
+
+} // namespace
+
+// ============================================================================
+
+// conversion -----------------------------------------------------------------
+
+/*static*/ double BiffHelper::calcDoubleFromRk( sal_Int32 nRkValue )
+{
+ DecodedDouble aDecDbl( 0.0 );
+ if( getFlag( nRkValue, BIFF_RK_INTFLAG ) )
+ {
+ sal_Int32 nTemp = nRkValue >> 2;
+ setFlag< sal_Int32 >( nTemp, 0xE0000000, nRkValue < 0 );
+ aDecDbl.mfValue = nTemp;
+ }
+ else
+ {
+ aDecDbl.maStruct.w32_parts.msw = static_cast< sal_uInt32 >( nRkValue & BIFF_RK_VALUEMASK );
+ }
+
+ if( getFlag( nRkValue, BIFF_RK_100FLAG ) )
+ aDecDbl.mfValue /= 100.0;
+
+ return aDecDbl.mfValue;
+}
+
+/*static*/ 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;
+}
+
+/*static*/ 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" );
+ }
+ DecodedDouble aDecDbl;
+ ::rtl::math::setNan( &aDecDbl.mfValue );
+ aDecDbl.maStruct.nan_parts.fraction_lo = nApiError;
+ return aDecDbl.mfValue;
+}
+
+/*static*/ rtl_TextEncoding BiffHelper::calcTextEncodingFromCodePage( sal_uInt16 nCodePage )
+{
+ // some specials for BIFF
+ switch( nCodePage )
+ {
+ case 1200: return RTL_TEXTENCODING_DONTKNOW; // BIFF8 Unicode
+ case 32768: return RTL_TEXTENCODING_APPLE_ROMAN;
+ case 32769: return RTL_TEXTENCODING_MS_1252; // BIFF2-BIFF3
+ }
+
+ rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
+ OSL_ENSURE( eTextEnc != RTL_TEXTENCODING_DONTKNOW, "BiffHelper::calcTextEncodingFromCodePage - unknown code page" );
+ return eTextEnc;
+}
+
+/*static*/ sal_uInt16 BiffHelper::calcCodePageFromTextEncoding( rtl_TextEncoding eTextEnc )
+{
+ sal_uInt32 nCodePage = rtl_getWindowsCodePageFromTextEncoding( eTextEnc );
+ OSL_ENSURE( (0 < nCodePage) && (nCodePage <= SAL_MAX_UINT16), "BiffHelper::calcCodePageFromTextEncoding - unknown text encoding" );
+ return static_cast< sal_uInt16 >( (nCodePage == 0) ? 1252 : nCodePage );
+}
+
+// BIFF12 import --------------------------------------------------------------
+
+/*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen )
+{
+ OUString aString;
+ if( !rStrm.isEof() )
+ {
+ sal_Int32 nCharCount = b32BitLen ? rStrm.readValue< sal_Int32 >() : rStrm.readValue< sal_Int16 >();
+ // string length -1 is often used to indicate a missing string
+ OSL_ENSURE( !rStrm.isEof() && (nCharCount >= -1), "BiffHelper::readString - invalid string length" );
+ if( !rStrm.isEof() && (nCharCount > 0) )
+ {
+ ::std::vector< sal_Unicode > aBuffer;
+ aBuffer.reserve( getLimitedValue< size_t, sal_Int32 >( nCharCount + 1, 0, 0xFFFF ) );
+ for( sal_Int32 nCharIdx = 0; !rStrm.isEof() && (nCharIdx < nCharCount); ++nCharIdx )
+ {
+ sal_uInt16 nChar;
+ rStrm.readValue( nChar );
+ aBuffer.push_back( static_cast< sal_Unicode >( nChar ) );
+ }
+ aBuffer.push_back( 0 );
+ aString = OUString( &aBuffer.front() );
+ }
+ }
+ return aString;
+}
+
+// BIFF2-BIFF8 import ---------------------------------------------------------
+
+/*static*/ bool BiffHelper::isBofRecord( BiffInputStream& rStrm )
+{
+ return
+ (rStrm.getRecId() == BIFF2_ID_BOF) ||
+ (rStrm.getRecId() == BIFF3_ID_BOF) ||
+ (rStrm.getRecId() == BIFF4_ID_BOF) ||
+ (rStrm.getRecId() == BIFF5_ID_BOF);
+}
+
+/*static*/ bool BiffHelper::skipRecordBlock( BiffInputStream& rStrm, sal_uInt16 nEndRecId )
+{
+ sal_uInt16 nStartRecId = rStrm.getRecId();
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != nEndRecId) )
+ if( rStrm.getRecId() == nStartRecId )
+ skipRecordBlock( rStrm, nEndRecId );
+ return !rStrm.isEof() && (rStrm.getRecId() == nEndRecId);
+}
+
+/*static*/ void BiffHelper::importImgData( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, BiffType eBiff )
+{
+ sal_uInt16 nFormat, nEnv;
+ sal_Int32 nBytes;
+ rStrm >> nFormat >> nEnv >> nBytes;
+ OSL_ENSURE( nBytes > 0, "BiffHelper::importImgData - invalid data size" );
+ if( (0 < nBytes) && (nBytes <= rStrm.getRemaining()) )
+ {
+ switch( nFormat )
+ {
+// case BIFF_IMGDATA_WMF: /* TODO */ break;
+ case BIFF_IMGDATA_DIB: lclImportImgDataDib( orDataSeq, rStrm, nBytes, eBiff ); break;
+// case BIFF_IMGDATA_NATIVE: /* TODO */ break;
+ default: OSL_ENSURE( false, "BiffHelper::importImgData - unknown image format" );
+ }
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/biffinputstream.cxx b/oox/source/xls/biffinputstream.cxx
new file mode 100644
index 000000000000..6dfa8f755c25
--- /dev/null
+++ b/oox/source/xls/biffinputstream.cxx
@@ -0,0 +1,633 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffinputstream.hxx"
+
+#include <algorithm>
+#include <rtl/ustrbuf.hxx>
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using ::rtl::OString;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+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( const BiffDecoderRef& rxDecoder )
+{
+ mxDecoder = rxDecoder;
+ 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 = !mrInStrm.isEof() && (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;
+}
+
+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.readMemory( &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 ),
+ mbCont( bContLookup )
+{
+ mbEof = true; // EOF will be true if stream is not inside a record
+}
+
+// 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( const BiffDecoderRef& rxDecoder )
+{
+ maRecBuffer.setDecoder( rxDecoder );
+}
+
+void BiffInputStream::enableDecoder( bool bEnable )
+{
+ maRecBuffer.enableDecoder( bEnable );
+}
+
+// stream/record state and info -----------------------------------------------
+
+sal_uInt16 BiffInputStream::getNextRecId()
+{
+ sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
+ if( isInRecord() )
+ {
+ sal_Int64 nCurrPos = tell(); // 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;
+}
+
+// BinaryStreamBase interface (seeking) ---------------------------------------
+
+bool BiffInputStream::isSeekable() const
+{
+ return true;
+}
+
+sal_Int64 BiffInputStream::tell() const
+{
+ return mbEof ? -1 : (mnCurrRecSize - maRecBuffer.getRecLeft());
+}
+
+sal_Int64 BiffInputStream::getLength() const
+{
+ if( !mbHasComplRec )
+ const_cast< BiffInputStream* >( this )->calcRecordLength();
+ return mnComplRecSize;
+}
+
+void BiffInputStream::seek( sal_Int64 nRecPos )
+{
+ if( isInRecord() )
+ {
+ if( mbEof || (nRecPos < tell()) )
+ restartRecord( false );
+ if( !mbEof && (nRecPos > tell()) )
+ skip( static_cast< sal_Int32 >( nRecPos - tell() ) );
+ }
+}
+
+sal_Int64 BiffInputStream::tellBase() const
+{
+ return maRecBuffer.getBaseStream().tell();
+}
+
+sal_Int64 BiffInputStream::getBaseLength() const
+{
+ return maRecBuffer.getBaseStream().getLength();
+}
+
+// BinaryInputStream interface (stream read access) ---------------------------
+
+sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = 0;
+ if( !mbEof )
+ {
+ orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) );
+ if( nBytes > 0 )
+ {
+ nRet = readMemory( orData.getArray(), nBytes );
+ if( nRet < nBytes )
+ orData.realloc( nRet );
+ }
+ }
+ return nRet;
+}
+
+sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes )
+{
+ sal_Int32 nRet = 0;
+ if( !mbEof && opMem && (nBytes > 0) )
+ {
+ sal_uInt8* pnBuffer = reinterpret_cast< sal_uInt8* >( opMem );
+ sal_Int32 nBytesLeft = nBytes;
+
+ while( !mbEof && (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( !mbEof, "BiffInputStream::readMemory - record overread" );
+ }
+ }
+ return nRet;
+}
+
+void BiffInputStream::skip( sal_Int32 nBytes )
+{
+ sal_Int32 nBytesLeft = nBytes;
+ while( !mbEof && (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( !mbEof, "BiffInputStream::skip - record overread" );
+ }
+}
+
+// byte strings ---------------------------------------------------------------
+
+OString BiffInputStream::readByteString( bool b16BitLen, bool bAllowNulChars )
+{
+ sal_Int32 nStrLen = b16BitLen ? readuInt16() : readuInt8();
+ return readCharArray( nStrLen, bAllowNulChars );
+}
+
+OUString BiffInputStream::readByteStringUC( bool b16BitLen, rtl_TextEncoding eTextEnc, bool bAllowNulChars )
+{
+ return OStringToOUString( readByteString( b16BitLen, bAllowNulChars ), eTextEnc );
+}
+
+void BiffInputStream::skipByteString( bool b16BitLen )
+{
+ skip( b16BitLen ? readuInt16() : readuInt8() );
+}
+
+// Unicode strings ------------------------------------------------------------
+
+OUString BiffInputStream::readUniStringChars( sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars )
+{
+ OUStringBuffer aBuffer;
+ aBuffer.ensureCapacity( nChars );
+
+ /* This function has to react on CONTINUE records to read the repeated
+ flags field, so readUnicodeArray() cannot be used here. */
+ sal_uInt16 nCharsLeft = nChars;
+ while( !mbEof && (nCharsLeft > 0) )
+ {
+ sal_uInt16 nPortionCount = 0;
+ if( b16BitChars )
+ {
+ nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 );
+ OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0),
+ "BiffInputStream::readUniStringChars - missing a byte" );
+ }
+ else
+ {
+ nPortionCount = getMaxRawReadSize( nCharsLeft );
+ }
+
+ // read the character array
+ appendUnicodeArray( aBuffer, nPortionCount, b16BitChars, bAllowNulChars );
+
+ // prepare for next CONTINUE record
+ nCharsLeft = nCharsLeft - nPortionCount;
+ if( nCharsLeft > 0 )
+ jumpToNextStringContinue( b16BitChars );
+ }
+
+ return aBuffer.makeStringAndClear();
+}
+
+OUString BiffInputStream::readUniStringBody( sal_uInt16 nChars, bool bAllowNulChars )
+{
+ bool b16BitChars;
+ sal_Int32 nAddSize;
+ readUniStringHeader( b16BitChars, nAddSize );
+ OUString aString = readUniStringChars( nChars, b16BitChars, bAllowNulChars );
+ skip( nAddSize );
+ return aString;
+}
+
+OUString BiffInputStream::readUniString( bool bAllowNulChars )
+{
+ return readUniStringBody( readuInt16(), bAllowNulChars );
+}
+
+void BiffInputStream::skipUniStringChars( sal_uInt16 nChars, bool b16BitChars )
+{
+ sal_uInt16 nCharsLeft = nChars;
+ while( !mbEof && (nCharsLeft > 0) )
+ {
+ sal_uInt16 nPortionCount;
+ if( b16BitChars )
+ {
+ nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 );
+ OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0),
+ "BiffInputStream::skipUniStringChars - missing a byte" );
+ skip( 2 * nPortionCount );
+ }
+ else
+ {
+ nPortionCount = getMaxRawReadSize( nCharsLeft );
+ skip( nPortionCount );
+ }
+
+ // prepare for next CONTINUE record
+ nCharsLeft = nCharsLeft - nPortionCount;
+ if( nCharsLeft > 0 )
+ jumpToNextStringContinue( b16BitChars );
+ }
+}
+
+void BiffInputStream::skipUniStringBody( sal_uInt16 nChars )
+{
+ bool b16BitChars;
+ sal_Int32 nAddSize;
+ readUniStringHeader( b16BitChars, nAddSize );
+ skipUniStringChars( nChars, b16BitChars );
+ skip( nAddSize );
+}
+
+void BiffInputStream::skipUniString()
+{
+ skipUniStringBody( readuInt16() );
+}
+
+// private --------------------------------------------------------------------
+
+void BiffInputStream::readAtom( void* opMem, sal_uInt8 nSize )
+{
+ // byte swapping is done in calling BinaryInputStream::readValue() template function
+ if( ensureRawReadSize( nSize ) )
+ maRecBuffer.read( opMem, nSize );
+}
+
+void BiffInputStream::setupRecord()
+{
+ // initialize class members
+ mnRecHandle = maRecBuffer.getRecHeaderPos();
+ mnRecId = maRecBuffer.getRecId();
+ mnAltContId = BIFF_ID_UNKNOWN;
+ mnCurrRecSize = mnComplRecSize = maRecBuffer.getRecSize();
+ mbHasComplRec = !mbCont;
+ mbEof = !isInRecord();
+ // 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;
+ }
+ mbEof = false;
+ }
+}
+
+void BiffInputStream::rewindToRecord( sal_Int64 nRecHandle )
+{
+ if( nRecHandle >= 0 )
+ {
+ maRecBuffer.restartAt( nRecHandle );
+ mnRecHandle = -1;
+ mbEof = true; // as long as the record is not started
+ }
+}
+
+bool BiffInputStream::isContinueId( sal_uInt16 nRecId ) const
+{
+ return (nRecId == BIFF_ID_CONT) || (nRecId == mnAltContId);
+}
+
+bool BiffInputStream::jumpToNextContinue()
+{
+ mbEof = mbEof || !mbCont || !isContinueId( maRecBuffer.getNextRecId() ) || !maRecBuffer.startNextRecord();
+ if( !mbEof )
+ mnCurrRecSize += maRecBuffer.getRecSize();
+ return !mbEof;
+}
+
+bool BiffInputStream::jumpToNextStringContinue( bool& rb16BitChars )
+{
+ OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - unexpected garbage" );
+
+ if( mbCont && (getRemaining() > 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. */
+ mbEof = mbEof || (maRecBuffer.getNextRecId() != BIFF_ID_CONT) || !maRecBuffer.startNextRecord();
+ if( !mbEof )
+ setupRecord();
+ }
+
+ // trying to read the flags invalidates stream, if no CONTINUE record has been found
+ sal_uInt8 nFlags;
+ readValue( nFlags );
+ rb16BitChars = getFlag( nFlags, BIFF_STRF_16BIT );
+ return !mbEof;
+}
+
+void BiffInputStream::calcRecordLength()
+{
+ sal_Int64 nCurrPos = tell(); // save current position in record
+ while( jumpToNextContinue() ) {} // jumpToNextContinue() adds up mnCurrRecSize
+ mnComplRecSize = mnCurrRecSize;
+ mbHasComplRec = true;
+ seek( nCurrPos ); // restore position, seek() resets old mbValid state
+}
+
+bool BiffInputStream::ensureRawReadSize( sal_uInt16 nBytes )
+{
+ if( !mbEof && (nBytes > 0) )
+ {
+ while( !mbEof && (maRecBuffer.getRecLeft() == 0) ) jumpToNextContinue();
+ mbEof = mbEof || (nBytes > maRecBuffer.getRecLeft());
+ OSL_ENSURE( !mbEof, "BiffInputStream::ensureRawReadSize - record overread" );
+ }
+ return !mbEof;
+}
+
+sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes ) const
+{
+ return getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() );
+}
+
+void BiffInputStream::appendUnicodeArray( OUStringBuffer& orBuffer, sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars )
+{
+ orBuffer.ensureCapacity( orBuffer.getLength() + nChars );
+ sal_uInt16 nChar;
+ for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx )
+ {
+ if( b16BitChars ) readValue( nChar ); else nChar = readuInt8();
+ orBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) );
+ }
+}
+
+void BiffInputStream::readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize )
+{
+ sal_uInt8 nFlags = readuInt8();
+ OSL_ENSURE( !getFlag( nFlags, BIFF_STRF_UNKNOWN ), "BiffInputStream::readUniStringHeader - unknown flags" );
+ orb16BitChars = getFlag( nFlags, BIFF_STRF_16BIT );
+ sal_uInt16 nFontCount = getFlag( nFlags, BIFF_STRF_RICH ) ? readuInt16() : 0;
+ sal_Int32 nPhoneticSize = getFlag( nFlags, BIFF_STRF_PHONETIC ) ? readInt32() : 0;
+ ornAddSize = 4 * nFontCount + ::std::max< sal_Int32 >( 0, nPhoneticSize );
+}
+
+// ============================================================================
+
+BiffInputStreamPos::BiffInputStreamPos( BiffInputStream& rStrm ) :
+ mrStrm( rStrm ),
+ mnRecHandle( rStrm.getRecHandle() ),
+ mnRecPos( rStrm.tell() )
+{
+}
+
+bool BiffInputStreamPos::restorePosition()
+{
+ bool bValidRec = mrStrm.startRecordByHandle( mnRecHandle );
+ if( bValidRec )
+ mrStrm.seek( mnRecPos );
+ return bValidRec && !mrStrm.isEof();
+}
+
+// ============================================================================
+
+BiffInputStreamPosGuard::BiffInputStreamPosGuard( BiffInputStream& rStrm ) :
+ BiffInputStreamPos( rStrm )
+{
+}
+
+BiffInputStreamPosGuard::~BiffInputStreamPosGuard()
+{
+ restorePosition();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/biffoutputstream.cxx b/oox/source/xls/biffoutputstream.cxx
new file mode 100644
index 000000000000..ba59f50bea4d
--- /dev/null
+++ b/oox/source/xls/biffoutputstream.cxx
@@ -0,0 +1,207 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/biffoutputstream.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.writeMemory( &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 )
+{
+}
+
+// record control -------------------------------------------------------------
+
+void BiffOutputStream::startRecord( sal_uInt16 nRecId )
+{
+ maRecBuffer.startRecord( nRecId );
+ setPortionSize( 0 );
+}
+
+void BiffOutputStream::endRecord()
+{
+ setPortionSize( 0 );
+ maRecBuffer.endRecord();
+}
+
+void BiffOutputStream::setPortionSize( sal_uInt16 nSize )
+{
+ OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::setPortionSize - block operation inside portion" );
+ mnPortionSize = nSize;
+ mnPortionPos = 0;
+}
+
+// BinaryStreamBase interface (seeking) ---------------------------------------
+
+sal_Int64 BiffOutputStream::tellBase() const
+{
+ return maRecBuffer.getBaseStream().tell();
+}
+
+sal_Int64 BiffOutputStream::getBaseLength() const
+{
+ return maRecBuffer.getBaseStream().getLength();
+}
+
+// BinaryOutputStream interface (stream write access) -------------------------
+
+void BiffOutputStream::writeData( const StreamDataSequence& rData )
+{
+ if( rData.hasElements() )
+ writeMemory( rData.getConstArray(), rData.getLength() );
+}
+
+void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
+{
+ if( pMem && (nBytes > 0) )
+ {
+ const sal_uInt8* pnBuffer = reinterpret_cast< const sal_uInt8* >( pMem );
+ sal_Int32 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_Int32 nBytes )
+{
+ sal_Int32 nBytesLeft = nBytes;
+ while( nBytesLeft > 0 )
+ {
+ sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft );
+ maRecBuffer.fill( nValue, nBlockSize );
+ nBytesLeft -= nBlockSize;
+ }
+}
+
+void BiffOutputStream::writeBlock( const void* pMem, sal_uInt16 nBytes )
+{
+ ensureRawBlock( nBytes );
+ maRecBuffer.write( pMem, nBytes );
+}
+
+// private --------------------------------------------------------------------
+
+void BiffOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize )
+{
+ // byte swapping is done in calling BinaryOutputStream::writeValue() template function
+ writeBlock( pMem, nSize );
+}
+
+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, "BiffOutputStream::ensureRawBlock - portion overflow" );
+ mnPortionPos = (mnPortionPos + nSize) % mnPortionSize; // prevent compiler warning, do not use operator+=, operator%=
+ }
+}
+
+sal_uInt16 BiffOutputStream::prepareRawBlock( sal_Int32 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_Int32 >( nTotalSize, 0, nRecLeft );
+ ensureRawBlock( nSize );
+ return nSize;
+}
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/chartsheetfragment.cxx b/oox/source/xls/chartsheetfragment.cxx
new file mode 100644
index 000000000000..c67768ef2f22
--- /dev/null
+++ b/oox/source/xls/chartsheetfragment.cxx
@@ -0,0 +1,291 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/chartsheetfragment.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetsettings.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+ChartsheetFragment::ChartsheetFragment( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath, const ISegmentProgressBarRef& rxProgressBar, sal_Int16 nSheet ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath, rxProgressBar, SHEETTYPE_CHARTSHEET, nSheet )
+{
+}
+
+ContextHandlerRef ChartsheetFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( chartsheet ) ) return this;
+ break;
+
+ case XLS_TOKEN( chartsheet ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheetViews ): return this;
+
+ case XLS_TOKEN( sheetPr ): getWorksheetSettings().importChartSheetPr( rAttribs ); break;
+ case XLS_TOKEN( sheetProtection ): getWorksheetSettings().importChartProtection( rAttribs ); break;
+ case XLS_TOKEN( pageMargins ): getPageSettings().importPageMargins( rAttribs ); break;
+ case XLS_TOKEN( pageSetup ): getPageSettings().importChartPageSetup( getRelations(), rAttribs ); break;
+ case XLS_TOKEN( headerFooter ): getPageSettings().importHeaderFooter( rAttribs ); return this;
+ case XLS_TOKEN( picture ): getPageSettings().importPicture( getRelations(), rAttribs ); break;
+ case XLS_TOKEN( drawing ): importDrawing( rAttribs ); break;
+ }
+ break;
+
+ case XLS_TOKEN( sheetViews ):
+ if( nElement == XLS_TOKEN( sheetView ) ) getSheetViewSettings().importChartSheetView( rAttribs );
+ break;
+
+ case XLS_TOKEN( headerFooter ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( firstHeader ):
+ case XLS_TOKEN( firstFooter ):
+ case XLS_TOKEN( oddHeader ):
+ case XLS_TOKEN( oddFooter ):
+ case XLS_TOKEN( evenHeader ):
+ case XLS_TOKEN( evenFooter ): return this; // collect contents in onCharacters()
+ }
+ break;
+ }
+ return 0;
+}
+
+void ChartsheetFragment::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ 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, getCurrentElement() );
+ break;
+ }
+}
+
+ContextHandlerRef ChartsheetFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_WORKSHEET ) return this;
+ break;
+
+ case BIFF12_ID_WORKSHEET:
+ switch( nRecId )
+ {
+ case BIFF12_ID_CHARTSHEETVIEWS: return this;
+
+ case BIFF12_ID_CHARTSHEETPR: getWorksheetSettings().importChartSheetPr( rStrm ); break;
+ case BIFF12_ID_CHARTPROTECTION: getWorksheetSettings().importChartProtection( rStrm ); break;
+ case BIFF12_ID_PAGEMARGINS: getPageSettings().importPageMargins( rStrm ); break;
+ case BIFF12_ID_CHARTPAGESETUP: getPageSettings().importChartPageSetup( getRelations(), rStrm ); break;
+ case BIFF12_ID_HEADERFOOTER: getPageSettings().importHeaderFooter( rStrm ); break;
+ case BIFF12_ID_PICTURE: getPageSettings().importPicture( getRelations(), rStrm ); break;
+ case BIFF12_ID_DRAWING: importDrawing( rStrm ); break;
+ }
+ break;
+
+ case BIFF12_ID_CHARTSHEETVIEWS:
+ if( nRecId == BIFF12_ID_CHARTSHEETVIEW ) getSheetViewSettings().importChartSheetView( rStrm );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* ChartsheetFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_CHARTSHEETVIEW, BIFF12_ID_CHARTSHEETVIEW + 1 },
+ { BIFF12_ID_CHARTSHEETVIEWS, BIFF12_ID_CHARTSHEETVIEWS + 1 },
+ { BIFF12_ID_CUSTOMCHARTVIEW, BIFF12_ID_CUSTOMCHARTVIEW + 1 },
+ { BIFF12_ID_CUSTOMCHARTVIEWS, BIFF12_ID_CUSTOMCHARTVIEWS + 1 },
+ { BIFF12_ID_HEADERFOOTER, BIFF12_ID_HEADERFOOTER + 1 },
+ { BIFF12_ID_WORKSHEET, BIFF12_ID_WORKSHEET + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void ChartsheetFragment::initializeImport()
+{
+ // initial processing in base class WorksheetHelper
+ initializeWorksheetImport();
+}
+
+void ChartsheetFragment::finalizeImport()
+{
+ // final processing in base class WorksheetHelper
+ finalizeWorksheetImport();
+}
+
+// private --------------------------------------------------------------------
+
+void ChartsheetFragment::importDrawing( const AttributeList& rAttribs )
+{
+ setDrawingPath( getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) ) );
+}
+
+void ChartsheetFragment::importDrawing( SequenceInputStream& rStrm )
+{
+ setDrawingPath( getFragmentPathFromRelId( BiffHelper::readString( rStrm ) ) );
+}
+
+// ============================================================================
+
+BiffChartsheetFragment::BiffChartsheetFragment( const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar, sal_Int16 nSheet ) :
+ BiffWorksheetFragmentBase( rParent, rxProgressBar, SHEETTYPE_CHARTSHEET, nSheet )
+{
+}
+
+bool BiffChartsheetFragment::importFragment()
+{
+ // initial processing in base class WorksheetHelper
+ initializeWorksheetImport();
+
+ WorksheetSettings& rWorksheetSett = getWorksheetSettings();
+ SheetViewSettings& rSheetViewSett = getSheetViewSettings();
+ PageSettings& rPageSett = getPageSettings();
+
+ // process all record in this sheet fragment
+ BiffInputStream& rStrm = getInputStream();
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ {
+ if( BiffHelper::isBofRecord( rStrm ) )
+ {
+ // skip unknown embedded fragments (BOF/EOF blocks)
+ skipFragment();
+ }
+ else
+ {
+ sal_uInt16 nRecId = rStrm.getRecId();
+ switch( nRecId )
+ {
+ // records in all BIFF versions
+ case BIFF_ID_BOTTOMMARGIN: rPageSett.importBottomMargin( rStrm ); break;
+ case BIFF_ID_CHBEGIN: BiffHelper::skipRecordBlock( rStrm, BIFF_ID_CHEND ); break;
+ case BIFF_ID_FOOTER: rPageSett.importFooter( rStrm ); break;
+ case BIFF_ID_HEADER: rPageSett.importHeader( rStrm ); break;
+ case BIFF_ID_LEFTMARGIN: rPageSett.importLeftMargin( rStrm ); break;
+ case BIFF_ID_PASSWORD: rWorksheetSett.importPassword( rStrm ); break;
+ case BIFF_ID_PROTECT: rWorksheetSett.importProtect( rStrm ); break;
+ case BIFF_ID_RIGHTMARGIN: rPageSett.importRightMargin( rStrm ); break;
+ case BIFF_ID_TOPMARGIN: rPageSett.importTopMargin( rStrm ); break;
+
+ // BIFF specific records
+ default: switch( getBiff() )
+ {
+ case BIFF2: switch( nRecId )
+ {
+ case BIFF2_ID_WINDOW2: rSheetViewSett.importWindow2( rStrm ); break;
+ }
+ break;
+
+ case BIFF3: switch( nRecId )
+ {
+ case BIFF_ID_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( 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_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( rStrm ); break;
+ case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( 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_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( rStrm ); break;
+ case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( rStrm ); break;
+ case BIFF_ID_SCENPROTECT: rWorksheetSett.importScenProtect( rStrm ); break;
+ case BIFF_ID_SCL: rSheetViewSett.importScl( 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_CODENAME: rWorksheetSett.importCodeName( rStrm ); break;
+ case BIFF_ID_HCENTER: rPageSett.importHorCenter( rStrm ); break;
+ case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( rStrm ); break;
+ case BIFF_ID_PICTURE: rPageSett.importPicture( rStrm ); break;
+ case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( rStrm ); break;
+ case BIFF_ID_SCL: rSheetViewSett.importScl( rStrm ); break;
+ case BIFF_ID_SHEETEXT: rWorksheetSett.importSheetExt( rStrm ); break;
+ case BIFF_ID_VCENTER: rPageSett.importVerCenter( rStrm ); break;
+ case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( rStrm ); break;
+ }
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+ }
+ }
+ }
+
+ // final processing in base class WorksheetHelper
+ finalizeWorksheetImport();
+ return rStrm.getRecId() == BIFF_ID_EOF;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx
new file mode 100644
index 000000000000..78d5fe044fe8
--- /dev/null
+++ b/oox/source/xls/commentsbuffer.cxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/commentsbuffer.hxx"
+
+#include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp>
+#include <com/sun/star/sheet/XSheetAnnotations.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/drawingfragment.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+CommentModel::CommentModel() :
+ mnAuthorId( -1 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+Comment::Comment( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void Comment::importComment( const AttributeList& rAttribs )
+{
+ maModel.mnAuthorId = rAttribs.getInteger( XML_authorId, -1 );
+ // cell range will be checked while inserting the comment into the document
+ getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex() );
+}
+
+void Comment::importComment( SequenceInputStream& rStrm )
+{
+ BinRange aBinRange;
+ rStrm >> maModel.mnAuthorId >> aBinRange;
+ // cell range will be checked while inserting the comment into the document
+ getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, aBinRange, getSheetIndex() );
+}
+
+RichStringRef Comment::createText()
+{
+ maModel.mxText.reset( new RichString( *this ) );
+ return maModel.mxText;
+}
+
+void Comment::finalizeImport()
+{
+ // BIFF12 stores cell range instead of cell address, use first cell of this range
+ OSL_ENSURE( (maModel.maRange.StartColumn == maModel.maRange.EndColumn) &&
+ (maModel.maRange.StartRow == maModel.maRange.EndRow),
+ "Comment::finalizeImport - comment anchor should be a single cell" );
+ CellAddress aNotePos( maModel.maRange.Sheet, maModel.maRange.StartColumn, maModel.maRange.StartRow );
+ if( getAddressConverter().checkCellAddress( aNotePos, true ) && maModel.mxText.get() ) try
+ {
+ maModel.mxText->finalizeImport();
+ OUString aNoteText = maModel.mxText->getPlainText();
+ // non-empty string required by note implementation
+ if( aNoteText.getLength() > 0 )
+ {
+ Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW );
+ Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW );
+ xAnnos->insertNew( aNotePos, aNoteText );
+ // receive craeted note from cell (insertNew does not return the note)
+ Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( aNotePos ), UNO_QUERY_THROW );
+ Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW );
+ Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW );
+ Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW );
+ // convert shape formatting
+ if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( aNotePos ) )
+ {
+ // position and formatting
+ pNoteShape->convertFormatting( xAnnoShape );
+ // visibility
+ const ::oox::vml::ClientData* pClientData = pNoteShape->getClientData();
+ xAnno->setIsVisible( pClientData && pClientData->mbVisible );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+CommentsBuffer::CommentsBuffer( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void CommentsBuffer::appendAuthor( const OUString& rAuthor )
+{
+ maAuthors.push_back( rAuthor );
+}
+
+CommentRef CommentsBuffer::createComment()
+{
+ CommentRef xComment( new Comment( *this ) );
+ maComments.push_back( xComment );
+ return xComment;
+}
+
+void CommentsBuffer::finalizeImport()
+{
+ maComments.forEachMem( &Comment::finalizeImport );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/commentsfragment.cxx b/oox/source/xls/commentsfragment.cxx
new file mode 100644
index 000000000000..b37860c4553e
--- /dev/null
+++ b/oox/source/xls/commentsfragment.cxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/commentsfragment.hxx"
+
+#include "oox/xls/richstringcontext.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+CommentsFragment::CommentsFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+ContextHandlerRef CommentsFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( comments ) ) return this;
+ break;
+ case XLS_TOKEN( comments ):
+ if( nElement == XLS_TOKEN( authors ) ) return this;
+ if( nElement == XLS_TOKEN( commentList ) ) return this;
+ break;
+ case XLS_TOKEN( authors ):
+ if( nElement == XLS_TOKEN( author ) ) return this; // collect author in onCharacters()
+ break;
+ case XLS_TOKEN( commentList ):
+ if( nElement == XLS_TOKEN( comment ) ) { importComment( rAttribs ); return this; }
+ break;
+ case XLS_TOKEN( comment ):
+ if( (nElement == XLS_TOKEN( text )) && mxComment.get() )
+ return new RichStringContext( *this, mxComment->createText() );
+ break;
+ }
+ return 0;
+}
+
+void CommentsFragment::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( XLS_TOKEN( author ) ) )
+ getComments().appendAuthor( rChars );
+}
+
+void CommentsFragment::onEndElement()
+{
+ if( isCurrentElement( XLS_TOKEN( comment ) ) )
+ mxComment.reset();
+}
+
+ContextHandlerRef CommentsFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_COMMENTS ) return this;
+ break;
+ case BIFF12_ID_COMMENTS:
+ if( nRecId == BIFF12_ID_COMMENTAUTHORS ) return this;
+ if( nRecId == BIFF12_ID_COMMENTLIST ) return this;
+ break;
+ case BIFF12_ID_COMMENTAUTHORS:
+ if( nRecId == BIFF12_ID_COMMENTAUTHOR ) getComments().appendAuthor( BiffHelper::readString( rStrm ) );
+ break;
+ case BIFF12_ID_COMMENTLIST:
+ if( nRecId == BIFF12_ID_COMMENT ) { importComment( rStrm ); return this; }
+ break;
+ case BIFF12_ID_COMMENT:
+ if( (nRecId == BIFF12_ID_COMMENTTEXT) && mxComment.get() )
+ mxComment->createText()->importString( rStrm, true );
+ break;
+ }
+ return 0;
+}
+
+void CommentsFragment::onEndRecord()
+{
+ if( isCurrentElement( BIFF12_ID_COMMENT ) )
+ mxComment.reset();
+}
+
+const RecordInfo* CommentsFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_COMMENT, BIFF12_ID_COMMENT + 1 },
+ { BIFF12_ID_COMMENTAUTHORS, BIFF12_ID_COMMENTAUTHORS + 1 },
+ { BIFF12_ID_COMMENTLIST, BIFF12_ID_COMMENTLIST + 1 },
+ { BIFF12_ID_COMMENTS, BIFF12_ID_COMMENTS + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+// private --------------------------------------------------------------------
+
+void CommentsFragment::importComment( const AttributeList& rAttribs )
+{
+ mxComment = getComments().createComment();
+ mxComment->importComment( rAttribs );
+}
+
+void CommentsFragment::importComment( SequenceInputStream& rStrm )
+{
+ mxComment = getComments().createComment();
+ mxComment->importComment( rStrm );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/condformatbuffer.cxx b/oox/source/xls/condformatbuffer.cxx
new file mode 100644
index 000000000000..51d9170e1794
--- /dev/null
+++ b/oox/source/xls/condformatbuffer.cxx
@@ -0,0 +1,774 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/condformatbuffer.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/sheet/ConditionOperator.hpp>
+#include <com/sun/star/sheet/XSheetCellRanges.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 BIFF12_CFRULE_TYPE_CELLIS = 1;
+const sal_Int32 BIFF12_CFRULE_TYPE_EXPRESSION = 2;
+const sal_Int32 BIFF12_CFRULE_TYPE_COLORSCALE = 3;
+const sal_Int32 BIFF12_CFRULE_TYPE_DATABAR = 4;
+const sal_Int32 BIFF12_CFRULE_TYPE_TOPTEN = 5;
+const sal_Int32 BIFF12_CFRULE_TYPE_ICONSET = 6;
+
+const sal_Int32 BIFF12_CFRULE_SUB_CELLIS = 0;
+const sal_Int32 BIFF12_CFRULE_SUB_EXPRESSION = 1;
+const sal_Int32 BIFF12_CFRULE_SUB_COLORSCALE = 2;
+const sal_Int32 BIFF12_CFRULE_SUB_DATABAR = 3;
+const sal_Int32 BIFF12_CFRULE_SUB_ICONSET = 4;
+const sal_Int32 BIFF12_CFRULE_SUB_TOPTEN = 5;
+const sal_Int32 BIFF12_CFRULE_SUB_UNIQUE = 7;
+const sal_Int32 BIFF12_CFRULE_SUB_TEXT = 8;
+const sal_Int32 BIFF12_CFRULE_SUB_BLANK = 9;
+const sal_Int32 BIFF12_CFRULE_SUB_NOTBLANK = 10;
+const sal_Int32 BIFF12_CFRULE_SUB_ERROR = 11;
+const sal_Int32 BIFF12_CFRULE_SUB_NOTERROR = 12;
+const sal_Int32 BIFF12_CFRULE_SUB_TODAY = 15;
+const sal_Int32 BIFF12_CFRULE_SUB_TOMORROW = 16;
+const sal_Int32 BIFF12_CFRULE_SUB_YESTERDAY = 17;
+const sal_Int32 BIFF12_CFRULE_SUB_LAST7DAYS = 18;
+const sal_Int32 BIFF12_CFRULE_SUB_LASTMONTH = 19;
+const sal_Int32 BIFF12_CFRULE_SUB_NEXTMONTH = 20;
+const sal_Int32 BIFF12_CFRULE_SUB_THISWEEK = 21;
+const sal_Int32 BIFF12_CFRULE_SUB_NEXTWEEK = 22;
+const sal_Int32 BIFF12_CFRULE_SUB_LASTWEEK = 23;
+const sal_Int32 BIFF12_CFRULE_SUB_THISMONTH = 24;
+const sal_Int32 BIFF12_CFRULE_SUB_ABOVEAVERAGE = 25;
+const sal_Int32 BIFF12_CFRULE_SUB_BELOWAVERAGE = 26;
+const sal_Int32 BIFF12_CFRULE_SUB_DUPLICATE = 27;
+const sal_Int32 BIFF12_CFRULE_SUB_EQABOVEAVERAGE = 29;
+const sal_Int32 BIFF12_CFRULE_SUB_EQBELOWAVERAGE = 30;
+
+const sal_Int32 BIFF12_CFRULE_TIMEOP_TODAY = 0;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_YESTERDAY = 1;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_LAST7DAYS = 2;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_THISWEEK = 3;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTWEEK = 4;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTMONTH = 5;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_TOMORROW = 6;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTWEEK = 7;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTMONTH = 8;
+const sal_Int32 BIFF12_CFRULE_TIMEOP_THISMONTH = 9;
+
+const sal_uInt16 BIFF12_CFRULE_STOPIFTRUE = 0x0002;
+const sal_uInt16 BIFF12_CFRULE_ABOVEAVERAGE = 0x0004;
+const sal_uInt16 BIFF12_CFRULE_BOTTOM = 0x0008;
+const sal_uInt16 BIFF12_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
+
+// ============================================================================
+
+CondFormatRuleModel::CondFormatRuleModel() :
+ 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 CondFormatRuleModel::setBiffOperator( 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 CondFormatRuleModel::setBiff12TextType( 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 )
+{
+ maModel.maText = rAttribs.getString( XML_text, OUString() );
+ maModel.mnPriority = rAttribs.getInteger( XML_priority, -1 );
+ maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
+ maModel.mnOperator = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID );
+ maModel.mnTimePeriod = rAttribs.getToken( XML_timePeriod, XML_TOKEN_INVALID );
+ maModel.mnRank = rAttribs.getInteger( XML_rank, 0 );
+ maModel.mnStdDev = rAttribs.getInteger( XML_stdDev, 0 );
+ maModel.mnDxfId = rAttribs.getInteger( XML_dxfId, -1 );
+ maModel.mbStopIfTrue = rAttribs.getBool( XML_stopIfTrue, false );
+ maModel.mbBottom = rAttribs.getBool( XML_bottom, false );
+ maModel.mbPercent = rAttribs.getBool( XML_percent, false );
+ maModel.mbAboveAverage = rAttribs.getBool( XML_aboveAverage, true );
+ maModel.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 );
+ maModel.maFormulas.push_back( aContext );
+}
+
+void CondFormatRule::importCfRule( SequenceInputStream& rStrm )
+{
+ sal_Int32 nType, nSubType, nOperator, nFmla1Size, nFmla2Size, nFmla3Size;
+ sal_uInt16 nFlags;
+ rStrm >> nType >> nSubType >> maModel.mnDxfId >> maModel.mnPriority >> nOperator;
+ rStrm.skip( 8 );
+ rStrm >> nFlags >> nFmla1Size >> nFmla2Size >> nFmla3Size >> maModel.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.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
+ if( rStrm.getRemaining() >= 8 )
+ {
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( mrCondFormat.getRanges().getBaseAddress() );
+ getFormulaParser().importFormula( aContext, rStrm );
+ maModel.maFormulas.push_back( aContext );
+
+ // second formula
+ OSL_ENSURE( (nFmla2Size >= 0) || (nFmla3Size == 0), "CondFormatRule::importCfRule - missing second formula" );
+ OSL_ENSURE( (nFmla2Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
+ if( rStrm.getRemaining() >= 8 )
+ {
+ getFormulaParser().importFormula( aContext, rStrm );
+ maModel.maFormulas.push_back( aContext );
+
+ // third formula
+ OSL_ENSURE( (nFmla3Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
+ if( rStrm.getRemaining() >= 8 )
+ {
+ getFormulaParser().importFormula( aContext, rStrm );
+ maModel.maFormulas.push_back( aContext );
+ }
+ }
+ }
+
+ // flags
+ maModel.mbStopIfTrue = getFlag( nFlags, BIFF12_CFRULE_STOPIFTRUE );
+ maModel.mbBottom = getFlag( nFlags, BIFF12_CFRULE_BOTTOM );
+ maModel.mbPercent = getFlag( nFlags, BIFF12_CFRULE_PERCENT );
+ maModel.mbAboveAverage = getFlag( nFlags, BIFF12_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 BIFF12_CFRULE_TYPE_CELLIS:
+ OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_CELLIS, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ maModel.mnType = XML_cellIs;
+ maModel.setBiffOperator( nOperator );
+ OSL_ENSURE( maModel.mnOperator != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unknown operator" );
+ break;
+ case BIFF12_CFRULE_TYPE_EXPRESSION:
+ // here we have to look at the subtype to find the real type...
+ switch( nSubType )
+ {
+ case BIFF12_CFRULE_SUB_EXPRESSION:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_expression;
+ break;
+ case BIFF12_CFRULE_SUB_UNIQUE:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_uniqueValues;
+ break;
+ case BIFF12_CFRULE_SUB_TEXT:
+ maModel.setBiff12TextType( nOperator );
+ OSL_ENSURE( maModel.mnType != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unexpected operator value" );
+ break;
+ case BIFF12_CFRULE_SUB_BLANK:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_containsBlanks;
+ break;
+ case BIFF12_CFRULE_SUB_NOTBLANK:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_notContainsBlanks;
+ break;
+ case BIFF12_CFRULE_SUB_ERROR:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_containsErrors;
+ break;
+ case BIFF12_CFRULE_SUB_NOTERROR:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_notContainsErrors;
+ break;
+ case BIFF12_CFRULE_SUB_TODAY:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_TODAY, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_today;
+ break;
+ case BIFF12_CFRULE_SUB_TOMORROW:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_TOMORROW, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_tomorrow;
+ break;
+ case BIFF12_CFRULE_SUB_YESTERDAY:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_YESTERDAY, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_yesterday;
+ break;
+ case BIFF12_CFRULE_SUB_LAST7DAYS:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LAST7DAYS, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_last7Days;
+ break;
+ case BIFF12_CFRULE_SUB_LASTMONTH:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LASTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_lastMonth;
+ break;
+ case BIFF12_CFRULE_SUB_NEXTMONTH:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_NEXTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_nextMonth;
+ break;
+ case BIFF12_CFRULE_SUB_THISWEEK:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_THISWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_thisWeek;
+ break;
+ case BIFF12_CFRULE_SUB_NEXTWEEK:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_NEXTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_nextWeek;
+ break;
+ case BIFF12_CFRULE_SUB_LASTWEEK:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LASTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_lastWeek;
+ break;
+ case BIFF12_CFRULE_SUB_THISMONTH:
+ OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_THISMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
+ maModel.mnType = XML_timePeriod;
+ maModel.mnTimePeriod = XML_thisMonth;
+ break;
+ case BIFF12_CFRULE_SUB_ABOVEAVERAGE:
+ OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maModel.mnType = XML_aboveAverage;
+ maModel.mnStdDev = nOperator; // operator field used for standard deviation
+ maModel.mbAboveAverage = true;
+ maModel.mbEqualAverage = false; // does not exist as real flag...
+ break;
+ case BIFF12_CFRULE_SUB_BELOWAVERAGE:
+ OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maModel.mnType = XML_aboveAverage;
+ maModel.mnStdDev = nOperator; // operator field used for standard deviation
+ maModel.mbAboveAverage = false;
+ maModel.mbEqualAverage = false; // does not exist as real flag...
+ break;
+ case BIFF12_CFRULE_SUB_DUPLICATE:
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_duplicateValues;
+ break;
+ case BIFF12_CFRULE_SUB_EQABOVEAVERAGE:
+ OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maModel.mnType = XML_aboveAverage;
+ maModel.mnStdDev = nOperator; // operator field used for standard deviation
+ maModel.mbAboveAverage = true;
+ maModel.mbEqualAverage = true; // does not exist as real flag...
+ break;
+ case BIFF12_CFRULE_SUB_EQBELOWAVERAGE:
+ OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
+ maModel.mnType = XML_aboveAverage;
+ maModel.mnStdDev = nOperator; // operator field used for standard deviation
+ maModel.mbAboveAverage = false;
+ maModel.mbEqualAverage = true; // does not exist as real flag...
+ break;
+ }
+ break;
+ case BIFF12_CFRULE_TYPE_COLORSCALE:
+ OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_COLORSCALE, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_colorScale;
+ break;
+ case BIFF12_CFRULE_TYPE_DATABAR:
+ OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_DATABAR, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.mnType = XML_dataBar;
+ break;
+ case BIFF12_CFRULE_TYPE_TOPTEN:
+ OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_TOPTEN, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ maModel.mnType = XML_top10;
+ maModel.mnRank = nOperator; // operator field used for rank value
+ break;
+ case BIFF12_CFRULE_TYPE_ICONSET:
+ OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_ICONSET, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
+ OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
+ maModel.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 };
+ maModel.mnType = STATIC_ARRAY_SELECT( spnTypeIds, nType, XML_TOKEN_INVALID );
+
+ maModel.setBiffOperator( nOperator );
+ maModel.mnPriority = nPriority;
+ maModel.mbStopIfTrue = true;
+
+ DxfRef xDxf = getStyles().createDxf( &maModel.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 );
+ maModel.maFormulas.push_back( aContext );
+ if( nFmla2Size > 0 )
+ {
+ getFormulaParser().importFormula( aContext, rStrm, &nFmla2Size );
+ maModel.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 relative 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.
+ - '#C' will be replaced by one of the comparison operators <, >, <=, or
+ >=, according to the 'aboveAverage' and 'equalAverage' flags.
+ */
+ OUString aReplaceFormula;
+
+ switch( maModel.mnType )
+ {
+ case XML_cellIs:
+ eOperator = CondFormatBuffer::convertToApiOperator( maModel.mnOperator );
+ break;
+ case XML_expression:
+ eOperator = ::com::sun::star::sheet::ConditionOperator_FORMULA;
+ break;
+ case XML_containsText:
+ OSL_ENSURE( maModel.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( maModel.mnOperator == XML_notContains, "CondFormatRule::finalizeImport - unexpected operator" );
+ aReplaceFormula = CREATE_OUSTRING( "ISERROR(SEARCH(#T,#B))" );
+ break;
+ case XML_beginsWith:
+ OSL_ENSURE( maModel.mnOperator == XML_beginsWith, "CondFormatRule::finalizeImport - unexpected operator" );
+ aReplaceFormula = CREATE_OUSTRING( "LEFT(#B,#L)=#T" );
+ break;
+ case XML_endsWith:
+ OSL_ENSURE( maModel.mnOperator == XML_endsWith, "CondFormatRule::finalizeImport - unexpected operator" );
+ aReplaceFormula = CREATE_OUSTRING( "RIGHT(#B,#L)=#T" );
+ break;
+ case XML_timePeriod:
+ switch( maModel.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( maModel.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( maModel.mnStdDev == 0 )
+ aReplaceFormula = CREATE_OUSTRING( "#B#CAVERAGE(#R)" );
+ break;
+ }
+
+ if( aReplaceFormula.getLength() > 0 )
+ {
+ OUString aAddress, aRanges, aText, aComp;
+ 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 )
+ // quote the comparison text, and handle embedded quote characters
+ aText = FormulaProcessorBase::generateApiString( maModel.maText );
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aText );
+ break;
+ case 'L': // length of comparison text
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
+ OUString::valueOf( maModel.maText.getLength() ) );
+ break;
+ case 'K': // top-10 rank
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
+ OUString::valueOf( maModel.mnRank ) );
+ break;
+ case 'M': // top-10 top/bottom flag
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
+ OUString::valueOf( static_cast< sal_Int32 >( maModel.mbBottom ? 1 : 0 ) ) );
+ break;
+ case 'C': // average comparison operator
+ if( aComp.getLength() == 0 )
+ aComp = maModel.mbAboveAverage ?
+ (maModel.mbEqualAverage ? CREATE_OUSTRING( ">=" ) : CREATE_OUSTRING( ">" )) :
+ (maModel.mbEqualAverage ? CREATE_OUSTRING( "<=" ) : CREATE_OUSTRING( "<" ));
+ aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aComp );
+ break;
+ default:
+ OSL_ENSURE( false, "CondFormatRule::finalizeImport - unknown placeholder" );
+ }
+ }
+
+ // set the replacement formula
+ maModel.maFormulas.clear();
+ appendFormula( aReplaceFormula );
+ eOperator = ::com::sun::star::sheet::ConditionOperator_FORMULA;
+ }
+
+ if( rxEntries.is() && (eOperator != ::com::sun::star::sheet::ConditionOperator_NONE) && !maModel.maFormulas.empty() )
+ {
+ ::std::vector< PropertyValue > aProps;
+ // create condition properties
+ lclAppendProperty( aProps, CREATE_OUSTRING( "Operator" ), eOperator );
+ lclAppendProperty( aProps, CREATE_OUSTRING( "Formula1" ), maModel.maFormulas[ 0 ].getTokens() );
+ if( maModel.maFormulas.size() >= 2 )
+ lclAppendProperty( aProps, CREATE_OUSTRING( "Formula2" ), maModel.maFormulas[ 1 ].getTokens() );
+
+ // style name for the formatting attributes
+ OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
+ if( aStyleName.getLength() > 0 )
+ lclAppendProperty( aProps, CREATE_OUSTRING( "StyleName" ), aStyleName );
+
+ // append the new rule
+ try
+ {
+ rxEntries->addNew( ContainerHelper::vectorToSequence( aProps ) );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+// ============================================================================
+
+CondFormatModel::CondFormatModel() :
+ mbPivot( false )
+{
+}
+
+// ============================================================================
+
+CondFormat::CondFormat( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void CondFormat::importConditionalFormatting( const AttributeList& rAttribs )
+{
+ getAddressConverter().convertToCellRangeList( maModel.maRanges, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), true );
+ maModel.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( SequenceInputStream& rStrm )
+{
+ BinRangeList aRanges;
+ rStrm.skip( 8 );
+ rStrm >> aRanges;
+ getAddressConverter().convertToCellRangeList( maModel.maRanges, aRanges, getSheetIndex(), true );
+}
+
+void CondFormat::importCfRule( SequenceInputStream& 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( maModel.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()
+{
+ try
+ {
+ Reference< XSheetCellRanges > xRanges( getCellRangeList( maModel.maRanges ), UNO_SET_THROW );
+ PropertySet aPropSet( xRanges );
+ Reference< XSheetConditionalEntries > xEntries( aPropSet.getAnyProperty( PROP_ConditionalFormat ), UNO_QUERY_THROW );
+ // maRules is sorted by rule priority
+ maRules.forEachMem( &CondFormatRule::finalizeImport, ::boost::cref( xEntries ) );
+ aPropSet.setProperty( PROP_ConditionalFormat, xEntries );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+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( SequenceInputStream& rStrm )
+{
+ CondFormatRef xCondFmt = createCondFormat();
+ xCondFmt->importCondFormatting( rStrm );
+ return xCondFmt;
+}
+
+void CondFormatBuffer::importCfHeader( BiffInputStream& rStrm )
+{
+ createCondFormat()->importCfHeader( rStrm );
+}
+
+void CondFormatBuffer::finalizeImport()
+{
+ maCondFormats.forEachMem( &CondFormat::finalizeImport );
+}
+
+ConditionOperator CondFormatBuffer::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;
+}
+
+// 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..091dc11fb614
--- /dev/null
+++ b/oox/source/xls/condformatcontext.cxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/condformatcontext.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+CondFormatContext::CondFormatContext( WorksheetFragmentBase& rFragment ) :
+ WorksheetContextBase( rFragment )
+{
+}
+
+ContextHandlerRef CondFormatContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( conditionalFormatting ):
+ return (nElement == XLS_TOKEN( cfRule )) ? this : 0;
+ case XLS_TOKEN( cfRule ):
+ return (nElement == XLS_TOKEN( formula )) ? this : 0;
+ }
+ return 0;
+}
+
+void CondFormatContext::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( conditionalFormatting ):
+ mxCondFmt = getCondFormats().importConditionalFormatting( rAttribs );
+ break;
+ case XLS_TOKEN( cfRule ):
+ if( mxCondFmt.get() ) mxRule = mxCondFmt->importCfRule( rAttribs );
+ break;
+ }
+}
+
+void CondFormatContext::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( XLS_TOKEN( formula ) ) && mxCondFmt.get() && mxRule.get() )
+ mxRule->appendFormula( rChars );
+}
+
+ContextHandlerRef CondFormatContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_CONDFORMATTING:
+ return (nRecId == BIFF12_ID_CFRULE) ? this : 0;
+ }
+ return 0;
+}
+
+void CondFormatContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_CONDFORMATTING:
+ mxCondFmt = getCondFormats().importCondFormatting( rStrm );
+ break;
+ case BIFF12_ID_CFRULE:
+ if( mxCondFmt.get() ) mxCondFmt->importCfRule( rStrm );
+ break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/connectionsbuffer.cxx b/oox/source/xls/connectionsbuffer.cxx
new file mode 100755
index 000000000000..6d0fcd65122f
--- /dev/null
+++ b/oox/source/xls/connectionsbuffer.cxx
@@ -0,0 +1,501 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/connectionsbuffer.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 BIFF12_RECONNECT_AS_REQUIRED = 1;
+const sal_Int32 BIFF12_RECONNECT_ALWAYS = 2;
+const sal_Int32 BIFF12_RECONNECT_NEVER = 3;
+
+const sal_uInt8 BIFF12_CONNECTION_SAVEPASSWORD_ON = 1;
+const sal_uInt8 BIFF12_CONNECTION_SAVEPASSWORD_OFF = 2;
+
+const sal_uInt16 BIFF12_CONNECTION_KEEPALIVE = 0x0001;
+const sal_uInt16 BIFF12_CONNECTION_NEW = 0x0002;
+const sal_uInt16 BIFF12_CONNECTION_DELETED = 0x0004;
+const sal_uInt16 BIFF12_CONNECTION_ONLYUSECONNFILE = 0x0008;
+const sal_uInt16 BIFF12_CONNECTION_BACKGROUND = 0x0010;
+const sal_uInt16 BIFF12_CONNECTION_REFRESHONLOAD = 0x0020;
+const sal_uInt16 BIFF12_CONNECTION_SAVEDATA = 0x0040;
+
+const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCEFILE = 0x0001;
+const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCECONNFILE = 0x0002;
+const sal_uInt16 BIFF12_CONNECTION_HAS_DESCRIPTION = 0x0004;
+const sal_uInt16 BIFF12_CONNECTION_HAS_NAME = 0x0008;
+const sal_uInt16 BIFF12_CONNECTION_HAS_SSOID = 0x0010;
+
+const sal_uInt32 BIFF12_WEBPR_XML = 0x00000100;
+const sal_uInt32 BIFF12_WEBPR_SOURCEDATA = 0x00000200;
+const sal_uInt32 BIFF12_WEBPR_PARSEPRE = 0x00000400;
+const sal_uInt32 BIFF12_WEBPR_CONSECUTIVE = 0x00000800;
+const sal_uInt32 BIFF12_WEBPR_FIRSTROW = 0x00001000;
+const sal_uInt32 BIFF12_WEBPR_XL97CREATED = 0x00002000;
+const sal_uInt32 BIFF12_WEBPR_TEXTDATES = 0x00004000;
+const sal_uInt32 BIFF12_WEBPR_XL2000REFRESHED = 0x00008000;
+const sal_uInt32 BIFF12_WEBPR_HTMLTABLES = 0x00010000;
+
+const sal_uInt8 BIFF12_WEBPR_HAS_POSTMETHOD = 0x01;
+const sal_uInt8 BIFF12_WEBPR_HAS_EDITPAGE = 0x02;
+const sal_uInt8 BIFF12_WEBPR_HAS_URL = 0x04;
+
+const sal_uInt16 BIFF_DBQUERY_ODBC = 0x0008;
+const sal_uInt16 BIFF_DBQUERY_SQLQUERY = 0x0010;
+const sal_uInt16 BIFF_DBQUERY_SERVERBASEDSQL = 0x0020;
+const sal_uInt16 BIFF_DBQUERY_HTML = 0x0040;
+const sal_uInt16 BIFF_DBQUERY_SAVEPASSWORD = 0x0080;
+const sal_uInt16 BIFF_DBQUERY_HTMLTABLES = 0x0100;
+
+const sal_uInt16 BIFF_QTSETTINGS_KEEPALIVE = 0x0001;
+const sal_uInt16 BIFF_QTSETTINGS_NEW = 0x0002;
+const sal_uInt16 BIFF_QTSETTINGS_SOURCEDATA = 0x0004;
+const sal_uInt16 BIFF_QTSETTINGS_WEBBASEDPROV = 0x0008;
+const sal_uInt16 BIFF_QTSETTINGS_REINITLIST = 0x0010;
+const sal_uInt16 BIFF_QTSETTINGS_XML = 0x0080;
+
+const sal_uInt16 BIFF_QTSETTINGS_PARSEPRE = 0x0001;
+const sal_uInt16 BIFF_QTSETTINGS_CONSECUTIVE = 0x0002;
+const sal_uInt16 BIFF_QTSETTINGS_FIRSTROW = 0x0004;
+const sal_uInt16 BIFF_QTSETTINGS_XL97CREATED = 0x0008;
+const sal_uInt16 BIFF_QTSETTINGS_TEXTDATES = 0x0010;
+const sal_uInt16 BIFF_QTSETTINGS_XL2000REFRESHED = 0x0020;
+
+const sal_uInt16 BIFF_QTSETTINGS_TEXTQUERY = 0x0001;
+const sal_uInt16 BIFF_QTSETTINGS_TABLENAMES = 0x0002;
+
+// ----------------------------------------------------------------------------
+
+OUString lclReadQueryString( BiffInputStream& rStrm, sal_uInt16 nCount )
+{
+ bool bValidRec = true;
+ OUStringBuffer aBuffer;
+ for( sal_uInt16 nIndex = 0; bValidRec && (nIndex < nCount); ++nIndex )
+ {
+ bValidRec = (rStrm.getNextRecId() == BIFF_ID_PCITEM_STRING) && rStrm.startNextRecord();
+ if( bValidRec )
+ aBuffer.append( rStrm.readUniString() );
+ }
+ OSL_ENSURE( bValidRec, "lclReadQueryString - missing PCITEM_STRING records" );
+ return aBuffer.makeStringAndClear();
+}
+
+void lclParseTables( WebPrModel::TablesVector& rTables, const OUString& rTableNames )
+{
+ rTables.clear();
+ OUString aTableNames = rTableNames.trim();
+ while( aTableNames.getLength() > 0 )
+ {
+ sal_Int32 nSep = -1;
+ // table names are enclosed in double quotes
+ if( aTableNames[ 0 ] == '"' )
+ {
+ // search closing quote character
+ sal_Int32 nEndQuote = aTableNames.indexOf( '"', 1 );
+ OSL_ENSURE( nEndQuote >= 1, "lclParseTables - invalid syntax" );
+ if( nEndQuote < 0 )
+ nEndQuote = aTableNames.getLength();
+ else
+ nSep = aTableNames.indexOf( ',', nEndQuote + 1 );
+ // extract text between quote characters
+ OUString aTableName = aTableNames.copy( 1, nEndQuote - 1 ).trim();
+ if( aTableName.getLength() > 0 )
+ rTables.push_back( Any( aTableName ) );
+ else
+ rTables.push_back( Any() );
+ }
+ else
+ {
+ nSep = aTableNames.indexOf( ',' );
+ if( nSep < 0 )
+ nSep = aTableNames.getLength();
+ OUString aTableIndex = aTableNames.copy( 0, nSep ).trim();
+ if( (aTableIndex.getLength() > 0) && (aTableIndex[ 0 ] >= '1') && (aTableIndex[ 0 ] <= '9') )
+ rTables.push_back( Any( aTableIndex.toInt32() ) );
+ else
+ rTables.push_back( Any() );
+ }
+
+ // remove processed item from aTableNames
+ if( (nSep < 0) || (nSep >= aTableNames.getLength()) )
+ aTableNames = OUString();
+ else
+ aTableNames = aTableNames.copy( nSep + 1 ).trim();
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+WebPrModel::WebPrModel() :
+ mnHtmlFormat( XML_none ),
+ mbXml( false ),
+ mbSourceData( false ),
+ mbParsePre( false ),
+ mbConsecutive( false ),
+ mbFirstRow( false ),
+ mbXl97Created( false ),
+ mbTextDates( false ),
+ mbXl2000Refreshed( false ),
+ mbHtmlTables( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ConnectionModel::ConnectionModel() :
+ mnId( -1 ),
+ mnType( BIFF12_CONNECTION_UNKNOWN ),
+ mnReconnectMethod( BIFF12_RECONNECT_AS_REQUIRED ),
+ mnCredentials( XML_integrated ),
+ mnInterval( 0 ),
+ mbKeepAlive( false ),
+ mbNew( false ),
+ mbDeleted( false ),
+ mbOnlyUseConnFile( false ),
+ mbBackground( false ),
+ mbRefreshOnLoad( false ),
+ mbSaveData( false ),
+ mbSavePassword( false )
+{
+}
+
+WebPrModel& ConnectionModel::createWebPr()
+{
+ OSL_ENSURE( !mxWebPr.get(), "ConnectionModel::createWebPr - multiple call" );
+ mxWebPr.reset( new WebPrModel );
+ return *mxWebPr;
+}
+
+// ----------------------------------------------------------------------------
+
+Connection::Connection( const WorkbookHelper& rHelper, sal_Int32 nConnId ) :
+ WorkbookHelper( rHelper )
+{
+ maModel.mnId = nConnId;
+}
+
+void Connection::importConnection( const AttributeList& rAttribs )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ maModel.maDescription = rAttribs.getXString( XML_description, OUString() );
+ maModel.maSourceFile = rAttribs.getXString( XML_sourceFile, OUString() );
+ maModel.maSourceConnFile = rAttribs.getXString( XML_odcFile, OUString() );
+ maModel.maSsoId = rAttribs.getXString( XML_singleSignOnId, OUString() );
+ maModel.mnId = rAttribs.getInteger( XML_id, -1 );
+ // type and reconnectionMethod are using the BIFF12 constants instead of XML tokens
+ maModel.mnType = rAttribs.getInteger( XML_type, BIFF12_CONNECTION_UNKNOWN );
+ maModel.mnReconnectMethod = rAttribs.getInteger( XML_reconnectionMethod, BIFF12_RECONNECT_AS_REQUIRED );
+ maModel.mnCredentials = rAttribs.getToken( XML_credentials, XML_integrated );
+ maModel.mnInterval = rAttribs.getInteger( XML_interval, 0 );
+ maModel.mbKeepAlive = rAttribs.getBool( XML_keepAlive, false );
+ maModel.mbNew = rAttribs.getBool( XML_new, false );
+ maModel.mbDeleted = rAttribs.getBool( XML_deleted, false );
+ maModel.mbOnlyUseConnFile = rAttribs.getBool( XML_onlyUseConnectionFile, false );
+ maModel.mbBackground = rAttribs.getBool( XML_background, false );
+ maModel.mbRefreshOnLoad = rAttribs.getBool( XML_refreshOnLoad, false );
+ maModel.mbSaveData = rAttribs.getBool( XML_saveData, false );
+ maModel.mbSavePassword = rAttribs.getBool( XML_savePassword, false );
+}
+
+void Connection::importWebPr( const AttributeList& rAttribs )
+{
+ WebPrModel& rWebPr = maModel.createWebPr();
+
+ rWebPr.maUrl = rAttribs.getXString( XML_url, OUString() );
+ rWebPr.maPostMethod = rAttribs.getXString( XML_post, OUString() );
+ rWebPr.maEditPage = rAttribs.getXString( XML_editPage, OUString() );
+ rWebPr.mnHtmlFormat = rAttribs.getToken( XML_htmlFormat, XML_none );
+ rWebPr.mbXml = rAttribs.getBool( XML_xml, false );
+ rWebPr.mbSourceData = rAttribs.getBool( XML_sourceData, false );
+ rWebPr.mbParsePre = rAttribs.getBool( XML_parsePre, false );
+ rWebPr.mbConsecutive = rAttribs.getBool( XML_consecutive, false );
+ rWebPr.mbFirstRow = rAttribs.getBool( XML_firstRow, false );
+ rWebPr.mbXl97Created = rAttribs.getBool( XML_xl97, false );
+ rWebPr.mbTextDates = rAttribs.getBool( XML_textDates, false );
+ rWebPr.mbXl2000Refreshed = rAttribs.getBool( XML_xl2000, false );
+ rWebPr.mbHtmlTables = rAttribs.getBool( XML_htmlTables, false );
+}
+
+void Connection::importTables( const AttributeList& /*rAttribs*/ )
+{
+ if( maModel.mxWebPr.get() )
+ {
+ OSL_ENSURE( maModel.mxWebPr->maTables.empty(), "Connection::importTables - multiple calls" );
+ maModel.mxWebPr->maTables.clear();
+ }
+}
+
+void Connection::importTable( const AttributeList& rAttribs, sal_Int32 nElement )
+{
+ if( maModel.mxWebPr.get() )
+ {
+ Any aTableAny;
+ switch( nElement )
+ {
+ case XLS_TOKEN( m ): break;
+ case XLS_TOKEN( s ): aTableAny <<= rAttribs.getXString( XML_v, OUString() ); break;
+ case XLS_TOKEN( x ): aTableAny <<= rAttribs.getInteger( XML_v, -1 ); break;
+ default:
+ OSL_ENSURE( false, "Connection::importTable - unexpected element" );
+ return;
+ }
+ maModel.mxWebPr->maTables.push_back( aTableAny );
+ }
+}
+
+void Connection::importConnection( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags, nStrFlags;
+ sal_uInt8 nSavePassword, nCredentials;
+ rStrm.skip( 2 );
+ rStrm >> nSavePassword;
+ rStrm.skip( 1 );
+ maModel.mnInterval = rStrm.readuInt16();
+ rStrm >> nFlags >> nStrFlags >> maModel.mnType >> maModel.mnReconnectMethod >> maModel.mnId >> nCredentials;
+
+ if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SOURCEFILE ) )
+ rStrm >> maModel.maSourceFile;
+ if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SOURCECONNFILE ) )
+ rStrm >> maModel.maSourceConnFile;
+ if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_DESCRIPTION ) )
+ rStrm >> maModel.maDescription;
+ if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_NAME ) )
+ rStrm >> maModel.maName;
+ if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SSOID ) )
+ rStrm >> maModel.maSsoId;
+
+ static const sal_Int32 spnCredentials[] = { XML_integrated, XML_none, XML_stored, XML_prompt };
+ maModel.mnCredentials = STATIC_ARRAY_SELECT( spnCredentials, nCredentials, XML_integrated );
+
+ maModel.mbKeepAlive = getFlag( nFlags, BIFF12_CONNECTION_KEEPALIVE );
+ maModel.mbNew = getFlag( nFlags, BIFF12_CONNECTION_NEW );
+ maModel.mbDeleted = getFlag( nFlags, BIFF12_CONNECTION_DELETED );
+ maModel.mbOnlyUseConnFile = getFlag( nFlags, BIFF12_CONNECTION_ONLYUSECONNFILE );
+ maModel.mbBackground = getFlag( nFlags, BIFF12_CONNECTION_BACKGROUND );
+ maModel.mbRefreshOnLoad = getFlag( nFlags, BIFF12_CONNECTION_REFRESHONLOAD );
+ maModel.mbSaveData = getFlag( nFlags, BIFF12_CONNECTION_SAVEDATA );
+ maModel.mbSavePassword = nSavePassword == BIFF12_CONNECTION_SAVEPASSWORD_ON;
+}
+
+void Connection::importWebPr( SequenceInputStream& rStrm )
+{
+ WebPrModel& rWebPr = maModel.createWebPr();
+
+ sal_uInt32 nFlags;
+ sal_uInt8 nStrFlags;
+ rStrm >> nFlags >> nStrFlags;
+
+ if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_URL ) )
+ rStrm >> rWebPr.maUrl;
+ if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_POSTMETHOD ) )
+ rStrm >> rWebPr.maPostMethod;
+ if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_EDITPAGE ) )
+ rStrm >> rWebPr.maEditPage;
+
+ static const sal_Int32 spnHmlFormats[] = { XML_none, XML_rtf, XML_all };
+ rWebPr.mnHtmlFormat = STATIC_ARRAY_SELECT( spnHmlFormats, extractValue< sal_uInt8 >( nFlags, 0, 8 ), XML_none );
+
+ rWebPr.mbXml = getFlag( nFlags, BIFF12_WEBPR_XML );
+ rWebPr.mbSourceData = getFlag( nFlags, BIFF12_WEBPR_SOURCEDATA );
+ rWebPr.mbParsePre = getFlag( nFlags, BIFF12_WEBPR_PARSEPRE );
+ rWebPr.mbConsecutive = getFlag( nFlags, BIFF12_WEBPR_CONSECUTIVE );
+ rWebPr.mbFirstRow = getFlag( nFlags, BIFF12_WEBPR_FIRSTROW );
+ rWebPr.mbXl97Created = getFlag( nFlags, BIFF12_WEBPR_XL97CREATED );
+ rWebPr.mbTextDates = getFlag( nFlags, BIFF12_WEBPR_TEXTDATES );
+ rWebPr.mbXl2000Refreshed = getFlag( nFlags, BIFF12_WEBPR_XL2000REFRESHED );
+ rWebPr.mbHtmlTables = getFlag( nFlags, BIFF12_WEBPR_HTMLTABLES );
+}
+
+void Connection::importWebPrTables( SequenceInputStream& /*rStrm*/ )
+{
+ if( maModel.mxWebPr.get() )
+ {
+ OSL_ENSURE( maModel.mxWebPr->maTables.empty(), "Connection::importWebPrTables - multiple calls" );
+ maModel.mxWebPr->maTables.clear();
+ }
+}
+
+void Connection::importWebPrTable( SequenceInputStream& rStrm, sal_Int32 nRecId )
+{
+ if( maModel.mxWebPr.get() )
+ {
+ Any aTableAny;
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCITEM_MISSING: break;
+ case BIFF12_ID_PCITEM_STRING: aTableAny <<= BiffHelper::readString( rStrm ); break;
+ case BIFF12_ID_PCITEM_INDEX: aTableAny <<= rStrm.readInt32(); break;
+ default:
+ OSL_ENSURE( false, "Connection::importWebPrTable - unexpected record" );
+ return;
+ }
+ maModel.mxWebPr->maTables.push_back( aTableAny );
+ }
+}
+
+void Connection::importDbQuery( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags, nSqlParamCount, nCommandCount, nPostMethodCount, nServerSqlCount, nOdbcConnCount;
+ rStrm >> nFlags >> nSqlParamCount >> nCommandCount >> nPostMethodCount >> nServerSqlCount >> nOdbcConnCount;
+
+ // same type constants in all BIFF versions
+ maModel.mnType = extractValue< sal_Int32 >( nFlags, 0, 3 );
+ maModel.mbSavePassword = getFlag( nFlags, BIFF_DBQUERY_SAVEPASSWORD );
+
+ OSL_ENSURE( getFlag( nFlags, BIFF_DBQUERY_ODBC ) == (maModel.mnType == BIFF12_CONNECTION_ODBC), "Connection::importDbQuery - wrong ODBC flag" );
+ OSL_ENSURE( getFlag( nFlags, BIFF_DBQUERY_SQLQUERY ) != (maModel.mnType == BIFF12_CONNECTION_HTML), "Connection::importDbQuery - wrong SQL query flag" );
+ OSL_ENSURE( getFlag( nFlags, BIFF_DBQUERY_HTML ) == (maModel.mnType == BIFF12_CONNECTION_HTML), "Connection::importDbQuery - wrong HTML flag" );
+
+ if( (maModel.mnType == BIFF12_CONNECTION_HTML) && getFlag( nFlags, BIFF_DBQUERY_HTML ) )
+ {
+ WebPrModel& rWebPr = maModel.createWebPr();
+ rWebPr.mbHtmlTables = getFlag( nFlags, BIFF_DBQUERY_HTMLTABLES );
+
+ // read HTML query URL and post method
+ rWebPr.maUrl = lclReadQueryString( rStrm, nCommandCount );
+ rWebPr.maPostMethod = lclReadQueryString( rStrm, nPostMethodCount );
+ }
+}
+
+void Connection::importQueryTableSettings( BiffInputStream& rStrm )
+{
+ rStrm.skip( 4 );
+ // source data type, again
+ sal_uInt16 nType = rStrm.readuInt16();
+ OSL_ENSURE( nType == maModel.mnType, "Connection::importQueryTableSettings - source data type mismatch" );
+ if( nType == maModel.mnType )
+ {
+ sal_uInt16 nFlags1, nFlags2, nFlags3, nHtmlFormat;
+ rStrm >> nFlags1 >> nFlags2 >> nFlags3;
+ rStrm.skip( 10 );
+ maModel.mnInterval = rStrm.readuInt16();
+ rStrm >> nHtmlFormat;
+
+ // first flags field: generic connection flags
+ maModel.mbKeepAlive = getFlag( nFlags1, BIFF_QTSETTINGS_KEEPALIVE );
+ maModel.mbNew = getFlag( nFlags1, BIFF_QTSETTINGS_NEW );
+
+ // meaning of second flags field is dependent on source data type
+ if( (maModel.mnType == BIFF12_CONNECTION_HTML) && maModel.mxWebPr.get() )
+ {
+ WebPrModel& rWebPr = *maModel.mxWebPr;
+
+ // HTML format is one-based in BIFF8 (but zero-based in BIFF12)
+ static const sal_Int32 spnHmlFormats[] = { XML_none, XML_none, XML_rtf, XML_all };
+ rWebPr.mnHtmlFormat = STATIC_ARRAY_SELECT( spnHmlFormats, nHtmlFormat, XML_none );
+
+ rWebPr.mbXml = getFlag( nFlags1, BIFF_QTSETTINGS_XML );
+ rWebPr.mbSourceData = getFlag( nFlags1, BIFF_QTSETTINGS_SOURCEDATA );
+ rWebPr.mbParsePre = getFlag( nFlags2, BIFF_QTSETTINGS_PARSEPRE );
+ rWebPr.mbConsecutive = getFlag( nFlags2, BIFF_QTSETTINGS_CONSECUTIVE );
+ rWebPr.mbFirstRow = getFlag( nFlags2, BIFF_QTSETTINGS_FIRSTROW );
+ rWebPr.mbXl97Created = getFlag( nFlags2, BIFF_QTSETTINGS_XL97CREATED );
+ rWebPr.mbTextDates = getFlag( nFlags2, BIFF_QTSETTINGS_TEXTDATES );
+ rWebPr.mbXl2000Refreshed = getFlag( nFlags2, BIFF_QTSETTINGS_XL2000REFRESHED );
+
+ // list of HTML table names or indexes
+ if( getFlag( nFlags3, BIFF_QTSETTINGS_TABLENAMES ) )
+ {
+ // a QUERYTABLESTRING record containing the table names must follow
+ bool bHasQTString = (rStrm.getNextRecId() == BIFF_ID_QUERYTABLESTRING) && rStrm.startNextRecord();
+ OSL_ENSURE( bHasQTString, "Connection::importQueryTableSettings - missing QUERYTABLESTRING record" );
+ if( bHasQTString )
+ {
+ rStrm.skip( 4 );
+ lclParseTables( rWebPr.maTables, rStrm.readUniString() );
+ }
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+ConnectionsBuffer::ConnectionsBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnUnusedId( 1 )
+{
+}
+
+Connection& ConnectionsBuffer::createConnection()
+{
+ ConnectionRef xConnection( new Connection( *this ) );
+ maConnections.push_back( xConnection );
+ return *xConnection;
+}
+
+Connection& ConnectionsBuffer::createConnectionWithId()
+{
+ ConnectionRef xConnection( new Connection( *this, mnUnusedId ) );
+ maConnections.push_back( xConnection );
+ insertConnectionToMap( xConnection );
+ return *xConnection;
+}
+
+void ConnectionsBuffer::finalizeImport()
+{
+ for( ConnectionVector::iterator aIt = maConnections.begin(), aEnd = maConnections.end(); aIt != aEnd; ++aIt )
+ insertConnectionToMap( *aIt );
+}
+
+ConnectionRef ConnectionsBuffer::getConnection( sal_Int32 nConnId ) const
+{
+ return maConnectionsById.get( nConnId );
+}
+
+void ConnectionsBuffer::insertConnectionToMap( const ConnectionRef& rxConnection )
+{
+ sal_Int32 nConnId = rxConnection->getConnectionId();
+ if( nConnId > 0 )
+ {
+ OSL_ENSURE( !maConnectionsById.has( nConnId ), "ConnectionsBuffer::insertConnectionToMap - multiple connection identifier" );
+ maConnectionsById[ nConnId ] = rxConnection;
+ mnUnusedId = ::std::max< sal_Int32 >( mnUnusedId, nConnId + 1 );
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/connectionsfragment.cxx b/oox/source/xls/connectionsfragment.cxx
new file mode 100644
index 000000000000..7aafcd84cd7e
--- /dev/null
+++ b/oox/source/xls/connectionsfragment.cxx
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/connectionsfragment.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/biffhelper.hxx"
+#include "oox/xls/connectionsbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+ConnectionContext::ConnectionContext( WorkbookFragmentBase& rParent, Connection& rConnection ) :
+ WorkbookContextBase( rParent ),
+ mrConnection( rConnection )
+{
+}
+
+ContextHandlerRef ConnectionContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( connection ):
+ if( nElement == XLS_TOKEN( webPr ) )
+ {
+ mrConnection.importWebPr( rAttribs );
+ return this;
+ }
+ break;
+
+ case XLS_TOKEN( webPr ):
+ if( nElement == XLS_TOKEN( tables ) )
+ {
+ mrConnection.importTables( rAttribs );
+ return this;
+ }
+ break;
+
+ case XLS_TOKEN( tables ):
+ mrConnection.importTable( rAttribs, nElement );
+ break;
+ }
+ return 0;
+}
+
+void ConnectionContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( getCurrentElement() == XLS_TOKEN( connection ) )
+ mrConnection.importConnection( rAttribs );
+}
+
+ContextHandlerRef ConnectionContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_CONNECTION:
+ if( nRecId == BIFF12_ID_WEBPR )
+ {
+ mrConnection.importWebPr( rStrm );
+ return this;
+ }
+ break;
+
+ case BIFF12_ID_WEBPR:
+ if( nRecId == BIFF12_ID_WEBPRTABLES )
+ {
+ mrConnection.importWebPrTables( rStrm );
+ return this;
+ }
+ break;
+
+ case BIFF12_ID_WEBPRTABLES:
+ mrConnection.importWebPrTable( rStrm, nRecId );
+ break;
+ }
+ return 0;
+}
+
+void ConnectionContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ if( getCurrentElement() == BIFF12_ID_CONNECTION )
+ mrConnection.importConnection( rStrm );
+}
+
+// ============================================================================
+
+ConnectionsFragment::ConnectionsFragment( const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ WorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+ContextHandlerRef ConnectionsFragment::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( connections ) )
+ return this;
+ break;
+
+ case XLS_TOKEN( connections ):
+ if( nElement == XLS_TOKEN( connection ) )
+ return new ConnectionContext( *this, getConnections().createConnection() );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef ConnectionsFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& /*rStrm*/ )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_CONNECTIONS )
+ return this;
+ break;
+
+ case BIFF12_ID_CONNECTIONS:
+ if( nRecId == BIFF12_ID_CONNECTION )
+ return new ConnectionContext( *this, getConnections().createConnection() );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* ConnectionsFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_CONNECTIONS, BIFF12_ID_CONNECTIONS + 1 },
+ { BIFF12_ID_CONNECTION, BIFF12_ID_CONNECTION + 1 },
+ { BIFF12_ID_WEBPR, BIFF12_ID_WEBPR + 1 },
+ { BIFF12_ID_WEBPRTABLES, BIFF12_ID_WEBPRTABLES + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void ConnectionsFragment::finalizeImport()
+{
+ getConnections().finalizeImport();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/defnamesbuffer.cxx b/oox/source/xls/defnamesbuffer.cxx
new file mode 100644
index 000000000000..96fcec0042f5
--- /dev/null
+++ b/oox/source/xls/defnamesbuffer.cxx
@@ -0,0 +1,706 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/defnamesbuffer.hxx"
+
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/ExternalReference.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/SingleReference.hpp>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.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/worksheetbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 BIFF12_DEFNAME_HIDDEN = 0x00000001;
+const sal_uInt32 BIFF12_DEFNAME_FUNC = 0x00000002;
+const sal_uInt32 BIFF12_DEFNAME_VBNAME = 0x00000004;
+const sal_uInt32 BIFF12_DEFNAME_MACRO = 0x00000008;
+const sal_uInt32 BIFF12_DEFNAME_CALCEXP = 0x00000010;
+const sal_uInt32 BIFF12_DEFNAME_BUILTIN = 0x00000020;
+const sal_uInt32 BIFF12_DEFNAME_PUBLISHED = 0x00008000;
+const sal_uInt32 BIFF12_DEFNAME_WBPARAM = 0x00010000;
+
+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_BIG = 0x1000;
+
+const sal_uInt8 BIFF2_DEFNAME_FUNC = 0x02; /// BIFF2 function/command flag.
+
+const sal_uInt16 BIFF_DEFNAME_GLOBAL = 0; /// 0 = Globally defined name.
+
+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;
+
+// ----------------------------------------------------------------------------
+
+const sal_Char* const spcLegacyPrefix = "Excel_BuiltIn_";
+const sal_Char* const spcOoxPrefix = "_xlnm.";
+
+const sal_Char* const sppcBaseNames[] =
+{
+ "Consolidate_Area",
+ "Auto_Open",
+ "Auto_Close",
+ "Extract",
+ "Database",
+ "Criteria",
+ "Print_Area",
+ "Print_Titles",
+ "Recorder",
+ "Data_Form",
+ "Auto_Activate",
+ "Auto_Deactivate",
+ "Sheet_Title",
+ "_FilterDatabase"
+};
+
+/** 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 - unsupported built-in identifier" );
+ OUStringBuffer aBuffer;
+ if( cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ) )
+ aBuffer.appendAscii( sppcBaseNames[ cBuiltinId ] );
+ else
+ aBuffer.append( static_cast< sal_Int32 >( cBuiltinId ) );
+ return aBuffer.makeStringAndClear();
+}
+
+OUString lclGetPrefixedName( sal_Unicode cBuiltinId )
+{
+ return OUStringBuffer().appendAscii( spcOoxPrefix ).append( lclGetBaseName( cBuiltinId ) ).makeStringAndClear();
+}
+
+/** returns the built-in name identifier from a perfixed built-in name, e.g. '_xlnm.Print_Area'. */
+sal_Unicode lclGetBuiltinIdFromPrefixedName( const OUString& rModelName )
+{
+ OUString aPrefix = OUString::createFromAscii( spcOoxPrefix );
+ sal_Int32 nPrefixLen = aPrefix.getLength();
+ if( rModelName.matchIgnoreAsciiCase( aPrefix ) )
+ {
+ for( sal_Unicode cBuiltinId = 0; cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ); ++cBuiltinId )
+ {
+ OUString aBaseName = lclGetBaseName( cBuiltinId );
+ sal_Int32 nBaseNameLen = aBaseName.getLength();
+ if( (rModelName.getLength() == nPrefixLen + nBaseNameLen) && rModelName.matchIgnoreAsciiCase( aBaseName, nPrefixLen ) )
+ return cBuiltinId;
+ }
+ }
+ return BIFF_DEFNAME_UNKNOWN;
+}
+
+/** returns the built-in name identifier from a built-in base name, e.g. 'Print_Area'. */
+sal_Unicode lclGetBuiltinIdFromBaseName( const OUString& rModelName )
+{
+ for( sal_Unicode cBuiltinId = 0; cBuiltinId < STATIC_ARRAY_SIZE( sppcBaseNames ); ++cBuiltinId )
+ if( rModelName.equalsIgnoreAsciiCaseAscii( sppcBaseNames[ cBuiltinId ] ) )
+ return cBuiltinId;
+ return BIFF_DEFNAME_UNKNOWN;
+}
+
+bool lclIsFilterDatabaseName( const OUString& rModelName )
+{
+ for( const sal_Char* const* ppcName = sppcFilterDbNames; ppcName < STATIC_ARRAY_END( sppcFilterDbNames ); ++ppcName )
+ if( rModelName.equalsIgnoreAsciiCaseAscii( *ppcName ) )
+ return true;
+ return false;
+}
+
+OUString lclGetUpcaseModelName( const OUString& rModelName )
+{
+ // TODO: i18n?
+ return rModelName.toAsciiUpperCase();
+}
+
+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 )
+{
+ using namespace ::com::sun::star::sheet::ReferenceFlags;
+ lclConvertRefFlags(
+ orApiRef.Flags, orApiRef.Column, orApiRef.RelativeColumn,
+ rBaseAddress.Column, COLUMN_RELATIVE, bColRel );
+ lclConvertRefFlags(
+ orApiRef.Flags, orApiRef.Row, orApiRef.RelativeRow,
+ rBaseAddress.Row, ROW_RELATIVE, bRowRel );
+}
+
+Any lclConvertReference( const Any& rRefAny, const CellAddress& rBaseAddress, sal_uInt16 nRelFlags )
+{
+ if( rRefAny.has< SingleReference >() && !getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ) && !getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) )
+ {
+ SingleReference aApiRef;
+ rRefAny >>= aApiRef;
+ lclConvertSingleRefFlags( aApiRef, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) );
+ return Any( aApiRef );
+ }
+ if( rRefAny.has< ComplexReference >() )
+ {
+ ComplexReference aApiRef;
+ rRefAny >>= aApiRef;
+ lclConvertSingleRefFlags( aApiRef.Reference1, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL1REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW1REL ) );
+ lclConvertSingleRefFlags( aApiRef.Reference2, rBaseAddress, getFlag( nRelFlags, BIFF_REFFLAG_COL2REL ), getFlag( nRelFlags, BIFF_REFFLAG_ROW2REL ) );
+ return Any( aApiRef );
+ }
+ return Any();
+}
+
+} // namespace
+
+// ============================================================================
+
+DefinedNameModel::DefinedNameModel() :
+ mnSheet( -1 ),
+ mnFuncGroupId( -1 ),
+ mbMacro( false ),
+ mbFunction( false ),
+ mbVBName( false ),
+ mbHidden( false )
+{
+}
+
+// ============================================================================
+
+DefinedNameBase::DefinedNameBase( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+const OUString& DefinedNameBase::getUpcaseModelName() const
+{
+ if( maUpModelName.getLength() == 0 )
+ maUpModelName = lclGetUpcaseModelName( maModel.maName );
+ return maUpModelName;
+}
+
+Any DefinedNameBase::getReference( const CellAddress& rBaseAddress ) const
+{
+ if( maRefAny.hasValue() && (maModel.maName.getLength() >= 2) && (maModel.maName[ 0 ] == '\x01') )
+ {
+ sal_Unicode cFlagsChar = getUpcaseModelName()[ 1 ];
+ if( ('A' <= cFlagsChar) && (cFlagsChar <= 'P') )
+ {
+ sal_uInt16 nRelFlags = static_cast< sal_uInt16 >( cFlagsChar - 'A' );
+ if( maRefAny.has< ExternalReference >() )
+ {
+ ExternalReference aApiExtRef;
+ maRefAny >>= aApiExtRef;
+ Any aRefAny = lclConvertReference( aApiExtRef.Reference, rBaseAddress, nRelFlags );
+ if( aRefAny.hasValue() )
+ {
+ aApiExtRef.Reference <<= aRefAny;
+ return Any( aApiExtRef );
+ }
+ }
+ else
+ {
+ return lclConvertReference( maRefAny, rBaseAddress, nRelFlags );
+ }
+ }
+ }
+ return Any();
+}
+
+void DefinedNameBase::importOoxFormula( FormulaContext& rContext, sal_Int16 nBaseSheet )
+{
+ if( maModel.maFormula.getLength() > 0 )
+ {
+ rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) );
+ getFormulaParser().importFormula( rContext, maModel.maFormula );
+ }
+ else
+ getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME );
+}
+
+void DefinedNameBase::importBiff12Formula( FormulaContext& rContext, sal_Int16 nBaseSheet, SequenceInputStream& rStrm )
+{
+ rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) );
+ getFormulaParser().importFormula( rContext, rStrm );
+}
+
+void DefinedNameBase::importBiffFormula( FormulaContext& rContext, sal_Int16 nBaseSheet, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize )
+{
+ rContext.setBaseAddress( CellAddress( nBaseSheet, 0, 0 ) );
+ if( !pnFmlaSize || (*pnFmlaSize > 0) )
+ getFormulaParser().importFormula( rContext, rStrm, pnFmlaSize );
+ else
+ getFormulaParser().convertErrorToFormula( rContext, BIFF_ERR_NAME );
+}
+
+void DefinedNameBase::extractReference( const ApiTokenSequence& rTokens )
+{
+ OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "DefinedNameBase::extractReference - unexpected call" );
+ maRefAny = getFormulaParser().extractReference( rTokens );
+}
+
+// ============================================================================
+
+DefinedName::DefinedName( const WorkbookHelper& rHelper ) :
+ DefinedNameBase( rHelper ),
+ mnTokenIndex( -1 ),
+ mcBuiltinId( BIFF_DEFNAME_UNKNOWN ),
+ mnFmlaSize( 0 )
+{
+}
+
+void DefinedName::importDefinedName( const AttributeList& rAttribs )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ maModel.mnSheet = rAttribs.getInteger( XML_localSheetId, -1 );
+ maModel.mnFuncGroupId = rAttribs.getInteger( XML_functionGroupId, -1 );
+ maModel.mbMacro = rAttribs.getBool( XML_xlm, false );
+ maModel.mbFunction = rAttribs.getBool( XML_function, false );
+ maModel.mbVBName = rAttribs.getBool( XML_vbProcedure, false );
+ maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
+ mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1;
+
+ /* Detect built-in state from name itself, there is no built-in flag.
+ Built-in names are prexixed with '_xlnm.' instead. */
+ mcBuiltinId = lclGetBuiltinIdFromPrefixedName( maModel.maName );
+}
+
+void DefinedName::setFormula( const OUString& rFormula )
+{
+ maModel.maFormula = rFormula;
+}
+
+void DefinedName::importDefinedName( SequenceInputStream& rStrm )
+{
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+ rStrm.skip( 1 ); // keyboard shortcut
+ rStrm >> maModel.mnSheet >> maModel.maName;
+ mnCalcSheet = (maModel.mnSheet >= 0) ? getWorksheets().getCalcSheetIndex( maModel.mnSheet ) : -1;
+
+ // macro function/command, hidden flag
+ maModel.mnFuncGroupId = extractValue< sal_Int32 >( nFlags, 6, 9 );
+ maModel.mbMacro = getFlag( nFlags, BIFF12_DEFNAME_MACRO );
+ maModel.mbFunction = getFlag( nFlags, BIFF12_DEFNAME_FUNC );
+ maModel.mbVBName = getFlag( nFlags, BIFF12_DEFNAME_VBNAME );
+ maModel.mbHidden = getFlag( nFlags, BIFF12_DEFNAME_HIDDEN );
+
+ // get built-in name index from name
+ if( getFlag( nFlags, BIFF12_DEFNAME_BUILTIN ) )
+ mcBuiltinId = lclGetBuiltinIdFromBaseName( maModel.maName );
+
+ // store token array data
+ sal_Int64 nRecPos = rStrm.tell();
+ sal_Int32 nFmlaSize = rStrm.readInt32();
+ rStrm.skip( nFmlaSize );
+ sal_Int32 nAddDataSize = rStrm.readInt32();
+ if( !rStrm.isEof() && (nFmlaSize > 0) && (nAddDataSize >= 0) && (rStrm.getRemaining() >= nAddDataSize) )
+ {
+ sal_Int32 nTotalSize = 8 + nFmlaSize + nAddDataSize;
+ mxFormula.reset( new StreamDataSequence );
+ rStrm.seek( nRecPos );
+ rStrm.readData( *mxFormula, nTotalSize );
+ }
+}
+
+void DefinedName::importDefinedName( BiffInputStream& rStrm, sal_Int16 nCalcSheet )
+{
+ 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 ) );
+ maModel.maName = rStrm.readCharArrayUC( nNameLen, getTextEncoding(), true );
+ }
+ break;
+ case BIFF3:
+ case BIFF4:
+ rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize;
+ maModel.maName = rStrm.readCharArrayUC( nNameLen, getTextEncoding(), true );
+ break;
+ case BIFF5:
+ rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize >> nRefId >> nTabId;
+ rStrm.skip( 4 );
+ maModel.maName = rStrm.readCharArrayUC( nNameLen, getTextEncoding(), true );
+ break;
+ case BIFF8:
+ rStrm >> nFlags >> nShortCut >> nNameLen >> mnFmlaSize >> nRefId >> nTabId;
+ rStrm.skip( 4 );
+ maModel.maName = rStrm.readUniStringBody( nNameLen, true );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+
+ // macro function/command, hidden flag
+ maModel.mnFuncGroupId = extractValue< sal_Int32 >( nFlags, 6, 6 );
+ maModel.mbMacro = getFlag( nFlags, BIFF_DEFNAME_MACRO );
+ maModel.mbFunction = getFlag( nFlags, BIFF_DEFNAME_FUNC );
+ maModel.mbVBName = getFlag( nFlags, BIFF_DEFNAME_VBNAME );
+ maModel.mbHidden = getFlag( nFlags, BIFF_DEFNAME_HIDDEN );
+
+ // get built-in name index from name
+ if( getFlag( nFlags, BIFF_DEFNAME_BUILTIN ) )
+ {
+ // name may be the built-in identifier or the built-in base name
+ if( maModel.maName.getLength() == 1 )
+ mcBuiltinId = maModel.maName[ 0 ];
+ else
+ mcBuiltinId = lclGetBuiltinIdFromBaseName( maModel.maName );
+ }
+ /* In BIFF5, '_FilterDatabase' appears as hidden user name without
+ built-in flag, and even worse, localized. */
+ else if( (eBiff == BIFF5) && lclIsFilterDatabaseName( maModel.maName ) )
+ {
+ mcBuiltinId = BIFF_DEFNAME_FILTERDATABASE;
+ }
+
+ // get sheet index for sheet-local names in BIFF5-BIFF8
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ // BIFF2-BIFF4: all defined names are sheet-local
+ mnCalcSheet = nCalcSheet;
+ break;
+ case BIFF5:
+ // #i44019# nTabId may be invalid, resolve nRefId to sheet index
+ if( nRefId != BIFF_DEFNAME_GLOBAL )
+ if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
+ if( pExtLink->getLinkType() == LINKTYPE_INTERNAL )
+ mnCalcSheet = pExtLink->getCalcSheetIndex();
+ break;
+ case BIFF8:
+ // convert one-based worksheet index to zero-based Calc sheet index
+ OSL_ENSURE( nTabId >= 0, "DefinedName::importDefinedName - invalid local sheet index" );
+ if( nTabId != BIFF_DEFNAME_GLOBAL )
+ mnCalcSheet = getWorksheets().getCalcSheetIndex( nTabId - 1 );
+ break;
+ case BIFF_UNKNOWN:
+ break;
+ }
+
+ if( (getBiff() <= BIFF4) && maModel.mbHidden && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') )
+ {
+ /* Read the token array of special internal names containing addresses
+ for BIFF3-BIFF4 3D references immediately. It is expected that
+ these names contain a simple cell reference or range reference.
+ Other regular defined names and external names rely on existence of
+ this reference. */
+ TokensFormulaContext aContext( true, true );
+ importBiffFormula( aContext, mnCalcSheet, rStrm, &mnFmlaSize );
+ extractReference( aContext.getTokens() );
+ }
+ else
+ {
+ /* Store record position of other defined names to be able to import
+ token array later. This is needed to correctly resolve references
+ to names that are stored later in the defined names list following
+ this name. */
+ mxBiffStrm.reset( new BiffInputStreamPos( rStrm ) );
+ }
+}
+
+void DefinedName::createNameObject()
+{
+ // do not create names for (macro) functions or VBA procedures
+ // #163146# do not ignore hidden names (may be regular names created by VBA scripts)
+ if( /*maModel.mbHidden ||*/ maModel.mbFunction || maModel.mbVBName )
+ return;
+
+ // convert original name to final Calc name (TODO: filter invalid characters from model name)
+ maCalcName = isBuiltinName() ? lclGetPrefixedName( mcBuiltinId ) : maModel.maName;
+
+ // #163146# do not rename sheet-local names by default, this breaks VBA scripts
+#if 0
+ // append sheet index for local names in multi-sheet documents
+ if( isWorkbookFile() && !isGlobalName() )
+ maCalcName = OUStringBuffer( maCalcName ).append( sal_Unicode( '_' ) ).
+ append( static_cast< sal_Int32 >( mnCalcSheet + 1 ) ).makeStringAndClear();
+#endif
+
+ // special flags for this name
+ sal_Int32 nNameFlags = 0;
+ using namespace ::com::sun::star::sheet::NamedRangeFlag;
+ if( !isGlobalName() ) switch( mcBuiltinId )
+ {
+ case BIFF_DEFNAME_CRITERIA: nNameFlags = FILTER_CRITERIA; break;
+ case BIFF_DEFNAME_PRINTAREA: nNameFlags = PRINT_AREA; break;
+ case BIFF_DEFNAME_PRINTTITLES: nNameFlags = COLUMN_HEADER | ROW_HEADER; break;
+ }
+
+ // create the name and insert it into the document, maCalcName will be changed to the resulting name
+ mxNamedRange = createNamedRangeObject( maCalcName, nNameFlags );
+ // index of this defined name used in formula token arrays
+ PropertySet aPropSet( mxNamedRange );
+ aPropSet.getProperty( mnTokenIndex, PROP_TokenIndex );
+}
+
+void DefinedName::convertFormula()
+{
+ Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY );
+ if( xTokens.is() )
+ {
+ // convert and set formula of the defined name
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ {
+ SimpleFormulaContext aContext( xTokens, true, false );
+ implImportOoxFormula( aContext );
+ }
+ break;
+ case FILTER_BIFF:
+ {
+ SimpleFormulaContext aContext( xTokens, true, getBiff() <= BIFF4 );
+ implImportBiffFormula( aContext );
+ }
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+
+ // set built-in names (print ranges, repeated titles, filter ranges)
+ if( !isGlobalName() ) switch( mcBuiltinId )
+ {
+ case BIFF_DEFNAME_PRINTAREA:
+ {
+ Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY );
+ ApiCellRangeList aPrintRanges;
+ getFormulaParser().extractCellRangeList( aPrintRanges, xTokens->getTokens(), false, mnCalcSheet );
+ if( xPrintAreas.is() && !aPrintRanges.empty() )
+ xPrintAreas->setPrintAreas( ContainerHelper::vectorToSequence( aPrintRanges ) );
+ }
+ break;
+ case BIFF_DEFNAME_PRINTTITLES:
+ {
+ Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY );
+ ApiCellRangeList aTitleRanges;
+ getFormulaParser().extractCellRangeList( aTitleRanges, xTokens->getTokens(), false, mnCalcSheet );
+ 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;
+ }
+ }
+}
+
+bool DefinedName::getAbsoluteRange( CellRangeAddress& orRange ) const
+{
+ /* ScNamedRangeObj::XCellRangeReferrer::getReferredCells is buggy with
+ relative references, so we extract an absolute reference by hand. */
+ Reference< XFormulaTokens > xTokens( mxNamedRange, UNO_QUERY );
+ return xTokens.is() && getFormulaParser().extractCellRange( orRange, xTokens->getTokens(), false );
+}
+
+void DefinedName::implImportOoxFormula( FormulaContext& rContext )
+{
+ if( mxFormula.get() )
+ {
+ SequenceInputStream aStrm( *mxFormula );
+ importBiff12Formula( rContext, mnCalcSheet, aStrm );
+ }
+ else
+ importOoxFormula( rContext, mnCalcSheet );
+}
+
+void DefinedName::implImportBiffFormula( FormulaContext& rContext )
+{
+ OSL_ENSURE( mxBiffStrm.get(), "DefinedName::implImportBiffFormula - missing BIFF stream" );
+ BiffInputStream& rStrm = mxBiffStrm->getStream();
+ BiffInputStreamPosGuard aStrmGuard( rStrm );
+ if( mxBiffStrm->restorePosition() )
+ importBiffFormula( rContext, mnCalcSheet, rStrm, &mnFmlaSize );
+}
+
+// ============================================================================
+
+DefinedNamesBuffer::DefinedNamesBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnCalcSheet( -1 )
+{
+}
+
+void DefinedNamesBuffer::setLocalCalcSheet( sal_Int16 nCalcSheet )
+{
+ OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4),
+ "DefinedNamesBuffer::setLocalCalcSheet - invalid call" );
+ mnCalcSheet = nCalcSheet;
+}
+
+DefinedNameRef DefinedNamesBuffer::importDefinedName( const AttributeList& rAttribs )
+{
+ DefinedNameRef xDefName = createDefinedName();
+ xDefName->importDefinedName( rAttribs );
+ return xDefName;
+}
+
+void DefinedNamesBuffer::importDefinedName( SequenceInputStream& rStrm )
+{
+ createDefinedName()->importDefinedName( rStrm );
+}
+
+void DefinedNamesBuffer::importDefinedName( BiffInputStream& rStrm )
+{
+ createDefinedName()->importDefinedName( rStrm, mnCalcSheet );
+}
+
+void DefinedNamesBuffer::finalizeImport()
+{
+ // first insert all names without formula definition into the document, and insert them into the maps
+ for( DefNameVector::iterator aIt = maDefNames.begin(), aEnd = maDefNames.end(); aIt != aEnd; ++aIt )
+ {
+ DefinedNameRef xDefName = *aIt;
+ xDefName->createNameObject();
+ // map by sheet index and original model name
+ maModelNameMap[ SheetNameKey( xDefName->getLocalCalcSheet(), xDefName->getUpcaseModelName() ) ] = xDefName;
+ // map by sheet index and built-in identifier
+ if( !xDefName->isGlobalName() && xDefName->isBuiltinName() )
+ maBuiltinMap[ BuiltinKey( xDefName->getLocalCalcSheet(), xDefName->getBuiltinId() ) ] = xDefName;
+ // map by API formula token identifier
+ sal_Int32 nTokenIndex = xDefName->getTokenIndex();
+ if( nTokenIndex >= 0 )
+ maTokenIdMap[ nTokenIndex ] = xDefName;
+ }
+
+ /* 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::getByTokenIndex( sal_Int32 nIndex ) const
+{
+ return maTokenIdMap.get( nIndex );
+}
+
+DefinedNameRef DefinedNamesBuffer::getByModelName( const OUString& rModelName, sal_Int16 nCalcSheet ) const
+{
+ OUString aUpcaseName = lclGetUpcaseModelName( rModelName );
+ DefinedNameRef xDefName = maModelNameMap.get( SheetNameKey( nCalcSheet, aUpcaseName ) );
+ // lookup global name, if no local name exists
+ if( !xDefName && (nCalcSheet >= 0) )
+ xDefName = maModelNameMap.get( SheetNameKey( -1, aUpcaseName ) );
+ return xDefName;
+}
+
+DefinedNameRef DefinedNamesBuffer::getByBuiltinId( sal_Unicode cBuiltinId, sal_Int16 nCalcSheet ) const
+{
+ return maBuiltinMap.get( BuiltinKey( nCalcSheet, cBuiltinId ) );
+}
+
+DefinedNameRef DefinedNamesBuffer::createDefinedName()
+{
+ DefinedNameRef xDefName( new DefinedName( *this ) );
+ maDefNames.push_back( xDefName );
+ return xDefName;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx
new file mode 100644
index 000000000000..e28608f728c6
--- /dev/null
+++ b/oox/source/xls/drawingfragment.cxx
@@ -0,0 +1,1099 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/drawingfragment.hxx"
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <rtl/strbuf.hxx>
+#include "oox/drawingml/connectorshapecontext.hxx"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::oox::ole;
+
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringToOString;
+// no using's for ::oox::vml, that may clash with ::oox::drawingml types
+
+// ============================================================================
+// DrawingML
+// ============================================================================
+
+namespace {
+
+/** Converts the passed 64-bit integer value from the passed unit to EMUs. */
+sal_Int64 lclCalcEmu( const UnitConverter& rUnitConv, sal_Int64 nValue, Unit eFromUnit )
+{
+ return (eFromUnit == UNIT_EMU) ? nValue :
+ static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( nValue ), eFromUnit, UNIT_EMU ) + 0.5 );
+}
+
+} // namespace
+
+// ============================================================================
+
+AnchorCellModel::AnchorCellModel() :
+ mnCol( -1 ),
+ mnRow( -1 ),
+ mnColOffset( 0 ),
+ mnRowOffset( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+AnchorClientDataModel::AnchorClientDataModel() :
+ mbLocksWithSheet( true ),
+ mbPrintsWithSheet( true )
+{
+}
+
+// ============================================================================
+
+ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper ),
+ meType( ANCHOR_INVALID ),
+ mnEditAs( XML_twoCell )
+{
+}
+
+void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( nElement )
+ {
+ case XDR_TOKEN( absoluteAnchor ):
+ meType = ANCHOR_ABSOLUTE;
+ break;
+ case XDR_TOKEN( oneCellAnchor ):
+ meType = ANCHOR_ONECELL;
+ break;
+ case XDR_TOKEN( twoCellAnchor ):
+ meType = ANCHOR_TWOCELL;
+ mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell );
+ break;
+ default:
+ OSL_ENSURE( false, "ShapeAnchor::importAnchor - unexpected element" );
+ }
+}
+
+void ShapeAnchor::importPos( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( meType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" );
+ maPos.X = rAttribs.getHyper( XML_x, 0 );
+ maPos.Y = rAttribs.getHyper( XML_y, 0 );
+}
+
+void ShapeAnchor::importExt( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( (meType == ANCHOR_ABSOLUTE) || (meType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" );
+ maSize.Width = rAttribs.getHyper( XML_cx, 0 );
+ maSize.Height = rAttribs.getHyper( XML_cy, 0 );
+}
+
+void ShapeAnchor::importClientData( const AttributeList& rAttribs )
+{
+ maClientData.mbLocksWithSheet = rAttribs.getBool( XML_fLocksWithSheet, true );
+ maClientData.mbPrintsWithSheet = rAttribs.getBool( XML_fPrintsWithSheet, true );
+}
+
+void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue )
+{
+ AnchorCellModel* pAnchorCell = 0;
+ switch( nParentContext )
+ {
+ case XDR_TOKEN( from ):
+ OSL_ENSURE( (meType == ANCHOR_ONECELL) || (meType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" );
+ pAnchorCell = &maFrom;
+ break;
+ case XDR_TOKEN( to ):
+ OSL_ENSURE( meType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" );
+ pAnchorCell = &maTo;
+ break;
+ default:
+ OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected parent element" );
+ }
+ if( pAnchorCell ) switch( nElement )
+ {
+ case XDR_TOKEN( col ): pAnchorCell->mnCol = rValue.toInt32(); break;
+ case XDR_TOKEN( row ): pAnchorCell->mnRow = rValue.toInt32(); break;
+ case XDR_TOKEN( colOff ): pAnchorCell->mnColOffset = rValue.toInt64(); break;
+ case XDR_TOKEN( rowOff ): pAnchorCell->mnRowOffset = rValue.toInt64(); break;
+ default: OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected element" );
+ }
+}
+
+void ShapeAnchor::importVmlAnchor( const OUString& rAnchor )
+{
+ meType = ANCHOR_VML;
+
+ ::std::vector< OUString > aTokens;
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ aTokens.push_back( rAnchor.getToken( 0, ',', nIndex ).trim() );
+
+ OSL_ENSURE( aTokens.size() >= 8, "ShapeAnchor::importVmlAnchor - missing anchor tokens" );
+ if( aTokens.size() >= 8 )
+ {
+ maFrom.mnCol = aTokens[ 0 ].toInt32();
+ maFrom.mnColOffset = aTokens[ 1 ].toInt32();
+ maFrom.mnRow = aTokens[ 2 ].toInt32();
+ maFrom.mnRowOffset = aTokens[ 3 ].toInt32();
+ maTo.mnCol = aTokens[ 4 ].toInt32();
+ maTo.mnColOffset = aTokens[ 5 ].toInt32();
+ maTo.mnRow = aTokens[ 6 ].toInt32();
+ maTo.mnRowOffset = aTokens[ 7 ].toInt32();
+ }
+}
+
+bool ShapeAnchor::isValidAnchor() const
+{
+ bool bValid = false;
+ switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ OSL_ENSURE( maPos.isValid(), "ShapeAnchor::isValidAnchor - invalid position" );
+ OSL_ENSURE( maSize.isValid(), "ShapeAnchor::isValidAnchor - invalid size" );
+ bValid = maPos.isValid() && maSize.isValid() && (maSize.Width > 0) && (maSize.Height > 0);
+ break;
+ case ANCHOR_ONECELL:
+ OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::isValidAnchor - invalid from position" );
+ OSL_ENSURE( maSize.isValid(), "ShapeAnchor::isValidAnchor - invalid size" );
+ bValid = maFrom.isValid() && maSize.isValid() && (maSize.Width > 0) && (maSize.Height > 0);
+ break;
+ case ANCHOR_TWOCELL:
+ case ANCHOR_VML:
+ OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::isValidAnchor - invalid from position" );
+ OSL_ENSURE( maTo.isValid(), "ShapeAnchor::isValidAnchor - invalid to position" );
+ bValid = maFrom.isValid() && maTo.isValid() &&
+ ((maFrom.mnCol < maTo.mnCol) || ((maFrom.mnCol == maTo.mnCol) && (maFrom.mnColOffset < maTo.mnColOffset))) &&
+ ((maFrom.mnRow < maTo.mnRow) || ((maFrom.mnRow == maTo.mnRow) && (maFrom.mnRowOffset < maTo.mnRowOffset)));
+ break;
+ case ANCHOR_INVALID:
+ OSL_ENSURE( false, "ShapeAnchor::isValidAnchor - invalid anchor" );
+ break;
+ }
+ return bValid;
+}
+
+Rectangle ShapeAnchor::calcApiLocation( const Size& rApiSheetSize, const AnchorSizeModel& rEmuSheetSize ) const
+{
+ AddressConverter& rAddrConv = getAddressConverter();
+ UnitConverter& rUnitConv = getUnitConverter();
+ Rectangle aApiLoc( -1, -1, -1, -1 );
+ Unit eUnitX = (meType == ANCHOR_VML) ? UNIT_SCREENX : UNIT_EMU;
+ Unit eUnitY = (meType == ANCHOR_VML) ? UNIT_SCREENY : UNIT_EMU;
+
+ // calculate shape position
+ switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcApiLocation - invalid position" );
+ if( maPos.isValid() && (maPos.X < rEmuSheetSize.Width) && (maPos.Y < rEmuSheetSize.Height) )
+ {
+ aApiLoc.X = rUnitConv.scaleToMm100( static_cast< double >( maPos.X ), UNIT_EMU );
+ aApiLoc.Y = rUnitConv.scaleToMm100( static_cast< double >( maPos.Y ), UNIT_EMU );
+ }
+ break;
+ case ANCHOR_ONECELL:
+ case ANCHOR_TWOCELL:
+ case ANCHOR_VML:
+ OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcApiLocation - invalid position" );
+ if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) )
+ {
+ Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow );
+ aApiLoc.X = aPoint.X + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnColOffset ), eUnitX );
+ aApiLoc.Y = aPoint.Y + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnRowOffset ), eUnitY );
+ }
+ break;
+ case ANCHOR_INVALID:
+ OSL_ENSURE( false, "ShapeAnchor::calcApiLocation - invalid anchor" );
+ break;
+ }
+
+ // calculate shape size
+ if( (aApiLoc.X >= 0) && (aApiLoc.Y >= 0) ) switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ case ANCHOR_ONECELL:
+ OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcApiLocation - invalid size" );
+ if( maSize.isValid() )
+ {
+ aApiLoc.Width = ::std::min< sal_Int32 >(
+ rUnitConv.scaleToMm100( static_cast< double >( maSize.Width ), UNIT_EMU ),
+ rApiSheetSize.Width - aApiLoc.X );
+ aApiLoc.Height = ::std::min< sal_Int32 >(
+ rUnitConv.scaleToMm100( static_cast< double >( maSize.Height ), UNIT_EMU ),
+ rApiSheetSize.Height - aApiLoc.Y );
+ }
+ break;
+ case ANCHOR_TWOCELL:
+ case ANCHOR_VML:
+ OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcApiLocation - invalid position" );
+ if( maTo.isValid() )
+ {
+ /* Pass a valid cell address to getCellPosition(), otherwise
+ nothing is returned, even if either row or column is valid. */
+ CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true );
+ Point aPoint = getCellPosition( aToCell.Column, aToCell.Row );
+ // width
+ aApiLoc.Width = rApiSheetSize.Width - aApiLoc.X;
+ if( aToCell.Column == maTo.mnCol )
+ {
+ aPoint.X += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnColOffset ), eUnitX );
+ aApiLoc.Width = ::std::min< sal_Int32 >( aPoint.X - aApiLoc.X + 1, aApiLoc.Width );
+ }
+ // height
+ aApiLoc.Height = rApiSheetSize.Height - aApiLoc.Y;
+ if( aToCell.Row == maTo.mnRow )
+ {
+ aPoint.Y += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnRowOffset ), eUnitY );
+ aApiLoc.Height = ::std::min< sal_Int32 >( aPoint.Y - aApiLoc.Y + 1, aApiLoc.Height );
+ }
+ }
+ break;
+ case ANCHOR_INVALID:
+ break;
+ }
+
+ return aApiLoc;
+}
+
+Rectangle ShapeAnchor::calcEmuLocation( const AnchorSizeModel& rEmuSheetSize ) const
+{
+ AddressConverter& rAddrConv = getAddressConverter();
+ UnitConverter& rUnitConv = getUnitConverter();
+
+ Size aSheetSize(
+ getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.Width, 0, SAL_MAX_INT32 ),
+ getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.Height, 0, SAL_MAX_INT32 ) );
+ Rectangle aLoc( -1, -1, -1, -1 );
+ Unit eUnitX = (meType == ANCHOR_VML) ? UNIT_SCREENX : UNIT_EMU;
+ Unit eUnitY = (meType == ANCHOR_VML) ? UNIT_SCREENY : UNIT_EMU;
+
+ // calculate shape position
+ switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" );
+ if( maPos.isValid() && (maPos.X < aSheetSize.Width) && (maPos.Y < aSheetSize.Height) )
+ {
+ aLoc.X = static_cast< sal_Int32 >( maPos.X );
+ aLoc.Y = static_cast< sal_Int32 >( maPos.Y );
+ }
+ break;
+ case ANCHOR_ONECELL:
+ case ANCHOR_TWOCELL:
+ case ANCHOR_VML:
+ OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" );
+ if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) )
+ {
+ Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow );
+ sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) ) + lclCalcEmu( rUnitConv, maFrom.mnColOffset, eUnitX );
+ sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) ) + lclCalcEmu( rUnitConv, maFrom.mnRowOffset, eUnitY );
+ if( (nX < aSheetSize.Width) && (nY < aSheetSize.Height) )
+ {
+ aLoc.X = static_cast< sal_Int32 >( nX );
+ aLoc.Y = static_cast< sal_Int32 >( nY );
+ }
+ }
+ break;
+ case ANCHOR_INVALID:
+ OSL_ENSURE( false, "ShapeAnchor::calcEmuLocation - invalid anchor" );
+ break;
+ }
+
+ // calculate shape size
+ if( (aLoc.X >= 0) && (aLoc.Y >= 0) ) switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ case ANCHOR_ONECELL:
+ OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcEmuLocation - invalid size" );
+ if( maSize.isValid() )
+ {
+ aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.Width, aSheetSize.Width - aLoc.X ) );
+ aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.Height, aSheetSize.Height - aLoc.Y ) );
+ }
+ break;
+ case ANCHOR_TWOCELL:
+ case ANCHOR_VML:
+ OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" );
+ if( maTo.isValid() )
+ {
+ /* Pass a valid cell address to getCellPosition(), otherwise
+ nothing is returned, even if either row or column is valid. */
+ CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true );
+ Point aPoint = getCellPosition( aToCell.Column, aToCell.Row );
+ sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) );
+ sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) );
+ // width
+ aLoc.Width = aSheetSize.Width - aLoc.X;
+ if( aToCell.Column == maTo.mnCol )
+ {
+ nX += lclCalcEmu( rUnitConv, maTo.mnColOffset, eUnitX );
+ aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nX - aLoc.X + 1, aLoc.Width ) );
+ }
+ // height
+ aLoc.Height = aSheetSize.Height - aLoc.Y;
+ if( aToCell.Row == maTo.mnRow )
+ {
+ nY += lclCalcEmu( rUnitConv, maTo.mnRowOffset, eUnitY );
+ aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nY - aLoc.Y + 1, aLoc.Height ) );
+ }
+ }
+ break;
+ case ANCHOR_INVALID:
+ break;
+ }
+
+ // add 0.75 mm (27,000 EMUs) in X direction to correct display error
+ if( aLoc.X >= 0 )
+ aLoc.X += 27000;
+ // remove 0.25 mm (9,000 EMUs) in Y direction to correct display error
+ if( aLoc.Y >= 9000 )
+ aLoc.Y -= 9000;
+
+ return aLoc;
+}
+
+// ============================================================================
+
+ShapeMacroAttacher::ShapeMacroAttacher( const OUString& rMacroName, const Reference< XShape >& rxShape ) :
+ VbaMacroAttacherBase( rMacroName ),
+ mxShape( rxShape )
+{
+}
+
+void ShapeMacroAttacher::attachMacro( const OUString& rMacroUrl )
+{
+ try
+ {
+ Reference< XEventsSupplier > xSupplier( mxShape, UNO_QUERY_THROW );
+ Reference< XNameReplace > xEvents( xSupplier->getEvents(), UNO_SET_THROW );
+ Sequence< PropertyValue > aEventProps( 2 );
+ aEventProps[ 0 ].Name = CREATE_OUSTRING( "EventType" );
+ aEventProps[ 0 ].Value <<= CREATE_OUSTRING( "Script" );
+ aEventProps[ 1 ].Name = CREATE_OUSTRING( "Script" );
+ aEventProps[ 1 ].Value <<= rMacroUrl;
+ xEvents->replaceByName( CREATE_OUSTRING( "OnClick" ), Any( aEventProps ) );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+Shape::Shape( const WorksheetHelper& rHelper, const AttributeList& rAttribs, const sal_Char* pcServiceName ) :
+ ::oox::drawingml::Shape( pcServiceName ),
+ WorksheetHelper( rHelper )
+{
+ OUString aMacro = rAttribs.getXString( XML_macro, OUString() );
+ if( aMacro.getLength() > 0 )
+ maMacroName = getFormulaParser().importMacroName( aMacro );
+}
+
+void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
+{
+ if( (maMacroName.getLength() > 0) && mxShape.is() )
+ {
+ VbaMacroAttacherRef xAttacher( new ShapeMacroAttacher( maMacroName, mxShape ) );
+ getBaseFilter().getVbaProject().registerMacroAttacher( xAttacher );
+ }
+ ::oox::drawingml::Shape::finalizeXShape( rFilter, rxShapes );
+}
+
+// ============================================================================
+
+GroupShapeContext::GroupShapeContext( ContextHandler& rParent,
+ const WorksheetHelper& rHelper, const ShapePtr& rxParentShape, const ShapePtr& rxShape ) :
+ ShapeGroupContext( rParent, rxParentShape, rxShape ),
+ WorksheetHelper( rHelper )
+{
+}
+
+/*static*/ ContextHandlerRef GroupShapeContext::createShapeContext( ContextHandler& rParent,
+ const WorksheetHelper& rHelper, sal_Int32 nElement, const AttributeList& rAttribs,
+ const ShapePtr& rxParentShape, ShapePtr* pxShape )
+{
+ switch( nElement )
+ {
+ case XDR_TOKEN( sp ):
+ {
+ ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.CustomShape" ) );
+ if( pxShape ) *pxShape = xShape;
+ return new ShapeContext( rParent, rxParentShape, xShape );
+ }
+ case XDR_TOKEN( cxnSp ):
+ {
+ ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.ConnectorShape" ) );
+ if( pxShape ) *pxShape = xShape;
+ return new ConnectorShapeContext( rParent, rxParentShape, xShape );
+ }
+ case XDR_TOKEN( pic ):
+ {
+ ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.GraphicObjectShape" ) );
+ if( pxShape ) *pxShape = xShape;
+ return new GraphicShapeContext( rParent, rxParentShape, xShape );
+ }
+ case XDR_TOKEN( graphicFrame ):
+ {
+ ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.GraphicObjectShape" ) );
+ if( pxShape ) *pxShape = xShape;
+ return new GraphicalObjectFrameContext( rParent, rxParentShape, xShape, rHelper.getSheetType() != SHEETTYPE_CHARTSHEET );
+ }
+ case XDR_TOKEN( grpSp ):
+ {
+ ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.GroupShape" ) );
+ if( pxShape ) *pxShape = xShape;
+ return new GroupShapeContext( rParent, rHelper, rxParentShape, xShape );
+ }
+ }
+ return 0;
+}
+
+Reference< XFastContextHandler > SAL_CALL GroupShapeContext::createFastChildContext(
+ sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
+{
+ ContextHandlerRef xContext = createShapeContext( *this, *this, nElement, AttributeList( rxAttribs ), mpGroupShapePtr );
+ return xContext.get() ? xContext.get() : ShapeGroupContext::createFastChildContext( nElement, rxAttribs );
+}
+
+// ============================================================================
+
+DrawingFragment::DrawingFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath ),
+ mxDrawPage( rHelper.getDrawPage(), UNO_QUERY )
+{
+ OSL_ENSURE( mxDrawPage.is(), "DrawingFragment::DrawingFragment - missing drawing page" );
+ maApiSheetSize = getDrawPageSize();
+ maEmuSheetSize.Width = static_cast< sal_Int64 >( getUnitConverter().scaleFromMm100( maApiSheetSize.Width, UNIT_EMU ) );
+ maEmuSheetSize.Height = static_cast< sal_Int64 >( getUnitConverter().scaleFromMm100( maApiSheetSize.Height, UNIT_EMU ) );
+}
+
+ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XDR_TOKEN( wsDr ) ) return this;
+ break;
+
+ case XDR_TOKEN( wsDr ):
+ switch( nElement )
+ {
+ case XDR_TOKEN( absoluteAnchor ):
+ case XDR_TOKEN( oneCellAnchor ):
+ case XDR_TOKEN( twoCellAnchor ):
+ mxAnchor.reset( new ShapeAnchor( *this ) );
+ mxAnchor->importAnchor( nElement, rAttribs );
+ return this;
+ }
+ break;
+
+ case XDR_TOKEN( absoluteAnchor ):
+ case XDR_TOKEN( oneCellAnchor ):
+ case XDR_TOKEN( twoCellAnchor ):
+ {
+ switch( nElement )
+ {
+ case XDR_TOKEN( from ):
+ case XDR_TOKEN( to ): return this;
+
+ case XDR_TOKEN( pos ): if( mxAnchor.get() ) mxAnchor->importPos( rAttribs ); break;
+ case XDR_TOKEN( ext ): if( mxAnchor.get() ) mxAnchor->importExt( rAttribs ); break;
+ case XDR_TOKEN( clientData ): if( mxAnchor.get() ) mxAnchor->importClientData( rAttribs ); break;
+
+ default: return GroupShapeContext::createShapeContext( *this, *this, nElement, rAttribs, ShapePtr(), &mxShape );
+ }
+ }
+ break;
+
+ case XDR_TOKEN( from ):
+ case XDR_TOKEN( to ):
+ switch( nElement )
+ {
+ case XDR_TOKEN( col ):
+ case XDR_TOKEN( row ):
+ case XDR_TOKEN( colOff ):
+ case XDR_TOKEN( rowOff ): return this; // collect index in onCharacters()
+ }
+ break;
+ }
+ return 0;
+}
+
+void DrawingFragment::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case XDR_TOKEN( col ):
+ case XDR_TOKEN( row ):
+ case XDR_TOKEN( colOff ):
+ case XDR_TOKEN( rowOff ):
+ if( mxAnchor.get() ) mxAnchor->setCellPos( getCurrentElement(), getParentElement(), rChars );
+ break;
+ }
+}
+
+void DrawingFragment::onEndElement()
+{
+ switch( getCurrentElement() )
+ {
+ case XDR_TOKEN( absoluteAnchor ):
+ case XDR_TOKEN( oneCellAnchor ):
+ case XDR_TOKEN( twoCellAnchor ):
+ if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() && mxAnchor->isValidAnchor() )
+ {
+ Rectangle aShapeRect = mxAnchor->calcEmuLocation( maEmuSheetSize );
+ if( (aShapeRect.X >= 0) && (aShapeRect.Y >= 0) && (aShapeRect.Width >= 0) && (aShapeRect.Height >= 0) )
+ {
+ mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRect );
+ /* Collect all shape positions in the WorksheetHelper base
+ class. But first, scale EMUs to 1/100 mm. */
+ const UnitConverter& rUnitConv = getUnitConverter();
+ Rectangle aShapeRectHmm(
+ rUnitConv.scaleToMm100( aShapeRect.X, UNIT_EMU ),
+ rUnitConv.scaleToMm100( aShapeRect.Y, UNIT_EMU ),
+ rUnitConv.scaleToMm100( aShapeRect.Width, UNIT_EMU ),
+ rUnitConv.scaleToMm100( aShapeRect.Height, UNIT_EMU ) );
+ extendShapeBoundingBox( aShapeRectHmm );
+ }
+ }
+ mxShape.reset();
+ mxAnchor.reset();
+ break;
+ }
+}
+
+// ============================================================================
+// VML
+// ============================================================================
+
+namespace {
+
+class VmlFindNoteFunc
+{
+public:
+ explicit VmlFindNoteFunc( const CellAddress& rPos );
+ bool operator()( const ::oox::vml::ShapeBase& rShape ) const;
+
+private:
+ sal_Int32 mnCol;
+ sal_Int32 mnRow;
+};
+
+// ----------------------------------------------------------------------------
+
+VmlFindNoteFunc::VmlFindNoteFunc( const CellAddress& rPos ) :
+ mnCol( rPos.Column ),
+ mnRow( rPos.Row )
+{
+}
+
+bool VmlFindNoteFunc::operator()( const ::oox::vml::ShapeBase& rShape ) const
+{
+ const ::oox::vml::ClientData* pClientData = rShape.getClientData();
+ return pClientData && (pClientData->mnCol == mnCol) && (pClientData->mnRow == mnRow);
+}
+
+} // namespace
+
+// ============================================================================
+
+VmlControlMacroAttacher::VmlControlMacroAttacher( const OUString& rMacroName,
+ const Reference< XIndexContainer >& rxCtrlFormIC, sal_Int32 nCtrlIndex, sal_Int32 nCtrlType, sal_Int32 nDropStyle ) :
+ VbaMacroAttacherBase( rMacroName ),
+ mxCtrlFormIC( rxCtrlFormIC ),
+ mnCtrlIndex( nCtrlIndex ),
+ mnCtrlType( nCtrlType ),
+ mnDropStyle( nDropStyle )
+{
+}
+
+void VmlControlMacroAttacher::attachMacro( const OUString& rMacroUrl )
+{
+ ScriptEventDescriptor aEventDesc;
+ aEventDesc.ScriptType = CREATE_OUSTRING( "Script" );
+ aEventDesc.ScriptCode = rMacroUrl;
+
+ // editable drop downs are treated like edit boxes
+ bool bEditDropDown = (mnCtrlType == XML_Drop) && (mnDropStyle == XML_ComboEdit);
+ sal_Int32 nCtrlType = bEditDropDown ? XML_Edit : mnCtrlType;
+
+ switch( nCtrlType )
+ {
+ case XML_Button:
+ case XML_Checkbox:
+ case XML_Radio:
+ aEventDesc.ListenerType = CREATE_OUSTRING( "XActionListener" );
+ aEventDesc.EventMethod = CREATE_OUSTRING( "actionPerformed" );
+ break;
+ case XML_Label:
+ case XML_GBox:
+ case XML_Dialog:
+ aEventDesc.ListenerType = CREATE_OUSTRING( "XMouseListener" );
+ aEventDesc.EventMethod = CREATE_OUSTRING( "mouseReleased" );
+ break;
+ case XML_Edit:
+ aEventDesc.ListenerType = CREATE_OUSTRING( "XTextListener" );
+ aEventDesc.EventMethod = CREATE_OUSTRING( "textChanged" );
+ break;
+ case XML_Spin:
+ case XML_Scroll:
+ aEventDesc.ListenerType = CREATE_OUSTRING( "XAdjustmentListener" );
+ aEventDesc.EventMethod = CREATE_OUSTRING( "adjustmentValueChanged" );
+ break;
+ case XML_List:
+ case XML_Drop:
+ aEventDesc.ListenerType = CREATE_OUSTRING( "XChangeListener" );
+ aEventDesc.EventMethod = CREATE_OUSTRING( "changed" );
+ break;
+ default:
+ OSL_ENSURE( false, "VmlControlMacroAttacher::attachMacro - unexpected object type" );
+ return;
+ }
+
+ try
+ {
+ Reference< XEventAttacherManager > xEventMgr( mxCtrlFormIC, UNO_QUERY_THROW );
+ xEventMgr->registerScriptEvent( mnCtrlIndex, aEventDesc );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+VmlDrawing::VmlDrawing( const WorksheetHelper& rHelper ) :
+ ::oox::vml::Drawing( rHelper.getOoxFilter(), rHelper.getDrawPage(), ::oox::vml::VMLDRAWING_EXCEL ),
+ WorksheetHelper( rHelper ),
+ maControlConv( rHelper.getBaseFilter().getModel(), rHelper.getBaseFilter().getGraphicHelper() )
+{
+ // default font for legacy listboxes and dropdowns: Tahoma, 8pt
+ maListBoxFont.moName = CREATE_OUSTRING( "Tahoma" );
+ maListBoxFont.moColor = CREATE_OUSTRING( "auto" );
+ maListBoxFont.monSize = 160;
+}
+
+const ::oox::vml::ShapeBase* VmlDrawing::getNoteShape( const CellAddress& rPos ) const
+{
+ return getShapes().findShape( VmlFindNoteFunc( rPos ) );
+}
+
+bool VmlDrawing::isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const
+{
+ const ::oox::vml::ClientData* pClientData = rShape.getClientData();
+ return !pClientData || (pClientData->mnObjType != XML_Note);
+}
+
+OUString VmlDrawing::getShapeBaseName( const ::oox::vml::ShapeBase& rShape ) const
+{
+ if( const ::oox::vml::ClientData* pClientData = rShape.getClientData() )
+ {
+ switch( pClientData->mnObjType )
+ {
+ case XML_Button: return CREATE_OUSTRING( "Button" );
+ case XML_Checkbox: return CREATE_OUSTRING( "Check Box" );
+ case XML_Dialog: return CREATE_OUSTRING( "Dialog Frame" );
+ case XML_Drop: return CREATE_OUSTRING( "Drop Down" );
+ case XML_Edit: return CREATE_OUSTRING( "Edit Box" );
+ case XML_GBox: return CREATE_OUSTRING( "Group Box" );
+ case XML_Label: return CREATE_OUSTRING( "Label" );
+ case XML_List: return CREATE_OUSTRING( "List Box" );
+ case XML_Note: return CREATE_OUSTRING( "Comment" );
+ case XML_Pict: return (pClientData->mbDde || getOleObjectInfo( rShape.getShapeId() )) ? CREATE_OUSTRING( "Object" ) : CREATE_OUSTRING( "Picture" );
+ case XML_Radio: return CREATE_OUSTRING( "Option Button" );
+ case XML_Scroll: return CREATE_OUSTRING( "Scroll Bar" );
+ case XML_Spin: return CREATE_OUSTRING( "Spinner" );
+ }
+ }
+ return ::oox::vml::Drawing::getShapeBaseName( rShape );
+}
+
+bool VmlDrawing::convertClientAnchor( Rectangle& orShapeRect, const OUString& rShapeAnchor ) const
+{
+ if( rShapeAnchor.getLength() == 0 )
+ return false;
+ ShapeAnchor aAnchor( *this );
+ aAnchor.importVmlAnchor( rShapeAnchor );
+ orShapeRect = aAnchor.calcApiLocation( getDrawPageSize(), AnchorSizeModel() );
+ return (orShapeRect.Width >= 0) && (orShapeRect.Height >= 0);
+}
+
+Reference< XShape > VmlDrawing::createAndInsertClientXShape( const ::oox::vml::ShapeBase& rShape,
+ const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ // simulate the legacy drawing controls with OLE form controls
+ OUString aShapeName = rShape.getShapeName();
+ const ::oox::vml::ClientData* pClientData = rShape.getClientData();
+ if( (aShapeName.getLength() > 0) && pClientData )
+ {
+ Rectangle aShapeRect = rShapeRect;
+ const ::oox::vml::TextBox* pTextBox = rShape.getTextBox();
+ EmbeddedControl aControl( aShapeName );
+ switch( pClientData->mnObjType )
+ {
+ case XML_Button:
+ {
+ AxCommandButtonModel& rAxModel = aControl.createModel< AxCommandButtonModel >();
+ convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign );
+ rAxModel.mnFlags = AX_FLAGS_ENABLED | AX_FLAGS_OPAQUE | AX_FLAGS_WORDWRAP;
+ rAxModel.mnVerticalAlign = pClientData->mnTextVAlign;
+ }
+ break;
+
+ case XML_Label:
+ {
+ AxLabelModel& rAxModel = aControl.createModel< AxLabelModel >();
+ convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign );
+ rAxModel.mnFlags = AX_FLAGS_ENABLED | AX_FLAGS_WORDWRAP;
+ rAxModel.mnBorderStyle = AX_BORDERSTYLE_NONE;
+ rAxModel.mnSpecialEffect = AX_SPECIALEFFECT_FLAT;
+ rAxModel.mnVerticalAlign = pClientData->mnTextVAlign;
+ }
+ break;
+
+ case XML_Edit:
+ {
+ bool bNumeric = (pClientData->mnVTEdit == ::oox::vml::VML_CLIENTDATA_INTEGER) || (pClientData->mnVTEdit == ::oox::vml::VML_CLIENTDATA_NUMBER);
+ AxMorphDataModelBase& rAxModel = bNumeric ?
+ static_cast< AxMorphDataModelBase& >( aControl.createModel< AxNumericFieldModel >() ) :
+ static_cast< AxMorphDataModelBase& >( aControl.createModel< AxTextBoxModel >() );
+ convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maValue, pTextBox, pClientData->mnTextHAlign );
+ setFlag( rAxModel.mnFlags, AX_FLAGS_MULTILINE, pClientData->mbMultiLine );
+ setFlag( rAxModel.mnScrollBars, AX_SCROLLBAR_VERTICAL, pClientData->mbVScroll );
+ if( pClientData->mbSecretEdit )
+ rAxModel.mnPasswordChar = '*';
+ }
+ break;
+
+ case XML_GBox:
+ {
+ AxFrameModel& rAxModel = aControl.createModel< AxFrameModel >();
+ convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign );
+ rAxModel.mnBorderStyle = pClientData->mbNo3D ? AX_BORDERSTYLE_SINGLE : AX_BORDERSTYLE_NONE;
+ rAxModel.mnSpecialEffect = pClientData->mbNo3D ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_BUMPED;
+
+ /* Move top border of groupbox up by half font height, because
+ Excel specifies Y position of the groupbox border line
+ instead the top border of the caption text. */
+ if( const ::oox::vml::TextFontModel* pFontModel = pTextBox ? pTextBox->getFirstFont() : 0 )
+ {
+ sal_Int32 nFontHeightHmm = getUnitConverter().scaleToMm100( pFontModel->monSize.get( 160 ), UNIT_TWIP );
+ sal_Int32 nYDiff = ::std::min< sal_Int32 >( nFontHeightHmm / 2, aShapeRect.Y );
+ aShapeRect.Y -= nYDiff;
+ aShapeRect.Height += nYDiff;
+ }
+ }
+ break;
+
+ case XML_Checkbox:
+ {
+ AxCheckBoxModel& rAxModel = aControl.createModel< AxCheckBoxModel >();
+ convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign );
+ convertControlBackground( rAxModel, rShape );
+ rAxModel.maValue = OUString::valueOf( pClientData->mnChecked );
+ rAxModel.mnSpecialEffect = pClientData->mbNo3D ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN;
+ rAxModel.mnVerticalAlign = pClientData->mnTextVAlign;
+ bool bTriState = (pClientData->mnChecked != ::oox::vml::VML_CLIENTDATA_UNCHECKED) && (pClientData->mnChecked != ::oox::vml::VML_CLIENTDATA_CHECKED);
+ rAxModel.mnMultiSelect = bTriState ? AX_SELCTION_MULTI : AX_SELCTION_SINGLE;
+ }
+ break;
+
+ case XML_Radio:
+ {
+ AxOptionButtonModel& rAxModel = aControl.createModel< AxOptionButtonModel >();
+ convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign );
+ convertControlBackground( rAxModel, rShape );
+ rAxModel.maValue = OUString::valueOf( pClientData->mnChecked );
+ rAxModel.mnSpecialEffect = pClientData->mbNo3D ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN;
+ rAxModel.mnVerticalAlign = pClientData->mnTextVAlign;
+ }
+ break;
+
+ case XML_List:
+ {
+ AxListBoxModel& rAxModel = aControl.createModel< AxListBoxModel >();
+ convertControlFontData( rAxModel.maFontData, rAxModel.mnTextColor, maListBoxFont );
+ rAxModel.mnBorderStyle = pClientData->mbNo3D2 ? AX_BORDERSTYLE_SINGLE : AX_BORDERSTYLE_NONE;
+ rAxModel.mnSpecialEffect = pClientData->mbNo3D2 ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN;
+ switch( pClientData->mnSelType )
+ {
+ case XML_Single: rAxModel.mnMultiSelect = AX_SELCTION_SINGLE; break;
+ case XML_Multi: rAxModel.mnMultiSelect = AX_SELCTION_MULTI; break;
+ case XML_Extend: rAxModel.mnMultiSelect = AX_SELCTION_EXTENDED; break;
+ }
+ }
+ break;
+
+ case XML_Drop:
+ {
+ AxComboBoxModel& rAxModel = aControl.createModel< AxComboBoxModel >();
+ convertControlFontData( rAxModel.maFontData, rAxModel.mnTextColor, maListBoxFont );
+ rAxModel.mnDisplayStyle = AX_DISPLAYSTYLE_DROPDOWN;
+ rAxModel.mnShowDropButton = AX_SHOWDROPBUTTON_ALWAYS;
+ rAxModel.mnBorderStyle = pClientData->mbNo3D2 ? AX_BORDERSTYLE_SINGLE : AX_BORDERSTYLE_NONE;
+ rAxModel.mnSpecialEffect = pClientData->mbNo3D2 ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN;
+ rAxModel.mnListRows = pClientData->mnDropLines;
+ }
+ break;
+
+ case XML_Spin:
+ {
+ AxSpinButtonModel& rAxModel = aControl.createModel< AxSpinButtonModel >();
+ rAxModel.mnMin = pClientData->mnMin;
+ rAxModel.mnMax = pClientData->mnMax;
+ rAxModel.mnPosition = pClientData->mnVal;
+ rAxModel.mnSmallChange = pClientData->mnInc;
+ }
+ break;
+
+ case XML_Scroll:
+ {
+ AxScrollBarModel& rAxModel = aControl.createModel< AxScrollBarModel >();
+ rAxModel.mnMin = pClientData->mnMin;
+ rAxModel.mnMax = pClientData->mnMax;
+ rAxModel.mnPosition = pClientData->mnVal;
+ rAxModel.mnSmallChange = pClientData->mnInc;
+ rAxModel.mnLargeChange = pClientData->mnPage;
+ }
+ break;
+
+ case XML_Dialog:
+ {
+ // fake with a group box
+ AxFrameModel& rAxModel = aControl.createModel< AxFrameModel >();
+ convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, XML_Left );
+ rAxModel.mnBorderStyle = AX_BORDERSTYLE_SINGLE;
+ rAxModel.mnSpecialEffect = AX_SPECIALEFFECT_FLAT;
+ }
+ break;
+ }
+
+ if( ControlModelBase* pAxModel = aControl.getModel() )
+ {
+ // create the control shape
+ pAxModel->maSize.first = aShapeRect.Width;
+ pAxModel->maSize.second = aShapeRect.Height;
+ sal_Int32 nCtrlIndex = -1;
+ Reference< XShape > xShape = createAndInsertXControlShape( aControl, rxShapes, aShapeRect, nCtrlIndex );
+
+ // control shape macro
+ if( xShape.is() && (nCtrlIndex >= 0) && (pClientData->maFmlaMacro.getLength() > 0) )
+ {
+ OUString aMacroName = getFormulaParser().importMacroName( pClientData->maFmlaMacro );
+ if( aMacroName.getLength() > 0 )
+ {
+ Reference< XIndexContainer > xFormIC = getControlForm().getXForm();
+ VbaMacroAttacherRef xAttacher( new VmlControlMacroAttacher( aMacroName, xFormIC, nCtrlIndex, pClientData->mnObjType, pClientData->mnDropStyle ) );
+ getBaseFilter().getVbaProject().registerMacroAttacher( xAttacher );
+ }
+ }
+
+ return xShape;
+ }
+ }
+
+ return Reference< XShape >();
+}
+
+void VmlDrawing::notifyXShapeInserted( const Reference< XShape >& rxShape,
+ const Rectangle& rShapeRect, const ::oox::vml::ShapeBase& rShape, bool bGroupChild )
+{
+ // collect all shape positions in the WorksheetHelper base class (but not children of group shapes)
+ if( !bGroupChild )
+ extendShapeBoundingBox( rShapeRect );
+
+ // convert settings from VML client data
+ if( const ::oox::vml::ClientData* pClientData = rShape.getClientData() )
+ {
+ // specific settings for embedded form controls
+ try
+ {
+ Reference< XControlShape > xCtrlShape( rxShape, UNO_QUERY_THROW );
+ Reference< XControlModel > xCtrlModel( xCtrlShape->getControl(), UNO_SET_THROW );
+ PropertySet aPropSet( xCtrlModel );
+
+ // printable
+ aPropSet.setProperty( PROP_Printable, pClientData->mbPrintObject );
+
+ // control source links
+ if( (pClientData->maFmlaLink.getLength() > 0) || (pClientData->maFmlaRange.getLength() > 0) )
+ maControlConv.bindToSources( xCtrlModel, pClientData->maFmlaLink, pClientData->maFmlaRange, getSheetIndex() );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+// private --------------------------------------------------------------------
+
+sal_uInt32 VmlDrawing::convertControlTextColor( const OUString& rTextColor ) const
+{
+ // color attribute not present or 'auto' - use passed default color
+ if( (rTextColor.getLength() == 0) || rTextColor.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "auto" ) ) )
+ return AX_SYSCOLOR_WINDOWTEXT;
+
+ if( rTextColor[ 0 ] == '#' )
+ {
+ // RGB colors in the format '#RRGGBB'
+ if( rTextColor.getLength() == 7 )
+ return OleHelper::encodeOleColor( rTextColor.copy( 1 ).toInt32( 16 ) );
+
+ // RGB colors in the format '#RGB'
+ if( rTextColor.getLength() == 4 )
+ {
+ sal_Int32 nR = rTextColor.copy( 1, 1 ).toInt32( 16 ) * 0x11;
+ sal_Int32 nG = rTextColor.copy( 2, 1 ).toInt32( 16 ) * 0x11;
+ sal_Int32 nB = rTextColor.copy( 3, 1 ).toInt32( 16 ) * 0x11;
+ return OleHelper::encodeOleColor( (nR << 16) | (nG << 8) | nB );
+ }
+
+ OSL_ENSURE( false, OStringBuffer( "VmlDrawing::convertControlTextColor - invalid color name '" ).
+ append( OUStringToOString( rTextColor, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() );
+ return AX_SYSCOLOR_WINDOWTEXT;
+ }
+
+ const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
+
+ /* Predefined color names or system color names (resolve to RGB to detect
+ valid color name). */
+ sal_Int32 nColorToken = AttributeConversion::decodeToken( rTextColor );
+ sal_Int32 nRgbValue = Color::getVmlPresetColor( nColorToken, API_RGB_TRANSPARENT );
+ if( nRgbValue == API_RGB_TRANSPARENT )
+ nRgbValue = rGraphicHelper.getSystemColor( nColorToken, API_RGB_TRANSPARENT );
+ if( nRgbValue != API_RGB_TRANSPARENT )
+ return OleHelper::encodeOleColor( nRgbValue );
+
+ // try palette color
+ return OleHelper::encodeOleColor( rGraphicHelper.getPaletteColor( rTextColor.toInt32() ) );
+}
+
+void VmlDrawing::convertControlFontData( AxFontData& rAxFontData, sal_uInt32& rnOleTextColor, const ::oox::vml::TextFontModel& rFontModel ) const
+{
+ if( rFontModel.moName.has() )
+ rAxFontData.maFontName = rFontModel.moName.get();
+
+ // font height: convert from twips to points, then to internal representation of AX controls
+ rAxFontData.setHeightPoints( static_cast< sal_Int16 >( (rFontModel.monSize.get( 200 ) + 10) / 20 ) );
+
+ // font effects
+ rAxFontData.mnFontEffects = 0;
+ setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_BOLD, rFontModel.mobBold.get( false ) );
+ setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_ITALIC, rFontModel.mobItalic.get( false ) );
+ setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_STRIKEOUT, rFontModel.mobStrikeout.get( false ) );
+ sal_Int32 nUnderline = rFontModel.monUnderline.get( XML_none );
+ setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_UNDERLINE, nUnderline != XML_none );
+ rAxFontData.mbDblUnderline = nUnderline == XML_double;
+
+ // font color
+ rnOleTextColor = convertControlTextColor( rFontModel.moColor.get( OUString() ) );
+}
+
+void VmlDrawing::convertControlText( AxFontData& rAxFontData, sal_uInt32& rnOleTextColor,
+ OUString& rCaption, const ::oox::vml::TextBox* pTextBox, sal_Int32 nTextHAlign ) const
+{
+ if( pTextBox )
+ {
+ rCaption = pTextBox->getText();
+ if( const ::oox::vml::TextFontModel* pFontModel = pTextBox->getFirstFont() )
+ convertControlFontData( rAxFontData, rnOleTextColor, *pFontModel );
+ }
+
+ switch( nTextHAlign )
+ {
+ case XML_Left: rAxFontData.mnHorAlign = AX_FONTDATA_LEFT; break;
+ case XML_Center: rAxFontData.mnHorAlign = AX_FONTDATA_CENTER; break;
+ case XML_Right: rAxFontData.mnHorAlign = AX_FONTDATA_RIGHT; break;
+ default: rAxFontData.mnHorAlign = AX_FONTDATA_LEFT;
+ }
+}
+
+void VmlDrawing::convertControlBackground( AxMorphDataModelBase& rAxModel, const ::oox::vml::ShapeBase& rShape ) const
+{
+ const ::oox::vml::FillModel& rFillModel = rShape.getTypeModel().maFillModel;
+ bool bHasFill = rFillModel.moFilled.get( true );
+ setFlag( rAxModel.mnFlags, AX_FLAGS_OPAQUE, bHasFill );
+ if( bHasFill )
+ {
+ const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
+ sal_Int32 nSysWindowColor = rGraphicHelper.getSystemColor( XML_window, API_RGB_WHITE );
+ ::oox::drawingml::Color aColor = ::oox::vml::ConversionHelper::decodeColor( rGraphicHelper, rFillModel.moColor, rFillModel.moOpacity, nSysWindowColor );
+ sal_Int32 nRgbValue = aColor.getColor( rGraphicHelper );
+ rAxModel.mnBackColor = OleHelper::encodeOleColor( nRgbValue );
+ }
+}
+
+// ============================================================================
+
+VmlDrawingFragment::VmlDrawingFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ ::oox::vml::DrawingFragment( rHelper.getOoxFilter(), rFragmentPath, rHelper.getVmlDrawing() ),
+ WorksheetHelper( rHelper )
+{
+}
+
+void VmlDrawingFragment::finalizeImport()
+{
+ ::oox::vml::DrawingFragment::finalizeImport();
+ getVmlDrawing().convertAndInsert();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/excelchartconverter.cxx b/oox/source/xls/excelchartconverter.cxx
new file mode 100644
index 000000000000..53c0a3b83bf2
--- /dev/null
+++ b/oox/source/xls/excelchartconverter.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/excelchartconverter.hxx"
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include "oox/drawingml/chart/datasourcemodel.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/xls/formulaparser.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::chart2;
+using namespace ::com::sun::star::chart2::data;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::oox::drawingml::chart::DataSequenceModel;
+using ::rtl::OUString;
+
+// ============================================================================
+
+ExcelChartConverter::ExcelChartConverter( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+ExcelChartConverter::~ExcelChartConverter()
+{
+}
+
+void ExcelChartConverter::createDataProvider( const Reference< XChartDocument >& rxChartDoc )
+{
+ try
+ {
+ Reference< XDataReceiver > xDataRec( rxChartDoc, UNO_QUERY_THROW );
+ Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW );
+ Reference< XDataProvider > xDataProv( xFactory->createInstance(
+ CREATE_OUSTRING( "com.sun.star.chart2.data.DataProvider" ) ), UNO_QUERY_THROW );
+ xDataRec->attachDataProvider( xDataProv );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+Reference< XDataSequence > ExcelChartConverter::createDataSequence(
+ const Reference< XDataProvider >& rxDataProvider, const DataSequenceModel& rDataSeq )
+{
+ Reference< XDataSequence > xDataSeq;
+ if( rxDataProvider.is() )
+ {
+ OUString aRangeRep;
+ if( rDataSeq.maFormula.getLength() > 0 )
+ {
+ // parse the formula string, create a token sequence
+ FormulaParser& rParser = getFormulaParser();
+ TokensFormulaContext aContext( true, true );
+ aContext.setBaseAddress( CellAddress( getCurrentSheetIndex(), 0, 0 ) );
+ rParser.importFormula( aContext, rDataSeq.maFormula );
+
+ // create a range list from the token sequence
+ ApiCellRangeList aRanges;
+ rParser.extractCellRangeList( aRanges, aContext.getTokens(), false );
+ aRangeRep = rParser.generateApiRangeListString( aRanges );
+ }
+ else if( !rDataSeq.maData.empty() )
+ {
+ // create a single-row array from constant source data
+ Matrix< Any > aMatrix( rDataSeq.maData.size(), 1 );
+ Matrix< Any >::iterator aMIt = aMatrix.begin();
+ // TODO: how to handle missing values in the map?
+ for( DataSequenceModel::AnyMap::const_iterator aDIt = rDataSeq.maData.begin(), aDEnd = rDataSeq.maData.end(); aDIt != aDEnd; ++aDIt, ++aMIt )
+ *aMIt = aDIt->second;
+ aRangeRep = FormulaProcessorBase::generateApiArray( aMatrix );
+ }
+
+ if( aRangeRep.getLength() > 0 ) try
+ {
+ // create the data sequence
+ xDataSeq = rxDataProvider->createDataSequenceByRangeRepresentation( aRangeRep );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "ExcelChartConverter::createDataSequence - cannot create data sequence" );
+ }
+ }
+ return xDataSeq;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/excelfilter.cxx b/oox/source/xls/excelfilter.cxx
new file mode 100644
index 000000000000..aeac1494c338
--- /dev/null
+++ b/oox/source/xls/excelfilter.cxx
@@ -0,0 +1,314 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/excelfilter.hxx"
+
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include "oox/dump/biffdumper.hxx"
+#include "oox/dump/xlsbdumper.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/xls/biffdetector.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/excelchartconverter.hxx"
+#include "oox/xls/excelvbaproject.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/workbookfragment.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+using ::oox::drawingml::table::TableStyleListPtr;
+
+// ============================================================================
+
+ExcelFilterBase::ExcelFilterBase() :
+ mpData( 0 )
+{
+}
+
+ExcelFilterBase::~ExcelFilterBase()
+{
+ OSL_ENSURE( !mpData, "ExcelFilterBase::~ExcelFilterBase - workbook data not cleared" );
+}
+
+void ExcelFilterBase::registerWorkbookData( WorkbookData& rData )
+{
+ mpData = &rData;
+}
+
+WorkbookData& ExcelFilterBase::getWorkbookData() const
+{
+ OSL_ENSURE( mpData, "ExcelFilterBase::getWorkbookData - missing workbook data" );
+ return *mpData;
+}
+
+void ExcelFilterBase::unregisterWorkbookData()
+{
+ mpData = 0;
+}
+
+// ============================================================================
+
+OUString SAL_CALL ExcelFilter_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelFilter" );
+}
+
+Sequence< OUString > SAL_CALL ExcelFilter_getSupportedServiceNames() throw()
+{
+ Sequence< OUString > aSeq( 2 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
+ aSeq[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL ExcelFilter_createInstance(
+ const Reference< XComponentContext >& rxContext ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new ExcelFilter( rxContext ) );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcelFilter::ExcelFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ XmlFilterBase( rxContext )
+{
+}
+
+ExcelFilter::~ExcelFilter()
+{
+}
+
+bool ExcelFilter::importDocument() throw()
+{
+ /* To activate the XLSX/XLSB dumper, insert the full path to the file
+ file:///<path-to-oox-module>/source/dump/xlsbdumper.ini
+ into the environment variable OOO_XLSBDUMPER and start the office with
+ this variable (nonpro only). */
+ OOX_DUMP_FILE( ::oox::dump::xlsb::Dumper );
+
+ OUString aWorkbookPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "officeDocument" ) );
+ if( aWorkbookPath.getLength() == 0 )
+ return false;
+
+ WorkbookHelperRoot aHelper( *this );
+ return aHelper.isValid() && importFragment( new WorkbookFragment( aHelper, aWorkbookPath ) );
+}
+
+bool ExcelFilter::exportDocument() throw()
+{
+ return false;
+}
+
+const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const
+{
+ return &WorkbookHelper( getWorkbookData() ).getTheme();
+}
+
+::oox::vml::Drawing* ExcelFilter::getVmlDrawing()
+{
+ return 0;
+}
+
+const TableStyleListPtr ExcelFilter::getTableStyles()
+{
+ return TableStyleListPtr();
+}
+
+::oox::drawingml::chart::ChartConverter& ExcelFilter::getChartConverter()
+{
+ return WorkbookHelper( getWorkbookData() ).getChartConverter();
+}
+
+GraphicHelper* ExcelFilter::implCreateGraphicHelper() const
+{
+ return new ExcelGraphicHelper( getWorkbookData() );
+}
+
+::oox::ole::VbaProject* ExcelFilter::implCreateVbaProject() const
+{
+ return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
+}
+
+OUString ExcelFilter::implGetImplementationName() const
+{
+ return ExcelFilter_getImplementationName();
+}
+
+// ============================================================================
+
+OUString SAL_CALL ExcelBiffFilter_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelBiffFilter" );
+}
+
+Sequence< OUString > SAL_CALL ExcelBiffFilter_getSupportedServiceNames() throw()
+{
+ Sequence< OUString > aSeq( 2 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
+ aSeq[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL ExcelBiffFilter_createInstance(
+ const Reference< XComponentContext >& rxContext ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new ExcelBiffFilter( rxContext ) );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcelBiffFilter::ExcelBiffFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ BinaryFilterBase( rxContext )
+{
+}
+
+ExcelBiffFilter::~ExcelBiffFilter()
+{
+}
+
+bool ExcelBiffFilter::importDocument() throw()
+{
+ /* To activate the BIFF dumper, insert the full path to the file
+ file:///<path-to-oox-module>/source/dump/biffdumper.ini
+ into the environment variable OOO_BIFFDUMPER and start the office with
+ this variable (nonpro only). */
+ OOX_DUMP_FILE( ::oox::dump::biff::Dumper );
+
+ /* The boolean argument "UseBiffFilter" passed through XInitialisation
+ decides whether to import/export the document with this filter (true),
+ or to only use the BIFF file dumper implemented in this filter (false
+ or missing) */
+ Any aUseBiffFilter = getArgument( CREATE_OUSTRING( "UseBiffFilter" ) );
+ bool bUseBiffFilter = false;
+ if( !(aUseBiffFilter >>= bUseBiffFilter) || !bUseBiffFilter )
+ return true;
+
+ // detect BIFF version and workbook stream name
+ OUString aWorkbookName;
+ BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
+ OSL_ENSURE( eBiff != BIFF_UNKNOWN, "ExcelBiffFilter::ExcelBiffFilter - invalid file format" );
+ if( eBiff == BIFF_UNKNOWN )
+ return false;
+
+ WorkbookHelperRoot aHelper( *this, eBiff );
+ return aHelper.isValid() && BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment();
+}
+
+bool ExcelBiffFilter::exportDocument() throw()
+{
+ return false;
+}
+
+GraphicHelper* ExcelBiffFilter::implCreateGraphicHelper() const
+{
+ return new ExcelGraphicHelper( getWorkbookData() );
+}
+
+::oox::ole::VbaProject* ExcelBiffFilter::implCreateVbaProject() const
+{
+ return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
+}
+
+OUString ExcelBiffFilter::implGetImplementationName() const
+{
+ return ExcelBiffFilter_getImplementationName();
+}
+
+// ============================================================================
+
+OUString SAL_CALL ExcelVbaProjectFilter_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelVbaProjectFilter" );
+}
+
+Sequence< OUString > SAL_CALL ExcelVbaProjectFilter_getSupportedServiceNames() throw()
+{
+ Sequence< OUString > aSeq( 1 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL ExcelVbaProjectFilter_createInstance(
+ const Reference< XComponentContext >& rxContext ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new ExcelVbaProjectFilter( rxContext ) );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcelVbaProjectFilter::ExcelVbaProjectFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
+ ExcelBiffFilter( rxContext )
+{
+}
+
+bool ExcelVbaProjectFilter::importDocument() throw()
+{
+ // detect BIFF version and workbook stream name
+ OUString aWorkbookName;
+ BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
+ OSL_ENSURE( eBiff == BIFF8, "ExcelVbaProjectFilter::ExcelVbaProjectFilter - invalid file format" );
+ if( eBiff != BIFF8 )
+ return false;
+
+ StorageRef xVbaPrjStrg = openSubStorage( CREATE_OUSTRING( "_VBA_PROJECT_CUR" ), false );
+ if( !xVbaPrjStrg || !xVbaPrjStrg->isStorage() )
+ return false;
+
+ WorkbookHelperRoot aHelper( *this, eBiff );
+ // set palette colors passed in service constructor
+ Any aPalette = getArgument( CREATE_OUSTRING( "ColorPalette" ) );
+ aHelper.getStyles().importPalette( aPalette );
+ // import the VBA project
+ getVbaProject().importVbaProject( *xVbaPrjStrg, getGraphicHelper() );
+ return true;
+}
+
+bool ExcelVbaProjectFilter::exportDocument() throw()
+{
+ return false;
+}
+
+OUString ExcelVbaProjectFilter::implGetImplementationName() const
+{
+ return ExcelVbaProjectFilter_getImplementationName();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/excelhandlers.cxx b/oox/source/xls/excelhandlers.cxx
new file mode 100644
index 000000000000..1ffad94d52f1
--- /dev/null
+++ b/oox/source/xls/excelhandlers.cxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/excelhandlers.hxx"
+
+#include "oox/core/filterbase.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using ::oox::core::FilterBase;
+using ::oox::core::FragmentHandler2;
+using ::rtl::OUString;
+
+// ============================================================================
+// ============================================================================
+
+WorkbookFragmentBase::WorkbookFragmentBase(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
+ WorkbookHelper( rHelper )
+{
+}
+
+// ============================================================================
+
+WorksheetFragmentBase::WorksheetFragmentBase( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
+ WorksheetHelperRoot( rHelper, rxProgressBar, eSheetType, nSheet )
+{
+}
+
+WorksheetFragmentBase::WorksheetFragmentBase(
+ const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
+ WorksheetHelperRoot( rHelper )
+{
+}
+
+// ============================================================================
+// ============================================================================
+
+BiffContextHandler::~BiffContextHandler()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+BiffWorkbookContextBase::BiffWorkbookContextBase( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+BiffWorksheetContextBase::BiffWorksheetContextBase( const WorkbookHelper& rHelper,
+ const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ WorksheetHelperRoot( rHelper, rxProgressBar, eSheetType, nSheet )
+{
+}
+
+BiffWorksheetContextBase::BiffWorksheetContextBase( const WorksheetHelper& rHelper ) :
+ WorksheetHelperRoot( rHelper )
+{
+}
+
+// ============================================================================
+
+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.
+
+BiffFragmentType lclStartFragment( BiffInputStream& rStrm, BiffType eBiff )
+{
+ BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN;
+ /* #i23425# Don't rely on BOF record ID to read BOF contents, but on
+ the detected BIFF version. */
+ if( BiffHelper::isBofRecord( rStrm ) )
+ {
+ // BOF is always written unencrypted
+ rStrm.enableDecoder( false );
+ rStrm.skip( 2 );
+ sal_uInt16 nType = rStrm.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_MACROSHEET; 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_MACROSHEET; 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_MACROSHEET; 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_CHARTSHEET; break;
+ case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break;
+ case BIFF_BOF_MODULE: eFragment = BIFF_FRAGMENT_MODULESHEET; 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;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+BiffFragmentHandler::BiffFragmentHandler( const FilterBase& rFilter, const OUString& rStrmName )
+{
+ // do not automatically close the root stream (indicated by empty stream name)
+ bool bRootStrm = rStrmName.getLength() == 0;
+ mxXInStrm.reset( new BinaryXInputStream( rFilter.openInputStream( rStrmName ), !bRootStrm ) );
+ mxBiffStrm.reset( new BiffInputStream( *mxXInStrm ) );
+}
+
+BiffFragmentHandler::~BiffFragmentHandler()
+{
+}
+
+BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff )
+{
+ return mxBiffStrm->startNextRecord() ? lclStartFragment( *mxBiffStrm, eBiff ) : BIFF_FRAGMENT_UNKNOWN;
+}
+
+BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff, sal_Int64 nRecHandle )
+{
+ return mxBiffStrm->startRecordByHandle( nRecHandle ) ? lclStartFragment( *mxBiffStrm, eBiff ) : BIFF_FRAGMENT_UNKNOWN;
+}
+
+bool BiffFragmentHandler::skipFragment()
+{
+ while( mxBiffStrm->startNextRecord() && (mxBiffStrm->getRecId() != BIFF_ID_EOF) )
+ if( BiffHelper::isBofRecord( *mxBiffStrm ) )
+ skipFragment();
+ return !mxBiffStrm->isEof() && (mxBiffStrm->getRecId() == BIFF_ID_EOF);
+}
+
+// ----------------------------------------------------------------------------
+
+BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelper, const OUString& rStrmName, bool bCloneDecoder ) :
+ BiffFragmentHandler( rHelper.getBaseFilter(), rStrmName ),
+ WorkbookHelper( rHelper )
+{
+ if( bCloneDecoder )
+ getCodecHelper().cloneDecoder( getInputStream() );
+}
+
+// ----------------------------------------------------------------------------
+
+BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ BiffFragmentHandler( rParent ),
+ WorksheetHelperRoot( rParent, rxProgressBar, eSheetType, nSheet )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+BiffSkipWorksheetFragment::BiffSkipWorksheetFragment( const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar, sal_Int16 nSheet ) :
+ BiffWorksheetFragmentBase( rParent, rxProgressBar, SHEETTYPE_EMPTYSHEET, nSheet )
+{
+}
+
+bool BiffSkipWorksheetFragment::importFragment()
+{
+ return skipFragment();
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/excelvbaproject.cxx b/oox/source/xls/excelvbaproject.cxx
new file mode 100755
index 000000000000..7fc8115cc680
--- /dev/null
+++ b/oox/source/xls/excelvbaproject.cxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/excelvbaproject.hxx"
+
+#include <list>
+#include <set>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertyset.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+ExcelVbaProject::ExcelVbaProject( const Reference< XComponentContext >& rxContext, const Reference< XSpreadsheetDocument >& rxDocument ) :
+ ::oox::ole::VbaProject( rxContext, Reference< XModel >( rxDocument, UNO_QUERY ), CREATE_OUSTRING( "Calc" ) ),
+ mxDocument( rxDocument )
+{
+}
+
+// protected ------------------------------------------------------------------
+
+namespace {
+
+struct SheetCodeNameInfo
+{
+ PropertySet maSheetProps; /// Property set of the sheet without codename.
+ OUString maPrefix; /// Prefix for the codename to be generated.
+
+ inline explicit SheetCodeNameInfo( PropertySet& rSheetProps, const OUString& rPrefix ) :
+ maSheetProps( rSheetProps ), maPrefix( rPrefix ) {}
+};
+
+typedef ::std::set< OUString > CodeNameSet;
+typedef ::std::list< SheetCodeNameInfo > SheetCodeNameInfoList;
+
+} // namespace
+
+void ExcelVbaProject::prepareImport()
+{
+ /* Check if the sheets have imported codenames. Generate new unused
+ codenames if not. */
+ if( mxDocument.is() ) try
+ {
+ // collect existing codenames (do not use them when creating new codenames)
+ CodeNameSet aUsedCodeNames;
+
+ // collect sheets without codenames
+ SheetCodeNameInfoList aCodeNameInfos;
+
+ // iterate over all imported sheets
+ Reference< XEnumerationAccess > xSheetsEA( mxDocument->getSheets(), UNO_QUERY_THROW );
+ Reference< XEnumeration > xSheetsEnum( xSheetsEA->createEnumeration(), UNO_SET_THROW );
+ // own try/catch for every sheet
+ while( xSheetsEnum->hasMoreElements() ) try
+ {
+ PropertySet aSheetProp( xSheetsEnum->nextElement() );
+ OUString aCodeName;
+ aSheetProp.getProperty( aCodeName, PROP_CodeName );
+ if( aCodeName.getLength() > 0 )
+ {
+ aUsedCodeNames.insert( aCodeName );
+ }
+ else
+ {
+ // TODO: once we have chart sheets we need a switch/case on sheet type ('SheetNNN' vs. 'ChartNNN')
+ aCodeNameInfos.push_back( SheetCodeNameInfo( aSheetProp, CREATE_OUSTRING( "Sheet" ) ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ // create new codenames if sheets do not have one
+ for( SheetCodeNameInfoList::iterator aIt = aCodeNameInfos.begin(), aEnd = aCodeNameInfos.end(); aIt != aEnd; ++aIt )
+ {
+ // search for an unused codename
+ sal_Int32 nCounter = 1;
+ OUString aCodeName;
+ do
+ {
+ aCodeName = OUStringBuffer( aIt->maPrefix ).append( nCounter++ ).makeStringAndClear();
+ }
+ while( aUsedCodeNames.count( aCodeName ) > 0 );
+ aUsedCodeNames.insert( aCodeName );
+
+ // set codename at sheet
+ aIt->maSheetProps.setProperty( PROP_CodeName, aCodeName );
+
+ // tell base class to create a dummy module
+ addDummyModule( aCodeName, ModuleType::DOCUMENT );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx
new file mode 100644
index 000000000000..683ac3582071
--- /dev/null
+++ b/oox/source/xls/externallinkbuffer.cxx
@@ -0,0 +1,1141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/externallinkbuffer.hxx"
+
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/DDELinkInfo.hpp>
+#include <com/sun/star/sheet/ExternalLinkType.hpp>
+#include <com/sun/star/sheet/ExternalReference.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/SingleReference.hpp>
+#include <com/sun/star/sheet/XDDELinks.hpp>
+#include <com/sun/star/sheet/XDDELink.hpp>
+#include <com/sun/star/sheet/XDDELinkResults.hpp>
+#include <com/sun/star/sheet/XExternalDocLink.hpp>
+#include <com/sun/star/sheet/XExternalDocLinks.hpp>
+#include <rtl/strbuf.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::Relation;
+using ::oox::core::Relations;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 BIFF12_EXTERNALBOOK_BOOK = 0;
+const sal_uInt16 BIFF12_EXTERNALBOOK_DDE = 1;
+const sal_uInt16 BIFF12_EXTERNALBOOK_OLE = 2;
+
+const sal_uInt16 BIFF12_EXTNAME_AUTOMATIC = 0x0002;
+const sal_uInt16 BIFF12_EXTNAME_PREFERPIC = 0x0004;
+const sal_uInt16 BIFF12_EXTNAME_STDDOCNAME = 0x0008;
+const sal_uInt16 BIFF12_EXTNAME_OLEOBJECT = 0x0010;
+const sal_uInt16 BIFF12_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
+
+// ============================================================================
+
+ExternalNameModel::ExternalNameModel() :
+ mbBuiltIn( false ),
+ mbNotify( false ),
+ mbPreferPic( false ),
+ mbStdDocName( false ),
+ mbOleObj( false ),
+ mbIconified( false )
+{
+}
+
+// ============================================================================
+
+ExternalName::ExternalName( const ExternalLink& rParentLink ) :
+ DefinedNameBase( rParentLink ),
+ mrParentLink( rParentLink ),
+ mnStorageId( 0 ),
+ mbDdeLinkCreated( false )
+{
+}
+
+void ExternalName::importDefinedName( const AttributeList& rAttribs )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importDefinedName - empty name" );
+ // zero-based index into sheet list of externalBook
+ maModel.mnSheet = rAttribs.getInteger( XML_sheetId, -1 );
+}
+
+void ExternalName::importDdeItem( const AttributeList& rAttribs )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importDdeItem - empty name" );
+ maExtNameModel.mbOleObj = false;
+ maExtNameModel.mbStdDocName = rAttribs.getBool( XML_ole, false );
+ maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
+ maExtNameModel.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 )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importOleItem - empty name" );
+ maExtNameModel.mbOleObj = true;
+ maExtNameModel.mbNotify = rAttribs.getBool( XML_advise, false );
+ maExtNameModel.mbPreferPic = rAttribs.getBool( XML_preferPic, false );
+ maExtNameModel.mbIconified = rAttribs.getBool( XML_icon, false );
+}
+
+void ExternalName::importExternalName( SequenceInputStream& rStrm )
+{
+ rStrm >> maModel.maName;
+ OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importExternalName - empty name" );
+}
+
+void ExternalName::importExternalNameFlags( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ sal_Int32 nSheetId;
+ rStrm >> nFlags >> nSheetId;
+ // index into sheet list of EXTSHEETNAMES (one-based in BIFF12)
+ maModel.mnSheet = nSheetId - 1;
+ // no flag for built-in names, as in OOXML...
+ maExtNameModel.mbNotify = getFlag( nFlags, BIFF12_EXTNAME_AUTOMATIC );
+ maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF12_EXTNAME_PREFERPIC );
+ maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF12_EXTNAME_STDDOCNAME );
+ maExtNameModel.mbOleObj = getFlag( nFlags, BIFF12_EXTNAME_OLEOBJECT );
+ maExtNameModel.mbIconified = getFlag( nFlags, BIFF12_EXTNAME_ICONIFIED );
+ OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_OLE) == maExtNameModel.mbOleObj,
+ "ExternalName::importExternalNameFlags - wrong OLE flag in external name" );
+}
+
+void ExternalName::importDdeItemValues( SequenceInputStream& rStrm )
+{
+ sal_Int32 nRows, nCols;
+ rStrm >> nRows >> nCols;
+ setResultSize( nCols, nRows );
+}
+
+void ExternalName::importDdeItemBool( SequenceInputStream& rStrm )
+{
+ appendResultValue< double >( (rStrm.readuInt8() == 0) ? 0.0 : 1.0 );
+}
+
+void ExternalName::importDdeItemDouble( SequenceInputStream& rStrm )
+{
+ appendResultValue( rStrm.readDouble() );
+}
+
+void ExternalName::importDdeItemError( SequenceInputStream& rStrm )
+{
+ appendResultValue( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) );
+}
+
+void ExternalName::importDdeItemString( SequenceInputStream& rStrm )
+{
+ appendResultValue( BiffHelper::readString( rStrm ) );
+}
+
+void ExternalName::importExternalName( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags = 0;
+ if( getBiff() >= BIFF3 )
+ {
+ rStrm >> nFlags;
+ maExtNameModel.mbBuiltIn = getFlag( nFlags, BIFF_EXTNAME_BUILTIN );
+ maExtNameModel.mbNotify = getFlag( nFlags, BIFF_EXTNAME_AUTOMATIC );
+ maExtNameModel.mbPreferPic = getFlag( nFlags, BIFF_EXTNAME_PREFERPIC );
+
+ // BIFF5-BIFF8: sheet index for sheet-local names, OLE settings
+ if( getBiff() >= BIFF5 )
+ {
+ maExtNameModel.mbStdDocName = getFlag( nFlags, BIFF_EXTNAME_STDDOCNAME );
+ maExtNameModel.mbOleObj = getFlag( nFlags, BIFF_EXTNAME_OLEOBJECT );
+ maExtNameModel.mbIconified = getFlag( nFlags, BIFF_EXTNAME_ICONIFIED );
+
+ if( maExtNameModel.mbOleObj )
+ {
+ rStrm >> mnStorageId;
+ }
+ else
+ {
+ /* Import the reference ID for names that are sheet-local in
+ the external document. This index will be resolved later to
+ the index of the external sheet cache which is able to
+ provide the name of the sheet related to this defined name.
+ - BIFF5: one-based index to EXTERNSHEET record containing
+ the document and sheet name
+ - BIFF8: one-based index into EXTERNALBOOK sheet name list
+ The value zero means this external name is a global name.
+ */
+ rStrm.skip( 2 );
+ maModel.mnSheet = rStrm.readuInt16();
+ }
+ }
+ }
+
+ maModel.maName = (getBiff() == BIFF8) ?
+ rStrm.readUniStringBody( rStrm.readuInt8() ) :
+ rStrm.readByteStringUC( false, getTextEncoding() );
+ OSL_ENSURE( maModel.maName.getLength() > 0, "ExternalName::importExternalName - empty name" );
+
+ // load cell references that are stored in hidden external names (seen in BIFF3-BIFF4)
+ bool bHiddenRef = (getBiff() <= BIFF4) && (maModel.maName.getLength() > 1) && (maModel.maName[ 0 ] == '\x01') && (rStrm.getRemaining() > 2);
+ switch( mrParentLink.getLinkType() )
+ {
+ case LINKTYPE_INTERNAL:
+ // cell references to other internal sheets are stored in hidden external names
+ if( bHiddenRef && (getBiff() == BIFF4) && isWorkbookFile() )
+ {
+ TokensFormulaContext aContext( true, true );
+ importBiffFormula( aContext, mrParentLink.getCalcSheetIndex(), rStrm );
+ extractReference( aContext.getTokens() );
+ }
+ break;
+
+ case LINKTYPE_EXTERNAL:
+ // cell references to other documents are stored in hidden external names
+ if( bHiddenRef )
+ {
+ TokensFormulaContext aContext( true, true );
+ importBiffFormula( aContext, 0, rStrm );
+ extractExternalReference( aContext.getTokens() );
+ }
+ break;
+
+ case LINKTYPE_DDE:
+ case LINKTYPE_OLE:
+ case LINKTYPE_MAYBE_DDE_OLE:
+ // DDE/OLE link results
+ if( rStrm.getRemaining() > 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.isEof() && (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.readByteStringUC( 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.isEof() && (maCurrIt == maResults.end()),
+ "ExternalName::importExternalName - stream error in result set" );
+ }
+ break;
+
+ default:;
+ }
+}
+
+#if 0
+sal_Int32 ExternalName::getSheetCacheIndex() const
+{
+ OSL_ENSURE( mrParentLink.getLinkType() == LINKTYPE_DDE, "ExternalName::getSheetCacheIndex - unexpected link type" );
+ sal_Int32 nCacheIdx = -1;
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ // OOXML/BIFF12: zero-based index into sheet list, -1 means global name
+ if( maModel.mnSheet >= 0 )
+ nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet );
+ break;
+ case FILTER_BIFF:
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ break;
+ case BIFF5:
+ if( maModel.mnSheet > 0 )
+ if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( maModel.mnSheet ).get() )
+ if( pExtLink->getLinkType() == LINKTYPE_EXTERNAL )
+ nCacheIdx = pExtLink->getSheetIndex();
+ break;
+ case BIFF8:
+ if( maModel.mnSheet > 0 )
+ nCacheIdx = mrParentLink.getSheetIndex( maModel.mnSheet - 1 );
+ break;
+ case BIFF_UNKNOWN:
+ break;
+ }
+ break;
+ case FILTER_UNKNOWN:
+ break;
+ }
+ return nCacheIdx;
+}
+#endif
+
+bool ExternalName::getDdeItemInfo( DDEItemInfo& orItemInfo ) const
+{
+ if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && (maModel.maName.getLength() > 0) )
+ {
+ orItemInfo.Item = maModel.maName;
+ orItemInfo.Results = ContainerHelper::matrixToSequenceSequence( maResults );
+ return true;
+ }
+ return false;
+}
+
+bool ExternalName::getDdeLinkData( OUString& orDdeServer, OUString& orDdeTopic, OUString& orDdeItem )
+{
+ if( (mrParentLink.getLinkType() == LINKTYPE_DDE) && (maModel.maName.getLength() > 0) )
+ {
+ // try to create a DDE link and to set the imported link results
+ if( !mbDdeLinkCreated ) try
+ {
+ PropertySet aDocProps( getDocument() );
+ Reference< XDDELinks > xDdeLinks( aDocProps.getAnyProperty( PROP_DDELinks ), UNO_QUERY_THROW );
+ mxDdeLink = xDdeLinks->addDDELink( mrParentLink.getClassName(), mrParentLink.getTargetUrl(), maModel.maName, ::com::sun::star::sheet::DDELinkMode_DEFAULT );
+ mbDdeLinkCreated = true; // ignore if setting results fails
+ if( !maResults.empty() )
+ {
+ Reference< XDDELinkResults > xResults( mxDdeLink, UNO_QUERY_THROW );
+ xResults->setResults( ContainerHelper::matrixToSequenceSequence( maResults ) );
+ }
+ }
+ 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;
+}
+
+// private --------------------------------------------------------------------
+
+namespace {
+
+void lclSetSheetCacheIndex( SingleReference& orApiRef, sal_Int32 nCacheIdx )
+{
+ using namespace ::com::sun::star::sheet::ReferenceFlags;
+ setFlag( orApiRef.Flags, SHEET_RELATIVE, false );
+ setFlag( orApiRef.Flags, SHEET_3D, true );
+ orApiRef.Sheet = nCacheIdx;
+}
+
+} // namespace
+
+void ExternalName::extractExternalReference( const ApiTokenSequence& rTokens )
+{
+ OSL_ENSURE( (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4), "ExternalName::setExternalReference - unexpected call" );
+ sal_Int32 nDocLinkIdx = mrParentLink.getDocumentLinkIndex();
+ sal_Int32 nCacheIdx = mrParentLink.getSheetCacheIndex();
+ if( (nDocLinkIdx >= 0) && (nCacheIdx >= 0) )
+ {
+ ExternalReference aExtApiRef;
+ aExtApiRef.Index = nDocLinkIdx;
+
+ Any aRefAny = getFormulaParser().extractReference( rTokens );
+ if( aRefAny.has< SingleReference >() )
+ {
+ SingleReference aApiRef;
+ aRefAny >>= aApiRef;
+ lclSetSheetCacheIndex( aApiRef, nCacheIdx );
+ aExtApiRef.Reference <<= aApiRef;
+ maRefAny <<= aExtApiRef;
+ }
+ else if( aRefAny.has< ComplexReference >() )
+ {
+ ComplexReference aApiRef;
+ aRefAny >>= aApiRef;
+ lclSetSheetCacheIndex( aApiRef.Reference1, nCacheIdx );
+ lclSetSheetCacheIndex( aApiRef.Reference2, nCacheIdx );
+ aExtApiRef.Reference <<= aApiRef;
+ maRefAny <<= aExtApiRef;
+ }
+ }
+}
+
+void ExternalName::setResultSize( sal_Int32 nColumns, sal_Int32 nRows )
+{
+ OSL_ENSURE( (mrParentLink.getLinkType() == LINKTYPE_DDE) || (mrParentLink.getLinkType() == LINKTYPE_OLE) ||
+ (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();
+}
+
+// ============================================================================
+
+void LinkSheetRange::setDeleted()
+{
+ meType = LINKSHEETRANGE_INTERNAL;
+ mnDocLink = mnFirst = mnLast = -1;
+}
+
+void LinkSheetRange::setSameSheet()
+{
+ meType = LINKSHEETRANGE_SAMESHEET;
+ mnDocLink = -1;
+ mnFirst = mnLast = 0;
+}
+
+void LinkSheetRange::setRange( sal_Int32 nFirst, sal_Int32 nLast )
+{
+ meType = LINKSHEETRANGE_INTERNAL;
+ mnDocLink = -1;
+ mnFirst = ::std::min( nFirst, nLast );
+ mnLast = ::std::max( nFirst, nLast );
+}
+
+void LinkSheetRange::setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast )
+{
+ if( nDocLink < 0 )
+ {
+ setDeleted();
+ }
+ else
+ {
+ meType = LINKSHEETRANGE_EXTERNAL;
+ mnDocLink = nDocLink;
+ mnFirst = ::std::min( nFirst, nLast );
+ mnLast = ::std::max( nFirst, nLast );
+ }
+}
+
+// ============================================================================
+
+ExternalLink::ExternalLink( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ meLinkType( LINKTYPE_UNKNOWN ),
+ meFuncLibType( FUNCLIB_UNKNOWN )
+{
+}
+
+void ExternalLink::importExternalReference( const AttributeList& rAttribs )
+{
+ maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
+}
+
+void ExternalLink::importExternalBook( const Relations& rRelations, const AttributeList& rAttribs )
+{
+ parseExternalReference( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
+}
+
+void ExternalLink::importSheetName( const AttributeList& rAttribs )
+{
+ insertExternalSheet( rAttribs.getXString( XML_val, OUString() ) );
+}
+
+void ExternalLink::importDefinedName( const AttributeList& rAttribs )
+{
+ createExternalName()->importDefinedName( rAttribs );
+}
+
+void ExternalLink::importDdeLink( const AttributeList& rAttribs )
+{
+ OUString aDdeService = rAttribs.getXString( XML_ddeService, OUString() );
+ OUString aDdeTopic = rAttribs.getXString( XML_ddeTopic, OUString() );
+ 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.getXString( XML_progId, OUString() );
+ OUString aTargetUrl = rRelations.getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
+}
+
+ExternalNameRef ExternalLink::importOleItem( const AttributeList& rAttribs )
+{
+ ExternalNameRef xExtName = createExternalName();
+ xExtName->importOleItem( rAttribs );
+ return xExtName;
+}
+
+void ExternalLink::importExternalRef( SequenceInputStream& rStrm )
+{
+ rStrm >> maRelId;
+}
+
+void ExternalLink::importExternalSelf( SequenceInputStream& )
+{
+ meLinkType = LINKTYPE_SELF;
+}
+
+void ExternalLink::importExternalSame( SequenceInputStream& )
+{
+ meLinkType = LINKTYPE_SAME;
+}
+
+void ExternalLink::importExternalAddin( SequenceInputStream& )
+{
+ meLinkType = LINKTYPE_UNKNOWN;
+}
+
+void ExternalLink::importExternalBook( const Relations& rRelations, SequenceInputStream& rStrm )
+{
+ switch( rStrm.readuInt16() )
+ {
+ case BIFF12_EXTERNALBOOK_BOOK:
+ parseExternalReference( rRelations, BiffHelper::readString( rStrm ) );
+ break;
+ case BIFF12_EXTERNALBOOK_DDE:
+ {
+ OUString aDdeService, aDdeTopic;
+ rStrm >> aDdeService >> aDdeTopic;
+ setDdeOleTargetUrl( aDdeService, aDdeTopic, LINKTYPE_DDE );
+ }
+ break;
+ case BIFF12_EXTERNALBOOK_OLE:
+ {
+ OUString aTargetUrl = rRelations.getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
+ OUString aProgId = BiffHelper::readString( rStrm );
+ setDdeOleTargetUrl( aProgId, aTargetUrl, LINKTYPE_OLE );
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "ExternalLink::importExternalBook - unknown link type" );
+ }
+}
+
+void ExternalLink::importExtSheetNames( SequenceInputStream& rStrm )
+{
+ // load external sheet names and create the sheet caches in the Calc document
+ OSL_ENSURE( (meLinkType == LINKTYPE_EXTERNAL) || (meLinkType == LINKTYPE_LIBRARY),
+ "ExternalLink::importExtSheetNames - invalid link type" );
+ if( meLinkType == LINKTYPE_EXTERNAL ) // ignore sheets of external libraries
+ for( sal_Int32 nSheet = 0, nCount = rStrm.readInt32(); !rStrm.isEof() && (nSheet < nCount); ++nSheet )
+ insertExternalSheet( BiffHelper::readString( rStrm ) );
+}
+
+ExternalNameRef ExternalLink::importExternalName( SequenceInputStream& rStrm )
+{
+ ExternalNameRef xExtName = createExternalName();
+ xExtName->importExternalName( rStrm );
+ return xExtName;
+}
+
+void ExternalLink::importExternSheet( BiffInputStream& rStrm )
+{
+ OStringBuffer aTargetBuffer( rStrm.readByteString( false, true ) );
+ // 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:
+ maCalcSheets.push_back( getWorksheets().getCalcSheetIndex( aSheetName ) );
+ break;
+ case LINKTYPE_EXTERNAL:
+ insertExternalSheet( (aSheetName.getLength() > 0) ? aSheetName : WorksheetBuffer::getBaseFileName( maTargetUrl ) );
+ break;
+ default:;
+ }
+}
+
+void ExternalLink::importExternalBook( BiffInputStream& rStrm )
+{
+ OUString aTarget;
+ sal_uInt16 nSheetCount;
+ rStrm >> nSheetCount;
+ if( rStrm.getRemaining() == 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.getRemaining() >= 3 )
+ {
+ // NUL characters may occur
+ aTarget = rStrm.readUniString( true );
+ }
+
+ // 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 sheet caches in the Calc document
+ if( meLinkType == LINKTYPE_EXTERNAL )
+ for( sal_uInt16 nSheet = 0; !rStrm.isEof() && (nSheet < nSheetCount); ++nSheet )
+ insertExternalSheet( rStrm.readUniString() );
+}
+
+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" );
+ }
+}
+
+ExternalLinkInfo ExternalLink::getLinkInfo() const
+{
+ ExternalLinkInfo aLinkInfo;
+ switch( meLinkType )
+ {
+ case LINKTYPE_EXTERNAL:
+ aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DOCUMENT;
+ aLinkInfo.Data <<= maTargetUrl;
+ break;
+ case LINKTYPE_DDE:
+ {
+ aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::DDE;
+ DDELinkInfo aDdeLinkInfo;
+ aDdeLinkInfo.Service = maClassName;
+ aDdeLinkInfo.Topic = maTargetUrl;
+ ::std::vector< DDEItemInfo > aItemInfos;
+ DDEItemInfo aItemInfo;
+ for( ExternalNameVector::const_iterator aIt = maExtNames.begin(), aEnd = maExtNames.end(); aIt != aEnd; ++aIt )
+ if( (*aIt)->getDdeItemInfo( aItemInfo ) )
+ aItemInfos.push_back( aItemInfo );
+ aDdeLinkInfo.Items = ContainerHelper::vectorToSequence( aItemInfos );
+ aLinkInfo.Data <<= aDdeLinkInfo;
+ }
+ break;
+ default:
+ aLinkInfo.Type = ::com::sun::star::sheet::ExternalLinkType::UNKNOWN;
+ }
+ return aLinkInfo;
+}
+
+FunctionLibraryType ExternalLink::getFuncLibraryType() const
+{
+ return (meLinkType == LINKTYPE_LIBRARY) ? meFuncLibType : FUNCLIB_UNKNOWN;
+}
+
+sal_Int16 ExternalLink::getCalcSheetIndex( sal_Int32 nTabId ) const
+{
+ OSL_ENSURE( meLinkType == LINKTYPE_INTERNAL, "ExternalLink::getCalcSheetIndex - invalid link type" );
+ OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOXML) || (getBiff() == BIFF8),
+ "ExternalLink::getCalcSheetIndex - invalid sheet index" );
+ return ContainerHelper::getVectorElement( maCalcSheets, nTabId, -1 );
+}
+
+sal_Int32 ExternalLink::getDocumentLinkIndex() const
+{
+ OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getDocumentLinkIndex - invalid link type" );
+ return mxDocLink.is() ? mxDocLink->getTokenIndex() : -1;
+}
+
+sal_Int32 ExternalLink::getSheetCacheIndex( sal_Int32 nTabId ) const
+{
+ OSL_ENSURE( meLinkType == LINKTYPE_EXTERNAL, "ExternalLink::getSheetCacheIndex - invalid link type" );
+ OSL_ENSURE( (nTabId == 0) || (getFilterType() == FILTER_OOXML) || (getBiff() == BIFF8),
+ "ExternalLink::getSheetCacheIndex - invalid sheet index" );
+ return ContainerHelper::getVectorElement( maSheetCaches, nTabId, -1 );
+}
+
+Reference< XExternalSheetCache > ExternalLink::getSheetCache( sal_Int32 nTabId ) const
+{
+ sal_Int32 nCacheIdx = getSheetCacheIndex( nTabId );
+ if( mxDocLink.is() && (nCacheIdx >= 0) ) try
+ {
+ // existing mxDocLink implies that this is an external link
+ Reference< XExternalSheetCache > xSheetCache( mxDocLink->getByIndex( nCacheIdx ), UNO_QUERY_THROW );
+ return xSheetCache;
+ }
+ catch( Exception& )
+ {
+ }
+ return 0;
+}
+
+void ExternalLink::getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const
+{
+ switch( meLinkType )
+ {
+ case LINKTYPE_SAME:
+ orSheetRange.setSameSheet();
+ break;
+
+ case LINKTYPE_SELF:
+ case LINKTYPE_INTERNAL:
+ orSheetRange.setRange( nTabId1, nTabId2 );
+ break;
+
+ case LINKTYPE_EXTERNAL:
+ {
+ sal_Int32 nDocLinkIdx = getDocumentLinkIndex();
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ // BIFF12: passed indexes point into sheet list of EXTSHEETLIST
+ orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
+ break;
+ case FILTER_BIFF:
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
+ break;
+ case BIFF5:
+ // BIFF5: first sheet from this external link, last sheet is passed in nTabId2
+ if( const ExternalLink* pExtLink2 = getExternalLinks().getExternalLink( nTabId2 ).get() )
+ if( (pExtLink2->getLinkType() == LINKTYPE_EXTERNAL) && (maTargetUrl == pExtLink2->getTargetUrl()) )
+ orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex(), pExtLink2->getSheetCacheIndex() );
+ break;
+ case BIFF8:
+ // BIFF8: passed indexes point into sheet list of EXTERNALBOOK
+ orSheetRange.setExternalRange( nDocLinkIdx, getSheetCacheIndex( nTabId1 ), getSheetCacheIndex( nTabId2 ) );
+ break;
+ case BIFF_UNKNOWN: break;
+ }
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+ }
+ break;
+
+ default:
+ // unsupported/unexpected link type: #REF! error
+ orSheetRange.setDeleted();
+ }
+}
+
+ExternalNameRef ExternalLink::getNameByIndex( sal_Int32 nIndex ) const
+{
+ return maExtNames.get( nIndex );
+}
+
+// private --------------------------------------------------------------------
+
+#define OOX_TARGETTYPE_EXTLINK CREATE_OFFICEDOC_RELATION_TYPE( "externalLinkPath" )
+#define OOX_TARGETTYPE_LIBRARY CREATE_MSOFFICE_RELATION_TYPE( "xlExternalLinkPath/xlLibrary" )
+
+void ExternalLink::setExternalTargetUrl( const OUString& rTargetUrl, const OUString& rTargetType )
+{
+ meLinkType = LINKTYPE_UNKNOWN;
+ if( rTargetType == OOX_TARGETTYPE_EXTLINK )
+ {
+ maTargetUrl = getBaseFilter().getAbsoluteUrl( rTargetUrl );
+ if( maTargetUrl.getLength() > 0 )
+ meLinkType = LINKTYPE_EXTERNAL;
+ }
+ else if( rTargetType == OOX_TARGETTYPE_LIBRARY )
+ {
+ meLinkType = LINKTYPE_LIBRARY;
+ meFuncLibType = getFormulaParser().getFuncLibTypeFromLibraryName( rTargetUrl );
+ }
+ OSL_ENSURE( meLinkType != LINKTYPE_UNKNOWN, "ExternalLink::setExternalTargetUrl - empty target URL or unknown target type" );
+
+ // create the external document link API object that will contain the sheet caches
+ if( meLinkType == LINKTYPE_EXTERNAL ) try
+ {
+ PropertySet aDocProps( getDocument() );
+ Reference< XExternalDocLinks > xDocLinks( aDocProps.getAnyProperty( PROP_ExternalDocLinks ), UNO_QUERY_THROW );
+ mxDocLink = xDocLinks->addDocLink( maTargetUrl );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+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" );
+}
+
+void ExternalLink::parseExternalReference( const Relations& rRelations, const OUString& rRelId )
+{
+ if( const Relation* pRelation = rRelations.getRelationFromRelId( rRelId ) )
+ setExternalTargetUrl( pRelation->maTarget, pRelation->maType );
+}
+
+OUString ExternalLink::parseBiffTargetUrl( const OUString& rBiffTargetUrl )
+{
+ meLinkType = LINKTYPE_UNKNOWN;
+
+ OUString aClassName, aTargetUrl, aSheetName;
+ switch( getAddressConverter().parseBiffTargetUrl( aClassName, aTargetUrl, aSheetName, rBiffTargetUrl ) )
+ {
+ case BIFF_TARGETTYPE_URL:
+ if( aTargetUrl.getLength() == 0 )
+ {
+ meLinkType = (aSheetName.getLength() > 0) ? LINKTYPE_INTERNAL : LINKTYPE_SELF;
+ }
+ else if( (aTargetUrl.getLength() == 1) && (aTargetUrl[ 0 ] == ':') )
+ {
+ if( getBiff() >= BIFF4 )
+ meLinkType = LINKTYPE_ANALYSIS;
+ }
+ else if( (aTargetUrl.getLength() > 1) || (aTargetUrl[ 0 ] != ' ') )
+ {
+ setExternalTargetUrl( aTargetUrl, OOX_TARGETTYPE_EXTLINK );
+ }
+ break;
+
+ case BIFF_TARGETTYPE_SAMESHEET:
+ OSL_ENSURE( (aTargetUrl.getLength() == 0) && (aSheetName.getLength() == 0), "ExternalLink::parseBiffTargetUrl - unexpected target or sheet name" );
+ meLinkType = LINKTYPE_SAME;
+ break;
+
+ case BIFF_TARGETTYPE_LIBRARY:
+ OSL_ENSURE( aSheetName.getLength() == 0, "ExternalLink::parseBiffTargetUrl - unexpected sheet name" );
+ setExternalTargetUrl( aTargetUrl, OOX_TARGETTYPE_LIBRARY );
+ break;
+
+ case BIFF_TARGETTYPE_DDE_OLE:
+ setDdeOleTargetUrl( aClassName, aTargetUrl, LINKTYPE_MAYBE_DDE_OLE );
+ break;
+
+ case BIFF_TARGETTYPE_UNKNOWN:
+ break;
+ }
+ return aSheetName;
+}
+
+void ExternalLink::insertExternalSheet( const OUString& rSheetName )
+{
+ OSL_ENSURE( rSheetName.getLength() > 0, "ExternalLink::insertExternalSheet - empty sheet name" );
+ if( mxDocLink.is() )
+ {
+ Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
+ sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
+ maSheetCaches.push_back( nCacheIdx );
+ }
+}
+
+ExternalNameRef ExternalLink::createExternalName()
+{
+ ExternalNameRef xExtName( new ExternalName( *this ) );
+ maExtNames.push_back( xExtName );
+ return xExtName;
+}
+
+// ============================================================================
+
+RefSheetsModel::RefSheetsModel() :
+ mnExtRefId( -1 ),
+ mnTabId1( -1 ),
+ mnTabId2( -1 )
+{
+}
+
+void RefSheetsModel::readBiff12Data( SequenceInputStream& rStrm )
+{
+ rStrm >> mnExtRefId >> mnTabId1 >> mnTabId2;
+}
+
+void RefSheetsModel::readBiff8Data( BiffInputStream& rStrm )
+{
+ mnExtRefId = rStrm.readuInt16();
+ mnTabId1 = rStrm.readInt16();
+ mnTabId2 = rStrm.readInt16();
+}
+
+// ----------------------------------------------------------------------------
+
+ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mxSelfRef( new ExternalLink( rHelper ) ),
+ mbUseRefSheets( false )
+{
+ mxSelfRef->setSelfLinkType();
+}
+
+ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs )
+{
+ ExternalLinkRef xExtLink = createExternalLink();
+ xExtLink->importExternalReference( rAttribs );
+ maExtLinks.push_back( xExtLink );
+ return xExtLink;
+}
+
+ExternalLinkRef ExternalLinkBuffer::importExternalRef( SequenceInputStream& rStrm )
+{
+ mbUseRefSheets = true;
+ ExternalLinkRef xExtLink = createExternalLink();
+ xExtLink->importExternalRef( rStrm );
+ maExtLinks.push_back( xExtLink );
+ return xExtLink;
+}
+
+void ExternalLinkBuffer::importExternalSelf( SequenceInputStream& rStrm )
+{
+ mbUseRefSheets = true;
+ createExternalLink()->importExternalSelf( rStrm );
+}
+
+void ExternalLinkBuffer::importExternalSame( SequenceInputStream& rStrm )
+{
+ mbUseRefSheets = true;
+ createExternalLink()->importExternalSame( rStrm );
+}
+
+void ExternalLinkBuffer::importExternalAddin( SequenceInputStream& rStrm )
+{
+ mbUseRefSheets = true;
+ createExternalLink()->importExternalAddin( rStrm );
+}
+
+void ExternalLinkBuffer::importExternalSheets( SequenceInputStream& 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_Int64 >( nRefCount, 0, rStrm.getRemaining() / 12 );
+ maRefSheets.reserve( nMaxCount );
+ for( size_t nRefId = 0; !rStrm.isEof() && (nRefId < nMaxCount); ++nRefId )
+ {
+ RefSheetsModel aRefSheets;
+ aRefSheets.readBiff12Data( 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( !maLinks.empty() )
+ maLinks.back()->importExternalName( rStrm );
+}
+
+void ExternalLinkBuffer::importExternSheet8( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( getBiff() == BIFF8, "ExternalLinkBuffer::importExternSheet8 - wrong BIFF version" );
+
+ sal_uInt16 nRefCount;
+ rStrm >> nRefCount;
+ OSL_ENSURE( static_cast< sal_Int64 >( nRefCount * 6 ) == rStrm.getRemaining(), "ExternalLinkBuffer::importExternSheet8 - invalid count" );
+ nRefCount = static_cast< sal_uInt16 >( ::std::min< sal_Int64 >( nRefCount, rStrm.getRemaining() / 6 ) );
+
+ /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET
+ records instead of only one as expected. Surprisingly, Excel seems to
+ insert the entries of the second record before the entries of the first
+ record. */
+ maRefSheets.insert( maRefSheets.begin(), nRefCount, RefSheetsModel() );
+ for( RefSheetsModelVec::iterator aIt = maRefSheets.begin(), aEnd = aIt + nRefCount; !rStrm.isEof() && (aIt != aEnd); ++aIt )
+ aIt->readBiff8Data( rStrm );
+}
+
+Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const
+{
+ ::std::vector< ExternalLinkInfo > aLinkInfos;
+ // should not be used for BIFF12 documents
+ OSL_ENSURE( (getFilterType() == FILTER_OOXML) && !mbUseRefSheets, "ExternalLinkBuffer::getLinkInfos - unexpected file format" );
+ // add entry for implicit index 0 (self reference to this document)
+ aLinkInfos.push_back( mxSelfRef->getLinkInfo() );
+ for( ExternalLinkVec::const_iterator aIt = maExtLinks.begin(), aEnd = maExtLinks.end(); aIt != aEnd; ++aIt )
+ aLinkInfos.push_back( (*aIt)->getLinkInfo() );
+ return ContainerHelper::vectorToSequence( aLinkInfos );
+}
+
+ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const
+{
+ ExternalLinkRef xExtLink;
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ // OOXML: 0 = this document, otherwise one-based index into link list
+ if( !bUseRefSheets || !mbUseRefSheets )
+ xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 );
+ // BIFF12: zero-based index into ref-sheets list
+ else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
+ xExtLink = maLinks.get( pRefSheets->mnExtRefId );
+ break;
+ case FILTER_BIFF:
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ // one-based index to EXTERNSHEET records
+ xExtLink = maLinks.get( nRefId - 1 );
+ break;
+ case BIFF5:
+ if( nRefId < 0 )
+ {
+ // internal links in formula tokens have negative index
+ xExtLink = maLinks.get( -nRefId - 1 );
+ if( xExtLink.get() && !xExtLink->isInternalLink() )
+ xExtLink.reset();
+ }
+ else
+ {
+ // one-based index to EXTERNSHEET records
+ xExtLink = maLinks.get( nRefId - 1 );
+ }
+ break;
+ case BIFF8:
+ // zero-based index into REF list in EXTERNSHEET record
+ if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
+ xExtLink = maLinks.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_OOXML) && mbUseRefSheets) || (getBiff() == BIFF8), "ExternalLinkBuffer::getSheetRange - wrong BIFF version" );
+ LinkSheetRange aSheetRange;
+ if( const ExternalLink* pExtLink = getExternalLink( nRefId ).get() )
+ if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) )
+ pExtLink->getSheetRange( aSheetRange, pRefSheets->mnTabId1, pRefSheets->mnTabId2 );
+ return aSheetRange;
+}
+
+// private --------------------------------------------------------------------
+
+ExternalLinkRef ExternalLinkBuffer::createExternalLink()
+{
+ ExternalLinkRef xExtLink( new ExternalLink( *this ) );
+ maLinks.push_back( xExtLink );
+ return xExtLink;
+}
+
+const RefSheetsModel* 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..094b192b817c
--- /dev/null
+++ b/oox/source/xls/externallinkfragment.cxx
@@ -0,0 +1,548 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/externallinkfragment.hxx"
+
+#include <com/sun/star/sheet/XExternalSheetCache.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/sheetdatacontext.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+// ============================================================================
+
+ExternalSheetDataContext::ExternalSheetDataContext(
+ WorkbookFragmentBase& rFragment, const Reference< XExternalSheetCache >& rxSheetCache ) :
+ WorkbookContextBase( rFragment ),
+ mxSheetCache( rxSheetCache )
+{
+ OSL_ENSURE( mxSheetCache.is(), "ExternalSheetDataContext::ExternalSheetDataContext - missing sheet cache" );
+}
+
+ContextHandlerRef ExternalSheetDataContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( sheetData ):
+ if( nElement == XLS_TOKEN( row ) ) return this;
+ break;
+ case XLS_TOKEN( row ):
+ if( nElement == XLS_TOKEN( cell ) ) { importCell( rAttribs ); return this; }
+ break;
+ case XLS_TOKEN( cell ):
+ if( nElement == XLS_TOKEN( v ) ) return this; // collect characters in onCharacters()
+ break;
+ }
+ return 0;
+}
+
+void ExternalSheetDataContext::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( XLS_TOKEN( v ) ) )
+ {
+ switch( mnCurrType )
+ {
+ case XML_b:
+ case XML_n:
+ setCellValue( Any( rChars.toDouble() ) );
+ break;
+ case XML_e:
+ setCellValue( Any( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( rChars ) ) ) );
+ break;
+ case XML_str:
+ setCellValue( Any( rChars ) );
+ break;
+ }
+ mnCurrType = XML_TOKEN_INVALID;
+ }
+}
+
+ContextHandlerRef ExternalSheetDataContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_EXTSHEETDATA:
+ if( nRecId == BIFF12_ID_EXTROW ) { maCurrPos.Row = rStrm.readInt32(); return this; }
+ break;
+ case BIFF12_ID_EXTROW:
+ switch( nRecId )
+ {
+ case BIFF12_ID_EXTCELL_BLANK: importExtCellBlank( rStrm ); break;
+ case BIFF12_ID_EXTCELL_BOOL: importExtCellBool( rStrm ); break;
+ case BIFF12_ID_EXTCELL_DOUBLE: importExtCellDouble( rStrm ); break;
+ case BIFF12_ID_EXTCELL_ERROR: importExtCellError( rStrm ); break;
+ case BIFF12_ID_EXTCELL_STRING: importExtCellString( rStrm ); break;
+ }
+ break;
+ }
+ return 0;
+}
+
+// private --------------------------------------------------------------------
+
+void ExternalSheetDataContext::importCell( const AttributeList& rAttribs )
+{
+ if( getAddressConverter().convertToCellAddress( maCurrPos, rAttribs.getString( XML_r, OUString() ), 0, false ) )
+ mnCurrType = rAttribs.getToken( XML_t, XML_n );
+ else
+ mnCurrType = XML_TOKEN_INVALID;
+}
+
+void ExternalSheetDataContext::importExtCellBlank( SequenceInputStream& rStrm )
+{
+ maCurrPos.Column = rStrm.readInt32();
+ setCellValue( Any( OUString() ) );
+}
+
+void ExternalSheetDataContext::importExtCellBool( SequenceInputStream& rStrm )
+{
+ maCurrPos.Column = rStrm.readInt32();
+ double fValue = (rStrm.readuInt8() == 0) ? 0.0 : 1.0;
+ setCellValue( Any( fValue ) );
+}
+
+void ExternalSheetDataContext::importExtCellDouble( SequenceInputStream& rStrm )
+{
+ maCurrPos.Column = rStrm.readInt32();
+ setCellValue( Any( rStrm.readDouble() ) );
+}
+
+void ExternalSheetDataContext::importExtCellError( SequenceInputStream& rStrm )
+{
+ maCurrPos.Column = rStrm.readInt32();
+ setCellValue( Any( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) ) );
+}
+
+void ExternalSheetDataContext::importExtCellString( SequenceInputStream& rStrm )
+{
+ maCurrPos.Column = rStrm.readInt32();
+ setCellValue( Any( BiffHelper::readString( rStrm ) ) );
+}
+
+void ExternalSheetDataContext::setCellValue( const Any& rValue )
+{
+ if( mxSheetCache.is() && getAddressConverter().checkCellAddress( maCurrPos, false ) ) try
+ {
+ mxSheetCache->setCellValue( maCurrPos.Column, maCurrPos.Row, rValue );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+ExternalLinkFragment::ExternalLinkFragment( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath, ExternalLink& rExtLink ) :
+ WorkbookFragmentBase( rHelper, rFragmentPath ),
+ mrExtLink( rExtLink ),
+ mnResultType( XML_TOKEN_INVALID )
+{
+}
+
+ContextHandlerRef ExternalLinkFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( externalLink ) ) return this;
+ break;
+
+ case XLS_TOKEN( externalLink ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( externalBook ): mrExtLink.importExternalBook( getRelations(), rAttribs ); return this;
+ case XLS_TOKEN( ddeLink ): mrExtLink.importDdeLink( rAttribs ); return this;
+ case XLS_TOKEN( oleLink ): mrExtLink.importOleLink( getRelations(), rAttribs ); return this;
+ }
+ break;
+
+ case XLS_TOKEN( externalBook ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheetNames ):
+ case XLS_TOKEN( definedNames ):
+ case XLS_TOKEN( sheetDataSet ): return this;
+ }
+ break;
+
+ case XLS_TOKEN( sheetNames ):
+ if( nElement == XLS_TOKEN( sheetName ) ) mrExtLink.importSheetName( rAttribs );
+ break;
+ case XLS_TOKEN( definedNames ):
+ if( nElement == XLS_TOKEN( definedName ) ) mrExtLink.importDefinedName( rAttribs );
+ break;
+ case XLS_TOKEN( sheetDataSet ):
+ if( (nElement == XLS_TOKEN( sheetData )) && (mrExtLink.getLinkType() == LINKTYPE_EXTERNAL) )
+ return createSheetDataContext( rAttribs.getInteger( XML_sheetId, -1 ) );
+ break;
+
+ case XLS_TOKEN( ddeLink ):
+ if( nElement == XLS_TOKEN( ddeItems ) ) return this;
+ break;
+ case XLS_TOKEN( ddeItems ):
+ if( nElement == XLS_TOKEN( ddeItem ) )
+ {
+ mxExtName = mrExtLink.importDdeItem( rAttribs );
+ return this;
+ }
+ break;
+ case XLS_TOKEN( ddeItem ):
+ if( nElement == XLS_TOKEN( values ) )
+ {
+ if( mxExtName.get() ) mxExtName->importValues( rAttribs );
+ return this;
+ }
+ break;
+ case XLS_TOKEN( values ):
+ if( nElement == XLS_TOKEN( value ) )
+ {
+ mnResultType = rAttribs.getToken( XML_t, XML_n );
+ return this;
+ }
+ break;
+ case XLS_TOKEN( value ):
+ if( nElement == XLS_TOKEN( val ) ) return this; // collect value in onCharacters()
+ break;
+
+ case XLS_TOKEN( oleLink ):
+ if( nElement == XLS_TOKEN( oleItems ) ) return this;
+ break;
+ case XLS_TOKEN( oleItems ):
+ if( nElement == XLS_TOKEN( oleItem ) ) mxExtName = mrExtLink.importOleItem( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+void ExternalLinkFragment::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( XLS_TOKEN( val ) ) )
+ maResultValue = rChars;
+}
+
+void ExternalLinkFragment::onEndElement()
+{
+ if( isCurrentElement( XLS_TOKEN( value ) ) && 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 ) );
+ }
+}
+
+ContextHandlerRef ExternalLinkFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_EXTERNALBOOK )
+ {
+ mrExtLink.importExternalBook( getRelations(), rStrm );
+ return this;
+ }
+ break;
+
+ case BIFF12_ID_EXTERNALBOOK:
+ switch( nRecId )
+ {
+ case BIFF12_ID_EXTSHEETDATA:
+ if( mrExtLink.getLinkType() == LINKTYPE_EXTERNAL )
+ return createSheetDataContext( rStrm.readInt32() );
+ break;
+
+ case BIFF12_ID_EXTSHEETNAMES: mrExtLink.importExtSheetNames( rStrm ); break;
+ case BIFF12_ID_EXTERNALNAME: mxExtName = mrExtLink.importExternalName( rStrm ); return this;
+ }
+ break;
+
+ case BIFF12_ID_EXTERNALNAME:
+ switch( nRecId )
+ {
+ case BIFF12_ID_EXTERNALNAMEFLAGS: if( mxExtName.get() ) mxExtName->importExternalNameFlags( rStrm ); break;
+ case BIFF12_ID_DDEITEMVALUES: if( mxExtName.get() ) mxExtName->importDdeItemValues( rStrm ); return this;
+ }
+ break;
+
+ case BIFF12_ID_DDEITEMVALUES:
+ switch( nRecId )
+ {
+ case BIFF12_ID_DDEITEM_BOOL: if( mxExtName.get() ) mxExtName->importDdeItemBool( rStrm ); break;
+ case BIFF12_ID_DDEITEM_DOUBLE: if( mxExtName.get() ) mxExtName->importDdeItemDouble( rStrm ); break;
+ case BIFF12_ID_DDEITEM_ERROR: if( mxExtName.get() ) mxExtName->importDdeItemError( rStrm ); break;
+ case BIFF12_ID_DDEITEM_STRING: if( mxExtName.get() ) mxExtName->importDdeItemString( rStrm ); break;
+ }
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef ExternalLinkFragment::createSheetDataContext( sal_Int32 nSheetId )
+{
+ return new ExternalSheetDataContext( *this, mrExtLink.getSheetCache( nSheetId ) );
+}
+
+const RecordInfo* ExternalLinkFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_DDEITEMVALUES, BIFF12_ID_DDEITEMVALUES + 1 },
+ { BIFF12_ID_EXTERNALBOOK, BIFF12_ID_EXTERNALBOOK + 228 },
+ { BIFF12_ID_EXTERNALNAME, BIFF12_ID_EXTERNALNAME + 10 },
+ { BIFF12_ID_EXTROW, -1 },
+ { BIFF12_ID_EXTSHEETDATA, BIFF12_ID_EXTSHEETDATA + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+// ============================================================================
+// ============================================================================
+
+BiffExternalSheetDataContext::BiffExternalSheetDataContext( const WorkbookHelper& rHelper, bool bImportDefNames ) :
+ BiffWorkbookContextBase( rHelper ),
+ mbImportDefNames( bImportDefNames )
+{
+}
+
+BiffExternalSheetDataContext::~BiffExternalSheetDataContext()
+{
+}
+
+void BiffExternalSheetDataContext::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;
+ }
+}
+
+// private --------------------------------------------------------------------
+
+void BiffExternalSheetDataContext::importExternSheet( BiffInputStream& rStrm )
+{
+ mxSheetCache.clear();
+ if( getBiff() == BIFF8 )
+ getExternalLinks().importExternSheet8( rStrm );
+ else
+ mxExtLink = getExternalLinks().importExternSheet( rStrm );
+}
+
+void BiffExternalSheetDataContext::importExternalBook( BiffInputStream& rStrm )
+{
+ mxSheetCache.clear();
+ mxExtLink = getExternalLinks().importExternalBook( rStrm );
+}
+
+void BiffExternalSheetDataContext::importExternalName( BiffInputStream& rStrm )
+{
+ if( mxExtLink.get() )
+ mxExtLink->importExternalName( rStrm );
+}
+
+void BiffExternalSheetDataContext::importXct( BiffInputStream& rStrm )
+{
+ mxSheetCache.clear();
+ if( mxExtLink.get() && (mxExtLink->getLinkType() == LINKTYPE_EXTERNAL) )
+ {
+ switch( getBiff() )
+ {
+ case BIFF2:
+ break;
+ case BIFF3:
+ case BIFF4:
+ case BIFF5:
+ mxSheetCache = mxExtLink->getSheetCache( 0 );
+ break;
+ case BIFF8:
+ rStrm.skip( 2 );
+ mxSheetCache = mxExtLink->getSheetCache( rStrm.readInt16() );
+ break;
+ case BIFF_UNKNOWN:
+ break;
+ }
+ }
+}
+
+void BiffExternalSheetDataContext::importCrn( BiffInputStream& rStrm )
+{
+ if( !mxSheetCache.is() ) return;
+
+ sal_uInt8 nCol2, nCol1;
+ sal_uInt16 nRow;
+ rStrm >> nCol2 >> nCol1 >> nRow;
+ bool bLoop = true;
+ for( BinAddress aBinAddr( nCol1, nRow ); bLoop && !rStrm.isEof() && (aBinAddr.mnCol <= nCol2); ++aBinAddr.mnCol )
+ {
+ switch( rStrm.readuInt8() )
+ {
+ case BIFF_DATATYPE_EMPTY:
+ rStrm.skip( 8 );
+ setCellValue( aBinAddr, Any( OUString() ) );
+ break;
+ case BIFF_DATATYPE_DOUBLE:
+ setCellValue( aBinAddr, Any( rStrm.readDouble() ) );
+ break;
+ case BIFF_DATATYPE_STRING:
+ {
+ OUString aText = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
+ setCellValue( aBinAddr, Any( aText ) );
+ }
+ break;
+ case BIFF_DATATYPE_BOOL:
+ {
+ double fValue = (rStrm.readuInt8() == 0) ? 0.0 : 1.0;
+ setCellValue( aBinAddr, Any( fValue ) );
+ rStrm.skip( 7 );
+ }
+ break;
+ case BIFF_DATATYPE_ERROR:
+ setCellValue( aBinAddr, Any( BiffHelper::calcDoubleFromError( rStrm.readuInt8() ) ) );
+ rStrm.skip( 7 );
+ break;
+ default:
+ OSL_ENSURE( false, "BiffExternalSheetDataContext::importCrn - unknown data type" );
+ bLoop = false;
+ }
+ }
+}
+
+void BiffExternalSheetDataContext::importDefinedName( BiffInputStream& rStrm )
+{
+ if( mbImportDefNames )
+ getDefinedNames().importDefinedName( rStrm );
+}
+
+void BiffExternalSheetDataContext::setCellValue( const BinAddress& rBinAddr, const Any& rValue )
+{
+ CellAddress aCellPos;
+ if( mxSheetCache.is() && getAddressConverter().convertToCellAddress( aCellPos, rBinAddr, 0, false ) ) try
+ {
+ mxSheetCache->setCellValue( aCellPos.Column, aCellPos.Row, rValue );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+BiffExternalLinkFragment::BiffExternalLinkFragment( const BiffWorkbookFragmentBase& rParent ) :
+ BiffWorkbookFragmentBase( rParent )
+{
+}
+
+bool BiffExternalLinkFragment::importFragment()
+{
+ // process all record in this sheet fragment
+ BiffExternalSheetDataContext aSheetContext( *this, false );
+ BiffInputStream& rStrm = getInputStream();
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ {
+ if( BiffHelper::isBofRecord( rStrm ) )
+ skipFragment(); // skip unknown embedded fragments
+ else
+ aSheetContext.importRecord( rStrm );
+ }
+ return !rStrm.isEof() && (rStrm.getRecId() == BIFF_ID_EOF);
+}
+
+// ============================================================================
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx
new file mode 100755
index 000000000000..ba8485d1f42b
--- /dev/null
+++ b/oox/source/xls/formulabase.cxx
@@ -0,0 +1,1739 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/formulabase.hxx"
+
+#include <map>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/AddressConvention.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/XFormulaParser.hpp>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OUStringToOString;
+
+// reference helpers ==========================================================
+
+BinSingleRef2d::BinSingleRef2d() :
+ mnCol( 0 ),
+ mnRow( 0 ),
+ mbColRel( false ),
+ mbRowRel( false )
+{
+}
+
+void BinSingleRef2d::setBiff12Data( sal_uInt16 nCol, sal_Int32 nRow, bool bRelativeAsOffset )
+{
+ mnCol = nCol & BIFF12_TOK_REF_COLMASK;
+ mnRow = nRow & BIFF12_TOK_REF_ROWMASK;
+ mbColRel = getFlag( nCol, BIFF12_TOK_REF_COLREL );
+ mbRowRel = getFlag( nCol, BIFF12_TOK_REF_ROWREL );
+ if( bRelativeAsOffset && mbColRel && (mnCol > (BIFF12_TOK_REF_COLMASK >> 1)) )
+ mnCol -= (BIFF12_TOK_REF_COLMASK + 1);
+ if( bRelativeAsOffset && mbRowRel && (mnRow > (BIFF12_TOK_REF_ROWMASK >> 1)) )
+ mnRow -= (BIFF12_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::readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_Int32 nRow;
+ sal_uInt16 nCol;
+ rStrm >> nRow >> nCol;
+ setBiff12Data( 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::readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset )
+{
+ sal_Int32 nRow1, nRow2;
+ sal_uInt16 nCol1, nCol2;
+ rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+ maRef1.setBiff12Data( nCol1, nRow1, bRelativeAsOffset );
+ maRef2.setBiff12Data( 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 );
+}
+
+// token vector, sequence =====================================================
+
+ApiTokenVector::ApiTokenVector()
+{
+}
+
+Any& ApiTokenVector::append( sal_Int32 nOpCode )
+{
+ resize( size() + 1 );
+ back().OpCode = nOpCode;
+ return back().Data;
+}
+
+// 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;
+}
+
+// function data ==============================================================
+
+namespace {
+
+const size_t FUNCINFO_PARAMINFOCOUNT = 5; /// Number of parameter type entries.
+
+const sal_uInt16 FUNCFLAG_VOLATILE = 0x0001; /// Result is volatile (e.g. NOW() function).
+const sal_uInt16 FUNCFLAG_IMPORTONLY = 0x0002; /// Only used in import filter.
+const sal_uInt16 FUNCFLAG_EXPORTONLY = 0x0004; /// Only used in export filter.
+const sal_uInt16 FUNCFLAG_MACROCALL = 0x0008; /// Function is stored as macro call in Excel (_xlfn. prefix). OOXML name MUST exist.
+const sal_uInt16 FUNCFLAG_MACROCALLODF = 0x0010; /// ODF-only function stored as macro call in Excel (_xlfnodf. prefix). ODF name MUST exist.
+const sal_uInt16 FUNCFLAG_EXTERNAL = 0x0020; /// Function is external in Calc.
+const sal_uInt16 FUNCFLAG_MACROFUNC = 0x0040; /// Function is a macro-sheet function.
+const sal_uInt16 FUNCFLAG_MACROCMD = 0x0080; /// Function is a macro-sheet command.
+const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0100; /// Function is always represented by a tFuncVar token.
+const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0200; /// Optional parameters are expected to appear in pairs.
+
+const sal_uInt16 FUNCFLAG_FUNCLIBMASK = 0xF000; /// Mask for function library bits.
+const sal_uInt16 FUNCFLAG_EUROTOOL = 0x1000; /// Function is part of the EuroTool add-in.
+
+typedef ::boost::shared_ptr< FunctionInfo > FunctionInfoRef;
+
+struct FunctionData
+{
+ const sal_Char* mpcOdfFuncName; /// ODF function name.
+ const sal_Char* mpcOoxFuncName; /// OOXML function name.
+ sal_uInt16 mnBiff12FuncId; /// BIFF12 function identifier.
+ sal_uInt16 mnBiffFuncId; /// BIFF2-BIFF8 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.
+ FunctionParamInfo mpParamInfos[ FUNCINFO_PARAMINFOCOUNT ]; /// Information about all parameters.
+ sal_uInt16 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_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF function identifier available.
+const sal_uInt8 MX = SAL_MAX_UINT8; /// Maximum parameter count.
+
+// abbreviations for function return token class
+const sal_uInt8 R = BIFF_TOKCLASS_REF;
+const sal_uInt8 V = BIFF_TOKCLASS_VAL;
+const sal_uInt8 A = BIFF_TOKCLASS_ARR;
+
+// abbreviations for parameter infos
+#define RO { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ORG, false }
+#define RV { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_VAL, false }
+#define RA { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ARR, false }
+#define RR { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPT, false }
+#define RX { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPX, false }
+#define VO { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ORG, true }
+#define VV { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_VAL, true }
+#define VA { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ARR, true }
+#define VR { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPT, true }
+#define VX { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPX, true }
+#define RO_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_ORG, false }
+#define VR_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_RPT, true }
+#define C { FUNC_PARAM_CALCONLY, FUNC_PARAMCONV_ORG, false }
+
+// Note: parameter types of all macro sheet functions (FUNCFLAG_MACROFUNC/FUNCFLAG_MACROCMD) untested!
+
+/** Functions new in BIFF2. */
+static const FunctionData saFuncTableBiff2[] =
+{
+ { "COUNT", "COUNT", 0, 0, 0, MX, V, { RX }, 0 },
+ { "IF", "IF", 1, 1, 2, 3, R, { VO, RO }, 0 },
+ { "ISNA", "ISNA", 2, 2, 1, 1, V, { VR }, 0 },
+ { "ISERROR", "ISERROR", 3, 3, 1, 1, V, { VR }, 0 },
+ { "SUM", "SUM", 4, 4, 0, MX, V, { RX }, 0 },
+ { "AVERAGE", "AVERAGE", 5, 5, 1, MX, V, { RX }, 0 },
+ { "MIN", "MIN", 6, 6, 1, MX, V, { RX }, 0 },
+ { "MAX", "MAX", 7, 7, 1, MX, V, { RX }, 0 },
+ { "ROW", "ROW", 8, 8, 0, 1, V, { RO }, 0 },
+ { "COLUMN", "COLUMN", 9, 9, 0, 1, V, { RO }, 0 },
+ { "NA", "NA", 10, 10, 0, 0, V, {}, 0 },
+ { "NPV", "NPV", 11, 11, 2, MX, V, { VR, RX }, 0 },
+ { "STDEV", "STDEV", 12, 12, 1, MX, V, { RX }, 0 },
+ { "DOLLAR", "DOLLAR", 13, 13, 1, 2, V, { VR }, 0 },
+ { "FIXED", "FIXED", 14, 14, 1, 2, V, { VR, VR, C }, 0 },
+ { "SIN", "SIN", 15, 15, 1, 1, V, { VR }, 0 },
+ { "COS", "COS", 16, 16, 1, 1, V, { VR }, 0 },
+ { "TAN", "TAN", 17, 17, 1, 1, V, { VR }, 0 },
+ { "COT", "TAN", 17, 17, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY },
+ { "ATAN", "ATAN", 18, 18, 1, 1, V, { VR }, 0 },
+ { "ACOT", "ATAN", 18, 18, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY },
+ { "PI", "PI", 19, 19, 0, 0, V, {}, 0 },
+ { "SQRT", "SQRT", 20, 20, 1, 1, V, { VR }, 0 },
+ { "EXP", "EXP", 21, 21, 1, 1, V, { VR }, 0 },
+ { "LN", "LN", 22, 22, 1, 1, V, { VR }, 0 },
+ { "LOG10", "LOG10", 23, 23, 1, 1, V, { VR }, 0 },
+ { "ABS", "ABS", 24, 24, 1, 1, V, { VR }, 0 },
+ { "INT", "INT", 25, 25, 1, 1, V, { VR }, 0 },
+ { "SIGN", "SIGN", 26, 26, 1, 1, V, { VR }, 0 },
+ { "ROUND", "ROUND", 27, 27, 2, 2, V, { VR }, 0 },
+ { "LOOKUP", "LOOKUP", 28, 28, 2, 3, V, { VR, RA }, 0 },
+ { "INDEX", "INDEX", 29, 29, 2, 4, R, { RA, VV }, 0 },
+ { "REPT", "REPT", 30, 30, 2, 2, V, { VR }, 0 },
+ { "MID", "MID", 31, 31, 3, 3, V, { VR }, 0 },
+ { "LEN", "LEN", 32, 32, 1, 1, V, { VR }, 0 },
+ { "VALUE", "VALUE", 33, 33, 1, 1, V, { VR }, 0 },
+ { "TRUE", "TRUE", 34, 34, 0, 0, V, {}, 0 },
+ { "FALSE", "FALSE", 35, 35, 0, 0, V, {}, 0 },
+ { "AND", "AND", 36, 36, 1, MX, V, { RX }, 0 },
+ { "OR", "OR", 37, 37, 1, MX, V, { RX }, 0 },
+ { "NOT", "NOT", 38, 38, 1, 1, V, { VR }, 0 },
+ { "MOD", "MOD", 39, 39, 2, 2, V, { VR }, 0 },
+ { "DCOUNT", "DCOUNT", 40, 40, 3, 3, V, { RO, RR }, 0 },
+ { "DSUM", "DSUM", 41, 41, 3, 3, V, { RO, RR }, 0 },
+ { "DAVERAGE", "DAVERAGE", 42, 42, 3, 3, V, { RO, RR }, 0 },
+ { "DMIN", "DMIN", 43, 43, 3, 3, V, { RO, RR }, 0 },
+ { "DMAX", "DMAX", 44, 44, 3, 3, V, { RO, RR }, 0 },
+ { "DSTDEV", "DSTDEV", 45, 45, 3, 3, V, { RO, RR }, 0 },
+ { "VAR", "VAR", 46, 46, 1, MX, V, { RX }, 0 },
+ { "DVAR", "DVAR", 47, 47, 3, 3, V, { RO, RR }, 0 },
+ { "TEXT", "TEXT", 48, 48, 2, 2, V, { VR }, 0 },
+ { "LINEST", "LINEST", 49, 49, 1, 2, A, { RA, RA, C, C }, 0 },
+ { "TREND", "TREND", 50, 50, 1, 3, A, { RA, RA, RA, C }, 0 },
+ { "LOGEST", "LOGEST", 51, 51, 1, 2, A, { RA, RA, C, C }, 0 },
+ { "GROWTH", "GROWTH", 52, 52, 1, 3, A, { RA, RA, RA, C }, 0 },
+ { "PV", "PV", 56, 56, 3, 5, V, { VR }, 0 },
+ { "FV", "FV", 57, 57, 3, 5, V, { VR }, 0 },
+ { "NPER", "NPER", 58, 58, 3, 5, V, { VR }, 0 },
+ { "PMT", "PMT", 59, 59, 3, 5, V, { VR }, 0 },
+ { "RATE", "RATE", 60, 60, 3, 6, V, { VR }, 0 },
+ { "MIRR", "MIRR", 61, 61, 3, 3, V, { RA, VR }, 0 },
+ { "IRR", "IRR", 62, 62, 1, 2, V, { RA, VR }, 0 },
+ { "RAND", "RAND", 63, 63, 0, 0, V, {}, FUNCFLAG_VOLATILE },
+ { "MATCH", "MATCH", 64, 64, 2, 3, V, { VR, RX, RR }, 0 },
+ { "DATE", "DATE", 65, 65, 3, 3, V, { VR }, 0 },
+ { "TIME", "TIME", 66, 66, 3, 3, V, { VR }, 0 },
+ { "DAY", "DAY", 67, 67, 1, 1, V, { VR }, 0 },
+ { "MONTH", "MONTH", 68, 68, 1, 1, V, { VR }, 0 },
+ { "YEAR", "YEAR", 69, 69, 1, 1, V, { VR }, 0 },
+ { "WEEKDAY", "WEEKDAY", 70, 70, 1, 1, V, { VR, C }, 0 },
+ { "HOUR", "HOUR", 71, 71, 1, 1, V, { VR }, 0 },
+ { "MINUTE", "MINUTE", 72, 72, 1, 1, V, { VR }, 0 },
+ { "SECOND", "SECOND", 73, 73, 1, 1, V, { VR }, 0 },
+ { "NOW", "NOW", 74, 74, 0, 0, V, {}, FUNCFLAG_VOLATILE },
+ { "AREAS", "AREAS", 75, 75, 1, 1, V, { RO }, 0 },
+ { "ROWS", "ROWS", 76, 76, 1, 1, V, { RO }, 0 },
+ { "COLUMNS", "COLUMNS", 77, 77, 1, 1, V, { RO }, 0 },
+ { "OFFSET", "OFFSET", 78, 78, 3, 5, R, { RO, VR }, FUNCFLAG_VOLATILE },
+ { "SEARCH", "SEARCH", 82, 82, 2, 3, V, { VR }, 0 },
+ { "TRANSPOSE", "TRANSPOSE", 83, 83, 1, 1, A, { VO }, 0 },
+ { "TYPE", "TYPE", 86, 86, 1, 1, V, { VX }, 0 },
+ { "ATAN2", "ATAN2", 97, 97, 2, 2, V, { VR }, 0 },
+ { "ASIN", "ASIN", 98, 98, 1, 1, V, { VR }, 0 },
+ { "ACOS", "ACOS", 99, 99, 1, 1, V, { VR }, 0 },
+ { "CHOOSE", "CHOOSE", 100, 100, 2, MX, R, { VO, RO }, 0 },
+ { "HLOOKUP", "HLOOKUP", 101, 101, 3, 3, V, { VV, RO, RO, C }, 0 },
+ { "VLOOKUP", "VLOOKUP", 102, 102, 3, 3, V, { VV, RO, RO, C }, 0 },
+ { "ISREF", "ISREF", 105, 105, 1, 1, V, { RX }, 0 },
+ { "LOG", "LOG", 109, 109, 1, 2, V, { VR }, 0 },
+ { "CHAR", "CHAR", 111, 111, 1, 1, V, { VR }, 0 },
+ { "LOWER", "LOWER", 112, 112, 1, 1, V, { VR }, 0 },
+ { "UPPER", "UPPER", 113, 113, 1, 1, V, { VR }, 0 },
+ { "PROPER", "PROPER", 114, 114, 1, 1, V, { VR }, 0 },
+ { "LEFT", "LEFT", 115, 115, 1, 2, V, { VR }, 0 },
+ { "RIGHT", "RIGHT", 116, 116, 1, 2, V, { VR }, 0 },
+ { "EXACT", "EXACT", 117, 117, 2, 2, V, { VR }, 0 },
+ { "TRIM", "TRIM", 118, 118, 1, 1, V, { VR }, 0 },
+ { "REPLACE", "REPLACE", 119, 119, 4, 4, V, { VR }, 0 },
+ { "SUBSTITUTE", "SUBSTITUTE", 120, 120, 3, 4, V, { VR }, 0 },
+ { "CODE", "CODE", 121, 121, 1, 1, V, { VR }, 0 },
+ { "FIND", "FIND", 124, 124, 2, 3, V, { VR }, 0 },
+ { "CELL", "CELL", 125, 125, 1, 2, V, { VV, RO }, FUNCFLAG_VOLATILE },
+ { "ISERR", "ISERR", 126, 126, 1, 1, V, { VR }, 0 },
+ { "ISTEXT", "ISTEXT", 127, 127, 1, 1, V, { VR }, 0 },
+ { "ISNUMBER", "ISNUMBER", 128, 128, 1, 1, V, { VR }, 0 },
+ { "ISBLANK", "ISBLANK", 129, 129, 1, 1, V, { VR }, 0 },
+ { "T", "T", 130, 130, 1, 1, V, { RO }, 0 },
+ { "N", "N", 131, 131, 1, 1, V, { RO }, 0 },
+ { "DATEVALUE", "DATEVALUE", 140, 140, 1, 1, V, { VR }, 0 },
+ { "TIMEVALUE", "TIMEVALUE", 141, 141, 1, 1, V, { VR }, 0 },
+ { "SLN", "SLN", 142, 142, 3, 3, V, { VR }, 0 },
+ { "SYD", "SYD", 143, 143, 4, 4, V, { VR }, 0 },
+ { "DDB", "DDB", 144, 144, 4, 5, V, { VR }, 0 },
+ { "INDIRECT", "INDIRECT", 148, 148, 1, 2, R, { VR }, FUNCFLAG_VOLATILE },
+ { "CLEAN", "CLEAN", 162, 162, 1, 1, V, { VR }, 0 },
+ { "MDETERM", "MDETERM", 163, 163, 1, 1, V, { VA }, 0 },
+ { "MINVERSE", "MINVERSE", 164, 164, 1, 1, A, { VA }, 0 },
+ { "MMULT", "MMULT", 165, 165, 2, 2, A, { VA }, 0 },
+ { "IPMT", "IPMT", 167, 167, 4, 6, V, { VR }, 0 },
+ { "PPMT", "PPMT", 168, 168, 4, 6, V, { VR }, 0 },
+ { "COUNTA", "COUNTA", 169, 169, 0, MX, V, { RX }, 0 },
+ { "PRODUCT", "PRODUCT", 183, 183, 0, MX, V, { RX }, 0 },
+ { "FACT", "FACT", 184, 184, 1, 1, V, { VR }, 0 },
+ { "DPRODUCT", "DPRODUCT", 189, 189, 3, 3, V, { RO, RR }, 0 },
+ { "ISNONTEXT", "ISNONTEXT", 190, 190, 1, 1, V, { VR }, 0 },
+ { "STDEVP", "STDEVP", 193, 193, 1, MX, V, { RX }, 0 },
+ { "VARP", "VARP", 194, 194, 1, MX, V, { RX }, 0 },
+ { "DSTDEVP", "DSTDEVP", 195, 195, 3, 3, V, { RO, RR }, 0 },
+ { "DVARP", "DVARP", 196, 196, 3, 3, V, { RO, RR }, 0 },
+ { "TRUNC", "TRUNC", 197, 197, 1, 1, V, { VR, C }, 0 },
+ { "ISLOGICAL", "ISLOGICAL", 198, 198, 1, 1, V, { VR }, 0 },
+ { "DCOUNTA", "DCOUNTA", 199, 199, 3, 3, V, { RO, RR }, 0 },
+ { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_IMPORTONLY },
+
+ // *** macro sheet commands ***
+
+ { 0, "A1.R1C1", 30, 30, 0, 1, V, { VR }, FUNCFLAG_MACROCMD },
+ { 0, "RETURN", 55, 55, 0, 1, R, { RO }, FUNCFLAG_MACROFUNC },
+ { 0, "ABSREF", 79, 79, 2, 2, R, { VR, RO }, FUNCFLAG_MACROFUNC },
+ { 0, "ADD.ARROW", 81, 81, 0, 0, V, {}, FUNCFLAG_MACROCMD },
+ { 0, "ACTIVE.CELL", 94, 94, 0, 0, R, {}, FUNCFLAG_MACROFUNC },
+ { 0, "ACTIVATE", 103, 103, 0, 2, V, { VR }, FUNCFLAG_MACROCMD },
+ { 0, "ACTIVATE.NEXT", 104, 104, 0, 0, V, {}, FUNCFLAG_MACROCMD },
+ { 0, "ACTIVATE.PREV", 105, 105, 0, 0, V, {}, FUNCFLAG_MACROCMD },
+ { 0, "ADD.BAR", 151, 151, 0, 0, V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
+ { 0, "ADD.MENU", 152, 152, 2, 2, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
+ { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }
+};
+
+/** Functions new in BIFF3. */
+static const FunctionData saFuncTableBiff3[] =
+{
+ { "LINEST", "LINEST", 49, 49, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { "TREND", "TREND", 50, 50, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { "LOGEST", "LOGEST", 51, 51, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { "GROWTH", "GROWTH", 52, 52, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { "TRUNC", "TRUNC", 197, 197, 1, 2, V, { VR }, 0 }, // BIFF2: 1, BIFF3: 1-2
+ { "DOLLAR", "USDOLLAR", 204, 204, 1, 2, V, { VR }, FUNCFLAG_IMPORTONLY },
+ { 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { VR }, 0 },
+ { 0/*"SEARCH"*/, "SEARCHB", 206, 206, 2, 3, V, { VR }, 0 },
+ { 0/*"REPLACE"*/, "REPLACEB", 207, 207, 4, 4, V, { VR }, 0 },
+ { 0/*"LEFT"*/, "LEFTB", 208, 208, 1, 2, V, { VR }, 0 },
+ { 0/*"RIGHT"*/, "RIGHTB", 209, 209, 1, 2, V, { VR }, 0 },
+ { 0/*"MID"*/, "MIDB", 210, 210, 3, 3, V, { VR }, 0 },
+ { 0/*"LEN"*/, "LENB", 211, 211, 1, 1, V, { VR }, 0 },
+ { "ROUNDUP", "ROUNDUP", 212, 212, 2, 2, V, { VR }, 0 },
+ { "ROUNDDOWN", "ROUNDDOWN", 213, 213, 2, 2, V, { VR }, 0 },
+ { "ASC", "ASC", 214, 214, 1, 1, V, { VR }, 0 },
+ { "JIS", "DBCS", 215, 215, 1, 1, V, { VR }, 0 },
+ { "ADDRESS", "ADDRESS", 219, 219, 2, 5, V, { VR }, 0 },
+ { "DAYS360", "DAYS360", 220, 220, 2, 2, V, { VR, VR, C }, 0 },
+ { "TODAY", "TODAY", 221, 221, 0, 0, V, {}, FUNCFLAG_VOLATILE },
+ { "VDB", "VDB", 222, 222, 5, 7, V, { VR }, 0 },
+ { "MEDIAN", "MEDIAN", 227, 227, 1, MX, V, { RX }, 0 },
+ { "SUMPRODUCT", "SUMPRODUCT", 228, 228, 1, MX, V, { VA }, 0 },
+ { "SINH", "SINH", 229, 229, 1, 1, V, { VR }, 0 },
+ { "COSH", "COSH", 230, 230, 1, 1, V, { VR }, 0 },
+ { "TANH", "TANH", 231, 231, 1, 1, V, { VR }, 0 },
+ { "COTH", "TANH", 231, 231, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY },
+ { "ASINH", "ASINH", 232, 232, 1, 1, V, { VR }, 0 },
+ { "ACOSH", "ACOSH", 233, 233, 1, 1, V, { VR }, 0 },
+ { "ATANH", "ATANH", 234, 234, 1, 1, V, { VR }, 0 },
+ { "ACOTH", "ATANH", 234, 234, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY },
+ { "DGET", "DGET", 235, 235, 3, 3, V, { RO, RR }, 0 },
+ { "INFO", "INFO", 244, 244, 1, 1, V, { VR }, FUNCFLAG_VOLATILE },
+
+ // *** macro sheet commands ***
+
+ { 0, "ADD.BAR", 151, 151, 0, 1, V, { VR }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1
+ { 0, "ADD.MENU", 152, 152, 2, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3
+ { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { VR, RO }, FUNCFLAG_MACROFUNC } // BIFF2: 3, BIFF3: 3-4
+};
+
+/** Functions new in BIFF4. */
+static const FunctionData saFuncTableBiff4[] =
+{
+ { "FIXED", "FIXED", 14, 14, 1, 3, V, { VR }, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
+ { "RANK", "RANK", 216, 216, 2, 3, V, { VR, RO, VR }, 0 },
+ { "DB", "DB", 247, 247, 4, 5, V, { VR }, 0 },
+ { "FREQUENCY", "FREQUENCY", 252, 252, 2, 2, A, { RA }, 0 },
+ { "ORG.OPENOFFICE.ERRORTYPE","ERROR.TYPE", 261, 261, 1, 1, V, { VR }, 0 },
+ { "AVEDEV", "AVEDEV", 269, 269, 1, MX, V, { RX }, 0 },
+ { "BETADIST", "BETADIST", 270, 270, 3, 5, V, { VR }, 0 },
+ { "GAMMALN", "GAMMALN", 271, 271, 1, 1, V, { VR }, 0 },
+ { "BETAINV", "BETAINV", 272, 272, 3, 5, V, { VR }, 0 },
+ { "BINOMDIST", "BINOMDIST", 273, 273, 4, 4, V, { VR }, 0 },
+ { "LEGACY.CHIDIST", "CHIDIST", 274, 274, 2, 2, V, { VR }, 0 },
+ { "LEGACY.CHIINV", "CHIINV", 275, 275, 2, 2, V, { VR }, 0 },
+ { "COMBIN", "COMBIN", 276, 276, 2, 2, V, { VR }, 0 },
+ { "CONFIDENCE", "CONFIDENCE", 277, 277, 3, 3, V, { VR }, 0 },
+ { "CRITBINOM", "CRITBINOM", 278, 278, 3, 3, V, { VR }, 0 },
+ { "EVEN", "EVEN", 279, 279, 1, 1, V, { VR }, 0 },
+ { "EXPONDIST", "EXPONDIST", 280, 280, 3, 3, V, { VR }, 0 },
+ { "LEGACY.FDIST", "FDIST", 281, 281, 3, 3, V, { VR }, 0 },
+ { "LEGACY.FINV", "FINV", 282, 282, 3, 3, V, { VR }, 0 },
+ { "FISHER", "FISHER", 283, 283, 1, 1, V, { VR }, 0 },
+ { "FISHERINV", "FISHERINV", 284, 284, 1, 1, V, { VR }, 0 },
+ { "FLOOR", "FLOOR", 285, 285, 2, 2, V, { VR, VR, C }, 0 },
+ { "GAMMADIST", "GAMMADIST", 286, 286, 4, 4, V, { VR }, 0 },
+ { "GAMMAINV", "GAMMAINV", 287, 287, 3, 3, V, { VR }, 0 },
+ { "CEILING", "CEILING", 288, 288, 2, 2, V, { VR, VR, C }, 0 },
+ { "HYPGEOMDIST", "HYPGEOMDIST", 289, 289, 4, 4, V, { VR }, 0 },
+ { "LOGNORMDIST", "LOGNORMDIST", 290, 290, 3, 3, V, { VR }, 0 },
+ { "LOGINV", "LOGINV", 291, 291, 3, 3, V, { VR }, 0 },
+ { "NEGBINOMDIST", "NEGBINOMDIST", 292, 292, 3, 3, V, { VR }, 0 },
+ { "NORMDIST", "NORMDIST", 293, 293, 4, 4, V, { VR }, 0 },
+ { "LEGACY.NORMSDIST", "NORMSDIST", 294, 294, 1, 1, V, { VR }, 0 },
+ { "NORMINV", "NORMINV", 295, 295, 3, 3, V, { VR }, 0 },
+ { "LEGACY.NORMSINV", "NORMSINV", 296, 296, 1, 1, V, { VR }, 0 },
+ { "STANDARDIZE", "STANDARDIZE", 297, 297, 3, 3, V, { VR }, 0 },
+ { "ODD", "ODD", 298, 298, 1, 1, V, { VR }, 0 },
+ { "PERMUT", "PERMUT", 299, 299, 2, 2, V, { VR }, 0 },
+ { "POISSON", "POISSON", 300, 300, 3, 3, V, { VR }, 0 },
+ { "TDIST", "TDIST", 301, 301, 3, 3, V, { VR }, 0 },
+ { "WEIBULL", "WEIBULL", 302, 302, 4, 4, V, { VR }, 0 },
+ { "SUMXMY2", "SUMXMY2", 303, 303, 2, 2, V, { VA }, 0 },
+ { "SUMX2MY2", "SUMX2MY2", 304, 304, 2, 2, V, { VA }, 0 },
+ { "SUMX2PY2", "SUMX2PY2", 305, 305, 2, 2, V, { VA }, 0 },
+ { "LEGACY.CHITEST", "CHITEST", 306, 306, 2, 2, V, { VA }, 0 },
+ { "CORREL", "CORREL", 307, 307, 2, 2, V, { VA }, 0 },
+ { "COVAR", "COVAR", 308, 308, 2, 2, V, { VA }, 0 },
+ { "FORECAST", "FORECAST", 309, 309, 3, 3, V, { VR, VA }, 0 },
+ { "FTEST", "FTEST", 310, 310, 2, 2, V, { VA }, 0 },
+ { "INTERCEPT", "INTERCEPT", 311, 311, 2, 2, V, { VA }, 0 },
+ { "PEARSON", "PEARSON", 312, 312, 2, 2, V, { VA }, 0 },
+ { "RSQ", "RSQ", 313, 313, 2, 2, V, { VA }, 0 },
+ { "STEYX", "STEYX", 314, 314, 2, 2, V, { VA }, 0 },
+ { "SLOPE", "SLOPE", 315, 315, 2, 2, V, { VA }, 0 },
+ { "TTEST", "TTEST", 316, 316, 4, 4, V, { VA, VA, VR }, 0 },
+ { "PROB", "PROB", 317, 317, 3, 4, V, { VA, VA, VR }, 0 },
+ { "DEVSQ", "DEVSQ", 318, 318, 1, MX, V, { RX }, 0 },
+ { "GEOMEAN", "GEOMEAN", 319, 319, 1, MX, V, { RX }, 0 },
+ { "HARMEAN", "HARMEAN", 320, 320, 1, MX, V, { RX }, 0 },
+ { "SUMSQ", "SUMSQ", 321, 321, 0, MX, V, { RX }, 0 },
+ { "KURT", "KURT", 322, 322, 1, MX, V, { RX }, 0 },
+ { "SKEW", "SKEW", 323, 323, 1, MX, V, { RX }, 0 },
+ { "ZTEST", "ZTEST", 324, 324, 2, 3, V, { RX, VR }, 0 },
+ { "LARGE", "LARGE", 325, 325, 2, 2, V, { RX, VR }, 0 },
+ { "SMALL", "SMALL", 326, 326, 2, 2, V, { RX, VR }, 0 },
+ { "QUARTILE", "QUARTILE", 327, 327, 2, 2, V, { RX, VR }, 0 },
+ { "PERCENTILE", "PERCENTILE", 328, 328, 2, 2, V, { RX, VR }, 0 },
+ { "PERCENTRANK", "PERCENTRANK", 329, 329, 2, 3, V, { RX, VR, VR_E }, 0 },
+ { "MODE", "MODE", 330, 330, 1, MX, V, { VA }, 0 },
+ { "TRIMMEAN", "TRIMMEAN", 331, 331, 2, 2, V, { RX, VR }, 0 },
+ { "TINV", "TINV", 332, 332, 2, 2, V, { VR }, 0 },
+
+ // *** Analysis add-in ***
+
+ { "HEX2BIN", "HEX2BIN", 384, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "HEX2DEC", "HEX2DEC", 385, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "HEX2OCT", "HEX2OCT", 386, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DEC2BIN", "DEC2BIN", 387, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DEC2HEX", "DEC2HEX", 388, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DEC2OCT", "DEC2OCT", 389, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "OCT2BIN", "OCT2BIN", 390, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "OCT2HEX", "OCT2HEX", 391, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "OCT2DEC", "OCT2DEC", 392, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "BIN2DEC", "BIN2DEC", 393, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "BIN2OCT", "BIN2OCT", 394, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "BIN2HEX", "BIN2HEX", 395, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMSUB", "IMSUB", 396, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMDIV", "IMDIV", 397, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMPOWER", "IMPOWER", 398, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMABS", "IMABS", 399, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMSQRT", "IMSQRT", 400, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMLN", "IMLN", 401, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMLOG2", "IMLOG2", 402, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMLOG10", "IMLOG10", 403, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMSIN", "IMSIN", 404, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMCOS", "IMCOS", 405, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMEXP", "IMEXP", 406, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMARGUMENT", "IMARGUMENT", 407, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMCONJUGATE", "IMCONJUGATE", 408, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMAGINARY", "IMAGINARY", 409, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMREAL", "IMREAL", 410, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "COMPLEX", "COMPLEX", 411, NOID, 2, 3, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "IMSUM", "IMSUM", 412, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL },
+ { "IMPRODUCT", "IMPRODUCT", 413, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL },
+ { "SERIESSUM", "SERIESSUM", 414, NOID, 4, 4, V, { RR, RR, RR, RX }, FUNCFLAG_EXTERNAL },
+ { "FACTDOUBLE", "FACTDOUBLE", 415, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "SQRTPI", "SQRTPI", 416, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "QUOTIENT", "QUOTIENT", 417, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DELTA", "DELTA", 418, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "GESTEP", "GESTEP", 419, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ISEVEN", "ISEVEN", 420, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "ISODD", "ISODD", 421, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "MROUND", "MROUND", 422, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ERF", "ERF", 423, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ERFC", "ERFC", 424, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "BESSELJ", "BESSELJ", 425, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "BESSELK", "BESSELK", 426, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "BESSELY", "BESSELY", 427, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "BESSELI", "BESSELI", 428, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "XIRR", "XIRR", 429, NOID, 2, 3, V, { RX, RX, RR }, FUNCFLAG_EXTERNAL },
+ { "XNPV", "XNPV", 430, NOID, 3, 3, V, { RR, RX, RX }, FUNCFLAG_EXTERNAL },
+ { "PRICEMAT", "PRICEMAT", 431, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "YIELDMAT", "YIELDMAT", 432, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "INTRATE", "INTRATE", 433, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "RECEIVED", "RECEIVED", 434, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DISC", "DISC", 435, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "PRICEDISC", "PRICEDISC", 436, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "YIELDDISC", "YIELDDISC", 437, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "TBILLEQ", "TBILLEQ", 438, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "TBILLPRICE", "TBILLPRICE", 439, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "TBILLYIELD", "TBILLYIELD", 440, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "PRICE", "PRICE", 441, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "YIELD", "YIELD", 442, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DOLLARDE", "DOLLARDE", 443, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DOLLARFR", "DOLLARFR", 444, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "NOMINAL", "NOMINAL", 445, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "EFFECT", "EFFECT", 446, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "CUMPRINC", "CUMPRINC", 447, NOID, 6, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "CUMIPMT", "CUMIPMT", 448, NOID, 6, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "EDATE", "EDATE", 449, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "EOMONTH", "EOMONTH", 450, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "YEARFRAC", "YEARFRAC", 451, NOID, 2, 3, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "COUPDAYBS", "COUPDAYBS", 452, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "COUPDAYS", "COUPDAYS", 453, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "COUPDAYSNC", "COUPDAYSNC", 454, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "COUPNCD", "COUPNCD", 455, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "COUPNUM", "COUPNUM", 456, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "COUPPCD", "COUPPCD", 457, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "DURATION", "DURATION", 458, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "MDURATION", "MDURATION", 459, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ODDLPRICE", "ODDLPRICE", 460, NOID, 7, 8, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ODDLYIELD", "ODDLYIELD", 461, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ODDFPRICE", "ODDFPRICE", 462, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ODDFYIELD", "ODDFYIELD", 463, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "RANDBETWEEN", "RANDBETWEEN", 464, NOID, 2, 2, V, { RR }, FUNCFLAG_VOLATILE | FUNCFLAG_EXTERNAL },
+ { "WEEKNUM", "WEEKNUM", 465, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "AMORDEGRC", "AMORDEGRC", 466, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "AMORLINC", "AMORLINC", 467, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "CONVERT", "CONVERT", 468, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "ACCRINT", "ACCRINT", 469, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "ACCRINTM", "ACCRINTM", 470, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL },
+ { "WORKDAY", "WORKDAY", 471, NOID, 2, 3, V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL },
+ { "NETWORKDAYS", "NETWORKDAYS", 472, NOID, 2, 3, V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL },
+ { "GCD", "GCD", 473, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "MULTINOMIAL", "MULTINOMIAL", 474, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL },
+ { "LCM", "LCM", 475, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in
+ { "FVSCHEDULE", "FVSCHEDULE", 476, NOID, 2, 2, V, { RR, RX }, FUNCFLAG_EXTERNAL },
+
+ // *** macro sheet commands ***
+
+ { 0, "ACTIVATE.NEXT", 104, 104, 0, 1, V, { VR }, FUNCFLAG_MACROCMD }, // BIFF2-3: 0, BIFF4: 0-1
+ { 0, "ACTIVATE.PREV", 105, 105, 0, 1, V, { VR }, FUNCFLAG_MACROCMD } // BIFF2-3: 0, BIFF4: 0-1
+};
+
+/** Functions new in BIFF5/BIFF7. */
+static const FunctionData saFuncTableBiff5[] =
+{
+ { "WEEKDAY", "WEEKDAY", 70, 70, 1, 2, V, { VR }, 0 }, // BIFF2-4: 1, BIFF5: 1-2
+ { "HLOOKUP", "HLOOKUP", 101, 101, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { "VLOOKUP", "VLOOKUP", 102, 102, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { "DAYS360", "DAYS360", 220, 220, 2, 3, V, { VR }, 0 }, // BIFF3-4: 2, BIFF5: 2-3
+ { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_EXPORTONLY }, // MACRO or EXTERNAL
+ { "CONCATENATE", "CONCATENATE", 336, 336, 0, MX, V, { VR }, 0 },
+ { "POWER", "POWER", 337, 337, 2, 2, V, { VR }, 0 },
+ { "RADIANS", "RADIANS", 342, 342, 1, 1, V, { VR }, 0 },
+ { "DEGREES", "DEGREES", 343, 343, 1, 1, V, { VR }, 0 },
+ { "SUBTOTAL", "SUBTOTAL", 344, 344, 2, MX, V, { VR, RO }, 0 },
+ { "SUMIF", "SUMIF", 345, 345, 2, 3, V, { RO, VR, RO }, 0 },
+ { "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { RO, VR }, 0 },
+ { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { RO }, 0 },
+ { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { VR }, 0 },
+ { 0, "DATEDIF", 351, 351, 3, 3, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc
+ { 0, "DATESTRING", 352, 352, 1, 1, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec
+ { 0, "NUMBERSTRING", 353, 353, 2, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec
+ { "ROMAN", "ROMAN", 354, 354, 1, 2, V, { VR }, 0 },
+
+ // *** EuroTool add-in ***
+
+ { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { VR }, FUNCFLAG_EUROTOOL },
+
+ // *** macro sheet commands ***
+
+ { 0, "ADD.MENU", 152, 152, 2, 4, V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4
+ { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5
+ { 0, "ADD.CHART.AUTOFORMAT", 390, 390, 0, 2, V, { VR }, FUNCFLAG_MACROCMD },
+ { 0, "ADD.LIST.ITEM", 451, 451, 0, 2, V, { VR }, FUNCFLAG_MACROCMD },
+ { 0, "ACTIVE.CELL.FONT", 476, 476, 0, 14, V, { VR }, FUNCFLAG_MACROCMD }
+};
+
+/** Functions new in BIFF8. */
+static const FunctionData saFuncTableBiff8[] =
+{
+ { "GETPIVOTDATA", "GETPIVOTDATA", 358, 358, 2, MX, V, { RR, RR, VR, VR }, FUNCFLAG_IMPORTONLY | FUNCFLAG_PARAMPAIRS },
+ { "HYPERLINK", "HYPERLINK", 359, 359, 1, 2, V, { VV, VO }, 0 },
+ { 0, "PHONETIC", 360, 360, 1, 1, V, { RO }, FUNCFLAG_IMPORTONLY },
+ { "AVERAGEA", "AVERAGEA", 361, 361, 1, MX, V, { RX }, 0 },
+ { "MAXA", "MAXA", 362, 362, 1, MX, V, { RX }, 0 },
+ { "MINA", "MINA", 363, 363, 1, MX, V, { RX }, 0 },
+ { "STDEVPA", "STDEVPA", 364, 364, 1, MX, V, { RX }, 0 },
+ { "VARPA", "VARPA", 365, 365, 1, MX, V, { RX }, 0 },
+ { "STDEVA", "STDEVA", 366, 366, 1, MX, V, { RX }, 0 },
+ { "VARA", "VARA", 367, 367, 1, MX, V, { RX }, 0 },
+ { "COM.MICROSOFT.BAHTTEXT", "BAHTTEXT", 368, 368, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "THAIDAYOFWEEK", 369, 369, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "THAIDIGIT", 370, 370, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "THAIMONTHOFYEAR", 371, 371, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "THAINUMSOUND", 372, 372, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "THAINUMSTRING", 373, 373, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "THAISTRINGLENGTH", 374, 374, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "ISTHAIDIGIT", 375, 375, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "ROUNDBAHTDOWN", 376, 376, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "ROUNDBAHTUP", 377, 377, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "THAIYEAR", 378, 378, 1, 1, V, { VR }, FUNCFLAG_MACROCALL },
+ { 0, "RTD", 379, 379, 3, 3, A, { VR, VR, RO }, 0 }
+};
+
+/** Functions new in OOXML. */
+static const FunctionData saFuncTableOox[] =
+{
+ { 0, "CUBEVALUE", 380, NOID, 1, MX, V, { VR, RX }, 0 },
+ { 0, "CUBEMEMBER", 381, NOID, 2, 3, V, { VR, RX, VR }, 0 },
+ { 0, "CUBEMEMBERPROPERTY", 382, NOID, 3, 3, V, { VR }, 0 },
+ { 0, "CUBERANKEDMEMBER", 383, NOID, 3, 4, V, { VR }, 0 },
+ { 0, "CUBEKPIMEMBER", 477, NOID, 3, 4, V, { VR }, 0 },
+ { 0, "CUBESET", 478, NOID, 2, 5, V, { VR, RX, VR }, 0 },
+ { 0, "CUBESETCOUNT", 479, NOID, 1, 1, V, { VR }, 0 },
+ { 0, "IFERROR", 480, NOID, 2, 2, V, { VO, RO }, 0 },
+ { 0, "COUNTIFS", 481, NOID, 2, MX, V, { RO, VR }, FUNCFLAG_PARAMPAIRS },
+ { 0, "SUMIFS", 482, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS },
+ { 0, "AVERAGEIF", 483, NOID, 2, 3, V, { RO, VR, RO }, 0 },
+ { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { RO, RO, VR }, 0 }
+};
+
+/** Functions defined by OpenFormula, but not supported by Calc or by Excel. */
+static const FunctionData saFuncTableOdf[] =
+{
+ { "ARABIC", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "B", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BASE", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITAND", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "IFNA", 0, NOID, NOID, 2, 2, V, { VR, RO }, FUNCFLAG_MACROCALLODF },
+ { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "MUNIT", 0, NOID, NOID, 1, 1, A, { VR }, FUNCFLAG_MACROCALLODF },
+ { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "PDURATION", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "PHI", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "RRI", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "SHEET", 0, NOID, NOID, 0, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "SHEETS", 0, NOID, NOID, 0, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "SKEWP", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF },
+ { "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "UNICODE", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "XOR", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF }
+};
+
+// ----------------------------------------------------------------------------
+
+const sal_Unicode API_TOKEN_OPEN = '(';
+const sal_Unicode API_TOKEN_CLOSE = ')';
+const sal_Unicode API_TOKEN_SEP = ';';
+
+const sal_Unicode API_TOKEN_ARRAY_OPEN = '{';
+const sal_Unicode API_TOKEN_ARRAY_CLOSE = '}';
+const sal_Unicode API_TOKEN_ARRAY_ROWSEP = '|';
+const sal_Unicode API_TOKEN_ARRAY_COLSEP = ';';
+
+} // namespace
+
+// function info parameter class iterator =====================================
+
+FunctionParamInfoIterator::FunctionParamInfoIterator( const FunctionInfo& rFuncInfo ) :
+ mpParamInfo( rFuncInfo.mpParamInfos ),
+ mpParamInfoEnd( rFuncInfo.mpParamInfos + FUNCINFO_PARAMINFOCOUNT ),
+ mbParamPairs( rFuncInfo.mbParamPairs )
+{
+ OSL_ENSURE( !mbParamPairs || (mpParamInfo + 1 < mpParamInfoEnd),
+ "FunctionParamInfoIterator::FunctionParamInfoIterator - expecting at least 2 infos for paired parameters" );
+}
+
+const FunctionParamInfo& FunctionParamInfoIterator::getParamInfo() const
+{
+ static const FunctionParamInfo saInvalidInfo = { FUNC_PARAM_NONE, FUNC_PARAMCONV_ORG, false };
+ return mpParamInfo ? *mpParamInfo : saInvalidInfo;
+}
+
+bool FunctionParamInfoIterator::isCalcOnlyParam() const
+{
+ return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_CALCONLY);
+}
+
+bool FunctionParamInfoIterator::isExcelOnlyParam() const
+{
+ return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_EXCELONLY);
+}
+
+FunctionParamInfoIterator& FunctionParamInfoIterator::operator++()
+{
+ if( mpParamInfo )
+ {
+ // move pointer to next entry, if something explicit follows
+ if( (mpParamInfo + 1 < mpParamInfoEnd) && (mpParamInfo[ 1 ].meValid != FUNC_PARAM_NONE) )
+ ++mpParamInfo;
+ // points to last info, but parameter pairs expected, move to previous info
+ else if( mbParamPairs )
+ --mpParamInfo;
+ // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
+ else if( isExcelOnlyParam() || isCalcOnlyParam() )
+ mpParamInfo = 0;
+ // otherwise: repeat last parameter class
+ }
+ return *this;
+}
+
+// function provider ==========================================================
+
+struct FunctionProviderImpl
+{
+ typedef RefMap< OUString, FunctionInfo > FuncNameMap;
+ typedef RefMap< sal_uInt16, FunctionInfo > FuncIdMap;
+
+ FunctionInfoVector maFuncs; /// All function infos in one list.
+ FuncNameMap maOdfFuncs; /// Maps ODF function names to function data.
+ FuncNameMap maOoxFuncs; /// Maps OOXML function names to function data.
+ FuncIdMap maBiff12Funcs; /// Maps BIFF12 function indexes to function data.
+ FuncIdMap maBiffFuncs; /// Maps BIFF2-BIFF8 function indexes to function data.
+ FuncNameMap maMacroFuncs; /// Maps macro function names to function data.
+
+ explicit FunctionProviderImpl( FilterType eFilter, BiffType eBiff, bool bImportFilter );
+
+private:
+ /** Creates and inserts a function info struct from the passed function data. */
+ void initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam );
+
+ /** Initializes the members from the passed function data list. */
+ void initFuncs(
+ const FunctionData* pBeg, const FunctionData* pEnd,
+ sal_uInt8 nMaxParam, bool bImportFilter );
+};
+
+// ----------------------------------------------------------------------------
+
+FunctionProviderImpl::FunctionProviderImpl( FilterType eFilter, BiffType eBiff, bool bImportFilter )
+{
+ OSL_ENSURE( bImportFilter, "FunctionProviderImpl::FunctionProviderImpl - need special handling for macro call functions" );
+ sal_uInt8 nMaxParam = 0;
+ switch( eFilter )
+ {
+ case FILTER_OOXML:
+ nMaxParam = OOX_MAX_PARAMCOUNT;
+ eBiff = BIFF8; // insert all BIFF function tables, then the OOXML table
+ break;
+ case FILTER_BIFF:
+ nMaxParam = BIFF_MAX_PARAMCOUNT;
+ break;
+ case FILTER_UNKNOWN:
+ OSL_ENSURE( false, "FunctionProviderImpl::FunctionProviderImpl - invalid filter type" );
+ break;
+ }
+ OSL_ENSURE( eBiff != BIFF_UNKNOWN, "FunctionProviderImpl::FunctionProviderImpl - invalid BIFF type" );
+
+ /* 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 )
+ initFuncs( saFuncTableBiff2, STATIC_ARRAY_END( saFuncTableBiff2 ), nMaxParam, bImportFilter );
+ if( eBiff >= BIFF3 )
+ initFuncs( saFuncTableBiff3, STATIC_ARRAY_END( saFuncTableBiff3 ), nMaxParam, bImportFilter );
+ if( eBiff >= BIFF4 )
+ initFuncs( saFuncTableBiff4, STATIC_ARRAY_END( saFuncTableBiff4 ), nMaxParam, bImportFilter );
+ if( eBiff >= BIFF5 )
+ initFuncs( saFuncTableBiff5, STATIC_ARRAY_END( saFuncTableBiff5 ), nMaxParam, bImportFilter );
+ if( eBiff >= BIFF8 )
+ initFuncs( saFuncTableBiff8, STATIC_ARRAY_END( saFuncTableBiff8 ), nMaxParam, bImportFilter );
+ if( eFilter == FILTER_OOXML )
+ initFuncs( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ), nMaxParam, bImportFilter );
+ initFuncs( saFuncTableOdf, STATIC_ARRAY_END( saFuncTableOdf ), nMaxParam, bImportFilter );
+}
+
+void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam )
+{
+ // create a function info object
+ FunctionInfoRef xFuncInfo( new FunctionInfo );
+ if( rFuncData.mpcOdfFuncName )
+ xFuncInfo->maOdfFuncName = OUString::createFromAscii( rFuncData.mpcOdfFuncName );
+ if( rFuncData.mpcOoxFuncName )
+ xFuncInfo->maOoxFuncName = OUString::createFromAscii( rFuncData.mpcOoxFuncName );
+
+ if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALL ) )
+ {
+ OSL_ENSURE( xFuncInfo->maOoxFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing OOXML function name" );
+ OSL_ENSURE( !getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ), "FunctionProviderImpl::initFunc - unexpected flag FUNCFLAG_MACROCALLODF" );
+ xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfn." ) + xFuncInfo->maOoxFuncName;
+ }
+ else if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ) )
+ {
+ OSL_ENSURE( xFuncInfo->maOdfFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing ODF function name" );
+ xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfnodf." ) + xFuncInfo->maOdfFuncName;
+ }
+
+ switch( rFuncData.mnFlags & FUNCFLAG_FUNCLIBMASK )
+ {
+ case FUNCFLAG_EUROTOOL: xFuncInfo->meFuncLibType = FUNCLIB_EUROTOOL; break;
+ default: xFuncInfo->meFuncLibType = FUNCLIB_UNKNOWN;
+ }
+
+ xFuncInfo->mnApiOpCode = -1;
+ xFuncInfo->mnBiff12FuncId = rFuncData.mnBiff12FuncId;
+ xFuncInfo->mnBiffFuncId = rFuncData.mnBiffFuncId;
+ xFuncInfo->mnMinParamCount = rFuncData.mnMinParamCount;
+ xFuncInfo->mnMaxParamCount = (rFuncData.mnMaxParamCount == MX) ? nMaxParam : rFuncData.mnMaxParamCount;
+ xFuncInfo->mnRetClass = rFuncData.mnRetClass;
+ xFuncInfo->mpParamInfos = rFuncData.mpParamInfos;
+ xFuncInfo->mbParamPairs = getFlag( rFuncData.mnFlags, FUNCFLAG_PARAMPAIRS );
+ xFuncInfo->mbVolatile = getFlag( rFuncData.mnFlags, FUNCFLAG_VOLATILE );
+ xFuncInfo->mbExternal = getFlag( rFuncData.mnFlags, FUNCFLAG_EXTERNAL );
+ bool bMacroCmd = getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCMD );
+ xFuncInfo->mbMacroFunc = bMacroCmd || getFlag( rFuncData.mnFlags, FUNCFLAG_MACROFUNC );
+ xFuncInfo->mbVarParam = bMacroCmd || (rFuncData.mnMinParamCount != rFuncData.mnMaxParamCount) || getFlag( rFuncData.mnFlags, FUNCFLAG_ALWAYSVAR );
+
+ setFlag( xFuncInfo->mnBiff12FuncId, BIFF_TOK_FUNCVAR_CMD, bMacroCmd );
+ setFlag( xFuncInfo->mnBiffFuncId, BIFF_TOK_FUNCVAR_CMD, bMacroCmd );
+
+ // insert the function info into the member maps
+ maFuncs.push_back( xFuncInfo );
+ if( xFuncInfo->maOdfFuncName.getLength() > 0 )
+ maOdfFuncs[ xFuncInfo->maOdfFuncName ] = xFuncInfo;
+ if( xFuncInfo->maOoxFuncName.getLength() > 0 )
+ maOoxFuncs[ xFuncInfo->maOoxFuncName ] = xFuncInfo;
+ if( xFuncInfo->mnBiff12FuncId != NOID )
+ maBiff12Funcs[ xFuncInfo->mnBiff12FuncId ] = xFuncInfo;
+ if( xFuncInfo->mnBiffFuncId != NOID )
+ maBiffFuncs[ xFuncInfo->mnBiffFuncId ] = xFuncInfo;
+ if( xFuncInfo->maBiffMacroName.getLength() > 0 )
+ maMacroFuncs[ xFuncInfo->maBiffMacroName ] = xFuncInfo;
+}
+
+void FunctionProviderImpl::initFuncs( const FunctionData* pBeg, const FunctionData* pEnd, sal_uInt8 nMaxParam, bool bImportFilter )
+{
+ for( const FunctionData* pIt = pBeg; pIt != pEnd; ++pIt )
+ if( pIt->isSupported( bImportFilter ) )
+ initFunc( *pIt, nMaxParam );
+}
+
+// ----------------------------------------------------------------------------
+
+FunctionProvider::FunctionProvider( FilterType eFilter, BiffType eBiff, bool bImportFilter ) :
+ mxFuncImpl( new FunctionProviderImpl( eFilter, eBiff, bImportFilter ) )
+{
+}
+
+FunctionProvider::~FunctionProvider()
+{
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromOdfFuncName( const OUString& rFuncName ) const
+{
+ return mxFuncImpl->maOdfFuncs.get( rFuncName ).get();
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromOoxFuncName( const OUString& rFuncName ) const
+{
+ return mxFuncImpl->maOoxFuncs.get( rFuncName ).get();
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromBiff12FuncId( sal_uInt16 nFuncId ) const
+{
+ return mxFuncImpl->maBiff12Funcs.get( nFuncId ).get();
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const
+{
+ return mxFuncImpl->maBiffFuncs.get( nFuncId ).get();
+}
+
+const FunctionInfo* FunctionProvider::getFuncInfoFromMacroName( const OUString& rFuncName ) const
+{
+ return mxFuncImpl->maMacroFuncs.get( rFuncName ).get();
+}
+
+FunctionLibraryType FunctionProvider::getFuncLibTypeFromLibraryName( const OUString& rLibraryName ) const
+{
+#define OOX_XLS_IS_LIBNAME( libname, basename ) (libname.equalsIgnoreAsciiCaseAscii( basename ".XLA" ) || libname.equalsIgnoreAsciiCaseAscii( basename ".XLAM" ))
+
+ // the EUROTOOL add-in containing the EUROCONVERT function
+ if( OOX_XLS_IS_LIBNAME( rLibraryName, "EUROTOOL" ) )
+ return FUNCLIB_EUROTOOL;
+
+#undef OOX_XLS_IS_LIBNAME
+
+ // default: unknown library
+ return FUNCLIB_UNKNOWN;
+}
+
+const FunctionInfoVector& FunctionProvider::getFuncs() const
+{
+ return mxFuncImpl->maFuncs;
+}
+
+// op-code and function provider ==============================================
+
+struct OpCodeProviderImpl : public ApiOpCodes
+{
+ typedef RefMap< sal_Int32, FunctionInfo > OpCodeFuncMap;
+ typedef RefMap< OUString, FunctionInfo > FuncNameMap;
+ typedef ::std::vector< FormulaOpCodeMapEntry > OpCodeEntryVector;
+
+ OpCodeFuncMap maOpCodeFuncs; /// Maps API function op-codes to function data.
+ FuncNameMap maExtProgFuncs; /// Maps programmatical API function names to function data.
+ OpCodeEntryVector maParserMap; /// OOXML token mapping for formula parser service.
+
+ explicit OpCodeProviderImpl(
+ const FunctionInfoVector& rFuncInfos,
+ const Reference< XMultiServiceFactory >& rxFactory );
+
+private:
+ typedef ::std::map< OUString, ApiToken > ApiTokenMap;
+ typedef Sequence< FormulaOpCodeMapEntry > OpCodeEntrySequence;
+
+ static bool fillEntrySeq( OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup );
+ static bool fillTokenMap( ApiTokenMap& orTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup );
+ bool fillFuncTokenMaps( ApiTokenMap& orIntFuncTokenMap, ApiTokenMap& orExtFuncTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper ) const;
+
+ static bool initOpCode( sal_Int32& ornOpCode, const OpCodeEntrySequence& rEntrySeq, sal_Int32 nSpecialId );
+ bool initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const OUString& rOdfName, const OUString& rOoxName );
+ bool initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName );
+ bool initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, sal_Unicode cOdfName, sal_Unicode cOoxName );
+
+ bool initFuncOpCode( FunctionInfo& orFuncInfo, const ApiTokenMap& rFuncTokenMap );
+ bool initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, const ApiTokenMap& rExtFuncTokenMap, const FunctionInfoVector& rFuncInfos );
+};
+
+// ----------------------------------------------------------------------------
+
+OpCodeProviderImpl::OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos,
+ const Reference< XMultiServiceFactory >& rxFactory )
+{
+ if( rxFactory.is() ) try
+ {
+ Reference< XFormulaOpCodeMapper > xMapper( rxFactory->createInstance(
+ CREATE_OUSTRING( "com.sun.star.sheet.FormulaOpCodeMapper" ) ), UNO_QUERY_THROW );
+
+ // op-codes provided as attributes
+ OPCODE_UNKNOWN = xMapper->getOpCodeUnknown();
+ OPCODE_EXTERNAL = xMapper->getOpCodeExternal();
+
+ using namespace ::com::sun::star::sheet::FormulaMapGroup;
+ using namespace ::com::sun::star::sheet::FormulaMapGroupSpecialOffset;
+
+ OpCodeEntrySequence aEntrySeq;
+ ApiTokenMap aTokenMap, aExtFuncTokenMap;
+ bool bIsValid =
+ // special
+ fillEntrySeq( aEntrySeq, xMapper, SPECIAL ) &&
+ initOpCode( OPCODE_PUSH, aEntrySeq, PUSH ) &&
+ initOpCode( OPCODE_MISSING, aEntrySeq, MISSING ) &&
+ initOpCode( OPCODE_SPACES, aEntrySeq, SPACES ) &&
+ initOpCode( OPCODE_NAME, aEntrySeq, NAME ) &&
+ initOpCode( OPCODE_DBAREA, aEntrySeq, DB_AREA ) &&
+ initOpCode( OPCODE_NLR, aEntrySeq, COL_ROW_NAME ) &&
+ initOpCode( OPCODE_MACRO, aEntrySeq, MACRO ) &&
+ initOpCode( OPCODE_BAD, aEntrySeq, BAD ) &&
+ initOpCode( OPCODE_NONAME, aEntrySeq, NO_NAME ) &&
+ // separators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, SEPARATORS ) &&
+ initOpCode( OPCODE_OPEN, aTokenMap, API_TOKEN_OPEN, '(' ) &&
+ initOpCode( OPCODE_CLOSE, aTokenMap, API_TOKEN_CLOSE, ')' ) &&
+ initOpCode( OPCODE_SEP, aTokenMap, API_TOKEN_SEP, ',' ) &&
+ // array separators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, ARRAY_SEPARATORS ) &&
+ initOpCode( OPCODE_ARRAY_OPEN, aTokenMap, API_TOKEN_ARRAY_OPEN, '{' ) &&
+ initOpCode( OPCODE_ARRAY_CLOSE, aTokenMap, API_TOKEN_ARRAY_CLOSE, '}' ) &&
+ initOpCode( OPCODE_ARRAY_ROWSEP, aTokenMap, API_TOKEN_ARRAY_ROWSEP, ';' ) &&
+ initOpCode( OPCODE_ARRAY_COLSEP, aTokenMap, API_TOKEN_ARRAY_COLSEP, ',' ) &&
+ // unary operators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, UNARY_OPERATORS ) &&
+ initOpCode( OPCODE_PLUS_SIGN, aTokenMap, '+', '\0' ) && // same op-code as OPCODE_ADD
+ initOpCode( OPCODE_MINUS_SIGN, aTokenMap, '-', '-' ) &&
+ initOpCode( OPCODE_PERCENT, aTokenMap, '%', '%' ) &&
+ // binary operators
+ fillTokenMap( aTokenMap, aEntrySeq, xMapper, BINARY_OPERATORS ) &&
+ initOpCode( OPCODE_ADD, aTokenMap, '+', '+' ) &&
+ initOpCode( OPCODE_SUB, aTokenMap, '-', '-' ) &&
+ initOpCode( OPCODE_MULT, aTokenMap, '*', '*' ) &&
+ initOpCode( OPCODE_DIV, aTokenMap, '/', '/' ) &&
+ initOpCode( OPCODE_POWER, aTokenMap, '^', '^' ) &&
+ initOpCode( OPCODE_CONCAT, aTokenMap, '&', '&' ) &&
+ initOpCode( OPCODE_EQUAL, aTokenMap, '=', '=' ) &&
+ initOpCode( OPCODE_NOT_EQUAL, aTokenMap, "<>", "<>" ) &&
+ initOpCode( OPCODE_LESS, aTokenMap, '<', '<' ) &&
+ initOpCode( OPCODE_LESS_EQUAL, aTokenMap, "<=", "<=" ) &&
+ initOpCode( OPCODE_GREATER, aTokenMap, '>', '>' ) &&
+ initOpCode( OPCODE_GREATER_EQUAL, aTokenMap, ">=", ">=" ) &&
+ initOpCode( OPCODE_INTERSECT, aTokenMap, '!', ' ' ) &&
+ initOpCode( OPCODE_LIST, aTokenMap, '~', ',' ) &&
+ initOpCode( OPCODE_RANGE, aTokenMap, ':', ':' ) &&
+ // functions
+ fillFuncTokenMaps( aTokenMap, aExtFuncTokenMap, aEntrySeq, xMapper ) &&
+ initFuncOpCodes( aTokenMap, aExtFuncTokenMap, rFuncInfos ) &&
+ initOpCode( OPCODE_DDE, aTokenMap, "DDE", 0 );
+
+ OSL_ENSURE( bIsValid, "OpCodeProviderImpl::OpCodeProviderImpl - opcodes not initialized" );
+ (void)bIsValid;
+
+ // OPCODE_PLUS_SIGN and OPCODE_ADD should be equal, otherwise "+" has to be passed above
+ OSL_ENSURE( OPCODE_PLUS_SIGN == OPCODE_ADD, "OpCodeProviderImpl::OpCodeProviderImpl - need opcode mapping for OPCODE_PLUS_SIGN" );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "OpCodeProviderImpl::OpCodeProviderImpl - cannot receive formula opcode mapper" );
+ }
+}
+
+bool OpCodeProviderImpl::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 OpCodeProviderImpl::fillTokenMap( ApiTokenMap& 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 orEntrySeq.hasElements();
+}
+
+bool OpCodeProviderImpl::fillFuncTokenMaps( ApiTokenMap& orIntFuncTokenMap, ApiTokenMap& orExtFuncTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper ) const
+{
+ orIntFuncTokenMap.clear();
+ orExtFuncTokenMap.clear();
+ if( fillEntrySeq( orEntrySeq, rxMapper, ::com::sun::star::sheet::FormulaMapGroup::FUNCTIONS ) )
+ {
+ const FormulaOpCodeMapEntry* pEntry = orEntrySeq.getConstArray();
+ const FormulaOpCodeMapEntry* pEntryEnd = pEntry + orEntrySeq.getLength();
+ for( ; pEntry != pEntryEnd; ++pEntry )
+ ((pEntry->Token.OpCode == OPCODE_EXTERNAL) ? orExtFuncTokenMap : orIntFuncTokenMap)[ pEntry->Name ] = pEntry->Token;
+ }
+ return orEntrySeq.hasElements();
+}
+
+bool OpCodeProviderImpl::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( "OpCodeProviderImpl::initOpCode - opcode for special offset " ).
+ append( nSpecialId ).append( " not found" ).getStr() );
+ return false;
+}
+
+bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const OUString& rOdfName, const OUString& rOoxName )
+{
+ ApiTokenMap::const_iterator aIt = rTokenMap.find( rOdfName );
+ if( aIt != rTokenMap.end() )
+ {
+ ornOpCode = aIt->second.OpCode;
+ if( rOoxName.getLength() > 0 )
+ {
+ FormulaOpCodeMapEntry aEntry;
+ aEntry.Name = rOoxName;
+ aEntry.Token.OpCode = ornOpCode;
+ maParserMap.push_back( aEntry );
+ }
+ return true;
+ }
+ OSL_ENSURE( false,
+ OStringBuffer( "OpCodeProviderImpl::initOpCode - opcode for \"" ).
+ append( OUStringToOString( rOdfName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( "\" not found" ).getStr() );
+ return false;
+}
+
+bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName )
+{
+ OUString aOoxName;
+ if( pcOoxName ) aOoxName = OUString::createFromAscii( pcOoxName );
+ return initOpCode( ornOpCode, rTokenMap, OUString::createFromAscii( pcOdfName ), aOoxName );
+}
+
+bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, sal_Unicode cOdfName, sal_Unicode cOoxName )
+{
+ OUString aOoxName;
+ if( cOoxName ) aOoxName = OUString( cOoxName );
+ return initOpCode( ornOpCode, rTokenMap, OUString( cOdfName ), aOoxName );
+}
+
+bool OpCodeProviderImpl::initFuncOpCode( FunctionInfo& orFuncInfo, const ApiTokenMap& rFuncTokenMap )
+{
+ bool bIsValid = false;
+ if( orFuncInfo.maOdfFuncName.getLength() > 0 )
+ {
+ ApiTokenMap::const_iterator aIt = rFuncTokenMap.find( orFuncInfo.maOdfFuncName );
+ if( aIt != rFuncTokenMap.end() )
+ {
+ orFuncInfo.mnApiOpCode = aIt->second.OpCode;
+ bIsValid =
+ (orFuncInfo.mnApiOpCode >= 0) &&
+ (orFuncInfo.mnApiOpCode != OPCODE_UNKNOWN) &&
+ (orFuncInfo.mnApiOpCode != OPCODE_NONAME);
+ OSL_ENSURE( bIsValid,
+ OStringBuffer( "OpCodeProviderImpl::initFuncOpCode - no valid opcode for ODF function \"" ).
+ append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( '"' ).getStr() );
+
+ if( bIsValid && (orFuncInfo.mnApiOpCode == OPCODE_EXTERNAL) )
+ {
+ bIsValid = (aIt->second.Data >>= orFuncInfo.maExtProgName) && (orFuncInfo.maExtProgName.getLength() > 0);
+ OSL_ENSURE( bIsValid,
+ OStringBuffer( "OpCodeProviderImpl::initFuncOpCode - no programmatical name for external function \"" ).
+ append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( '"' ).getStr() );
+ }
+
+ // add to parser map, if OOXML function name exists
+ if( bIsValid && (orFuncInfo.maOoxFuncName.getLength() > 0) )
+ {
+ // create the parser map entry
+ FormulaOpCodeMapEntry aEntry;
+ aEntry.Name = orFuncInfo.maOoxFuncName;
+ aEntry.Token = aIt->second;
+ maParserMap.push_back( aEntry );
+ }
+ }
+ else
+ {
+ // ignore entries for functions unknown by Calc *and* by Excel
+ bIsValid = orFuncInfo.maOoxFuncName.getLength() == 0;
+ }
+ }
+ else if( orFuncInfo.mnBiffFuncId == BIFF_FUNC_EXTERNCALL )
+ {
+ orFuncInfo.mnApiOpCode = OPCODE_EXTERNAL;
+ bIsValid = true;
+ }
+ else if( orFuncInfo.maOoxFuncName.getLength() > 0 )
+ {
+ orFuncInfo.mnApiOpCode = OPCODE_BAD;
+ bIsValid = true;
+ }
+
+ if( !bIsValid || (orFuncInfo.mnApiOpCode == OPCODE_UNKNOWN) || (orFuncInfo.mnApiOpCode < 0) )
+ orFuncInfo.mnApiOpCode = OPCODE_NONAME;
+ return bIsValid;
+}
+
+bool OpCodeProviderImpl::initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, const ApiTokenMap& rExtFuncTokenMap, const FunctionInfoVector& rFuncInfos )
+{
+ bool bIsValid = true;
+ for( FunctionInfoVector::const_iterator aIt = rFuncInfos.begin(), aEnd = rFuncInfos.end(); aIt != aEnd; ++aIt )
+ {
+ FunctionInfoRef xFuncInfo = *aIt;
+ // set API opcode from ODF function name
+ bIsValid &= initFuncOpCode( *xFuncInfo, xFuncInfo->mbExternal ? rExtFuncTokenMap : rIntFuncTokenMap );
+ // insert the function info into the maps
+ if( xFuncInfo->mnApiOpCode != OPCODE_NONAME )
+ {
+ if( (xFuncInfo->mnApiOpCode == OPCODE_EXTERNAL) && (xFuncInfo->maExtProgName.getLength() > 0) )
+ maExtProgFuncs[ xFuncInfo->maExtProgName ] = xFuncInfo;
+ else
+ maOpCodeFuncs[ xFuncInfo->mnApiOpCode ] = xFuncInfo;
+ }
+ }
+ return bIsValid;
+}
+
+// ----------------------------------------------------------------------------
+
+OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxFactory,
+ FilterType eFilter, BiffType eBiff, bool bImportFilter ) :
+ FunctionProvider( eFilter, eBiff, bImportFilter ),
+ mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxFactory ) )
+{
+}
+
+OpCodeProvider::~OpCodeProvider()
+{
+}
+
+const ApiOpCodes& OpCodeProvider::getOpCodes() const
+{
+ return *mxOpCodeImpl;
+}
+
+const FunctionInfo* OpCodeProvider::getFuncInfoFromApiToken( const ApiToken& rToken ) const
+{
+ const FunctionInfo* pFuncInfo = 0;
+ if( (rToken.OpCode == mxOpCodeImpl->OPCODE_EXTERNAL) && rToken.Data.has< OUString >() )
+ pFuncInfo = mxOpCodeImpl->maExtProgFuncs.get( rToken.Data.get< OUString >() ).get();
+ else if( (rToken.OpCode == mxOpCodeImpl->OPCODE_MACRO) && rToken.Data.has< OUString >() )
+ pFuncInfo = getFuncInfoFromMacroName( rToken.Data.get< OUString >() );
+ else if( (rToken.OpCode == mxOpCodeImpl->OPCODE_BAD) && rToken.Data.has< OUString >() )
+ pFuncInfo = getFuncInfoFromOoxFuncName( rToken.Data.get< OUString >() );
+ else
+ pFuncInfo = mxOpCodeImpl->maOpCodeFuncs.get( rToken.OpCode ).get();
+ return pFuncInfo;
+}
+
+Sequence< FormulaOpCodeMapEntry > OpCodeProvider::getOoxParserMap() const
+{
+ return ContainerHelper::vectorToSequence( mxOpCodeImpl->maParserMap );
+}
+
+// API formula parser wrapper =================================================
+
+ApiParserWrapper::ApiParserWrapper(
+ const Reference< XMultiServiceFactory >& rxFactory, const OpCodeProvider& rOpCodeProv ) :
+ OpCodeProvider( rOpCodeProv )
+{
+ if( rxFactory.is() ) try
+ {
+ mxParser.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( mxParser.is(), "ApiParserWrapper::ApiParserWrapper - cannot create API formula parser object" );
+ maParserProps.set( mxParser );
+ maParserProps.setProperty( PROP_CompileEnglish, true );
+ maParserProps.setProperty( PROP_FormulaConvention, ::com::sun::star::sheet::AddressConvention::XL_OOX );
+ maParserProps.setProperty( PROP_IgnoreLeadingSpaces, false );
+ maParserProps.setProperty( PROP_OpCodeMap, getOoxParserMap() );
+}
+
+ApiTokenSequence ApiParserWrapper::parseFormula( const OUString& rFormula, const CellAddress& rRefPos )
+{
+ ApiTokenSequence aTokenSeq;
+ if( mxParser.is() ) try
+ {
+ aTokenSeq = mxParser->parseFormula( rFormula, rRefPos );
+ }
+ catch( Exception& )
+ {
+ }
+ return aTokenSeq;
+}
+
+// formula contexts ===========================================================
+
+FormulaContext::FormulaContext( bool bRelativeAsOffset, bool b2dRefsAs3dRefs, bool bAllowNulChars ) :
+ maBaseAddress( 0, 0, 0 ),
+ mbRelativeAsOffset( bRelativeAsOffset ),
+ mb2dRefsAs3dRefs( b2dRefsAs3dRefs ),
+ mbAllowNulChars( bAllowNulChars )
+{
+}
+
+FormulaContext::~FormulaContext()
+{
+}
+
+void FormulaContext::setSharedFormula( const CellAddress& )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+TokensFormulaContext::TokensFormulaContext( bool bRelativeAsOffset, bool b2dRefsAs3dRefs, bool bAllowNulChars ) :
+ FormulaContext( bRelativeAsOffset, b2dRefsAs3dRefs, bAllowNulChars )
+{
+}
+
+void TokensFormulaContext::setTokens( const ApiTokenSequence& rTokens )
+{
+ maTokens = rTokens;
+}
+
+// ----------------------------------------------------------------------------
+
+SimpleFormulaContext::SimpleFormulaContext( const Reference< XFormulaTokens >& rxTokens,
+ bool bRelativeAsOffset, bool b2dRefsAs3dRefs, bool bAllowNulChars ) :
+ FormulaContext( bRelativeAsOffset, b2dRefsAs3dRefs, bAllowNulChars ),
+ mxTokens( rxTokens )
+{
+ OSL_ENSURE( mxTokens.is(), "SimpleFormulaContext::SimpleFormulaContext - missing XFormulaTokens interface" );
+}
+
+void SimpleFormulaContext::setTokens( const ApiTokenSequence& rTokens )
+{
+ mxTokens->setTokens( rTokens );
+}
+
+// formula parser/printer base class for filters ==============================
+
+namespace {
+
+bool lclConvertToCellAddress( CellAddress& orAddress, const SingleReference& rSingleRef, sal_Int32 nForbiddenFlags, sal_Int32 nFilterBySheet )
+{
+ orAddress = CellAddress( static_cast< sal_Int16 >( rSingleRef.Sheet ),
+ rSingleRef.Column, rSingleRef.Row );
+ return
+ !getFlag( rSingleRef.Flags, nForbiddenFlags ) &&
+ ((nFilterBySheet < 0) || (nFilterBySheet == rSingleRef.Sheet));
+}
+
+bool lclConvertToCellRange( CellRangeAddress& orRange, const ComplexReference& rComplexRef, sal_Int32 nForbiddenFlags, sal_Int32 nFilterBySheet )
+{
+ orRange = CellRangeAddress( static_cast< sal_Int16 >( rComplexRef.Reference1.Sheet ),
+ rComplexRef.Reference1.Column, rComplexRef.Reference1.Row,
+ rComplexRef.Reference2.Column, rComplexRef.Reference2.Row );
+ return
+ !getFlag( rComplexRef.Reference1.Flags, nForbiddenFlags ) &&
+ !getFlag( rComplexRef.Reference2.Flags, nForbiddenFlags ) &&
+ (rComplexRef.Reference1.Sheet == rComplexRef.Reference2.Sheet) &&
+ ((nFilterBySheet < 0) || (nFilterBySheet == rComplexRef.Reference1.Sheet));
+}
+
+enum TokenToRangeListState { STATE_REF, STATE_SEP, STATE_OPEN, STATE_CLOSE, STATE_ERROR };
+
+TokenToRangeListState lclProcessRef( ApiCellRangeList& orRanges, const Any& rData, bool bAllowRelative, sal_Int32 nFilterBySheet )
+{
+ using namespace ::com::sun::star::sheet::ReferenceFlags;
+ const sal_Int32 FORBIDDEN_FLAGS_DEL = COLUMN_DELETED | ROW_DELETED | SHEET_DELETED;
+ const sal_Int32 FORBIDDEN_FLAGS_REL = FORBIDDEN_FLAGS_DEL | COLUMN_RELATIVE | ROW_RELATIVE | SHEET_RELATIVE | RELATIVE_NAME;
+
+ sal_Int32 nForbiddenFlags = bAllowRelative ? FORBIDDEN_FLAGS_DEL : FORBIDDEN_FLAGS_REL;
+ SingleReference aSingleRef;
+ if( rData >>= aSingleRef )
+ {
+ CellAddress aAddress;
+ // ignore invalid addresses (with #REF! errors), but do not stop parsing
+ if( lclConvertToCellAddress( aAddress, aSingleRef, nForbiddenFlags, nFilterBySheet ) )
+ 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 do not stop parsing
+ if( lclConvertToCellRange( aRange, aComplexRef, nForbiddenFlags, nFilterBySheet ) )
+ 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 ) :
+ OpCodeProvider( rHelper.getDocumentFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ),
+ ApiOpCodes( getOpCodes() ),
+ WorkbookHelper( 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();
+}
+
+// ----------------------------------------------------------------------------
+
+OUString FormulaProcessorBase::generateApiAddressString( const CellAddress& rAddress ) const
+{
+ OUString aCellName;
+ PropertySet aCellProp( getCellFromDoc( rAddress ) );
+ aCellProp.getProperty( aCellName, PROP_AbsoluteName );
+ OSL_ENSURE( aCellName.getLength() > 0, "FormulaProcessorBase::generateApiAddressString - cannot create cell address string" );
+ return aCellName;
+}
+
+OUString FormulaProcessorBase::generateApiRangeString( const CellRangeAddress& rRange ) const
+{
+ OUString aRangeName;
+ PropertySet aRangeProp( getCellRangeFromDoc( rRange ) );
+ aRangeProp.getProperty( aRangeName, PROP_AbsoluteName );
+ OSL_ENSURE( aRangeName.getLength() > 0, "FormulaProcessorBase::generateApiRangeString - cannot create cell range string" );
+ return aRangeName;
+}
+
+OUString FormulaProcessorBase::generateApiRangeListString( const ApiCellRangeList& rRanges ) const
+{
+ OUStringBuffer aBuffer;
+ for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt )
+ {
+ OUString aRangeName = generateApiRangeString( *aIt );
+ if( aRangeName.getLength() > 0 )
+ {
+ if( aBuffer.getLength() > 0 )
+ aBuffer.append( API_TOKEN_SEP );
+ aBuffer.append( aRangeName );
+ }
+ }
+ return aBuffer.makeStringAndClear();
+}
+
+OUString FormulaProcessorBase::generateApiString( const OUString& rString )
+{
+ OUString aRetString = rString;
+ sal_Int32 nQuotePos = aRetString.getLength();
+ while( (nQuotePos = aRetString.lastIndexOf( '"', nQuotePos )) >= 0 )
+ aRetString = aRetString.replaceAt( nQuotePos, 1, CREATE_OUSTRING( "\"\"" ) );
+ return OUStringBuffer().append( sal_Unicode( '"' ) ).append( aRetString ).append( sal_Unicode( '"' ) ).makeStringAndClear();
+}
+
+OUString FormulaProcessorBase::generateApiArray( const Matrix< Any >& rMatrix )
+{
+ OSL_ENSURE( !rMatrix.empty(), "FormulaProcessorBase::generateApiArray - missing matrix values" );
+ OUStringBuffer aBuffer;
+ aBuffer.append( API_TOKEN_ARRAY_OPEN );
+ for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow )
+ {
+ if( nRow > 0 )
+ aBuffer.append( API_TOKEN_ARRAY_ROWSEP );
+ for( Matrix< Any >::const_iterator aBeg = rMatrix.row_begin( nRow ), aIt = aBeg, aEnd = rMatrix.row_end( nRow ); aIt != aEnd; ++aIt )
+ {
+ double fValue = 0.0;
+ OUString aString;
+ if( aIt != aBeg )
+ aBuffer.append( API_TOKEN_ARRAY_COLSEP );
+ if( *aIt >>= fValue )
+ aBuffer.append( fValue );
+ else if( *aIt >>= aString )
+ aBuffer.append( generateApiString( aString ) );
+ else
+ aBuffer.appendAscii( "\"\"" );
+ }
+ }
+ aBuffer.append( API_TOKEN_ARRAY_CLOSE );
+ return aBuffer.makeStringAndClear();
+}
+
+// ----------------------------------------------------------------------------
+
+Any FormulaProcessorBase::extractReference( const ApiTokenSequence& rTokens ) const
+{
+ ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true );
+ if( aTokenIt.is() && (aTokenIt->OpCode == OPCODE_PUSH) )
+ {
+ Any aRefAny = aTokenIt->Data;
+ if( !(++aTokenIt).is() && (aRefAny.has< SingleReference >() || aRefAny.has< ComplexReference >()) )
+ return aRefAny;
+ }
+ return Any();
+}
+
+bool FormulaProcessorBase::extractCellAddress( CellAddress& orAddress,
+ const ApiTokenSequence& rTokens, bool bAllowRelative ) const
+{
+ CellRangeAddress aRange;
+ if( extractCellRange( aRange, rTokens, bAllowRelative ) && (aRange.StartColumn == aRange.EndColumn) && (aRange.StartRow == aRange.EndRow) )
+ {
+ orAddress.Sheet = aRange.Sheet;
+ orAddress.Column = aRange.StartColumn;
+ orAddress.Row = aRange.StartRow;
+ return true;
+ }
+ return false;
+}
+
+bool FormulaProcessorBase::extractCellRange( CellRangeAddress& orRange,
+ const ApiTokenSequence& rTokens, bool bAllowRelative ) const
+{
+ ApiCellRangeList aRanges;
+ lclProcessRef( aRanges, extractReference( rTokens ), bAllowRelative, -1 );
+ if( !aRanges.empty() )
+ {
+ orRange = aRanges.front();
+ return true;
+ }
+ return false;
+}
+
+void FormulaProcessorBase::extractCellRangeList( ApiCellRangeList& orRanges,
+ const ApiTokenSequence& rTokens, bool bAllowRelative, sal_Int32 nFilterBySheet ) const
+{
+ orRanges.clear();
+ TokenToRangeListState eState = STATE_OPEN;
+ sal_Int32 nParenLevel = 0;
+ for( ApiTokenIterator aIt( rTokens, OPCODE_SPACES, true ); aIt.is() && (eState != STATE_ERROR); ++aIt )
+ {
+ sal_Int32 nOpCode = aIt->OpCode;
+ switch( eState )
+ {
+ // #i107275# accept OPCODE_SEP and OPCODE_LIST as separator token
+ case STATE_REF:
+ if( nOpCode == OPCODE_SEP ) eState = STATE_SEP;
+ else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
+ else eState = STATE_ERROR;
+ break;
+ case STATE_SEP:
+ if( nOpCode == OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet );
+ else if( nOpCode == OPCODE_SEP ) eState = STATE_SEP;
+ else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel );
+ else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
+ else eState = STATE_ERROR;
+ break;
+ case STATE_OPEN:
+ if( nOpCode == OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet );
+ else if( nOpCode == OPCODE_SEP ) eState = STATE_SEP;
+ else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel );
+ else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
+ else eState = STATE_ERROR;
+ break;
+ case STATE_CLOSE:
+ if( nOpCode == OPCODE_SEP ) eState = STATE_SEP;
+ else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP;
+ else if( nOpCode == 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, OPCODE_SPACES, true );
+ return aTokenIt.is() && (aTokenIt->OpCode == 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( OPCODE_SEP, Any() ) );
+ aNewTokens.push_back( ApiToken( 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..8b1f1b809d88
--- /dev/null
+++ b/oox/source/xls/formulaparser.cxx
@@ -0,0 +1,2917 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/formulaparser.hxx"
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/ComplexReference.hpp>
+#include <com/sun/star/sheet/ExternalReference.hpp>
+#include <com/sun/star/sheet/FormulaToken.hpp>
+#include <com/sun/star/sheet/ReferenceFlags.hpp>
+#include <com/sun/star/sheet/SingleReference.hpp>
+#include "oox/core/filterbase.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"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::sheet::ReferenceFlags;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+sal_uInt16 lclReadFmlaSize( BiffInputStream& rStrm, BiffType eBiff, const sal_uInt16* pnFmlaSize )
+{
+ return pnFmlaSize ? *pnFmlaSize : ((eBiff == BIFF2) ? rStrm.readuInt8() : rStrm.readuInt16());
+}
+
+} // namespace
+
+// formula finalizer ==========================================================
+
+FormulaFinalizer::FormulaFinalizer( const OpCodeProvider& rOpCodeProv ) :
+ OpCodeProvider( rOpCodeProv ),
+ ApiOpCodes( getOpCodes() )
+{
+ maTokens.reserve( 0x2000 );
+}
+
+ApiTokenSequence FormulaFinalizer::finalizeTokenArray( const ApiTokenSequence& rTokens )
+{
+ maTokens.clear();
+ if( rTokens.hasElements() )
+ {
+ const ApiToken* pToken = rTokens.getConstArray();
+ processTokens( pToken, pToken + rTokens.getLength() );
+ }
+ return ContainerHelper::vectorToSequence( maTokens );
+}
+
+const FunctionInfo* FormulaFinalizer::resolveBadFuncName( const OUString& ) const
+{
+ return 0;
+}
+
+OUString FormulaFinalizer::resolveDefinedName( sal_Int32 ) const
+{
+ return OUString();
+}
+
+const FunctionInfo* FormulaFinalizer::getFunctionInfo( ApiToken& orFuncToken )
+{
+ // first, try to find a regular function info from token op-code
+ if( const FunctionInfo* pRegFuncInfo = getFuncInfoFromApiToken( orFuncToken ) )
+ return pRegFuncInfo;
+
+ // try to recognize a function from an external library
+ if( (orFuncToken.OpCode == OPCODE_BAD) && orFuncToken.Data.has< OUString >() )
+ {
+ // virtual call to resolveBadFuncName()
+ if( const FunctionInfo* pLibFuncInfo = resolveBadFuncName( orFuncToken.Data.get< OUString >() ) )
+ {
+ // write function op-code to the OPCODE_BAD token
+ orFuncToken.OpCode = pLibFuncInfo->mnApiOpCode;
+ // if it is an external function, insert programmatic function name
+ if( (orFuncToken.OpCode == OPCODE_EXTERNAL) && (pLibFuncInfo->maExtProgName.getLength() > 0) )
+ orFuncToken.Data <<= pLibFuncInfo->maExtProgName;
+ else
+ orFuncToken.Data.clear(); // clear string from OPCODE_BAD
+ return pLibFuncInfo;
+ }
+ }
+
+ // no success - return null
+ return 0;
+
+}
+
+const FunctionInfo* FormulaFinalizer::getExternCallInfo( ApiToken& orFuncToken, const ApiToken& rECToken )
+{
+ // try to resolve the passed token to a supported sheet function
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromApiToken( rECToken ) )
+ {
+ orFuncToken.OpCode = pFuncInfo->mnApiOpCode;
+ // programmatic add-in function name
+ if( (pFuncInfo->mnApiOpCode == OPCODE_EXTERNAL) && (pFuncInfo->maExtProgName.getLength() > 0) )
+ orFuncToken.Data <<= pFuncInfo->maExtProgName;
+ // name of unsupported function, convert to OPCODE_BAD to preserve the name
+ else if( (pFuncInfo->mnApiOpCode == OPCODE_BAD) && (pFuncInfo->maOoxFuncName.getLength() > 0) )
+ orFuncToken.Data <<= pFuncInfo->maOoxFuncName;
+ return pFuncInfo;
+ }
+
+ // macro call or unknown function name, move data to function token
+ if( (rECToken.OpCode == OPCODE_MACRO) || (rECToken.OpCode == OPCODE_BAD) )
+ orFuncToken = rECToken;
+
+ // defined name used as function call, convert to OPCODE_BAD to preserve the name
+ if( (rECToken.OpCode == OPCODE_NAME) && rECToken.Data.has< sal_Int32 >() )
+ {
+ OUString aDefName = resolveDefinedName( rECToken.Data.get< sal_Int32 >() );
+ if( aDefName.getLength() > 0 )
+ {
+ orFuncToken.OpCode = OPCODE_BAD;
+ orFuncToken.Data <<= aDefName;
+ }
+ }
+
+ return 0;
+}
+
+void FormulaFinalizer::processTokens( const ApiToken* pToken, const ApiToken* pTokenEnd )
+{
+ while( pToken < pTokenEnd )
+ {
+ // push the current token into the vector
+ bool bValid = appendFinalToken( *pToken );
+ // try to process a function
+ if( const FunctionInfo* pFuncInfo = bValid ? getFunctionInfo( maTokens.back() ) : 0 )
+ pToken = processParameters( *pFuncInfo, pToken + 1, pTokenEnd );
+ // otherwise, go to next token
+ else
+ ++pToken;
+ }
+}
+
+const ApiToken* FormulaFinalizer::processParameters(
+ const FunctionInfo& rFuncInfo, const ApiToken* pToken, const ApiToken* pTokenEnd )
+{
+ // remember position of the token containing the function op-code
+ size_t nFuncNameIdx = maTokens.size() - 1;
+
+ // process a function, if an OPCODE_OPEN token is following
+ OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN), "FormulaFinalizer::processParameters - OPCODE_OPEN expected" );
+ if( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN) )
+ {
+ // append the OPCODE_OPEN token to the vector
+ maTokens.append( OPCODE_OPEN );
+
+ // store positions of OPCODE_OPEN, parameter separators, and OPCODE_CLOSE
+ ParameterPosVector aParams;
+ pToken = findParameters( aParams, pToken, pTokenEnd );
+ OSL_ENSURE( aParams.size() >= 2, "FormulaFinalizer::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 EXTERN.CALL functions. The actual function name is
+ contained as reference to a defined name in the first (hidden)
+ parameter. */
+ if( rFuncInfo.mnBiffFuncId == BIFF_FUNC_EXTERNCALL )
+ {
+ ApiToken& rFuncToken = maTokens[ nFuncNameIdx ];
+ rFuncToken.OpCode = OPCODE_NONAME;
+
+ // try to initialize function token from first parameter
+ if( const ApiToken* pECToken = getSingleToken( *aPosIt + 1, *(aPosIt + 1) ) )
+ if( const FunctionInfo* pECFuncInfo = getExternCallInfo( rFuncToken, *pECToken ) )
+ pRealFuncInfo = pECFuncInfo;
+
+ /* On success (something has been inserted into rFuncToken),
+ skip the first parameter. */
+ if( rFuncToken.OpCode != OPCODE_NONAME )
+ {
+ --nParamCount;
+ ++aPosIt;
+ }
+ }
+
+ // process all parameters
+ FunctionParamInfoIterator aParamInfoIt( *pRealFuncInfo );
+ size_t nLastValidSize = maTokens.size();
+ size_t nLastValidCount = 0;
+ for( size_t nParam = 0; nParam < nParamCount; ++nParam, ++aPosIt, ++aParamInfoIt )
+ {
+ // add embedded Calc-only parameters
+ if( aParamInfoIt.isCalcOnlyParam() )
+ {
+ appendCalcOnlyParameter( *pRealFuncInfo, nParam );
+ while( aParamInfoIt.isCalcOnlyParam() ) ++aParamInfoIt;
+ }
+
+ const ApiToken* pParamBegin = *aPosIt + 1;
+ const ApiToken* pParamEnd = *(aPosIt + 1);
+ bool bIsEmpty = isEmptyParameter( pParamBegin, pParamEnd );
+
+ if( !aParamInfoIt.isExcelOnlyParam() )
+ {
+ // replace empty second and third parameter in IF function with zeros
+ if( (pRealFuncInfo->mnBiff12FuncId == BIFF_FUNC_IF) && ((nParam == 1) || (nParam == 2)) && bIsEmpty )
+ {
+ maTokens.append< double >( OPCODE_PUSH, 0.0 );
+ bIsEmpty = false;
+ }
+ else
+ {
+ // process all tokens of the parameter
+ processTokens( pParamBegin, pParamEnd );
+ }
+ // append parameter separator token
+ maTokens.append( 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 = maTokens.size();
+ nLastValidCount = nParam + 1;
+ }
+ }
+
+ // #84453# remove trailing optional empty parameters
+ maTokens.resize( nLastValidSize );
+
+ // add trailing Calc-only parameters
+ if( aParamInfoIt.isCalcOnlyParam() )
+ appendCalcOnlyParameter( *pRealFuncInfo, nLastValidCount );
+
+ // add optional parameters that are required in Calc
+ appendRequiredParameters( *pRealFuncInfo, nLastValidCount );
+
+ // remove last parameter separator token
+ if( maTokens.back().OpCode == OPCODE_SEP )
+ maTokens.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 != OPCODE_BAD )
+ maTokens.append( OPCODE_CLOSE );
+ }
+
+ /* Replace OPCODE_EXTERNAL with OPCODE_NONAME to get #NAME! error in cell,
+ if no matching add-in function was found. */
+ ApiToken& rFuncNameToken = maTokens[ nFuncNameIdx ];
+ if( (rFuncNameToken.OpCode == OPCODE_EXTERNAL) && !rFuncNameToken.Data.hasValue() )
+ rFuncNameToken.OpCode = OPCODE_NONAME;
+
+ return pToken;
+}
+
+bool FormulaFinalizer::isEmptyParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
+ if( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_MISSING) ) ++pToken;
+ while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
+ return pToken == pTokenEnd;
+}
+
+const ApiToken* FormulaFinalizer::getSingleToken( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ const ApiToken* pSingleToken = 0;
+ // skip leading whitespace tokens
+ while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
+ // remember first non-whitespace token
+ if( pToken < pTokenEnd ) pSingleToken = pToken++;
+ // skip trailing whitespace tokens
+ while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
+ // return null, if other non-whitespace tokens follow
+ return (pToken == pTokenEnd) ? pSingleToken : 0;
+}
+
+const ApiToken* FormulaFinalizer::skipParentheses( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ // skip tokens between OPCODE_OPEN and OPCODE_CLOSE
+ OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN), "skipParentheses - OPCODE_OPEN expected" );
+ ++pToken;
+ while( (pToken < pTokenEnd) && (pToken->OpCode != OPCODE_CLOSE) )
+ {
+ if( pToken->OpCode == OPCODE_OPEN )
+ pToken = skipParentheses( pToken, pTokenEnd );
+ else
+ ++pToken;
+ }
+ // skip the OPCODE_CLOSE token
+ OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode == OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode == OPCODE_BAD), "skipParentheses - OPCODE_CLOSE expected" );
+ return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
+}
+
+const ApiToken* FormulaFinalizer::findParameters( ParameterPosVector& rParams,
+ const ApiToken* pToken, const ApiToken* pTokenEnd ) const
+{
+ // push position of OPCODE_OPEN
+ OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN), "FormulaFinalizer::findParameters - OPCODE_OPEN expected" );
+ rParams.push_back( pToken++ );
+
+ // find positions of parameter separators
+ while( (pToken < pTokenEnd) && (pToken->OpCode != OPCODE_CLOSE) )
+ {
+ if( pToken->OpCode == OPCODE_OPEN )
+ pToken = skipParentheses( pToken, pTokenEnd );
+ else if( pToken->OpCode == OPCODE_SEP )
+ rParams.push_back( pToken++ );
+ else
+ ++pToken;
+ }
+
+ // push position of OPCODE_CLOSE
+ OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode == OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode == OPCODE_BAD), "FormulaFinalizer::findParameters - OPCODE_CLOSE expected" );
+ rParams.push_back( pToken );
+ return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
+}
+
+void FormulaFinalizer::appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam )
+{
+ (void)nParam; // prevent 'unused' warning
+ switch( rFuncInfo.mnBiff12FuncId )
+ {
+ case BIFF_FUNC_FLOOR:
+ case BIFF_FUNC_CEILING:
+ OSL_ENSURE( nParam == 2, "FormulaFinalizer::appendCalcOnlyParameter - unexpected parameter index" );
+ maTokens.append< double >( OPCODE_PUSH, 1.0 );
+ maTokens.append( OPCODE_SEP );
+ break;
+ }
+}
+
+void FormulaFinalizer::appendRequiredParameters( const FunctionInfo& rFuncInfo, size_t nParamCount )
+{
+ switch( rFuncInfo.mnBiff12FuncId )
+ {
+ case BIFF_FUNC_WEEKNUM:
+ if( nParamCount == 1 )
+ {
+ maTokens.append< double >( OPCODE_PUSH, 1.0 );
+ maTokens.append( OPCODE_SEP );
+ }
+ break;
+ }
+}
+
+bool FormulaFinalizer::appendFinalToken( const ApiToken& rToken )
+{
+ // replace OPCODE_MACRO without macro name with #NAME? error code
+ bool bValid = (rToken.OpCode != OPCODE_MACRO) || rToken.Data.hasValue();
+ if( bValid )
+ {
+ maTokens.push_back( rToken );
+ }
+ else
+ {
+ maTokens.append( OPCODE_ARRAY_OPEN );
+ maTokens.append( OPCODE_PUSH, BiffHelper::calcDoubleFromError( BIFF_ERR_NAME ) );
+ maTokens.append( OPCODE_ARRAY_CLOSE );
+ }
+ return bValid;
+}
+
+// parser implementation base =================================================
+
+class FormulaParserImpl : public FormulaFinalizer, public WorkbookHelper
+{
+public:
+ explicit FormulaParserImpl( const FormulaParser& rParent );
+
+ /** Converts an XML formula string. */
+ virtual void importOoxFormula(
+ FormulaContext& rContext,
+ const OUString& rFormulaString );
+
+ /** Imports and converts a BIFF12 token array from the passed stream. */
+ virtual void importBiff12Formula(
+ FormulaContext& rContext,
+ SequenceInputStream& rStrm );
+
+ /** Imports and converts a BIFF2-BIFF8 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 );
+
+ /** Tries to resolve the passed ref-id to an OLE target URL. */
+ OUString resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const;
+
+protected:
+ typedef ::std::pair< sal_Int32, bool > WhiteSpace;
+ typedef ::std::vector< WhiteSpace > WhiteSpaceVec;
+
+ /** 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();
+ static void appendSpaces( WhiteSpaceVec& orSpaces, sal_Int32 nCount, bool bLineFeed );
+ void appendLeadingSpaces( sal_Int32 nCount, bool bLineFeed );
+ void appendOpeningSpaces( sal_Int32 nCount, bool bLineFeed );
+ void appendClosingSpaces( sal_Int32 nCount, bool bLineFeed );
+
+ size_t getFormulaSize() const;
+ Any& appendRawToken( sal_Int32 nOpCode );
+ Any& insertRawToken( sal_Int32 nOpCode, size_t nIndexFromEnd );
+ size_t appendWhiteSpaceTokens( const WhiteSpaceVec* pSpaces );
+ size_t insertWhiteSpaceTokens( const WhiteSpaceVec* pSpaces, 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, const WhiteSpaceVec* pSpaces = 0 );
+ bool pushAnyOperandToken( const Any& rAny, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
+ template< typename Type >
+ bool pushValueOperandToken( const Type& rValue, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
+ template< typename Type >
+ inline bool pushValueOperandToken( const Type& rValue, const WhiteSpaceVec* pSpaces = 0 )
+ { return pushValueOperandToken( rValue, OPCODE_PUSH, pSpaces ); }
+ bool pushParenthesesOperandToken( const WhiteSpaceVec* pOpeningSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
+ bool pushUnaryPreOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
+ bool pushUnaryPostOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
+ bool pushBinaryOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
+ bool pushParenthesesOperatorToken( const WhiteSpaceVec* pOpeningSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
+ bool pushFunctionOperatorToken( sal_Int32 nOpCode, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
+ bool pushFunctionOperatorToken( const FunctionInfo& rFuncInfo, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
+
+ 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, OPCODE_PUSH ); }
+ bool pushBoolOperand( bool bValue );
+ bool pushErrorOperand( double fEncodedError );
+ bool pushBiffBoolOperand( sal_uInt8 nValue );
+ 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 );
+ template< typename Type >
+ bool pushReferenceOperand( const LinkSheetRange& rSheetRange, const Type& rApiRef );
+ 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 bPushBadToken );
+ bool pushDefinedNameOperand( const DefinedNameRef& rxDefName );
+ bool pushExternalFuncOperand( const FunctionInfo& rFuncInfo );
+ bool pushDdeLinkOperand( const OUString& rDdeServer, const OUString& rDdeTopic, const OUString& rDdeItem );
+ bool pushExternalNameOperand( const ExternalNameRef& rxExtName, const ExternalLink& rExtLink );
+
+ 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, bool bSameSheet ) 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, bool bSameSheet, 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;
+
+private:
+ // finalize token sequence ------------------------------------------------
+
+ virtual const FunctionInfo* resolveBadFuncName( const OUString& rTokenData ) const;
+ virtual ::rtl::OUString resolveDefinedName( sal_Int32 nTokenIndex ) const;
+
+protected:
+ 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< size_t > SizeTypeVector;
+
+ ApiTokenVector maTokenStorage; /// Raw unordered token storage.
+ SizeTypeVector maTokenIndexes; /// Indexes into maTokenStorage.
+ SizeTypeVector maOperandSizeStack; /// Stack with token sizes per operand.
+ WhiteSpaceVec maLeadingSpaces; /// List of whitespaces before next token.
+ WhiteSpaceVec maOpeningSpaces; /// List of whitespaces before opening parenthesis.
+ WhiteSpaceVec maClosingSpaces; /// List of whitespaces before closing parenthesis.
+ FormulaContext* mpContext; /// Current formula context.
+};
+
+// ----------------------------------------------------------------------------
+
+FormulaParserImpl::FormulaParserImpl( const FormulaParser& rParent ) :
+ FormulaFinalizer( rParent ),
+ WorkbookHelper( rParent ),
+ mnMaxApiCol( rParent.getAddressConverter().getMaxApiAddress().Column ),
+ mnMaxApiRow( rParent.getAddressConverter().getMaxApiAddress().Row ),
+ mnMaxXlsCol( rParent.getAddressConverter().getMaxXlsAddress().Column ),
+ mnMaxXlsRow( rParent.getAddressConverter().getMaxXlsAddress().Row ),
+ mpContext( 0 )
+{
+ // reserve enough space to make resize(), push_back() etc. cheap
+ maTokenStorage.reserve( 0x2000 );
+ maTokenIndexes.reserve( 0x2000 );
+ maOperandSizeStack.reserve( 256 );
+ maLeadingSpaces.reserve( 256 );
+ maOpeningSpaces.reserve( 256 );
+ maClosingSpaces.reserve( 256 );
+}
+
+void FormulaParserImpl::importOoxFormula( FormulaContext&, const OUString& )
+{
+ OSL_ENSURE( false, "FormulaParserImpl::importOoxFormula - not implemented" );
+}
+
+void FormulaParserImpl::importBiff12Formula( FormulaContext&, SequenceInputStream& )
+{
+ OSL_ENSURE( false, "FormulaParserImpl::importBiff12Formula - 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 );
+}
+
+OUString FormulaParserImpl::resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const
+{
+ const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId, bUseRefSheets ).get();
+ OSL_ENSURE( pExtLink && (pExtLink->getLinkType() == LINKTYPE_OLE), "FormulaParserImpl::resolveOleTarget - missing or wrong link" );
+ if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_OLE) )
+ return getBaseFilter().getAbsoluteUrl( pExtLink->getTargetUrl() );
+ return OUString();
+}
+
+void FormulaParserImpl::initializeImport( FormulaContext& rContext )
+{
+ maTokenStorage.clear();
+ maTokenIndexes.clear();
+ maOperandSizeStack.clear();
+ mpContext = &rContext;
+}
+
+void FormulaParserImpl::finalizeImport( const ApiTokenSequence& rTokens )
+{
+ ApiTokenSequence aFinalTokens = finalizeTokenArray( rTokens );
+ if( aFinalTokens.hasElements() )
+ mpContext->setTokens( aFinalTokens );
+}
+
+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()
+{
+ maLeadingSpaces.clear();
+ maOpeningSpaces.clear();
+ maClosingSpaces.clear();
+ return true;
+}
+
+void FormulaParserImpl::appendSpaces( WhiteSpaceVec& orSpaces, sal_Int32 nCount, bool bLineFeed )
+{
+ OSL_ENSURE( nCount >= 0, "FormulaParserImpl::appendSpaces - negative count" );
+ if( nCount > 0 )
+ orSpaces.push_back( WhiteSpace( nCount, bLineFeed ) );
+}
+
+void FormulaParserImpl::appendLeadingSpaces( sal_Int32 nCount, bool bLineFeed )
+{
+ appendSpaces( maLeadingSpaces, nCount, bLineFeed );
+}
+
+void FormulaParserImpl::appendOpeningSpaces( sal_Int32 nCount, bool bLineFeed )
+{
+ appendSpaces( maOpeningSpaces, nCount, bLineFeed );
+}
+
+void FormulaParserImpl::appendClosingSpaces( sal_Int32 nCount, bool bLineFeed )
+{
+ appendSpaces( maClosingSpaces, nCount, bLineFeed );
+}
+
+size_t FormulaParserImpl::getFormulaSize() const
+{
+ return maTokenIndexes.size();
+}
+
+Any& FormulaParserImpl::appendRawToken( sal_Int32 nOpCode )
+{
+ maTokenIndexes.push_back( maTokenStorage.size() );
+ return maTokenStorage.append( nOpCode );
+}
+
+Any& FormulaParserImpl::insertRawToken( sal_Int32 nOpCode, size_t nIndexFromEnd )
+{
+ maTokenIndexes.insert( maTokenIndexes.end() - nIndexFromEnd, maTokenStorage.size() );
+ return maTokenStorage.append( nOpCode );
+}
+
+size_t FormulaParserImpl::appendWhiteSpaceTokens( const WhiteSpaceVec* pSpaces )
+{
+ if( pSpaces && !pSpaces->empty() )
+ for( WhiteSpaceVec::const_iterator aIt = pSpaces->begin(), aEnd = pSpaces->end(); aIt != aEnd; ++aIt )
+ appendRawToken( OPCODE_SPACES ) <<= aIt->first;
+ return pSpaces ? pSpaces->size() : 0;
+}
+
+size_t FormulaParserImpl::insertWhiteSpaceTokens( const WhiteSpaceVec* pSpaces, size_t nIndexFromEnd )
+{
+ if( pSpaces && !pSpaces->empty() )
+ for( WhiteSpaceVec::const_iterator aIt = pSpaces->begin(), aEnd = pSpaces->end(); aIt != aEnd; ++aIt )
+ insertRawToken( OPCODE_SPACES, nIndexFromEnd ) <<= aIt->first;
+ return pSpaces ? pSpaces->size() : 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, const WhiteSpaceVec* pSpaces )
+{
+ size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
+ appendRawToken( nOpCode );
+ pushOperandSize( nSpacesSize + 1 );
+ return true;
+}
+
+bool FormulaParserImpl::pushAnyOperandToken( const Any& rAny, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
+{
+ size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
+ appendRawToken( nOpCode ) = rAny;
+ pushOperandSize( nSpacesSize + 1 );
+ return true;
+}
+
+template< typename Type >
+bool FormulaParserImpl::pushValueOperandToken( const Type& rValue, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
+{
+ size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
+ appendRawToken( nOpCode ) <<= rValue;
+ pushOperandSize( nSpacesSize + 1 );
+ return true;
+}
+
+bool FormulaParserImpl::pushParenthesesOperandToken( const WhiteSpaceVec* pOpeningSpaces, const WhiteSpaceVec* pClosingSpaces )
+{
+ size_t nSpacesSize = appendWhiteSpaceTokens( pOpeningSpaces );
+ appendRawToken( OPCODE_OPEN );
+ nSpacesSize += appendWhiteSpaceTokens( pClosingSpaces );
+ appendRawToken( OPCODE_CLOSE );
+ pushOperandSize( nSpacesSize + 2 );
+ return true;
+}
+
+bool FormulaParserImpl::pushUnaryPreOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 1;
+ if( bOk )
+ {
+ size_t nOpSize = popOperandSize();
+ size_t nSpacesSize = insertWhiteSpaceTokens( pSpaces, nOpSize );
+ insertRawToken( nOpCode, nOpSize );
+ pushOperandSize( nOpSize + nSpacesSize + 1 );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushUnaryPostOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 1;
+ if( bOk )
+ {
+ size_t nOpSize = popOperandSize();
+ size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
+ appendRawToken( nOpCode );
+ pushOperandSize( nOpSize + nSpacesSize + 1 );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushBinaryOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 2;
+ if( bOk )
+ {
+ size_t nOp2Size = popOperandSize();
+ size_t nOp1Size = popOperandSize();
+ size_t nSpacesSize = insertWhiteSpaceTokens( pSpaces, nOp2Size );
+ insertRawToken( nOpCode, nOp2Size );
+ pushOperandSize( nOp1Size + nSpacesSize + 1 + nOp2Size );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushParenthesesOperatorToken( const WhiteSpaceVec* pOpeningSpaces, const WhiteSpaceVec* pClosingSpaces )
+{
+ bool bOk = maOperandSizeStack.size() >= 1;
+ if( bOk )
+ {
+ size_t nOpSize = popOperandSize();
+ size_t nSpacesSize = insertWhiteSpaceTokens( pOpeningSpaces, nOpSize );
+ insertRawToken( OPCODE_OPEN, nOpSize );
+ nSpacesSize += appendWhiteSpaceTokens( pClosingSpaces );
+ appendRawToken( OPCODE_CLOSE );
+ pushOperandSize( nOpSize + nSpacesSize + 2 );
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushFunctionOperatorToken( sal_Int32 nOpCode, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces, const WhiteSpaceVec* pClosingSpaces )
+{
+ /* #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( OPCODE_SEP );
+
+ // add function parentheses and function name
+ return bOk &&
+ ((nParamCount > 0) ? pushParenthesesOperatorToken( 0, pClosingSpaces ) : pushParenthesesOperandToken( 0, pClosingSpaces )) &&
+ pushUnaryPreOperatorToken( nOpCode, pLeadingSpaces );
+}
+
+bool FormulaParserImpl::pushFunctionOperatorToken( const FunctionInfo& rFuncInfo, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces, const WhiteSpaceVec* pClosingSpaces )
+{
+ bool bOk = pushFunctionOperatorToken( rFuncInfo.mnApiOpCode, nParamCount, pLeadingSpaces, pClosingSpaces );
+ if( bOk )
+ {
+ // create an external add-in call for the passed built-in function
+ if( (rFuncInfo.mnApiOpCode == OPCODE_EXTERNAL) && (rFuncInfo.maExtProgName.getLength() > 0) )
+ getOperandToken( 1, 0, 0 ).Data <<= rFuncInfo.maExtProgName;
+ // create a bad token with unsupported function name
+ else if( (rFuncInfo.mnApiOpCode == OPCODE_BAD) && (rFuncInfo.maOoxFuncName.getLength() > 0) )
+ getOperandToken( 1, 0, 0 ).Data <<= rFuncInfo.maOoxFuncName;
+ }
+ return bOk;
+}
+
+bool FormulaParserImpl::pushOperand( sal_Int32 nOpCode )
+{
+ return pushOperandToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushAnyOperand( const Any& rAny, sal_Int32 nOpCode )
+{
+ return pushAnyOperandToken( rAny, nOpCode, &maLeadingSpaces ) && resetSpaces();
+}
+
+template< typename Type >
+bool FormulaParserImpl::pushValueOperand( const Type& rValue, sal_Int32 nOpCode )
+{
+ return pushValueOperandToken( rValue, nOpCode, &maLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushBoolOperand( bool bValue )
+{
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( bValue ? BIFF_FUNC_TRUE : BIFF_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( OPCODE_ARRAY_OPEN );
+ size_t nOpSize = popOperandSize();
+ size_t nOldArraySize = maTokenIndexes.size();
+ // push a double containing the Calc error code
+ appendRawToken( OPCODE_PUSH ) <<= fEncodedError;
+ // close token array and set resulting operand size
+ appendRawToken( OPCODE_ARRAY_CLOSE );
+ pushOperandSize( nOpSize + maTokenIndexes.size() - nOldArraySize );
+ return true;
+}
+
+bool FormulaParserImpl::pushBiffBoolOperand( sal_uInt8 nValue )
+{
+ return pushBoolOperand( nValue != BIFF_TOK_BOOL_FALSE );
+}
+
+bool FormulaParserImpl::pushBiffErrorOperand( sal_uInt8 nErrorCode )
+{
+ return pushErrorOperand( BiffHelper::calcDoubleFromError( nErrorCode ) );
+}
+
+bool FormulaParserImpl::pushParenthesesOperand()
+{
+ return pushParenthesesOperandToken( &maOpeningSpaces, &maClosingSpaces ) && 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 );
+}
+
+template< typename Type >
+bool FormulaParserImpl::pushReferenceOperand( const LinkSheetRange& rSheetRange, const Type& rApiRef )
+{
+ if( rSheetRange.isExternal() )
+ {
+ ExternalReference aApiExtRef;
+ aApiExtRef.Index = rSheetRange.getDocLinkIndex();
+ aApiExtRef.Reference <<= rApiRef;
+ return pushValueOperand( aApiExtRef );
+ }
+ return pushValueOperand( rApiRef );
+}
+
+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 pushReferenceOperand( rSheetRange, aApiRef );
+ }
+ SingleReference aApiRef;
+ convertReference3d( aApiRef, rSheetRange.getFirstSheet(), rSheetRange.isSameSheet(), rRef, bDeleted, bRelativeAsOffset );
+ return pushReferenceOperand( rSheetRange, 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 pushReferenceOperand( rSheetRange, aApiRef );
+}
+
+bool FormulaParserImpl::pushNlrOperand( const BinSingleRef2d& rRef )
+{
+ SingleReference aApiRef;
+ convertReference2d( aApiRef, rRef, false, false );
+ return pushValueOperand( aApiRef, OPCODE_NLR );
+}
+
+bool FormulaParserImpl::pushEmbeddedRefOperand( const DefinedNameBase& rName, bool bPushBadToken )
+{
+ Any aRefAny = rName.getReference( mpContext->getBaseAddress() );
+ if( aRefAny.hasValue() )
+ return pushAnyOperand( aRefAny, OPCODE_PUSH );
+ if( bPushBadToken && (rName.getModelName().getLength() > 0) && (rName.getModelName()[ 0 ] >= ' ') )
+ return pushValueOperand( rName.getModelName(), OPCODE_BAD );
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool FormulaParserImpl::pushDefinedNameOperand( const DefinedNameRef& rxDefName )
+{
+ if( !rxDefName || (rxDefName->getModelName().getLength() == 0) )
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+ if( rxDefName->isMacroFunction() )
+ return pushValueOperand( rxDefName->getModelName(), OPCODE_MACRO );
+ if( rxDefName->getTokenIndex() >= 0 )
+ return pushValueOperand( rxDefName->getTokenIndex(), OPCODE_NAME );
+ return pushEmbeddedRefOperand( *rxDefName, true );
+}
+
+bool FormulaParserImpl::pushExternalFuncOperand( const FunctionInfo& rFuncInfo )
+{
+ return (rFuncInfo.mnApiOpCode == OPCODE_EXTERNAL) ?
+ pushValueOperand( rFuncInfo.maExtProgName, OPCODE_EXTERNAL ) :
+ pushOperand( rFuncInfo.mnApiOpCode );
+}
+
+bool FormulaParserImpl::pushDdeLinkOperand( const OUString& rDdeServer, const OUString& rDdeTopic, const OUString& rDdeItem )
+{
+ // create the function call DDE("server";"topic";"item")
+ return
+ pushValueOperandToken( rDdeServer ) &&
+ pushValueOperandToken( rDdeTopic ) &&
+ pushValueOperandToken( rDdeItem ) &&
+ pushFunctionOperator( OPCODE_DDE, 3 );
+}
+
+bool FormulaParserImpl::pushExternalNameOperand( const ExternalNameRef& rxExtName, const ExternalLink& rExtLink )
+{
+ if( rxExtName.get() ) switch( rExtLink.getLinkType() )
+ {
+ case LINKTYPE_INTERNAL:
+ case LINKTYPE_EXTERNAL:
+ return pushEmbeddedRefOperand( *rxExtName, false );
+
+ case LINKTYPE_ANALYSIS:
+ // TODO: need support for localized addin function names
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( rxExtName->getUpcaseModelName() ) )
+ return pushExternalFuncOperand( *pFuncInfo );
+ break;
+
+ case LINKTYPE_LIBRARY:
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( rxExtName->getUpcaseModelName() ) )
+ if( (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) && (pFuncInfo->meFuncLibType == rExtLink.getFuncLibraryType()) )
+ return pushExternalFuncOperand( *pFuncInfo );
+ break;
+
+ case LINKTYPE_DDE:
+ {
+ OUString aDdeServer, aDdeTopic, aDdeItem;
+ if( rxExtName->getDdeLinkData( aDdeServer, aDdeTopic, aDdeItem ) )
+ return pushDdeLinkOperand( aDdeServer, aDdeTopic, aDdeItem );
+ }
+ break;
+
+ default:
+ OSL_ENSURE( rExtLink.getLinkType() != LINKTYPE_SELF, "FormulaParserImpl::pushExternalNameOperand - invalid call" );
+ }
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool FormulaParserImpl::pushUnaryPreOperator( sal_Int32 nOpCode )
+{
+ return pushUnaryPreOperatorToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushUnaryPostOperator( sal_Int32 nOpCode )
+{
+ return pushUnaryPostOperatorToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushBinaryOperator( sal_Int32 nOpCode )
+{
+ return pushBinaryOperatorToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushParenthesesOperator()
+{
+ return pushParenthesesOperatorToken( &maOpeningSpaces, &maClosingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushFunctionOperator( sal_Int32 nOpCode, size_t nParamCount )
+{
+ return pushFunctionOperatorToken( nOpCode, nParamCount, &maLeadingSpaces, &maClosingSpaces ) && resetSpaces();
+}
+
+bool FormulaParserImpl::pushFunctionOperator( const FunctionInfo& rFuncInfo, size_t nParamCount )
+{
+ return pushFunctionOperatorToken( rFuncInfo, nParamCount, &maLeadingSpaces, &maClosingSpaces ) && resetSpaces();
+}
+
+// reference conversion -------------------------------------------------------
+
+void FormulaParserImpl::initReference2d( SingleReference& orApiRef ) const
+{
+ if( mpContext->is2dRefsAs3dRefs() )
+ {
+ initReference3d( orApiRef, mpContext->getBaseAddress().Sheet, false );
+ }
+ 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, bool bSameSheet ) const
+{
+ orApiRef.Flags = SHEET_3D;
+ if( nSheet < 0 )
+ {
+ orApiRef.Sheet = 0;
+ orApiRef.Flags |= SHEET_DELETED;
+ }
+ else if( bSameSheet )
+ {
+ OSL_ENSURE( nSheet == 0, "FormulaParserImpl::initReference3d - invalid sheet index" );
+ orApiRef.Flags |= SHEET_RELATIVE;
+ orApiRef.RelativeSheet = 0;
+ }
+ 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, bool bSameSheet, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ initReference3d( orApiRef, nSheet, bSameSheet );
+ convertReference( orApiRef, rRef, bDeleted, bRelativeAsOffset );
+}
+
+void FormulaParserImpl::convertReference3d( ComplexReference& orApiRef, const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const
+{
+ bool bSameSheet = rSheetRange.isSameSheet();
+ initReference3d( orApiRef.Reference1, rSheetRange.getFirstSheet(), bSameSheet );
+ initReference3d( orApiRef.Reference2, rSheetRange.getLastSheet(), bSameSheet );
+ 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 ----------------------------------------------------
+
+const FunctionInfo* FormulaParserImpl::resolveBadFuncName( const OUString& rTokenData ) const
+{
+ /* Try to parse calls to library functions. The format of such a function
+ call is "[n]!funcname", n>0 being the link identifier of the function
+ library spreadsheet file. */
+ sal_Int32 nBracketOpen = rTokenData.indexOf( '[' );
+ sal_Int32 nBracketClose = rTokenData.indexOf( ']' );
+ sal_Int32 nExclamation = rTokenData.indexOf( '!' );
+ if( (0 == nBracketOpen) && (nBracketOpen + 1 < nBracketClose) && (nBracketClose + 1 == nExclamation) && (nExclamation + 1 < rTokenData.getLength()) )
+ {
+ sal_Int32 nRefId = rTokenData.copy( nBracketOpen + 1, nBracketClose - nBracketOpen - 1 ).toInt32();
+ const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get();
+ if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_LIBRARY) )
+ {
+ OUString aFuncName = rTokenData.copy( nExclamation + 1 ).toAsciiUpperCase();
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( aFuncName ) )
+ if( (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) && (pFuncInfo->meFuncLibType == pExtLink->getFuncLibraryType()) )
+ return pFuncInfo;
+ }
+ }
+ return 0;
+}
+
+OUString FormulaParserImpl::resolveDefinedName( sal_Int32 nTokenIndex ) const
+{
+ if( const DefinedName* pDefName = getDefinedNames().getByTokenIndex( nTokenIndex ).get() )
+ return pDefName->getCalcName();
+ return OUString();
+}
+
+// OOXML/BIFF12 parser implementation =========================================
+
+class OoxFormulaParserImpl : public FormulaParserImpl
+{
+public:
+ explicit OoxFormulaParserImpl( const FormulaParser& rParent );
+
+ virtual void importOoxFormula(
+ FormulaContext& rContext,
+ const OUString& rFormulaString );
+
+ virtual void importBiff12Formula(
+ FormulaContext& rContext,
+ SequenceInputStream& rStrm );
+
+private:
+ // import token contents and create API formula token ---------------------
+
+ bool importAttrToken( SequenceInputStream& rStrm );
+ bool importSpaceToken( SequenceInputStream& rStrm );
+ bool importTableToken( SequenceInputStream& rStrm );
+ bool importArrayToken( SequenceInputStream& rStrm );
+ bool importRefToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importAreaToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importRef3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importArea3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
+ bool importMemAreaToken( SequenceInputStream& rStrm, bool bAddData );
+ bool importMemFuncToken( SequenceInputStream& rStrm );
+ bool importNameToken( SequenceInputStream& rStrm );
+ bool importNameXToken( SequenceInputStream& rStrm );
+ bool importFuncToken( SequenceInputStream& rStrm );
+ bool importFuncVarToken( SequenceInputStream& rStrm );
+ bool importExpToken( SequenceInputStream& rStrm );
+
+ LinkSheetRange readSheetRange( SequenceInputStream& rStrm );
+
+ void swapStreamPosition( SequenceInputStream& rStrm );
+ void skipMemAreaAddData( SequenceInputStream& rStrm );
+
+ // convert BIN token and push API operand or operator ---------------------
+
+ bool pushBiff12Name( sal_Int32 nNameId );
+ bool pushBiff12ExtName( sal_Int32 nRefId, sal_Int32 nNameId );
+ bool pushBiff12Function( sal_uInt16 nFuncId );
+ bool pushBiff12Function( sal_uInt16 nFuncId, sal_uInt8 nParamCount );
+
+private:
+ ApiParserWrapper maApiParser; /// Wrapper for the API formula parser object.
+ sal_Int64 mnAddDataPos; /// Current stream position for additional data (tExp, tArray, tMemArea).
+ bool mbNeedExtRefs; /// True = parser needs initialization of external reference info.
+};
+
+// ----------------------------------------------------------------------------
+
+OoxFormulaParserImpl::OoxFormulaParserImpl( const FormulaParser& rParent ) :
+ FormulaParserImpl( rParent ),
+ maApiParser( rParent.getDocumentFactory(), rParent ),
+ mnAddDataPos( 0 ),
+ mbNeedExtRefs( true )
+{
+}
+
+void OoxFormulaParserImpl::importOoxFormula( FormulaContext& rContext, const OUString& rFormulaString )
+{
+ if( mbNeedExtRefs )
+ {
+ maApiParser.getParserProperties().setProperty( PROP_ExternalLinks, getExternalLinks().getLinkInfos() );
+ mbNeedExtRefs = false;
+ }
+ initializeImport( rContext );
+ finalizeImport( maApiParser.parseFormula( rFormulaString, rContext.getBaseAddress() ) );
+}
+
+void OoxFormulaParserImpl::importBiff12Formula( FormulaContext& rContext, SequenceInputStream& rStrm )
+{
+ initializeImport( rContext );
+
+ sal_Int32 nFmlaSize = rStrm.readInt32();
+ sal_Int64 nFmlaPos = rStrm.tell();
+ sal_Int64 nFmlaEndPos = nFmlaPos + nFmlaSize;
+
+ rStrm.seek( nFmlaEndPos );
+ sal_Int32 nAddDataSize = rStrm.readInt32();
+ mnAddDataPos = rStrm.tell();
+ sal_Int64 nAddDataEndPos = mnAddDataPos + nAddDataSize;
+ rStrm.seek( nFmlaPos );
+
+ bool bOk = (nFmlaSize >= 0) && (nAddDataSize >= 0);
+ bool bRelativeAsOffset = getFormulaContext().isRelativeAsOffset();
+
+ while( bOk && !rStrm.isEof() && (rStrm.tell() < 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( OPCODE_ADD ); break;
+ case BIFF_TOKID_SUB: bOk = pushBinaryOperator( OPCODE_SUB ); break;
+ case BIFF_TOKID_MUL: bOk = pushBinaryOperator( OPCODE_MULT ); break;
+ case BIFF_TOKID_DIV: bOk = pushBinaryOperator( OPCODE_DIV ); break;
+ case BIFF_TOKID_POWER: bOk = pushBinaryOperator( OPCODE_POWER ); break;
+ case BIFF_TOKID_CONCAT: bOk = pushBinaryOperator( OPCODE_CONCAT ); break;
+ case BIFF_TOKID_LT: bOk = pushBinaryOperator( OPCODE_LESS ); break;
+ case BIFF_TOKID_LE: bOk = pushBinaryOperator( OPCODE_LESS_EQUAL ); break;
+ case BIFF_TOKID_EQ: bOk = pushBinaryOperator( OPCODE_EQUAL ); break;
+ case BIFF_TOKID_GE: bOk = pushBinaryOperator( OPCODE_GREATER_EQUAL ); break;
+ case BIFF_TOKID_GT: bOk = pushBinaryOperator( OPCODE_GREATER ); break;
+ case BIFF_TOKID_NE: bOk = pushBinaryOperator( OPCODE_NOT_EQUAL ); break;
+ case BIFF_TOKID_ISECT: bOk = pushBinaryOperator( OPCODE_INTERSECT ); break;
+ case BIFF_TOKID_LIST: bOk = pushBinaryOperator( OPCODE_LIST ); break;
+ case BIFF_TOKID_RANGE: bOk = pushBinaryOperator( OPCODE_RANGE ); break;
+ case BIFF_TOKID_UPLUS: bOk = pushUnaryPreOperator( OPCODE_PLUS_SIGN ); break;
+ case BIFF_TOKID_UMINUS: bOk = pushUnaryPreOperator( OPCODE_MINUS_SIGN ); break;
+ case BIFF_TOKID_PERCENT: bOk = pushUnaryPostOperator( OPCODE_PERCENT ); break;
+ case BIFF_TOKID_PAREN: bOk = pushParenthesesOperator(); break;
+ case BIFF_TOKID_MISSARG: bOk = pushOperand( OPCODE_MISSING ); break;
+ case BIFF_TOKID_STR: bOk = pushValueOperand( BiffHelper::readString( rStrm, 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 = pushBiffBoolOperand( rStrm.readuInt8() ); 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.tell() == 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( SequenceInputStream& rStrm )
+{
+ bool bOk = true;
+ sal_uInt8 nType;
+ rStrm >> nType;
+ // equal flags in all BIFFs
+ switch( nType )
+ {
+ case 0: // sometimes, tAttrSkip tokens miss the type flag
+ case BIFF_TOK_ATTR_VOLATILE:
+ case BIFF_TOK_ATTR_IF:
+ case BIFF_TOK_ATTR_SKIP:
+ case BIFF_TOK_ATTR_ASSIGN:
+ case BIFF_TOK_ATTR_IFERROR:
+ rStrm.skip( 2 );
+ break;
+ case BIFF_TOK_ATTR_CHOOSE:
+ rStrm.skip( 2 * rStrm.readuInt16() + 2 );
+ break;
+ case BIFF_TOK_ATTR_SUM:
+ rStrm.skip( 2 );
+ bOk = pushBiff12Function( BIFF_FUNC_SUM, 1 );
+ break;
+ case BIFF_TOK_ATTR_SPACE:
+ case BIFF_TOK_ATTR_SPACE_VOLATILE:
+ bOk = importSpaceToken( rStrm );
+ break;
+ default:
+ bOk = false;
+ }
+ return bOk;
+}
+
+bool OoxFormulaParserImpl::importSpaceToken( SequenceInputStream& rStrm )
+{
+ // equal constants in BIFF and OOX
+ sal_uInt8 nType, nCount;
+ rStrm >> nType >> nCount;
+ switch( nType )
+ {
+ case BIFF_TOK_ATTR_SPACE_SP:
+ appendLeadingSpaces( nCount, false );
+ break;
+ case BIFF_TOK_ATTR_SPACE_BR:
+ appendLeadingSpaces( nCount, true );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_OPEN:
+ appendOpeningSpaces( nCount, false );
+ break;
+ case BIFF_TOK_ATTR_SPACE_BR_OPEN:
+ appendOpeningSpaces( nCount, true );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_CLOSE:
+ appendClosingSpaces( nCount, false );
+ break;
+ case BIFF_TOK_ATTR_SPACE_BR_CLOSE:
+ appendClosingSpaces( nCount, true );
+ break;
+ }
+ return true;
+}
+
+bool OoxFormulaParserImpl::importTableToken( SequenceInputStream& 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, BIFF12_TOK_TABLE_COLUMN );
+ bool bColRange = getFlag( nFlags, BIFF12_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, BIFF12_TOK_TABLE_ALL );
+ bool bHeaderRows = getFlag( nFlags, BIFF12_TOK_TABLE_HEADERS );
+ bool bDataRows = getFlag( nFlags, BIFF12_TOK_TABLE_DATA );
+ bool bTotalsRows = getFlag( nFlags, BIFF12_TOK_TABLE_TOTALS );
+ bool bThisRow = getFlag( nFlags, BIFF12_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, OPCODE_DBAREA );
+ // create an OFFSET function call to refer to a subrange of the table
+ const FunctionInfo* pRowsInfo = getFuncInfoFromBiff12FuncId( BIFF_FUNC_ROWS );
+ const FunctionInfo* pColumnsInfo = getFuncInfoFromBiff12FuncId( BIFF_FUNC_COLUMNS );
+ return
+ pRowsInfo && pColumnsInfo &&
+ pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
+ (bFixedStartRow ?
+ pushValueOperandToken< double >( nStartRow ) :
+ (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
+ pushFunctionOperatorToken( *pRowsInfo, 1 ) &&
+ pushValueOperandToken< double >( nHeight - nStartRow ) &&
+ pushBinaryOperatorToken( OPCODE_SUB ))) &&
+ pushValueOperandToken< double >( nStartCol ) &&
+ (bFixedHeight ?
+ pushValueOperandToken< double >( nEndRow - nStartRow + 1 ) :
+ (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
+ pushFunctionOperatorToken( *pRowsInfo, 1 ) &&
+ (((nStartRow == 0) && (nEndRow + 1 == nHeight)) ||
+ (pushValueOperandToken< double >( nHeight - (nEndRow - nStartRow + 1) ) &&
+ pushBinaryOperatorToken( OPCODE_SUB ))))) &&
+ (((nStartCol == 0) && (nEndCol + 1 == nWidth)) ?
+ (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
+ pushFunctionOperatorToken( *pColumnsInfo, 1 )) :
+ pushValueOperandToken< double >( nEndCol - nStartCol + 1 )) &&
+ pushBiff12Function( BIFF_FUNC_OFFSET, 5 );
+ }
+ }
+ return pushBiffErrorOperand( BIFF_ERR_REF );
+}
+
+bool OoxFormulaParserImpl::importArrayToken( SequenceInputStream& rStrm )
+{
+ rStrm.skip( 14 );
+
+ // start token array with opening brace and leading spaces
+ pushOperand( 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.isEof() && (nRow < nRows); ++nRow )
+ {
+ if( nRow > 0 )
+ appendRawToken( OPCODE_ARRAY_ROWSEP );
+ for( sal_Int32 nCol = 0; !rStrm.isEof() && (nCol < nCols); ++nCol )
+ {
+ if( nCol > 0 )
+ appendRawToken( OPCODE_ARRAY_COLSEP );
+ switch( rStrm.readuInt8() )
+ {
+ case BIFF_TOK_ARRAY_DOUBLE:
+ appendRawToken( OPCODE_PUSH ) <<= rStrm.readDouble();
+ break;
+ case BIFF_TOK_ARRAY_STRING:
+ appendRawToken( OPCODE_PUSH ) <<= BiffHelper::readString( rStrm, false );
+ break;
+ case BIFF_TOK_ARRAY_BOOL:
+ appendRawToken( OPCODE_PUSH ) <<= static_cast< double >( (rStrm.readuInt8() == BIFF_TOK_BOOL_FALSE) ? 0.0 : 1.0 );
+ break;
+ case BIFF_TOK_ARRAY_ERROR:
+ appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( rStrm.readuInt8() );
+ rStrm.skip( 3 );
+ break;
+ default:
+ OSL_ENSURE( false, "OoxFormulaParserImpl::importArrayToken - unknown data type" );
+ appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( BIFF_ERR_NA );
+ }
+ }
+ }
+ swapStreamPosition( rStrm );
+
+ // close token array and set resulting operand size
+ appendRawToken( OPCODE_ARRAY_CLOSE );
+ pushOperandSize( nOpSize + getFormulaSize() - nOldArraySize );
+ return true;
+}
+
+bool OoxFormulaParserImpl::importRefToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinSingleRef2d aRef;
+ aRef.readBiff12Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importAreaToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ BinComplexRef2d aRef;
+ aRef.readBiff12Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importRef3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange( rStrm );
+ BinSingleRef2d aRef;
+ aRef.readBiff12Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importArea3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
+{
+ LinkSheetRange aSheetRange = readSheetRange( rStrm );
+ BinComplexRef2d aRef;
+ aRef.readBiff12Data( rStrm, bRelativeAsOffset );
+ return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
+}
+
+bool OoxFormulaParserImpl::importMemAreaToken( SequenceInputStream& rStrm, bool bAddData )
+{
+ rStrm.skip( 6 );
+ if( bAddData )
+ skipMemAreaAddData( rStrm );
+ return true;
+}
+
+bool OoxFormulaParserImpl::importMemFuncToken( SequenceInputStream& rStrm )
+{
+ rStrm.skip( 2 );
+ return true;
+}
+
+bool OoxFormulaParserImpl::importNameToken( SequenceInputStream& rStrm )
+{
+ return pushBiff12Name( rStrm.readInt32() );
+}
+
+bool OoxFormulaParserImpl::importNameXToken( SequenceInputStream& rStrm )
+{
+ sal_Int32 nRefId = rStrm.readInt16();
+ sal_Int32 nNameId = rStrm.readInt32();
+ return pushBiff12ExtName( nRefId, nNameId );
+}
+
+bool OoxFormulaParserImpl::importFuncToken( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFuncId;
+ rStrm >> nFuncId;
+ return pushBiff12Function( nFuncId );
+}
+
+bool OoxFormulaParserImpl::importFuncVarToken( SequenceInputStream& rStrm )
+{
+ sal_uInt8 nParamCount;
+ sal_uInt16 nFuncId;
+ rStrm >> nParamCount >> nFuncId;
+ return pushBiff12Function( nFuncId, nParamCount );
+}
+
+bool OoxFormulaParserImpl::importExpToken( SequenceInputStream& 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( SequenceInputStream& rStrm )
+{
+ return getExternalLinks().getSheetRange( rStrm.readInt16() );
+}
+
+void OoxFormulaParserImpl::swapStreamPosition( SequenceInputStream& rStrm )
+{
+ sal_Int64 nRecPos = rStrm.tell();
+ rStrm.seek( mnAddDataPos );
+ mnAddDataPos = nRecPos;
+}
+
+void OoxFormulaParserImpl::skipMemAreaAddData( SequenceInputStream& rStrm )
+{
+ swapStreamPosition( rStrm );
+ rStrm.skip( 16 * rStrm.readInt32() );
+ swapStreamPosition( rStrm );
+}
+
+// convert BIN token and push API operand or operator -------------------------
+
+bool OoxFormulaParserImpl::pushBiff12Name( sal_Int32 nNameId )
+{
+ // one-based in BIFF12 formulas
+ return pushDefinedNameOperand( getDefinedNames().getByIndex( nNameId - 1 ) );
+}
+
+bool OoxFormulaParserImpl::pushBiff12ExtName( sal_Int32 nRefId, sal_Int32 nNameId )
+{
+ if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
+ {
+ if( pExtLink->getLinkType() == LINKTYPE_SELF )
+ return pushBiff12Name( nNameId );
+ // external name indexes are one-based in BIFF12
+ ExternalNameRef xExtName = pExtLink->getNameByIndex( nNameId - 1 );
+ return pushExternalNameOperand( xExtName, *pExtLink );
+ }
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool OoxFormulaParserImpl::pushBiff12Function( sal_uInt16 nFuncId )
+{
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( nFuncId ) )
+ if( pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount )
+ return pushFunctionOperator( *pFuncInfo, pFuncInfo->mnMinParamCount );
+ return pushFunctionOperator( OPCODE_NONAME, 0 );
+}
+
+bool OoxFormulaParserImpl::pushBiff12Function( sal_uInt16 nFuncId, sal_uInt8 nParamCount )
+{
+ if( getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD ) )
+ nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( nFuncId ) )
+ return pushFunctionOperator( *pFuncInfo, nParamCount );
+ return pushFunctionOperator( 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 FormulaParser& rParent );
+
+ 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_Int64 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 FormulaParser& rParent ) :
+ FormulaParserImpl( rParent ),
+ 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 = lclReadFmlaSize( rStrm, getBiff(), pnFmlaSize );
+ sal_Int64 nEndPos = mnAddDataPos = rStrm.tell() + nFmlaSize;
+ bool bRelativeAsOffset = getFormulaContext().isRelativeAsOffset();
+
+ bool bOk = true;
+ while( bOk && !rStrm.isEof() && (rStrm.tell() < nEndPos) )
+ {
+ sal_uInt8 nTokenId;
+ rStrm >> nTokenId;
+ sal_uInt8 nTokenClass = nTokenId & BIFF_TOKCLASS_MASK;
+ sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
+
+ bOk = !getFlag( nTokenId, BIFF_TOKFLAG_INVALID );
+ if( bOk )
+ {
+ 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( OPCODE_ADD ); break;
+ case BIFF_TOKID_SUB: bOk = pushBinaryOperator( OPCODE_SUB ); break;
+ case BIFF_TOKID_MUL: bOk = pushBinaryOperator( OPCODE_MULT ); break;
+ case BIFF_TOKID_DIV: bOk = pushBinaryOperator( OPCODE_DIV ); break;
+ case BIFF_TOKID_POWER: bOk = pushBinaryOperator( OPCODE_POWER ); break;
+ case BIFF_TOKID_CONCAT: bOk = pushBinaryOperator( OPCODE_CONCAT ); break;
+ case BIFF_TOKID_LT: bOk = pushBinaryOperator( OPCODE_LESS ); break;
+ case BIFF_TOKID_LE: bOk = pushBinaryOperator( OPCODE_LESS_EQUAL ); break;
+ case BIFF_TOKID_EQ: bOk = pushBinaryOperator( OPCODE_EQUAL ); break;
+ case BIFF_TOKID_GE: bOk = pushBinaryOperator( OPCODE_GREATER_EQUAL ); break;
+ case BIFF_TOKID_GT: bOk = pushBinaryOperator( OPCODE_GREATER ); break;
+ case BIFF_TOKID_NE: bOk = pushBinaryOperator( OPCODE_NOT_EQUAL ); break;
+ case BIFF_TOKID_ISECT: bOk = pushBinaryOperator( OPCODE_INTERSECT ); break;
+ case BIFF_TOKID_LIST: bOk = pushBinaryOperator( OPCODE_LIST ); break;
+ case BIFF_TOKID_RANGE: bOk = pushBinaryOperator( OPCODE_RANGE ); break;
+ case BIFF_TOKID_UPLUS: bOk = pushUnaryPreOperator( OPCODE_PLUS_SIGN ); break;
+ case BIFF_TOKID_UMINUS: bOk = pushUnaryPreOperator( OPCODE_MINUS_SIGN ); break;
+ case BIFF_TOKID_PERCENT: bOk = pushUnaryPostOperator( OPCODE_PERCENT ); break;
+ case BIFF_TOKID_PAREN: bOk = pushParenthesesOperator(); break;
+ case BIFF_TOKID_MISSARG: bOk = pushOperand( 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 = pushBiffBoolOperand( rStrm.readuInt8() ); 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.tell() == 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.readByteStringUC( false, getTextEncoding(), getFormulaContext().isNulCharsAllowed() ) );
+}
+
+bool BiffFormulaParserImpl::importStrToken8( BiffInputStream& rStrm )
+{
+ // read flags field for empty strings also
+ return pushValueOperand( rStrm.readUniStringBody( rStrm.readuInt8(), getFormulaContext().isNulCharsAllowed() ) );
+}
+
+bool BiffFormulaParserImpl::importAttrToken( BiffInputStream& rStrm )
+{
+ bool bOk = true;
+ sal_uInt8 nType;
+ rStrm >> nType;
+ switch( nType )
+ {
+ case 0: // sometimes, tAttrSkip tokens miss the type flag
+ 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:
+ appendLeadingSpaces( nCount, false );
+ break;
+ case BIFF_TOK_ATTR_SPACE_BR:
+ appendLeadingSpaces( nCount, true );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_OPEN:
+ appendOpeningSpaces( nCount, false );
+ break;
+ case BIFF_TOK_ATTR_SPACE_BR_OPEN:
+ appendOpeningSpaces( nCount, true );
+ break;
+ case BIFF_TOK_ATTR_SPACE_SP_CLOSE:
+ appendClosingSpaces( nCount, false );
+ break;
+ case BIFF_TOK_ATTR_SPACE_BR_CLOSE:
+ appendClosingSpaces( nCount, true );
+ 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( OPCODE_ARRAY_OPEN );
+ size_t nOpSize = popOperandSize();
+ size_t nOldArraySize = getFormulaSize();
+ bool bBiff8 = getBiff() == BIFF8;
+ bool bNulChars = getFormulaContext().isNulCharsAllowed();
+
+ // 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.isEof() && (nRow < nRows); ++nRow )
+ {
+ if( nRow > 0 )
+ appendRawToken( OPCODE_ARRAY_ROWSEP );
+ for( sal_uInt16 nCol = 0; !rStrm.isEof() && (nCol < nCols); ++nCol )
+ {
+ if( nCol > 0 )
+ appendRawToken( OPCODE_ARRAY_COLSEP );
+ switch( rStrm.readuInt8() )
+ {
+ case BIFF_DATATYPE_EMPTY:
+ appendRawToken( OPCODE_PUSH ) <<= OUString();
+ rStrm.skip( 8 );
+ break;
+ case BIFF_DATATYPE_DOUBLE:
+ appendRawToken( OPCODE_PUSH ) <<= rStrm.readDouble();
+ break;
+ case BIFF_DATATYPE_STRING:
+ appendRawToken( OPCODE_PUSH ) <<= bBiff8 ?
+ rStrm.readUniString( bNulChars ) :
+ rStrm.readByteStringUC( false, getTextEncoding(), bNulChars );
+ break;
+ case BIFF_DATATYPE_BOOL:
+ appendRawToken( OPCODE_PUSH ) <<= static_cast< double >( (rStrm.readuInt8() == BIFF_TOK_BOOL_FALSE) ? 0.0 : 1.0 );
+ rStrm.skip( 7 );
+ break;
+ case BIFF_DATATYPE_ERROR:
+ appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( rStrm.readuInt8() );
+ rStrm.skip( 7 );
+ break;
+ default:
+ OSL_ENSURE( false, "BiffFormulaParserImpl::importArrayToken - unknown data type" );
+ appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( BIFF_ERR_NA );
+ }
+ }
+ }
+ swapStreamPosition( rStrm );
+
+ // close token array and set resulting operand size
+ appendRawToken( 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_Int64 nRecPos = rStrm.tell();
+ rStrm.seek( mnAddDataPos );
+ mnAddDataPos = nRecPos;
+}
+
+void BiffFormulaParserImpl::skipMemAreaAddData( BiffInputStream& rStrm )
+{
+ swapStreamPosition( rStrm );
+ sal_Int32 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_Int64 nEndPos = rStrm.tell() + 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.isEof() && 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 );
+ }
+ return pushBiffErrorOperand( BIFF_ERR_NAME );
+}
+
+bool BiffFormulaParserImpl::pushBiffFunction( sal_uInt16 nFuncId )
+{
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiffFuncId( nFuncId ) )
+ if( pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount )
+ return pushFunctionOperator( *pFuncInfo, pFuncInfo->mnMinParamCount );
+ return pushFunctionOperator( 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 = getFuncInfoFromBiffFuncId( nFuncId ) )
+ return pushFunctionOperator( *pFuncInfo, nParamCount );
+ return pushFunctionOperator( OPCODE_NONAME, nParamCount );
+}
+
+// ============================================================================
+
+namespace {
+
+/** Extracts the reference identifier and the remaining data from a formula in
+ the format '[RefID]Remaining'. */
+bool lclExtractRefId( sal_Int32& rnRefId, OUString& rRemainder, const OUString& rFormulaString )
+{
+ if( (rFormulaString.getLength() >= 4) && (rFormulaString[ 0 ] == '[') )
+ {
+ sal_Int32 nBracketClose = rFormulaString.indexOf( ']', 1 );
+ if( nBracketClose >= 2 )
+ {
+ rnRefId = rFormulaString.copy( 1, nBracketClose - 1 ).toInt32();
+ rRemainder = rFormulaString.copy( nBracketClose + 1 );
+ return rRemainder.getLength() > 0;
+ }
+ }
+ return false;
+}
+
+}
+
+// ----------------------------------------------------------------------------
+
+FormulaParser::FormulaParser( const WorkbookHelper& rHelper ) :
+ FormulaProcessorBase( rHelper )
+{
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML: mxImpl.reset( new OoxFormulaParserImpl( *this ) ); break;
+ case FILTER_BIFF: mxImpl.reset( new BiffFormulaParserImpl( *this ) ); 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, SequenceInputStream& rStrm ) const
+{
+ mxImpl->importBiff12Formula( 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 = OPCODE_ARRAY_OPEN;
+ aTokens[ 1 ].OpCode = OPCODE_PUSH;
+ aTokens[ 1 ].Data <<= BiffHelper::calcDoubleFromError( nErrorCode );
+ aTokens[ 2 ].OpCode = 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 = OPCODE_NAME;
+ aTokens[ 0 ].Data <<= nTokenIndex;
+ mxImpl->setFormula( rContext, aTokens );
+ }
+ else
+ convertErrorToFormula( rContext, BIFF_ERR_REF );
+}
+
+void FormulaParser::convertNumberToHyperlink( FormulaContext& rContext, const OUString& rUrl, double fValue ) const
+{
+ OSL_ENSURE( rUrl.getLength() > 0, "FormulaParser::convertNumberToHyperlink - missing URL" );
+ if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( BIFF_FUNC_HYPERLINK ) )
+ {
+ ApiTokenSequence aTokens( 6 );
+ aTokens[ 0 ].OpCode = pFuncInfo->mnApiOpCode;
+ aTokens[ 1 ].OpCode = OPCODE_OPEN;
+ aTokens[ 2 ].OpCode = OPCODE_PUSH;
+ aTokens[ 2 ].Data <<= rUrl;
+ aTokens[ 3 ].OpCode = OPCODE_SEP;
+ aTokens[ 4 ].OpCode = OPCODE_PUSH;
+ aTokens[ 4 ].Data <<= fValue;
+ aTokens[ 5 ].OpCode = OPCODE_CLOSE;
+ mxImpl->setFormula( rContext, aTokens );
+ }
+}
+
+OUString FormulaParser::importOleTargetLink( const OUString& rFormulaString )
+{
+ sal_Int32 nRefId = -1;
+ OUString aRemainder;
+ if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() >= 3) &&
+ (aRemainder[ 0 ] == '!') && (aRemainder[ 1 ] == '\'') && (aRemainder[ aRemainder.getLength() - 1 ] == '\'') )
+ return mxImpl->resolveOleTarget( nRefId, false );
+ return OUString();
+}
+
+OUString FormulaParser::importOleTargetLink( SequenceInputStream& rStrm )
+{
+ OUString aTargetLink;
+ sal_Int32 nFmlaSize = rStrm.readInt32();
+ sal_Int64 nFmlaEndPos = rStrm.tell() + ::std::max< sal_Int32 >( nFmlaSize, 0 );
+ if( (nFmlaSize == 7) && (rStrm.getRemaining() >= 7) )
+ {
+ sal_uInt8 nToken;
+ sal_Int16 nRefId;
+ sal_Int32 nNameId;
+ rStrm >> nToken >> nRefId >> nNameId;
+ if( nToken == (BIFF_TOKCLASS_VAL|BIFF_TOKID_NAMEX) )
+ aTargetLink = mxImpl->resolveOleTarget( nRefId, true );
+ }
+ rStrm.seek( nFmlaEndPos );
+ return aTargetLink;
+}
+
+OUString FormulaParser::importOleTargetLink( BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) const
+{
+ OUString aTargetLink;
+ sal_uInt16 nFmlaSize = lclReadFmlaSize( rStrm, getBiff(), pnFmlaSize );
+ rStrm.skip( nFmlaSize );
+ return aTargetLink;
+}
+
+OUString FormulaParser::importMacroName( const OUString& rFormulaString )
+{
+ /* Valid macros are either sheet macros or VBA macros. OOXML and all BIFF
+ documents store defined names for sheet macros, but OOXML documents do
+ not store any defined name for VBA macros (while BIFF documents do).
+ Sheet macros may be defined locally to a sheet, or globally to the
+ document. As a result, all of the following macro specifiers are valid:
+
+ 1) Macros located in the own document:
+ [0]!MySheetMacro (global sheet macro 'MySheetMacro')
+ Macro1!MyMacro (sheet-local sheet macro 'MyMacro')
+ [0]!MyVBAProc (VBA macro 'MyVBAProc')
+ [0]!Mod1.MyVBAProc (VBA macro 'MyVBAProc' from code module 'Mod1')
+
+ 2) Macros from an external document:
+ [2]!MySheetMacro (global external sheet macro 'MySheetMacro')
+ [2]Macro1!MyMacro (sheet-local external sheet macro 'MyMacro')
+ [2]!MyVBAProc (external VBA macro 'MyVBAProc')
+ [2]!Mod1.MyVBAProc (external VBA macro from code module 'Mod1')
+
+ This implementation is only interested in VBA macros from the own
+ document, ignoring the valid syntax 'Macro1!MyMacro' for sheet-local
+ sheet macros.
+ */
+ sal_Int32 nRefId = -1;
+ OUString aRemainder;
+ if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() > 1) && (aRemainder[ 0 ] == '!') )
+ {
+ /* In BIFF12 documents, the reference identifier is always the
+ one-based index of the external link as it is in OOXML documents
+ (it is not an index into the list of reference sheets as used in
+ cell formulas). Index 0 is an implicit placeholder for the own
+ document. In BIFF12 documents, the reference to the own document is
+ stored explicitly, mostly at the top of the list, so index 1 may
+ resolve to the own document too.
+ Passing 'false' to getExternalLink() specifies to ignore the
+ reference sheets list (if existing) and to access the list of
+ external links directly. */
+ const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId, false ).get();
+ OSL_ENSURE( pExtLink, "FormulaParser::importMacroName - missing link" );
+ // do not accept macros in external documents (not supported)
+ if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_SELF) )
+ {
+ // ignore sheet macros (defined name for VBA macros may not exist, see above)
+ OUString aMacroName = aRemainder.copy( 1 );
+ const DefinedName* pDefName = getDefinedNames().getByModelName( aMacroName ).get();
+ if( !pDefName || pDefName->isVBName() )
+ return aMacroName;
+ }
+ }
+ return OUString();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/makefile.mk b/oox/source/xls/makefile.mk
new file mode 100644
index 000000000000..6ca6e6a271b9
--- /dev/null
+++ b/oox/source/xls/makefile.mk
@@ -0,0 +1,103 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+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)$/autofilterbuffer.obj \
+ $(SLO)$/autofiltercontext.obj \
+ $(SLO)$/biffcodec.obj \
+ $(SLO)$/biffdetector.obj \
+ $(SLO)$/biffhelper.obj \
+ $(SLO)$/biffinputstream.obj \
+ $(SLO)$/biffoutputstream.obj \
+ $(SLO)$/chartsheetfragment.obj \
+ $(SLO)$/commentsbuffer.obj \
+ $(SLO)$/commentsfragment.obj \
+ $(SLO)$/condformatbuffer.obj \
+ $(SLO)$/condformatcontext.obj \
+ $(SLO)$/connectionsbuffer.obj \
+ $(SLO)$/connectionsfragment.obj \
+ $(SLO)$/defnamesbuffer.obj \
+ $(SLO)$/drawingfragment.obj \
+ $(SLO)$/excelchartconverter.obj \
+ $(SLO)$/excelfilter.obj \
+ $(SLO)$/excelhandlers.obj \
+ $(SLO)$/excelvbaproject.obj \
+ $(SLO)$/externallinkbuffer.obj \
+ $(SLO)$/externallinkfragment.obj \
+ $(SLO)$/formulabase.obj \
+ $(SLO)$/formulaparser.obj \
+ $(SLO)$/numberformatsbuffer.obj \
+ $(SLO)$/ooxformulaparser.obj \
+ $(SLO)$/pagesettings.obj \
+ $(SLO)$/pivotcachebuffer.obj \
+ $(SLO)$/pivotcachefragment.obj \
+ $(SLO)$/pivottablebuffer.obj \
+ $(SLO)$/pivottablefragment.obj \
+ $(SLO)$/querytablebuffer.obj \
+ $(SLO)$/querytablefragment.obj \
+ $(SLO)$/richstring.obj \
+ $(SLO)$/richstringcontext.obj \
+ $(SLO)$/scenariobuffer.obj \
+ $(SLO)$/scenariocontext.obj \
+ $(SLO)$/sharedformulabuffer.obj \
+ $(SLO)$/sharedstringsbuffer.obj \
+ $(SLO)$/sharedstringsfragment.obj \
+ $(SLO)$/sheetdatacontext.obj \
+ $(SLO)$/stylesbuffer.obj \
+ $(SLO)$/stylesfragment.obj \
+ $(SLO)$/tablebuffer.obj \
+ $(SLO)$/tablefragment.obj \
+ $(SLO)$/themebuffer.obj \
+ $(SLO)$/unitconverter.obj \
+ $(SLO)$/viewsettings.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..c77381b2a1c8
--- /dev/null
+++ b/oox/source/xls/numberformatsbuffer.cxx
@@ -0,0 +1,2116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/numberformatsbuffer.hxx"
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/i18n/NumberFormatIndex.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/XNumberFormats.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <rtl/strbuf.hxx>
+#include <rtl/string.hxx>
+#include <osl/thread.h>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OStringToOUString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+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
+};
+
+} // namespace
+
+// ============================================================================
+
+NumFmtModel::NumFmtModel() :
+ mnPredefId( -1 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ApiNumFmtData::ApiNumFmtData() :
+ mnIndex( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+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;
+}
+
+// ----------------------------------------------------------------------------
+
+/** Functor for converting an XML number format to an API number format index. */
+class NumberFormatFinalizer
+{
+public:
+ explicit NumberFormatFinalizer( 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;
+};
+
+NumberFormatFinalizer::NumberFormatFinalizer( 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(), "NumberFormatFinalizer::NumberFormatFinalizer - cannot get number formats" );
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+NumberFormat::NumberFormat( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void NumberFormat::setFormatCode( const OUString& rFmtCode )
+{
+ maModel.maFmtCode = rFmtCode;
+}
+
+void NumberFormat::setFormatCode( const Locale& rLocale, const sal_Char* pcFmtCode )
+{
+ maModel.maLocale = rLocale;
+ maModel.maFmtCode = OStringToOUString( OString( pcFmtCode ), RTL_TEXTENCODING_UTF8 );
+ maModel.mnPredefId = -1;
+}
+
+void NumberFormat::setPredefinedId( const Locale& rLocale, sal_Int16 nPredefId )
+{
+ maModel.maLocale = rLocale;
+ maModel.maFmtCode = OUString();
+ maModel.mnPredefId = nPredefId;
+}
+
+sal_Int32 NumberFormat::finalizeImport( const Reference< XNumberFormats >& rxNumFmts, const Locale& rFromLocale )
+{
+ if( rxNumFmts.is() && (maModel.maFmtCode.getLength() > 0) )
+ maApiData.mnIndex = lclCreateFormat( rxNumFmts, maModel.maFmtCode, maModel.maLocale, rFromLocale );
+ else
+ maApiData.mnIndex = lclCreatePredefinedFormat( rxNumFmts, maModel.mnPredefId, maModel.maLocale );
+ return maApiData.mnIndex;
+}
+
+void NumberFormat::writeToPropertyMap( PropertyMap& rPropMap ) const
+{
+ rPropMap[ PROP_NumberFormat ] <<= maApiData.mnIndex;
+}
+
+// ============================================================================
+
+NumberFormatsBuffer::NumberFormatsBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnNextBiffIndex( 0 )
+{
+ // get the current locale
+ try
+ {
+ Reference< XMultiServiceFactory > xConfigProv( getGlobalFactory()->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.getXString( XML_formatCode, OUString() );
+ return createNumFmt( nNumFmtId, aFmtCode );
+}
+
+void NumberFormatsBuffer::importNumFmt( SequenceInputStream& rStrm )
+{
+ sal_Int32 nNumFmtId = rStrm.readuInt16();
+ OUString aFmtCode = BiffHelper::readString( rStrm );
+ createNumFmt( nNumFmtId, aFmtCode );
+}
+
+void NumberFormatsBuffer::importFormat( BiffInputStream& rStrm )
+{
+ OUString aFmtCode;
+ switch( getBiff() )
+ {
+ case BIFF2:
+ case BIFF3:
+ aFmtCode = rStrm.readByteStringUC( false, getTextEncoding() );
+ break;
+ case BIFF4:
+ rStrm.skip( 2 ); // in BIFF4 the index field exists, but is undefined
+ aFmtCode = rStrm.readByteStringUC( false, getTextEncoding() );
+ break;
+ case BIFF5:
+ mnNextBiffIndex = rStrm.readuInt16();
+ aFmtCode = rStrm.readByteStringUC( 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( NumberFormatFinalizer( *this ) );
+}
+
+void NumberFormatsBuffer::writeToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const
+{
+ if( const NumberFormat* pNumFmt = maNumFmts.get( nNumFmtId ).get() )
+ pNumFmt->writeToPropertyMap( rPropMap );
+}
+
+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/ooxformulaparser.cxx b/oox/source/xls/ooxformulaparser.cxx
new file mode 100644
index 000000000000..efa69abcb750
--- /dev/null
+++ b/oox/source/xls/ooxformulaparser.cxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/ooxformulaparser.hxx"
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include "oox/xls/formulaparser.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+class OOXMLFormulaParserImpl : private FormulaFinalizer
+{
+public:
+ explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory );
+
+ Sequence< FormulaToken > parseFormula( const OUString& rFormula, const CellAddress& rReferencePos );
+
+protected:
+ virtual const FunctionInfo* resolveBadFuncName( const OUString& rTokenData ) const;
+
+private:
+ ApiParserWrapper maApiParser;
+};
+
+// ----------------------------------------------------------------------------
+
+OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory ) :
+ FormulaFinalizer( OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ),
+ maApiParser( rxFactory, *this )
+{
+}
+
+Sequence< FormulaToken > OOXMLFormulaParserImpl::parseFormula( const OUString& rFormula, const CellAddress& rReferencePos )
+{
+ return finalizeTokenArray( maApiParser.parseFormula( rFormula, rReferencePos ) );
+}
+
+const FunctionInfo* OOXMLFormulaParserImpl::resolveBadFuncName( const OUString& rTokenData ) const
+{
+ /* Try to parse calls to library functions. The format of such a function
+ call is assumed to be
+ "'<path-to-office-install>\Library\<libname>'!<funcname>". */
+
+ // the string has to start with an apostroph (followed by the library URL)
+ if( (rTokenData.getLength() >= 6) && (rTokenData[ 0 ] == '\'') )
+ {
+ // library URL and function name are separated by an exclamation mark
+ sal_Int32 nExclamPos = rTokenData.lastIndexOf( '!' );
+ if( (1 < nExclamPos) && (nExclamPos + 1 < rTokenData.getLength()) && (rTokenData[ nExclamPos - 1 ] == '\'') )
+ {
+ // find the last backslash that separates library path and name
+ sal_Int32 nFileSep = rTokenData.lastIndexOf( '\\', nExclamPos - 2 );
+ if( nFileSep > 1 )
+ {
+ // find preceding backslash that separates the last directory name
+ sal_Int32 nDirSep = rTokenData.lastIndexOf( '\\', nFileSep - 1 );
+ // function library is located in a directory called 'library'
+ if( (nDirSep > 0) && rTokenData.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "\\LIBRARY\\" ), nDirSep ) )
+ {
+ // try to find a function info for the function name
+ OUString aFuncName = rTokenData.copy( nExclamPos + 1 ).toAsciiUpperCase();
+ const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( aFuncName );
+ if( pFuncInfo && (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) )
+ {
+ // check that the name of the library matches
+ OUString aLibName = rTokenData.copy( nFileSep + 1, nExclamPos - nFileSep - 2 );
+ if( pFuncInfo->meFuncLibType == getFuncLibTypeFromLibraryName( aLibName ) )
+ return pFuncInfo;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+// ============================================================================
+
+class OOXMLFormulaPrinterImpl : public OpCodeProvider
+{
+public:
+ explicit OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory );
+
+private:
+ ApiParserWrapper maApiParser;
+};
+
+// ----------------------------------------------------------------------------
+
+OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory ) :
+ OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, false ),
+ maApiParser( rxFactory, *this )
+{
+}
+
+// ============================================================================
+
+Sequence< OUString > OOXMLFormulaParser_getSupportedServiceNames()
+{
+ Sequence< OUString > aServiceNames( 1 );
+ aServiceNames[ 0 ] = CREATE_OUSTRING( "com.sun.star.sheet.FilterFormulaParser" );
+ return aServiceNames;
+}
+
+OUString OOXMLFormulaParser_getImplementationName()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.FormulaParser" );
+}
+
+Reference< XInterface > SAL_CALL OOXMLFormulaParser_createInstance( const Reference< XComponentContext >& ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new OOXMLFormulaParser );
+}
+
+// ============================================================================
+
+OOXMLFormulaParser::OOXMLFormulaParser()
+{
+}
+
+OOXMLFormulaParser::~OOXMLFormulaParser()
+{
+}
+
+// com.sun.star.lang.XServiceInfo interface -----------------------------------
+
+OUString SAL_CALL OOXMLFormulaParser::getImplementationName() throw( RuntimeException )
+{
+ return OOXMLFormulaParser_getImplementationName();
+}
+
+sal_Bool SAL_CALL OOXMLFormulaParser::supportsService( const OUString& rService ) throw( RuntimeException )
+{
+ const Sequence< OUString > aServices( OOXMLFormulaParser_getSupportedServiceNames() );
+ const OUString* pArray = aServices.getConstArray();
+ const OUString* pArrayEnd = pArray + aServices.getLength();
+ return ::std::find( pArray, pArrayEnd, rService ) != pArrayEnd;
+}
+
+Sequence< OUString > SAL_CALL OOXMLFormulaParser::getSupportedServiceNames() throw( RuntimeException )
+{
+ return OOXMLFormulaParser_getSupportedServiceNames();
+}
+
+// com.sun.star.lang.XInitialization interface --------------------------------
+
+void SAL_CALL OOXMLFormulaParser::initialize( const Sequence< Any >& rArgs ) throw( Exception, RuntimeException )
+{
+ OSL_ENSURE( rArgs.hasElements(), "OOXMLFormulaParser::initialize - missing arguments" );
+ if( !rArgs.hasElements() )
+ throw RuntimeException();
+ mxComponent.set( rArgs[ 0 ], UNO_QUERY_THROW );
+}
+
+// com.sun.star.sheet.XFilterFormulaParser interface --------------------------
+
+OUString SAL_CALL OOXMLFormulaParser::getSupportedNamespace() throw( RuntimeException )
+{
+ return CREATE_OUSTRING( "http://schemas.microsoft.com/office/excel/formula" );
+}
+
+// com.sun.star.sheet.XFormulaParser interface --------------------------------
+
+Sequence< FormulaToken > SAL_CALL OOXMLFormulaParser::parseFormula(
+ const OUString& rFormula, const CellAddress& rReferencePos ) throw( RuntimeException )
+{
+ if( !mxParserImpl )
+ {
+ Reference< XMultiServiceFactory > xFactory( mxComponent, UNO_QUERY_THROW );
+ mxParserImpl.reset( new OOXMLFormulaParserImpl( xFactory ) );
+ }
+ return mxParserImpl->parseFormula( rFormula, rReferencePos );
+}
+
+OUString SAL_CALL OOXMLFormulaParser::printFormula(
+ const Sequence< FormulaToken >& /*rTokens*/, const CellAddress& /*rReferencePos*/ ) throw( RuntimeException )
+{
+ // not implemented
+ throw RuntimeException();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/pagesettings.cxx b/oox/source/xls/pagesettings.cxx
new file mode 100644
index 000000000000..188bf78544ec
--- /dev/null
+++ b/oox/source/xls/pagesettings.cxx
@@ -0,0 +1,1250 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/pagesettings.hxx"
+
+#include <algorithm>
+#include <set>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+#include <com/sun/star/style/GraphicLocation.hpp>
+#include <com/sun/star/text/FilenameDisplayFormat.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::Relations;
+using ::rtl::OString;
+using ::rtl::OStringBuffer;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+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 BIFF12_PRINTOPT_HORCENTER = 0x0001;
+const sal_uInt16 BIFF12_PRINTOPT_VERCENTER = 0x0002;
+const sal_uInt16 BIFF12_PRINTOPT_PRINTHEADING = 0x0004;
+const sal_uInt16 BIFF12_PRINTOPT_PRINTGRID = 0x0008;
+
+const sal_uInt16 BIFF12_HEADERFOOTER_DIFFEVEN = 0x0001;
+const sal_uInt16 BIFF12_HEADERFOOTER_DIFFFIRST = 0x0002;
+const sal_uInt16 BIFF12_HEADERFOOTER_SCALEDOC = 0x0004;
+const sal_uInt16 BIFF12_HEADERFOOTER_ALIGNMARGIN = 0x0008;
+
+const sal_uInt16 BIFF12_PAGESETUP_INROWS = 0x0001;
+const sal_uInt16 BIFF12_PAGESETUP_LANDSCAPE = 0x0002;
+const sal_uInt16 BIFF12_PAGESETUP_INVALID = 0x0004;
+const sal_uInt16 BIFF12_PAGESETUP_BLACKWHITE = 0x0008;
+const sal_uInt16 BIFF12_PAGESETUP_DRAFTQUALITY = 0x0010;
+const sal_uInt16 BIFF12_PAGESETUP_PRINTNOTES = 0x0020;
+const sal_uInt16 BIFF12_PAGESETUP_DEFAULTORIENT = 0x0040;
+const sal_uInt16 BIFF12_PAGESETUP_USEFIRSTPAGE = 0x0080;
+const sal_uInt16 BIFF12_PAGESETUP_NOTES_END = 0x0100; // different to BIFF flag
+
+const sal_uInt16 BIFF12_CHARTPAGESETUP_LANDSCAPE = 0x0001;
+const sal_uInt16 BIFF12_CHARTPAGESETUP_INVALID = 0x0002;
+const sal_uInt16 BIFF12_CHARTPAGESETUP_BLACKWHITE = 0x0004;
+const sal_uInt16 BIFF12_CHARTPAGESETUP_DEFAULTORIENT= 0x0008;
+const sal_uInt16 BIFF12_CHARTPAGESETUP_USEFIRSTPAGE = 0x0010;
+const sal_uInt16 BIFF12_CHARTPAGESETUP_DRAFTQUALITY = 0x0020;
+
+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
+
+// ============================================================================
+
+PageSettingsModel::PageSettingsModel() :
+ 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 PageSettingsModel::setBiffPrintErrors( 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::importPrintOptions( const AttributeList& rAttribs )
+{
+ maModel.mbHorCenter = rAttribs.getBool( XML_horizontalCentered, false );
+ maModel.mbVerCenter = rAttribs.getBool( XML_verticalCentered, false );
+ maModel.mbPrintGrid = rAttribs.getBool( XML_gridLines, false );
+ maModel.mbPrintHeadings = rAttribs.getBool( XML_headings, false );
+}
+
+void PageSettings::importPageMargins( const AttributeList& rAttribs )
+{
+ maModel.mfLeftMargin = rAttribs.getDouble( XML_left, OOX_MARGIN_DEFAULT_LR );
+ maModel.mfRightMargin = rAttribs.getDouble( XML_right, OOX_MARGIN_DEFAULT_LR );
+ maModel.mfTopMargin = rAttribs.getDouble( XML_top, OOX_MARGIN_DEFAULT_TB );
+ maModel.mfBottomMargin = rAttribs.getDouble( XML_bottom, OOX_MARGIN_DEFAULT_TB );
+ maModel.mfHeaderMargin = rAttribs.getDouble( XML_header, OOX_MARGIN_DEFAULT_HF );
+ maModel.mfFooterMargin = rAttribs.getDouble( XML_footer, OOX_MARGIN_DEFAULT_HF );
+}
+
+void PageSettings::importPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
+{
+ maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ maModel.mnPaperSize = rAttribs.getInteger( XML_paperSize, 1 );
+ maModel.mnCopies = rAttribs.getInteger( XML_copies, 1 );
+ maModel.mnScale = rAttribs.getInteger( XML_scale, 100 );
+ maModel.mnFirstPage = rAttribs.getInteger( XML_firstPageNumber, 1 );
+ maModel.mnFitToWidth = rAttribs.getInteger( XML_fitToWidth, 1 );
+ maModel.mnFitToHeight = rAttribs.getInteger( XML_fitToHeight, 1 );
+ maModel.mnHorPrintRes = rAttribs.getInteger( XML_horizontalDpi, 600 );
+ maModel.mnVerPrintRes = rAttribs.getInteger( XML_verticalDpi, 600 );
+ maModel.mnOrientation = rAttribs.getToken( XML_orientation, XML_default );
+ maModel.mnPageOrder = rAttribs.getToken( XML_pageOrder, XML_downThenOver );
+ maModel.mnCellComments = rAttribs.getToken( XML_cellComments, XML_none );
+ maModel.mnPrintErrors = rAttribs.getToken( XML_errors, XML_displayed );
+ maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true );
+ maModel.mbUseFirstPage = rAttribs.getBool( XML_useFirstPageNumber, false );
+ maModel.mbBlackWhite = rAttribs.getBool( XML_blackAndWhite, false );
+ maModel.mbDraftQuality = rAttribs.getBool( XML_draft, false );
+}
+
+void PageSettings::importChartPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
+{
+ maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ maModel.mnPaperSize = rAttribs.getInteger( XML_paperSize, 1 );
+ maModel.mnCopies = rAttribs.getInteger( XML_copies, 1 );
+ maModel.mnFirstPage = rAttribs.getInteger( XML_firstPageNumber, 1 );
+ maModel.mnHorPrintRes = rAttribs.getInteger( XML_horizontalDpi, 600 );
+ maModel.mnVerPrintRes = rAttribs.getInteger( XML_verticalDpi, 600 );
+ maModel.mnOrientation = rAttribs.getToken( XML_orientation, XML_default );
+ maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true );
+ maModel.mbUseFirstPage = rAttribs.getBool( XML_useFirstPageNumber, false );
+ maModel.mbBlackWhite = rAttribs.getBool( XML_blackAndWhite, false );
+ maModel.mbDraftQuality = rAttribs.getBool( XML_draft, false );
+}
+
+void PageSettings::importHeaderFooter( const AttributeList& rAttribs )
+{
+ maModel.mbUseEvenHF = rAttribs.getBool( XML_differentOddEven, false );
+ maModel.mbUseFirstHF = rAttribs.getBool( XML_differentFirst, false );
+}
+
+void PageSettings::importHeaderFooterCharacters( const OUString& rChars, sal_Int32 nElement )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( oddHeader ): maModel.maOddHeader += rChars; break;
+ case XLS_TOKEN( oddFooter ): maModel.maOddFooter += rChars; break;
+ case XLS_TOKEN( evenHeader ): maModel.maEvenHeader += rChars; break;
+ case XLS_TOKEN( evenFooter ): maModel.maEvenFooter += rChars; break;
+ case XLS_TOKEN( firstHeader ): maModel.maFirstHeader += rChars; break;
+ case XLS_TOKEN( firstFooter ): maModel.maFirstFooter += rChars; break;
+ }
+}
+
+void PageSettings::importPicture( const Relations& rRelations, const AttributeList& rAttribs )
+{
+ importPictureData( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
+}
+
+void PageSettings::importPageMargins( SequenceInputStream& rStrm )
+{
+ rStrm >> maModel.mfLeftMargin >> maModel.mfRightMargin
+ >> maModel.mfTopMargin >> maModel.mfBottomMargin
+ >> maModel.mfHeaderMargin >> maModel.mfFooterMargin;
+}
+
+void PageSettings::importPrintOptions( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ maModel.mbHorCenter = getFlag( nFlags, BIFF12_PRINTOPT_HORCENTER );
+ maModel.mbVerCenter = getFlag( nFlags, BIFF12_PRINTOPT_VERCENTER );
+ maModel.mbPrintGrid = getFlag( nFlags, BIFF12_PRINTOPT_PRINTGRID );
+ maModel.mbPrintHeadings = getFlag( nFlags, BIFF12_PRINTOPT_PRINTHEADING );
+}
+
+void PageSettings::importPageSetup( const Relations& rRelations, SequenceInputStream& rStrm )
+{
+ OUString aRelId;
+ sal_uInt16 nFlags;
+ rStrm >> maModel.mnPaperSize >> maModel.mnScale
+ >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
+ >> maModel.mnCopies >> maModel.mnFirstPage
+ >> maModel.mnFitToWidth >> maModel.mnFitToHeight
+ >> nFlags >> aRelId;
+ maModel.setBiffPrintErrors( extractValue< sal_uInt8 >( nFlags, 9, 2 ) );
+ maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( aRelId );
+ maModel.mnOrientation = getFlagValue( nFlags, BIFF12_PAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_PAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
+ maModel.mnPageOrder = getFlagValue( nFlags, BIFF12_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
+ maModel.mnCellComments = getFlagValue( nFlags, BIFF12_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF12_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
+ maModel.mbValidSettings = !getFlag( nFlags, BIFF12_PAGESETUP_INVALID );
+ maModel.mbUseFirstPage = getFlag( nFlags, BIFF12_PAGESETUP_USEFIRSTPAGE );
+ maModel.mbBlackWhite = getFlag( nFlags, BIFF12_PAGESETUP_BLACKWHITE );
+ maModel.mbDraftQuality = getFlag( nFlags, BIFF12_PAGESETUP_DRAFTQUALITY );
+}
+
+void PageSettings::importChartPageSetup( const Relations& rRelations, SequenceInputStream& rStrm )
+{
+ OUString aRelId;
+ sal_uInt16 nFirstPage, nFlags;
+ rStrm >> maModel.mnPaperSize >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
+ >> maModel.mnCopies >> nFirstPage >> nFlags >> aRelId;
+ maModel.maBinSettPath = rRelations.getFragmentPathFromRelId( aRelId );
+ maModel.mnFirstPage = nFirstPage; // 16-bit in CHARTPAGESETUP
+ maModel.mnOrientation = getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
+ maModel.mbValidSettings = !getFlag( nFlags, BIFF12_CHARTPAGESETUP_INVALID );
+ maModel.mbUseFirstPage = getFlag( nFlags, BIFF12_CHARTPAGESETUP_USEFIRSTPAGE );
+ maModel.mbBlackWhite = getFlag( nFlags, BIFF12_CHARTPAGESETUP_BLACKWHITE );
+ maModel.mbDraftQuality = getFlag( nFlags, BIFF12_CHARTPAGESETUP_DRAFTQUALITY );
+}
+
+void PageSettings::importHeaderFooter( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags
+ >> maModel.maOddHeader >> maModel.maOddFooter
+ >> maModel.maEvenHeader >> maModel.maEvenFooter
+ >> maModel.maFirstHeader >> maModel.maFirstFooter;
+ maModel.mbUseEvenHF = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFEVEN );
+ maModel.mbUseFirstHF = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFFIRST );
+}
+
+void PageSettings::importPicture( const Relations& rRelations, SequenceInputStream& rStrm )
+{
+ importPictureData( rRelations, BiffHelper::readString( rStrm ) );
+}
+
+void PageSettings::importLeftMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maModel.mfLeftMargin;
+}
+
+void PageSettings::importRightMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maModel.mfRightMargin;
+}
+
+void PageSettings::importTopMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maModel.mfTopMargin;
+}
+
+void PageSettings::importBottomMargin( BiffInputStream& rStrm )
+{
+ rStrm >> maModel.mfBottomMargin;
+}
+
+void PageSettings::importPageSetup( BiffInputStream& rStrm )
+{
+ sal_uInt16 nPaperSize, nScale, nFirstPage, nFitToWidth, nFitToHeight, nFlags;
+ rStrm >> nPaperSize >> nScale >> nFirstPage >> nFitToWidth >> nFitToHeight >> nFlags;
+
+ maModel.mnPaperSize = nPaperSize; // equal in BIFF and OOX
+ maModel.mnScale = nScale;
+ maModel.mnFirstPage = nFirstPage;
+ maModel.mnFitToWidth = nFitToWidth;
+ maModel.mnFitToHeight = nFitToHeight;
+ maModel.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_PORTRAIT, XML_portrait, XML_landscape );
+ maModel.mnPageOrder = getFlagValue( nFlags, BIFF_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
+ maModel.mbValidSettings = !getFlag( nFlags, BIFF_PAGESETUP_INVALID );
+ maModel.mbUseFirstPage = true;
+ maModel.mbBlackWhite = getFlag( nFlags, BIFF_PAGESETUP_BLACKWHITE );
+
+ if( getBiff() >= BIFF5 )
+ {
+ sal_uInt16 nHorPrintRes, nVerPrintRes, nCopies;
+ rStrm >> nHorPrintRes >> nVerPrintRes >> maModel.mfHeaderMargin >> maModel.mfFooterMargin >> nCopies;
+
+ maModel.mnCopies = nCopies;
+ maModel.mnOrientation = getFlagValue( nFlags, BIFF_PAGESETUP_DEFAULTORIENT, XML_default, maModel.mnOrientation );
+ maModel.mnHorPrintRes = nHorPrintRes;
+ maModel.mnVerPrintRes = nVerPrintRes;
+ maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, XML_asDisplayed, XML_none );
+ maModel.mbUseFirstPage = getFlag( nFlags, BIFF_PAGESETUP_USEFIRSTPAGE );
+ maModel.mbDraftQuality = getFlag( nFlags, BIFF_PAGESETUP_DRAFTQUALITY );
+
+ if( getBiff() == BIFF8 )
+ {
+ maModel.setBiffPrintErrors( extractValue< sal_uInt8 >( nFlags, 10, 2 ) );
+ maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
+ }
+ }
+}
+
+void PageSettings::importHorCenter( BiffInputStream& rStrm )
+{
+ maModel.mbHorCenter = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importVerCenter( BiffInputStream& rStrm )
+{
+ maModel.mbVerCenter = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importPrintHeaders( BiffInputStream& rStrm )
+{
+ maModel.mbPrintHeadings = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importPrintGridLines( BiffInputStream& rStrm )
+{
+ maModel.mbPrintGrid = rStrm.readuInt16() != 0;
+}
+
+void PageSettings::importHeader( BiffInputStream& rStrm )
+{
+ if( rStrm.getRemaining() > 0 )
+ maModel.maOddHeader = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
+ else
+ maModel.maOddHeader = OUString();
+}
+
+void PageSettings::importFooter( BiffInputStream& rStrm )
+{
+ if( rStrm.getRemaining() > 0 )
+ maModel.maOddFooter = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
+ else
+ maModel.maOddFooter = OUString();
+}
+
+void PageSettings::importPicture( BiffInputStream& rStrm )
+{
+ StreamDataSequence aPictureData;
+ BiffHelper::importImgData( aPictureData, rStrm, getBiff() );
+ maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importGraphicObject( aPictureData );
+}
+
+void PageSettings::setFitToPagesMode( bool bFitToPages )
+{
+ maModel.mbFitToPages = bFitToPages;
+}
+
+void PageSettings::finalizeImport()
+{
+ OUStringBuffer aStyleNameBuffer( CREATE_OUSTRING( "PageStyle_" ) );
+ Reference< XNamed > xSheetName( getSheet(), 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 );
+ getPageSettingsConverter().writePageSettingsProperties( aStyleProps, maModel, getSheetType() );
+
+ PropertySet aSheetProps( getSheet() );
+ aSheetProps.setProperty( PROP_PageStyle, aStyleName );
+}
+
+void PageSettings::importPictureData( const Relations& rRelations, const OUString& rRelId )
+{
+ OUString aPicturePath = rRelations.getFragmentPathFromRelId( rRelId );
+ if( aPicturePath.getLength() > 0 )
+ maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importEmbeddedGraphicObject( aPicturePath );
+}
+
+// ============================================================================
+// ============================================================================
+
+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 HeaderFooterParser : public WorkbookHelper
+{
+public:
+ explicit HeaderFooterParser( const WorkbookHelper& rHelper );
+
+ /** Parses the passed string and creates the header/footer contents.
+ @returns The total height of the converted header or footer in points. */
+ double parse(
+ const Reference< XHeaderFooterContent >& rxContext,
+ const OUString& rData );
+
+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;
+
+ const OUString maPageNumberService;
+ const OUString maPageCountService;
+ const OUString maSheetNameService;
+ const OUString maFileNameService;
+ const OUString maDateTimeService;
+ const OStringSet maBoldNames; /// All names for bold font style in lowercase UTF-8.
+ const 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.
+ FontModel maFontModel; /// Font attributes of current text range.
+};
+
+// ----------------------------------------------------------------------------
+
+namespace {
+
+// different names for bold font style (lowercase)
+static const sal_Char* const sppcBoldNames[] =
+{
+ "bold",
+ "fett", // German 'bold'
+ "demibold",
+ "halbfett", // German 'demibold'
+ "black",
+ "heavy"
+};
+
+// different names for italic font style (lowercase)
+static const sal_Char* const sppcItalicNames[] =
+{
+ "italic",
+ "kursiv", // German 'italic'
+ "oblique",
+ "schr\303\204g", // German 'oblique' with uppercase A umlaut
+ "schr\303\244g" // German 'oblique' with lowercase A umlaut
+};
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+HeaderFooterParser::HeaderFooterParser( 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" ) ),
+ maBoldNames( sppcBoldNames, STATIC_ARRAY_END( sppcBoldNames ) ),
+ maItalicNames( sppcItalicNames, STATIC_ARRAY_END( sppcItalicNames ) ),
+ maPortions( static_cast< size_t >( HF_COUNT ) ),
+ meCurrPortion( HF_CENTER )
+{
+}
+
+double HeaderFooterParser::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 0.0;
+
+ meCurrPortion = HF_CENTER;
+ maBuffer.setLength( 0 );
+ maFontModel = getStyles().getDefaultFontModel();
+ 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( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::NAME_AND_EXT );
+ appendField( xContent );
+ }
+ break;
+ case 'Z': // file path (without file name), OOXML, BIFF12, and BIFF8 only
+ if( (getFilterType() == FILTER_OOXML) || ((getFilterType() == FILTER_BIFF) && (getBiff() == BIFF8)) )
+ {
+ Reference< XTextContent > xContent = createField( maFileNameService );
+ PropertySet aPropSet( xContent );
+ // FilenameDisplayFormat::PATH not supported by Calc
+ aPropSet.setProperty( PROP_FileFormat, ::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( PROP_IsDate, true );
+ appendField( xContent );
+ }
+ break;
+ case 'T': // time
+ {
+ Reference< XTextContent > xContent = createField( maDateTimeService );
+ PropertySet aPropSet( xContent );
+ aPropSet.setProperty( PROP_IsDate, false );
+ appendField( xContent );
+ }
+ break;
+
+ case 'B': // bold
+ setAttributes();
+ maFontModel.mbBold = !maFontModel.mbBold;
+ break;
+ case 'I': // italic
+ setAttributes();
+ maFontModel.mbItalic = !maFontModel.mbItalic;
+ break;
+ case 'U': // underline
+ setAttributes();
+ maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_single) ? XML_none : XML_single;
+ break;
+ case 'E': // double underline
+ setAttributes();
+ maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_double) ? XML_none : XML_double;
+ break;
+ case 'S': // strikeout
+ setAttributes();
+ maFontModel.mbStrikeout = !maFontModel.mbStrikeout;
+ break;
+ case 'X': // superscript
+ setAttributes();
+ maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_superscript) ? XML_baseline : XML_superscript;
+ break;
+ case 'Y': // subsrcipt
+ setAttributes();
+ maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_subscript) ? XML_baseline : XML_subscript;
+ break;
+ case 'O': // outlined
+ setAttributes();
+ maFontModel.mbOutline = !maFontModel.mbOutline;
+ break;
+ case 'H': // shadow
+ setAttributes();
+ maFontModel.mbShadow = !maFontModel.mbShadow;
+ break;
+
+ case 'K': // text color (not in BIFF)
+ if( (getFilterType() == FILTER_OOXML) && (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();
+ maFontModel.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 );
+
+ return ::std::max( maPortions[ HF_LEFT ].mfTotalHeight,
+ ::std::max( maPortions[ HF_CENTER ].mfTotalHeight, maPortions[ HF_RIGHT ].mfTotalHeight ) );
+}
+
+// private --------------------------------------------------------------------
+
+double HeaderFooterParser::getCurrHeight( HFPortionId ePortion ) const
+{
+ double fMaxHt = maPortions[ ePortion ].mfCurrHeight;
+ return (fMaxHt == 0.0) ? maFontModel.mfHeight : fMaxHt;
+}
+
+double HeaderFooterParser::getCurrHeight() const
+{
+ return getCurrHeight( meCurrPortion );
+}
+
+void HeaderFooterParser::updateCurrHeight( HFPortionId ePortion )
+{
+ double& rfMaxHt = maPortions[ ePortion ].mfCurrHeight;
+ rfMaxHt = ::std::max( rfMaxHt, maFontModel.mfHeight );
+}
+
+void HeaderFooterParser::updateCurrHeight()
+{
+ updateCurrHeight( meCurrPortion );
+}
+
+void HeaderFooterParser::setAttributes()
+{
+ Reference< XTextRange > xRange( getStartPos(), UNO_QUERY );
+ getEndPos()->gotoRange( xRange, sal_False );
+ getEndPos()->gotoEnd( sal_True );
+ if( !getEndPos()->isCollapsed() )
+ {
+ Font aFont( *this, maFontModel );
+ aFont.finalizeImport();
+ PropertySet aPropSet( getEndPos() );
+ aFont.writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT );
+ getStartPos()->gotoEnd( sal_False );
+ getEndPos()->gotoEnd( sal_False );
+ }
+}
+
+void HeaderFooterParser::appendText()
+{
+ if( maBuffer.getLength() > 0 )
+ {
+ getEndPos()->gotoEnd( sal_False );
+ getEndPos()->setString( maBuffer.makeStringAndClear() );
+ updateCurrHeight();
+ }
+}
+
+void HeaderFooterParser::appendLineBreak()
+{
+ getEndPos()->gotoEnd( sal_False );
+ getEndPos()->setString( OUString( sal_Unicode( '\n' ) ) );
+ getPortion().mfTotalHeight += getCurrHeight();
+ getPortion().mfCurrHeight = 0;
+}
+
+Reference< XTextContent > HeaderFooterParser::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( "HeaderFooterParser::createField - error while creating text field \"" ).
+ append( OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ) ).
+ append( '"' ).getStr() );
+ }
+ return xContent;
+}
+
+void HeaderFooterParser::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 HeaderFooterParser::convertFontName( const OUString& rName )
+{
+ if( rName.getLength() > 0 )
+ {
+ // single dash is document default font
+ if( (rName.getLength() == 1) && (rName[ 0 ] == '-') )
+ maFontModel.maName = getStyles().getDefaultFontModel().maName;
+ else
+ maFontModel.maName = rName;
+ }
+}
+
+void HeaderFooterParser::convertFontStyle( const OUString& rStyle )
+{
+ maFontModel.mbBold = maFontModel.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 )
+ maFontModel.mbBold = true;
+ else if( maItalicNames.count( aToken ) > 0 )
+ maFontModel.mbItalic = true;
+ }
+ }
+}
+
+void HeaderFooterParser::convertFontColor( const OUString& rColor )
+{
+ OSL_ENSURE( rColor.getLength() == 6, "HeaderFooterParser::convertFontColor - invalid font color code" );
+ if( (rColor[ 2 ] == '+') || (rColor[ 2 ] == '-') )
+ // theme color: TTSNNN (TT = decimal theme index, S = +/-, NNN = decimal tint/shade in percent)
+ maFontModel.maColor.setTheme(
+ rColor.copy( 0, 2 ).toInt32(),
+ static_cast< double >( rColor.copy( 2 ).toInt32() ) / 100.0 );
+ else
+ // RGB color: RRGGBB
+ maFontModel.maColor.setRgb( rColor.toInt32( 16 ) );
+}
+
+void HeaderFooterParser::finalizePortion()
+{
+ appendText();
+ setAttributes();
+}
+
+void HeaderFooterParser::setNewPortion( HFPortionId ePortion )
+{
+ if( ePortion != meCurrPortion )
+ {
+ finalizePortion();
+ meCurrPortion = ePortion;
+ maFontModel = getStyles().getDefaultFontModel();
+ }
+}
+
+// ============================================================================
+
+namespace {
+
+/** 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
+
+// ----------------------------------------------------------------------------
+
+PageSettingsConverter::HFHelperData::HFHelperData( sal_Int32 nLeftPropId, sal_Int32 nRightPropId ) :
+ mnLeftPropId( nLeftPropId ),
+ mnRightPropId( nRightPropId ),
+ mnHeight( 0 ),
+ mnBodyDist( 0 ),
+ mbHasContent( false ),
+ mbShareOddEven( false ),
+ mbDynamicHeight( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PageSettingsConverter::PageSettingsConverter( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mxHFParser( new HeaderFooterParser( rHelper ) ),
+ maHeaderData( PROP_LeftPageHeaderContent, PROP_RightPageHeaderContent ),
+ maFooterData( PROP_LeftPageFooterContent, PROP_RightPageFooterContent )
+{
+}
+
+PageSettingsConverter::~PageSettingsConverter()
+{
+}
+
+void PageSettingsConverter::writePageSettingsProperties(
+ PropertySet& rPropSet, const PageSettingsModel& rModel, WorksheetType eSheetType )
+{
+ // special handling for chart sheets
+ bool bChartSheet = eSheetType == SHEETTYPE_CHARTSHEET;
+
+ // printout scaling
+ if( bChartSheet )
+ {
+ // always fit chart sheet to 1 page
+ rPropSet.setProperty< sal_Int16 >( PROP_ScaleToPages, 1 );
+ }
+ else if( rModel.mbFitToPages )
+ {
+ // fit to number of pages
+ rPropSet.setProperty( PROP_ScaleToPagesX, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToWidth, 0, 1000 ) );
+ rPropSet.setProperty( PROP_ScaleToPagesY, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToHeight, 0, 1000 ) );
+ }
+ else
+ {
+ // scale may be 0 which indicates uninitialized
+ sal_Int16 nScale = (rModel.mbValidSettings && (rModel.mnScale > 0)) ? getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnScale, 10, 400 ) : 100;
+ rPropSet.setProperty( PROP_PageScale, nScale );
+ }
+
+ // paper orientation
+ bool bLandscape = rModel.mnOrientation == XML_landscape;
+ // default orientation for current sheet type (chart sheets default to landscape)
+ if( !rModel.mbValidSettings || (rModel.mnOrientation == XML_default) )
+ bLandscape = bChartSheet;
+
+ // paper size
+ if( rModel.mbValidSettings && (0 < rModel.mnPaperSize) && (rModel.mnPaperSize < static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( spPaperSizeTable ) )) )
+ {
+ const ApiPaperSize& rPaperSize = spPaperSizeTable[ rModel.mnPaperSize ];
+ Size aSize( rPaperSize.mnWidth, rPaperSize.mnHeight );
+ if( bLandscape )
+ ::std::swap( aSize.Width, aSize.Height );
+ rPropSet.setProperty( PROP_Size, aSize );
+ }
+
+ // header/footer
+ convertHeaderFooterData( rPropSet, maHeaderData, rModel.maOddHeader, rModel.maEvenHeader, rModel.mbUseEvenHF, rModel.mfTopMargin, rModel.mfHeaderMargin );
+ convertHeaderFooterData( rPropSet, maFooterData, rModel.maOddFooter, rModel.maEvenFooter, rModel.mbUseEvenHF, rModel.mfBottomMargin, rModel.mfFooterMargin );
+
+ // write all properties to property set
+ const UnitConverter& rUnitConv = getUnitConverter();
+ PropertyMap aPropMap;
+ aPropMap[ PROP_IsLandscape ] <<= bLandscape;
+ aPropMap[ PROP_FirstPageNumber ] <<= getLimitedValue< sal_Int16, sal_Int32 >( rModel.mbUseFirstPage ? rModel.mnFirstPage : 0, 0, 9999 );
+ aPropMap[ PROP_PrintDownFirst ] <<= (rModel.mnPageOrder == XML_downThenOver);
+ aPropMap[ PROP_PrintAnnotations ] <<= (rModel.mnCellComments == XML_asDisplayed);
+ aPropMap[ PROP_CenterHorizontally ] <<= rModel.mbHorCenter;
+ aPropMap[ PROP_CenterVertically ] <<= rModel.mbVerCenter;
+ aPropMap[ PROP_PrintGrid ] <<= (!bChartSheet && rModel.mbPrintGrid); // no gridlines in chart sheets
+ aPropMap[ PROP_PrintHeaders ] <<= (!bChartSheet && rModel.mbPrintHeadings); // no column/row headings in chart sheets
+ aPropMap[ PROP_LeftMargin ] <<= rUnitConv.scaleToMm100( rModel.mfLeftMargin, UNIT_INCH );
+ aPropMap[ PROP_RightMargin ] <<= rUnitConv.scaleToMm100( rModel.mfRightMargin, UNIT_INCH );
+ // #i23296# In Calc, "TopMargin" property is distance to top of header if enabled
+ aPropMap[ PROP_TopMargin ] <<= rUnitConv.scaleToMm100( maHeaderData.mbHasContent ? rModel.mfHeaderMargin : rModel.mfTopMargin, UNIT_INCH );
+ // #i23296# In Calc, "BottomMargin" property is distance to bottom of footer if enabled
+ aPropMap[ PROP_BottomMargin ] <<= rUnitConv.scaleToMm100( maFooterData.mbHasContent ? rModel.mfFooterMargin : rModel.mfBottomMargin, UNIT_INCH );
+ aPropMap[ PROP_HeaderIsOn ] <<= maHeaderData.mbHasContent;
+ aPropMap[ PROP_HeaderIsShared ] <<= maHeaderData.mbShareOddEven;
+ aPropMap[ PROP_HeaderIsDynamicHeight ] <<= maHeaderData.mbDynamicHeight;
+ aPropMap[ PROP_HeaderHeight ] <<= maHeaderData.mnHeight;
+ aPropMap[ PROP_HeaderBodyDistance ] <<= maHeaderData.mnBodyDist;
+ aPropMap[ PROP_FooterIsOn ] <<= maFooterData.mbHasContent;
+ aPropMap[ PROP_FooterIsShared ] <<= maFooterData.mbShareOddEven;
+ aPropMap[ PROP_FooterIsDynamicHeight ] <<= maFooterData.mbDynamicHeight;
+ aPropMap[ PROP_FooterHeight ] <<= maFooterData.mnHeight;
+ aPropMap[ PROP_FooterBodyDistance ] <<= maFooterData.mnBodyDist;
+ // background image
+ if( rModel.maGraphicUrl.getLength() > 0 )
+ {
+ aPropMap[ PROP_BackGraphicURL ] <<= rModel.maGraphicUrl;
+ aPropMap[ PROP_BackGraphicLocation ] <<= ::com::sun::star::style::GraphicLocation_TILED;
+ }
+
+ rPropSet.setProperties( aPropMap );
+}
+
+void PageSettingsConverter::convertHeaderFooterData(
+ PropertySet& rPropSet, HFHelperData& orHFData,
+ 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, orHFData.mnRightPropId, rOddContent ) : 0;
+ sal_Int32 nEvenHeight = bHasEvenContent ? writeHeaderFooter( rPropSet, orHFData.mnLeftPropId, rEvenContent ) : 0;
+
+ orHFData.mnHeight = 750;
+ orHFData.mnBodyDist = 250;
+ orHFData.mbHasContent = bHasOddContent || bHasEvenContent;
+ orHFData.mbShareOddEven = !bUseEvenContent;
+ orHFData.mbDynamicHeight = true;
+
+ if( orHFData.mbHasContent )
+ {
+ // use maximum height of odd/even header/footer
+ orHFData.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 */
+ orHFData.mnBodyDist = getUnitConverter().scaleToMm100( fPageMargin - fContentMargin, UNIT_INCH ) - orHFData.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. */
+ orHFData.mbDynamicHeight = orHFData.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"). */
+ orHFData.mnHeight += orHFData.mnBodyDist;
+ // negative body distance not allowed
+ orHFData.mnBodyDist = ::std::max< sal_Int32 >( orHFData.mnBodyDist, 0 );
+ }
+}
+
+sal_Int32 PageSettingsConverter::writeHeaderFooter(
+ PropertySet& rPropSet, sal_Int32 nPropId, const OUString& rContent )
+{
+ OSL_ENSURE( rContent.getLength() > 0, "PageSettingsConverter::writeHeaderFooter - empty h/f string found" );
+ sal_Int32 nHeight = 0;
+ if( rContent.getLength() > 0 )
+ {
+ Reference< XHeaderFooterContent > xHFContent( rPropSet.getAnyProperty( nPropId ), UNO_QUERY );
+ if( xHFContent.is() )
+ {
+ double fTotalHeight = mxHFParser->parse( xHFContent, rContent );
+ rPropSet.setProperty( nPropId, xHFContent );
+ nHeight = getUnitConverter().scaleToMm100( fTotalHeight, UNIT_POINT );
+ }
+ }
+ return nHeight;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx
new file mode 100644
index 000000000000..e8ca3539e167
--- /dev/null
+++ b/oox/source/xls/pivotcachebuffer.cxx
@@ -0,0 +1,1543 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/pivotcachebuffer.hxx"
+
+#include <set>
+#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/DataPilotFieldGroupBy.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupInfo.hpp>
+#include <com/sun/star/sheet/XDataPilotFieldGrouping.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/pivotcachefragment.hxx"
+#include "oox/xls/tablebuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::oox::core::Relations;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 BIFF12_PCDFIELD_SERVERFIELD = 0x0001;
+const sal_uInt16 BIFF12_PCDFIELD_NOUNIQUEITEMS = 0x0002;
+const sal_uInt16 BIFF12_PCDFIELD_DATABASEFIELD = 0x0004;
+const sal_uInt16 BIFF12_PCDFIELD_HASCAPTION = 0x0008;
+const sal_uInt16 BIFF12_PCDFIELD_MEMBERPROPFIELD = 0x0010;
+const sal_uInt16 BIFF12_PCDFIELD_HASFORMULA = 0x0100;
+const sal_uInt16 BIFF12_PCDFIELD_HASPROPERTYNAME = 0x0200;
+
+const sal_uInt16 BIFF12_PCDFSITEMS_HASSEMIMIXED = 0x0001;
+const sal_uInt16 BIFF12_PCDFSITEMS_HASNONDATE = 0x0002;
+const sal_uInt16 BIFF12_PCDFSITEMS_HASDATE = 0x0004;
+const sal_uInt16 BIFF12_PCDFSITEMS_HASSTRING = 0x0008;
+const sal_uInt16 BIFF12_PCDFSITEMS_HASBLANK = 0x0010;
+const sal_uInt16 BIFF12_PCDFSITEMS_HASMIXED = 0x0020;
+const sal_uInt16 BIFF12_PCDFSITEMS_ISNUMERIC = 0x0040;
+const sal_uInt16 BIFF12_PCDFSITEMS_ISINTEGER = 0x0080;
+const sal_uInt16 BIFF12_PCDFSITEMS_HASMINMAX = 0x0100;
+const sal_uInt16 BIFF12_PCDFSITEMS_HASLONGTEXT = 0x0200;
+
+const sal_uInt16 BIFF12_PCITEM_ARRAY_DOUBLE = 0x0001;
+const sal_uInt16 BIFF12_PCITEM_ARRAY_STRING = 0x0002;
+const sal_uInt16 BIFF12_PCITEM_ARRAY_ERROR = 0x0010;
+const sal_uInt16 BIFF12_PCITEM_ARRAY_DATE = 0x0020;
+
+const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOSTART = 0x01;
+const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOEND = 0x02;
+const sal_uInt8 BIFF12_PCDFRANGEPR_DATEGROUP = 0x04;
+
+const sal_uInt8 BIFF12_PCDEFINITION_SAVEDATA = 0x01;
+const sal_uInt8 BIFF12_PCDEFINITION_INVALID = 0x02;
+const sal_uInt8 BIFF12_PCDEFINITION_REFRESHONLOAD = 0x04;
+const sal_uInt8 BIFF12_PCDEFINITION_OPTIMIZEMEMORY = 0x08;
+const sal_uInt8 BIFF12_PCDEFINITION_ENABLEREFRESH = 0x10;
+const sal_uInt8 BIFF12_PCDEFINITION_BACKGROUNDQUERY = 0x20;
+const sal_uInt8 BIFF12_PCDEFINITION_UPGRADEONREFR = 0x40;
+const sal_uInt8 BIFF12_PCDEFINITION_TUPELCACHE = 0x80;
+
+const sal_uInt8 BIFF12_PCDEFINITION_HASUSERNAME = 0x01;
+const sal_uInt8 BIFF12_PCDEFINITION_HASRELID = 0x02;
+const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTSUBQUERY = 0x04;
+const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTDRILL = 0x08;
+
+const sal_uInt8 BIFF12_PCDWBSOURCE_HASRELID = 0x01;
+const sal_uInt8 BIFF12_PCDWBSOURCE_HASSHEET = 0x02;
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt16 BIFF_PCDSOURCE_WORKSHEET = 0x0001;
+const sal_uInt16 BIFF_PCDSOURCE_EXTERNAL = 0x0002;
+const sal_uInt16 BIFF_PCDSOURCE_CONSOLIDATION = 0x0004;
+const sal_uInt16 BIFF_PCDSOURCE_SCENARIO = 0x0010;
+
+const sal_uInt16 BIFF_PC_NOSTRING = 0xFFFF;
+
+const sal_uInt16 BIFF_PCDFIELD_HASITEMS = 0x0001;
+const sal_uInt16 BIFF_PCDFIELD_HASUNSHAREDITEMS = 0x0002;
+const sal_uInt16 BIFF_PCDFIELD_CALCULATED = 0x0004;
+const sal_uInt16 BIFF_PCDFIELD_HASPARENT = 0x0008;
+const sal_uInt16 BIFF_PCDFIELD_RANGEGROUP = 0x0010;
+const sal_uInt16 BIFF_PCDFIELD_ISNUMERIC = 0x0020;
+const sal_uInt16 BIFF_PCDFIELD_HASSEMIMIXED = 0x0080;
+const sal_uInt16 BIFF_PCDFIELD_HASMINMAX = 0x0100;
+const sal_uInt16 BIFF_PCDFIELD_HASLONGINDEX = 0x0200;
+const sal_uInt16 BIFF_PCDFIELD_HASNONDATE = 0x0400;
+const sal_uInt16 BIFF_PCDFIELD_HASDATE = 0x0800;
+const sal_uInt16 BIFF_PCDFIELD_SERVERFIELD = 0x2000;
+const sal_uInt16 BIFF_PCDFIELD_NOUNIQUEITEMS = 0x4000;
+
+const sal_uInt16 BIFF_PCDFRANGEPR_AUTOSTART = 0x0001;
+const sal_uInt16 BIFF_PCDFRANGEPR_AUTOEND = 0x0002;
+
+const sal_uInt16 BIFF_PCDEFINITION_SAVEDATA = 0x0001;
+const sal_uInt16 BIFF_PCDEFINITION_INVALID = 0x0002;
+const sal_uInt16 BIFF_PCDEFINITION_REFRESHONLOAD = 0x0004;
+const sal_uInt16 BIFF_PCDEFINITION_OPTIMIZEMEMORY = 0x0008;
+const sal_uInt16 BIFF_PCDEFINITION_BACKGROUNDQUERY = 0x0010;
+const sal_uInt16 BIFF_PCDEFINITION_ENABLEREFRESH = 0x0020;
+
+// ----------------------------------------------------------------------------
+
+/** Adjusts the weird date format read from binary streams.
+
+ Dates before 1900-Mar-01 are stored including the non-existing leap day
+ 1900-02-29. Time values (without date) are stored as times of day
+ 1900-Jan-00. Nothing has to be done when the workbook is stored in 1904
+ date mode (dates before 1904-Jan-01 will not occur in this case).
+ */
+void lclAdjustBinDateTime( DateTime& orDateTime )
+{
+ if( (orDateTime.Year == 1900) && (orDateTime.Month <= 2) )
+ {
+ OSL_ENSURE( (orDateTime.Month == 1) || ((orDateTime.Month == 2) && (orDateTime.Day > 0)), "lclAdjustBinDateTime - invalid date" );
+ switch( orDateTime.Month )
+ {
+ case 2: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; --orDateTime.Month; } break;
+ case 1: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; orDateTime.Month = 12; --orDateTime.Year; } break;
+ }
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+PivotCacheItem::PivotCacheItem() :
+ mnType( XML_m )
+{
+}
+
+void PivotCacheItem::readString( const AttributeList& rAttribs )
+{
+ maValue <<= rAttribs.getXString( XML_v, OUString() );
+ mnType = XML_s;
+}
+
+void PivotCacheItem::readNumeric( const AttributeList& rAttribs )
+{
+ maValue <<= rAttribs.getDouble( XML_v, 0.0 );
+ mnType = XML_n;
+}
+
+void PivotCacheItem::readDate( const AttributeList& rAttribs )
+{
+ maValue <<= rAttribs.getDateTime( XML_v, DateTime() );
+ mnType = XML_d;
+}
+
+void PivotCacheItem::readBool( const AttributeList& rAttribs )
+{
+ maValue <<= rAttribs.getBool( XML_v, false );
+ mnType = XML_b;
+}
+
+void PivotCacheItem::readError( const AttributeList& rAttribs, const UnitConverter& rUnitConverter )
+{
+ maValue <<= static_cast< sal_Int32 >( rUnitConverter.calcBiffErrorCode( rAttribs.getXString( XML_v, OUString() ) ) );
+ mnType = XML_e;
+}
+
+void PivotCacheItem::readIndex( const AttributeList& rAttribs )
+{
+ maValue <<= rAttribs.getInteger( XML_v, -1 );
+ mnType = XML_x;
+}
+
+void PivotCacheItem::readString( SequenceInputStream& rStrm )
+{
+ maValue <<= BiffHelper::readString( rStrm );
+ mnType = XML_s;
+}
+
+void PivotCacheItem::readDouble( SequenceInputStream& rStrm )
+{
+ maValue <<= rStrm.readDouble();
+ mnType = XML_n;
+}
+
+void PivotCacheItem::readDate( SequenceInputStream& rStrm )
+{
+ DateTime aDateTime;
+ aDateTime.Year = rStrm.readuInt16();
+ aDateTime.Month = rStrm.readuInt16();
+ aDateTime.Day = rStrm.readuInt8();
+ aDateTime.Hours = rStrm.readuInt8();
+ aDateTime.Minutes = rStrm.readuInt8();
+ aDateTime.Seconds = rStrm.readuInt8();
+ lclAdjustBinDateTime( aDateTime );
+ maValue <<= aDateTime;
+ mnType = XML_d;
+}
+
+void PivotCacheItem::readBool( SequenceInputStream& rStrm )
+{
+ maValue <<= (rStrm.readuInt8() != 0);
+ mnType = XML_b;
+}
+
+void PivotCacheItem::readError( SequenceInputStream& rStrm )
+{
+ maValue <<= static_cast< sal_Int32 >( rStrm.readuInt8() );
+ mnType = XML_e;
+}
+
+void PivotCacheItem::readIndex( SequenceInputStream& rStrm )
+{
+ maValue <<= rStrm.readInt32();
+ mnType = XML_x;
+}
+
+void PivotCacheItem::readString( BiffInputStream& rStrm, const WorkbookHelper& rHelper )
+{
+ maValue <<= (rHelper.getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( true, rHelper.getTextEncoding() );
+ mnType = XML_s;
+}
+
+void PivotCacheItem::readDouble( BiffInputStream& rStrm )
+{
+ maValue <<= rStrm.readDouble();
+ mnType = XML_n;
+}
+
+void PivotCacheItem::readInteger( BiffInputStream& rStrm )
+{
+ maValue <<= rStrm.readInt16();
+ mnType = XML_i; // fake, used for BIFF only
+}
+
+void PivotCacheItem::readDate( BiffInputStream& rStrm )
+{
+ DateTime aDateTime;
+ aDateTime.Year = rStrm.readuInt16();
+ aDateTime.Month = rStrm.readuInt16();
+ aDateTime.Day = rStrm.readuInt8();
+ aDateTime.Hours = rStrm.readuInt8();
+ aDateTime.Minutes = rStrm.readuInt8();
+ aDateTime.Seconds = rStrm.readuInt8();
+ lclAdjustBinDateTime( aDateTime );
+ maValue <<= aDateTime;
+ mnType = XML_d;
+}
+
+void PivotCacheItem::readBool( BiffInputStream& rStrm )
+{
+ maValue <<= (rStrm.readuInt8() != 0);
+ mnType = XML_b;
+}
+
+void PivotCacheItem::readError( BiffInputStream& rStrm )
+{
+ maValue <<= static_cast< sal_Int32 >( rStrm.readuInt8() );
+ mnType = XML_e;
+}
+
+OUString PivotCacheItem::getName() const
+{
+ switch( mnType )
+ {
+ case XML_m: return OUString();
+ case XML_s: return maValue.get< OUString >();
+ case XML_n: return OUString::valueOf( maValue.get< double >() ); // !TODO
+ case XML_i: return OUString::valueOf( maValue.get< sal_Int32 >() );
+ case XML_d: return OUString(); // !TODO
+ case XML_b: return OUString::valueOf( static_cast< sal_Bool >( maValue.get< bool >() ) ); // !TODO
+ case XML_e: return OUString(); // !TODO
+ }
+ OSL_ENSURE( false, "PivotCacheItem::getName - invalid data type" );
+ return OUString();
+}
+
+// ----------------------------------------------------------------------------
+
+PivotCacheItemList::PivotCacheItemList( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void PivotCacheItemList::importItem( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ PivotCacheItem& rItem = createItem();
+ switch( nElement )
+ {
+ case XLS_TOKEN( m ): break;
+ case XLS_TOKEN( s ): rItem.readString( rAttribs ); break;
+ case XLS_TOKEN( n ): rItem.readNumeric( rAttribs ); break;
+ case XLS_TOKEN( d ): rItem.readDate( rAttribs ); break;
+ case XLS_TOKEN( b ): rItem.readBool( rAttribs ); break;
+ case XLS_TOKEN( e ): rItem.readError( rAttribs, getUnitConverter() ); break;
+ default: OSL_ENSURE( false, "PivotCacheItemList::importItem - unknown element type" );
+ }
+}
+
+void PivotCacheItemList::importItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ if( nRecId == BIFF12_ID_PCITEM_ARRAY )
+ {
+ importArray( rStrm );
+ return;
+ }
+
+ PivotCacheItem& rItem = createItem();
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCITEM_MISSING:
+ case BIFF12_ID_PCITEMA_MISSING: break;
+ case BIFF12_ID_PCITEM_STRING:
+ case BIFF12_ID_PCITEMA_STRING: rItem.readString( rStrm ); break;
+ case BIFF12_ID_PCITEM_DOUBLE:
+ case BIFF12_ID_PCITEMA_DOUBLE: rItem.readDouble( rStrm ); break;
+ case BIFF12_ID_PCITEM_DATE:
+ case BIFF12_ID_PCITEMA_DATE: rItem.readDate( rStrm ); break;
+ case BIFF12_ID_PCITEM_BOOL:
+ case BIFF12_ID_PCITEMA_BOOL: rItem.readBool( rStrm ); break;
+ case BIFF12_ID_PCITEM_ERROR:
+ case BIFF12_ID_PCITEMA_ERROR: rItem.readError( rStrm ); break;
+ default: OSL_ENSURE( false, "PivotCacheItemList::importItem - unknown record type" );
+ }
+}
+
+void PivotCacheItemList::importItemList( BiffInputStream& rStrm, sal_uInt16 nCount )
+{
+ bool bLoop = true;
+ for( sal_uInt16 nItemIdx = 0; bLoop && (nItemIdx < nCount); ++nItemIdx )
+ {
+ bLoop = rStrm.startNextRecord();
+ if( bLoop ) switch( rStrm.getRecId() )
+ {
+ case BIFF_ID_PCITEM_MISSING: createItem(); break;
+ case BIFF_ID_PCITEM_STRING: createItem().readString( rStrm, *this ); break;
+ case BIFF_ID_PCITEM_DOUBLE: createItem().readDouble( rStrm ); break;
+ case BIFF_ID_PCITEM_INTEGER: createItem().readInteger( rStrm ); break;
+ case BIFF_ID_PCITEM_DATE: createItem().readDate( rStrm ); break;
+ case BIFF_ID_PCITEM_BOOL: createItem().readBool( rStrm ); break;
+ case BIFF_ID_PCITEM_ERROR: createItem().readError( rStrm ); break;
+ default: rStrm.rewindRecord(); bLoop = false;
+ }
+ }
+ OSL_ENSURE( bLoop, "PivotCacheItemList::importItemList - could not read all cache item records" );
+}
+
+const PivotCacheItem* PivotCacheItemList::getCacheItem( sal_Int32 nItemIdx ) const
+{
+ return ContainerHelper::getVectorElement( maItems, nItemIdx );
+}
+
+void PivotCacheItemList::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
+{
+ orItemNames.clear();
+ orItemNames.reserve( maItems.size() );
+ for( CacheItemVector::const_iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
+ orItemNames.push_back( aIt->getName() );
+}
+
+// private --------------------------------------------------------------------
+
+PivotCacheItem& PivotCacheItemList::createItem()
+{
+ maItems.resize( maItems.size() + 1 );
+ return maItems.back();
+}
+
+void PivotCacheItemList::importArray( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nType = rStrm.readuInt16();
+ sal_Int32 nCount = rStrm.readInt32();
+ for( sal_Int32 nIdx = 0; !rStrm.isEof() && (nIdx < nCount); ++nIdx )
+ {
+ switch( nType )
+ {
+ case BIFF12_PCITEM_ARRAY_DOUBLE: createItem().readDouble( rStrm ); break;
+ case BIFF12_PCITEM_ARRAY_STRING: createItem().readString( rStrm ); break;
+ case BIFF12_PCITEM_ARRAY_ERROR: createItem().readError( rStrm ); break;
+ case BIFF12_PCITEM_ARRAY_DATE: createItem().readDate( rStrm ); break;
+ default:
+ OSL_ENSURE( false, "PivotCacheItemList::importArray - unknown data type" );
+ nIdx = nCount;
+ }
+ }
+}
+
+// ============================================================================
+
+PCFieldModel::PCFieldModel() :
+ mnNumFmtId( 0 ),
+ mnSqlType( 0 ),
+ mnHierarchy( 0 ),
+ mnLevel( 0 ),
+ mnMappingCount( 0 ),
+ mbDatabaseField( true ),
+ mbServerField( false ),
+ mbUniqueList( true ),
+ mbMemberPropField( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PCSharedItemsModel::PCSharedItemsModel() :
+ mbHasSemiMixed( true ),
+ mbHasNonDate( true ),
+ mbHasDate( false ),
+ mbHasString( true ),
+ mbHasBlank( false ),
+ mbHasMixed( false ),
+ mbIsNumeric( false ),
+ mbIsInteger( false ),
+ mbHasLongText( false ),
+ mbHasLongIndexes( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PCFieldGroupModel::PCFieldGroupModel() :
+ mfStartValue( 0.0 ),
+ mfEndValue( 0.0 ),
+ mfInterval( 1.0 ),
+ mnParentField( -1 ),
+ mnBaseField( -1 ),
+ mnGroupBy( XML_range ),
+ mbRangeGroup( false ),
+ mbDateGroup( false ),
+ mbAutoStart( true ),
+ mbAutoEnd( true )
+{
+}
+
+void PCFieldGroupModel::setBiffGroupBy( sal_uInt8 nGroupBy )
+{
+ static const sal_Int32 spnGroupBy[] = { XML_range,
+ XML_seconds, XML_minutes, XML_hours, XML_days, XML_months, XML_quarters, XML_years };
+ mnGroupBy = STATIC_ARRAY_SELECT( spnGroupBy, nGroupBy, XML_range );
+}
+
+// ----------------------------------------------------------------------------
+
+PivotCacheField::PivotCacheField( const WorkbookHelper& rHelper, bool bIsDatabaseField ) :
+ WorkbookHelper( rHelper ),
+ maSharedItems( rHelper ),
+ maGroupItems( rHelper )
+{
+ maFieldModel.mbDatabaseField = bIsDatabaseField;
+}
+
+void PivotCacheField::importCacheField( const AttributeList& rAttribs )
+{
+ maFieldModel.maName = rAttribs.getXString( XML_name, OUString() );
+ maFieldModel.maCaption = rAttribs.getXString( XML_caption, OUString() );
+ maFieldModel.maPropertyName = rAttribs.getXString( XML_propertyName, OUString() );
+ maFieldModel.maFormula = rAttribs.getXString( XML_formula, OUString() );
+ maFieldModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
+ maFieldModel.mnSqlType = rAttribs.getInteger( XML_sqlType, 0 );
+ maFieldModel.mnHierarchy = rAttribs.getInteger( XML_hierarchy, 0 );
+ maFieldModel.mnLevel = rAttribs.getInteger( XML_level, 0 );
+ maFieldModel.mnMappingCount = rAttribs.getInteger( XML_mappingCount, 0 );
+ maFieldModel.mbDatabaseField = rAttribs.getBool( XML_databaseField, true );
+ maFieldModel.mbServerField = rAttribs.getBool( XML_serverField, false );
+ maFieldModel.mbUniqueList = rAttribs.getBool( XML_uniqueList, true );
+ maFieldModel.mbMemberPropField = rAttribs.getBool( XML_memberPropertyField, false );
+}
+
+void PivotCacheField::importSharedItems( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( maSharedItems.empty(), "PivotCacheField::importSharedItems - multiple shared items elements" );
+ maSharedItemsModel.mbHasSemiMixed = rAttribs.getBool( XML_containsSemiMixedTypes, true );
+ maSharedItemsModel.mbHasNonDate = rAttribs.getBool( XML_containsNonDate, true );
+ maSharedItemsModel.mbHasDate = rAttribs.getBool( XML_containsDate, false );
+ maSharedItemsModel.mbHasString = rAttribs.getBool( XML_containsString, true );
+ maSharedItemsModel.mbHasBlank = rAttribs.getBool( XML_containsBlank, false );
+ maSharedItemsModel.mbHasMixed = rAttribs.getBool( XML_containsMixedTypes, false );
+ maSharedItemsModel.mbIsNumeric = rAttribs.getBool( XML_containsNumber, false );
+ maSharedItemsModel.mbIsInteger = rAttribs.getBool( XML_containsInteger, false );
+ maSharedItemsModel.mbHasLongText = rAttribs.getBool( XML_longText, false );
+}
+
+void PivotCacheField::importSharedItem( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ maSharedItems.importItem( nElement, rAttribs );
+}
+
+void PivotCacheField::importFieldGroup( const AttributeList& rAttribs )
+{
+ maFieldGroupModel.mnParentField = rAttribs.getInteger( XML_par, -1 );
+ maFieldGroupModel.mnBaseField = rAttribs.getInteger( XML_base, -1 );
+}
+
+void PivotCacheField::importRangePr( const AttributeList& rAttribs )
+{
+ maFieldGroupModel.maStartDate = rAttribs.getDateTime( XML_startDate, DateTime() );
+ maFieldGroupModel.maEndDate = rAttribs.getDateTime( XML_endDate, DateTime() );
+ maFieldGroupModel.mfStartValue = rAttribs.getDouble( XML_startNum, 0.0 );
+ maFieldGroupModel.mfEndValue = rAttribs.getDouble( XML_endNum, 0.0 );
+ maFieldGroupModel.mfInterval = rAttribs.getDouble( XML_groupInterval, 1.0 );
+ maFieldGroupModel.mnGroupBy = rAttribs.getToken( XML_groupBy, XML_range );
+ maFieldGroupModel.mbRangeGroup = true;
+ maFieldGroupModel.mbDateGroup = maFieldGroupModel.mnGroupBy != XML_range;
+ maFieldGroupModel.mbAutoStart = rAttribs.getBool( XML_autoStart, true );
+ maFieldGroupModel.mbAutoEnd = rAttribs.getBool( XML_autoEnd, true );
+}
+
+void PivotCacheField::importDiscretePrItem( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ OSL_ENSURE( nElement == XLS_TOKEN( x ), "PivotCacheField::importDiscretePrItem - unexpected element" );
+ if( nElement == XLS_TOKEN( x ) )
+ maDiscreteItems.push_back( rAttribs.getInteger( XML_v, -1 ) );
+}
+
+void PivotCacheField::importGroupItem( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ maGroupItems.importItem( nElement, rAttribs );
+}
+
+void PivotCacheField::importPCDField( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags >> maFieldModel.mnNumFmtId;
+ maFieldModel.mnSqlType = rStrm.readInt16();
+ rStrm >> maFieldModel.mnHierarchy >> maFieldModel.mnLevel >> maFieldModel.mnMappingCount >> maFieldModel.maName;
+ if( getFlag( nFlags, BIFF12_PCDFIELD_HASCAPTION ) )
+ rStrm >> maFieldModel.maCaption;
+ if( getFlag( nFlags, BIFF12_PCDFIELD_HASFORMULA ) )
+ rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
+ if( maFieldModel.mnMappingCount > 0 )
+ rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
+ if( getFlag( nFlags, BIFF12_PCDFIELD_HASPROPERTYNAME ) )
+ rStrm >> maFieldModel.maPropertyName;
+
+ maFieldModel.mbDatabaseField = getFlag( nFlags, BIFF12_PCDFIELD_DATABASEFIELD );
+ maFieldModel.mbServerField = getFlag( nFlags, BIFF12_PCDFIELD_SERVERFIELD );
+ maFieldModel.mbUniqueList = !getFlag( nFlags, BIFF12_PCDFIELD_NOUNIQUEITEMS );
+ maFieldModel.mbMemberPropField = getFlag( nFlags, BIFF12_PCDFIELD_MEMBERPROPFIELD );
+}
+
+void PivotCacheField::importPCDFSharedItems( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ maSharedItemsModel.mbHasSemiMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSEMIMIXED );
+ maSharedItemsModel.mbHasNonDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASNONDATE );
+ maSharedItemsModel.mbHasDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASDATE );
+ maSharedItemsModel.mbHasString = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSTRING );
+ maSharedItemsModel.mbHasBlank = getFlag( nFlags, BIFF12_PCDFSITEMS_HASBLANK );
+ maSharedItemsModel.mbHasMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASMIXED );
+ maSharedItemsModel.mbIsNumeric = getFlag( nFlags, BIFF12_PCDFSITEMS_ISNUMERIC );
+ maSharedItemsModel.mbIsInteger = getFlag( nFlags, BIFF12_PCDFSITEMS_ISINTEGER );
+ maSharedItemsModel.mbHasLongText = getFlag( nFlags, BIFF12_PCDFSITEMS_HASLONGTEXT );
+}
+
+void PivotCacheField::importPCDFSharedItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ maSharedItems.importItem( nRecId, rStrm );
+}
+
+void PivotCacheField::importPCDFieldGroup( SequenceInputStream& rStrm )
+{
+ rStrm >> maFieldGroupModel.mnParentField >> maFieldGroupModel.mnBaseField;
+}
+
+void PivotCacheField::importPCDFRangePr( SequenceInputStream& rStrm )
+{
+ sal_uInt8 nGroupBy, nFlags;
+ rStrm >> nGroupBy >> nFlags >> maFieldGroupModel.mfStartValue >> maFieldGroupModel.mfEndValue >> maFieldGroupModel.mfInterval;
+
+ maFieldGroupModel.setBiffGroupBy( nGroupBy );
+ maFieldGroupModel.mbRangeGroup = true;
+ maFieldGroupModel.mbDateGroup = getFlag( nFlags, BIFF12_PCDFRANGEPR_DATEGROUP );
+ maFieldGroupModel.mbAutoStart = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOSTART );
+ maFieldGroupModel.mbAutoEnd = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOEND );
+
+ OSL_ENSURE( maFieldGroupModel.mbDateGroup == (maFieldGroupModel.mnGroupBy != XML_range), "PivotCacheField::importPCDFRangePr - wrong date flag" );
+ if( maFieldGroupModel.mbDateGroup )
+ {
+ maFieldGroupModel.maStartDate = getUnitConverter().calcDateTimeFromSerial( maFieldGroupModel.mfStartValue );
+ maFieldGroupModel.maEndDate = getUnitConverter().calcDateTimeFromSerial( maFieldGroupModel.mfEndValue );
+ }
+}
+
+void PivotCacheField::importPCDFDiscretePrItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( nRecId == BIFF12_ID_PCITEM_INDEX, "PivotCacheField::importPCDFDiscretePrItem - unexpected record" );
+ if( nRecId == BIFF12_ID_PCITEM_INDEX )
+ maDiscreteItems.push_back( rStrm.readInt32() );
+}
+
+void PivotCacheField::importPCDFGroupItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ maGroupItems.importItem( nRecId, rStrm );
+}
+
+void PivotCacheField::importPCDField( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags, nGroupItems, nBaseItems, nSharedItems;
+ rStrm >> nFlags;
+ maFieldGroupModel.mnParentField = rStrm.readuInt16();
+ maFieldGroupModel.mnBaseField = rStrm.readuInt16();
+ rStrm.skip( 2 ); // number of unique items (either shared or group)
+ rStrm >> nGroupItems >> nBaseItems >> nSharedItems;
+ maFieldModel.maName = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( true, getTextEncoding() );
+
+ maFieldModel.mbServerField = getFlag( nFlags, BIFF_PCDFIELD_SERVERFIELD );
+ maFieldModel.mbUniqueList = !getFlag( nFlags, BIFF_PCDFIELD_NOUNIQUEITEMS );
+ maSharedItemsModel.mbHasSemiMixed = getFlag( nFlags, BIFF_PCDFIELD_HASSEMIMIXED );
+ maSharedItemsModel.mbHasNonDate = getFlag( nFlags, BIFF_PCDFIELD_HASNONDATE );
+ maSharedItemsModel.mbHasDate = getFlag( nFlags, BIFF_PCDFIELD_HASDATE );
+ maSharedItemsModel.mbIsNumeric = getFlag( nFlags, BIFF_PCDFIELD_ISNUMERIC );
+ maSharedItemsModel.mbHasLongIndexes = getFlag( nFlags, BIFF_PCDFIELD_HASLONGINDEX );
+ maFieldGroupModel.mbRangeGroup = getFlag( nFlags, BIFF_PCDFIELD_RANGEGROUP );
+
+ // in BIFF, presence of parent group field is denoted by a flag
+ if( !getFlag( nFlags, BIFF_PCDFIELD_HASPARENT ) )
+ maFieldGroupModel.mnParentField = -1;
+
+ // following PCDFSQLTYPE record contains SQL type
+ if( (rStrm.getNextRecId() == BIFF_ID_PCDFSQLTYPE) && rStrm.startNextRecord() )
+ maFieldModel.mnSqlType = rStrm.readInt16();
+
+ // read group items, if any
+ if( nGroupItems > 0 )
+ {
+ OSL_ENSURE( getFlag( nFlags, BIFF_PCDFIELD_HASITEMS ), "PivotCacheField::importPCDField - missing items flag" );
+ maGroupItems.importItemList( rStrm, nGroupItems );
+
+ sal_uInt16 nNextRecId = rStrm.getNextRecId();
+ bool bHasRangePr = nNextRecId == BIFF_ID_PCDFRANGEPR;
+ bool bHasDiscretePr = nNextRecId == BIFF_ID_PCDFDISCRETEPR;
+
+ OSL_ENSURE( bHasRangePr || bHasDiscretePr, "PivotCacheField::importPCDField - missing group properties record" );
+ OSL_ENSURE( bHasRangePr == maFieldGroupModel.mbRangeGroup, "PivotCacheField::importPCDField - invalid range grouping flag" );
+ if( bHasRangePr && rStrm.startNextRecord() )
+ importPCDFRangePr( rStrm );
+ else if( bHasDiscretePr && rStrm.startNextRecord() )
+ importPCDFDiscretePr( rStrm );
+ }
+
+ // read the shared items, if any
+ if( nSharedItems > 0 )
+ {
+ OSL_ENSURE( getFlag( nFlags, BIFF_PCDFIELD_HASITEMS ), "PivotCacheField::importPCDField - missing items flag" );
+ maSharedItems.importItemList( rStrm, nSharedItems );
+ }
+}
+
+void PivotCacheField::importPCDFRangePr( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ maFieldGroupModel.setBiffGroupBy( extractValue< sal_uInt8 >( nFlags, 2, 3 ) );
+ maFieldGroupModel.mbRangeGroup = true;
+ maFieldGroupModel.mbDateGroup = maFieldGroupModel.mnGroupBy != XML_range;
+ maFieldGroupModel.mbAutoStart = getFlag( nFlags, BIFF_PCDFRANGEPR_AUTOSTART );
+ maFieldGroupModel.mbAutoEnd = getFlag( nFlags, BIFF_PCDFRANGEPR_AUTOEND );
+
+ /* Start, end, and interval are stored in 3 separate item records. Type of
+ the items is dependent on numeric/date mode. Numeric groups expect
+ three PCITEM_DOUBLE records, date groups expect two PCITEM_DATE records
+ and one PCITEM_INT record. */
+ PivotCacheItemList aLimits( *this );
+ aLimits.importItemList( rStrm, 3 );
+ OSL_ENSURE( aLimits.size() == 3, "PivotCacheField::importPCDFRangePr - missing grouping records" );
+ const PivotCacheItem* pStartValue = aLimits.getCacheItem( 0 );
+ const PivotCacheItem* pEndValue = aLimits.getCacheItem( 1 );
+ const PivotCacheItem* pInterval = aLimits.getCacheItem( 2 );
+ if( pStartValue && pEndValue && pInterval )
+ {
+ if( maFieldGroupModel.mbDateGroup )
+ {
+ bool bHasTypes = (pStartValue->getType() == XML_d) && (pEndValue->getType() == XML_d) && (pInterval->getType() == XML_i);
+ OSL_ENSURE( bHasTypes, "PivotCacheField::importPCDFRangePr - wrong data types in grouping items" );
+ if( bHasTypes )
+ {
+ maFieldGroupModel.maStartDate = pStartValue->getValue().get< DateTime >();
+ maFieldGroupModel.maEndDate = pEndValue->getValue().get< DateTime >();
+ maFieldGroupModel.mfInterval = pInterval->getValue().get< sal_Int16 >();
+ }
+ }
+ else
+ {
+ bool bHasTypes = (pStartValue->getType() == XML_n) && (pEndValue->getType() == XML_n) && (pInterval->getType() == XML_n);
+ OSL_ENSURE( bHasTypes, "PivotCacheField::importPCDFRangePr - wrong data types in grouping items" );
+ if( bHasTypes )
+ {
+ maFieldGroupModel.mfStartValue = pStartValue->getValue().get< double >();
+ maFieldGroupModel.mfEndValue = pEndValue->getValue().get< double >();
+ maFieldGroupModel.mfInterval = pInterval->getValue().get< double >();
+ }
+ }
+ }
+}
+
+void PivotCacheField::importPCDFDiscretePr( BiffInputStream& rStrm )
+{
+ sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.getLength() / 2 );
+ for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ maDiscreteItems.push_back( rStrm.readuInt16() );
+}
+
+const PivotCacheItem* PivotCacheField::getCacheItem( sal_Int32 nItemIdx ) const
+{
+ if( hasGroupItems() )
+ return maGroupItems.getCacheItem( nItemIdx );
+ if( hasSharedItems() )
+ return maSharedItems.getCacheItem( nItemIdx );
+ return 0;
+}
+
+void PivotCacheField::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
+{
+ if( hasGroupItems() )
+ maGroupItems.getCacheItemNames( orItemNames );
+ else if( hasSharedItems() )
+ maSharedItems.getCacheItemNames( orItemNames );
+}
+
+void PivotCacheField::convertNumericGrouping( const Reference< XDataPilotField >& rxDPField ) const
+{
+ OSL_ENSURE( hasGroupItems() && hasNumericGrouping(), "PivotCacheField::convertNumericGrouping - not a numeric group field" );
+ PropertySet aPropSet( rxDPField );
+ if( hasGroupItems() && hasNumericGrouping() && aPropSet.is() )
+ {
+ DataPilotFieldGroupInfo aGroupInfo;
+ aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
+ aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
+ aGroupInfo.HasDateValues = sal_False;
+ aGroupInfo.Start = maFieldGroupModel.mfStartValue;
+ aGroupInfo.End = maFieldGroupModel.mfEndValue;
+ aGroupInfo.Step = maFieldGroupModel.mfInterval;
+ aGroupInfo.GroupBy = 0;
+ aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
+ }
+}
+
+OUString PivotCacheField::createDateGroupField( const Reference< XDataPilotField >& rxBaseDPField ) const
+{
+ OSL_ENSURE( hasGroupItems() && hasDateGrouping(), "PivotCacheField::createDateGroupField - not a numeric group field" );
+ Reference< XDataPilotField > xDPGroupField;
+ PropertySet aPropSet( rxBaseDPField );
+ if( hasGroupItems() && hasDateGrouping() && aPropSet.is() )
+ {
+ bool bDayRanges = (maFieldGroupModel.mnGroupBy == XML_days) && (maFieldGroupModel.mfInterval >= 2.0);
+
+ DataPilotFieldGroupInfo aGroupInfo;
+ aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
+ aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
+ aGroupInfo.HasDateValues = sal_True;
+ aGroupInfo.Start = getUnitConverter().calcSerialFromDateTime( maFieldGroupModel.maStartDate );
+ aGroupInfo.End = getUnitConverter().calcSerialFromDateTime( maFieldGroupModel.maEndDate );
+ aGroupInfo.Step = bDayRanges ? maFieldGroupModel.mfInterval : 0.0;
+
+ using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
+ switch( maFieldGroupModel.mnGroupBy )
+ {
+ case XML_years: aGroupInfo.GroupBy = YEARS; break;
+ case XML_quarters: aGroupInfo.GroupBy = QUARTERS; break;
+ case XML_months: aGroupInfo.GroupBy = MONTHS; break;
+ case XML_days: aGroupInfo.GroupBy = DAYS; break;
+ case XML_hours: aGroupInfo.GroupBy = HOURS; break;
+ case XML_minutes: aGroupInfo.GroupBy = MINUTES; break;
+ case XML_seconds: aGroupInfo.GroupBy = SECONDS; break;
+ default: OSL_ENSURE( false, "PivotCacheField::convertRangeGrouping - unknown date/time interval" );
+ }
+
+ try
+ {
+ Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY_THROW );
+ xDPGroupField = xDPGrouping->createDateGroup( aGroupInfo );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
+ return xFieldName.is() ? xFieldName->getName() : OUString();
+}
+
+OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotField >& rxBaseDPField, PivotCacheGroupItemVector& orItemNames ) const
+{
+ OSL_ENSURE( hasGroupItems() && !maDiscreteItems.empty(), "PivotCacheField::createParentGroupField - not a group field" );
+ OSL_ENSURE( maDiscreteItems.size() == orItemNames.size(), "PivotCacheField::createParentGroupField - number of item names does not match grouping info" );
+ Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY );
+ if( !xDPGrouping.is() ) return OUString();
+
+ // map the group item indexes from maGroupItems to all item indexes from maDiscreteItems
+ typedef ::std::vector< sal_Int32 > GroupItemList;
+ typedef ::std::vector< GroupItemList > GroupItemMap;
+ GroupItemMap aItemMap( maGroupItems.size() );
+ for( IndexVector::const_iterator aBeg = maDiscreteItems.begin(), aIt = aBeg, aEnd = maDiscreteItems.end(); aIt != aEnd; ++aIt )
+ if( GroupItemList* pItems = ContainerHelper::getVectorElementAccess( aItemMap, *aIt ) )
+ pItems->push_back( static_cast< sal_Int32 >( aIt - aBeg ) );
+
+ // process all groups
+ Reference< XDataPilotField > xDPGroupField;
+ for( GroupItemMap::iterator aBeg = aItemMap.begin(), aIt = aBeg, aEnd = aItemMap.end(); aIt != aEnd; ++aIt )
+ {
+ OSL_ENSURE( !aIt->empty(), "PivotCacheField::createParentGroupField - item/group should not be empty" );
+ // if the item count is greater than 1, the item is a group of items
+ if( aIt->size() > 1 )
+ {
+ /* Insert the names of the items that are part of this group. Calc
+ expects the names of the members of the field whose members are
+ grouped (which may be the names of groups too). Excel provides
+ the names of the base field items instead (no group names
+ involved). Therefore, the passed collection of current item
+ names as they are already grouped is used here to resolve the
+ item names. */
+ ::std::vector< OUString > aMembers;
+ for( GroupItemList::iterator aBeg2 = aIt->begin(), aIt2 = aBeg2, aEnd2 = aIt->end(); aIt2 != aEnd2; ++aIt2 )
+ if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, *aIt2 ) )
+ if( ::std::find( aMembers.begin(), aMembers.end(), pName->maGroupName ) == aMembers.end() )
+ aMembers.push_back( pName->maGroupName );
+
+ /* Check again, that this is not just a group that is not grouped
+ further with other items. */
+ if( aMembers.size() > 1 ) try
+ {
+ // only the first call of createNameGroup() returns the new field
+ Reference< XDataPilotField > xDPNewField = xDPGrouping->createNameGroup( ContainerHelper::vectorToSequence( aMembers ) );
+ OSL_ENSURE( xDPGroupField.is() != xDPNewField.is(), "PivotCacheField::createParentGroupField - missing group field" );
+ if( !xDPGroupField.is() )
+ xDPGroupField = xDPNewField;
+
+ // get current grouping info
+ DataPilotFieldGroupInfo aGroupInfo;
+ PropertySet aPropSet( xDPGroupField );
+ aPropSet.getProperty( aGroupInfo, PROP_GroupInfo );
+
+ /* Find the group object and the auto-generated group name.
+ The returned field contains all groups derived from the
+ previous field if that is grouped too. To find the correct
+ group, the first item used to create the group is serached.
+ Calc provides the original item names of the base field
+ when the group is querried for its members. Its does not
+ provide the names of members that are already groups in the
+ field used to create the new groups. (Is this a bug?)
+ Therefore, a name from the passed list of original item
+ names is used to find the correct group. */
+ OUString aFirstItem;
+ if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, aIt->front() ) )
+ aFirstItem = pName->maOrigName;
+ Reference< XNamed > xGroupName;
+ OUString aAutoName;
+ Reference< XIndexAccess > xGroupsIA( aGroupInfo.Groups, UNO_QUERY_THROW );
+ for( sal_Int32 nIdx = 0, nCount = xGroupsIA->getCount(); (nIdx < nCount) && (aAutoName.getLength() == 0); ++nIdx ) try
+ {
+ Reference< XNameAccess > xItemsNA( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
+ if( xItemsNA->hasByName( aFirstItem ) )
+ {
+ xGroupName.set( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
+ aAutoName = xGroupName->getName();
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( aAutoName.getLength() > 0, "PivotCacheField::createParentGroupField - cannot find auto-generated group name" );
+
+ // get the real group name from the list of group items
+ OUString aGroupName;
+ if( const PivotCacheItem* pGroupItem = maGroupItems.getCacheItem( static_cast< sal_Int32 >( aIt - aBeg ) ) )
+ aGroupName = pGroupItem->getName();
+ OSL_ENSURE( aGroupName.getLength() > 0, "PivotCacheField::createParentGroupField - cannot find group name" );
+ if( aGroupName.getLength() == 0 )
+ aGroupName = aAutoName;
+
+ if( xGroupName.is() && (aGroupName.getLength() > 0) )
+ {
+ // replace the auto-generated group name with the real name
+ if( aAutoName != aGroupName )
+ {
+ xGroupName->setName( aGroupName );
+ aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
+ }
+ // replace original item names in passed vector with group name
+ for( GroupItemList::iterator aIt2 = aIt->begin(), aEnd2 = aIt->end(); aIt2 != aEnd2; ++aIt2 )
+ if( PivotCacheGroupItem* pName = ContainerHelper::getVectorElementAccess( orItemNames, *aIt2 ) )
+ pName->maGroupName = aGroupName;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+
+ Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
+ return xFieldName.is() ? xFieldName->getName() : OUString();
+}
+
+void PivotCacheField::writeSourceHeaderCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ rSheetHelper.setStringCell( rSheetHelper.getCell( CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow ) ), maFieldModel.maName );
+}
+
+void PivotCacheField::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
+{
+ bool bHasIndex = rItem.getType() == XML_x;
+ OSL_ENSURE( bHasIndex != maSharedItems.empty(), "PivotCacheField::writeSourceDataCell - shared items missing or not expected" );
+ if( bHasIndex )
+ writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem.getValue().get< sal_Int32 >() );
+ else
+ writeItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem );
+}
+
+void PivotCacheField::importPCRecordItem( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ if( hasSharedItems() )
+ {
+ writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rStrm.readInt32() );
+ }
+ else
+ {
+ PivotCacheItem aItem;
+ if( maSharedItemsModel.mbIsNumeric )
+ aItem.readDouble( rStrm );
+ else if( maSharedItemsModel.mbHasDate && !maSharedItemsModel.mbHasString )
+ aItem.readDate( rStrm );
+ else
+ aItem.readString( rStrm );
+ writeItemToSourceDataCell( rSheetHelper, nCol, nRow, aItem );
+ }
+}
+
+void PivotCacheField::importPCItemIndex( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ OSL_ENSURE( hasSharedItems(), "PivotCacheField::importPCItemIndex - invalid call, no shared items found" );
+ sal_Int32 nIndex = maSharedItemsModel.mbHasLongIndexes ? rStrm.readuInt16() : rStrm.readuInt8();
+ writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, nIndex );
+}
+
+// private --------------------------------------------------------------------
+
+void PivotCacheField::writeItemToSourceDataCell( WorksheetHelper& rSheetHelper,
+ sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
+{
+ if( rItem.getType() != XML_m )
+ {
+ Reference< XCell > xCell = rSheetHelper.getCell( CellAddress( rSheetHelper.getSheetIndex(), nCol, nRow ) );
+ if( xCell.is() ) switch( rItem.getType() )
+ {
+ case XML_s: rSheetHelper.setStringCell( xCell, rItem.getValue().get< OUString >() ); break;
+ case XML_n: xCell->setValue( rItem.getValue().get< double >() ); break;
+ case XML_i: xCell->setValue( rItem.getValue().get< sal_Int16 >() ); break;
+ case XML_d: rSheetHelper.setDateTimeCell( xCell, rItem.getValue().get< DateTime >() ); break;
+ case XML_b: rSheetHelper.setBooleanCell( xCell, rItem.getValue().get< bool >() ); break;
+ case XML_e: rSheetHelper.setErrorCell( xCell, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break;
+ default: OSL_ENSURE( false, "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" );
+ }
+ }
+}
+
+void PivotCacheField::writeSharedItemToSourceDataCell(
+ WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nItemIdx ) const
+{
+ if( const PivotCacheItem* pCacheItem = maSharedItems.getCacheItem( nItemIdx ) )
+ writeItemToSourceDataCell( rSheetHelper, nCol, nRow, *pCacheItem );
+}
+
+// ============================================================================
+
+PCDefinitionModel::PCDefinitionModel() :
+ mfRefreshedDate( 0.0 ),
+ mnRecords( 0 ),
+ mnMissItemsLimit( 0 ),
+ mnDatabaseFields( 0 ),
+ mbInvalid( false ),
+ mbSaveData( true ),
+ mbRefreshOnLoad( false ),
+ mbOptimizeMemory( false ),
+ mbEnableRefresh( true ),
+ mbBackgroundQuery( false ),
+ mbUpgradeOnRefresh( false ),
+ mbTupleCache( false ),
+ mbSupportSubquery( false ),
+ mbSupportDrill( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PCSourceModel::PCSourceModel() :
+ mnSourceType( XML_TOKEN_INVALID ),
+ mnConnectionId( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PCWorksheetSourceModel::PCWorksheetSourceModel()
+{
+ maRange.StartColumn = maRange.StartRow = maRange.EndColumn = maRange.EndRow = -1;
+}
+
+// ----------------------------------------------------------------------------
+
+PivotCache::PivotCache( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mbValidSource( false ),
+ mbDummySheet( false )
+{
+}
+
+void PivotCache::importPivotCacheDefinition( const AttributeList& rAttribs )
+{
+ maDefModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
+ maDefModel.maRefreshedBy = rAttribs.getXString( XML_refreshedBy, OUString() );
+ maDefModel.mfRefreshedDate = rAttribs.getDouble( XML_refreshedDate, 0.0 );
+ maDefModel.mnRecords = rAttribs.getInteger( XML_recordCount, 0 );
+ maDefModel.mnMissItemsLimit = rAttribs.getInteger( XML_missingItemsLimit, 0 );
+ maDefModel.mbInvalid = rAttribs.getBool( XML_invalid, false );
+ maDefModel.mbSaveData = rAttribs.getBool( XML_saveData, true );
+ maDefModel.mbRefreshOnLoad = rAttribs.getBool( XML_refreshOnLoad, false );
+ maDefModel.mbOptimizeMemory = rAttribs.getBool( XML_optimizeMemory, false );
+ maDefModel.mbEnableRefresh = rAttribs.getBool( XML_enableRefresh, true );
+ maDefModel.mbBackgroundQuery = rAttribs.getBool( XML_backgroundQuery, false );
+ maDefModel.mbUpgradeOnRefresh = rAttribs.getBool( XML_upgradeOnRefresh, false );
+ maDefModel.mbTupleCache = rAttribs.getBool( XML_tupleCache, false );
+ maDefModel.mbSupportSubquery = rAttribs.getBool( XML_supportSubquery, false );
+ maDefModel.mbSupportDrill = rAttribs.getBool( XML_supportAdvancedDrill, false );
+}
+
+void PivotCache::importCacheSource( const AttributeList& rAttribs )
+{
+ maSourceModel.mnSourceType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
+ maSourceModel.mnConnectionId = rAttribs.getInteger( XML_connectionId, 0 );
+}
+
+void PivotCache::importWorksheetSource( const AttributeList& rAttribs, const Relations& rRelations )
+{
+ maSheetSrcModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
+ maSheetSrcModel.maSheet = rAttribs.getXString( XML_sheet, OUString() );
+ maSheetSrcModel.maDefName = rAttribs.getXString( XML_name, OUString() );
+
+ // resolve URL of external document
+ maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
+ // store range address unchecked with sheet index 0, will be resolved/checked later
+ getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, rAttribs.getString( XML_ref, OUString() ), 0 );
+}
+
+void PivotCache::importPCDefinition( SequenceInputStream& rStrm )
+{
+ sal_uInt8 nFlags1, nFlags2;
+ rStrm.skip( 3 ); // create/refresh version id's
+ rStrm >> nFlags1 >> maDefModel.mnMissItemsLimit >> maDefModel.mfRefreshedDate >> nFlags2 >> maDefModel.mnRecords;
+ if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASUSERNAME ) )
+ rStrm >> maDefModel.maRefreshedBy;
+ if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASRELID ) )
+ rStrm >> maDefModel.maRelId;
+
+ maDefModel.mbInvalid = getFlag( nFlags1, BIFF12_PCDEFINITION_INVALID );
+ maDefModel.mbSaveData = getFlag( nFlags1, BIFF12_PCDEFINITION_SAVEDATA );
+ maDefModel.mbRefreshOnLoad = getFlag( nFlags1, BIFF12_PCDEFINITION_REFRESHONLOAD );
+ maDefModel.mbOptimizeMemory = getFlag( nFlags1, BIFF12_PCDEFINITION_OPTIMIZEMEMORY );
+ maDefModel.mbEnableRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_ENABLEREFRESH );
+ maDefModel.mbBackgroundQuery = getFlag( nFlags1, BIFF12_PCDEFINITION_BACKGROUNDQUERY );
+ maDefModel.mbUpgradeOnRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_UPGRADEONREFR );
+ maDefModel.mbTupleCache = getFlag( nFlags1, BIFF12_PCDEFINITION_TUPELCACHE );
+ maDefModel.mbSupportSubquery = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTSUBQUERY );
+ maDefModel.mbSupportDrill = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTDRILL );
+}
+
+void PivotCache::importPCDSource( SequenceInputStream& rStrm )
+{
+ sal_Int32 nSourceType;
+ rStrm >> nSourceType >> maSourceModel.mnConnectionId;
+ static const sal_Int32 spnSourceTypes[] = { XML_worksheet, XML_external, XML_consolidation, XML_scenario };
+ maSourceModel.mnSourceType = STATIC_ARRAY_SELECT( spnSourceTypes, nSourceType, XML_TOKEN_INVALID );
+}
+
+void PivotCache::importPCDSheetSource( SequenceInputStream& rStrm, const Relations& rRelations )
+{
+ sal_uInt8 nIsDefName, nIsBuiltinName, nFlags;
+ rStrm >> nIsDefName >> nIsBuiltinName >> nFlags;
+ if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASSHEET ) )
+ rStrm >> maSheetSrcModel.maSheet;
+ if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASRELID ) )
+ rStrm >> maSheetSrcModel.maRelId;
+
+ // read cell range or defined name
+ if( nIsDefName == 0 )
+ {
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ // store range address unchecked with sheet index 0, will be resolved/checked later
+ getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, aBinRange, 0 );
+ }
+ else
+ {
+ rStrm >> maSheetSrcModel.maDefName;
+ if( nIsBuiltinName != 0 )
+ maSheetSrcModel.maDefName = CREATE_OUSTRING( "_xlnm." ) + maSheetSrcModel.maDefName;
+ }
+
+ // resolve URL of external document
+ maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
+}
+
+void PivotCache::importPCDSource( BiffInputStream& rStrm )
+{
+ switch( rStrm.readuInt16() )
+ {
+ case BIFF_PCDSOURCE_WORKSHEET:
+ {
+ maSourceModel.mnSourceType = XML_worksheet;
+ sal_uInt16 nNextRecId = rStrm.getNextRecId();
+ switch( nNextRecId )
+ {
+ case BIFF_ID_DCONREF: if( rStrm.startNextRecord() ) importDConRef( rStrm ); break;
+ case BIFF_ID_DCONNAME: if( rStrm.startNextRecord() ) importDConName( rStrm ); break;
+ case BIFF_ID_DCONBINAME: if( rStrm.startNextRecord() ) importDConBIName( rStrm ); break;
+ }
+ }
+ break;
+ case BIFF_PCDSOURCE_EXTERNAL:
+ maSourceModel.mnSourceType = XML_external;
+ break;
+ case BIFF_PCDSOURCE_CONSOLIDATION:
+ maSourceModel.mnSourceType = XML_consolidation;
+ break;
+ case BIFF_PCDSOURCE_SCENARIO:
+ maSourceModel.mnSourceType = XML_scenario;
+ break;
+ default:
+ maSourceModel.mnSourceType = XML_TOKEN_INVALID;
+ }
+}
+
+void PivotCache::importPCDefinition( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags, nUserNameLen;
+ rStrm >> maDefModel.mnRecords;
+ rStrm.skip( 2 ); // repeated cache ID
+ rStrm >> nFlags;
+ rStrm.skip( 2 ); // unused
+ rStrm >> maDefModel.mnDatabaseFields;
+ rStrm.skip( 6 ); // total field count, report record count, (repeated) cache type
+ rStrm >> nUserNameLen;
+ if( nUserNameLen != BIFF_PC_NOSTRING )
+ maDefModel.maRefreshedBy = (getBiff() == BIFF8) ?
+ rStrm.readUniString( nUserNameLen ) :
+ rStrm.readCharArrayUC( nUserNameLen, getTextEncoding() );
+
+ maDefModel.mbInvalid = getFlag( nFlags, BIFF_PCDEFINITION_INVALID );
+ maDefModel.mbSaveData = getFlag( nFlags, BIFF_PCDEFINITION_SAVEDATA );
+ maDefModel.mbRefreshOnLoad = getFlag( nFlags, BIFF_PCDEFINITION_REFRESHONLOAD );
+ maDefModel.mbOptimizeMemory = getFlag( nFlags, BIFF_PCDEFINITION_OPTIMIZEMEMORY );
+ maDefModel.mbEnableRefresh = getFlag( nFlags, BIFF_PCDEFINITION_ENABLEREFRESH );
+ maDefModel.mbBackgroundQuery = getFlag( nFlags, BIFF_PCDEFINITION_BACKGROUNDQUERY );
+
+ if( (rStrm.getNextRecId() == BIFF_ID_PCDEFINITION2) && rStrm.startNextRecord() )
+ rStrm >> maDefModel.mfRefreshedDate;
+}
+
+PivotCacheField& PivotCache::createCacheField( bool bInitDatabaseField )
+{
+ bool bIsDatabaseField = !bInitDatabaseField || (maFields.size() < maDefModel.mnDatabaseFields);
+ PivotCacheFieldVector::value_type xCacheField( new PivotCacheField( *this, bIsDatabaseField ) );
+ maFields.push_back( xCacheField );
+ return *xCacheField;
+}
+
+void PivotCache::finalizeImport()
+{
+ // collect all fields that are based on source data (needed to finalize source data below)
+ OSL_ENSURE( !maFields.empty(), "PivotCache::finalizeImport - no pivot cache fields found" );
+ for( PivotCacheFieldVector::const_iterator aIt = maFields.begin(), aEnd = maFields.end(); aIt != aEnd; ++aIt )
+ {
+ if( (*aIt)->isDatabaseField() )
+ {
+ OSL_ENSURE( (aIt == maFields.begin()) || (*(aIt - 1))->isDatabaseField(),
+ "PivotCache::finalizeImport - database field follows a calculated field" );
+ maDatabaseIndexes.push_back( static_cast< sal_Int32 >( maDatabaseFields.size() ) );
+ maDatabaseFields.push_back( *aIt );
+ }
+ else
+ {
+ maDatabaseIndexes.push_back( -1 );
+ }
+ }
+ OSL_ENSURE( !maDatabaseFields.empty(), "PivotCache::finalizeImport - no pivot cache source fields found" );
+
+ // finalize source data depending on source type
+ switch( maSourceModel.mnSourceType )
+ {
+ case XML_worksheet:
+ {
+ // decide whether an external document is used
+ bool bInternal = (maTargetUrl.getLength() == 0) && (maSheetSrcModel.maRelId.getLength() == 0);
+ bool bExternal = maTargetUrl.getLength() > 0; // relation ID may be empty, e.g. BIFF import
+ OSL_ENSURE( bInternal || bExternal, "PivotCache::finalizeImport - invalid external document URL" );
+ if( bInternal )
+ finalizeInternalSheetSource();
+ else if( bExternal )
+ finalizeExternalSheetSource();
+ }
+ break;
+
+ // currently, we only support worksheet data sources
+ case XML_external:
+ break;
+ case XML_consolidation:
+ break;
+ case XML_scenario:
+ break;
+ }
+}
+
+sal_Int32 PivotCache::getCacheFieldCount() const
+{
+ return static_cast< sal_Int32 >( maFields.size() );
+}
+
+const PivotCacheField* PivotCache::getCacheField( sal_Int32 nFieldIdx ) const
+{
+ return maFields.get( nFieldIdx ).get();
+}
+
+sal_Int32 PivotCache::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
+{
+ return ContainerHelper::getVectorElement( maDatabaseIndexes, nFieldIdx, -1 );
+}
+
+void PivotCache::writeSourceHeaderCells( WorksheetHelper& rSheetHelper ) const
+{
+ OSL_ENSURE( static_cast< size_t >( maSheetSrcModel.maRange.EndColumn - maSheetSrcModel.maRange.StartColumn + 1 ) == maDatabaseFields.size(),
+ "PivotCache::writeSourceHeaderCells - source cell range width does not match number of source fields" );
+ sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
+ sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
+ sal_Int32 nRow = maSheetSrcModel.maRange.StartRow;
+ for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
+ (*aIt)->writeSourceHeaderCell( rSheetHelper, nCol, nRow );
+}
+
+void PivotCache::writeSourceDataCell( WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
+{
+ OSL_ENSURE( (0 <= nCol) && (nCol <= maSheetSrcModel.maRange.EndColumn - maSheetSrcModel.maRange.StartColumn), "PivotCache::writeSourceDataCell - invalid column index" );
+ OSL_ENSURE( (0 < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow - maSheetSrcModel.maRange.StartRow), "PivotCache::writeSourceDataCell - invalid row index" );
+ if( const PivotCacheField* pCacheField = maDatabaseFields.get( nCol ).get() )
+ pCacheField->writeSourceDataCell( rSheetHelper, maSheetSrcModel.maRange.StartColumn + nCol, maSheetSrcModel.maRange.StartRow + nRow, rItem );
+}
+
+void PivotCache::importPCRecord( SequenceInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const
+{
+ OSL_ENSURE( (0 < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow - maSheetSrcModel.maRange.StartRow), "PivotCache::importPCRecord - invalid row index" );
+ sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
+ sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
+ nRow += maSheetSrcModel.maRange.StartRow;
+ for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
+ (*aIt)->importPCRecordItem( rStrm, rSheetHelper, nCol, nRow );
+}
+
+void PivotCache::importPCItemIndexList( BiffInputStream& rStrm, WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const
+{
+ OSL_ENSURE( (0 < nRow) && (nRow <= maSheetSrcModel.maRange.EndRow - maSheetSrcModel.maRange.StartRow), "PivotCache::importPCItemIndexList - invalid row index" );
+ sal_Int32 nCol = maSheetSrcModel.maRange.StartColumn;
+ sal_Int32 nMaxCol = getAddressConverter().getMaxApiAddress().Column;
+ nRow += maSheetSrcModel.maRange.StartRow;
+ for( PivotCacheFieldVector::const_iterator aIt = maDatabaseFields.begin(), aEnd = maDatabaseFields.end(); !rStrm.isEof() && (aIt != aEnd) && (nCol <= nMaxCol); ++aIt, ++nCol )
+ if( (*aIt)->hasSharedItems() )
+ (*aIt)->importPCItemIndex( rStrm, rSheetHelper, nCol, nRow );
+}
+
+// private --------------------------------------------------------------------
+
+void PivotCache::importDConRef( BiffInputStream& rStrm )
+{
+ BinRange aBinRange;
+ aBinRange.read( rStrm, false ); // always 8-bit column indexes
+ // store range address unchecked with sheet index 0, will be resolved/checked later
+ getAddressConverter().convertToCellRangeUnchecked( maSheetSrcModel.maRange, aBinRange, 0 );
+
+ // the URL with (required) sheet name and optional URL of an external document
+ importDConUrl( rStrm );
+ OSL_ENSURE( maSheetSrcModel.maSheet.getLength() > 0, "PivotCache::importDConRef - missing sheet name" );
+}
+
+void PivotCache::importDConName( BiffInputStream& rStrm )
+{
+ maSheetSrcModel.maDefName = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
+ OSL_ENSURE( maSheetSrcModel.maDefName.getLength() > 0, "PivotCache::importDConName - missing defined name" );
+ importDConUrl( rStrm );
+}
+
+void PivotCache::importDConBIName( BiffInputStream& rStrm )
+{
+ sal_uInt8 nNameId = rStrm.readuInt8();
+ rStrm.skip( 3 );
+ maSheetSrcModel.maDefName = OUString( sal_Unicode( nNameId ) );
+ importDConUrl( rStrm );
+}
+
+void PivotCache::importDConUrl( BiffInputStream& rStrm )
+{
+ // the URL with sheet name and optional URL of an external document
+ OUString aEncodedUrl;
+ if( getBiff() == BIFF8 )
+ {
+ // empty string does not contain a flags byte, cannot use simple readUniString() here...
+ sal_uInt16 nChars = rStrm.readuInt16();
+ if( nChars > 0 )
+ aEncodedUrl = rStrm.readUniString( nChars );
+ }
+ else
+ {
+ aEncodedUrl = rStrm.readByteStringUC( false, getTextEncoding() );
+ }
+
+ if( aEncodedUrl.getLength() > 0 )
+ {
+ OUString aClassName;
+ getAddressConverter().parseBiffTargetUrl( aClassName, maTargetUrl, maSheetSrcModel.maSheet, aEncodedUrl, true );
+ }
+}
+
+void PivotCache::finalizeInternalSheetSource()
+{
+ // resolve sheet name to sheet index
+ sal_Int16 nSheet = getWorksheets().getCalcSheetIndex( maSheetSrcModel.maSheet );
+
+ // if cache is based on a defined name or table, try to resolve to cell range
+ if( maSheetSrcModel.maDefName.getLength() > 0 )
+ {
+ // local or global defined name
+ if( const DefinedName* pDefName = getDefinedNames().getByModelName( maSheetSrcModel.maDefName, nSheet ).get() )
+ {
+ mbValidSource = pDefName->getAbsoluteRange( maSheetSrcModel.maRange );
+ }
+ // table
+ else if( const Table* pTable = getTables().getTable( maSheetSrcModel.maDefName ).get() )
+ {
+ // get original range from table, but exclude the totals row(s)
+ maSheetSrcModel.maRange = pTable->getOriginalRange();
+ mbValidSource = (pTable->getHeight() - pTable->getTotalsRows()) > 1;
+ if( mbValidSource )
+ maSheetSrcModel.maRange.EndRow -= pTable->getTotalsRows();
+ }
+ }
+ // else try the cell range (if the sheet exists)
+ else if( nSheet >= 0 )
+ {
+ // insert sheet index into the range, range address will be checked below
+ maSheetSrcModel.maRange.Sheet = nSheet;
+ mbValidSource = true;
+ }
+ // else sheet has been deleted, generate the source data from cache
+ else if( maSheetSrcModel.maSheet.getLength() > 0 )
+ {
+ prepareSourceDataSheet();
+ // return here to skip the source range check below
+ return;
+ }
+
+ // check range location, do not allow ranges that overflow the sheet partly
+ mbValidSource = mbValidSource &&
+ getAddressConverter().checkCellRange( maSheetSrcModel.maRange, false, true ) &&
+ (maSheetSrcModel.maRange.StartRow < maSheetSrcModel.maRange.EndRow);
+}
+
+void PivotCache::finalizeExternalSheetSource()
+{
+ /* If pivot cache is based on external sheet data, try to restore sheet
+ data from cache records. No support for external defined names or tables,
+ sheet name and path to cache records fragment (OOXML only) are required. */
+ bool bHasRelation = (getFilterType() == FILTER_BIFF) || (maDefModel.maRelId.getLength() > 0);
+ if( bHasRelation && (maSheetSrcModel.maDefName.getLength() == 0) && (maSheetSrcModel.maSheet.getLength() > 0) )
+ prepareSourceDataSheet();
+}
+
+void PivotCache::prepareSourceDataSheet()
+{
+ // data will be inserted in top-left cell, sheet index is still set to 0 (will be set below)
+ maSheetSrcModel.maRange.EndColumn -= maSheetSrcModel.maRange.StartColumn;
+ maSheetSrcModel.maRange.StartColumn = 0;
+ maSheetSrcModel.maRange.EndRow -= maSheetSrcModel.maRange.StartRow;
+ maSheetSrcModel.maRange.StartRow = 0;
+ // check range location, do not allow ranges that overflow the sheet partly
+ if( getAddressConverter().checkCellRange( maSheetSrcModel.maRange, false, true ) )
+ {
+ OUString aSheetName = CREATE_OUSTRING( "DPCache_" ) + maSheetSrcModel.maSheet;
+ maSheetSrcModel.maRange.Sheet = getWorksheets().insertEmptySheet( aSheetName, false );
+ mbValidSource = mbDummySheet = maSheetSrcModel.maRange.Sheet >= 0;
+ }
+}
+
+// ============================================================================
+
+PivotCacheBuffer::PivotCacheBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void PivotCacheBuffer::registerPivotCacheFragment( sal_Int32 nCacheId, const OUString& rFragmentPath )
+{
+ OSL_ENSURE( nCacheId >= 0, "PivotCacheBuffer::registerPivotCacheFragment - invalid pivot cache identifier" );
+ OSL_ENSURE( maFragmentPaths.count( nCacheId ) == 0, "PivotCacheBuffer::registerPivotCacheFragment - fragment path exists already" );
+ if( (nCacheId >= 0) && (rFragmentPath.getLength() > 0) )
+ maFragmentPaths[ nCacheId ] = rFragmentPath;
+}
+
+void PivotCacheBuffer::importPivotCacheRef( BiffInputStream& rStrm )
+{
+ // read the PIVOTCACHE record that contains the stream ID
+ sal_Int32 nCacheId = rStrm.readuInt16();
+ OSL_ENSURE( maFragmentPaths.count( nCacheId ) == 0, "PivotCacheBuffer::importPivotCacheRef - cache stream exists already" );
+ OUStringBuffer aStrmName;
+ static const sal_Unicode spcHexChars[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
+ for( sal_uInt8 nBit = 0; nBit < 16; nBit += 4 )
+ aStrmName.insert( 0, spcHexChars[ extractValue< size_t >( nCacheId, nBit, 4 ) ] );
+ aStrmName.insert( 0, (getBiff() == BIFF8) ? CREATE_OUSTRING( "_SX_DB_CUR/" ) : CREATE_OUSTRING( "_SX_DB/" ) );
+ maFragmentPaths[ nCacheId ] = aStrmName.makeStringAndClear();
+
+ // try to read PCDSOURCE record (will read following data location records too)
+ sal_uInt16 nNextRecId = rStrm.getNextRecId();
+ OSL_ENSURE( nNextRecId == BIFF_ID_PCDSOURCE, "PivotCacheBuffer::importPivotCacheRef - PCDSOURCE record expected" );
+ if( (nNextRecId == BIFF_ID_PCDSOURCE) && rStrm.startNextRecord() )
+ createPivotCache( nCacheId ).importPCDSource( rStrm );
+}
+
+PivotCache* PivotCacheBuffer::importPivotCacheFragment( sal_Int32 nCacheId )
+{
+ switch( getFilterType() )
+ {
+ /* OOXML/BIFF12 filter: On first call for the cache ID, the pivot
+ cache object is created and inserted into maCaches. Then, the cache
+ definition fragment is read and the cache is returned. On
+ subsequent calls, the created cache will be found in maCaches and
+ returned immediately. */
+ case FILTER_OOXML:
+ {
+ // try to find an imported pivot cache
+ if( PivotCache* pCache = maCaches.get( nCacheId ).get() )
+ return pCache;
+
+ // check if a fragment path exists for the passed cache identifier
+ FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
+ if( aIt == maFragmentPaths.end() )
+ return 0;
+
+ /* Import the cache fragment. This may create a dummy data sheet
+ for external sheet sources. */
+ PivotCache& rCache = createPivotCache( nCacheId );
+ importOoxFragment( new PivotCacheDefinitionFragment( *this, aIt->second, rCache ) );
+ return &rCache;
+ }
+
+ /* BIFF filter: Pivot table provides 0-based index into list of pivot
+ cache source links (PIVOTCACHE/PCDSOURCE/... record blocks in
+ workbook stream). First, this index has to be resolved to the cache
+ identifier that is used to manage the cache stream names (the
+ maFragmentPaths member). The cache object itself exists already
+ before the first call for the cache source index (see
+ PivotCacheBuffer::importPivotCacheRef() above), because source data
+ link is part of workbook data, not of the cache stream. To detect
+ subsequent calls with an already initialized cache, the entry in
+ maFragmentPaths will be removed after reading the cache stream. */
+ case FILTER_BIFF:
+ {
+ /* Resolve cache index to cache identifier and try to find pivot
+ cache. Cache must exist already for a valid cache index. */
+ nCacheId = ContainerHelper::getVectorElement( maCacheIds, nCacheId, -1 );
+ PivotCache* pCache = maCaches.get( nCacheId ).get();
+ if( !pCache )
+ return 0;
+
+ /* Try to find fragment path entry (stream name). If missing, the
+ stream has been read already, and the cache can be returned. */
+ FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
+ if( aIt != maFragmentPaths.end() )
+ {
+ /* Import the cache stream. This may create a dummy data sheet
+ for external sheet sources. */
+ BiffPivotCacheFragment( *this, aIt->second, *pCache ).importFragment();
+ // remove the fragment entry to mark that the cache is initialized
+ maFragmentPaths.erase( aIt );
+ }
+ return pCache;
+ }
+
+ case FILTER_UNKNOWN:
+ OSL_ENSURE( false, "PivotCacheBuffer::importPivotCacheFragment - unknown filter type" );
+ }
+ return 0;
+}
+
+PivotCache& PivotCacheBuffer::createPivotCache( sal_Int32 nCacheId )
+{
+ maCacheIds.push_back( nCacheId );
+ PivotCacheMap::mapped_type& rxCache = maCaches[ nCacheId ];
+ rxCache.reset( new PivotCache( *this ) );
+ return *rxCache;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/pivotcachefragment.cxx b/oox/source/xls/pivotcachefragment.cxx
new file mode 100644
index 000000000000..d49077af4f91
--- /dev/null
+++ b/oox/source/xls/pivotcachefragment.cxx
@@ -0,0 +1,466 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/pivotcachefragment.hxx"
+
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/pivotcachebuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+PivotCacheFieldContext::PivotCacheFieldContext( WorkbookFragmentBase& rFragment, PivotCacheField& rCacheField ) :
+ WorkbookContextBase( rFragment ),
+ mrCacheField( rCacheField )
+{
+}
+
+ContextHandlerRef PivotCacheFieldContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( cacheField ):
+ if( nElement == XLS_TOKEN( sharedItems ) ) { mrCacheField.importSharedItems( rAttribs ); return this; }
+ if( nElement == XLS_TOKEN( fieldGroup ) ) { mrCacheField.importFieldGroup( rAttribs ); return this; }
+ break;
+
+ case XLS_TOKEN( fieldGroup ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( rangePr ): mrCacheField.importRangePr( rAttribs ); break;
+ case XLS_TOKEN( discretePr ): return this;
+ case XLS_TOKEN( groupItems ): return this;
+ }
+ break;
+
+ case XLS_TOKEN( sharedItems ): mrCacheField.importSharedItem( nElement, rAttribs ); break;
+ case XLS_TOKEN( discretePr ): mrCacheField.importDiscretePrItem( nElement, rAttribs ); break;
+ case XLS_TOKEN( groupItems ): mrCacheField.importGroupItem( nElement, rAttribs ); break;
+ }
+ return 0;
+}
+
+void PivotCacheFieldContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( isRootElement() )
+ mrCacheField.importCacheField( rAttribs );
+}
+
+ContextHandlerRef PivotCacheFieldContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_PCDFIELD:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCDFSHAREDITEMS: mrCacheField.importPCDFSharedItems( rStrm ); return this;
+ case BIFF12_ID_PCDFIELDGROUP: mrCacheField.importPCDFieldGroup( rStrm ); return this;
+ }
+ break;
+
+ case BIFF12_ID_PCDFIELDGROUP:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCDFRANGEPR: mrCacheField.importPCDFRangePr( rStrm ); break;
+ case BIFF12_ID_PCDFDISCRETEPR: return this;
+ case BIFF12_ID_PCDFGROUPITEMS: return this;
+ }
+ break;
+
+ case BIFF12_ID_PCDFSHAREDITEMS: mrCacheField.importPCDFSharedItem( nRecId, rStrm ); break;
+ case BIFF12_ID_PCDFDISCRETEPR: mrCacheField.importPCDFDiscretePrItem( nRecId, rStrm ); break;
+ case BIFF12_ID_PCDFGROUPITEMS: mrCacheField.importPCDFGroupItem( nRecId, rStrm ); break;
+ }
+ return 0;
+}
+
+void PivotCacheFieldContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ if( isRootElement() )
+ mrCacheField.importPCDField( rStrm );
+}
+
+// ============================================================================
+
+PivotCacheDefinitionFragment::PivotCacheDefinitionFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath, PivotCache& rPivotCache ) :
+ WorkbookFragmentBase( rHelper, rFragmentPath ),
+ mrPivotCache( rPivotCache )
+{
+}
+
+ContextHandlerRef PivotCacheDefinitionFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( pivotCacheDefinition ) ) { mrPivotCache.importPivotCacheDefinition( rAttribs ); return this; }
+ break;
+
+ case XLS_TOKEN( pivotCacheDefinition ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( cacheSource ): mrPivotCache.importCacheSource( rAttribs ); return this;
+ case XLS_TOKEN( cacheFields ): return this;
+ }
+ break;
+
+ case XLS_TOKEN( cacheSource ):
+ if( nElement == XLS_TOKEN( worksheetSource ) ) mrPivotCache.importWorksheetSource( rAttribs, getRelations() );
+ break;
+
+ case XLS_TOKEN( cacheFields ):
+ if( nElement == XLS_TOKEN( cacheField ) ) return new PivotCacheFieldContext( *this, mrPivotCache.createCacheField() );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef PivotCacheDefinitionFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_PCDEFINITION ) { mrPivotCache.importPCDefinition( rStrm ); return this; }
+ break;
+
+ case BIFF12_ID_PCDEFINITION:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCDSOURCE: mrPivotCache.importPCDSource( rStrm ); return this;
+ case BIFF12_ID_PCDFIELDS: return this;
+ }
+ break;
+
+ case BIFF12_ID_PCDSOURCE:
+ if( nRecId == BIFF12_ID_PCDSHEETSOURCE ) mrPivotCache.importPCDSheetSource( rStrm, getRelations() );
+ break;
+
+ case BIFF12_ID_PCDFIELDS:
+ if( nRecId == BIFF12_ID_PCDFIELD ) return new PivotCacheFieldContext( *this, mrPivotCache.createCacheField() );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* PivotCacheDefinitionFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_PCDEFINITION, BIFF12_ID_PCDEFINITION + 1 },
+ { BIFF12_ID_PCDFDISCRETEPR, BIFF12_ID_PCDFDISCRETEPR + 1 },
+ { BIFF12_ID_PCDFGROUPITEMS, BIFF12_ID_PCDFGROUPITEMS + 1 },
+ { BIFF12_ID_PCDFIELD, BIFF12_ID_PCDFIELD + 1 },
+ { BIFF12_ID_PCDFIELDGROUP, BIFF12_ID_PCDFIELDGROUP + 1 },
+ { BIFF12_ID_PCDFIELDS, BIFF12_ID_PCDFIELDS + 1 },
+ { BIFF12_ID_PCDFRANGEPR, BIFF12_ID_PCDFRANGEPR + 1 },
+ { BIFF12_ID_PCDFSHAREDITEMS, BIFF12_ID_PCDFSHAREDITEMS + 1 },
+ { BIFF12_ID_PCITEM_ARRAY, BIFF12_ID_PCITEM_ARRAY + 1 },
+ { BIFF12_ID_PCDSHEETSOURCE, BIFF12_ID_PCDSHEETSOURCE + 1 },
+ { BIFF12_ID_PCDSOURCE, BIFF12_ID_PCDSOURCE + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void PivotCacheDefinitionFragment::finalizeImport()
+{
+ // finalize the cache (check source range etc.)
+ mrPivotCache.finalizeImport();
+
+ // load the cache records, if the cache is based on a deleted or an external worksheet
+ if( mrPivotCache.isValidDataSource() && mrPivotCache.isBasedOnDummySheet() )
+ {
+ OUString aRecFragmentPath = getRelations().getFragmentPathFromRelId( mrPivotCache.getRecordsRelId() );
+ if( aRecFragmentPath.getLength() > 0 )
+ importOoxFragment( new PivotCacheRecordsFragment( *this, aRecFragmentPath, mrPivotCache ) );
+ }
+}
+
+// ============================================================================
+
+PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath, const PivotCache& rPivotCache ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, rPivotCache.getSourceRange().Sheet ),
+ mrPivotCache( rPivotCache ),
+ mnCol( 0 ),
+ mnRow( 0 ),
+ mbInRecord( false )
+{
+ // prepare sheet: insert column header names into top row
+ rPivotCache.writeSourceHeaderCells( *this );
+}
+
+ContextHandlerRef PivotCacheRecordsFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( pivotCacheRecords ) ) return this;
+ break;
+
+ case XLS_TOKEN( pivotCacheRecords ):
+ if( nElement == XLS_TOKEN( r ) ) { startCacheRecord(); return this; }
+ break;
+
+ case XLS_TOKEN( r ):
+ {
+ PivotCacheItem aItem;
+ switch( nElement )
+ {
+ case XLS_TOKEN( m ): break;
+ case XLS_TOKEN( s ): aItem.readString( rAttribs ); break;
+ case XLS_TOKEN( n ): aItem.readNumeric( rAttribs ); break;
+ case XLS_TOKEN( d ): aItem.readDate( rAttribs ); break;
+ case XLS_TOKEN( b ): aItem.readBool( rAttribs ); break;
+ case XLS_TOKEN( e ): aItem.readError( rAttribs, getUnitConverter() ); break;
+ case XLS_TOKEN( x ): aItem.readIndex( rAttribs ); break;
+ default: OSL_ENSURE( false, "PivotCacheRecordsFragment::onCreateContext - unexpected element" );
+ }
+ mrPivotCache.writeSourceDataCell( *this, mnCol, mnRow, aItem );
+ ++mnCol;
+ }
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef PivotCacheRecordsFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_PCRECORDS ) return this;
+ break;
+
+ case BIFF12_ID_PCRECORDS:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCRECORD: importPCRecord( rStrm ); break;
+ case BIFF12_ID_PCRECORDDT: startCacheRecord(); break;
+ default: importPCRecordItem( nRecId, rStrm ); break;
+ }
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* PivotCacheRecordsFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_PCRECORDS, BIFF12_ID_PCRECORDS + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+// private --------------------------------------------------------------------
+
+void PivotCacheRecordsFragment::startCacheRecord()
+{
+ mnCol = 0;
+ ++mnRow;
+ mbInRecord = true;
+}
+
+void PivotCacheRecordsFragment::importPCRecord( SequenceInputStream& rStrm )
+{
+ startCacheRecord();
+ mrPivotCache.importPCRecord( rStrm, *this, mnRow );
+ mbInRecord = false;
+}
+
+void PivotCacheRecordsFragment::importPCRecordItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ if( mbInRecord )
+ {
+ PivotCacheItem aItem;
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCITEM_MISSING: break;
+ case BIFF12_ID_PCITEM_STRING: aItem.readString( rStrm ); break;
+ case BIFF12_ID_PCITEM_DOUBLE: aItem.readDouble( rStrm ); break;
+ case BIFF12_ID_PCITEM_DATE: aItem.readDate( rStrm ); break;
+ case BIFF12_ID_PCITEM_BOOL: aItem.readBool( rStrm ); break;
+ case BIFF12_ID_PCITEM_ERROR: aItem.readError( rStrm ); break;
+ case BIFF12_ID_PCITEM_INDEX: aItem.readIndex( rStrm ); break;
+ default: OSL_ENSURE( false, "PivotCacheRecordsFragment::importPCRecordItem - unexpected record" );
+ }
+ mrPivotCache.writeSourceDataCell( *this, mnCol, mnRow, aItem );
+ ++mnCol;
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+namespace {
+
+bool lclSeekToPCDField( BiffInputStream& rStrm )
+{
+ sal_Int64 nRecHandle = rStrm.getRecHandle();
+ while( rStrm.startNextRecord() )
+ if( rStrm.getRecId() == BIFF_ID_PCDFIELD )
+ return true;
+ rStrm.startRecordByHandle( nRecHandle );
+ return false;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+BiffPivotCacheFragment::BiffPivotCacheFragment(
+ const WorkbookHelper& rHelper, const OUString& rStrmName, PivotCache& rPivotCache ) :
+ BiffWorkbookFragmentBase( rHelper, rStrmName, true ),
+ mrPivotCache( rPivotCache )
+{
+}
+
+bool BiffPivotCacheFragment::importFragment()
+{
+ BiffInputStream& rStrm = getInputStream();
+ if( rStrm.startNextRecord() && (rStrm.getRecId() == BIFF_ID_PCDEFINITION) )
+ {
+ // read PCDEFINITION and optional PCDEFINITION2 records
+ mrPivotCache.importPCDefinition( rStrm );
+
+ // read cache fields as long as another PCDFIELD record can be found
+ while( lclSeekToPCDField( rStrm ) )
+ mrPivotCache.createCacheField( true ).importPCDField( rStrm );
+
+ // finalize the cache (check source range etc.)
+ mrPivotCache.finalizeImport();
+
+ // load the cache records, if the cache is based on a deleted or an external worksheet
+ if( mrPivotCache.isValidDataSource() && mrPivotCache.isBasedOnDummySheet() )
+ {
+ /* Last call of lclSeekToPCDField() failed and kept stream position
+ unchanged. Stream should point to source data table now. */
+ BiffPivotCacheRecordsContext aContext( *this, mrPivotCache );
+ if( aContext.isValidSheet() )
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ aContext.importRecord( rStrm );
+ }
+ }
+
+ return rStrm.getRecId() == BIFF_ID_EOF;
+}
+
+// ============================================================================
+
+BiffPivotCacheRecordsContext::BiffPivotCacheRecordsContext( const WorkbookHelper& rHelper, const PivotCache& rPivotCache ) :
+ BiffWorksheetContextBase( rHelper, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, rPivotCache.getSourceRange().Sheet ),
+ mrPivotCache( rPivotCache ),
+ mnColIdx( 0 ),
+ mnRow( 0 ),
+ mbHasShared( false ),
+ mbInRow( false )
+{
+ // prepare sheet: insert column header names into top row
+ mrPivotCache.writeSourceHeaderCells( *this );
+
+ // find all fields without shared items, remember column indexes in source data
+ for( sal_Int32 nFieldIdx = 0, nFieldCount = mrPivotCache.getCacheFieldCount(), nCol = 0; nFieldIdx < nFieldCount; ++nFieldIdx )
+ {
+ const PivotCacheField* pCacheField = mrPivotCache.getCacheField( nFieldIdx );
+ if( pCacheField && pCacheField->isDatabaseField() )
+ {
+ if( pCacheField->hasSharedItems() )
+ mbHasShared = true;
+ else
+ maUnsharedCols.push_back( nCol );
+ ++nCol;
+ }
+ }
+}
+
+void BiffPivotCacheRecordsContext::importRecord( BiffInputStream& rStrm )
+{
+ if( rStrm.getRecId() == BIFF_ID_PCITEM_INDEXLIST )
+ {
+ OSL_ENSURE( mbHasShared, "BiffPivotCacheRecordsContext::importRecord - unexpected PCITEM_INDEXLIST record" );
+ // PCITEM_INDEXLIST record always in front of a new data row
+ startNextRow();
+ mrPivotCache.importPCItemIndexList( rStrm, *this, mnRow );
+ mbInRow = !maUnsharedCols.empty(); // mbInRow remains true, if unshared items are expected
+ return;
+ }
+
+ PivotCacheItem aItem;
+ switch( rStrm.getRecId() )
+ {
+ case BIFF_ID_PCITEM_MISSING: break;
+ case BIFF_ID_PCITEM_STRING: aItem.readString( rStrm, *this ); break;
+ case BIFF_ID_PCITEM_DOUBLE: aItem.readDouble( rStrm ); break;
+ case BIFF_ID_PCITEM_INTEGER: aItem.readInteger( rStrm ); break;
+ case BIFF_ID_PCITEM_DATE: aItem.readDate( rStrm ); break;
+ case BIFF_ID_PCITEM_BOOL: aItem.readBool( rStrm ); break;
+ case BIFF_ID_PCITEM_ERROR: aItem.readError( rStrm ); break;
+ default: return; // unknown record, ignore
+ }
+
+ // find next column index, might start new row if no fields with shared items exist
+ if( mbInRow && (mnColIdx == maUnsharedCols.size()) )
+ {
+ OSL_ENSURE( !mbHasShared, "BiffPivotCacheRecordsContext::importRecord - PCITEM_INDEXLIST record missing" );
+ mbInRow = mbHasShared; // do not leave current row if PCITEM_INDEXLIST is expected
+ }
+ // start next row on first call, or on row wrap without shared items
+ if( !mbInRow )
+ startNextRow();
+
+ // write the item data to the sheet cell
+ OSL_ENSURE( mnColIdx < maUnsharedCols.size(), "BiffPivotCacheRecordsContext::importRecord - invalid column index" );
+ if( mnColIdx < maUnsharedCols.size() )
+ mrPivotCache.writeSourceDataCell( *this, maUnsharedCols[ mnColIdx ], mnRow, aItem );
+ ++mnColIdx;
+}
+
+void BiffPivotCacheRecordsContext::startNextRow()
+{
+ mnColIdx = 0;
+ ++mnRow;
+ mbInRow = true;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/pivottablebuffer.cxx b/oox/source/xls/pivottablebuffer.cxx
new file mode 100644
index 000000000000..7cdeddaa879b
--- /dev/null
+++ b/oox/source/xls/pivottablebuffer.cxx
@@ -0,0 +1,1567 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/pivottablebuffer.hxx"
+
+#include <set>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/XDataPilotDataLayoutFieldSupplier.hpp>
+#include <com/sun/star/sheet/XDataPilotField.hpp>
+#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
+#include <com/sun/star/sheet/XSheetOperation.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 OOX_PT_DATALAYOUTFIELD = -2; /// Placeholder index of data layout field.
+
+const sal_Int32 OOX_PT_PREVIOUS_ITEM = 0x001000FC; /// Calculation of data item result is based on previous item.
+const sal_Int32 OOX_PT_NEXT_ITEM = 0x001000FD; /// Calculation of data item result is based on next item.
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt32 BIFF12_PTFIELD_DATAFIELD = 0x00000008;
+const sal_uInt32 BIFF12_PTFIELD_DEFAULT = 0x00000100;
+const sal_uInt32 BIFF12_PTFIELD_SUM = 0x00000200;
+const sal_uInt32 BIFF12_PTFIELD_COUNTA = 0x00000400;
+const sal_uInt32 BIFF12_PTFIELD_AVERAGE = 0x00000800;
+const sal_uInt32 BIFF12_PTFIELD_MAX = 0x00001000;
+const sal_uInt32 BIFF12_PTFIELD_MIN = 0x00002000;
+const sal_uInt32 BIFF12_PTFIELD_PRODUCT = 0x00004000;
+const sal_uInt32 BIFF12_PTFIELD_COUNT = 0x00008000;
+const sal_uInt32 BIFF12_PTFIELD_STDDEV = 0x00010000;
+const sal_uInt32 BIFF12_PTFIELD_STDDEVP = 0x00020000;
+const sal_uInt32 BIFF12_PTFIELD_VAR = 0x00040000;
+const sal_uInt32 BIFF12_PTFIELD_VARP = 0x00080000;
+
+const sal_uInt32 BIFF12_PTFIELD_SHOWALL = 0x00000020;
+const sal_uInt32 BIFF12_PTFIELD_OUTLINE = 0x00000040;
+const sal_uInt32 BIFF12_PTFIELD_INSERTBLANKROW = 0x00000080;
+const sal_uInt32 BIFF12_PTFIELD_SUBTOTALTOP = 0x00000100;
+const sal_uInt32 BIFF12_PTFIELD_INSERTPAGEBREAK = 0x00000800;
+const sal_uInt32 BIFF12_PTFIELD_AUTOSORT = 0x00001000;
+const sal_uInt32 BIFF12_PTFIELD_SORTASCENDING = 0x00002000;
+const sal_uInt32 BIFF12_PTFIELD_AUTOSHOW = 0x00004000;
+const sal_uInt32 BIFF12_PTFIELD_AUTOSHOWTOP = 0x00008000;
+const sal_uInt32 BIFF12_PTFIELD_MULTIPAGEITEMS = 0x00080000;
+
+const sal_uInt16 BIFF12_PTFITEM_HIDDEN = 0x0001;
+const sal_uInt16 BIFF12_PTFITEM_HIDEDETAILS = 0x0002;
+
+const sal_uInt8 BIFF12_PTPAGEFIELD_HASNAME = 0x01;
+const sal_uInt8 BIFF12_PTPAGEFIELD_HASOLAPCAPTION = 0x02;
+const sal_Int32 BIFF12_PTPAGEFIELD_MULTIITEMS = 0x001000FE;
+
+const sal_uInt16 BIFF12_PTFILTER_HASNAME = 0x0001;
+const sal_uInt16 BIFF12_PTFILTER_HASDESCRIPTION = 0x0002;
+const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE1 = 0x0004;
+const sal_uInt16 BIFF12_PTFILTER_HASSTRVALUE2 = 0x0008;
+
+const sal_uInt8 BIFF12_TOP10FILTER_TOP = 0x01;
+const sal_uInt8 BIFF12_TOP10FILTER_PERCENT = 0x02;
+
+const sal_uInt32 BIFF12_PTDEF_SHOWITEMS = 0x00000100;
+const sal_uInt32 BIFF12_PTDEF_DISABLEFIELDLIST = 0x00000400;
+const sal_uInt32 BIFF12_PTDEF_HIDECALCMEMBERS = 0x00001000;
+const sal_uInt32 BIFF12_PTDEF_WITHHIDDENTOTALS = 0x00002000;
+const sal_uInt32 BIFF12_PTDEF_HIDEDRILL = 0x00100000;
+const sal_uInt32 BIFF12_PTDEF_PRINTDRILL = 0x00200000;
+const sal_uInt32 BIFF12_PTDEF_HIDEHEADERS = 0x80000000;
+
+const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYROW = 0x00000004;
+const sal_uInt32 BIFF12_PTDEF_SHOWEMPTYCOL = 0x00000008;
+const sal_uInt32 BIFF12_PTDEF_ENABLEDRILL = 0x00000020;
+const sal_uInt32 BIFF12_PTDEF_PRESERVEFORMATTING = 0x00000080;
+const sal_uInt32 BIFF12_PTDEF_USEAUTOFORMAT = 0x00000100;
+const sal_uInt32 BIFF12_PTDEF_SHOWERROR = 0x00000200;
+const sal_uInt32 BIFF12_PTDEF_SHOWMISSING = 0x00000400;
+const sal_uInt32 BIFF12_PTDEF_PAGEOVERTHENDOWN = 0x00000800;
+const sal_uInt32 BIFF12_PTDEF_SUBTOTALHIDDENITEMS = 0x00001000;
+const sal_uInt32 BIFF12_PTDEF_ROWGRANDTOTALS = 0x00002000;
+const sal_uInt32 BIFF12_PTDEF_COLGRANDTOTALS = 0x00004000;
+const sal_uInt32 BIFF12_PTDEF_FIELDPRINTTITLES = 0x00008000;
+const sal_uInt32 BIFF12_PTDEF_ITEMPRINTTITLES = 0x00020000;
+const sal_uInt32 BIFF12_PTDEF_MERGEITEM = 0x00040000;
+const sal_uInt32 BIFF12_PTDEF_HASDATACAPTION = 0x00080000;
+const sal_uInt32 BIFF12_PTDEF_HASGRANDTOTALCAPTION = 0x00100000;
+const sal_uInt32 BIFF12_PTDEF_HASPAGESTYLE = 0x00200000;
+const sal_uInt32 BIFF12_PTDEF_HASPIVOTTABLESTYLE = 0x00400000;
+const sal_uInt32 BIFF12_PTDEF_HASVACATEDSTYLE = 0x00800000;
+const sal_uInt32 BIFF12_PTDEF_APPLYNUMFMT = 0x01000000;
+const sal_uInt32 BIFF12_PTDEF_APPLYFONT = 0x02000000;
+const sal_uInt32 BIFF12_PTDEF_APPLYALIGNMENT = 0x04000000;
+const sal_uInt32 BIFF12_PTDEF_APPLYBORDER = 0x08000000;
+const sal_uInt32 BIFF12_PTDEF_APPLYFILL = 0x10000000;
+const sal_uInt32 BIFF12_PTDEF_APPLYPROTECTION = 0x20000000;
+const sal_uInt32 BIFF12_PTDEF_HASTAG = 0x40000000;
+
+const sal_uInt32 BIFF12_PTDEF_NOERRORCAPTION = 0x00000040;
+const sal_uInt32 BIFF12_PTDEF_NOMISSINGCAPTION = 0x00000080;
+const sal_uInt32 BIFF12_PTDEF_HASROWHEADERCAPTION = 0x00000400;
+const sal_uInt32 BIFF12_PTDEF_HASCOLHEADERCAPTION = 0x00000800;
+const sal_uInt32 BIFF12_PTDEF_FIELDLISTSORTASC = 0x00001000;
+const sal_uInt32 BIFF12_PTDEF_NOCUSTOMLISTSORT = 0x00004000;
+
+const sal_uInt8 BIFF12_PTDEF_ROWAXIS = 1;
+const sal_uInt8 BIFF12_PTDEF_COLAXIS = 2;
+
+// ----------------------------------------------------------------------------
+
+const sal_uInt16 BIFF_PT_NOSTRING = 0xFFFF;
+
+const sal_uInt16 BIFF_PTFIELD_DATAFIELD = 0x0008;
+const sal_uInt16 BIFF_PTFIELD_DEFAULT = 0x0001;
+const sal_uInt16 BIFF_PTFIELD_SUM = 0x0002;
+const sal_uInt16 BIFF_PTFIELD_COUNTA = 0x0004;
+const sal_uInt16 BIFF_PTFIELD_AVERAGE = 0x0008;
+const sal_uInt16 BIFF_PTFIELD_MAX = 0x0010;
+const sal_uInt16 BIFF_PTFIELD_MIN = 0x0020;
+const sal_uInt16 BIFF_PTFIELD_PRODUCT = 0x0040;
+const sal_uInt16 BIFF_PTFIELD_COUNT = 0x0080;
+const sal_uInt16 BIFF_PTFIELD_STDDEV = 0x0100;
+const sal_uInt16 BIFF_PTFIELD_STDDEVP = 0x0200;
+const sal_uInt16 BIFF_PTFIELD_VAR = 0x0400;
+const sal_uInt16 BIFF_PTFIELD_VARP = 0x0800;
+
+const sal_uInt32 BIFF_PTFIELD2_SHOWALL = 0x00000001;
+const sal_uInt32 BIFF_PTFIELD2_AUTOSORT = 0x00000200;
+const sal_uInt32 BIFF_PTFIELD2_SORTASCENDING = 0x00000400;
+const sal_uInt32 BIFF_PTFIELD2_AUTOSHOW = 0x00000800;
+const sal_uInt32 BIFF_PTFIELD2_AUTOSHOWTOP = 0x00001000;
+const sal_uInt32 BIFF_PTFIELD2_OUTLINE = 0x00200000;
+const sal_uInt32 BIFF_PTFIELD2_INSERTBLANKROW = 0x00400000;
+const sal_uInt32 BIFF_PTFIELD2_SUBTOTALTOP = 0x00800000;
+
+const sal_uInt16 BIFF_PTFITEM_HIDDEN = 0x0001;
+const sal_uInt16 BIFF_PTFITEM_HIDEDETAILS = 0x0002;
+
+const sal_uInt16 BIFF_PTDEF_ROWGRANDTOTALS = 0x0001;
+const sal_uInt16 BIFF_PTDEF_COLGRANDTOTALS = 0x0002;
+
+const sal_uInt8 BIFF_PTDEF_ROWAXIS = 1;
+const sal_uInt8 BIFF_PTDEF_COLAXIS = 2;
+
+const sal_uInt32 BIFF_PTDEF2_PAGEOVERTHENDOWN = 0x00000001;
+const sal_uInt32 BIFF_PTDE2F_ENABLEDRILL = 0x00020000;
+const sal_uInt32 BIFF_PTDEF2_PRESERVEFORMATTING = 0x00080000;
+const sal_uInt32 BIFF_PTDEF2_MERGEITEM = 0x00100000;
+const sal_uInt32 BIFF_PTDEF2_SHOWERROR = 0x00200000;
+const sal_uInt32 BIFF_PTDEF2_SHOWMISSING = 0x00400000;
+const sal_uInt32 BIFF_PTDEF2_SUBTOTALHIDDENITEMS = 0x00800000;
+
+const sal_Int16 BIFF_PTPAGEFIELDS_ALLITEMS = 0x7FFD;
+
+const sal_Int16 BIFF_PTDATAFIELD_PREVIOUS = 0x7FFB;
+const sal_Int16 BIFF_PTDATAFIELD_NEXT = 0x7FFC;
+
+// ----------------------------------------------------------------------------
+
+OUString lclReadPivotString( const WorkbookHelper& rHelper, BiffInputStream& rStrm, sal_uInt16 nLen )
+{
+ if( nLen == BIFF_PT_NOSTRING )
+ return OUString();
+ return (rHelper.getBiff() == BIFF8) ? rStrm.readUniStringBody( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() );
+}
+
+} // namespace
+
+// ============================================================================
+
+PTFieldItemModel::PTFieldItemModel() :
+ mnCacheItem( -1 ),
+ mnType( XML_data ),
+ mbShowDetails( true ),
+ mbHidden( false )
+{
+}
+
+void PTFieldItemModel::setBiffType( sal_uInt16 nType )
+{
+ static const sal_Int32 spnTypes[] = { XML_data, XML_default,
+ XML_sum, XML_countA, XML_avg, XML_max, XML_min, XML_product, XML_count,
+ XML_stdDev, XML_stdDevP, XML_var, XML_varP, XML_grand, XML_blank };
+ mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_data );
+}
+
+// ----------------------------------------------------------------------------
+
+PTFieldModel::PTFieldModel() :
+ mnAxis( XML_TOKEN_INVALID ),
+ mnNumFmtId( 0 ),
+ mnAutoShowItems( 10 ),
+ mnAutoShowRankBy( -1 ),
+ mnSortType( XML_manual ),
+ mnSortRefField( -1 ),
+ mnSortRefItem( -1 ),
+ mbDataField( false ),
+ mbDefaultSubtotal( true ),
+ mbSumSubtotal( false ),
+ mbCountASubtotal( false ),
+ mbAverageSubtotal( false ),
+ mbMaxSubtotal( false ),
+ mbMinSubtotal( false ),
+ mbProductSubtotal( false ),
+ mbCountSubtotal( false ),
+ mbStdDevSubtotal( false ),
+ mbStdDevPSubtotal( false ),
+ mbVarSubtotal( false ),
+ mbVarPSubtotal( false ),
+ mbShowAll( true ),
+ mbOutline( true ),
+ mbSubtotalTop( true ),
+ mbInsertBlankRow( false ),
+ mbInsertPageBreak( false ),
+ mbAutoShow( false ),
+ mbTopAutoShow( true ),
+ mbMultiPageItems( false )
+{
+}
+
+void PTFieldModel::setBiffAxis( sal_uInt8 nAxis )
+{
+ /* Weird. The axis field is organized as bit field, but only one of the
+ row/col/page flags are allowed at the same time and refer to the values
+ 'axisRow', 'axisCol', and 'axisPage' of the XML attribute
+ 'pivotField@axis'. Additionally, the fourth bit determines if the field
+ is a data field, which may appear combined with the row/col/page flags.
+ Therefore, this bit is unrelated to the 'axisValues' value of the
+ 'pivotField@axis' attribute, but refers to the 'pivotField@dataField'
+ boolean attribute. */
+ static const sal_Int32 spnAxisIds[] = { XML_TOKEN_INVALID, XML_axisRow, XML_axisCol, XML_TOKEN_INVALID, XML_axisPage };
+ mnAxis = STATIC_ARRAY_SELECT( spnAxisIds, nAxis, XML_TOKEN_INVALID );
+}
+
+// ----------------------------------------------------------------------------
+
+PTPageFieldModel::PTPageFieldModel() :
+ mnField( -1 ),
+ mnItem( BIFF12_PTPAGEFIELD_MULTIITEMS )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PTDataFieldModel::PTDataFieldModel() :
+ mnField( -1 ),
+ mnSubtotal( XML_sum ),
+ mnShowDataAs( XML_normal ),
+ mnBaseField( -1 ),
+ mnBaseItem( -1 ),
+ mnNumFmtId( 0 )
+{
+}
+
+void PTDataFieldModel::setBiffSubtotal( sal_Int32 nSubtotal )
+{
+ static sal_Int32 spnSubtotals[] = { XML_sum, XML_count, XML_average, XML_max, XML_min, XML_product, XML_countNums, XML_stdDev, XML_stdDevp, XML_var, XML_varp };
+ mnSubtotal = STATIC_ARRAY_SELECT( spnSubtotals, nSubtotal, XML_TOKEN_INVALID );
+}
+
+void PTDataFieldModel::setBiffShowDataAs( sal_Int32 nShowDataAs )
+{
+ static sal_Int32 spnShowDataAs[] = { XML_normal, XML_difference, XML_percent, XML_percentDiff, XML_runTotal, XML_percentOfRow, XML_percentOfCol, XML_percentOfTotal, XML_index };
+ mnShowDataAs = STATIC_ARRAY_SELECT( spnShowDataAs, nShowDataAs, XML_TOKEN_INVALID );
+}
+
+// ----------------------------------------------------------------------------
+
+PivotTableField::PivotTableField( PivotTable& rPivotTable, sal_Int32 nFieldIndex ) :
+ WorkbookHelper( rPivotTable ),
+ mrPivotTable( rPivotTable ),
+ mnFieldIndex( nFieldIndex )
+{
+}
+
+void PivotTableField::importPivotField( const AttributeList& rAttribs )
+{
+ /* The documentation mentions a value 'axisValues' for the attribute
+ 'pivotField@axis'. But this value is not used to mark a data field, as
+ data fields may be inserted in one of the row/column/page dimensions at
+ the same time. Therefore, the boolean attribute 'pivotField@dataField'
+ is really used to mark data fields. */
+ maModel.mnAxis = rAttribs.getToken( XML_axis, XML_TOKEN_INVALID );
+ maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
+ maModel.mnAutoShowItems = rAttribs.getInteger( XML_itemPageCount, 10 );
+ maModel.mnAutoShowRankBy = rAttribs.getInteger( XML_rankBy, -1 );
+ maModel.mnSortType = rAttribs.getToken( XML_sortType, XML_manual );
+ maModel.mbDataField = rAttribs.getBool( XML_dataField, false );
+ maModel.mbDefaultSubtotal = rAttribs.getBool( XML_defaultSubtotal, true );
+ maModel.mbSumSubtotal = rAttribs.getBool( XML_sumSubtotal, false );
+ maModel.mbCountASubtotal = rAttribs.getBool( XML_countASubtotal, false );
+ maModel.mbAverageSubtotal = rAttribs.getBool( XML_avgSubtotal, false );
+ maModel.mbMaxSubtotal = rAttribs.getBool( XML_maxSubtotal, false );
+ maModel.mbMinSubtotal = rAttribs.getBool( XML_minSubtotal, false );
+ maModel.mbProductSubtotal = rAttribs.getBool( XML_productSubtotal, false );
+ maModel.mbCountSubtotal = rAttribs.getBool( XML_countSubtotal, false );
+ maModel.mbStdDevSubtotal = rAttribs.getBool( XML_stdDevSubtotal, false );
+ maModel.mbStdDevPSubtotal = rAttribs.getBool( XML_stdDevPSubtotal, false );
+ maModel.mbVarSubtotal = rAttribs.getBool( XML_varSubtotal, false );
+ maModel.mbVarPSubtotal = rAttribs.getBool( XML_varPSubtotal, false );
+ maModel.mbShowAll = rAttribs.getBool( XML_showAll, true );
+ maModel.mbOutline = rAttribs.getBool( XML_outline, true );
+ maModel.mbSubtotalTop = rAttribs.getBool( XML_subtotalTop, true );
+ maModel.mbInsertBlankRow = rAttribs.getBool( XML_insertBlankRow, false );
+ maModel.mbInsertPageBreak = rAttribs.getBool( XML_insertPageBreak, false );
+ maModel.mbAutoShow = rAttribs.getBool( XML_autoShow, false );
+ maModel.mbTopAutoShow = rAttribs.getBool( XML_topAutoShow, true );
+ maModel.mbMultiPageItems = rAttribs.getBool( XML_multipleItemSelectionAllowed, false );
+}
+
+void PivotTableField::importItem( const AttributeList& rAttribs )
+{
+ PTFieldItemModel aModel;
+ aModel.mnCacheItem = rAttribs.getInteger( XML_x, -1 );
+ aModel.mnType = rAttribs.getToken( XML_t, XML_data );
+ aModel.mbShowDetails = rAttribs.getBool( XML_sd, true );
+ aModel.mbHidden = rAttribs.getBool( XML_h, false );
+ maItems.push_back( aModel );
+}
+
+void PivotTableField::importReference( const AttributeList& rAttribs )
+{
+ // field index is stored as unsigned integer
+ maModel.mnSortRefField = static_cast< sal_Int32 >( rAttribs.getUnsigned( XML_field, SAL_MAX_UINT32 ) );
+}
+
+void PivotTableField::importReferenceItem( const AttributeList& rAttribs )
+{
+ maModel.mnSortRefItem = rAttribs.getInteger( XML_v, -1 );
+}
+
+void PivotTableField::importPTField( SequenceInputStream& rStrm )
+{
+ sal_uInt32 nFlags1, nFlags2;
+ rStrm >> nFlags1 >> maModel.mnNumFmtId >> nFlags2 >> maModel.mnAutoShowItems >> maModel.mnAutoShowRankBy;
+
+ maModel.setBiffAxis( extractValue< sal_uInt8 >( nFlags1, 0, 3 ) );
+ maModel.mbDataField = getFlag( nFlags1, BIFF12_PTFIELD_DATAFIELD );
+ maModel.mbDefaultSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_DEFAULT );
+ maModel.mbSumSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_SUM );
+ maModel.mbCountASubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNTA );
+ maModel.mbAverageSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_AVERAGE );
+ maModel.mbMaxSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MAX );
+ maModel.mbMinSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_MIN );
+ maModel.mbProductSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_PRODUCT );
+ maModel.mbCountSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_COUNT );
+ maModel.mbStdDevSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEV );
+ maModel.mbStdDevPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_STDDEVP );
+ maModel.mbVarSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VAR );
+ maModel.mbVarPSubtotal = getFlag( nFlags1, BIFF12_PTFIELD_VARP );
+
+ maModel.mbShowAll = getFlag( nFlags2, BIFF12_PTFIELD_SHOWALL );
+ maModel.mbOutline = getFlag( nFlags2, BIFF12_PTFIELD_OUTLINE );
+ maModel.mbSubtotalTop = getFlag( nFlags2, BIFF12_PTFIELD_SUBTOTALTOP );
+ maModel.mbInsertBlankRow = getFlag( nFlags2, BIFF12_PTFIELD_INSERTBLANKROW );
+ maModel.mbInsertPageBreak = getFlag( nFlags2, BIFF12_PTFIELD_INSERTPAGEBREAK );
+ maModel.mbAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOW );
+ maModel.mbTopAutoShow = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSHOWTOP );
+ maModel.mbMultiPageItems = getFlag( nFlags2, BIFF12_PTFIELD_MULTIPAGEITEMS );
+
+ bool bAutoSort = getFlag( nFlags2, BIFF12_PTFIELD_AUTOSORT );
+ bool bAscending = getFlag( nFlags2, BIFF12_PTFIELD_SORTASCENDING );
+ maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
+}
+
+void PivotTableField::importPTFItem( SequenceInputStream& rStrm )
+{
+ PTFieldItemModel aModel;
+ sal_uInt8 nType;
+ sal_uInt16 nFlags;
+ rStrm >> nType >> nFlags >> aModel.mnCacheItem;
+
+ aModel.setBiffType( nType );
+ aModel.mbShowDetails = !getFlag( nFlags, BIFF12_PTFITEM_HIDEDETAILS );
+ aModel.mbHidden = getFlag( nFlags, BIFF12_PTFITEM_HIDDEN );
+
+ maItems.push_back( aModel );
+}
+
+void PivotTableField::importPTReference( SequenceInputStream& rStrm )
+{
+ rStrm >> maModel.mnSortRefField;
+}
+
+void PivotTableField::importPTReferenceItem( SequenceInputStream& rStrm )
+{
+ rStrm >> maModel.mnSortRefItem;
+}
+
+void PivotTableField::importPTField( BiffInputStream& rStrm )
+{
+ sal_uInt16 nAxis, nSubtCount, nSubtotals;
+ rStrm >> nAxis >> nSubtCount >> nSubtotals;
+ rStrm.skip( 2 ); // item count
+
+ maModel.setBiffAxis( extractValue< sal_uInt8 >( nAxis, 0, 3 ) );
+ maModel.mbDataField = getFlag( nAxis, BIFF_PTFIELD_DATAFIELD );
+
+ maModel.mbDefaultSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_DEFAULT );
+ maModel.mbSumSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_SUM );
+ maModel.mbCountASubtotal = getFlag( nSubtotals, BIFF_PTFIELD_COUNTA );
+ maModel.mbAverageSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_AVERAGE );
+ maModel.mbMaxSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_MAX );
+ maModel.mbMinSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_MIN );
+ maModel.mbProductSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_PRODUCT );
+ maModel.mbCountSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_COUNT );
+ maModel.mbStdDevSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_STDDEV );
+ maModel.mbStdDevPSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_STDDEVP );
+ maModel.mbVarSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_VAR );
+ maModel.mbVarPSubtotal = getFlag( nSubtotals, BIFF_PTFIELD_VARP );
+
+ // set different defaults for BIFF
+ maModel.mbShowAll = maModel.mbOutline = maModel.mbSubtotalTop = false;
+
+ // read following items
+ while( (rStrm.getNextRecId() == BIFF_ID_PTFITEM) && rStrm.startNextRecord() )
+ importPTFItem( rStrm );
+
+ // read following PTFIELD2 record with additional field settings
+ if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_PTFIELD2) && rStrm.startNextRecord() )
+ importPTField2( rStrm );
+}
+
+void PivotTableField::importPTField2( BiffInputStream& rStrm )
+{
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+ maModel.mnSortRefItem = rStrm.readInt16();
+ maModel.mnAutoShowRankBy = rStrm.readInt16();
+ maModel.mnNumFmtId = rStrm.readuInt16();
+
+ maModel.mnAutoShowItems = extractValue< sal_Int32 >( nFlags, 24, 8 );
+ maModel.mbShowAll = getFlag( nFlags, BIFF_PTFIELD2_SHOWALL );
+ maModel.mbOutline = getFlag( nFlags, BIFF_PTFIELD2_OUTLINE );
+ maModel.mbSubtotalTop = getFlag( nFlags, BIFF_PTFIELD2_SUBTOTALTOP );
+ maModel.mbInsertBlankRow = getFlag( nFlags, BIFF_PTFIELD2_INSERTBLANKROW );
+ maModel.mbAutoShow = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOW );
+ maModel.mbTopAutoShow = getFlag( nFlags, BIFF_PTFIELD2_AUTOSHOWTOP );
+
+ bool bAutoSort = getFlag( nFlags, BIFF_PTFIELD2_AUTOSORT );
+ bool bAscending = getFlag( nFlags, BIFF_PTFIELD2_SORTASCENDING );
+ maModel.mnSortType = bAutoSort ? (bAscending ? XML_ascending : XML_descending) : XML_manual;
+ // mnSortRefField == OOX_PT_DATALAYOUTFIELD will indicate sorting by data field
+ if( maModel.mnSortRefItem >= 0 )
+ maModel.mnSortRefField = OOX_PT_DATALAYOUTFIELD;
+}
+
+void PivotTableField::importPTFItem( BiffInputStream& rStrm )
+{
+ PTFieldItemModel aModel;
+ sal_uInt16 nType, nFlags;
+ sal_Int16 nCacheItem;
+ rStrm >> nType >> nFlags >> nCacheItem;
+
+ aModel.setBiffType( nType );
+ aModel.mnCacheItem = nCacheItem;
+ aModel.mbShowDetails = !getFlag( nFlags, BIFF_PTFITEM_HIDEDETAILS );
+ aModel.mbHidden = getFlag( nFlags, BIFF_PTFITEM_HIDDEN );
+
+ maItems.push_back( aModel );
+}
+
+void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& rxDPDesc )
+{
+ /* Process all fields based on source data, other fields (e.g. group
+ fields) are processed from here. PivotCacahe::getDatabaseIndex()
+ returns -1 for all fields not based on source data. */
+ Reference< XDataPilotField > xDPField;
+ sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
+ if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
+ {
+ // try to get the source field and its name from passed DataPilot descriptor
+ Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
+ xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
+ Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
+ maDPFieldName = xDPFieldName->getName();
+ OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeImport - no field name in source data found" );
+
+ // try to convert grouping settings
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
+ {
+ // numeric grouping is done inplace, no nested group fields will appear
+ if( pCacheField->hasNumericGrouping() )
+ {
+ pCacheField->convertNumericGrouping( xDPField );
+ }
+ else if( pCacheField->hasDateGrouping() )
+ {
+ // first date group settings are inplace
+ pCacheField->createDateGroupField( xDPField );
+ // create all nested group fields (if any)
+ mrPivotTable.finalizeDateGroupingImport( xDPField, mnFieldIndex );
+ }
+ else if( pCacheField->hasParentGrouping() )
+ {
+ // create a list of all item names, needed to map between original and group items
+ ::std::vector< OUString > aItems;
+ pCacheField->getCacheItemNames( aItems );
+ PivotCacheGroupItemVector aItemNames;
+ for( ::std::vector< OUString >::iterator aIt = aItems.begin(), aEnd = aItems.end(); aIt != aEnd; ++aIt )
+ aItemNames.push_back( PivotCacheGroupItem( *aIt ) );
+ // create all nested group fields (if any)
+ mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, aItemNames );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
+{
+ if( maDPFieldName.getLength() == 0 ) // prevent endless loops if file format is broken
+ {
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
+ {
+ if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) )
+ {
+ maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField );
+ OSL_ENSURE( maDPFieldName.getLength() > 0, "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
+ }
+ }
+ }
+}
+
+void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, PivotCacheGroupItemVector& orItemNames )
+{
+ if( maDPFieldName.getLength() == 0 ) // prevent endless loops if file format is broken
+ {
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
+ {
+ maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, orItemNames );
+ // on success, try to create nested group fields
+ Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
+ if( xDPField.is() )
+ mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames );
+ }
+ }
+}
+
+void PivotTableField::convertRowField()
+{
+ convertRowColPageField( XML_axisRow );
+}
+
+void PivotTableField::convertColField()
+{
+ convertRowColPageField( XML_axisCol );
+}
+
+void PivotTableField::convertHiddenField()
+{
+ convertRowColPageField( XML_TOKEN_INVALID );
+}
+
+void PivotTableField::convertPageField( const PTPageFieldModel& rPageField )
+{
+ OSL_ENSURE( rPageField.mnField == mnFieldIndex, "PivotTableField::convertPageField - wrong field index" );
+ // convert all settings common for row/column/page fields
+ Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage );
+
+ if( xDPField.is() )
+ {
+ PropertySet aPropSet( xDPField );
+ using namespace ::com::sun::star::sheet;
+
+ // find cache item used as 'selected page'
+ sal_Int32 nCacheItem = -1;
+ if( maModel.mbMultiPageItems )
+ {
+ // multiple items may be selected
+ OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" );
+ // try to find a single visible item
+ bool bHasMultiItems = false;
+ for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); (aIt != aEnd) && !bHasMultiItems; ++aIt )
+ {
+ if( (aIt->mnType == XML_data) && !aIt->mbHidden )
+ {
+ bHasMultiItems = nCacheItem >= 0;
+ nCacheItem = bHasMultiItems ? -1 : aIt->mnCacheItem;
+ }
+ }
+ }
+ else
+ {
+ // single item may be selected
+ if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) )
+ nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem;
+ }
+
+ if( nCacheItem >= 0 )
+ {
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
+ {
+ if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) )
+ {
+ OUString aSelectedPage = pSharedItem->getName();
+ if( aSelectedPage.getLength() > 0 )
+ aPropSet.setProperty( PROP_SelectedPage, aSelectedPage );
+ }
+ }
+ }
+ }
+}
+
+void PivotTableField::convertDataField( const PTDataFieldModel& rDataField )
+{
+ OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" );
+ OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" );
+ Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
+ if( xDPField.is() )
+ {
+ PropertySet aPropSet( xDPField );
+ using namespace ::com::sun::star::sheet;
+
+ // field orientation
+ aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA );
+
+ /* Field aggregation function. Documentation is a little bit confused
+ about which names to use for the count functions. The name 'count'
+ means 'count all', and 'countNum' means 'count numbers'. On the
+ other hand, for subtotals, 'countA' means 'count all', and 'count'
+ means 'count numbers' (see above). */
+ GeneralFunction eAggFunc = GeneralFunction_SUM;
+ switch( rDataField.mnSubtotal )
+ {
+ case XML_sum: eAggFunc = GeneralFunction_SUM; break;
+ case XML_count: eAggFunc = GeneralFunction_COUNT; break;
+ case XML_average: eAggFunc = GeneralFunction_AVERAGE; break;
+ case XML_max: eAggFunc = GeneralFunction_MAX; break;
+ case XML_min: eAggFunc = GeneralFunction_MIN; break;
+ case XML_product: eAggFunc = GeneralFunction_PRODUCT; break;
+ case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS; break;
+ case XML_stdDev: eAggFunc = GeneralFunction_STDEV; break;
+ case XML_stdDevp: eAggFunc = GeneralFunction_STDEVP; break;
+ case XML_var: eAggFunc = GeneralFunction_VAR; break;
+ case XML_varp: eAggFunc = GeneralFunction_VARP; break;
+ default: OSL_ENSURE( false, "PivotTableField::convertDataField - unknown aggregation function" );
+ }
+ aPropSet.setProperty( PROP_Function, eAggFunc );
+
+ // field reference ('show data as')
+ DataPilotFieldReference aReference;
+ aReference.ReferenceType = DataPilotFieldReferenceType::NONE;
+ switch( rDataField.mnShowDataAs )
+ {
+ case XML_difference: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE; break;
+ case XML_percent: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE; break;
+ case XML_percentDiff: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break;
+ case XML_runTotal: aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL; break;
+ case XML_percentOfRow: aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE; break;
+ case XML_percentOfCol: aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE; break;
+ case XML_percentOfTotal: aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE; break;
+ case XML_index: aReference.ReferenceType = DataPilotFieldReferenceType::INDEX; break;
+ }
+ if( aReference.ReferenceType != DataPilotFieldReferenceType::NONE )
+ {
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ) )
+ {
+ aReference.ReferenceField = pCacheField->getName();
+ switch( rDataField.mnBaseItem )
+ {
+ case OOX_PT_PREVIOUS_ITEM:
+ aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
+ break;
+ case OOX_PT_NEXT_ITEM:
+ aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
+ break;
+ default:
+ aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
+ if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) )
+ aReference.ReferenceItemName = pCacheItem->getName();
+ }
+ aPropSet.setProperty( PROP_Reference, aReference );
+ }
+ }
+ }
+}
+
+// private --------------------------------------------------------------------
+
+Reference< XDataPilotField > PivotTableField::convertRowColPageField( sal_Int32 nAxis )
+{
+ bool bDataLayout = mnFieldIndex == OOX_PT_DATALAYOUTFIELD;
+ Reference< XDataPilotField > xDPField = bDataLayout ? mrPivotTable.getDataLayoutField() : mrPivotTable.getDataPilotField( maDPFieldName );
+ OSL_ENSURE( bDataLayout || (nAxis == maModel.mnAxis), "PivotTableField::convertRowColPageField - field axis mismatch" );
+
+ if( xDPField.is() )
+ {
+ PropertySet aPropSet( xDPField );
+ using namespace ::com::sun::star::sheet;
+
+ // field orientation
+ DataPilotFieldOrientation eFieldOrient = DataPilotFieldOrientation_HIDDEN;
+ switch( nAxis )
+ {
+ case XML_axisRow: eFieldOrient = DataPilotFieldOrientation_ROW; break;
+ case XML_axisCol: eFieldOrient = DataPilotFieldOrientation_COLUMN; break;
+ case XML_axisPage: eFieldOrient = DataPilotFieldOrientation_PAGE; break;
+ }
+ if( eFieldOrient != DataPilotFieldOrientation_HIDDEN )
+ aPropSet.setProperty( PROP_Orientation, eFieldOrient );
+
+ // all other settings not for the data layout field
+ if( !bDataLayout )
+ {
+ /* Field subtotal functions. Ignore the 'defaultSubtotal' flag, if
+ explicit functions are set. This is different behaviour between
+ XML (where 'defaultSubtotal' is set regardless of other
+ functions) and binary formats (where 'defaultSubtotal' is not
+ set if other functions are set). */
+ ::std::vector< GeneralFunction > aSubtotals;
+ /* Order of subtotals is fixed in Excel. Documentation is a little
+ bit confused about which names to use for the count functions.
+ For subtotals, 'countA' means 'count all', and 'count' means
+ 'count numbers'. On the other hand, for the data field
+ aggregation function, 'count' means 'count all', and 'countNum'
+ means 'count numbers' (see below). */
+ if( maModel.mbSumSubtotal ) aSubtotals.push_back( GeneralFunction_SUM );
+ if( maModel.mbCountASubtotal ) aSubtotals.push_back( GeneralFunction_COUNT );
+ if( maModel.mbAverageSubtotal ) aSubtotals.push_back( GeneralFunction_AVERAGE );
+ if( maModel.mbMaxSubtotal ) aSubtotals.push_back( GeneralFunction_MAX );
+ if( maModel.mbMinSubtotal ) aSubtotals.push_back( GeneralFunction_MIN );
+ if( maModel.mbProductSubtotal ) aSubtotals.push_back( GeneralFunction_PRODUCT );
+ if( maModel.mbCountSubtotal ) aSubtotals.push_back( GeneralFunction_COUNTNUMS );
+ if( maModel.mbStdDevSubtotal ) aSubtotals.push_back( GeneralFunction_STDEV );
+ if( maModel.mbStdDevPSubtotal ) aSubtotals.push_back( GeneralFunction_STDEVP );
+ if( maModel.mbVarSubtotal ) aSubtotals.push_back( GeneralFunction_VAR );
+ if( maModel.mbVarPSubtotal ) aSubtotals.push_back( GeneralFunction_VARP );
+ // if no function is set manually, check the 'defaultSubtotal' flag
+ if( aSubtotals.empty() && maModel.mbDefaultSubtotal )
+ aSubtotals.push_back( GeneralFunction_AUTO );
+ aPropSet.setProperty( PROP_Subtotals, ContainerHelper::vectorToSequence( aSubtotals ) );
+
+ // layout settings
+ DataPilotFieldLayoutInfo aLayoutInfo;
+ aLayoutInfo.LayoutMode = maModel.mbOutline ?
+ (maModel.mbSubtotalTop ? DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP : DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM) :
+ DataPilotFieldLayoutMode::TABULAR_LAYOUT;
+ aLayoutInfo.AddEmptyLines = maModel.mbInsertBlankRow;
+ aPropSet.setProperty( PROP_LayoutInfo, aLayoutInfo );
+ aPropSet.setProperty( PROP_ShowEmpty, maModel.mbShowAll );
+
+ // auto show (OOXML/BIFF12 only)
+ if( maModel.mbAutoShow )
+ {
+ DataPilotFieldAutoShowInfo aAutoShowInfo;
+ aAutoShowInfo.IsEnabled = sal_True;
+ aAutoShowInfo.ShowItemsMode = maModel.mbTopAutoShow ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
+ aAutoShowInfo.ItemCount = maModel.mnAutoShowItems;
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnAutoShowRankBy ) )
+ aAutoShowInfo.DataField = pCacheField->getName();
+ aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
+ }
+
+ // auto sort
+ DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.IsAscending = maModel.mnSortType == XML_ascending;
+ if( (maModel.mnSortType != XML_ascending) && (maModel.mnSortType != XML_descending) )
+ {
+ aSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
+ }
+ else
+ {
+ const PivotCacheField* pCacheField = (maModel.mnSortRefField == OOX_PT_DATALAYOUTFIELD) ?
+ mrPivotTable.getCacheFieldOfDataField( maModel.mnSortRefItem ) : 0;
+ if( pCacheField )
+ {
+ aSortInfo.Mode = DataPilotFieldSortMode::DATA;
+ aSortInfo.Field = pCacheField->getName();
+ }
+ else
+ {
+ aSortInfo.Mode = DataPilotFieldSortMode::NAME;
+ }
+ }
+ aPropSet.setProperty( PROP_SortInfo, aSortInfo );
+
+ // item settings
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) try
+ {
+ Reference< XNameAccess > xDPItemsNA( xDPField->getItems(), UNO_QUERY_THROW );
+ for( ItemModelVector::iterator aIt = maItems.begin(), aEnd = maItems.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->mnType == XML_data )
+ {
+ if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( aIt->mnCacheItem ) ) try
+ {
+ PropertySet aItemProp( xDPItemsNA->getByName( pSharedItem->getName() ) );
+ aItemProp.setProperty( PROP_ShowDetail, aIt->mbShowDetails );
+ aItemProp.setProperty( PROP_IsHidden, aIt->mbHidden );
+ }
+ catch( Exception& )
+ {
+ // catch every failed container access to be able to process following items
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ return xDPField;
+}
+
+// ============================================================================
+
+PTFilterModel::PTFilterModel() :
+ mfValue( 0.0 ),
+ mnField( -1 ),
+ mnMemPropField( -1 ),
+ mnType( XML_TOKEN_INVALID ),
+ mnEvalOrder( 0 ),
+ mnId( -1 ),
+ mnMeasureField( -1 ),
+ mnMeasureHier( -1 ),
+ mbTopFilter( true )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PivotTableFilter::PivotTableFilter( const PivotTable& rPivotTable ) :
+ WorkbookHelper( rPivotTable ),
+ mrPivotTable( rPivotTable )
+{
+}
+
+void PivotTableFilter::importFilter( const AttributeList& rAttribs )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ maModel.maDescription = rAttribs.getXString( XML_description, OUString() );
+ maModel.maStrValue1 = rAttribs.getXString( XML_stringValue1, OUString() );
+ maModel.maStrValue2 = rAttribs.getXString( XML_stringValue2, OUString() );
+ maModel.mnField = rAttribs.getInteger( XML_fld, -1 );
+ maModel.mnMemPropField = rAttribs.getInteger( XML_mpFld, -1 );
+ maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
+ maModel.mnEvalOrder = rAttribs.getInteger( XML_evalOrder, 0 );
+ maModel.mnId = rAttribs.getInteger( XML_id, -1 );
+ maModel.mnMeasureField = rAttribs.getInteger( XML_iMeasureFld, -1 );
+ maModel.mnMeasureHier = rAttribs.getInteger( XML_iMeasureHier, -1 );
+}
+
+void PivotTableFilter::importTop10( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( rAttribs.getBool( XML_percent, false ) == (maModel.mnType == XML_percent),
+ "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
+ maModel.mfValue = rAttribs.getDouble( XML_val, 0.0 );
+ maModel.mbTopFilter = rAttribs.getBool( XML_top, true );
+}
+
+void PivotTableFilter::importPTFilter( SequenceInputStream& rStrm )
+{
+ sal_Int32 nType;
+ sal_uInt16 nFlags;
+ rStrm >> maModel.mnField >> maModel.mnMemPropField >> nType;
+ rStrm.skip( 4 ); // unused
+ rStrm >> maModel.mnId >> maModel.mnMeasureField >> maModel.mnMeasureHier >> nFlags;
+ if( getFlag( nFlags, BIFF12_PTFILTER_HASNAME ) )
+ rStrm >> maModel.maName;
+ if( getFlag( nFlags, BIFF12_PTFILTER_HASDESCRIPTION ) )
+ rStrm >> maModel.maDescription;
+ if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE1 ) )
+ rStrm >> maModel.maStrValue1;
+ if( getFlag( nFlags, BIFF12_PTFILTER_HASSTRVALUE2 ) )
+ rStrm >> maModel.maStrValue2;
+
+ static sal_Int32 spnTypes[] =
+ {
+ XML_unknown,
+ // data field top10 filter (1-3)
+ XML_count, XML_percent, XML_sum,
+ // caption filter (4-17)
+ XML_captionEqual, XML_captionNotEqual,
+ XML_captionBeginsWith, XML_captionNotBeginsWith, XML_captionEndsWith, XML_captionNotEndsWith,
+ XML_captionContains, XML_captionNotContains, XML_captionGreaterThan, XML_captionGreaterThanOrEqual,
+ XML_captionLessThan, XML_captionLessThanOrEqual, XML_captionBetween, XML_captionNotBetween,
+ // value filter (18-25)
+ XML_valueEqual, XML_valueNotEqual, XML_valueGreaterThan, XML_valueGreaterThanOrEqual,
+ XML_valueLessThan, XML_valueLessThanOrEqual, XML_valueBetween, XML_valueNotBetween,
+ // date filter (26-65)
+ XML_dateEqual, XML_dateOlderThan, XML_dateNewerThan, XML_dateBetween,
+ XML_tomorrow, XML_today, XML_yesterday, XML_nextWeek, XML_thisWeek, XML_lastWeek,
+ XML_nextMonth, XML_thisMonth, XML_lastMonth, XML_nextQuarter, XML_thisQuarter, XML_lastQuarter,
+ XML_nextYear, XML_thisYear, XML_lastYear, XML_yearToDate, XML_Q1, XML_Q2, XML_Q3, XML_Q4,
+ XML_M1, XML_M2, XML_M3, XML_M4, XML_M5, XML_M6, XML_M7, XML_M8, XML_M9, XML_M10, XML_M11, XML_M12,
+ XML_dateNotEqual, XML_dateOlderThanOrEqual, XML_dateNewerThanOrEqual, XML_dateNotBetween
+ };
+ maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
+}
+
+void PivotTableFilter::importTop10Filter( SequenceInputStream& rStrm )
+{
+ sal_uInt8 nFlags;
+ rStrm >> nFlags >> maModel.mfValue;
+
+ OSL_ENSURE( getFlag( nFlags, BIFF12_TOP10FILTER_PERCENT ) == (maModel.mnType == XML_percent),
+ "PivotTableFilter::importTop10 - unexpected value of percent attribute" );
+ maModel.mbTopFilter = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
+}
+
+void PivotTableFilter::finalizeImport()
+{
+ // only simple top10 filter supported
+ if( maModel.mnType == XML_count )
+ {
+ PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) );
+ if( aPropSet.is() )
+ {
+ using namespace ::com::sun::star::sheet;
+ DataPilotFieldAutoShowInfo aAutoShowInfo;
+ aAutoShowInfo.IsEnabled = sal_True;
+ aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM;
+ aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 );
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) )
+ aAutoShowInfo.DataField = pCacheField->getName();
+ aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo );
+ }
+ }
+}
+
+// ============================================================================
+
+PTDefinitionModel::PTDefinitionModel() :
+ mnCacheId( -1 ),
+ mnDataPosition( 0 ),
+ mnPageWrap( 0 ),
+ mnIndent( 1 ),
+ mnChartFormat( 0 ),
+ mnRowFields( 0 ),
+ mnColFields( 0 ),
+ mbDataOnRows( false ),
+ mbShowError( false ),
+ mbShowMissing( true ),
+ mbShowItems( true ),
+ mbDisableFieldList( false ),
+ mbShowCalcMembers( true ),
+ mbVisualTotals( true ),
+ mbShowDrill( true ),
+ mbPrintDrill( false ),
+ mbEnableDrill( true ),
+ mbPreserveFormatting( true ),
+ mbUseAutoFormat( false ),
+ mbPageOverThenDown( false ),
+ mbSubtotalHiddenItems( false ),
+ mbRowGrandTotals( true ),
+ mbColGrandTotals( true ),
+ mbFieldPrintTitles( false ),
+ mbItemPrintTitles( false ),
+ mbMergeItem( false ),
+ mbShowEmptyRow( false ),
+ mbShowEmptyCol( false ),
+ mbShowHeaders( true ),
+ mbFieldListSortAsc( false ),
+ mbCustomListSort( true )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PTLocationModel::PTLocationModel() :
+ mnFirstHeaderRow( 0 ),
+ mnFirstDataRow( 0 ),
+ mnFirstDataCol( 0 ),
+ mnRowPageCount( 0 ),
+ mnColPageCount( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+PivotTable::PivotTable( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maDataField( *this, OOX_PT_DATALAYOUTFIELD ),
+ mpPivotCache( 0 )
+{
+}
+
+void PivotTable::importPivotTableDefinition( const AttributeList& rAttribs )
+{
+ maDefModel.maName = rAttribs.getXString( XML_name, OUString() );
+ maDefModel.maDataCaption = rAttribs.getXString( XML_dataCaption , OUString() );
+ maDefModel.maGrandTotalCaption = rAttribs.getXString( XML_grandTotalCaption, OUString() );
+ maDefModel.maRowHeaderCaption = rAttribs.getXString( XML_rowHeaderCaption, OUString() );
+ maDefModel.maColHeaderCaption = rAttribs.getXString( XML_colHeaderCaption, OUString() );
+ maDefModel.maErrorCaption = rAttribs.getXString( XML_errorCaption, OUString() );
+ maDefModel.maMissingCaption = rAttribs.getXString( XML_missingCaption, OUString() );
+ maDefModel.maPageStyle = rAttribs.getXString( XML_pageStyle, OUString() );
+ maDefModel.maPivotTableStyle = rAttribs.getXString( XML_pivotTableStyle, OUString() );
+ maDefModel.maVacatedStyle = rAttribs.getXString( XML_vacatedStyle, OUString() );
+ maDefModel.maTag = rAttribs.getXString( XML_tag, OUString() );
+ maDefModel.mnCacheId = rAttribs.getInteger( XML_cacheId, -1 );
+ maDefModel.mnDataPosition = rAttribs.getInteger( XML_dataPosition, 0 );
+ maDefModel.mnPageWrap = rAttribs.getInteger( XML_pageWrap, 0 );
+ maDefModel.mnIndent = rAttribs.getInteger( XML_indent, 1 );
+ maDefModel.mnChartFormat = rAttribs.getInteger( XML_chartFormat, 0 );
+ maDefModel.mnAutoFormatId = rAttribs.getInteger( XML_autoFormatId, 0 );
+ maDefModel.mbDataOnRows = rAttribs.getBool( XML_dataOnRows, false );
+ maDefModel.mbShowError = rAttribs.getBool( XML_showError, false );
+ maDefModel.mbShowMissing = rAttribs.getBool( XML_showMissing, true );
+ maDefModel.mbShowItems = rAttribs.getBool( XML_showItems, true );
+ maDefModel.mbDisableFieldList = rAttribs.getBool( XML_disableFieldList, false );
+ maDefModel.mbShowCalcMembers = rAttribs.getBool( XML_showCalcMbrs, true );
+ maDefModel.mbVisualTotals = rAttribs.getBool( XML_visualTotals, true );
+ maDefModel.mbShowDrill = rAttribs.getBool( XML_showDrill, true );
+ maDefModel.mbPrintDrill = rAttribs.getBool( XML_printDrill, false );
+ maDefModel.mbEnableDrill = rAttribs.getBool( XML_enableDrill, true );
+ maDefModel.mbPreserveFormatting = rAttribs.getBool( XML_preserveFormatting, true );
+ maDefModel.mbUseAutoFormat = rAttribs.getBool( XML_useAutoFormatting, false );
+ maDefModel.mbPageOverThenDown = rAttribs.getBool( XML_pageOverThenDown, false );
+ maDefModel.mbSubtotalHiddenItems = rAttribs.getBool( XML_subtotalHiddenItems, false );
+ maDefModel.mbRowGrandTotals = rAttribs.getBool( XML_rowGrandTotals, true );
+ maDefModel.mbColGrandTotals = rAttribs.getBool( XML_colGrandTotals, true );
+ maDefModel.mbFieldPrintTitles = rAttribs.getBool( XML_fieldPrintTitles, false );
+ maDefModel.mbItemPrintTitles = rAttribs.getBool( XML_itemPrintTitles, false );
+ maDefModel.mbMergeItem = rAttribs.getBool( XML_mergeItem, false );
+ maDefModel.mbShowEmptyRow = rAttribs.getBool( XML_showEmptyRow, false );
+ maDefModel.mbShowEmptyCol = rAttribs.getBool( XML_showEmptyCol, false );
+ maDefModel.mbShowHeaders = rAttribs.getBool( XML_showHeaders, true );
+ maDefModel.mbFieldListSortAsc = rAttribs.getBool( XML_fieldListSortAscending, false );
+ maDefModel.mbCustomListSort = rAttribs.getBool( XML_customListSort, true );
+ maDefModel.mbApplyNumFmt = rAttribs.getBool( XML_applyNumberFormats, false );
+ maDefModel.mbApplyFont = rAttribs.getBool( XML_applyFontFormats, false );
+ maDefModel.mbApplyAlignment = rAttribs.getBool( XML_applyAlignmentFormats, false );
+ maDefModel.mbApplyBorder = rAttribs.getBool( XML_applyBorderFormats, false );
+ maDefModel.mbApplyFill = rAttribs.getBool( XML_applyPatternFormats, false );
+ // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
+ maDefModel.mbApplyProtection = rAttribs.getBool( XML_applyWidthHeightFormats, false );
+}
+
+void PivotTable::importLocation( const AttributeList& rAttribs, sal_Int16 nSheet )
+{
+ getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet );
+ maLocationModel.mnFirstHeaderRow = rAttribs.getInteger( XML_firstHeaderRow, 0 );
+ maLocationModel.mnFirstDataRow = rAttribs.getInteger( XML_firstDataRow, 0 );
+ maLocationModel.mnFirstDataCol = rAttribs.getInteger( XML_firstDataCol, 0 );
+ maLocationModel.mnRowPageCount = rAttribs.getInteger( XML_rowPageCount, 0 );
+ maLocationModel.mnColPageCount = rAttribs.getInteger( XML_colPageCount, 0 );
+}
+
+void PivotTable::importRowField( const AttributeList& rAttribs )
+{
+ importField( maRowFields, rAttribs );
+}
+
+void PivotTable::importColField( const AttributeList& rAttribs )
+{
+ importField( maColFields, rAttribs );
+}
+
+void PivotTable::importPageField( const AttributeList& rAttribs )
+{
+ PTPageFieldModel aModel;
+ aModel.maName = rAttribs.getXString( XML_name, OUString() );
+ aModel.mnField = rAttribs.getInteger( XML_fld, -1 );
+ // specification is wrong, XML_item is not the cache item, but the field item
+ aModel.mnItem = rAttribs.getInteger( XML_item, BIFF12_PTPAGEFIELD_MULTIITEMS );
+ maPageFields.push_back( aModel );
+}
+
+void PivotTable::importDataField( const AttributeList& rAttribs )
+{
+ PTDataFieldModel aModel;
+ aModel.maName = rAttribs.getXString( XML_name, OUString() );
+ aModel.mnField = rAttribs.getInteger( XML_fld, -1 );
+ aModel.mnSubtotal = rAttribs.getToken( XML_subtotal, XML_sum );
+ aModel.mnShowDataAs = rAttribs.getToken( XML_showDataAs, XML_normal );
+ aModel.mnBaseField = rAttribs.getInteger( XML_baseField, -1 );
+ aModel.mnBaseItem = rAttribs.getInteger( XML_baseItem, -1 );
+ aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
+ maDataFields.push_back( aModel );
+}
+
+void PivotTable::importPTDefinition( SequenceInputStream& rStrm )
+{
+ sal_uInt32 nFlags1, nFlags2, nFlags3;
+ sal_uInt8 nDataAxis;
+ rStrm >> nFlags1 >> nFlags2 >> nFlags3 >> nDataAxis;
+ maDefModel.mnPageWrap = rStrm.readuInt8();
+ rStrm.skip( 2 ); // refresh versions
+ rStrm >> maDefModel.mnDataPosition;
+ maDefModel.mnAutoFormatId = rStrm.readuInt16();
+ rStrm.skip( 2 ); // unused
+ rStrm >> maDefModel.mnChartFormat >> maDefModel.mnCacheId >> maDefModel.maName;
+ if( getFlag( nFlags2, BIFF12_PTDEF_HASDATACAPTION ) )
+ rStrm >> maDefModel.maDataCaption;
+ if( getFlag( nFlags2, BIFF12_PTDEF_HASGRANDTOTALCAPTION ) )
+ rStrm >> maDefModel.maGrandTotalCaption;
+ if( !getFlag( nFlags3, BIFF12_PTDEF_NOERRORCAPTION ) ) // missing flag indicates existing string
+ rStrm >> maDefModel.maErrorCaption;
+ if( !getFlag( nFlags3, BIFF12_PTDEF_NOMISSINGCAPTION ) ) // missing flag indicates existing string
+ rStrm >> maDefModel.maMissingCaption;
+ if( getFlag( nFlags2, BIFF12_PTDEF_HASPAGESTYLE ) )
+ rStrm >> maDefModel.maPageStyle;
+ if( getFlag( nFlags2, BIFF12_PTDEF_HASPIVOTTABLESTYLE ) )
+ rStrm >> maDefModel.maPivotTableStyle;
+ if( getFlag( nFlags2, BIFF12_PTDEF_HASVACATEDSTYLE ) )
+ rStrm >> maDefModel.maVacatedStyle;
+ if( getFlag( nFlags2, BIFF12_PTDEF_HASTAG ) )
+ rStrm >> maDefModel.maTag;
+ if( getFlag( nFlags3, BIFF12_PTDEF_HASCOLHEADERCAPTION ) ) // TODO: right order (col/row)? spec is unclear
+ rStrm >> maDefModel.maColHeaderCaption;
+ if( getFlag( nFlags3, BIFF12_PTDEF_HASROWHEADERCAPTION ) )
+ rStrm >> maDefModel.maRowHeaderCaption;
+
+ OSL_ENSURE( (nDataAxis == BIFF12_PTDEF_ROWAXIS) || (nDataAxis == BIFF12_PTDEF_COLAXIS),
+ "PivotTable::importPTDefinition - unexpected axis position for data field" );
+
+ maDefModel.mnIndent = extractValue< sal_uInt8 >( nFlags1, 24, 7 );
+ maDefModel.mbDataOnRows = nDataAxis == BIFF12_PTDEF_ROWAXIS;
+ maDefModel.mbShowError = getFlag( nFlags2, BIFF12_PTDEF_SHOWERROR );
+ maDefModel.mbShowMissing = getFlag( nFlags2, BIFF12_PTDEF_SHOWMISSING );
+ maDefModel.mbShowItems = getFlag( nFlags1, BIFF12_PTDEF_SHOWITEMS );
+ maDefModel.mbDisableFieldList = getFlag( nFlags1, BIFF12_PTDEF_DISABLEFIELDLIST );
+ maDefModel.mbShowCalcMembers = !getFlag( nFlags1, BIFF12_PTDEF_HIDECALCMEMBERS );
+ maDefModel.mbVisualTotals = !getFlag( nFlags1, BIFF12_PTDEF_WITHHIDDENTOTALS );
+ maDefModel.mbShowDrill = !getFlag( nFlags1, BIFF12_PTDEF_HIDEDRILL );
+ maDefModel.mbPrintDrill = getFlag( nFlags1, BIFF12_PTDEF_PRINTDRILL );
+ maDefModel.mbEnableDrill = getFlag( nFlags2, BIFF12_PTDEF_ENABLEDRILL );
+ maDefModel.mbPreserveFormatting = getFlag( nFlags2, BIFF12_PTDEF_PRESERVEFORMATTING );
+ maDefModel.mbUseAutoFormat = getFlag( nFlags2, BIFF12_PTDEF_USEAUTOFORMAT );
+ maDefModel.mbPageOverThenDown = getFlag( nFlags2, BIFF12_PTDEF_PAGEOVERTHENDOWN );
+ maDefModel.mbSubtotalHiddenItems = getFlag( nFlags2, BIFF12_PTDEF_SUBTOTALHIDDENITEMS );
+ maDefModel.mbRowGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_ROWGRANDTOTALS );
+ maDefModel.mbColGrandTotals = getFlag( nFlags2, BIFF12_PTDEF_COLGRANDTOTALS );
+ maDefModel.mbFieldPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_FIELDPRINTTITLES );
+ maDefModel.mbItemPrintTitles = getFlag( nFlags2, BIFF12_PTDEF_ITEMPRINTTITLES );
+ maDefModel.mbMergeItem = getFlag( nFlags2, BIFF12_PTDEF_MERGEITEM );
+ maDefModel.mbApplyNumFmt = getFlag( nFlags2, BIFF12_PTDEF_APPLYNUMFMT );
+ maDefModel.mbApplyFont = getFlag( nFlags2, BIFF12_PTDEF_APPLYFONT );
+ maDefModel.mbApplyAlignment = getFlag( nFlags2, BIFF12_PTDEF_APPLYALIGNMENT );
+ maDefModel.mbApplyBorder = getFlag( nFlags2, BIFF12_PTDEF_APPLYBORDER );
+ maDefModel.mbApplyFill = getFlag( nFlags2, BIFF12_PTDEF_APPLYFILL );
+ maDefModel.mbApplyProtection = getFlag( nFlags2, BIFF12_PTDEF_APPLYPROTECTION );
+ maDefModel.mbShowEmptyRow = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYROW );
+ maDefModel.mbShowEmptyCol = getFlag( nFlags2, BIFF12_PTDEF_SHOWEMPTYCOL );
+ maDefModel.mbShowHeaders = !getFlag( nFlags1, BIFF12_PTDEF_HIDEHEADERS );
+ maDefModel.mbFieldListSortAsc = getFlag( nFlags3, BIFF12_PTDEF_FIELDLISTSORTASC );
+ maDefModel.mbCustomListSort = !getFlag( nFlags3, BIFF12_PTDEF_NOCUSTOMLISTSORT );
+}
+
+void PivotTable::importPTLocation( SequenceInputStream& rStrm, sal_Int16 nSheet )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange >> maLocationModel.mnFirstHeaderRow
+ >> maLocationModel.mnFirstDataRow >> maLocationModel.mnFirstDataCol
+ >> maLocationModel.mnRowPageCount >> maLocationModel.mnColPageCount;
+ getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
+}
+
+void PivotTable::importPTRowFields( SequenceInputStream& rStrm )
+{
+ importFields( maRowFields, rStrm );
+}
+
+void PivotTable::importPTColFields( SequenceInputStream& rStrm )
+{
+ importFields( maColFields, rStrm );
+}
+
+void PivotTable::importPTPageField( SequenceInputStream& rStrm )
+{
+ PTPageFieldModel aModel;
+ sal_uInt8 nFlags;
+ rStrm >> aModel.mnField >> aModel.mnItem;
+ rStrm.skip( 4 ); // hierarchy
+ rStrm >> nFlags;
+ if( getFlag( nFlags, BIFF12_PTPAGEFIELD_HASNAME ) )
+ rStrm >> aModel.maName;
+ maPageFields.push_back( aModel );
+}
+
+void PivotTable::importPTDataField( SequenceInputStream& rStrm )
+{
+ PTDataFieldModel aModel;
+ sal_Int32 nSubtotal, nShowDataAs;
+ sal_uInt8 nHasName;
+ rStrm >> aModel.mnField >> nSubtotal >> nShowDataAs >> aModel.mnBaseField >> aModel.mnBaseItem >> aModel.mnNumFmtId >> nHasName;
+ if( nHasName == 1 )
+ rStrm >> aModel.maName;
+ aModel.setBiffSubtotal( nSubtotal );
+ aModel.setBiffShowDataAs( nShowDataAs );
+ maDataFields.push_back( aModel );
+}
+
+void PivotTable::importPTDefinition( BiffInputStream& rStrm, sal_Int16 nSheet )
+{
+ BinRange aBinRange;
+ sal_uInt16 nFlags, nTabNameLen, nDataNameLen;
+ rStrm >> aBinRange;
+ maLocationModel.mnFirstHeaderRow = rStrm.readuInt16();
+ maLocationModel.mnFirstDataRow = rStrm.readuInt16();
+ maLocationModel.mnFirstDataCol = rStrm.readuInt16();
+ maDefModel.mnCacheId = rStrm.readuInt16();
+ rStrm.skip( 2 ); // unused
+ maDefModel.mbDataOnRows = rStrm.readuInt16() == BIFF_PTDEF_ROWAXIS;
+ maDefModel.mnDataPosition = rStrm.readInt16();
+ rStrm.skip( 2 ); // number of fields
+ rStrm >> maDefModel.mnRowFields >> maDefModel.mnColFields;
+ rStrm.skip( 8 ); // number of page fields, data fields, data rows, data columns
+ rStrm >> nFlags;
+ maDefModel.mnChartFormat = rStrm.readuInt16();
+ rStrm >> nTabNameLen >> nDataNameLen;
+ maDefModel.maName = lclReadPivotString( *this, rStrm, nTabNameLen );
+ maDefModel.maDataCaption = lclReadPivotString( *this, rStrm, nDataNameLen );
+
+ maDefModel.mbRowGrandTotals = getFlag( nFlags, BIFF_PTDEF_ROWGRANDTOTALS );
+ maDefModel.mbColGrandTotals = getFlag( nFlags, BIFF_PTDEF_COLGRANDTOTALS );
+
+ getAddressConverter().convertToCellRangeUnchecked( maLocationModel.maRange, aBinRange, nSheet );
+}
+
+void PivotTable::importPTDefinition2( BiffInputStream& rStrm )
+{
+ if( getBiff() == BIFF8 )
+ {
+ sal_uInt16 nErrCaptLen, nMissCaptLen, nTagLen, nPageStyleLen, nTabStyleLen, nVacStyleLen;
+ sal_uInt32 nFlags;
+ rStrm.skip( 2 ); // number of formatting records
+ rStrm >> nErrCaptLen >> nMissCaptLen >> nTagLen;
+ rStrm.skip( 6 ); // number of selection records, page rows, page columns
+ rStrm >> nFlags >> nPageStyleLen >> nTabStyleLen >> nVacStyleLen;
+ maDefModel.maErrorCaption = lclReadPivotString( *this, rStrm, nErrCaptLen );
+ maDefModel.maMissingCaption = lclReadPivotString( *this, rStrm, nMissCaptLen );
+ maDefModel.maTag = lclReadPivotString( *this, rStrm, nTagLen );
+ maDefModel.maPageStyle = lclReadPivotString( *this, rStrm, nPageStyleLen );
+ maDefModel.maPivotTableStyle = lclReadPivotString( *this, rStrm, nTabStyleLen );
+ maDefModel.maVacatedStyle = lclReadPivotString( *this, rStrm, nVacStyleLen );
+
+ maDefModel.mbShowError = getFlag( nFlags, BIFF_PTDEF2_SHOWERROR );
+ maDefModel.mbShowMissing = getFlag( nFlags, BIFF_PTDEF2_SHOWMISSING );
+ maDefModel.mbEnableDrill = getFlag( nFlags, BIFF_PTDE2F_ENABLEDRILL );
+ maDefModel.mbPreserveFormatting = getFlag( nFlags, BIFF_PTDEF2_PRESERVEFORMATTING );
+ maDefModel.mbPageOverThenDown = getFlag( nFlags, BIFF_PTDEF2_PAGEOVERTHENDOWN );
+ maDefModel.mbSubtotalHiddenItems = getFlag( nFlags, BIFF_PTDEF2_SUBTOTALHIDDENITEMS );
+ maDefModel.mbMergeItem = getFlag( nFlags, BIFF_PTDEF2_MERGEITEM );
+ }
+}
+
+void PivotTable::importPTRowColFields( BiffInputStream& rStrm )
+{
+ // first PTROWCOLFIELDS record contains row fields unless there are no row fields
+ if( (maDefModel.mnRowFields > 0) && maRowFields.empty() )
+ importFields( maRowFields, rStrm, maDefModel.mnRowFields );
+ else if( (maDefModel.mnColFields > 0) && maColFields.empty() )
+ importFields( maColFields, rStrm, maDefModel.mnColFields );
+}
+
+void PivotTable::importPTPageFields( BiffInputStream& rStrm )
+{
+ while( rStrm.getRemaining() >= 6 )
+ {
+ PTPageFieldModel aModel;
+ sal_Int16 nField, nItem;
+ rStrm >> nField >> nItem;
+ rStrm.skip( 2 ); // dropdown object ID
+ aModel.mnField = nField;
+ aModel.mnItem = (nItem == BIFF_PTPAGEFIELDS_ALLITEMS) ? BIFF12_PTPAGEFIELD_MULTIITEMS : nItem;
+ maPageFields.push_back( aModel );
+ }
+}
+
+void PivotTable::importPTDataField( BiffInputStream& rStrm )
+{
+ PTDataFieldModel aModel;
+ sal_Int16 nField, nBaseField, nBaseItem;
+ sal_uInt16 nSubtotal, nShowDataAs, nNumFmt, nNameLen;
+ rStrm >> nField >> nSubtotal >> nShowDataAs >> nBaseField >> nBaseItem >> nNumFmt >> nNameLen;
+ aModel.maName = lclReadPivotString( *this, rStrm, nNameLen );
+
+ aModel.mnField = nField;
+ aModel.setBiffSubtotal( nSubtotal );
+ aModel.setBiffShowDataAs( nShowDataAs );
+ aModel.mnBaseField = nBaseField;
+ switch( nBaseItem )
+ {
+ case BIFF_PTDATAFIELD_PREVIOUS: aModel.mnBaseItem = OOX_PT_PREVIOUS_ITEM; break;
+ case BIFF_PTDATAFIELD_NEXT: aModel.mnBaseItem = OOX_PT_NEXT_ITEM; break;
+ default: aModel.mnBaseItem = nBaseItem;
+ }
+ aModel.mnNumFmtId = nNumFmt;
+
+ maDataFields.push_back( aModel );
+}
+
+PivotTableField& PivotTable::createTableField()
+{
+ sal_Int32 nFieldIndex = static_cast< sal_Int32 >( maFields.size() );
+ PivotTableFieldVector::value_type xTableField( new PivotTableField( *this, nFieldIndex ) );
+ maFields.push_back( xTableField );
+ return *xTableField;
+}
+
+PivotTableFilter& PivotTable::createTableFilter()
+{
+ PivotTableFilterVector::value_type xTableFilter( new PivotTableFilter( *this ) );
+ maFilters.push_back( xTableFilter );
+ return *xTableFilter;
+}
+
+void PivotTable::finalizeImport()
+{
+ if( getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) )
+ {
+ mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId );
+ if( mpPivotCache && mpPivotCache->isValidDataSource() && (maDefModel.maName.getLength() > 0) )
+ {
+ // clear destination area of the original pivot table
+ try
+ {
+ Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW );
+ using namespace ::com::sun::star::sheet::CellFlags;
+ xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED );
+ }
+ catch( Exception& )
+ {
+ }
+
+ try
+ {
+ // create a new data pilot descriptor based on the source data
+ Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.Sheet ), UNO_QUERY_THROW );
+ Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW );
+ mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW );
+ mxDPDescriptor->setSourceRange( mpPivotCache->getSourceRange() );
+ mxDPDescriptor->setTag( maDefModel.maTag );
+
+ // global data pilot properties
+ PropertySet aDescProp( mxDPDescriptor );
+ aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals );
+ aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals );
+ aDescProp.setProperty( PROP_ShowFilterButton, false );
+ aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill );
+
+ // finalize all fields, this finds field names and creates grouping fields
+ maFields.forEachMem( &PivotTableField::finalizeImport, ::boost::cref( mxDPDescriptor ) );
+
+ // all row fields
+ for( IndexVector::iterator aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
+ if( PivotTableField* pField = getTableField( *aIt ) )
+ pField->convertRowField();
+
+ // all column fields
+ for( IndexVector::iterator aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt )
+ if( PivotTableField* pField = getTableField( *aIt ) )
+ pField->convertColField();
+
+ // all page fields
+ for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
+ if( PivotTableField* pField = getTableField( aIt->mnField ) )
+ pField->convertPageField( *aIt );
+
+ // all hidden fields
+ ::std::set< sal_Int32 > aVisFields;
+ aVisFields.insert( maRowFields.begin(), maRowFields.end() );
+ aVisFields.insert( maColFields.begin(), maColFields.end() );
+ for( PageFieldVector::iterator aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt )
+ aVisFields.insert( aIt->mnField );
+ for( PivotTableFieldVector::iterator aBeg = maFields.begin(), aIt = aBeg, aEnd = maFields.end(); aIt != aEnd; ++aIt )
+ if( aVisFields.count( static_cast< sal_Int32 >( aIt - aBeg ) ) == 0 )
+ (*aIt)->convertHiddenField();
+
+ // all data fields
+ for( DataFieldVector::iterator aIt = maDataFields.begin(), aEnd = maDataFields.end(); aIt != aEnd; ++aIt )
+ if( PivotTableField* pField = getTableField( aIt->mnField ) )
+ pField->convertDataField( *aIt );
+
+ // filters
+ maFilters.forEachMem( &PivotTableFilter::finalizeImport );
+
+ // calculate base position of table
+ CellAddress aPos( maLocationModel.maRange.Sheet, maLocationModel.maRange.StartColumn, maLocationModel.maRange.StartRow );
+ /* If page fields exist, include them into the destination
+ area (they are excluded in Excel). Add an extra blank row. */
+ if( !maPageFields.empty() )
+ aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 );
+
+ // insert the DataPilot table into the sheet
+ xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "PivotTable::finalizeImport - exception while creating the DataPilot table" );
+ }
+ }
+ }
+}
+
+void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
+{
+ // process all fields, there is no chaining information in the cache fields
+ maFields.forEachMem( &PivotTableField::finalizeDateGroupingImport, ::boost::cref( rxBaseDPField ), nBaseFieldIdx );
+}
+
+void PivotTable::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField,
+ const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames )
+{
+ // try to create parent group fields that group the items of the passed base field
+ if( PivotTableField* pParentTableField = maFields.get( rBaseCacheField.getParentGroupField() ).get() )
+ pParentTableField->finalizeParentGroupingImport( rxBaseDPField, orItemNames );
+}
+
+Reference< XDataPilotField > PivotTable::getDataPilotField( const OUString& rFieldName ) const
+{
+ Reference< XDataPilotField > xDPField;
+ if( (rFieldName.getLength() > 0) && mxDPDescriptor.is() ) try
+ {
+ Reference< XNameAccess > xDPFieldsNA( mxDPDescriptor->getDataPilotFields(), UNO_QUERY_THROW );
+ xDPField.set( xDPFieldsNA->getByName( rFieldName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xDPField;
+}
+
+Reference< XDataPilotField > PivotTable::getDataPilotField( sal_Int32 nFieldIdx ) const
+{
+ Reference< XDataPilotField > xDPField;
+ if( const PivotTableField* pTableField = maFields.get( nFieldIdx ).get() )
+ xDPField = getDataPilotField( pTableField->getDPFieldName() );
+ return xDPField;
+}
+
+Reference< XDataPilotField > PivotTable::getDataLayoutField() const
+{
+ Reference< XDataPilotField > xDPField;
+ try
+ {
+ Reference< XDataPilotDataLayoutFieldSupplier > xDPDataFieldSupp( mxDPDescriptor, UNO_QUERY_THROW );
+ xDPField = xDPDataFieldSupp->getDataLayoutField();
+ }
+ catch( Exception& )
+ {
+ }
+ return xDPField;
+}
+
+const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const
+{
+ return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : 0;
+}
+
+const PivotCacheField* PivotTable::getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const
+{
+ const PTDataFieldModel* pDataField = ContainerHelper::getVectorElement( maDataFields, nDataItemIdx );
+ return pDataField ? getCacheField( pDataField->mnField ) : 0;
+}
+
+sal_Int32 PivotTable::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
+{
+ return mpPivotCache ? mpPivotCache->getCacheDatabaseIndex( nFieldIdx ) : -1;
+}
+
+// private --------------------------------------------------------------------
+
+PivotTableField* PivotTable::getTableField( sal_Int32 nFieldIdx )
+{
+ return (nFieldIdx == OOX_PT_DATALAYOUTFIELD) ? &maDataField : maFields.get( nFieldIdx ).get();
+}
+
+void PivotTable::importField( IndexVector& orFields, const AttributeList& rAttribs )
+{
+ orFields.push_back( rAttribs.getInteger( XML_x, -1 ) );
+}
+
+void PivotTable::importFields( IndexVector& orFields, SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
+ orFields.clear();
+ sal_Int32 nCount = rStrm.readInt32();
+ OSL_ENSURE( 4 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
+ nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 4 );
+ for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
+ orFields.push_back( rStrm.readInt32() );
+}
+
+void PivotTable::importFields( IndexVector& orFields, BiffInputStream& rStrm, sal_Int32 nCount )
+{
+ OSL_ENSURE( orFields.empty(), "PivotTable::importFields - multiple record instances" );
+ orFields.clear();
+ OSL_ENSURE( 2 * nCount == rStrm.getRemaining(), "PivotTable::importFields - invalid field count" );
+ nCount = static_cast< sal_Int32 >( rStrm.getRemaining() / 2 );
+ for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
+ orFields.push_back( rStrm.readInt16() );
+}
+
+// ============================================================================
+
+PivotTableBuffer::PivotTableBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+PivotTable& PivotTableBuffer::createPivotTable()
+{
+ PivotTableVector::value_type xTable( new PivotTable( *this ) );
+ maTables.push_back( xTable );
+ return *xTable;
+}
+
+void PivotTableBuffer::finalizeImport()
+{
+ maTables.forEachMem( &PivotTable::finalizeImport );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/pivottablefragment.cxx b/oox/source/xls/pivottablefragment.cxx
new file mode 100644
index 000000000000..6e28118711c9
--- /dev/null
+++ b/oox/source/xls/pivottablefragment.cxx
@@ -0,0 +1,319 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/pivottablefragment.hxx"
+
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/pivottablebuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+PivotTableFieldContext::PivotTableFieldContext( WorksheetFragmentBase& rFragment, PivotTableField& rTableField ) :
+ WorksheetContextBase( rFragment ),
+ mrTableField( rTableField )
+{
+}
+
+ContextHandlerRef PivotTableFieldContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( pivotField ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( items ): return this;
+ case XLS_TOKEN( autoSortScope ): return this;
+ }
+ break;
+ case XLS_TOKEN( items ):
+ if( nElement == XLS_TOKEN( item ) ) mrTableField.importItem( rAttribs );
+ break;
+ case XLS_TOKEN( autoSortScope ):
+ if( nElement == XLS_TOKEN( pivotArea ) ) return this;
+ break;
+ case XLS_TOKEN( pivotArea ):
+ if( nElement == XLS_TOKEN( references ) ) return this;
+ break;
+ case XLS_TOKEN( references ):
+ if( nElement == XLS_TOKEN( reference ) ) { mrTableField.importReference( rAttribs ); return this; }
+ break;
+ case XLS_TOKEN( reference ):
+ if( nElement == XLS_TOKEN( x ) ) mrTableField.importReferenceItem( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+void PivotTableFieldContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( isRootElement() )
+ mrTableField.importPivotField( rAttribs );
+}
+
+ContextHandlerRef PivotTableFieldContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_PTFIELD:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PTFITEMS: return this;
+ case BIFF12_ID_AUTOSORTSCOPE: return this;
+ }
+ break;
+ case BIFF12_ID_PTFITEMS:
+ if( nRecId == BIFF12_ID_PTFITEM ) mrTableField.importPTFItem( rStrm );
+ break;
+ case BIFF12_ID_AUTOSORTSCOPE:
+ if( nRecId == BIFF12_ID_PIVOTAREA ) return this;
+ break;
+ case BIFF12_ID_PIVOTAREA:
+ if( nRecId == BIFF12_ID_PTREFERENCES ) return this;
+ break;
+ case BIFF12_ID_PTREFERENCES:
+ if( nRecId == BIFF12_ID_PTREFERENCE ) { mrTableField.importPTReference( rStrm ); return this; }
+ break;
+ case BIFF12_ID_PTREFERENCE:
+ if( nRecId == BIFF12_ID_PTREFERENCEITEM ) mrTableField.importPTReferenceItem( rStrm );
+ break;
+ }
+ return 0;
+}
+
+void PivotTableFieldContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ if( isRootElement() )
+ mrTableField.importPTField( rStrm );
+}
+
+// ============================================================================
+
+PivotTableFilterContext::PivotTableFilterContext( WorksheetFragmentBase& rFragment, PivotTableFilter& rTableFilter ) :
+ WorksheetContextBase( rFragment ),
+ mrTableFilter( rTableFilter )
+{
+}
+
+ContextHandlerRef PivotTableFilterContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( filter ):
+ if( nElement == XLS_TOKEN( autoFilter ) ) return this;
+ break;
+ case XLS_TOKEN( autoFilter ):
+ if( nElement == XLS_TOKEN( filterColumn ) ) return this;
+ break;
+ case XLS_TOKEN( filterColumn ):
+ if( nElement == XLS_TOKEN( top10 ) ) mrTableFilter.importTop10( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+void PivotTableFilterContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( isRootElement() )
+ mrTableFilter.importFilter( rAttribs );
+}
+
+ContextHandlerRef PivotTableFilterContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_PTFILTER:
+ if( nRecId == BIFF12_ID_AUTOFILTER ) return this;
+ break;
+ case BIFF12_ID_AUTOFILTER:
+ if( nRecId == BIFF12_ID_FILTERCOLUMN ) return this;
+ break;
+ case BIFF12_ID_FILTERCOLUMN:
+ if( nRecId == BIFF12_ID_TOP10FILTER ) mrTableFilter.importTop10Filter( rStrm );
+ break;
+ }
+ return 0;
+}
+
+void PivotTableFilterContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ if( isRootElement() )
+ mrTableFilter.importPTFilter( rStrm );
+}
+
+// ============================================================================
+
+PivotTableFragment::PivotTableFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath ),
+ mrPivotTable( getPivotTables().createPivotTable() )
+{
+}
+
+ContextHandlerRef PivotTableFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( pivotTableDefinition ) ) { mrPivotTable.importPivotTableDefinition( rAttribs ); return this; }
+ break;
+
+ case XLS_TOKEN( pivotTableDefinition ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( location ): mrPivotTable.importLocation( rAttribs, getSheetIndex() ); break;
+ case XLS_TOKEN( pivotFields ): return this;
+ case XLS_TOKEN( rowFields ): return this;
+ case XLS_TOKEN( colFields ): return this;
+ case XLS_TOKEN( pageFields ): return this;
+ case XLS_TOKEN( dataFields ): return this;
+ case XLS_TOKEN( filters ): return this;
+ }
+ break;
+
+ case XLS_TOKEN( pivotFields ):
+ if( nElement == XLS_TOKEN( pivotField ) ) return new PivotTableFieldContext( *this, mrPivotTable.createTableField() );
+ break;
+ case XLS_TOKEN( rowFields ):
+ if( nElement == XLS_TOKEN( field ) ) mrPivotTable.importRowField( rAttribs );
+ break;
+ case XLS_TOKEN( colFields ):
+ if( nElement == XLS_TOKEN( field ) ) mrPivotTable.importColField( rAttribs );
+ break;
+ case XLS_TOKEN( pageFields ):
+ if( nElement == XLS_TOKEN( pageField ) ) mrPivotTable.importPageField( rAttribs );
+ break;
+ case XLS_TOKEN( dataFields ):
+ if( nElement == XLS_TOKEN( dataField ) ) mrPivotTable.importDataField( rAttribs );
+ break;
+ case XLS_TOKEN( filters ):
+ if( nElement == XLS_TOKEN( filter ) ) return new PivotTableFilterContext( *this, mrPivotTable.createTableFilter() );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef PivotTableFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_PTDEFINITION ) { mrPivotTable.importPTDefinition( rStrm ); return this; }
+ break;
+
+ case BIFF12_ID_PTDEFINITION:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PTLOCATION: mrPivotTable.importPTLocation( rStrm, getSheetIndex() ); break;
+ case BIFF12_ID_PTFIELDS: return this;
+ case BIFF12_ID_PTROWFIELDS: mrPivotTable.importPTRowFields( rStrm ); break;
+ case BIFF12_ID_PTCOLFIELDS: mrPivotTable.importPTColFields( rStrm ); break;
+ case BIFF12_ID_PTPAGEFIELDS: return this;
+ case BIFF12_ID_PTDATAFIELDS: return this;
+ case BIFF12_ID_PTFILTERS: return this;
+ }
+ break;
+
+ case BIFF12_ID_PTFIELDS:
+ if( nRecId == BIFF12_ID_PTFIELD ) return new PivotTableFieldContext( *this, mrPivotTable.createTableField() );
+ break;
+ case BIFF12_ID_PTPAGEFIELDS:
+ if( nRecId == BIFF12_ID_PTPAGEFIELD ) mrPivotTable.importPTPageField( rStrm );
+ break;
+ case BIFF12_ID_PTDATAFIELDS:
+ if( nRecId == BIFF12_ID_PTDATAFIELD ) mrPivotTable.importPTDataField( rStrm );
+ break;
+ case BIFF12_ID_PTFILTERS:
+ if( nRecId == BIFF12_ID_PTFILTER ) return new PivotTableFilterContext( *this, mrPivotTable.createTableFilter() );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* PivotTableFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_AUTOFILTER, BIFF12_ID_AUTOFILTER + 1 },
+ { BIFF12_ID_AUTOSORTSCOPE, BIFF12_ID_AUTOSORTSCOPE + 1 },
+ { BIFF12_ID_FILTERCOLUMN, BIFF12_ID_FILTERCOLUMN + 1 },
+ { BIFF12_ID_PIVOTAREA, BIFF12_ID_PIVOTAREA + 1 },
+ { BIFF12_ID_PTCOLFIELDS, BIFF12_ID_PTCOLFIELDS + 1 },
+ { BIFF12_ID_PTDATAFIELD, BIFF12_ID_PTDATAFIELD + 1 },
+ { BIFF12_ID_PTDATAFIELDS, BIFF12_ID_PTDATAFIELDS + 1 },
+ { BIFF12_ID_PTDEFINITION, BIFF12_ID_PTDEFINITION + 35 },
+ { BIFF12_ID_PTFIELD, BIFF12_ID_PTFIELD + 1 },
+ { BIFF12_ID_PTFIELDS, BIFF12_ID_PTFIELDS + 1 },
+ { BIFF12_ID_PTFILTER, BIFF12_ID_PTFILTER + 1 },
+ { BIFF12_ID_PTFILTERS, BIFF12_ID_PTFILTERS + 1 },
+ { BIFF12_ID_PTFITEM, BIFF12_ID_PTFITEM - 1 },
+ { BIFF12_ID_PTFITEMS, BIFF12_ID_PTFITEMS + 1 },
+ { BIFF12_ID_PTLOCATION, BIFF12_ID_PTLOCATION - 1 },
+ { BIFF12_ID_PTPAGEFIELD, BIFF12_ID_PTPAGEFIELD + 1 },
+ { BIFF12_ID_PTPAGEFIELDS, BIFF12_ID_PTPAGEFIELDS + 1 },
+ { BIFF12_ID_PTREFERENCE, BIFF12_ID_PTREFERENCE + 1 },
+ { BIFF12_ID_PTREFERENCEITEM, BIFF12_ID_PTREFERENCEITEM + 1 },
+ { BIFF12_ID_PTREFERENCES, BIFF12_ID_PTREFERENCES + 1 },
+ { BIFF12_ID_PTROWFIELDS, BIFF12_ID_PTROWFIELDS + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+// ============================================================================
+// ============================================================================
+
+BiffPivotTableContext::BiffPivotTableContext( const WorksheetHelper& rHelper ) :
+ BiffWorksheetContextBase( rHelper ),
+ mrPivotTable( getPivotTables().createPivotTable() )
+{
+}
+
+void BiffPivotTableContext::importRecord( BiffInputStream& rStrm )
+{
+ switch( rStrm.getRecId() )
+ {
+ case BIFF_ID_PTDEFINITION: mrPivotTable.importPTDefinition( rStrm, getSheetIndex() ); break;
+ case BIFF_ID_PTDEFINITION2: mrPivotTable.importPTDefinition2( rStrm ); break;
+ case BIFF_ID_PTFIELD: mrPivotTable.createTableField().importPTField( rStrm ); break;
+ case BIFF_ID_PTROWCOLFIELDS: mrPivotTable.importPTRowColFields( rStrm ); break;
+ case BIFF_ID_PTPAGEFIELDS: mrPivotTable.importPTPageFields( rStrm ); break;
+ case BIFF_ID_PTDATAFIELD: mrPivotTable.importPTDataField( rStrm ); break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/querytablebuffer.cxx b/oox/source/xls/querytablebuffer.cxx
new file mode 100644
index 000000000000..28ace4de52d8
--- /dev/null
+++ b/oox/source/xls/querytablebuffer.cxx
@@ -0,0 +1,390 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/querytablebuffer.hxx"
+
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/sheet/XAreaLink.hpp>
+#include <com/sun/star/sheet/XAreaLinks.hpp>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/connectionsbuffer.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 BIFF12_QUERYTABLE_HEADERS = 0x00000001;
+const sal_uInt32 BIFF12_QUERYTABLE_ROWNUMBERS = 0x00000002;
+const sal_uInt32 BIFF12_QUERYTABLE_DISABLEREFRESH = 0x00000004;
+const sal_uInt32 BIFF12_QUERYTABLE_BACKGROUND = 0x00000008;
+const sal_uInt32 BIFF12_QUERYTABLE_FIRSTBACKGROUND = 0x00000010;
+const sal_uInt32 BIFF12_QUERYTABLE_REFRESHONLOAD = 0x00000020;
+const sal_uInt32 BIFF12_QUERYTABLE_FILLFORMULAS = 0x00000100;
+const sal_uInt32 BIFF12_QUERYTABLE_SAVEDATA = 0x00000200;
+const sal_uInt32 BIFF12_QUERYTABLE_DISABLEEDIT = 0x00000400;
+const sal_uInt32 BIFF12_QUERYTABLE_PRESERVEFORMAT = 0x00000800;
+const sal_uInt32 BIFF12_QUERYTABLE_ADJUSTCOLWIDTH = 0x00001000;
+const sal_uInt32 BIFF12_QUERYTABLE_INTERMEDIATE = 0x00002000;
+const sal_uInt32 BIFF12_QUERYTABLE_APPLYNUMFMT = 0x00004000;
+const sal_uInt32 BIFF12_QUERYTABLE_APPLYFONT = 0x00008000;
+const sal_uInt32 BIFF12_QUERYTABLE_APPLYALIGNMENT = 0x00010000;
+const sal_uInt32 BIFF12_QUERYTABLE_APPLYBORDER = 0x00020000;
+const sal_uInt32 BIFF12_QUERYTABLE_APPLYFILL = 0x00040000;
+const sal_uInt32 BIFF12_QUERYTABLE_APPLYPROTECTION = 0x00080000;
+
+const sal_uInt16 BIFF_QUERYTABLE_HEADERS = 0x0001;
+const sal_uInt16 BIFF_QUERYTABLE_ROWNUMBERS = 0x0002;
+const sal_uInt16 BIFF_QUERYTABLE_DISABLEREFRESH = 0x0004;
+const sal_uInt16 BIFF_QUERYTABLE_BACKGROUND = 0x0008;
+const sal_uInt16 BIFF_QUERYTABLE_FIRSTBACKGROUND = 0x0010;
+const sal_uInt16 BIFF_QUERYTABLE_REFRESHONLOAD = 0x0020;
+const sal_uInt16 BIFF_QUERYTABLE_DELETEUNUSED = 0x0040;
+const sal_uInt16 BIFF_QUERYTABLE_FILLFORMULAS = 0x0080;
+const sal_uInt16 BIFF_QUERYTABLE_ADJUSTCOLWIDTH = 0x0100;
+const sal_uInt16 BIFF_QUERYTABLE_SAVEDATA = 0x0200;
+const sal_uInt16 BIFF_QUERYTABLE_DISABLEEDIT = 0x0400;
+const sal_uInt16 BIFF_QUERYTABLE_OVERWRITEEXISTING = 0x2000;
+
+const sal_uInt16 BIFF_QUERYTABLE_APPLYNUMFMT = 0x0001;
+const sal_uInt16 BIFF_QUERYTABLE_APPLYFONT = 0x0002;
+const sal_uInt16 BIFF_QUERYTABLE_APPLYALIGNMENT = 0x0004;
+const sal_uInt16 BIFF_QUERYTABLE_APPLYBORDER = 0x0008;
+const sal_uInt16 BIFF_QUERYTABLE_APPLYFILL = 0x0010;
+const sal_uInt16 BIFF_QUERYTABLE_APPLYPROTECTION = 0x0020;
+
+const sal_uInt32 BIFF_QTREFRESH_PRESERVEFORMAT = 0x00000001;
+const sal_uInt32 BIFF_QTREFRESH_ADJUSTCOLWIDTH = 0x00000002;
+
+// ----------------------------------------------------------------------------
+
+void lclAppendWebQueryTableName( OUStringBuffer& rTables, const OUString& rTableName )
+{
+ if( rTableName.getLength() > 0 )
+ {
+ if( rTables.getLength() > 0 )
+ rTables.append( sal_Unicode( ';' ) );
+ rTables.appendAscii( RTL_CONSTASCII_STRINGPARAM( "HTML__" ) ).append( rTableName );
+ }
+}
+
+void lclAppendWebQueryTableIndex( OUStringBuffer& rTables, sal_Int32 nTableIndex )
+{
+ if( nTableIndex > 0 )
+ {
+ if( rTables.getLength() > 0 )
+ rTables.append( sal_Unicode( ';' ) );
+ rTables.appendAscii( RTL_CONSTASCII_STRINGPARAM( "HTML_" ) ).append( nTableIndex );
+ }
+}
+
+OUString lclBuildWebQueryTables( const WebPrModel::TablesVector& rTables )
+{
+ if( rTables.empty() )
+ return CREATE_OUSTRING( "HTML_tables" );
+
+ OUStringBuffer aTables;
+ for( WebPrModel::TablesVector::const_iterator aIt = rTables.begin(), aEnd = rTables.end(); aIt != aEnd; ++aIt )
+ {
+ if( aIt->has< OUString >() )
+ lclAppendWebQueryTableName( aTables, aIt->get< OUString >() );
+ else if( aIt->has< sal_Int32 >() )
+ lclAppendWebQueryTableIndex( aTables, aIt->get< sal_Int32 >() );
+ }
+ return aTables.makeStringAndClear();
+}
+
+Reference< XAreaLink > lclFindAreaLink(
+ const Reference< XAreaLinks >& rxAreaLinks, const CellAddress& rDestPos,
+ const OUString& rFileUrl, const OUString& rTables, const OUString& rFilterName, const OUString& rFilterOptions )
+{
+ try
+ {
+ Reference< XEnumerationAccess > xAreaLinksEA( rxAreaLinks, UNO_QUERY_THROW );
+ Reference< XEnumeration > xAreaLinksEnum( xAreaLinksEA->createEnumeration(), UNO_SET_THROW );
+ while( xAreaLinksEnum->hasMoreElements() )
+ {
+ Reference< XAreaLink > xAreaLink( xAreaLinksEnum->nextElement(), UNO_QUERY_THROW );
+ PropertySet aPropSet( xAreaLink );
+ CellRangeAddress aDestArea = xAreaLink->getDestArea();
+ OUString aString;
+ if( (rDestPos.Sheet == aDestArea.Sheet) && (rDestPos.Column == aDestArea.StartColumn) && (rDestPos.Row == aDestArea.StartRow) &&
+ (rTables == xAreaLink->getSourceArea()) &&
+ aPropSet.getProperty( aString, PROP_Url ) && (rFileUrl == aString) &&
+ aPropSet.getProperty( aString, PROP_Filter ) && (rFilterName == aString) &&
+ aPropSet.getProperty( aString, PROP_FilterOptions ) && (rFilterOptions == aString) )
+ return xAreaLink;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ return Reference< XAreaLink >();
+}
+
+} // namespace
+
+// ============================================================================
+
+QueryTableModel::QueryTableModel() :
+ mnConnId( -1 ),
+ mnGrowShrinkType( XML_insertDelete ),
+ mbHeaders( true ),
+ mbRowNumbers( false ),
+ mbDisableRefresh( false ),
+ mbBackground( true ),
+ mbFirstBackground( false ),
+ mbRefreshOnLoad( false ),
+ mbFillFormulas( false ),
+ mbRemoveDataOnSave( false ),
+ mbDisableEdit( false ),
+ mbPreserveFormat( true ),
+ mbAdjustColWidth( true ),
+ mbIntermediate( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+QueryTable::QueryTable( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void QueryTable::importQueryTable( const AttributeList& rAttribs )
+{
+ maModel.maDefName = rAttribs.getXString( XML_name, OUString() );
+ maModel.mnConnId = rAttribs.getInteger( XML_connectionId, -1 );
+ maModel.mnGrowShrinkType = rAttribs.getToken( XML_growShrinkType, XML_insertDelete );
+ maModel.mnAutoFormatId = rAttribs.getInteger( XML_autoFormatId, 0 );
+ maModel.mbHeaders = rAttribs.getBool( XML_headers, true );
+ maModel.mbRowNumbers = rAttribs.getBool( XML_rowNumbers, false );
+ maModel.mbDisableRefresh = rAttribs.getBool( XML_disableRefresh, false );
+ maModel.mbBackground = rAttribs.getBool( XML_backgroundRefresh, true );
+ maModel.mbFirstBackground = rAttribs.getBool( XML_firstBackgroundRefresh, false );
+ maModel.mbRefreshOnLoad = rAttribs.getBool( XML_refreshOnLoad, false );
+ maModel.mbFillFormulas = rAttribs.getBool( XML_fillFormulas, false );
+ maModel.mbRemoveDataOnSave = rAttribs.getBool( XML_removeDataOnSave, false );
+ maModel.mbDisableEdit = rAttribs.getBool( XML_disableEdit, false );
+ maModel.mbPreserveFormat = rAttribs.getBool( XML_preserveFormatting, true );
+ maModel.mbAdjustColWidth = rAttribs.getBool( XML_adjustColumnWidth, true );
+ maModel.mbIntermediate = rAttribs.getBool( XML_intermediate, false );
+ maModel.mbApplyNumFmt = rAttribs.getBool( XML_applyNumberFormats, false );
+ maModel.mbApplyFont = rAttribs.getBool( XML_applyFontFormats, false );
+ maModel.mbApplyAlignment = rAttribs.getBool( XML_applyAlignmentFormats, false );
+ maModel.mbApplyBorder = rAttribs.getBool( XML_applyBorderFormats, false );
+ maModel.mbApplyFill = rAttribs.getBool( XML_applyPatternFormats, false );
+ // OOXML and BIFF12 documentation differ: OOXML mentions width/height, BIFF12 mentions protection
+ maModel.mbApplyProtection = rAttribs.getBool( XML_applyWidthHeightFormats, false );
+}
+
+void QueryTable::importQueryTable( SequenceInputStream& rStrm )
+{
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+ maModel.mnAutoFormatId = rStrm.readuInt16();
+ rStrm >> maModel.mnConnId >> maModel.maDefName;
+
+ static const sal_Int32 spnGrowShrinkTypes[] = { XML_insertClear, XML_insertDelete, XML_overwriteClear };
+ maModel.mnGrowShrinkType = STATIC_ARRAY_SELECT( spnGrowShrinkTypes, extractValue< sal_uInt8 >( nFlags, 6, 2 ), XML_insertDelete );
+
+ maModel.mbHeaders = getFlag( nFlags, BIFF12_QUERYTABLE_HEADERS );
+ maModel.mbRowNumbers = getFlag( nFlags, BIFF12_QUERYTABLE_ROWNUMBERS );
+ maModel.mbDisableRefresh = getFlag( nFlags, BIFF12_QUERYTABLE_DISABLEREFRESH );
+ maModel.mbBackground = getFlag( nFlags, BIFF12_QUERYTABLE_BACKGROUND );
+ maModel.mbFirstBackground = getFlag( nFlags, BIFF12_QUERYTABLE_FIRSTBACKGROUND );
+ maModel.mbRefreshOnLoad = getFlag( nFlags, BIFF12_QUERYTABLE_REFRESHONLOAD );
+ maModel.mbFillFormulas = getFlag( nFlags, BIFF12_QUERYTABLE_FILLFORMULAS );
+ maModel.mbRemoveDataOnSave = !getFlag( nFlags, BIFF12_QUERYTABLE_SAVEDATA ); // flag negated in BIFF12
+ maModel.mbDisableEdit = getFlag( nFlags, BIFF12_QUERYTABLE_DISABLEEDIT );
+ maModel.mbPreserveFormat = getFlag( nFlags, BIFF12_QUERYTABLE_PRESERVEFORMAT );
+ maModel.mbAdjustColWidth = getFlag( nFlags, BIFF12_QUERYTABLE_ADJUSTCOLWIDTH );
+ maModel.mbIntermediate = getFlag( nFlags, BIFF12_QUERYTABLE_INTERMEDIATE );
+ maModel.mbApplyNumFmt = getFlag( nFlags, BIFF12_QUERYTABLE_APPLYNUMFMT );
+ maModel.mbApplyFont = getFlag( nFlags, BIFF12_QUERYTABLE_APPLYFONT );
+ maModel.mbApplyAlignment = getFlag( nFlags, BIFF12_QUERYTABLE_APPLYALIGNMENT );
+ maModel.mbApplyBorder = getFlag( nFlags, BIFF12_QUERYTABLE_APPLYBORDER );
+ maModel.mbApplyFill = getFlag( nFlags, BIFF12_QUERYTABLE_APPLYFILL );
+ maModel.mbApplyProtection = getFlag( nFlags, BIFF12_QUERYTABLE_APPLYPROTECTION );
+}
+
+void QueryTable::importQueryTable( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags, nAutoFormatFlags;
+ rStrm >> nFlags;
+ maModel.mnAutoFormatId = rStrm.readuInt16();
+ rStrm >> nAutoFormatFlags;
+ rStrm.skip( 4 );
+ maModel.maDefName = rStrm.readUniString();
+
+ bool bDeleteUnused = getFlag( nFlags, BIFF_QUERYTABLE_DELETEUNUSED );
+ bool bOverwriteExisting = getFlag( nFlags, BIFF_QUERYTABLE_OVERWRITEEXISTING );
+ OSL_ENSURE( !bDeleteUnused || !bOverwriteExisting, "QueryTable::importQueryTable - invalid flags" );
+ maModel.mnGrowShrinkType = bDeleteUnused ? XML_insertDelete : (bOverwriteExisting ? XML_overwriteClear : XML_insertClear);
+
+ maModel.mbHeaders = getFlag( nFlags, BIFF_QUERYTABLE_HEADERS );
+ maModel.mbRowNumbers = getFlag( nFlags, BIFF_QUERYTABLE_ROWNUMBERS );
+ maModel.mbDisableRefresh = getFlag( nFlags, BIFF_QUERYTABLE_DISABLEREFRESH );
+ maModel.mbBackground = getFlag( nFlags, BIFF_QUERYTABLE_BACKGROUND );
+ maModel.mbFirstBackground = getFlag( nFlags, BIFF_QUERYTABLE_FIRSTBACKGROUND );
+ maModel.mbRefreshOnLoad = getFlag( nFlags, BIFF_QUERYTABLE_REFRESHONLOAD );
+ maModel.mbFillFormulas = getFlag( nFlags, BIFF_QUERYTABLE_FILLFORMULAS );
+ maModel.mbRemoveDataOnSave = !getFlag( nFlags, BIFF_QUERYTABLE_SAVEDATA ); // flag negated in BIFF
+ maModel.mbDisableEdit = getFlag( nFlags, BIFF_QUERYTABLE_DISABLEEDIT );
+ maModel.mbAdjustColWidth = getFlag( nFlags, BIFF_QUERYTABLE_ADJUSTCOLWIDTH );
+ maModel.mbApplyNumFmt = getFlag( nAutoFormatFlags, BIFF_QUERYTABLE_APPLYNUMFMT );
+ maModel.mbApplyFont = getFlag( nAutoFormatFlags, BIFF_QUERYTABLE_APPLYFONT );
+ maModel.mbApplyAlignment = getFlag( nAutoFormatFlags, BIFF_QUERYTABLE_APPLYALIGNMENT );
+ maModel.mbApplyBorder = getFlag( nAutoFormatFlags, BIFF_QUERYTABLE_APPLYBORDER );
+ maModel.mbApplyFill = getFlag( nAutoFormatFlags, BIFF_QUERYTABLE_APPLYFILL );
+ maModel.mbApplyProtection = getFlag( nAutoFormatFlags, BIFF_QUERYTABLE_APPLYPROTECTION );
+
+ // create a new connection object that will store settings from following records
+ OSL_ENSURE( maModel.mnConnId == -1, "QueryTable::importQueryTable - multiple call" );
+ Connection& rConnection = getConnections().createConnectionWithId();
+ maModel.mnConnId = rConnection.getConnectionId();
+
+ // a DBQUERY record with some PCITEM_STRING records must follow
+ bool bHasDbQuery = (rStrm.getNextRecId() == BIFF_ID_DBQUERY) && rStrm.startNextRecord();
+ OSL_ENSURE( bHasDbQuery, "QueryTable::importQueryTable - missing DBQUERY record" );
+ if( bHasDbQuery )
+ rConnection.importDbQuery( rStrm );
+}
+
+void QueryTable::importQueryTableRefresh( BiffInputStream& rStrm )
+{
+ rStrm.skip( 4 );
+ bool bPivot = rStrm.readuInt16() != 0;
+ OSL_ENSURE( !bPivot, "QueryTable::importQueryTableRefresh - unexpected pivot flag" );
+ if( !bPivot )
+ {
+ rStrm.skip( 2 );
+ sal_uInt32 nFlags = rStrm.readuInt32();
+ maModel.mbPreserveFormat = getFlag( nFlags, BIFF_QTREFRESH_PRESERVEFORMAT );
+ maModel.mbAdjustColWidth = getFlag( nFlags, BIFF_QTREFRESH_ADJUSTCOLWIDTH );
+ }
+}
+
+void QueryTable::importQueryTableSettings( BiffInputStream& rStrm )
+{
+ ConnectionRef xConnection = getConnections().getConnection( maModel.mnConnId );
+ OSL_ENSURE( xConnection.get(), "QueryTable::importQueryTableSettings - missing connection object" );
+ if( xConnection.get() )
+ xConnection->importQueryTableSettings( rStrm );
+}
+
+void QueryTable::finalizeImport()
+{
+ ConnectionRef xConnection = getConnections().getConnection( maModel.mnConnId );
+ OSL_ENSURE( xConnection.get(), "QueryTable::finalizeImport - missing connection object" );
+ if( xConnection.get() && (xConnection->getConnectionType() == BIFF12_CONNECTION_HTML) )
+ {
+ // check that valid web query properties exist
+ const WebPrModel* pWebPr = xConnection->getModel().mxWebPr.get();
+ if( pWebPr && !pWebPr->mbXml )
+ {
+ OUString aFileUrl = getBaseFilter().getAbsoluteUrl( pWebPr->maUrl );
+ if( aFileUrl.getLength() > 0 )
+ {
+ // resolve destination cell range (stored as defined name containing the range)
+ OUString aDefName = maModel.maDefName.replace( ' ', '_' ).replace( '-', '_' );
+ DefinedNameRef xDefName = getDefinedNames().getByModelName( aDefName, getSheetIndex() );
+ OSL_ENSURE( xDefName.get(), "QueryTable::finalizeImport - missing defined name" );
+ if( xDefName.get() )
+ {
+ CellRangeAddress aDestRange;
+ bool bIsRange = xDefName->getAbsoluteRange( aDestRange ) && (aDestRange.Sheet == getSheetIndex());
+ OSL_ENSURE( bIsRange, "QueryTable::finalizeImport - defined name does not contain valid cell range" );
+ if( bIsRange && getAddressConverter().checkCellRange( aDestRange, false, true ) )
+ {
+ CellAddress aDestPos( aDestRange.Sheet, aDestRange.StartColumn, aDestRange.StartRow );
+ // find tables mode: entire document, all tables, or specific tables
+ OUString aTables = pWebPr->mbHtmlTables ? lclBuildWebQueryTables( pWebPr->maTables ) : CREATE_OUSTRING( "HTML_all" );
+ if( aTables.getLength() > 0 ) try
+ {
+ PropertySet aDocProps( getDocument() );
+ Reference< XAreaLinks > xAreaLinks( aDocProps.getAnyProperty( PROP_AreaLinks ), UNO_QUERY_THROW );
+ OUString aFilterName = CREATE_OUSTRING( "calc_HTML_WebQuery" );
+ OUString aFilterOptions;
+ xAreaLinks->insertAtPosition( aDestPos, aFileUrl, aTables, aFilterName, aFilterOptions );
+ // set refresh interval (convert minutes to seconds)
+ sal_Int32 nRefreshPeriod = xConnection->getModel().mnInterval * 60;
+ if( nRefreshPeriod > 0 )
+ {
+ PropertySet aPropSet( lclFindAreaLink( xAreaLinks, aDestPos, aFileUrl, aTables, aFilterName, aFilterOptions ) );
+ aPropSet.setProperty( PROP_RefreshPeriod, nRefreshPeriod );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+QueryTableBuffer::QueryTableBuffer( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+QueryTable& QueryTableBuffer::createQueryTable()
+{
+ QueryTableVector::value_type xQueryTable( new QueryTable( *this ) );
+ maQueryTables.push_back( xQueryTable );
+ return *xQueryTable;
+}
+
+void QueryTableBuffer::finalizeImport()
+{
+ maQueryTables.forEachMem( &QueryTable::finalizeImport );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/querytablefragment.cxx b/oox/source/xls/querytablefragment.cxx
new file mode 100644
index 000000000000..c74aa53a581e
--- /dev/null
+++ b/oox/source/xls/querytablefragment.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/querytablefragment.hxx"
+
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/querytablebuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+QueryTableFragment::QueryTableFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath ),
+ mrQueryTable( getQueryTables().createQueryTable() )
+{
+}
+
+ContextHandlerRef QueryTableFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( queryTable ) )
+ mrQueryTable.importQueryTable( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef QueryTableFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_QUERYTABLE )
+ mrQueryTable.importQueryTable( rStrm );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* QueryTableFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_QUERYTABLE, BIFF12_ID_QUERYTABLE + 1 },
+ { BIFF12_ID_QUERYTABLEREFRESH, BIFF12_ID_QUERYTABLEREFRESH + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+// ============================================================================
+
+BiffQueryTableContext::BiffQueryTableContext( const WorksheetHelper& rHelper ) :
+ BiffWorksheetContextBase( rHelper ),
+ mrQueryTable( getQueryTables().createQueryTable() )
+{
+}
+
+void BiffQueryTableContext::importRecord( BiffInputStream& rStrm )
+{
+ switch( rStrm.getRecId() )
+ {
+ case BIFF_ID_QUERYTABLE: mrQueryTable.importQueryTable( rStrm ); break;
+ case BIFF_ID_QUERYTABLEREFRESH: mrQueryTable.importQueryTableRefresh( rStrm ); break;
+ case BIFF_ID_QUERYTABLESETTINGS: mrQueryTable.importQueryTableSettings( rStrm ); break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/richstring.cxx b/oox/source/xls/richstring.cxx
new file mode 100644
index 000000000000..5c79373b09b2
--- /dev/null
+++ b/oox/source/xls/richstring.cxx
@@ -0,0 +1,614 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/richstring.hxx"
+
+#include <com/sun/star/text/XText.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt8 BIFF12_STRINGFLAG_FONTS = 0x01;
+const sal_uInt8 BIFF12_STRINGFLAG_PHONETICS = 0x02;
+
+} // namespace
+
+// ============================================================================
+
+RichStringPortion::RichStringPortion( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mnFontId( -1 )
+{
+}
+
+void RichStringPortion::setText( const OUString& rText )
+{
+ maText = rText;
+}
+
+FontRef RichStringPortion::createFont()
+{
+ 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_TEXT );
+ }
+ if( const Font* pFont = getStyles().getFontFromCellXf( nXfId ).get() )
+ {
+ if( pFont->needsRichTextFormat() )
+ {
+ PropertySet aPropSet( xRange );
+ pFont->writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT );
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void FontPortionModel::read( SequenceInputStream& rStrm )
+{
+ mnPos = rStrm.readuInt16();
+ mnFontId = rStrm.readuInt16();
+}
+
+void FontPortionModel::read( BiffInputStream& rStrm, BiffFontPortionMode eMode )
+{
+ switch( eMode )
+ {
+ case BIFF_FONTPORTION_8BIT:
+ mnPos = rStrm.readuInt8();
+ mnFontId = rStrm.readuInt8();
+ break;
+ case BIFF_FONTPORTION_16BIT:
+ mnPos = rStrm.readuInt16();
+ mnFontId = rStrm.readuInt16();
+ break;
+ case BIFF_FONTPORTION_OBJ:
+ mnPos = rStrm.readuInt16();
+ mnFontId = rStrm.readuInt16();
+ rStrm.skip( 4 );
+ break;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void FontPortionModelList::appendPortion( const FontPortionModel& rPortion )
+{
+ // #i33341# real life -- same character index may occur several times
+ OSL_ENSURE( empty() || (back().mnPos <= rPortion.mnPos), "FontPortionModelList::appendPortion - wrong char order" );
+ if( empty() || (back().mnPos < rPortion.mnPos) )
+ push_back( rPortion );
+ else
+ back().mnFontId = rPortion.mnFontId;
+}
+
+void FontPortionModelList::importPortions( SequenceInputStream& rStrm )
+{
+ sal_Int32 nCount = rStrm.readInt32();
+ clear();
+ if( nCount > 0 )
+ {
+ reserve( getLimitedValue< size_t, sal_Int64 >( nCount, 0, rStrm.getRemaining() / 4 ) );
+ /* #i33341# real life -- same character index may occur several times
+ -> use appendPortion() to validate string position. */
+ FontPortionModel aPortion;
+ for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ {
+ aPortion.read( rStrm );
+ appendPortion( aPortion );
+ }
+ }
+}
+
+void FontPortionModelList::importPortions( BiffInputStream& rStrm, sal_uInt16 nCount, BiffFontPortionMode eMode )
+{
+ clear();
+ reserve( nCount );
+ /* #i33341# real life -- same character index may occur several times
+ -> use appendPortion() to validate string position. */
+ FontPortionModel aPortion;
+ for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ {
+ aPortion.read( rStrm, eMode );
+ appendPortion( aPortion );
+ }
+}
+
+void FontPortionModelList::importPortions( BiffInputStream& rStrm, bool b16Bit )
+{
+ sal_uInt16 nCount = b16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
+ importPortions( rStrm, nCount, b16Bit ? BIFF_FONTPORTION_16BIT : BIFF_FONTPORTION_8BIT );
+}
+
+// ============================================================================
+
+PhoneticDataModel::PhoneticDataModel() :
+ mnFontId( -1 ),
+ mnType( XML_fullwidthKatakana ),
+ mnAlignment( XML_left )
+{
+}
+
+void PhoneticDataModel::setBiffData( 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 )
+{
+ maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 );
+ maModel.mnType = rAttribs.getToken( XML_type, XML_fullwidthKatakana );
+ maModel.mnAlignment = rAttribs.getToken( XML_alignment, XML_left );
+}
+
+void PhoneticSettings::importPhoneticPr( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFontId;
+ sal_Int32 nType, nAlignment;
+ rStrm >> nFontId >> nType >> nAlignment;
+ maModel.mnFontId = nFontId;
+ maModel.setBiffData( nType, nAlignment );
+}
+
+void PhoneticSettings::importPhoneticPr( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFontId, nFlags;
+ rStrm >> nFontId >> nFlags;
+ maModel.mnFontId = nFontId;
+ maModel.setBiffData( extractValue< sal_Int32 >( nFlags, 0, 2 ), extractValue< sal_Int32 >( nFlags, 2, 2 ) );
+ // following: range list with cells showing phonetic text
+}
+
+void PhoneticSettings::importStringData( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFontId, nFlags;
+ rStrm >> nFontId >> nFlags;
+ maModel.mnFontId = nFontId;
+ maModel.setBiffData( extractValue< sal_Int32 >( nFlags, 0, 2 ), extractValue< sal_Int32 >( nFlags, 2, 2 ) );
+}
+
+void PhoneticSettings::importStringData( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFontId, nFlags;
+ rStrm >> nFontId >> nFlags;
+ maModel.mnFontId = nFontId;
+ maModel.setBiffData( 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 PhoneticPortionModel::read( SequenceInputStream& rStrm )
+{
+ mnPos = rStrm.readuInt16();
+ mnBasePos = rStrm.readuInt16();
+ mnBaseLen = rStrm.readuInt16();
+}
+
+void PhoneticPortionModel::read( BiffInputStream& rStrm )
+{
+ mnPos = rStrm.readuInt16();
+ mnBasePos = rStrm.readuInt16();
+ mnBaseLen = rStrm.readuInt16();
+}
+
+// ----------------------------------------------------------------------------
+
+void PhoneticPortionModelList::appendPortion( const PhoneticPortionModel& rPortion )
+{
+ // same character index may occur several times
+ OSL_ENSURE( empty() || ((back().mnPos <= rPortion.mnPos) &&
+ (back().mnBasePos + back().mnBaseLen <= rPortion.mnBasePos)),
+ "PhoneticPortionModelList::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 PhoneticPortionModelList::importPortions( SequenceInputStream& rStrm )
+{
+ sal_Int32 nCount = rStrm.readInt32();
+ clear();
+ if( nCount > 0 )
+ {
+ reserve( getLimitedValue< size_t, sal_Int64 >( nCount, 0, rStrm.getRemaining() / 6 ) );
+ PhoneticPortionModel aPortion;
+ for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ {
+ aPortion.read( rStrm );
+ appendPortion( aPortion );
+ }
+ }
+}
+
+OUString PhoneticPortionModelList::importPortions( BiffInputStream& rStrm, sal_Int32 nPhoneticSize )
+{
+ OUString aPhoneticText;
+ sal_uInt16 nPortionCount, nTextLen1, nTextLen2;
+ rStrm >> nPortionCount >> nTextLen1 >> nTextLen2;
+ OSL_ENSURE( nTextLen1 == nTextLen2, "PhoneticPortionModelList::importPortions - wrong phonetic text length" );
+ if( (nTextLen1 == nTextLen2) && (nTextLen1 > 0) )
+ {
+ sal_Int32 nMinSize = 2 * nTextLen1 + 6 * nPortionCount + 14;
+ OSL_ENSURE( nMinSize <= nPhoneticSize, "PhoneticPortionModelList::importPortions - wrong size of phonetic data" );
+ if( nMinSize <= nPhoneticSize )
+ {
+ aPhoneticText = rStrm.readUnicodeArray( nTextLen1 );
+ clear();
+ reserve( nPortionCount );
+ PhoneticPortionModel 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( SequenceInputStream& rStrm, bool bRich )
+{
+ sal_uInt8 nFlags = bRich ? rStrm.readuInt8() : 0;
+ OUString aBaseText = BiffHelper::readString( rStrm );
+
+ if( !rStrm.isEof() && getFlag( nFlags, BIFF12_STRINGFLAG_FONTS ) )
+ {
+ FontPortionModelList aPortions;
+ aPortions.importPortions( rStrm );
+ createFontPortions( aBaseText, aPortions );
+ }
+ else
+ {
+ createPortion()->setText( aBaseText );
+ }
+
+ if( !rStrm.isEof() && getFlag( nFlags, BIFF12_STRINGFLAG_PHONETICS ) )
+ {
+ OUString aPhoneticText = BiffHelper::readString( rStrm );
+ PhoneticPortionModelList 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.isEof() && getFlag( nFlags, BIFF_STR_EXTRAFONTS ) )
+ {
+ FontPortionModelList 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 = getFlag( nFlagField, BIFF_STRF_16BIT );
+ bool bFonts = getFlag( nFlagField, BIFF_STRF_RICH );
+ bool bPhonetic = getFlag( nFlagField, BIFF_STRF_PHONETIC );
+ sal_uInt16 nFontCount = bFonts ? rStrm.readuInt16() : 0;
+ sal_Int32 nPhoneticSize = bPhonetic ? rStrm.readInt32() : 0;
+
+ // --- character array ---
+ OUString aBaseText = rStrm.readUniStringChars( nChars, b16Bit );
+
+ // --- formatting ---
+ // #122185# bRich flag may be set, but format runs may be missing
+ if( !rStrm.isEof() && (nFontCount > 0) )
+ {
+ FontPortionModelList aPortions;
+ aPortions.importPortions( rStrm, nFontCount, BIFF_FONTPORTION_16BIT );
+ createFontPortions( aBaseText, aPortions );
+ }
+ else
+ {
+ createPortion()->setText( aBaseText );
+ }
+
+ // --- Asian phonetic information ---
+ // #122185# bPhonetic flag may be set, but phonetic info may be missing
+ if( !rStrm.isEof() && (nPhoneticSize > 0) )
+ {
+ sal_Int64 nPhoneticEnd = rStrm.tell() + 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_Int32 nMinSize = nSize + 4;
+ OSL_ENSURE( nMinSize <= nPhoneticSize, "RichString::importUniString - wrong size of phonetic data" );
+ if( (nId == 1) && (nMinSize <= nPhoneticSize) )
+ {
+ maPhonSettings.importStringData( rStrm );
+ PhoneticPortionModelList aPortions;
+ OUString aPhoneticText = aPortions.importPortions( rStrm, nPhoneticSize );
+ createPhoneticPortions( aPhoneticText, aPortions, aBaseText.getLength() );
+ }
+ }
+ rStrm.seek( nPhoneticEnd );
+ }
+}
+
+void RichString::finalizeImport()
+{
+ maFontPortions.forEachMem( &RichStringPortion::finalizeImport );
+}
+
+OUString RichString::getPlainText() const
+{
+ OUStringBuffer aBuffer;
+ for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt )
+ aBuffer.append( (*aIt)->getText() );
+ return aBuffer.makeStringAndClear();
+}
+
+void RichString::convert( const Reference< XText >& rxText, sal_Int32 nXfId ) const
+{
+ for( PortionVec::const_iterator aIt = maFontPortions.begin(), aEnd = maFontPortions.end(); aIt != aEnd; ++aIt )
+ {
+ (*aIt)->convert( rxText, nXfId );
+ nXfId = -1; // use passed XF identifier for first portion only
+ }
+}
+
+// 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, FontPortionModelList& 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(), FontPortionModel( 0, -1 ) );
+ if( rPortions.back().mnPos < nStrLen )
+ rPortions.push_back( FontPortionModel( nStrLen, -1 ) );
+
+ // create all string portions according to the font id vector
+ for( FontPortionModelList::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, FontPortionModelList& 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(), FontPortionModel( 0, -1 ) );
+ if( rPortions.back().mnPos < nStrLen )
+ rPortions.push_back( FontPortionModel( nStrLen, -1 ) );
+
+ // create all string portions according to the font id vector
+ for( FontPortionModelList::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, PhoneticPortionModelList& 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( PhoneticPortionModel( 0, 0, nBaseLen ) );
+ // add trailing string position to ease the following loop
+ if( rPortions.back().mnPos < nStrLen )
+ rPortions.push_back( PhoneticPortionModel( nStrLen, nBaseLen, 0 ) );
+
+ // create all phonetic portions according to the portions vector
+ for( PhoneticPortionModelList::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..a3cfbe054406
--- /dev/null
+++ b/oox/source/xls/richstringcontext.cxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/richstringcontext.hxx"
+
+#include "oox/xls/stylesfragment.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+ContextHandlerRef RichStringContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() )
+ {
+ switch( nElement )
+ {
+ case XLS_TOKEN( t ):
+ mxPortion = mxString->importText( rAttribs );
+ return this; // collect text in onCharacters()
+ case XLS_TOKEN( r ):
+ mxPortion = mxString->importRun( rAttribs );
+ return this;
+ case XLS_TOKEN( rPh ):
+ mxPhonetic = mxString->importPhoneticRun( rAttribs );
+ return this;
+ case XLS_TOKEN( phoneticPr ):
+ mxString->importPhoneticPr( rAttribs );
+ break;
+ }
+ }
+ else switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( r ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( rPr ):
+ if( mxPortion.get() )
+ return new FontContext( *this, mxPortion->createFont() );
+ break;
+
+ case XLS_TOKEN( t ):
+ return this; // collect portion text in onCharacters()
+ }
+ break;
+
+ case XLS_TOKEN( rPh ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( t ):
+ return this; // collect phonetic text in onCharacters()
+ }
+ break;
+ }
+ return 0;
+}
+
+void RichStringContext::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( XLS_TOKEN( t ) ) ) switch( getParentElement() )
+ {
+ case XLS_TOKEN( rPh ):
+ if( mxPhonetic.get() )
+ mxPhonetic->setText( rChars );
+ break;
+ default:
+ if( mxPortion.get() )
+ mxPortion->setText( rChars );
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/scenariobuffer.cxx b/oox/source/xls/scenariobuffer.cxx
new file mode 100644
index 000000000000..8915f1ae0c7b
--- /dev/null
+++ b/oox/source/xls/scenariobuffer.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/scenariobuffer.hxx"
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XScenario.hpp>
+#include <com/sun/star/sheet/XScenarios.hpp>
+#include <com/sun/star/sheet/XScenariosSupplier.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_Int32 BIFF_SCENARIO_DELETED = 0x4000;
+
+} // namespace
+
+// ============================================================================
+
+ScenarioCellModel::ScenarioCellModel() :
+ mnNumFmtId( 0 ),
+ mbDeleted( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScenarioModel::ScenarioModel() :
+ mbLocked( false ),
+ mbHidden( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+Scenario::Scenario( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
+ WorkbookHelper( rHelper ),
+ mnSheet( nSheet )
+{
+}
+
+void Scenario::importScenario( const AttributeList& rAttribs )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ maModel.maComment = rAttribs.getXString( XML_comment, OUString() );
+ maModel.maUser = rAttribs.getXString( XML_user, OUString() );
+ maModel.mbLocked = rAttribs.getBool( XML_locked, false );
+ maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
+}
+
+void Scenario::importInputCells( const AttributeList& rAttribs )
+{
+ ScenarioCellModel aModel;
+ getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, rAttribs.getString( XML_r, OUString() ), mnSheet );
+ aModel.maValue = rAttribs.getXString( XML_val, OUString() );
+ aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
+ aModel.mbDeleted = rAttribs.getBool( XML_deleted, false );
+ maCells.push_back( aModel );
+}
+
+void Scenario::importScenario( SequenceInputStream& rStrm )
+{
+ rStrm.skip( 2 ); // cell count
+ // two longs instead of flag field
+ maModel.mbLocked = rStrm.readInt32() != 0;
+ maModel.mbHidden = rStrm.readInt32() != 0;
+ rStrm >> maModel.maName >> maModel.maComment >> maModel.maUser;
+}
+
+void Scenario::importInputCells( SequenceInputStream& rStrm )
+{
+ // TODO: where is the deleted flag?
+ ScenarioCellModel aModel;
+ BinAddress aPos;
+ rStrm >> aPos;
+ rStrm.skip( 8 );
+ aModel.mnNumFmtId = rStrm.readuInt16();
+ rStrm >> aModel.maValue;
+ getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, aPos, mnSheet );
+ maCells.push_back( aModel );
+}
+
+void Scenario::importScenario( BiffInputStream& rStrm )
+{
+ sal_uInt16 nCellCount;
+ sal_uInt8 nNameLen, nCommentLen, nUserLen;
+ rStrm >> nCellCount;
+ // two bytes instead of flag field
+ maModel.mbLocked = rStrm.readuInt8() != 0;
+ maModel.mbHidden = rStrm.readuInt8() != 0;
+ rStrm >> nNameLen >> nCommentLen >> nUserLen;
+ maModel.maName = rStrm.readUniStringBody( nNameLen );
+ // user name: before comment (in difference to leading length field), repeated length
+ if( nUserLen > 0 )
+ maModel.maUser = rStrm.readUniString();
+ // comment: repeated length
+ if( nCommentLen > 0 )
+ maModel.maComment = rStrm.readUniString();
+
+ // list of cell addresses
+ for( sal_uInt16 nCell = 0; !rStrm.isEof() && (nCell < nCellCount); ++nCell )
+ {
+ ScenarioCellModel aModel;
+ BinAddress aPos;
+ rStrm >> aPos;
+ // deleted flag is encoded in column index
+ aModel.mbDeleted = getFlag( aPos.mnCol, BIFF_SCENARIO_DELETED );
+ setFlag( aPos.mnCol, BIFF_SCENARIO_DELETED, false );
+ getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, aPos, mnSheet );
+ maCells.push_back( aModel );
+ }
+
+ // list of cell values
+ for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); !rStrm.isEof() && (aIt != aEnd); ++aIt )
+ aIt->maValue = rStrm.readUniString();
+}
+
+void Scenario::finalizeImport()
+{
+ AddressConverter& rAddrConv = getAddressConverter();
+ ::std::vector< CellRangeAddress > aRanges;
+ for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
+ if( !aIt->mbDeleted && rAddrConv.checkCellAddress( aIt->maPos, true ) )
+ aRanges.push_back( CellRangeAddress( aIt->maPos.Sheet, aIt->maPos.Column, aIt->maPos.Row, aIt->maPos.Column, aIt->maPos.Row ) );
+
+ if( !aRanges.empty() && (maModel.maName.getLength() > 0) ) try
+ {
+ /* Find an unused name for the scenario (Calc stores scenario data in
+ hidden sheets named after the scenario following the base sheet). */
+ Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
+ OUString aScenName = ContainerHelper::getUnusedName( xSheetsNA, maModel.maName, '_' );
+
+ // create the new scenario sheet
+ Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
+ Reference< XScenarios > xScenarios( xScenariosSupp->getScenarios(), UNO_SET_THROW );
+ xScenarios->addNewByName( aScenName, ContainerHelper::vectorToSequence( aRanges ), maModel.maComment );
+
+ // write scenario cell values
+ Reference< XSpreadsheet > xSheet( getSheetFromDoc( aScenName ), UNO_SET_THROW );
+ for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
+ {
+ if( !aIt->mbDeleted ) try
+ {
+ // use XCell::setFormula to auto-detect values and strings
+ Reference< XCell > xCell( xSheet->getCellByPosition( aIt->maPos.Column, aIt->maPos.Row ), UNO_SET_THROW );
+ xCell->setFormula( aIt->maValue );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ // scenario properties
+ PropertySet aPropSet( xScenarios->getByName( aScenName ) );
+ aPropSet.setProperty( PROP_IsActive, false );
+ aPropSet.setProperty( PROP_CopyBack, false );
+ aPropSet.setProperty( PROP_CopyStyles, false );
+ aPropSet.setProperty( PROP_CopyFormulas, false );
+ aPropSet.setProperty( PROP_Protected, maModel.mbLocked );
+ // #112621# do not show/print scenario border
+ aPropSet.setProperty( PROP_ShowBorder, false );
+ aPropSet.setProperty( PROP_PrintBorder, false );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+SheetScenariosModel::SheetScenariosModel() :
+ mnCurrent( 0 ),
+ mnShown( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+SheetScenarios::SheetScenarios( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
+ WorkbookHelper( rHelper ),
+ mnSheet( nSheet )
+{
+}
+
+void SheetScenarios::importScenarios( const AttributeList& rAttribs )
+{
+ maModel.mnCurrent = rAttribs.getInteger( XML_current, 0 );
+ maModel.mnShown = rAttribs.getInteger( XML_show, 0 );
+}
+
+void SheetScenarios::importScenarios( SequenceInputStream& rStrm )
+{
+ maModel.mnCurrent = rStrm.readuInt16();
+ maModel.mnShown = rStrm.readuInt16();
+}
+
+void SheetScenarios::importScenarios( BiffInputStream& rStrm )
+{
+ rStrm.skip( 2 ); // scenario count
+ maModel.mnCurrent = rStrm.readuInt16();
+ maModel.mnShown = rStrm.readuInt16();
+
+ // read following SCENARIO records
+ while( (rStrm.getNextRecId() == BIFF_ID_SCENARIO) && rStrm.startNextRecord() )
+ createScenario().importScenario( rStrm );
+}
+
+Scenario& SheetScenarios::createScenario()
+{
+ ScenarioVector::value_type xScenario( new Scenario( *this, mnSheet ) );
+ maScenarios.push_back( xScenario );
+ return *xScenario;
+}
+
+void SheetScenarios::finalizeImport()
+{
+ maScenarios.forEachMem( &Scenario::finalizeImport );
+
+ // activate a scenario
+ try
+ {
+ Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xScenariosIA( xScenariosSupp->getScenarios(), UNO_QUERY_THROW );
+ Reference< XScenario > xScenario( xScenariosIA->getByIndex( maModel.mnShown ), UNO_QUERY_THROW );
+ xScenario->apply();
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+ScenarioBuffer::ScenarioBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+SheetScenarios& ScenarioBuffer::createSheetScenarios( sal_Int16 nSheet )
+{
+ SheetScenariosMap::mapped_type& rxSheetScens = maSheetScenarios[ nSheet ];
+ if( !rxSheetScens )
+ rxSheetScens.reset( new SheetScenarios( *this, nSheet ) );
+ return *rxSheetScens;
+}
+
+void ScenarioBuffer::finalizeImport()
+{
+ maSheetScenarios.forEachMem( &SheetScenarios::finalizeImport );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/scenariocontext.cxx b/oox/source/xls/scenariocontext.cxx
new file mode 100644
index 000000000000..be44bc8545f2
--- /dev/null
+++ b/oox/source/xls/scenariocontext.cxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/scenariocontext.hxx"
+
+#include "oox/xls/scenariobuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using ::oox::core::ContextHandlerRef;
+
+// ============================================================================
+
+ScenarioContext::ScenarioContext( WorksheetContextBase& rParent, SheetScenarios& rSheetScenarios ) :
+ WorksheetContextBase( rParent ),
+ mrScenario( rSheetScenarios.createScenario() )
+{
+}
+
+ContextHandlerRef ScenarioContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( scenario ):
+ if( nElement == XLS_TOKEN( inputCells ) ) mrScenario.importInputCells( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+void ScenarioContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( isRootElement() )
+ mrScenario.importScenario( rAttribs );
+}
+
+ContextHandlerRef ScenarioContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_SCENARIO:
+ if( nRecId == BIFF12_ID_INPUTCELLS ) mrScenario.importInputCells( rStrm );
+ break;
+ }
+ return 0;
+}
+
+void ScenarioContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ if( isRootElement() )
+ mrScenario.importScenario( rStrm );
+}
+
+// ============================================================================
+
+ScenariosContext::ScenariosContext( WorksheetFragmentBase& rFragment ) :
+ WorksheetContextBase( rFragment ),
+ mrSheetScenarios( getScenarios().createSheetScenarios( getSheetIndex() ) )
+{
+}
+
+ContextHandlerRef ScenariosContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( scenarios ):
+ if( nElement == XLS_TOKEN( scenario ) ) return new ScenarioContext( *this, mrSheetScenarios );
+ break;
+ }
+ return 0;
+}
+
+void ScenariosContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( isRootElement() )
+ mrSheetScenarios.importScenarios( rAttribs );
+}
+
+ContextHandlerRef ScenariosContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_SCENARIOS:
+ if( nRecId == BIFF12_ID_SCENARIO ) return new ScenarioContext( *this, mrSheetScenarios );
+ break;
+ }
+ return 0;
+}
+
+void ScenariosContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ if( isRootElement() )
+ mrSheetScenarios.importScenarios( rStrm );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/sharedformulabuffer.cxx b/oox/source/xls/sharedformulabuffer.cxx
new file mode 100644
index 000000000000..efdfe801f784
--- /dev/null
+++ b/oox/source/xls/sharedformulabuffer.cxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/sharedformulabuffer.hxx"
+
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/formulaparser.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+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, 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( SequenceInputStream& rStrm, const CellAddress& rBaseAddr )
+{
+ BinRange aRange;
+ rStrm >> aRange;
+ CellRangeAddress aFmlaRange;
+ if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true, 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, 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 = createNamedRangeObject( aName );
+ PropertySet aNameProps( xNamedRange );
+ aNameProps.setProperty( PROP_IsSharedFormula, true );
+ sal_Int32 nTokenIndex = -1;
+ if( aNameProps.getProperty( nTokenIndex, PROP_TokenIndex ) && (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..59d3a905bc40
--- /dev/null
+++ b/oox/source/xls/sharedstringsbuffer.cxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/sharedstringsbuffer.hxx"
+
+#include "oox/xls/biffinputstream.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+
+// ============================================================================
+
+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 )
+{
+ rStrm.skip( 4 );
+ sal_Int32 nStringCount = rStrm.readInt32();
+ if( nStringCount > 0 )
+ {
+ maStrings.clear();
+ maStrings.reserve( static_cast< size_t >( nStringCount ) );
+ for( ; !rStrm.isEof() && (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..bdb60f6962b8
--- /dev/null
+++ b/oox/source/xls/sharedstringsfragment.cxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/sharedstringsfragment.hxx"
+
+#include "oox/xls/richstringcontext.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+SharedStringsFragment::SharedStringsFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ WorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+ContextHandlerRef SharedStringsFragment::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( sst ) )
+ return this;
+ break;
+
+ case XLS_TOKEN( sst ):
+ if( nElement == XLS_TOKEN( si ) )
+ return new RichStringContext( *this, getSharedStrings().createRichString() );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef SharedStringsFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_SST )
+ return this;
+ break;
+
+ case BIFF12_ID_SST:
+ if( nRecId == BIFF12_ID_SI )
+ getSharedStrings().createRichString()->importString( rStrm, true );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* SharedStringsFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_SST, BIFF12_ID_SST + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void SharedStringsFragment::finalizeImport()
+{
+ getSharedStrings().finalizeImport();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx
new file mode 100644
index 000000000000..c515ec02bfbe
--- /dev/null
+++ b/oox/source/xls/sheetdatacontext.cxx
@@ -0,0 +1,982 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/sheetdatacontext.hxx"
+
+#include <com/sun/star/sheet/XArrayFormulaTokens.hpp>
+#include <com/sun/star/sheet/XFormulaTokens.hpp>
+#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/text/XText.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/richstringcontext.hxx"
+#include "oox/xls/sharedformulabuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::ContextHandlerRef;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+// record constants -----------------------------------------------------------
+
+const sal_uInt32 BIFF12_CELL_SHOWPHONETIC = 0x01000000;
+
+const sal_uInt8 BIFF12_DATATABLE_ROW = 0x01;
+const sal_uInt8 BIFF12_DATATABLE_2D = 0x02;
+const sal_uInt8 BIFF12_DATATABLE_REF1DEL = 0x04;
+const sal_uInt8 BIFF12_DATATABLE_REF2DEL = 0x08;
+
+const sal_uInt16 BIFF12_ROW_THICKTOP = 0x0001;
+const sal_uInt16 BIFF12_ROW_THICKBOTTOM = 0x0002;
+const sal_uInt16 BIFF12_ROW_COLLAPSED = 0x0800;
+const sal_uInt16 BIFF12_ROW_HIDDEN = 0x1000;
+const sal_uInt16 BIFF12_ROW_CUSTOMHEIGHT = 0x2000;
+const sal_uInt16 BIFF12_ROW_CUSTOMFORMAT = 0x4000;
+const sal_uInt8 BIFF12_ROW_SHOWPHONETIC = 0x01;
+
+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 BIFF2_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
+
+// ============================================================================
+
+SheetDataContext::SheetDataContext( WorksheetFragmentBase& rFragment ) :
+ WorksheetContextBase( rFragment )
+{
+}
+
+ContextHandlerRef SheetDataContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( sheetData ):
+ if( nElement == XLS_TOKEN( row ) ) { importRow( rAttribs ); return this; }
+ break;
+
+ case XLS_TOKEN( row ):
+ if( nElement == XLS_TOKEN( c ) ) { importCell( rAttribs ); return this; }
+ break;
+
+ case XLS_TOKEN( c ):
+ if( maCurrCell.mxCell.is() ) switch( nElement )
+ {
+ case XLS_TOKEN( is ):
+ mxInlineStr.reset( new RichString( *this ) );
+ return new RichStringContext( *this, mxInlineStr );
+ case XLS_TOKEN( v ):
+ return this;
+ case XLS_TOKEN( f ):
+ importFormula( rAttribs );
+ return this;
+ }
+ break;
+ }
+ return 0;
+}
+
+void SheetDataContext::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ 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, true ) )
+ setTableOperation( aTableRange, maTableData );
+ }
+ break;
+
+ default:
+ OSL_ENSURE( false, "SheetDataContext::onCharacters - unknown formula type" );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ break;
+ }
+}
+
+void SheetDataContext::onEndElement()
+{
+ if( isCurrentElement( XLS_TOKEN( c ) ) && maCurrCell.mxCell.is() )
+ {
+ if( maCurrCell.mxCell->getType() == CellContentType_EMPTY )
+ {
+ if( maCurrCell.mbHasValueStr )
+ {
+ // implemented in WorksheetHelper class
+ setCell( 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 );
+ }
+}
+
+ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_SHEETDATA:
+ switch( nRecId )
+ {
+ case BIFF12_ID_ROW: importRow( rStrm ); return this;
+ }
+ break;
+
+ case BIFF12_ID_ROW:
+ switch( nRecId )
+ {
+ case BIFF12_ID_ARRAY: importArray( rStrm ); break;
+ case BIFF12_ID_CELL_BOOL: importCellBool( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_CELL_BLANK: importCellBlank( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_CELL_DOUBLE: importCellDouble( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_CELL_ERROR: importCellError( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_CELL_RK: importCellRk( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_CELL_RSTRING: importCellRString( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_CELL_SI: importCellSi( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_CELL_STRING: importCellString( rStrm, CELLTYPE_VALUE ); break;
+ case BIFF12_ID_DATATABLE: importDataTable( rStrm ); break;
+ case BIFF12_ID_FORMULA_BOOL: importCellBool( rStrm, CELLTYPE_FORMULA ); break;
+ case BIFF12_ID_FORMULA_DOUBLE: importCellDouble( rStrm, CELLTYPE_FORMULA ); break;
+ case BIFF12_ID_FORMULA_ERROR: importCellError( rStrm, CELLTYPE_FORMULA ); break;
+ case BIFF12_ID_FORMULA_STRING: importCellString( rStrm, CELLTYPE_FORMULA ); break;
+ case BIFF12_ID_MULTCELL_BOOL: importCellBool( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_MULTCELL_BLANK: importCellBlank( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_MULTCELL_DOUBLE: importCellDouble( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_MULTCELL_ERROR: importCellError( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_MULTCELL_RK: importCellRk( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_MULTCELL_RSTRING:importCellRString( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_MULTCELL_SI: importCellSi( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_MULTCELL_STRING: importCellString( rStrm, CELLTYPE_MULTI ); break;
+ case BIFF12_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
+ }
+ break;
+ }
+ return 0;
+}
+
+// private --------------------------------------------------------------------
+
+void SheetDataContext::importRow( const AttributeList& rAttribs )
+{
+ RowModel aModel;
+ aModel.mnFirstRow = aModel.mnLastRow = rAttribs.getInteger( XML_r, -1 );
+ aModel.mfHeight = rAttribs.getDouble( XML_ht, -1.0 );
+ aModel.mnXfId = rAttribs.getInteger( XML_s, -1 );
+ aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
+ aModel.mbCustomHeight = rAttribs.getBool( XML_customHeight, false );
+ aModel.mbCustomFormat = rAttribs.getBool( XML_customFormat, false );
+ aModel.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
+ aModel.mbHidden = rAttribs.getBool( XML_hidden, false );
+ aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
+ aModel.mbThickTop = rAttribs.getBool( XML_thickTop, false );
+ aModel.mbThickBottom = rAttribs.getBool( XML_thickBot, false );
+ // set row properties in the current sheet
+ setRowModel( aModel );
+}
+
+void SheetDataContext::importCell( const AttributeList& rAttribs )
+{
+ maCurrCell.reset();
+ maCurrCell.mxCell = getCell( rAttribs.getString( XML_r, OUString() ), &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();
+
+ // update used area of the sheet
+ if( maCurrCell.mxCell.is() )
+ extendUsedArea( maCurrCell.maAddress );
+}
+
+void SheetDataContext::importFormula( const AttributeList& rAttribs )
+{
+ maCurrCell.maFormulaRef = rAttribs.getString( XML_ref, OUString() );
+ maCurrCell.mnFormulaType = rAttribs.getToken( XML_t, XML_normal );
+ maCurrCell.mnSharedId = rAttribs.getInteger( XML_si, -1 );
+ maTableData.maRef1 = rAttribs.getString( XML_r1, OUString() );
+ maTableData.maRef2 = rAttribs.getString( XML_r2, OUString() );
+ 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 SheetDataContext::importCellHeader( SequenceInputStream& rStrm, CellType eCellType )
+{
+ maCurrCell.reset();
+
+ switch( eCellType )
+ {
+ case CELLTYPE_VALUE:
+ case CELLTYPE_FORMULA: rStrm >> maCurrPos.mnCol; break;
+ case CELLTYPE_MULTI: ++maCurrPos.mnCol; break;
+ }
+
+ sal_uInt32 nXfId;
+ rStrm >> nXfId;
+
+ maCurrCell.mxCell = getCell( maCurrPos, &maCurrCell.maAddress );
+ maCurrCell.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 );
+ maCurrCell.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC );
+
+ // update used area of the sheet
+ if( maCurrCell.mxCell.is() )
+ extendUsedArea( maCurrCell.maAddress );
+}
+
+void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCellType )
+{
+ importCellHeader( rStrm, eCellType );
+ maCurrCell.mnCellType = XML_b;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ bool bValue = rStrm.readuInt8() != 0;
+ if( eCellType == CELLTYPE_FORMULA )
+ {
+ importCellFormula( rStrm );
+ }
+ else
+ {
+ setBooleanCell( maCurrCell.mxCell, bValue );
+ // #108770# set 'Standard' number format for all Boolean cells
+ maCurrCell.mnNumFmtId = 0;
+ }
+ }
+ setCellFormat( maCurrCell );
+}
+
+void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCellType )
+{
+ OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" );
+ importCellHeader( rStrm, eCellType );
+ setCellFormat( maCurrCell );
+}
+
+void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType )
+{
+ importCellHeader( rStrm, eCellType );
+ maCurrCell.mnCellType = XML_n;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ double fValue = rStrm.readDouble();
+ if( eCellType == CELLTYPE_FORMULA )
+ importCellFormula( rStrm );
+ else
+ maCurrCell.mxCell->setValue( fValue );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCellType )
+{
+ importCellHeader( rStrm, eCellType );
+ maCurrCell.mnCellType = XML_e;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ {
+ sal_uInt8 nErrorCode = rStrm.readuInt8();
+ if( eCellType == CELLTYPE_FORMULA )
+ importCellFormula( rStrm );
+ else
+ setErrorCell( maCurrCell.mxCell, nErrorCode );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellType )
+{
+ OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRk - no formula cells supported" );
+ importCellHeader( rStrm, eCellType );
+ maCurrCell.mnCellType = XML_n;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
+ setCellFormat( maCurrCell );
+}
+
+void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType eCellType )
+{
+ OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRString - no formula cells supported" );
+ importCellHeader( rStrm, eCellType );
+ 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 SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellType )
+{
+ OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellSi - no formula cells supported" );
+ importCellHeader( rStrm, eCellType );
+ maCurrCell.mnCellType = XML_s;
+ if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ setSharedStringCell( maCurrCell.mxCell, rStrm.readInt32(), maCurrCell.mnXfId );
+ setCellFormat( maCurrCell );
+}
+
+void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eCellType )
+{
+ importCellHeader( rStrm, eCellType );
+ 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( eCellType == CELLTYPE_FORMULA )
+ importCellFormula( rStrm );
+ else
+ aString.convert( xText, maCurrCell.mnXfId );
+ }
+ setCellFormat( maCurrCell );
+}
+
+void SheetDataContext::importCellFormula( SequenceInputStream& 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 SheetDataContext::importRow( SequenceInputStream& rStrm )
+{
+ RowModel aModel;
+
+ sal_uInt16 nHeight, nFlags1;
+ sal_uInt8 nFlags2;
+ rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2;
+
+ // row index is 0-based in BIFF12, but RowModel expects 1-based
+ aModel.mnFirstRow = aModel.mnLastRow = maCurrPos.mnRow + 1;
+ // row height is in twips in BIFF12, convert to points
+ aModel.mfHeight = nHeight / 20.0;
+ aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 );
+ aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT );
+ aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT );
+ aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC );
+ aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN );
+ aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED );
+ aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP );
+ aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM );
+ // set row properties in the current sheet
+ setRowModel( aModel );
+}
+
+void SheetDataContext::importArray( SequenceInputStream& 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 SheetDataContext::importSharedFmla( SequenceInputStream& rStrm )
+{
+ getSharedFormulas().importSharedFmla( rStrm, maCurrCell.maAddress );
+}
+
+void SheetDataContext::importDataTable( SequenceInputStream& rStrm )
+{
+ BinRange aRange;
+ rStrm >> aRange;
+ CellRangeAddress aTableRange;
+ if( getAddressConverter().convertToCellRange( aTableRange, aRange, getSheetIndex(), true, true ) )
+ {
+ DataTableModel aModel;
+ BinAddress aRef1, aRef2;
+ sal_uInt8 nFlags;
+ rStrm >> aRef1 >> aRef2 >> nFlags;
+ aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
+ aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
+ aModel.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW );
+ aModel.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D );
+ aModel.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL );
+ aModel.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL );
+ setTableOperation( aTableRange, aModel );
+ }
+}
+
+// ============================================================================
+
+BiffSheetDataContext::BiffSheetDataContext( const WorksheetHelper& rHelper ) :
+ BiffWorksheetContextBase( 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 );
+ // update used area of the sheet
+ if( maCurrCell.mxCell.is() )
+ extendUsedArea( 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 == BIFF2_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.getRemaining() > 2; ++aAddr.mnCol )
+ {
+ setCurrCell( aAddr );
+ importXfId( rStrm, false );
+ setCellFormat( maCurrCell );
+ }
+}
+
+void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm )
+{
+ BinAddress aAddr;
+ for( rStrm >> aAddr; rStrm.getRemaining() > 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 )
+{
+ RowModel aModel;
+
+ sal_uInt16 nRow, nHeight;
+ rStrm >> nRow;
+ rStrm.skip( 4 );
+ rStrm >> nHeight;
+ if( getBiff() == BIFF2 )
+ {
+ rStrm.skip( 2 );
+ aModel.mbCustomFormat = rStrm.readuInt8() == BIFF2_ROW_CUSTOMFORMAT;
+ if( aModel.mbCustomFormat )
+ {
+ rStrm.skip( 5 );
+ aModel.mnXfId = rStrm.readuInt16();
+ }
+ }
+ else
+ {
+ rStrm.skip( 4 );
+ sal_uInt32 nFlags = rStrm.readuInt32();
+ aModel.mnXfId = extractValue< sal_Int32 >( nFlags, 16, 12 );
+ aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 0, 3 );
+ aModel.mbCustomFormat = getFlag( nFlags, BIFF_ROW_CUSTOMFORMAT );
+ aModel.mbCustomHeight = getFlag( nFlags, BIFF_ROW_CUSTOMHEIGHT );
+ aModel.mbShowPhonetic = getFlag( nFlags, BIFF_ROW_SHOWPHONETIC );
+ aModel.mbHidden = getFlag( nFlags, BIFF_ROW_HIDDEN );
+ aModel.mbCollapsed = getFlag( nFlags, BIFF_ROW_COLLAPSED );
+ aModel.mbThickTop = getFlag( nFlags, BIFF_ROW_THICKTOP );
+ aModel.mbThickBottom = getFlag( nFlags, BIFF_ROW_THICKBOTTOM );
+ }
+
+ // row index is 0-based in BIFF, but RowModel expects 1-based
+ aModel.mnFirstRow = aModel.mnLastRow = nRow + 1;
+ // row height is in twips in BIFF, convert to points
+ aModel.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0;
+ // set row properties in the current sheet
+ setRowModel( aModel );
+}
+
+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, true ) )
+ {
+ DataTableModel aModel;
+ BinAddress aRef1, aRef2;
+ switch( rStrm.getRecId() )
+ {
+ case BIFF2_ID_DATATABLE:
+ rStrm.skip( 1 );
+ aModel.mbRowTable = rStrm.readuInt8() != 0;
+ aModel.mb2dTable = false;
+ rStrm >> aRef1;
+ break;
+ case BIFF2_ID_DATATABLE2:
+ rStrm.skip( 2 );
+ aModel.mb2dTable = true;
+ rStrm >> aRef1 >> aRef2;
+ break;
+ case BIFF3_ID_DATATABLE:
+ {
+ sal_uInt16 nFlags;
+ rStrm >> nFlags >> aRef1 >> aRef2;
+ aModel.mbRowTable = getFlag( nFlags, BIFF_DATATABLE_ROW );
+ aModel.mb2dTable = getFlag( nFlags, BIFF_DATATABLE_2D );
+ aModel.mbRef1Deleted = getFlag( nFlags, BIFF_DATATABLE_REF1DEL );
+ aModel.mbRef2Deleted = getFlag( nFlags, BIFF_DATATABLE_REF2DEL );
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "BiffSheetDataContext::importDataTable - unknown record id" );
+ }
+ aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
+ aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
+ setTableOperation( aTableRange, aModel );
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx
new file mode 100644
index 000000000000..56c26d8b9f67
--- /dev/null
+++ b/oox/source/xls/stylesbuffer.cxx
@@ -0,0 +1,3471 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/stylesbuffer.hxx"
+
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/FontPitch.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontType.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XFont2.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameAccess.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/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/condformatbuffer.hxx"
+#include "oox/xls/excelhandlers.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::FilterBase;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+// OOXML constants ------------------------------------------------------------
+
+// OOXML predefined color indexes (also used in BIFF3-BIFF8)
+const sal_Int32 OOX_COLOR_USEROFFSET = 0; /// First user defined color in palette (OOXML/BIFF12).
+const sal_Int32 BIFF_COLOR_USEROFFSET = 8; /// First user defined color in palette (BIFF3-BIFF8).
+
+// OOXML 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;
+
+// OOXML 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;
+
+// OOXML 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;
+
+// OOXML cell indentation
+const sal_Int32 OOX_XF_INDENT_NONE = 0;
+
+// OOXML 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.
+
+// BIFF12 constants -----------------------------------------------------------
+
+// BIFF12 color types
+const sal_uInt8 BIFF12_COLOR_AUTO = 0;
+const sal_uInt8 BIFF12_COLOR_INDEXED = 1;
+const sal_uInt8 BIFF12_COLOR_RGB = 2;
+const sal_uInt8 BIFF12_COLOR_THEME = 3;
+
+// BIFF12 diagonal borders
+const sal_uInt8 BIFF12_BORDER_DIAG_TLBR = 0x01; /// Top-left to bottom-right.
+const sal_uInt8 BIFF12_BORDER_DIAG_BLTR = 0x02; /// Bottom-left to top-right.
+
+// BIFF12 gradient fill
+const sal_Int32 BIFF12_FILL_GRADIENT = 40;
+
+// BIFF12 XF flags
+const sal_uInt32 BIFF12_XF_WRAPTEXT = 0x00400000;
+const sal_uInt32 BIFF12_XF_JUSTLASTLINE = 0x00800000;
+const sal_uInt32 BIFF12_XF_SHRINK = 0x01000000;
+const sal_uInt32 BIFF12_XF_LOCKED = 0x10000000;
+const sal_uInt32 BIFF12_XF_HIDDEN = 0x20000000;
+
+// BIFF12 XF attribute used flags
+const sal_uInt16 BIFF12_XF_NUMFMT_USED = 0x0001;
+const sal_uInt16 BIFF12_XF_FONT_USED = 0x0002;
+const sal_uInt16 BIFF12_XF_ALIGN_USED = 0x0004;
+const sal_uInt16 BIFF12_XF_BORDER_USED = 0x0008;
+const sal_uInt16 BIFF12_XF_AREA_USED = 0x0010;
+const sal_uInt16 BIFF12_XF_PROT_USED = 0x0020;
+
+// BIFF12 DXF constants
+const sal_uInt16 BIFF12_DXF_FILL_PATTERN = 0;
+const sal_uInt16 BIFF12_DXF_FILL_FGCOLOR = 1;
+const sal_uInt16 BIFF12_DXF_FILL_BGCOLOR = 2;
+const sal_uInt16 BIFF12_DXF_FILL_GRADIENT = 3;
+const sal_uInt16 BIFF12_DXF_FILL_STOP = 4;
+const sal_uInt16 BIFF12_DXF_FONT_COLOR = 5;
+const sal_uInt16 BIFF12_DXF_BORDER_TOP = 6;
+const sal_uInt16 BIFF12_DXF_BORDER_BOTTOM = 7;
+const sal_uInt16 BIFF12_DXF_BORDER_LEFT = 8;
+const sal_uInt16 BIFF12_DXF_BORDER_RIGHT = 9;
+const sal_uInt16 BIFF12_DXF_BORDER_DIAG = 10;
+const sal_uInt16 BIFF12_DXF_BORDER_VERT = 11;
+const sal_uInt16 BIFF12_DXF_BORDER_HOR = 12;
+const sal_uInt16 BIFF12_DXF_BORDER_DIAGUP = 13;
+const sal_uInt16 BIFF12_DXF_BORDER_DIAGDOWN = 14;
+const sal_uInt16 BIFF12_DXF_FONT_NAME = 24;
+const sal_uInt16 BIFF12_DXF_FONT_WEIGHT = 25;
+const sal_uInt16 BIFF12_DXF_FONT_UNDERLINE = 26;
+const sal_uInt16 BIFF12_DXF_FONT_ESCAPEMENT = 27;
+const sal_uInt16 BIFF12_DXF_FONT_ITALIC = 28;
+const sal_uInt16 BIFF12_DXF_FONT_STRIKE = 29;
+const sal_uInt16 BIFF12_DXF_FONT_OUTLINE = 30;
+const sal_uInt16 BIFF12_DXF_FONT_SHADOW = 31;
+const sal_uInt16 BIFF12_DXF_FONT_CONDENSE = 32;
+const sal_uInt16 BIFF12_DXF_FONT_EXTEND = 33;
+const sal_uInt16 BIFF12_DXF_FONT_CHARSET = 34;
+const sal_uInt16 BIFF12_DXF_FONT_FAMILY = 35;
+const sal_uInt16 BIFF12_DXF_FONT_HEIGHT = 36;
+const sal_uInt16 BIFF12_DXF_FONT_SCHEME = 37;
+const sal_uInt16 BIFF12_DXF_NUMFMT_CODE = 38;
+const sal_uInt16 BIFF12_DXF_NUMFMT_ID = 41;
+
+// BIFF12 CELLSTYLE flags
+const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN = 0x0001;
+const sal_uInt16 BIFF12_CELLSTYLE_HIDDEN = 0x0002;
+const sal_uInt16 BIFF12_CELLSTYLE_CUSTOM = 0x0004;
+
+// 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 BIFF12
+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 BIFF12
+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 STYLEEXT flags
+const sal_uInt8 BIFF_STYLEEXT_BUILTIN = 0x01;
+const sal_uInt8 BIFF_STYLEEXT_HIDDEN = 0x02;
+const sal_uInt8 BIFF_STYLEEXT_CUSTOM = 0x04;
+
+// BIFF conditional formatting
+const sal_uInt32 BIFF_CFRULE_BORDER_LEFT = 0x00000400;
+const sal_uInt32 BIFF_CFRULE_BORDER_RIGHT = 0x00000800;
+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 lclReadRgbColor( BinaryInputStream& rStrm )
+{
+ sal_uInt8 nR, nG, nB, nA;
+ rStrm >> nR >> nG >> nB >> nA;
+ sal_Int32 nValue = nA;
+ nValue <<= 8;
+ nValue |= nR;
+ nValue <<= 8;
+ nValue |= nG;
+ nValue <<= 8;
+ nValue |= nB;
+ return nValue;
+}
+
+} // namespace
+
+// ============================================================================
+
+ExcelGraphicHelper::ExcelGraphicHelper( const WorkbookHelper& rHelper ) :
+ GraphicHelper( rHelper.getBaseFilter().getComponentContext(), rHelper.getBaseFilter().getTargetFrame(), rHelper.getBaseFilter().getStorage() ),
+ WorkbookHelper( rHelper )
+{
+}
+
+sal_Int32 ExcelGraphicHelper::getSchemeColor( sal_Int32 nToken ) const
+{
+ if( getFilterType() == FILTER_OOXML )
+ return getTheme().getColorByToken( nToken );
+ return GraphicHelper::getSchemeColor( nToken );
+}
+
+sal_Int32 ExcelGraphicHelper::getPaletteColor( sal_Int32 nPaletteIdx ) const
+{
+ return getStyles().getPaletteColor( nPaletteIdx );
+}
+
+// ============================================================================
+
+void Color::setAuto()
+{
+ clearTransformations();
+ setSchemeClr( XML_phClr );
+}
+
+void Color::setRgb( sal_Int32 nRgbValue, double fTint )
+{
+ clearTransformations();
+ setSrgbClr( nRgbValue & 0xFFFFFF );
+ if( fTint != 0.0 ) addExcelTintTransformation( fTint );
+}
+
+void Color::setTheme( sal_Int32 nThemeIdx, double fTint )
+{
+ clearTransformations();
+ static const sal_Int32 spnColorTokens[] = {
+ XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2,
+ XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink };
+ setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) );
+ if( fTint != 0.0 ) addExcelTintTransformation( fTint );
+}
+
+void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint )
+{
+ clearTransformations();
+ setPaletteClr( nPaletteIdx );
+ if( fTint != 0.0 ) addExcelTintTransformation( fTint );
+}
+
+void Color::importColor( const AttributeList& rAttribs )
+{
+ if( rAttribs.getBool( XML_auto, false ) )
+ setAuto();
+ else if( rAttribs.hasAttribute( XML_rgb ) )
+ setRgb( rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ), rAttribs.getDouble( XML_tint, 0.0 ) );
+ else if( rAttribs.hasAttribute( XML_theme ) )
+ setTheme( rAttribs.getInteger( XML_theme, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
+ else if( rAttribs.hasAttribute( XML_indexed ) )
+ setIndexed( rAttribs.getInteger( XML_indexed, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
+ else
+ {
+ OSL_ENSURE( false, "Color::importColor - unknown color type" );
+ setAuto();
+ }
+}
+
+void Color::importColor( SequenceInputStream& rStrm )
+{
+ sal_uInt8 nFlags, nIndex;
+ sal_Int16 nTint;
+ rStrm >> nFlags >> nIndex >> nTint;
+
+ // scale tint from signed 16-bit to double range -1.0 ... 1.0
+ double fTint = nTint;
+ if( nTint < 0 )
+ fTint /= -SAL_MIN_INT16;
+ else if( nTint > 0 )
+ fTint /= SAL_MAX_INT16;
+
+ switch( extractValue< sal_uInt8 >( nFlags, 1, 7 ) )
+ {
+ case BIFF12_COLOR_AUTO:
+ setAuto();
+ rStrm.skip( 4 );
+ break;
+ case BIFF12_COLOR_INDEXED:
+ setIndexed( nIndex, fTint );
+ rStrm.skip( 4 );
+ break;
+ case BIFF12_COLOR_RGB:
+ setRgb( lclReadRgbColor( rStrm ), fTint );
+ break;
+ case BIFF12_COLOR_THEME:
+ setTheme( nIndex, fTint );
+ rStrm.skip( 4 );
+ break;
+ default:
+ OSL_ENSURE( false, "Color::importColor - unknown color type" );
+ setAuto();
+ rStrm.skip( 4 );
+ }
+}
+
+void Color::importColorId( SequenceInputStream& rStrm )
+{
+ setIndexed( rStrm.readInt32() );
+}
+
+void Color::importColorRgb( SequenceInputStream& rStrm )
+{
+ setRgb( lclReadRgbColor( rStrm ) );
+}
+
+void Color::importColorId( BiffInputStream& rStrm, bool b16Bit )
+{
+ setIndexed( b16Bit ? rStrm.readuInt16() : rStrm.readuInt8() );
+}
+
+void Color::importColorRgb( BiffInputStream& rStrm )
+{
+ setRgb( lclReadRgbColor( rStrm ) );
+}
+
+SequenceInputStream& operator>>( SequenceInputStream& rStrm, Color& 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/BIFF12/OOXML. */
+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 )
+{
+ // default colors
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ 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.getIntegerHex( XML_rgb, API_RGB_WHITE ) );
+}
+
+void ColorPalette::importPaletteColor( SequenceInputStream& rStrm )
+{
+ sal_Int32 nRgb = lclReadRgbColor( rStrm );
+ appendColor( nRgb & 0xFFFFFF );
+}
+
+void ColorPalette::importPalette( BiffInputStream& rStrm )
+{
+ sal_uInt16 nCount;
+ rStrm >> nCount;
+ OSL_ENSURE( rStrm.getRemaining() == 4 * nCount, "ColorPalette::importPalette - wrong palette size" );
+
+ // fill palette from BIFF_COLOR_USEROFFSET
+ mnAppendIndex = BIFF_COLOR_USEROFFSET;
+ for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
+ {
+ sal_Int32 nRgb = lclReadRgbColor( rStrm );
+ appendColor( nRgb & 0xFFFFFF );
+ }
+}
+
+void ColorPalette::importPalette( const Any& rPalette )
+{
+ Sequence< sal_Int32 > rColorSeq;
+ if( (rPalette >>= rColorSeq) && rColorSeq.hasElements() )
+ {
+ const sal_Int32* pnColor = rColorSeq.getConstArray();
+ const sal_Int32* pnColorEnd = pnColor + rColorSeq.getLength();
+ for( ; pnColor < pnColorEnd; ++pnColor )
+ appendColor( *pnColor & 0xFFFFFF );
+ }
+}
+
+sal_Int32 ColorPalette::getColor( sal_Int32 nPaletteIdx ) const
+{
+ sal_Int32 nColor = API_RGB_TRANSPARENT;
+ if( const sal_Int32* pnPaletteColor = ContainerHelper::getVectorElement( maColors, nPaletteIdx ) )
+ {
+ nColor = *pnPaletteColor;
+ }
+ else switch( nPaletteIdx )
+ {
+ case OOX_COLOR_WINDOWTEXT3:
+ case OOX_COLOR_WINDOWTEXT:
+ case OOX_COLOR_CHWINDOWTEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_windowText ); break;
+ case OOX_COLOR_WINDOWBACK3:
+ case OOX_COLOR_WINDOWBACK:
+ case OOX_COLOR_CHWINDOWBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_window ); break;
+ case OOX_COLOR_BUTTONBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_btnFace ); break;
+ case OOX_COLOR_CHBORDERAUTO: nColor = API_RGB_BLACK; /* really always black? */ break;
+ case OOX_COLOR_NOTEBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoBk ); break;
+ case OOX_COLOR_NOTETEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoText ); break;
+ 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;
+}
+
+// ============================================================================
+
+namespace {
+
+void lclSetFontName( ApiScriptFontName& rFontName, const FontDescriptor& rFontDesc, bool bHasGlyphs )
+{
+ if( bHasGlyphs )
+ {
+ rFontName.maName = rFontDesc.Name;
+ rFontName.mnFamily = rFontDesc.Family;
+ // API font descriptor contains rtl_TextEncoding constants
+ rFontName.mnTextEnc = rFontDesc.CharSet;
+ }
+ else
+ {
+ rFontName = ApiScriptFontName();
+ }
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+FontModel::FontModel() :
+ mnScheme( XML_none ),
+ mnFamily( OOX_FONTFAMILY_NONE ),
+ mnCharSet( WINDOWS_CHARSET_DEFAULT ),
+ mfHeight( 0.0 ),
+ mnUnderline( XML_none ),
+ mnEscapement( XML_baseline ),
+ mbBold( false ),
+ mbItalic( false ),
+ mbStrikeout( false ),
+ mbOutline( false ),
+ mbShadow( false )
+{
+}
+
+void FontModel::setBiff12Scheme( sal_uInt8 nScheme )
+{
+ static const sal_Int32 spnSchemes[] = { XML_none, XML_major, XML_minor };
+ mnScheme = STATIC_ARRAY_SELECT( spnSchemes, nScheme, XML_none );
+}
+
+void FontModel::setBiffHeight( sal_uInt16 nHeight )
+{
+ mfHeight = nHeight / 20.0; // convert twips to points
+}
+
+void FontModel::setBiffWeight( sal_uInt16 nWeight )
+{
+ mbBold = nWeight >= BIFF_FONTWEIGHT_BOLD;
+}
+
+void FontModel::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 FontModel::setBiffEscapement( sal_uInt16 nEscapement )
+{
+ static const sal_Int32 spnEscapes[] = { XML_baseline, XML_superscript, XML_subscript };
+ mnEscapement = STATIC_ARRAY_SELECT( spnEscapes, nEscapement, XML_baseline );
+}
+
+// ----------------------------------------------------------------------------
+
+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 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ApiScriptFontName::ApiScriptFontName() :
+ mnFamily( ::com::sun::star::awt::FontFamily::DONTKNOW ),
+ mnTextEnc( RTL_TEXTENCODING_DONTKNOW )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+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 )
+{
+ maLatinFont.maName = maDesc.Name;
+}
+
+// ============================================================================
+
+Font::Font( const WorkbookHelper& rHelper, bool bDxf ) :
+ WorkbookHelper( rHelper ),
+ maModel( rHelper.getTheme().getDefaultFontModel() ),
+ maUsedFlags( !bDxf ),
+ mbDxf( bDxf )
+{
+}
+
+Font::Font( const WorkbookHelper& rHelper, const FontModel& rModel ) :
+ WorkbookHelper( rHelper ),
+ maModel( rModel ),
+ maUsedFlags( true ),
+ mbDxf( false )
+{
+}
+
+void Font::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ const FontModel& rDefModel = getTheme().getDefaultFontModel();
+ switch( nElement )
+ {
+ case XLS_TOKEN( name ): // when in <font> element
+ case XLS_TOKEN( rFont ): // when in <rPr> element
+ if( rAttribs.hasAttribute( XML_val ) )
+ {
+ maModel.maName = rAttribs.getXString( XML_val, OUString() );
+ maUsedFlags.mbNameUsed = true;
+ }
+ break;
+ case XLS_TOKEN( scheme ):
+ maModel.mnScheme = rAttribs.getToken( XML_val, rDefModel.mnScheme );
+ break;
+ case XLS_TOKEN( family ):
+ maModel.mnFamily = rAttribs.getInteger( XML_val, rDefModel.mnFamily );
+ break;
+ case XLS_TOKEN( charset ):
+ maModel.mnCharSet = rAttribs.getInteger( XML_val, rDefModel.mnCharSet );
+ break;
+ case XLS_TOKEN( sz ):
+ maModel.mfHeight = rAttribs.getDouble( XML_val, rDefModel.mfHeight );
+ maUsedFlags.mbHeightUsed = true;
+ break;
+ case XLS_TOKEN( color ):
+ maModel.maColor.importColor( rAttribs );
+ maUsedFlags.mbColorUsed = true;
+ break;
+ case XLS_TOKEN( u ):
+ maModel.mnUnderline = rAttribs.getToken( XML_val, XML_single );
+ maUsedFlags.mbUnderlineUsed = true;
+ break;
+ case XLS_TOKEN( vertAlign ):
+ maModel.mnEscapement = rAttribs.getToken( XML_val, XML_baseline );
+ maUsedFlags.mbEscapementUsed = true;
+ break;
+ case XLS_TOKEN( b ):
+ maModel.mbBold = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbWeightUsed = true;
+ break;
+ case XLS_TOKEN( i ):
+ maModel.mbItalic = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbPostureUsed = true;
+ break;
+ case XLS_TOKEN( strike ):
+ maModel.mbStrikeout = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbStrikeoutUsed = true;
+ break;
+ case XLS_TOKEN( outline ):
+ maModel.mbOutline = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbOutlineUsed = true;
+ break;
+ case XLS_TOKEN( shadow ):
+ maModel.mbShadow = rAttribs.getBool( XML_val, true );
+ maUsedFlags.mbShadowUsed = true;
+ break;
+ }
+}
+
+void Font::importFont( SequenceInputStream& 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 >> maModel.maColor >> nScheme >> maModel.maName;
+
+ // equal constants in all BIFFs for weight, underline, and escapement
+ maModel.setBiff12Scheme( nScheme );
+ maModel.setBiffHeight( nHeight );
+ maModel.setBiffWeight( nWeight );
+ maModel.setBiffUnderline( nUnderline );
+ maModel.setBiffEscapement( nEscapement );
+ maModel.mnFamily = nFamily;
+ maModel.mnCharSet = nCharSet;
+ // equal flags in all BIFFs
+ maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
+ maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT );
+ maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE );
+ maModel.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW );
+}
+
+void Font::importDxfName( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfName - missing conditional formatting flag" );
+ maModel.maName = BiffHelper::readString( rStrm, false );
+ maUsedFlags.mbColorUsed = true;
+}
+
+void Font::importDxfColor( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfColor - missing conditional formatting flag" );
+ rStrm >> maModel.maColor;
+ maUsedFlags.mbColorUsed = true;
+}
+
+void Font::importDxfScheme( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfScheme - missing conditional formatting flag" );
+ maModel.setBiff12Scheme( rStrm.readuInt8() );
+ maUsedFlags.mbSchemeUsed = true;
+}
+
+void Font::importDxfHeight( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfHeight - missing conditional formatting flag" );
+ maModel.setBiffHeight( rStrm.readuInt16() );
+ maUsedFlags.mbHeightUsed = true;
+}
+
+void Font::importDxfWeight( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfWeight - missing conditional formatting flag" );
+ maModel.setBiffWeight( rStrm.readuInt16() );
+ maUsedFlags.mbWeightUsed = true;
+}
+
+void Font::importDxfUnderline( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfUnderline - missing conditional formatting flag" );
+ maModel.setBiffUnderline( rStrm.readuInt16() );
+ maUsedFlags.mbUnderlineUsed = true;
+}
+
+void Font::importDxfEscapement( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfEscapement - missing conditional formatting flag" );
+ maModel.setBiffEscapement( rStrm.readuInt16() );
+ maUsedFlags.mbEscapementUsed = true;
+}
+
+void Font::importDxfFlag( sal_Int32 nElement, SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Font::importDxfFlag - missing conditional formatting flag" );
+ bool bFlag = rStrm.readuInt8() != 0;
+ switch( nElement )
+ {
+ case XML_i:
+ maModel.mbItalic = bFlag;
+ maUsedFlags.mbPostureUsed = true;
+ break;
+ case XML_strike:
+ maModel.mbStrikeout = bFlag;
+ maUsedFlags.mbStrikeoutUsed = true;
+ break;
+ case XML_outline:
+ maModel.mbOutline = bFlag;
+ maUsedFlags.mbOutlineUsed = true;
+ break;
+ case XML_shadow:
+ maModel.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" );
+ maModel.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.getRemaining() >= 118, "Font::importCfRule - missing record data" );
+ sal_Int64 nRecPos = rStrm.tell();
+ maModel.maName = rStrm.readUniStringBody( rStrm.readuInt8() );
+ maUsedFlags.mbNameUsed = maModel.maName.getLength() > 0;
+ OSL_ENSURE( !rStrm.isEof() && (rStrm.tell() <= 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 )
+ maModel.maColor.setIndexed( nColor );
+ if( (maUsedFlags.mbHeightUsed = (0 < nHeight) && (nHeight <= 0x7FFF)) == true )
+ maModel.setBiffHeight( static_cast< sal_uInt16 >( nHeight ) );
+ if( (maUsedFlags.mbUnderlineUsed = !getFlag( nFontFlags3, BIFF_CFRULE_FONT_UNDERL )) == true )
+ maModel.setBiffUnderline( nUnderline );
+ if( (maUsedFlags.mbEscapementUsed = !getFlag( nFontFlags2, BIFF_CFRULE_FONT_ESCAPEM )) == true )
+ maModel.setBiffEscapement( nEscapement );
+ if( (maUsedFlags.mbWeightUsed = maUsedFlags.mbPostureUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STYLE )) == true )
+ {
+ maModel.setBiffWeight( nWeight );
+ maModel.mbItalic = getFlag( nStyle, BIFF_CFRULE_FONT_STYLE );
+ }
+ if( (maUsedFlags.mbStrikeoutUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STRIKEOUT )) == true )
+ maModel.mbStrikeout = getFlag( nStyle, BIFF_CFRULE_FONT_STRIKEOUT );
+ if( (maUsedFlags.mbOutlineUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_OUTLINE )) == true )
+ maModel.mbOutline = getFlag( nStyle, BIFF_CFRULE_FONT_OUTLINE );
+ if( (maUsedFlags.mbShadowUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_SHADOW )) == true )
+ maModel.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 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) )
+ eFontEnc = rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) );
+ return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? getTextEncoding() : eFontEnc;
+}
+
+void Font::finalizeImport()
+{
+ namespace cssawt = ::com::sun::star::awt;
+
+ // font name
+ maApiData.maDesc.Name = maModel.maName;
+
+ // font family
+ switch( maModel.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 (API font descriptor uses rtl_TextEncoding in member CharSet!)
+ if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) )
+ maApiData.maDesc.CharSet = static_cast< sal_Int16 >(
+ rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) );
+
+ // color, height, weight, slant, strikeout, outline, shadow
+ maApiData.mnColor = maModel.maColor.getColor( getBaseFilter().getGraphicHelper() );
+ maApiData.maDesc.Height = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 );
+ maApiData.maDesc.Weight = maModel.mbBold ? cssawt::FontWeight::BOLD : cssawt::FontWeight::NORMAL;
+ maApiData.maDesc.Slant = maModel.mbItalic ? cssawt::FontSlant_ITALIC : cssawt::FontSlant_NONE;
+ maApiData.maDesc.Strikeout = maModel.mbStrikeout ? cssawt::FontStrikeout::SINGLE : cssawt::FontStrikeout::NONE;
+ maApiData.mbOutline = maModel.mbOutline;
+ maApiData.mbShadow = maModel.mbShadow;
+
+ // underline
+ switch( maModel.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( maModel.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 )
+ {
+ PropertySet aDocProps( getDocument() );
+ Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY );
+ if( xDevice.is() )
+ {
+ Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY );
+ if( xFont.is() )
+ {
+ // #91658# CJK fonts
+ bool bHasAsian =
+ 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
+ bool bHasCmplx =
+ 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
+ bool bHasLatin =
+ (!bHasAsian && !bHasCmplx) ||
+ xFont->hasGlyphs( OUString( sal_Unicode( 'A' ) ) );
+
+ lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin );
+ lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian );
+ lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx );
+ }
+ }
+ }
+}
+
+const FontDescriptor& Font::getFontDescriptor() const
+{
+ return maApiData.maDesc;
+}
+
+bool Font::needsRichTextFormat() const
+{
+ return maApiData.mnEscapement != API_ESCAPE_NONE;
+}
+
+void Font::writeToPropertyMap( PropertyMap& rPropMap, FontPropertyType ePropType ) const
+{
+ // font name properties
+ if( maUsedFlags.mbNameUsed )
+ {
+ if( maApiData.maLatinFont.maName.getLength() > 0 )
+ {
+ rPropMap[ PROP_CharFontName ] <<= maApiData.maLatinFont.maName;
+ rPropMap[ PROP_CharFontFamily ] <<= maApiData.maLatinFont.mnFamily;
+ rPropMap[ PROP_CharFontCharSet ] <<= maApiData.maLatinFont.mnTextEnc;
+ }
+ if( maApiData.maAsianFont.maName.getLength() > 0 )
+ {
+ rPropMap[ PROP_CharFontNameAsian ] <<= maApiData.maAsianFont.maName;
+ rPropMap[ PROP_CharFontFamilyAsian ] <<= maApiData.maAsianFont.mnFamily;
+ rPropMap[ PROP_CharFontCharSetAsian ] <<= maApiData.maAsianFont.mnTextEnc;
+ }
+ if( maApiData.maCmplxFont.maName.getLength() > 0 )
+ {
+ rPropMap[ PROP_CharFontNameComplex ] <<= maApiData.maCmplxFont.maName;
+ rPropMap[ PROP_CharFontFamilyComplex ] <<= maApiData.maCmplxFont.mnFamily;
+ rPropMap[ PROP_CharFontCharSetComplex ] <<= maApiData.maCmplxFont.mnTextEnc;
+ }
+ }
+ // font height
+ if( maUsedFlags.mbHeightUsed )
+ {
+ float fHeight = static_cast< float >( maApiData.maDesc.Height / 20.0 ); // twips to points
+ rPropMap[ PROP_CharHeight ] <<= fHeight;
+ rPropMap[ PROP_CharHeightAsian ] <<= fHeight;
+ rPropMap[ PROP_CharHeightComplex ] <<= fHeight;
+ }
+ // font weight
+ if( maUsedFlags.mbWeightUsed )
+ {
+ float fWeight = maApiData.maDesc.Weight;
+ rPropMap[ PROP_CharWeight ] <<= fWeight;
+ rPropMap[ PROP_CharWeightAsian ] <<= fWeight;
+ rPropMap[ PROP_CharWeightComplex ] <<= fWeight;
+ }
+ // font posture
+ if( maUsedFlags.mbPostureUsed )
+ {
+ rPropMap[ PROP_CharPosture ] <<= maApiData.maDesc.Slant;
+ rPropMap[ PROP_CharPostureAsian ] <<= maApiData.maDesc.Slant;
+ rPropMap[ PROP_CharPostureComplex ] <<= maApiData.maDesc.Slant;
+ }
+ // character color
+ if( maUsedFlags.mbColorUsed )
+ rPropMap[ PROP_CharColor ] <<= maApiData.mnColor;
+ // underline style
+ if( maUsedFlags.mbUnderlineUsed )
+ rPropMap[ PROP_CharUnderline ] <<= maApiData.maDesc.Underline;
+ // strike out style
+ if( maUsedFlags.mbStrikeoutUsed )
+ rPropMap[ PROP_CharStrikeout ] <<= maApiData.maDesc.Strikeout;
+ // outline style
+ if( maUsedFlags.mbOutlineUsed )
+ rPropMap[ PROP_CharContoured ] <<= maApiData.mbOutline;
+ // shadow style
+ if( maUsedFlags.mbShadowUsed )
+ rPropMap[ PROP_CharShadowed ] <<= maApiData.mbShadow;
+ // escapement
+ if( maUsedFlags.mbEscapementUsed && (ePropType == FONT_PROPTYPE_TEXT) )
+ {
+ rPropMap[ PROP_CharEscapement ] <<= maApiData.mnEscapement;
+ rPropMap[ PROP_CharEscapementHeight ] <<= maApiData.mnEscapeHeight;
+ }
+}
+
+void Font::writeToPropertySet( PropertySet& rPropSet, FontPropertyType ePropType ) const
+{
+ PropertyMap aPropMap;
+ writeToPropertyMap( aPropMap, ePropType );
+ rPropSet.setProperties( aPropMap );
+}
+
+void Font::importFontData2( BiffInputStream& rStrm )
+{
+ sal_uInt16 nHeight, nFlags;
+ rStrm >> nHeight >> nFlags;
+
+ maModel.setBiffHeight( nHeight );
+ maModel.mnFamily = OOX_FONTFAMILY_NONE;
+ maModel.mnCharSet = -1; // ensure to not use font charset in byte string import
+ maModel.mnUnderline = getFlagValue( nFlags, BIFF_FONTFLAG_UNDERLINE, XML_single, XML_none );
+ maModel.mnEscapement = XML_none;
+ maModel.mbBold = getFlag( nFlags, BIFF_FONTFLAG_BOLD );
+ maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
+ maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT );
+ maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE );
+ maModel.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 );
+
+ maModel.setBiffWeight( nWeight );
+ maModel.setBiffUnderline( nUnderline );
+ maModel.setBiffEscapement( nEscapement );
+ // equal constants in XML and BIFF for family and charset
+ maModel.mnFamily = nFamily;
+ maModel.mnCharSet = nCharSet;
+}
+
+void Font::importFontName2( BiffInputStream& rStrm )
+{
+ maModel.maName = rStrm.readByteStringUC( false, getTextEncoding() );
+}
+
+void Font::importFontName8( BiffInputStream& rStrm )
+{
+ maModel.maName = rStrm.readUniStringBody( rStrm.readuInt8() );
+}
+
+// ============================================================================
+
+AlignmentModel::AlignmentModel() :
+ 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 AlignmentModel::setBiffHorAlign( 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 AlignmentModel::setBiffVerAlign( 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 AlignmentModel::setBiffTextOrient( 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 );
+}
+
+// ----------------------------------------------------------------------------
+
+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);
+}
+
+// ============================================================================
+
+Alignment::Alignment( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void Alignment::importAlignment( const AttributeList& rAttribs )
+{
+ maModel.mnHorAlign = rAttribs.getToken( XML_horizontal, XML_general );
+ maModel.mnVerAlign = rAttribs.getToken( XML_vertical, XML_bottom );
+ maModel.mnTextDir = rAttribs.getInteger( XML_readingOrder, OOX_XF_TEXTDIR_CONTEXT );
+ maModel.mnRotation = rAttribs.getInteger( XML_textRotation, OOX_XF_ROTATION_NONE );
+ maModel.mnIndent = rAttribs.getInteger( XML_indent, OOX_XF_INDENT_NONE );
+ maModel.mbWrapText = rAttribs.getBool( XML_wrapText, false );
+ maModel.mbShrink = rAttribs.getBool( XML_shrinkToFit, false );
+ maModel.mbJustLastLine = rAttribs.getBool( XML_justifyLastLine, false );
+}
+
+void Alignment::setBiff12Data( sal_uInt32 nFlags )
+{
+ maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 16, 3 ) );
+ maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nFlags, 19, 3 ) );
+ maModel.mnTextDir = extractValue< sal_Int32 >( nFlags, 26, 2 );
+ maModel.mnRotation = extractValue< sal_Int32 >( nFlags, 0, 8 );
+ maModel.mnIndent = extractValue< sal_uInt8 >( nFlags, 8, 8 );
+ maModel.mbWrapText = getFlag( nFlags, BIFF12_XF_WRAPTEXT );
+ maModel.mbShrink = getFlag( nFlags, BIFF12_XF_SHRINK );
+ maModel.mbJustLastLine = getFlag( nFlags, BIFF12_XF_JUSTLASTLINE );
+}
+
+void Alignment::setBiff2Data( sal_uInt8 nFlags )
+{
+ maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 0, 3 ) );
+}
+
+void Alignment::setBiff3Data( sal_uInt16 nAlign )
+{
+ maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); // new in BIFF3
+}
+
+void Alignment::setBiff4Data( sal_uInt16 nAlign )
+{
+ maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 2 ) ); // new in BIFF4
+ maModel.setBiffTextOrient( extractValue< sal_uInt8 >( nAlign, 6, 2 ) ); // new in BIFF4
+ maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT );
+}
+
+void Alignment::setBiff5Data( sal_uInt16 nAlign )
+{
+ maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) );
+ maModel.setBiffTextOrient( extractValue< sal_uInt8 >( nAlign, 8, 2 ) );
+ maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT );
+}
+
+void Alignment::setBiff8Data( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib )
+{
+ maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) );
+ maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) );
+ maModel.mnTextDir = extractValue< sal_Int32 >( nMiscAttrib, 6, 2 ); // new in BIFF8
+ maModel.mnRotation = extractValue< sal_Int32 >( nAlign, 8, 8 ); // new in BIFF8
+ maModel.mnIndent = extractValue< sal_uInt8 >( nMiscAttrib, 0, 4 ); // new in BIFF8
+ maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT );
+ maModel.mbShrink = getFlag( nMiscAttrib, BIFF_XF_SHRINK ); // new in BIFF8
+ maModel.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( maModel.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( maModel.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
+ OOXML/BIFF12, and as multiple of 10 points in BIFF8. */
+ sal_Int32 nIndent = 0;
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML: nIndent = getUnitConverter().scaleToMm100( 3.0 * maModel.mnIndent, UNIT_SPACE ); break;
+ case FILTER_BIFF: nIndent = getUnitConverter().scaleToMm100( 10.0 * maModel.mnIndent, UNIT_POINT ); break;
+ case FILTER_UNKNOWN: break;
+ }
+ if( (0 <= nIndent) && (nIndent <= SAL_MAX_INT16) )
+ maApiData.mnIndent = static_cast< sal_Int16 >( nIndent );
+
+ // complex text direction
+ switch( maModel.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 = maModel.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 (#i84960 automatic line break, if vertically justified/distributed)
+ maApiData.mbWrapText = maModel.mbWrapText || (maModel.mnVerAlign == XML_distributed) || (maModel.mnVerAlign == XML_justify);
+ maApiData.mbShrink = maModel.mbShrink;
+
+}
+
+void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const
+{
+ rPropMap[ PROP_HoriJustify ] <<= maApiData.meHorJustify;
+ rPropMap[ PROP_VertJustify ] <<= maApiData.meVerJustify;
+ rPropMap[ PROP_WritingMode ] <<= maApiData.mnWritingMode;
+ rPropMap[ PROP_RotateAngle ] <<= maApiData.mnRotation;
+ rPropMap[ PROP_Orientation ] <<= maApiData.meOrientation;
+ rPropMap[ PROP_ParaIndent ] <<= maApiData.mnIndent;
+ rPropMap[ PROP_IsTextWrapped ] <<= maApiData.mbWrapText;
+ rPropMap[ PROP_ShrinkToFit ] <<= maApiData.mbShrink;
+}
+
+// ============================================================================
+
+ProtectionModel::ProtectionModel() :
+ mbLocked( true ), // default in Excel and Calc
+ mbHidden( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+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);
+}
+
+// ============================================================================
+
+Protection::Protection( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+void Protection::importProtection( const AttributeList& rAttribs )
+{
+ maModel.mbLocked = rAttribs.getBool( XML_locked, true );
+ maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
+}
+
+void Protection::setBiff12Data( sal_uInt32 nFlags )
+{
+ maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED );
+ maModel.mbHidden = getFlag( nFlags, BIFF12_XF_HIDDEN );
+}
+
+void Protection::setBiff2Data( sal_uInt8 nNumFmt )
+{
+ maModel.mbLocked = getFlag( nNumFmt, BIFF2_XF_LOCKED );
+ maModel.mbHidden = getFlag( nNumFmt, BIFF2_XF_HIDDEN );
+}
+
+void Protection::setBiff3Data( sal_uInt16 nProt )
+{
+ maModel.mbLocked = getFlag( nProt, BIFF_XF_LOCKED );
+ maModel.mbHidden = getFlag( nProt, BIFF_XF_HIDDEN );
+}
+
+void Protection::finalizeImport()
+{
+ maApiData.maCellProt.IsLocked = maModel.mbLocked;
+ maApiData.maCellProt.IsFormulaHidden = maModel.mbHidden;
+}
+
+void Protection::writeToPropertyMap( PropertyMap& rPropMap ) const
+{
+ rPropMap[ PROP_CellProtection ] <<= maApiData.maCellProt;
+}
+
+// ============================================================================
+
+BorderLineModel::BorderLineModel( bool bDxf ) :
+ mnStyle( XML_none ),
+ mbUsed( !bDxf )
+{
+ maColor.setIndexed( OOX_COLOR_WINDOWTEXT );
+}
+
+void BorderLineModel::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 BorderLineModel::setBiffData( sal_uInt8 nLineStyle, sal_uInt16 nLineColor )
+{
+ maColor.setIndexed( nLineColor );
+ setBiffStyle( nLineStyle );
+}
+
+// ----------------------------------------------------------------------------
+
+BorderModel::BorderModel( bool bDxf ) :
+ maLeft( bDxf ),
+ maRight( bDxf ),
+ maTop( bDxf ),
+ maBottom( bDxf ),
+ maDiagonal( bDxf ),
+ mbDiagTLtoBR( false ),
+ mbDiagBLtoTR( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ApiBorderData::ApiBorderData() :
+ mbBorderUsed( false ),
+ mbDiagUsed( false )
+{
+}
+
+bool ApiBorderData::hasAnyOuterBorder() const
+{
+ return
+ (maBorder.IsTopLineValid && (maBorder.TopLine.OuterLineWidth > 0)) ||
+ (maBorder.IsBottomLineValid && (maBorder.BottomLine.OuterLineWidth > 0)) ||
+ (maBorder.IsLeftLineValid && (maBorder.LeftLine.OuterLineWidth > 0)) ||
+ (maBorder.IsRightLineValid && (maBorder.RightLine.OuterLineWidth > 0));
+}
+
+namespace {
+
+bool operator==( const BorderLine& rLeft, const BorderLine& rRight )
+{
+ return
+ (rLeft.Color == rRight.Color) &&
+ (rLeft.InnerLineWidth == rRight.InnerLineWidth) &&
+ (rLeft.OuterLineWidth == rRight.OuterLineWidth) &&
+ (rLeft.LineDistance == rRight.LineDistance);
+}
+
+bool operator==( const TableBorder& rLeft, const TableBorder& rRight )
+{
+ return
+ (rLeft.TopLine == rRight.TopLine) &&
+ (rLeft.IsTopLineValid == rRight.IsTopLineValid) &&
+ (rLeft.BottomLine == rRight.BottomLine) &&
+ (rLeft.IsBottomLineValid == rRight.IsBottomLineValid) &&
+ (rLeft.LeftLine == rRight.LeftLine) &&
+ (rLeft.IsLeftLineValid == rRight.IsLeftLineValid) &&
+ (rLeft.RightLine == rRight.RightLine) &&
+ (rLeft.IsRightLineValid == rRight.IsRightLineValid) &&
+ (rLeft.HorizontalLine == rRight.HorizontalLine) &&
+ (rLeft.IsHorizontalLineValid == rRight.IsHorizontalLineValid) &&
+ (rLeft.VerticalLine == rRight.VerticalLine) &&
+ (rLeft.IsVerticalLineValid == rRight.IsVerticalLineValid) &&
+ (rLeft.Distance == rRight.Distance) &&
+ (rLeft.IsDistanceValid == rRight.IsDistanceValid);
+}
+
+} // namespace
+
+bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight )
+{
+ return
+ (rLeft.maBorder == rRight.maBorder) &&
+ (rLeft.maTLtoBR == rRight.maTLtoBR) &&
+ (rLeft.maBLtoTR == rRight.maBLtoTR) &&
+ (rLeft.mbBorderUsed == rRight.mbBorderUsed) &&
+ (rLeft.mbDiagUsed == rRight.mbDiagUsed);
+}
+
+// ============================================================================
+
+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 ),
+ maModel( bDxf ),
+ mbDxf( bDxf )
+{
+}
+
+void Border::importBorder( const AttributeList& rAttribs )
+{
+ maModel.mbDiagTLtoBR = rAttribs.getBool( XML_diagonalDown, false );
+ maModel.mbDiagBLtoTR = rAttribs.getBool( XML_diagonalUp, false );
+}
+
+void Border::importStyle( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
+ {
+ pBorderLine->mnStyle = rAttribs.getToken( XML_style, XML_none );
+ pBorderLine->mbUsed = true;
+ }
+}
+
+void Border::importColor( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
+ pBorderLine->maColor.importColor( rAttribs );
+}
+
+void Border::importBorder( SequenceInputStream& rStrm )
+{
+ sal_uInt8 nFlags = rStrm.readuInt8();
+ maModel.mbDiagTLtoBR = getFlag( nFlags, BIFF12_BORDER_DIAG_TLBR );
+ maModel.mbDiagBLtoTR = getFlag( nFlags, BIFF12_BORDER_DIAG_BLTR );
+ maModel.maTop.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maModel.maTop.maColor;
+ maModel.maBottom.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maModel.maBottom.maColor;
+ maModel.maLeft.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maModel.maLeft.maColor;
+ maModel.maRight.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maModel.maRight.maColor;
+ maModel.maDiagonal.setBiffStyle( rStrm.readuInt16() );
+ rStrm >> maModel.maDiagonal.maColor;
+}
+
+void Border::importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Border::importDxfBorder - missing conditional formatting flag" );
+ if( BorderLineModel* 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" );
+ maModel.maLeft.setBiffData( getFlagValue( nFlags, BIFF2_XF_LEFTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maModel.maRight.setBiffData( getFlagValue( nFlags, BIFF2_XF_RIGHTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maModel.maTop.setBiffData( getFlagValue( nFlags, BIFF2_XF_TOPLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maModel.maBottom.setBiffData( getFlagValue( nFlags, BIFF2_XF_BOTTOMLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK );
+ maModel.maDiagonal.mbUsed = false;
+}
+
+void Border::setBiff3Data( sal_uInt32 nBorder )
+{
+ OSL_ENSURE( !mbDxf, "Border::setBiff3Data - unexpected conditional formatting flag" );
+ maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 8, 3 ), extractValue< sal_uInt16 >( nBorder, 11, 5 ) );
+ maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 24, 3 ), extractValue< sal_uInt16 >( nBorder, 27, 5 ) );
+ maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 3, 5 ) );
+ maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder, 16, 3 ), extractValue< sal_uInt16 >( nBorder, 19, 5 ) );
+ maModel.maDiagonal.mbUsed = false;
+}
+
+void Border::setBiff5Data( sal_uInt32 nBorder, sal_uInt32 nArea )
+{
+ OSL_ENSURE( !mbDxf, "Border::setBiff5Data - unexpected conditional formatting flag" );
+ maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 3, 3 ), extractValue< sal_uInt16 >( nBorder, 16, 7 ) );
+ maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 6, 3 ), extractValue< sal_uInt16 >( nBorder, 23, 7 ) );
+ maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 9, 7 ) );
+ maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nArea, 22, 3 ), extractValue< sal_uInt16 >( nArea, 25, 7 ) );
+ maModel.maDiagonal.mbUsed = false;
+}
+
+void Border::setBiff8Data( sal_uInt32 nBorder1, sal_uInt32 nBorder2 )
+{
+ OSL_ENSURE( !mbDxf, "Border::setBiff8Data - unexpected conditional formatting flag" );
+ maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder1, 0, 4 ), extractValue< sal_uInt16 >( nBorder1, 16, 7 ) );
+ maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder1, 4, 4 ), extractValue< sal_uInt16 >( nBorder1, 23, 7 ) );
+ maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder1, 8, 4 ), extractValue< sal_uInt16 >( nBorder2, 0, 7 ) );
+ maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder1, 12, 4 ), extractValue< sal_uInt16 >( nBorder2, 7, 7 ) );
+ maModel.mbDiagTLtoBR = getFlag( nBorder1, BIFF_XF_DIAG_TLBR );
+ maModel.mbDiagBLtoTR = getFlag( nBorder1, BIFF_XF_DIAG_BLTR );
+ if( maModel.mbDiagTLtoBR || maModel.mbDiagBLtoTR )
+ maModel.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 );
+ maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nStyle, 0, 4 ), extractValue< sal_uInt16 >( nColor, 0, 7 ) );
+ maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nStyle, 4, 4 ), extractValue< sal_uInt16 >( nColor, 7, 7 ) );
+ maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nStyle, 8, 4 ), extractValue< sal_uInt16 >( nColor, 16, 7 ) );
+ maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nStyle, 12, 4 ), extractValue< sal_uInt16 >( nColor, 23, 7 ) );
+ maModel.maLeft.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_LEFT );
+ maModel.maRight.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_RIGHT );
+ maModel.maTop.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_TOP );
+ maModel.maBottom.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_BOTTOM );
+}
+
+void Border::finalizeImport()
+{
+ maApiData.mbBorderUsed = maModel.maLeft.mbUsed || maModel.maRight.mbUsed || maModel.maTop.mbUsed || maModel.maBottom.mbUsed;
+ maApiData.mbDiagUsed = maModel.maDiagonal.mbUsed;
+
+ maApiData.maBorder.IsLeftLineValid = convertBorderLine( maApiData.maBorder.LeftLine, maModel.maLeft );
+ maApiData.maBorder.IsRightLineValid = convertBorderLine( maApiData.maBorder.RightLine, maModel.maRight );
+ maApiData.maBorder.IsTopLineValid = convertBorderLine( maApiData.maBorder.TopLine, maModel.maTop );
+ maApiData.maBorder.IsBottomLineValid = convertBorderLine( maApiData.maBorder.BottomLine, maModel.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( maModel.mbDiagTLtoBR )
+ convertBorderLine( maApiData.maTLtoBR, maModel.maDiagonal );
+ if( maModel.mbDiagBLtoTR )
+ convertBorderLine( maApiData.maBLtoTR, maModel.maDiagonal );
+}
+
+void Border::writeToPropertyMap( PropertyMap& rPropMap ) const
+{
+ if( maApiData.mbBorderUsed )
+ rPropMap[ PROP_TableBorder ] <<= maApiData.maBorder;
+ if( maApiData.mbDiagUsed )
+ {
+ rPropMap[ PROP_DiagonalTLBR ] <<= maApiData.maTLtoBR;
+ rPropMap[ PROP_DiagonalBLTR ] <<= maApiData.maBLtoTR;
+ }
+}
+
+BorderLineModel* Border::getBorderLine( sal_Int32 nElement )
+{
+ switch( nElement )
+ {
+ case XLS_TOKEN( left ): return &maModel.maLeft;
+ case XLS_TOKEN( right ): return &maModel.maRight;
+ case XLS_TOKEN( top ): return &maModel.maTop;
+ case XLS_TOKEN( bottom ): return &maModel.maBottom;
+ case XLS_TOKEN( diagonal ): return &maModel.maDiagonal;
+ }
+ return 0;
+}
+
+bool Border::convertBorderLine( BorderLine& rBorderLine, const BorderLineModel& rModel )
+{
+ rBorderLine.Color = rModel.maColor.getColor( getBaseFilter().getGraphicHelper(), API_RGB_BLACK );
+ switch( rModel.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 rModel.mbUsed;
+}
+
+
+// ============================================================================
+
+PatternFillModel::PatternFillModel( bool bDxf ) :
+ mnPattern( XML_none ),
+ mbPattColorUsed( !bDxf ),
+ mbFillColorUsed( !bDxf ),
+ mbPatternUsed( !bDxf )
+{
+ maPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT );
+ maFillColor.setIndexed( OOX_COLOR_WINDOWBACK );
+}
+
+void PatternFillModel::setBiffPattern( 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 PatternFillModel::setBiffData( sal_uInt16 nPatternColor, sal_uInt16 nFillColor, sal_uInt8 nPattern )
+{
+ maPatternColor.setIndexed( nPatternColor );
+ maFillColor.setIndexed( nFillColor );
+ // patterns equal in all BIFFs
+ setBiffPattern( nPattern );
+}
+
+// ----------------------------------------------------------------------------
+
+GradientFillModel::GradientFillModel() :
+ mnType( XML_linear ),
+ mfAngle( 0.0 ),
+ mfLeft( 0.0 ),
+ mfRight( 0.0 ),
+ mfTop( 0.0 ),
+ mfBottom( 0.0 )
+{
+}
+
+void GradientFillModel::readGradient( SequenceInputStream& 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 GradientFillModel::readGradientStop( SequenceInputStream& rStrm, bool bDxf )
+{
+ Color aColor;
+ double fPosition;
+ if( bDxf )
+ {
+ rStrm.skip( 2 );
+ rStrm >> fPosition >> aColor;
+ }
+ else
+ {
+ rStrm >> aColor >> fPosition;
+ }
+ if( !rStrm.isEof() && (fPosition >= 0.0) )
+ maColors[ fPosition ] = aColor;
+}
+
+// ----------------------------------------------------------------------------
+
+ApiSolidFillData::ApiSolidFillData() :
+ mnColor( API_RGB_TRANSPARENT ),
+ mbTransparent( true ),
+ mbUsed( false )
+{
+}
+
+bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight )
+{
+ return
+ (rLeft.mnColor == rRight.mnColor) &&
+ (rLeft.mbTransparent == rRight.mbTransparent) &&
+ (rLeft.mbUsed == rRight.mbUsed);
+}
+
+// ============================================================================
+
+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 )
+{
+}
+
+void Fill::importPatternFill( const AttributeList& rAttribs )
+{
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->mnPattern = rAttribs.getToken( XML_patternType, XML_none );
+ if( mbDxf )
+ mxPatternModel->mbPatternUsed = rAttribs.hasAttribute( XML_patternType );
+}
+
+void Fill::importFgColor( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( mxPatternModel.get(), "Fill::importFgColor - missing pattern data" );
+ if( mxPatternModel.get() )
+ {
+ mxPatternModel->maPatternColor.importColor( rAttribs );
+ mxPatternModel->mbPattColorUsed = true;
+ }
+}
+
+void Fill::importBgColor( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( mxPatternModel.get(), "Fill::importBgColor - missing pattern data" );
+ if( mxPatternModel.get() )
+ {
+ mxPatternModel->maFillColor.importColor( rAttribs );
+ mxPatternModel->mbFillColorUsed = true;
+ }
+}
+
+void Fill::importGradientFill( const AttributeList& rAttribs )
+{
+ mxGradientModel.reset( new GradientFillModel );
+ mxGradientModel->mnType = rAttribs.getToken( XML_type, XML_linear );
+ mxGradientModel->mfAngle = rAttribs.getDouble( XML_degree, 0.0 );
+ mxGradientModel->mfLeft = rAttribs.getDouble( XML_left, 0.0 );
+ mxGradientModel->mfRight = rAttribs.getDouble( XML_right, 0.0 );
+ mxGradientModel->mfTop = rAttribs.getDouble( XML_top, 0.0 );
+ mxGradientModel->mfBottom = rAttribs.getDouble( XML_bottom, 0.0 );
+}
+
+void Fill::importColor( const AttributeList& rAttribs, double fPosition )
+{
+ OSL_ENSURE( mxGradientModel.get(), "Fill::importColor - missing gradient data" );
+ if( mxGradientModel.get() && (fPosition >= 0.0) )
+ mxGradientModel->maColors[ fPosition ].importColor( rAttribs );
+}
+
+void Fill::importFill( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( !mbDxf, "Fill::importFill - unexpected conditional formatting flag" );
+ sal_Int32 nPattern = rStrm.readInt32();
+ if( nPattern == BIFF12_FILL_GRADIENT )
+ {
+ mxGradientModel.reset( new GradientFillModel );
+ sal_Int32 nStopCount;
+ rStrm.skip( 16 );
+ mxGradientModel->readGradient( rStrm );
+ rStrm >> nStopCount;
+ for( sal_Int32 nStop = 0; (nStop < nStopCount) && !rStrm.isEof(); ++nStop )
+ mxGradientModel->readGradientStop( rStrm, false );
+ }
+ else
+ {
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->setBiffPattern( nPattern );
+ rStrm >> mxPatternModel->maPatternColor >> mxPatternModel->maFillColor;
+ }
+}
+
+void Fill::importDxfPattern( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfPattern - missing conditional formatting flag" );
+ if( !mxPatternModel )
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->setBiffPattern( rStrm.readuInt8() );
+ mxPatternModel->mbPatternUsed = true;
+}
+
+void Fill::importDxfFgColor( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfFgColor - missing conditional formatting flag" );
+ if( !mxPatternModel )
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->maPatternColor.importColor( rStrm );
+ mxPatternModel->mbPattColorUsed = true;
+}
+
+void Fill::importDxfBgColor( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfBgColor - missing conditional formatting flag" );
+ if( !mxPatternModel )
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->maFillColor.importColor( rStrm );
+ mxPatternModel->mbFillColorUsed = true;
+}
+
+void Fill::importDxfGradient( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfGradient - missing conditional formatting flag" );
+ if( !mxGradientModel )
+ mxGradientModel.reset( new GradientFillModel );
+ mxGradientModel->readGradient( rStrm );
+}
+
+void Fill::importDxfStop( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( mbDxf, "Fill::importDxfStop - missing conditional formatting flag" );
+ if( !mxGradientModel )
+ mxGradientModel.reset( new GradientFillModel );
+ mxGradientModel->readGradientStop( rStrm, true );
+}
+
+void Fill::setBiff2Data( sal_uInt8 nFlags )
+{
+ OSL_ENSURE( !mbDxf, "Fill::setBiff2Data - unexpected conditional formatting flag" );
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->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" );
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->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" );
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->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" );
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ mxPatternModel->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" );
+ mxPatternModel.reset( new PatternFillModel( mbDxf ) );
+ sal_uInt32 nFillData;
+ rStrm >> nFillData;
+ mxPatternModel->setBiffData(
+ extractValue< sal_uInt16 >( nFillData, 16, 7 ),
+ extractValue< sal_uInt16 >( nFillData, 23, 7 ),
+ extractValue< sal_uInt8 >( nFillData, 10, 6 ) );
+ mxPatternModel->mbPattColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTCOLOR );
+ mxPatternModel->mbFillColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_FILLCOLOR );
+ mxPatternModel->mbPatternUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTERN );
+}
+
+void Fill::finalizeImport()
+{
+ const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
+
+ if( mxPatternModel.get() )
+ {
+ // finalize the OOXML data struct
+ PatternFillModel& rModel = *mxPatternModel;
+ if( mbDxf )
+ {
+ if( rModel.mbFillColorUsed && (!rModel.mbPatternUsed || (rModel.mnPattern == XML_solid)) )
+ {
+ rModel.maPatternColor = rModel.maFillColor;
+ rModel.mnPattern = XML_solid;
+ rModel.mbPattColorUsed = rModel.mbPatternUsed = true;
+ }
+ else if( !rModel.mbFillColorUsed && rModel.mbPatternUsed && (rModel.mnPattern == XML_solid) )
+ {
+ rModel.mbPatternUsed = false;
+ }
+ }
+
+ // convert to API fill settings
+ maApiData.mbUsed = rModel.mbPatternUsed;
+ if( rModel.mnPattern == XML_none )
+ {
+ maApiData.mnColor = API_RGB_TRANSPARENT;
+ maApiData.mbTransparent = true;
+ }
+ else
+ {
+ sal_Int32 nAlpha = 0x80;
+ switch( rModel.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;
+ }
+
+ sal_Int32 nWinTextColor = rGraphicHelper.getSystemColor( XML_windowText );
+ sal_Int32 nWinColor = rGraphicHelper.getSystemColor( XML_window );
+
+ if( !rModel.mbPattColorUsed )
+ rModel.maPatternColor.setAuto();
+ sal_Int32 nPattColor = rModel.maPatternColor.getColor( rGraphicHelper, nWinTextColor );
+
+ if( !rModel.mbFillColorUsed )
+ rModel.maFillColor.setAuto();
+ sal_Int32 nFillColor = rModel.maFillColor.getColor( rGraphicHelper, nWinColor );
+
+ maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha );
+ maApiData.mbTransparent = false;
+ }
+ }
+ else if( mxGradientModel.get() && !mxGradientModel->maColors.empty() )
+ {
+ GradientFillModel& rModel = *mxGradientModel;
+ maApiData.mbUsed = true; // no support for differential attributes
+ GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin();
+ OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
+ maApiData.mnColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
+ if( ++aIt != rModel.maColors.end() )
+ {
+ OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
+ sal_Int32 nEndColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
+ maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 );
+ maApiData.mbTransparent = false;
+ }
+ }
+}
+
+void Fill::writeToPropertyMap( PropertyMap& rPropMap ) const
+{
+ if( maApiData.mbUsed )
+ {
+ rPropMap[ PROP_CellBackColor ] <<= maApiData.mnColor;
+ rPropMap[ PROP_IsCellBackgroundTransparent ] <<= maApiData.mbTransparent;
+ }
+}
+
+// ============================================================================
+
+XfModel::XfModel() :
+ 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 ),
+ meRotationRef( ::com::sun::star::table::CellVertJustify_STANDARD )
+{
+}
+
+void Xf::setAllUsedFlags( bool bUsed )
+{
+ maModel.mbAlignUsed = maModel.mbProtUsed = maModel.mbFontUsed =
+ maModel.mbNumFmtUsed = maModel.mbBorderUsed = maModel.mbAreaUsed = bUsed;
+}
+
+void Xf::importXf( const AttributeList& rAttribs, bool bCellXf )
+{
+ maModel.mbCellXf = bCellXf;
+ maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 );
+ maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 );
+ maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 );
+ maModel.mnBorderId = rAttribs.getInteger( XML_borderId, -1 );
+ maModel.mnFillId = rAttribs.getInteger( XML_fillId, -1 );
+
+ /* Default value of the apply*** attributes is dependent on context:
+ true in cellStyleXfs element, false in cellXfs element... */
+ maModel.mbAlignUsed = rAttribs.getBool( XML_applyAlignment, !maModel.mbCellXf );
+ maModel.mbProtUsed = rAttribs.getBool( XML_applyProtection, !maModel.mbCellXf );
+ maModel.mbFontUsed = rAttribs.getBool( XML_applyFont, !maModel.mbCellXf );
+ maModel.mbNumFmtUsed = rAttribs.getBool( XML_applyNumberFormat, !maModel.mbCellXf );
+ maModel.mbBorderUsed = rAttribs.getBool( XML_applyBorder, !maModel.mbCellXf );
+ maModel.mbAreaUsed = rAttribs.getBool( XML_applyFill, !maModel.mbCellXf );
+}
+
+void Xf::importAlignment( const AttributeList& rAttribs )
+{
+ maAlignment.importAlignment( rAttribs );
+}
+
+void Xf::importProtection( const AttributeList& rAttribs )
+{
+ maProtection.importProtection( rAttribs );
+}
+
+void Xf::importXf( SequenceInputStream& rStrm, bool bCellXf )
+{
+ maModel.mbCellXf = bCellXf;
+ maModel.mnStyleXfId = rStrm.readuInt16();
+ maModel.mnNumFmtId = rStrm.readuInt16();
+ maModel.mnFontId = rStrm.readuInt16();
+ maModel.mnFillId = rStrm.readuInt16();
+ maModel.mnBorderId = rStrm.readuInt16();
+ sal_uInt32 nFlags = rStrm.readuInt32();
+ maAlignment.setBiff12Data( nFlags );
+ maProtection.setBiff12Data( nFlags );
+ // used flags, see comments in Xf::setBiffUsedFlags()
+ sal_uInt16 nUsedFlags = rStrm.readuInt16();
+ maModel.mbFontUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_FONT_USED );
+ maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_NUMFMT_USED );
+ maModel.mbAlignUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_ALIGN_USED );
+ maModel.mbProtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_PROT_USED );
+ maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_BORDER_USED );
+ maModel.mbAreaUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_AREA_USED );
+}
+
+void Xf::importXf( BiffInputStream& rStrm )
+{
+ BorderRef xBorder = getStyles().createBorder( &maModel.mnBorderId );
+ FillRef xFill = getStyles().createFill( &maModel.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 );
+ maModel.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maModel.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
+ maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); // new in BIFF3
+ maModel.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 );
+ maModel.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maModel.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
+ maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE );
+ maModel.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 );
+ maModel.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maModel.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
+ maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE );
+ maModel.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 );
+ maModel.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maModel.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
+ maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE );
+ maModel.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 );
+ maModel.mnFontId = static_cast< sal_Int32 >( nFontId );
+ maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId );
+ }
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+}
+
+void Xf::finalizeImport()
+{
+ StylesBuffer& rStyles = getStyles();
+
+ // alignment and protection
+ maAlignment.finalizeImport();
+ maProtection.finalizeImport();
+
+ /* Enables the used flags, if the formatting attributes differ from the
+ style XF. In cell XFs Excel uses the cell attributes, if they differ
+ from the parent style XF (even if the used flag is switched off).
+ #109899# ...or if the respective flag is not set in parent style XF.
+ */
+ const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0;
+ if( pStyleXf )
+ {
+ const XfModel& rStyleData = pStyleXf->maModel;
+ if( !maModel.mbFontUsed )
+ maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
+ if( !maModel.mbNumFmtUsed )
+ maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
+ if( !maModel.mbAlignUsed )
+ maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData());
+ if( !maModel.mbProtUsed )
+ maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData());
+ if( !maModel.mbBorderUsed )
+ maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId );
+ if( !maModel.mbAreaUsed )
+ maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId );
+ }
+
+ /* #i38709# Decide which rotation reference mode to use. If any outer
+ border line of the cell is set (either explicitly or via cell style),
+ and the cell contents are rotated, set rotation reference to bottom of
+ cell. This causes the borders to be painted rotated with the text. */
+ if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) )
+ {
+ sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1);
+ if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() )
+ if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() )
+ meRotationRef = ::com::sun::star::table::CellVertJustify_BOTTOM;
+ }
+}
+
+FontRef Xf::getFont() const
+{
+ return getStyles().getFont( maModel.mnFontId );
+}
+
+bool Xf::hasAnyUsedFlags() const
+{
+ return
+ maModel.mbAlignUsed || maModel.mbProtUsed || maModel.mbFontUsed ||
+ maModel.mbNumFmtUsed || maModel.mbBorderUsed || maModel.mbAreaUsed;
+}
+
+void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const
+{
+ StylesBuffer& rStyles = getStyles();
+
+ // create and set cell style
+ if( isCellXf() )
+ rPropMap[ PROP_CellStyle ] <<= rStyles.createCellStyle( maModel.mnStyleXfId );
+
+ if( maModel.mbFontUsed )
+ rStyles.writeFontToPropertyMap( rPropMap, maModel.mnFontId );
+ if( maModel.mbNumFmtUsed )
+ rStyles.writeNumFmtToPropertyMap( rPropMap, maModel.mnNumFmtId );
+ if( maModel.mbAlignUsed )
+ maAlignment.writeToPropertyMap( rPropMap );
+ if( maModel.mbProtUsed )
+ maProtection.writeToPropertyMap( rPropMap );
+ if( maModel.mbBorderUsed )
+ rStyles.writeBorderToPropertyMap( rPropMap, maModel.mnBorderId );
+ if( maModel.mbAreaUsed )
+ rStyles.writeFillToPropertyMap( rPropMap, maModel.mnFillId );
+ if( maModel.mbAlignUsed || maModel.mbBorderUsed )
+ rPropMap[ PROP_RotateReference ] <<= meRotationRef;
+}
+
+void Xf::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ PropertyMap aPropMap;
+ writeToPropertyMap( aPropMap );
+ rPropSet.setProperties( aPropMap );
+}
+
+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 "isCellXf() == getFlag(...)" construct evaluates to true in both
+ mentioned cases: cell XF and set bit; or style XF and cleared bit.
+ */
+ maModel.mbFontUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_FONT_USED );
+ maModel.mbNumFmtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED );
+ maModel.mbAlignUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED );
+ maModel.mbProtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_PROT_USED );
+ maModel.mbBorderUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_BORDER_USED );
+ maModel.mbAreaUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_AREA_USED );
+}
+
+// ============================================================================
+
+Dxf::Dxf( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+FontRef Dxf::createFont( bool bAlwaysNew )
+{
+ if( bAlwaysNew || !mxFont )
+ mxFont.reset( new Font( *this, true ) );
+ return mxFont;
+}
+
+BorderRef Dxf::createBorder( bool bAlwaysNew )
+{
+ if( bAlwaysNew || !mxBorder )
+ mxBorder.reset( new Border( *this, true ) );
+ return mxBorder;
+}
+
+FillRef Dxf::createFill( bool bAlwaysNew )
+{
+ if( bAlwaysNew || !mxFill )
+ mxFill.reset( new Fill( *this, true ) );
+ return mxFill;
+}
+
+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 );
+}
+
+void Dxf::importDxf( SequenceInputStream& rStrm )
+{
+ sal_Int32 nNumFmtId = -1;
+ OUString aFmtCode;
+ sal_uInt16 nRecCount;
+ rStrm.skip( 4 ); // flags
+ rStrm >> nRecCount;
+ for( sal_uInt16 nRec = 0; !rStrm.isEof() && (nRec < nRecCount); ++nRec )
+ {
+ sal_uInt16 nSubRecId, nSubRecSize;
+ sal_Int64 nRecEnd = rStrm.tell();
+ rStrm >> nSubRecId >> nSubRecSize;
+ nRecEnd += nSubRecSize;
+ switch( nSubRecId )
+ {
+ case BIFF12_DXF_FILL_PATTERN: createFill( false )->importDxfPattern( rStrm ); break;
+ case BIFF12_DXF_FILL_FGCOLOR: createFill( false )->importDxfFgColor( rStrm ); break;
+ case BIFF12_DXF_FILL_BGCOLOR: createFill( false )->importDxfBgColor( rStrm ); break;
+ case BIFF12_DXF_FILL_GRADIENT: createFill( false )->importDxfGradient( rStrm ); break;
+ case BIFF12_DXF_FILL_STOP: createFill( false )->importDxfStop( rStrm ); break;
+ case BIFF12_DXF_FONT_COLOR: createFont( false )->importDxfColor( rStrm ); break;
+ case BIFF12_DXF_BORDER_TOP: createBorder( false )->importDxfBorder( XLS_TOKEN( top ), rStrm ); break;
+ case BIFF12_DXF_BORDER_BOTTOM: createBorder( false )->importDxfBorder( XLS_TOKEN( bottom ), rStrm ); break;
+ case BIFF12_DXF_BORDER_LEFT: createBorder( false )->importDxfBorder( XLS_TOKEN( left ), rStrm ); break;
+ case BIFF12_DXF_BORDER_RIGHT: createBorder( false )->importDxfBorder( XLS_TOKEN( right ), rStrm ); break;
+ case BIFF12_DXF_FONT_NAME: createFont( false )->importDxfName( rStrm ); break;
+ case BIFF12_DXF_FONT_WEIGHT: createFont( false )->importDxfWeight( rStrm ); break;
+ case BIFF12_DXF_FONT_UNDERLINE: createFont( false )->importDxfUnderline( rStrm ); break;
+ case BIFF12_DXF_FONT_ESCAPEMENT: createFont( false )->importDxfEscapement( rStrm ); break;
+ case BIFF12_DXF_FONT_ITALIC: createFont( false )->importDxfFlag( XML_i, rStrm ); break;
+ case BIFF12_DXF_FONT_STRIKE: createFont( false )->importDxfFlag( XML_strike, rStrm ); break;
+ case BIFF12_DXF_FONT_OUTLINE: createFont( false )->importDxfFlag( XML_outline, rStrm ); break;
+ case BIFF12_DXF_FONT_SHADOW: createFont( false )->importDxfFlag( XML_shadow, rStrm ); break;
+ case BIFF12_DXF_FONT_HEIGHT: createFont( false )->importDxfHeight( rStrm ); break;
+ case BIFF12_DXF_FONT_SCHEME: createFont( false )->importDxfScheme( rStrm ); break;
+ case BIFF12_DXF_NUMFMT_CODE: aFmtCode = BiffHelper::readString( rStrm, false ); break;
+ case BIFF12_DXF_NUMFMT_ID: nNumFmtId = rStrm.readuInt16(); break;
+ }
+ rStrm.seek( nRecEnd );
+ }
+ OSL_ENSURE( !rStrm.isEof() && (rStrm.getRemaining() == 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()->importCfRule( rStrm );
+ if( getFlag( nFlags, BIFF_CFRULE_ALIGNBLOCK ) )
+ rStrm.skip( 8 );
+ if( getFlag( nFlags, BIFF_CFRULE_BORDERBLOCK ) )
+ createBorder()->importCfRule( rStrm, nFlags );
+ if( getFlag( nFlags, BIFF_CFRULE_FILLBLOCK ) )
+ createFill()->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();
+}
+
+void Dxf::writeToPropertyMap( PropertyMap& rPropMap ) const
+{
+ if( mxFont.get() )
+ mxFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL );
+ if( mxNumFmt.get() )
+ mxNumFmt->writeToPropertyMap( rPropMap );
+ if( mxAlignment.get() )
+ mxAlignment->writeToPropertyMap( rPropMap );
+ if( mxProtection.get() )
+ mxProtection->writeToPropertyMap( rPropMap );
+ if( mxBorder.get() )
+ mxBorder->writeToPropertyMap( rPropMap );
+ if( mxFill.get() )
+ mxFill->writeToPropertyMap( rPropMap );
+}
+
+void Dxf::writeToPropertySet( PropertySet& rPropSet ) const
+{
+ PropertyMap aPropMap;
+ writeToPropertyMap( aPropMap );
+ rPropSet.setProperties( aPropMap );
+}
+
+// ============================================================================
+
+namespace {
+
+const sal_Char* const spcLegacyStyleNamePrefix = "Excel_BuiltIn_";
+const sal_Char* const sppcLegacyStyleNames[] =
+{
+ "Normal",
+ "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[] =
+{
+ "Normal",
+ "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 ) );
+
+OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 )
+{
+ OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" );
+ OUStringBuffer aStyleName;
+ 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 );
+ return aStyleName.makeStringAndClear();
+}
+
+OUString lclGetBuiltInStyleName( const OUString& rName )
+{
+ OUStringBuffer aStyleName;
+ aStyleName.appendAscii( spcStyleNamePrefix ).append( rName );
+ return aStyleName.makeStringAndClear();
+}
+
+bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar )
+{
+ // try the other built-in styles
+ OUString aPrefix = OUString::createFromAscii( spcStyleNamePrefix );
+ sal_Int32 nPrefixLen = aPrefix.getLength();
+ sal_Int32 nFoundId = 0;
+ sal_Int32 nNextChar = 0;
+ if( rStyleName.matchIgnoreAsciiCase( aPrefix ) )
+ {
+ OUString aShortName;
+ for( sal_Int32 nId = 0; nId < snStyleNamesCount; ++nId )
+ {
+ aShortName = OUString::createFromAscii( sppcStyleNames[ nId ] );
+ if( rStyleName.matchIgnoreAsciiCase( aShortName, nPrefixLen ) &&
+ (nNextChar < nPrefixLen + aShortName.getLength()) )
+ {
+ nFoundId = nId;
+ nNextChar = nPrefixLen + aShortName.getLength();
+ }
+ }
+ }
+
+ 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
+
+// ----------------------------------------------------------------------------
+
+CellStyleModel::CellStyleModel() :
+ mnXfId( -1 ),
+ mnBuiltinId( -1 ),
+ mnLevel( 0 ),
+ mbBuiltin( false ),
+ mbCustom( false ),
+ mbHidden( false )
+{
+}
+
+bool CellStyleModel::isBuiltin() const
+{
+ return mbBuiltin && (mnBuiltinId >= 0);
+}
+
+bool CellStyleModel::isDefaultStyle() const
+{
+ return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL);
+}
+
+// ============================================================================
+
+CellStyle::CellStyle( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ mbCreated( false )
+{
+}
+
+void CellStyle::importCellStyle( const AttributeList& rAttribs )
+{
+ maModel.maName = rAttribs.getXString( XML_name, OUString() );
+ maModel.mnXfId = rAttribs.getInteger( XML_xfId, -1 );
+ maModel.mnBuiltinId = rAttribs.getInteger( XML_builtinId, -1 );
+ maModel.mnLevel = rAttribs.getInteger( XML_iLevel, 0 );
+ maModel.mbBuiltin = rAttribs.hasAttribute( XML_builtinId );
+ maModel.mbCustom = rAttribs.getBool( XML_customBuiltin, false );
+ maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
+}
+
+void CellStyle::importCellStyle( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> maModel.mnXfId >> nFlags;
+ maModel.mnBuiltinId = rStrm.readInt8();
+ maModel.mnLevel = rStrm.readInt8();
+ rStrm >> maModel.maName;
+ maModel.mbBuiltin = getFlag( nFlags, BIFF12_CELLSTYLE_BUILTIN );
+ maModel.mbCustom = getFlag( nFlags, BIFF12_CELLSTYLE_CUSTOM );
+ maModel.mbHidden = getFlag( nFlags, BIFF12_CELLSTYLE_HIDDEN );
+}
+
+void CellStyle::importStyle( BiffInputStream& rStrm )
+{
+ sal_uInt16 nStyleXf;
+ rStrm >> nStyleXf;
+ maModel.mnXfId = static_cast< sal_Int32 >( nStyleXf & BIFF_STYLE_XFMASK );
+ maModel.mbBuiltin = getFlag( nStyleXf, BIFF_STYLE_BUILTIN );
+ if( maModel.mbBuiltin )
+ {
+ maModel.mnBuiltinId = rStrm.readInt8();
+ maModel.mnLevel = rStrm.readInt8();
+ }
+ else
+ {
+ maModel.maName = (getBiff() == BIFF8) ?
+ rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
+ // #i103281# check if this is a new built-in style introduced in XL2007
+ if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_STYLEEXT) && rStrm.startNextRecord() )
+ {
+ sal_uInt8 nExtFlags;
+ rStrm.skip( 12 );
+ rStrm >> nExtFlags;
+ maModel.mbBuiltin = getFlag( nExtFlags, BIFF_STYLEEXT_BUILTIN );
+ maModel.mbCustom = getFlag( nExtFlags, BIFF_STYLEEXT_CUSTOM );
+ maModel.mbHidden = getFlag( nExtFlags, BIFF_STYLEEXT_HIDDEN );
+ if( maModel.mbBuiltin )
+ {
+ maModel.mnBuiltinId = rStrm.readInt8();
+ maModel.mnLevel = rStrm.readInt8();
+ }
+ }
+ }
+}
+
+void CellStyle::createCellStyle()
+{
+ // #i1624# #i1768# ignore unnamed user styles
+ if( !mbCreated )
+ mbCreated = maFinalName.getLength() == 0;
+
+ /* #i103281# do not create another style of the same name, if it exists
+ already. This is needed to prevent that styles pasted from clipboard
+ get duplicated over and over. */
+ if( !mbCreated ) try
+ {
+ Reference< XNameAccess > xCellStylesNA( getStyleFamily( false ), UNO_QUERY_THROW );
+ mbCreated = xCellStylesNA->hasByName( maFinalName );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // create the style object in the document
+ if( !mbCreated ) try
+ {
+ mbCreated = true;
+ Reference< XStyle > xStyle( createStyleObject( maFinalName, false ), UNO_SET_THROW );
+ // write style formatting properties
+ PropertySet aPropSet( xStyle );
+ getStyles().writeStyleXfToPropertySet( aPropSet, maModel.mnXfId );
+ if( !maModel.isDefaultStyle() )
+ xStyle->setParentStyle( getStyles().getDefaultStyleName() );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void CellStyle::finalizeImport( const OUString& rFinalName )
+{
+ maFinalName = rFinalName;
+ if( !maModel.isBuiltin() || maModel.mbCustom )
+ createCellStyle();
+}
+
+// ============================================================================
+
+CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs )
+{
+ CellStyleRef xCellStyle( new CellStyle( *this ) );
+ xCellStyle->importCellStyle( rAttribs );
+ insertCellStyle( xCellStyle );
+ return xCellStyle;
+}
+
+CellStyleRef CellStyleBuffer::importCellStyle( SequenceInputStream& rStrm )
+{
+ CellStyleRef xCellStyle( new CellStyle( *this ) );
+ xCellStyle->importCellStyle( rStrm );
+ insertCellStyle( xCellStyle );
+ return xCellStyle;
+}
+
+CellStyleRef CellStyleBuffer::importStyle( BiffInputStream& rStrm )
+{
+ CellStyleRef xCellStyle( new CellStyle( *this ) );
+ xCellStyle->importStyle( rStrm );
+ insertCellStyle( xCellStyle );
+ return xCellStyle;
+}
+
+void CellStyleBuffer::finalizeImport()
+{
+ // calculate final names of all styles
+ typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap;
+ CellStyleNameMap aCellStyles;
+ CellStyleVector aConflictNameStyles;
+
+ /* First, reserve style names that are built-in in Calc. This causes that
+ imported cell styles get different unused names and thus do not try to
+ overwrite these built-in styles. For BIFF4 workbooks (which contain a
+ separate list of cell styles per sheet), reserve all existing styles if
+ current sheet is not the first sheet (this styles buffer will be
+ constructed again for every new sheet). This will create unique names
+ for styles in different sheets with the same name. Assuming that the
+ BIFF4W import filter is never used to import from clipboard... */
+ bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0);
+ try
+ {
+ // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess...
+ Reference< XIndexAccess > xStyleFamilyIA( getStyleFamily( false ), UNO_QUERY_THROW );
+ for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex )
+ {
+ Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW );
+ if( bReserveAll || !xStyle->isUserDefined() )
+ {
+ Reference< XNamed > xStyleName( xStyle, UNO_QUERY_THROW );
+ // create an empty entry by using ::std::map<>::operator[]
+ aCellStyles[ xStyleName->getName() ];
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ /* Calculate names of built-in styles. Store styles with reserved names
+ in the aConflictNameStyles list. */
+ for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt )
+ {
+ const CellStyleModel& rModel = (*aIt)->getModel();
+ OUString aStyleName = lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel );
+ OSL_ENSURE( bReserveAll || (aCellStyles.count( aStyleName ) == 0),
+ "CellStyleBuffer::finalizeImport - multiple styles with equal built-in identifier" );
+ if( aCellStyles.count( aStyleName ) > 0 )
+ aConflictNameStyles.push_back( *aIt );
+ else
+ aCellStyles[ aStyleName ] = *aIt;
+ }
+
+ /* Calculate names of user defined styles. Store styles with reserved
+ names in the aConflictNameStyles list. */
+ for( CellStyleVector::iterator aIt = maUserStyles.begin(), aEnd = maUserStyles.end(); aIt != aEnd; ++aIt )
+ {
+ const CellStyleModel& rModel = (*aIt)->getModel();
+ // #i1624# #i1768# ignore unnamed user styles
+ if( rModel.maName.getLength() > 0 )
+ {
+ if( aCellStyles.count( rModel.maName ) > 0 )
+ aConflictNameStyles.push_back( *aIt );
+ else
+ aCellStyles[ rModel.maName ] = *aIt;
+ }
+ }
+
+ // find unused names for all styles with conflicting names
+ for( CellStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
+ {
+ const CellStyleModel& rModel = (*aIt)->getModel();
+ OUString aUnusedName;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aUnusedName = OUStringBuffer( rModel.maName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear();
+ }
+ while( aCellStyles.count( aUnusedName ) > 0 );
+ aCellStyles[ aUnusedName ] = *aIt;
+ }
+
+ // set final names and create user-defined and modified built-in cell styles
+ aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport );
+}
+
+sal_Int32 CellStyleBuffer::getDefaultXfId() const
+{
+ return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1;
+}
+
+OUString CellStyleBuffer::getDefaultStyleName() const
+{
+ return createCellStyle( mxDefStyle );
+}
+
+OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const
+{
+ return createCellStyle( maStylesByXf.get( nXfId ) );
+}
+
+// private --------------------------------------------------------------------
+
+void CellStyleBuffer::insertCellStyle( CellStyleRef xCellStyle )
+{
+ const CellStyleModel& rModel = xCellStyle->getModel();
+ if( rModel.mnXfId >= 0 )
+ {
+ // insert into the built-in map or user defined map
+ (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle );
+
+ // insert into the XF identifier map
+ OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" );
+ maStylesByXf[ rModel.mnXfId ] = xCellStyle;
+
+ // remember default cell style
+ if( rModel.isDefaultStyle() )
+ mxDefStyle = xCellStyle;
+ }
+}
+
+OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle ) const
+{
+ if( rxCellStyle.get() )
+ {
+ rxCellStyle->createCellStyle();
+ const OUString& rStyleName = rxCellStyle->getFinalStyleName();
+ if( rStyleName.getLength() > 0 )
+ return rStyleName;
+ }
+ // on error: fallback to default style
+ return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() );
+}
+
+// ============================================================================
+
+AutoFormatModel::AutoFormatModel() :
+ mnAutoFormatId( 0 ),
+ mbApplyNumFmt( false ),
+ mbApplyFont( false ),
+ mbApplyAlignment( false ),
+ mbApplyBorder( false ),
+ mbApplyFill( false ),
+ mbApplyProtection( false )
+{
+}
+
+// ============================================================================
+
+StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maPalette( rHelper ),
+ maNumFmts( rHelper ),
+ maCellStyles( rHelper )
+{
+}
+
+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 );
+}
+
+NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs )
+{
+ return maNumFmts.importNumFmt( rAttribs );
+}
+
+CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs )
+{
+ return maCellStyles.importCellStyle( rAttribs );
+}
+
+void StylesBuffer::importPaletteColor( SequenceInputStream& rStrm )
+{
+ maPalette.importPaletteColor( rStrm );
+}
+
+void StylesBuffer::importNumFmt( SequenceInputStream& rStrm )
+{
+ maNumFmts.importNumFmt( rStrm );
+}
+
+void StylesBuffer::importCellStyle( SequenceInputStream& rStrm )
+{
+ maCellStyles.importCellStyle( rStrm );
+}
+
+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 ) );
+ xXf->importXf( rStrm );
+
+ XfRef xCellXf, xStyleXf;
+ (xXf->isCellXf() ? xCellXf : xStyleXf) = xXf;
+ maCellXfs.push_back( xCellXf );
+ maStyleXfs.push_back( xStyleXf );
+}
+
+void StylesBuffer::importStyle( BiffInputStream& rStrm )
+{
+ maCellStyles.importStyle( rStrm );
+}
+
+void StylesBuffer::importPalette( const Any& rPalette )
+{
+ maPalette.importPalette( rPalette );
+}
+
+void StylesBuffer::finalizeImport()
+{
+ // fonts first, are needed to finalize unit converter and XFs below
+ maFonts.forEachMem( &Font::finalizeImport );
+ // finalize unit coefficients 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
+ maStyleXfs.forEachMem( &Xf::finalizeImport );
+ maCellXfs.forEachMem( &Xf::finalizeImport );
+ // built-in and user defined cell styles
+ maCellStyles.finalizeImport();
+ // differential formatting (for conditional formatting)
+ maDxfs.forEachMem( &Dxf::finalizeImport );
+}
+
+sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const
+{
+ return maPalette.getColor( nPaletteIdx );
+}
+
+FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const
+{
+ return maFonts.get( nFontId );
+}
+
+BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const
+{
+ return maBorders.get( nBorderId );
+}
+
+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( maCellStyles.getDefaultXfId() ).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 FontModel& StylesBuffer::getDefaultFontModel() const
+{
+ FontRef xDefFont = getDefaultFont();
+ return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel();
+}
+
+bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const
+{
+ if( nBorderId1 == nBorderId2 )
+ return true;
+
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ // in OOXML, borders are assumed to be unique
+ return false;
+
+ case FILTER_BIFF:
+ {
+ // in BIFF, a new border entry has been created for every XF
+ const Border* pBorder1 = maBorders.get( nBorderId1 ).get();
+ const Border* pBorder2 = maBorders.get( nBorderId2 ).get();
+ return pBorder1 && pBorder2 && (pBorder1->getApiData() == pBorder2->getApiData());
+ }
+
+ case FILTER_UNKNOWN:
+ break;
+ }
+ return false;
+}
+
+bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const
+{
+ if( nFillId1 == nFillId2 )
+ return true;
+
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ // in OOXML, fills are assumed to be unique
+ return false;
+
+ case FILTER_BIFF:
+ {
+ // in BIFF, a new fill entry has been created for every XF
+ const Fill* pFill1 = maFills.get( nFillId1 ).get();
+ const Fill* pFill2 = maFills.get( nFillId2 ).get();
+ return pFill1 && pFill2 && (pFill1->getApiData() == pFill2->getApiData());
+ }
+
+ case FILTER_UNKNOWN:
+ break;
+ }
+ return false;
+}
+
+OUString StylesBuffer::getDefaultStyleName() const
+{
+ return maCellStyles.getDefaultStyleName();
+}
+
+OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const
+{
+ return maCellStyles.createCellStyle( nXfId );
+}
+
+OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
+{
+ OUString& rStyleName = maDxfStyles[ nDxfId ];
+ if( rStyleName.getLength() == 0 )
+ {
+ if( Dxf* pDxf = maDxfs.get( nDxfId ).get() )
+ {
+ rStyleName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear();
+ // create the style sheet (this may change rStyleName if such a style already exists)
+ Reference< XStyle > xStyle = createStyleObject( rStyleName, false );
+ // write style formatting properties
+ PropertySet aPropSet( xStyle );
+ pDxf->writeToPropertySet( aPropSet );
+ }
+ // on error: fallback to default style
+ if( rStyleName.getLength() == 0 )
+ rStyleName = maCellStyles.getDefaultStyleName();
+ }
+ return rStyleName;
+}
+
+void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const
+{
+ if( Font* pFont = maFonts.get( nFontId ).get() )
+ pFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL );
+}
+
+void StylesBuffer::writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const
+{
+ maNumFmts.writeToPropertyMap( rPropMap, nNumFmtId );
+}
+
+void StylesBuffer::writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const
+{
+ if( Border* pBorder = maBorders.get( nBorderId ).get() )
+ pBorder->writeToPropertyMap( rPropMap );
+}
+
+void StylesBuffer::writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const
+{
+ if( Fill* pFill = maFills.get( nFillId ).get() )
+ pFill->writeToPropertyMap( rPropMap );
+}
+
+void StylesBuffer::writeCellXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const
+{
+ if( Xf* pXf = maCellXfs.get( nXfId ).get() )
+ pXf->writeToPropertyMap( rPropMap );
+}
+
+void StylesBuffer::writeStyleXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const
+{
+ if( Xf* pXf = maStyleXfs.get( nXfId ).get() )
+ pXf->writeToPropertyMap( rPropMap );
+}
+
+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 );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/stylesfragment.cxx b/oox/source/xls/stylesfragment.cxx
new file mode 100644
index 000000000000..c890196dc518
--- /dev/null
+++ b/oox/source/xls/stylesfragment.cxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/stylesfragment.hxx"
+
+#include "oox/helper/attributelist.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+IndexedColorsContext::IndexedColorsContext( WorkbookFragmentBase& rFragment ) :
+ WorkbookContextBase( rFragment )
+{
+}
+
+ContextHandlerRef IndexedColorsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( indexedColors ):
+ if( nElement == XLS_TOKEN( rgbColor ) ) getStyles().importPaletteColor( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef IndexedColorsContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_INDEXEDCOLORS:
+ if( nRecId == BIFF12_ID_RGBCOLOR ) getStyles().importPaletteColor( rStrm );
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ContextHandlerRef FontContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( mxFont.get() )
+ mxFont->importAttribs( nElement, rAttribs );
+ return 0;
+}
+
+// ============================================================================
+
+void BorderContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( mxBorder.get() && (getCurrentElement() == XLS_TOKEN( border )) )
+ mxBorder->importBorder( rAttribs );
+}
+
+ContextHandlerRef BorderContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( mxBorder.get() ) switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( border ):
+ mxBorder->importStyle( nElement, rAttribs );
+ return this;
+
+ default:
+ if( nElement == XLS_TOKEN( color ) )
+ mxBorder->importColor( getCurrentElement(), rAttribs );
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ContextHandlerRef FillContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( mxFill.get() ) switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( fill ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( patternFill ): mxFill->importPatternFill( rAttribs ); return this;
+ case XLS_TOKEN( gradientFill ): mxFill->importGradientFill( rAttribs ); return this;
+ }
+ break;
+ case XLS_TOKEN( patternFill ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( fgColor ): mxFill->importFgColor( rAttribs ); break;
+ case XLS_TOKEN( bgColor ): mxFill->importBgColor( rAttribs ); break;
+ }
+ break;
+ case XLS_TOKEN( gradientFill ):
+ if( nElement == XLS_TOKEN( stop ) )
+ {
+ mfGradPos = rAttribs.getDouble( XML_position, -1.0 );
+ return this;
+ }
+ break;
+ case XLS_TOKEN( stop ):
+ if( nElement == XLS_TOKEN( color ) )
+ mxFill->importColor( rAttribs, mfGradPos );
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+void XfContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( mxXf.get() && (getCurrentElement() == XLS_TOKEN( xf )) )
+ mxXf->importXf( rAttribs, mbCellXf );
+}
+
+ContextHandlerRef XfContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( mxXf.get() ) switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( xf ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( alignment ): mxXf->importAlignment( rAttribs ); break;
+ case XLS_TOKEN( protection ): mxXf->importProtection( rAttribs ); break;
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+ContextHandlerRef DxfContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( mxDxf.get() ) switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( dxf ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( font ): return new FontContext( *this, mxDxf->createFont() );
+ case XLS_TOKEN( border ): return new BorderContext( *this, mxDxf->createBorder() );
+ case XLS_TOKEN( fill ): return new FillContext( *this, mxDxf->createFill() );
+
+ case XLS_TOKEN( numFmt ): mxDxf->importNumFmt( rAttribs ); break;
+#if 0
+ case XLS_TOKEN( alignment ): mxDxf->importAlignment( rAttribs ); break;
+ case XLS_TOKEN( protection ): mxDxf->importProtection( rAttribs ); break;
+#endif
+ }
+ break;
+ }
+ return 0;
+}
+
+// ============================================================================
+
+StylesFragment::StylesFragment( const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ WorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+ContextHandlerRef StylesFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( styleSheet ) ) return this;
+ break;
+
+ case XLS_TOKEN( styleSheet ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( colors ):
+ case XLS_TOKEN( numFmts ):
+ case XLS_TOKEN( fonts ):
+ case XLS_TOKEN( borders ):
+ case XLS_TOKEN( fills ):
+ case XLS_TOKEN( cellXfs ):
+ case XLS_TOKEN( cellStyleXfs ):
+ case XLS_TOKEN( dxfs ):
+ case XLS_TOKEN( cellStyles ): return this;
+ }
+ break;
+
+ case XLS_TOKEN( colors ):
+ if( nElement == XLS_TOKEN( indexedColors ) ) return new IndexedColorsContext( *this );
+ break;
+ case XLS_TOKEN( numFmts ):
+ if( nElement == XLS_TOKEN( numFmt ) ) getStyles().importNumFmt( rAttribs );
+ break;
+ case XLS_TOKEN( fonts ):
+ if( nElement == XLS_TOKEN( font ) ) return new FontContext( *this, getStyles().createFont() );
+ break;
+ case XLS_TOKEN( borders ):
+ if( nElement == XLS_TOKEN( border ) ) return new BorderContext( *this, getStyles().createBorder() );
+ break;
+ case XLS_TOKEN( fills ):
+ if( nElement == XLS_TOKEN( fill ) ) return new FillContext( *this, getStyles().createFill() );
+ break;
+ case XLS_TOKEN( cellXfs ):
+ if( nElement == XLS_TOKEN( xf ) ) return new XfContext( *this, getStyles().createCellXf(), true );
+ break;
+ case XLS_TOKEN( cellStyleXfs ):
+ if( nElement == XLS_TOKEN( xf ) ) return new XfContext( *this, getStyles().createStyleXf(), false );
+ break;
+ case XLS_TOKEN( dxfs ):
+ if( nElement == XLS_TOKEN( dxf ) ) return new DxfContext( *this, getStyles().createDxf() );
+ break;
+ case XLS_TOKEN( cellStyles ):
+ if( nElement == XLS_TOKEN( cellStyle ) ) getStyles().importCellStyle( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef StylesFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_STYLESHEET ) return this;
+ break;
+
+ case BIFF12_ID_STYLESHEET:
+ switch( nRecId )
+ {
+ case BIFF12_ID_COLORS:
+ case BIFF12_ID_NUMFMTS:
+ case BIFF12_ID_FONTS:
+ case BIFF12_ID_BORDERS:
+ case BIFF12_ID_FILLS:
+ case BIFF12_ID_CELLXFS:
+ case BIFF12_ID_CELLSTYLEXFS:
+ case BIFF12_ID_DXFS:
+ case BIFF12_ID_CELLSTYLES: return this;
+ }
+ break;
+
+ case BIFF12_ID_COLORS:
+ if( nRecId == BIFF12_ID_INDEXEDCOLORS ) return new IndexedColorsContext( *this );
+ break;
+ case BIFF12_ID_NUMFMTS:
+ if( nRecId == BIFF12_ID_NUMFMT ) getStyles().importNumFmt( rStrm );
+ break;
+ case BIFF12_ID_FONTS:
+ if( nRecId == BIFF12_ID_FONT ) getStyles().createFont()->importFont( rStrm );
+ break;
+ case BIFF12_ID_BORDERS:
+ if( nRecId == BIFF12_ID_BORDER ) getStyles().createBorder()->importBorder( rStrm );
+ break;
+ case BIFF12_ID_FILLS:
+ if( nRecId == BIFF12_ID_FILL ) getStyles().createFill()->importFill( rStrm );
+ break;
+ case BIFF12_ID_CELLXFS:
+ if( nRecId == BIFF12_ID_XF ) getStyles().createCellXf()->importXf( rStrm, true );
+ break;
+ case BIFF12_ID_CELLSTYLEXFS:
+ if( nRecId == BIFF12_ID_XF ) getStyles().createStyleXf()->importXf( rStrm, false );
+ break;
+ case BIFF12_ID_DXFS:
+ if( nRecId == BIFF12_ID_DXF ) getStyles().createDxf()->importDxf( rStrm );
+ break;
+ case BIFF12_ID_CELLSTYLES:
+ if( nRecId == BIFF12_ID_CELLSTYLE ) getStyles().importCellStyle( rStrm );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* StylesFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_BORDERS, BIFF12_ID_BORDERS + 1 },
+ { BIFF12_ID_CELLSTYLES, BIFF12_ID_CELLSTYLES + 1 },
+ { BIFF12_ID_CELLSTYLEXFS, BIFF12_ID_CELLSTYLEXFS + 1 },
+ { BIFF12_ID_CELLXFS, BIFF12_ID_CELLXFS + 1 },
+ { BIFF12_ID_COLORS, BIFF12_ID_COLORS + 1 },
+ { BIFF12_ID_DXFS, BIFF12_ID_DXFS + 1 },
+ { BIFF12_ID_FILLS, BIFF12_ID_FILLS + 1 },
+ { BIFF12_ID_FONTS, BIFF12_ID_FONTS + 1 },
+ { BIFF12_ID_INDEXEDCOLORS, BIFF12_ID_INDEXEDCOLORS + 1 },
+ { BIFF12_ID_MRUCOLORS, BIFF12_ID_MRUCOLORS + 1 },
+ { BIFF12_ID_NUMFMTS, BIFF12_ID_NUMFMTS + 1 },
+ { BIFF12_ID_STYLESHEET, BIFF12_ID_STYLESHEET + 1 },
+ { BIFF12_ID_TABLESTYLES, BIFF12_ID_TABLESTYLES + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void StylesFragment::finalizeImport()
+{
+ getStyles().finalizeImport();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/tablebuffer.cxx b/oox/source/xls/tablebuffer.cxx
new file mode 100644
index 000000000000..91fad31e6ee4
--- /dev/null
+++ b/oox/source/xls/tablebuffer.cxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/tablebuffer.hxx"
+
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+TableModel::TableModel() :
+ mnId( -1 ),
+ mnType( XML_worksheet ),
+ mnHeaderRows( 1 ),
+ mnTotalsRows( 0 )
+{
+}
+
+// ============================================================================
+
+Table::Table( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maAutoFilters( rHelper ),
+ mnTokenIndex( -1 )
+{
+}
+
+void Table::importTable( const AttributeList& rAttribs, sal_Int16 nSheet )
+{
+ getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, rAttribs.getString( XML_ref, OUString() ), nSheet );
+ maModel.maProgName = rAttribs.getXString( XML_name, OUString() );
+ maModel.maDisplayName = rAttribs.getXString( XML_displayName, OUString() );
+ maModel.mnId = rAttribs.getInteger( XML_id, -1 );
+ maModel.mnType = rAttribs.getToken( XML_tableType, XML_worksheet );
+ maModel.mnHeaderRows = rAttribs.getInteger( XML_headerRowCount, 1 );
+ maModel.mnTotalsRows = rAttribs.getInteger( XML_totalsRowCount, 0 );
+}
+
+void Table::importTable( SequenceInputStream& rStrm, sal_Int16 nSheet )
+{
+ BinRange aBinRange;
+ sal_Int32 nType;
+ rStrm >> aBinRange >> nType >> maModel.mnId >> maModel.mnHeaderRows >> maModel.mnTotalsRows;
+ rStrm.skip( 32 );
+ rStrm >> maModel.maProgName >> maModel.maDisplayName;
+
+ getAddressConverter().convertToCellRangeUnchecked( maModel.maRange, aBinRange, nSheet );
+ static const sal_Int32 spnTypes[] = { XML_worksheet, XML_TOKEN_INVALID, XML_TOKEN_INVALID, XML_queryTable };
+ maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
+}
+
+void Table::finalizeImport()
+{
+ // create database range
+ if( (maModel.mnId > 0) && (maModel.maDisplayName.getLength() > 0) ) try
+ {
+ maDBRangeName = maModel.maDisplayName;
+ Reference< XDatabaseRange > xDatabaseRange( createDatabaseRangeObject( maDBRangeName, maModel.maRange ), UNO_SET_THROW );
+ maDestRange = xDatabaseRange->getDataArea();
+
+ // get formula token index of the database range
+ PropertySet aPropSet( xDatabaseRange );
+ if( !aPropSet.getProperty( mnTokenIndex, PROP_TokenIndex ) )
+ mnTokenIndex = -1;
+
+ // filter settings
+ maAutoFilters.finalizeImport( xDatabaseRange );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "Table::finalizeImport - cannot create database range" );
+ }
+}
+
+// ============================================================================
+
+TableBuffer::TableBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+Table& TableBuffer::createTable()
+{
+ TableVector::value_type xTable( new Table( *this ) );
+ maTables.push_back( xTable );
+ return *xTable;
+}
+
+void TableBuffer::finalizeImport()
+{
+ // map all tables by identifier and display name
+ for( TableVector::iterator aIt = maTables.begin(), aEnd = maTables.end(); aIt != aEnd; ++aIt )
+ insertTableToMaps( *aIt );
+ // finalize all valid tables
+ maIdTables.forEachMem( &Table::finalizeImport );
+}
+
+TableRef TableBuffer::getTable( sal_Int32 nTableId ) const
+{
+ return maIdTables.get( nTableId );
+}
+
+TableRef TableBuffer::getTable( const OUString& rDispName ) const
+{
+ return maNameTables.get( rDispName );
+}
+
+// private --------------------------------------------------------------------
+
+void TableBuffer::insertTableToMaps( const TableRef& rxTable )
+{
+ sal_Int32 nTableId = rxTable->getTableId();
+ const OUString& rDispName = rxTable->getDisplayName();
+ if( (nTableId > 0) && (rDispName.getLength() > 0) )
+ {
+ OSL_ENSURE( !maIdTables.has( nTableId ), "TableBuffer::insertTableToMaps - multiple table identifier" );
+ maIdTables[ nTableId ] = rxTable;
+ OSL_ENSURE( !maNameTables.has( rDispName ), "TableBuffer::insertTableToMaps - multiple table name" );
+ maNameTables[ rDispName ] = rxTable;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/tablefragment.cxx b/oox/source/xls/tablefragment.cxx
new file mode 100644
index 000000000000..37503f8577fb
--- /dev/null
+++ b/oox/source/xls/tablefragment.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/tablefragment.hxx"
+
+#include "oox/xls/autofilterbuffer.hxx"
+#include "oox/xls/autofiltercontext.hxx"
+#include "oox/xls/tablebuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+TableFragment::TableFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath ),
+ mrTable( getTables().createTable() )
+{
+}
+
+ContextHandlerRef TableFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( table ) )
+ {
+ mrTable.importTable( rAttribs, getSheetIndex() );
+ return this;
+ }
+ break;
+ case XLS_TOKEN( table ):
+ if( nElement == XLS_TOKEN( autoFilter ) )
+ return new AutoFilterContext( *this, mrTable.createAutoFilter() );
+ break;
+ }
+ return 0;
+}
+
+ContextHandlerRef TableFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_TABLE )
+ {
+ mrTable.importTable( rStrm, getSheetIndex() );
+ return this;
+ }
+ break;
+ case BIFF12_ID_TABLE:
+ if( nRecId == BIFF12_ID_AUTOFILTER )
+ return new AutoFilterContext( *this, mrTable.createAutoFilter() );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* TableFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_AUTOFILTER, BIFF12_ID_AUTOFILTER + 1 },
+ { BIFF12_ID_CUSTOMFILTERS, BIFF12_ID_CUSTOMFILTERS + 1 },
+ { BIFF12_ID_DISCRETEFILTERS, BIFF12_ID_DISCRETEFILTERS + 1 },
+ { BIFF12_ID_FILTERCOLUMN, BIFF12_ID_FILTERCOLUMN + 1 },
+ { BIFF12_ID_TABLE, BIFF12_ID_TABLE + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/themebuffer.cxx b/oox/source/xls/themebuffer.cxx
new file mode 100644
index 000000000000..c3e016327133
--- /dev/null
+++ b/oox/source/xls/themebuffer.cxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/themebuffer.hxx"
+
+#include "oox/xls/stylesbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using ::oox::drawingml::ClrScheme;
+
+// ============================================================================
+
+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 ),
+ mxDefFontModel( new FontModel )
+{
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ //! TODO: locale dependent font name
+ mxDefFontModel->maName = CREATE_OUSTRING( "Cambria" );
+ mxDefFontModel->mfHeight = 11.0;
+ break;
+ case FILTER_BIFF:
+ //! TODO: BIFF dependent font name
+ mxDefFontModel->maName = CREATE_OUSTRING( "Arial" );
+ mxDefFontModel->mfHeight = 10.0;
+ break;
+ case FILTER_UNKNOWN: break;
+ }
+}
+
+ThemeBuffer::~ThemeBuffer()
+{
+}
+
+sal_Int32 ThemeBuffer::getColorByToken( sal_Int32 nToken ) const
+{
+ sal_Int32 nColor = 0;
+ return getClrScheme().getColor( nToken, nColor ) ? nColor : API_RGB_TRANSPARENT;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/unitconverter.cxx b/oox/source/xls/unitconverter.cxx
new file mode 100644
index 000000000000..1b5f1e9b072c
--- /dev/null
+++ b/oox/source/xls/unitconverter.cxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/unitconverter.hxx"
+
+#include <com/sun/star/awt/DeviceInfo.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XFont.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <rtl/math.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const double MM100_PER_INCH = 2540.0;
+const double MM100_PER_POINT = MM100_PER_INCH / 72.0;
+const double MM100_PER_TWIP = MM100_PER_POINT / 20.0;
+const double MM100_PER_EMU = 1.0 / 360.0;
+
+// ----------------------------------------------------------------------------
+
+/** Returns true, if the passed year is a leap year. */
+inline sal_Int32 lclIsLeapYear( sal_Int32 nYear )
+{
+ return ((nYear % 4) == 0) && (((nYear % 100) != 0) || ((nYear % 400) == 0));
+}
+
+void lclSkipYearBlock( sal_Int32& ornDays, sal_uInt16& ornYear, sal_Int32 nDaysInBlock, sal_Int32 nYearsPerBlock, sal_Int32 nMaxBlocks )
+{
+ sal_Int32 nBlocks = ::std::min< sal_Int32 >( ornDays / nDaysInBlock, nMaxBlocks );
+ ornYear = static_cast< sal_uInt16 >( ornYear + nYearsPerBlock * nBlocks );
+ ornDays -= nBlocks * nDaysInBlock;
+}
+
+/** Returns the number of days before the passed date, starting from the null
+ date 0000-Jan-01, using standard leap year conventions. */
+sal_Int32 lclGetDays( const Date& rDate )
+{
+ // number of days in all full years before passed date including all leap days
+ sal_Int32 nDays = rDate.Year * 365 + ((rDate.Year + 3) / 4) - ((rDate.Year + 99) / 100) + ((rDate.Year + 399) / 400);
+ OSL_ENSURE( (1 <= rDate.Month) && (rDate.Month <= 12), "lclGetDays - invalid month" );
+ OSL_ENSURE( (1 <= rDate.Day) && (rDate.Day <= 31), "lclGetDays - invalid day" ); // yes, this is weak...
+ if( (1 <= rDate.Month) && (rDate.Month <= 12) )
+ {
+ // number of days at start of month jan feb mar apr may jun jul aug sep oct nov dec
+ static const sal_Int32 spnCumDays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+ // add number of days in full months before passed date
+ nDays += spnCumDays[ rDate.Month - 1 ];
+ // add number of days from passed date (this adds one day too much)
+ nDays += rDate.Day;
+ /* Remove the one day added too much if there is no leap day before
+ the passed day in the passed year. This means: remove the day, if
+ we are in january or february (leap day not reached if existing),
+ or if the passed year is not a leap year. */
+ if( (rDate.Month < 3) || !lclIsLeapYear( rDate.Year ) )
+ --nDays;
+ }
+ return nDays;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+UnitConverter::UnitConverter( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper ),
+ maCoeffs( UNIT_ENUM_SIZE, 1.0 ),
+ mnNullDate( lclGetDays( Date( 30, 12, 1899 ) ) )
+{
+ // initialize constant and default coefficients
+ const DeviceInfo& rDeviceInfo = getBaseFilter().getGraphicHelper().getDeviceInfo();
+ maCoeffs[ UNIT_INCH ] = MM100_PER_INCH;
+ maCoeffs[ UNIT_POINT ] = MM100_PER_POINT;
+ maCoeffs[ UNIT_TWIP ] = MM100_PER_TWIP;
+ maCoeffs[ UNIT_EMU ] = MM100_PER_EMU;
+ maCoeffs[ UNIT_SCREENX ] = (rDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / rDeviceInfo.PixelPerMeterX) : 50.0;
+ maCoeffs[ UNIT_SCREENY ] = (rDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / rDeviceInfo.PixelPerMeterY) : 50.0;
+ maCoeffs[ UNIT_REFDEVX ] = 12.5; // default: 1 px = 0.125 mm
+ maCoeffs[ UNIT_REFDEVY ] = 12.5; // default: 1 px = 0.125 mm
+ maCoeffs[ UNIT_DIGIT ] = 200.0; // default: 1 digit = 2 mm
+ maCoeffs[ UNIT_SPACE ] = 100.0; // default 1 space = 1 mm
+
+ // error code maps
+ addErrorCode( BIFF_ERR_NULL, CREATE_OUSTRING( "#NULL!" ) );
+ addErrorCode( BIFF_ERR_DIV0, CREATE_OUSTRING( "#DIV/0!" ) );
+ addErrorCode( BIFF_ERR_VALUE, CREATE_OUSTRING( "#VALUE!" ) );
+ addErrorCode( BIFF_ERR_REF, CREATE_OUSTRING( "#REF!" ) );
+ addErrorCode( BIFF_ERR_NAME, CREATE_OUSTRING( "#NAME?" ) );
+ addErrorCode( BIFF_ERR_NUM, CREATE_OUSTRING( "#NUM!" ) );
+ addErrorCode( BIFF_ERR_NA, CREATE_OUSTRING( "#NA" ) );
+}
+
+void UnitConverter::finalizeImport()
+{
+ PropertySet aDocProps( getDocument() );
+ Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY );
+ if( xDevice.is() )
+ {
+ // get reference device metric first, needed to get character widths below
+ DeviceInfo aInfo = xDevice->getInfo();
+ maCoeffs[ UNIT_REFDEVX ] = 100000.0 / aInfo.PixelPerMeterX;
+ maCoeffs[ UNIT_REFDEVY ] = 100000.0 / aInfo.PixelPerMeterY;
+
+ // 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 >( scaleValue( aDesc.Height, UNIT_TWIP, UNIT_REFDEVX ) + 0.5 );
+ 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, scaleToMm100( xFont->getCharWidth( cChar ), UNIT_REFDEVX ) );
+ if( nDigitWidth > 0 )
+ maCoeffs[ UNIT_DIGIT ] = nDigitWidth;
+ // get width of space character
+ sal_Int32 nSpaceWidth = scaleToMm100( xFont->getCharWidth( ' ' ), UNIT_REFDEVX );
+ if( nSpaceWidth > 0 )
+ maCoeffs[ UNIT_SPACE ] = nSpaceWidth;
+ }
+ }
+ }
+}
+
+void UnitConverter::finalizeNullDate( const Date& rNullDate )
+{
+ // convert the nulldate to number of days since 0000-Jan-01
+ mnNullDate = lclGetDays( rNullDate );
+}
+
+// conversion -----------------------------------------------------------------
+
+double UnitConverter::scaleValue( double fValue, Unit eFromUnit, Unit eToUnit ) const
+{
+ return (eFromUnit == eToUnit) ? fValue : (fValue * getCoefficient( eFromUnit ) / getCoefficient( eToUnit ));
+}
+
+sal_Int32 UnitConverter::scaleToMm100( double fValue, Unit eUnit ) const
+{
+ return static_cast< sal_Int32 >( fValue * getCoefficient( eUnit ) + 0.5 );
+}
+
+double UnitConverter::scaleFromMm100( sal_Int32 nMm100, Unit eUnit ) const
+{
+ return static_cast< double >( nMm100 ) / getCoefficient( eUnit );
+}
+
+double UnitConverter::calcSerialFromDateTime( const DateTime& rDateTime ) const
+{
+ sal_Int32 nDays = lclGetDays( Date( rDateTime.Day, rDateTime.Month, rDateTime.Year ) ) - mnNullDate;
+ OSL_ENSURE( nDays >= 0, "UnitConverter::calcDateTimeSerial - invalid date" );
+ OSL_ENSURE( (rDateTime.Hours <= 23) && (rDateTime.Minutes <= 59) && (rDateTime.Seconds <= 59), "UnitConverter::calcDateTimeSerial - invalid time" );
+ return nDays + rDateTime.Hours / 24.0 + rDateTime.Minutes / 1440.0 + rDateTime.Seconds / 86400.0;
+}
+
+DateTime UnitConverter::calcDateTimeFromSerial( double fSerial ) const
+{
+ DateTime aDateTime( 0, 0, 0, 0, 1, 1, 0 );
+ double fDays = 0.0;
+ double fTime = modf( fSerial, &fDays );
+
+ // calculate date from number of days with O(1) complexity
+ sal_Int32 nDays = getLimitedValue< sal_Int32, double >( fDays + mnNullDate, 0, 3652424 );
+ // skip year 0, assumed to be a leap year. By starting at year 1, leap years can be handled easily
+ if( nDays >= 366 ) { ++aDateTime.Year; nDays -= 366; }
+ // skip full blocks of 400, 100, 4 years, and remaining full years
+ lclSkipYearBlock( nDays, aDateTime.Year, 400 * 365 + 97, 400, 24 );
+ lclSkipYearBlock( nDays, aDateTime.Year, 100 * 365 + 24, 100, 3 );
+ lclSkipYearBlock( nDays, aDateTime.Year, 4 * 365 + 1, 4, 24 );
+ lclSkipYearBlock( nDays, aDateTime.Year, 365, 1, 3 );
+ // skip full months of current year
+ static const sal_Int32 spnDaysInMonth[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ if( (nDays >= 59) && !lclIsLeapYear( aDateTime.Year ) ) ++nDays;
+ const sal_Int32* pnDaysInMonth = spnDaysInMonth;
+ while( *pnDaysInMonth >= nDays ) { ++aDateTime.Month; nDays -= *pnDaysInMonth; ++pnDaysInMonth; }
+ aDateTime.Day = static_cast< sal_uInt16 >( nDays + 1 );
+
+ // calculate time from fractional part of serial
+ sal_Int32 nTime = getLimitedValue< sal_Int32, double >( fTime * 86400, 0, 86399 );
+ aDateTime.Seconds = static_cast< sal_uInt16 >( nTime % 60 );
+ nTime /= 60;
+ aDateTime.Minutes = static_cast< sal_uInt16 >( nTime % 60 );
+ aDateTime.Hours = static_cast< sal_uInt16 >( nTime / 60 );
+
+ return aDateTime;
+}
+
+OUString UnitConverter::calcOoxErrorCode( sal_uInt8 nErrorCode ) const
+{
+ BiffErrorCodeMap::const_iterator aIt = maBiffErrCodes.find( nErrorCode );
+ return (aIt == maBiffErrCodes.end()) ? CREATE_OUSTRING( "#N/A" ) : aIt->second;
+}
+
+sal_uInt8 UnitConverter::calcBiffErrorCode( const OUString& rErrorCode ) const
+{
+ OoxErrorCodeMap::const_iterator aIt = maOoxErrCodes.find( rErrorCode );
+ return (aIt == maOoxErrCodes.end()) ? BIFF_ERR_NA : aIt->second;
+}
+
+void UnitConverter::addErrorCode( sal_uInt8 nErrorCode, const OUString& rErrorCode )
+{
+ maOoxErrCodes[ rErrorCode ] = nErrorCode;
+ maBiffErrCodes[ nErrorCode ] = rErrorCode;
+}
+
+double UnitConverter::getCoefficient( Unit eUnit ) const
+{
+ OSL_ENSURE( static_cast< size_t >( eUnit ) < UNIT_ENUM_SIZE, "UnitConverter::getCoefficient - invalid unit" );
+ return maCoeffs[ static_cast< size_t >( eUnit ) ];
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx
new file mode 100644
index 000000000000..c9658dd41cf9
--- /dev/null
+++ b/oox/source/xls/viewsettings.cxx
@@ -0,0 +1,823 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/viewsettings.hxx"
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/document/XViewDataSupplier.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/unitconverter.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::FilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
+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 BIFF12_PANE_FROZEN = 0x01;
+const sal_uInt8 BIFF12_PANE_FROZENNOSPLIT = 0x02;
+
+const sal_uInt16 BIFF12_SHEETVIEW_WINPROTECTED = 0x0001;
+const sal_uInt16 BIFF12_SHEETVIEW_SHOWFORMULAS = 0x0002;
+const sal_uInt16 BIFF12_SHEETVIEW_SHOWGRID = 0x0004;
+const sal_uInt16 BIFF12_SHEETVIEW_SHOWHEADINGS = 0x0008;
+const sal_uInt16 BIFF12_SHEETVIEW_SHOWZEROS = 0x0010;
+const sal_uInt16 BIFF12_SHEETVIEW_RIGHTTOLEFT = 0x0020;
+const sal_uInt16 BIFF12_SHEETVIEW_SELECTED = 0x0040;
+const sal_uInt16 BIFF12_SHEETVIEW_SHOWRULER = 0x0080;
+const sal_uInt16 BIFF12_SHEETVIEW_SHOWOUTLINE = 0x0100;
+const sal_uInt16 BIFF12_SHEETVIEW_DEFGRIDCOLOR = 0x0200;
+const sal_uInt16 BIFF12_SHEETVIEW_SHOWWHITESPACE = 0x0400;
+
+const sal_uInt16 BIFF12_CHARTSHEETVIEW_SELECTED = 0x0001;
+const sal_uInt16 BIFF12_CHARTSHEETVIEW_ZOOMTOFIT = 0x0002;
+
+const sal_uInt8 BIFF12_WBVIEW_HIDDEN = 0x01;
+const sal_uInt8 BIFF12_WBVIEW_MINIMIZED = 0x02;
+const sal_uInt8 BIFF12_WBVIEW_SHOWHORSCROLL = 0x08;
+const sal_uInt8 BIFF12_WBVIEW_SHOWVERSCROLL = 0x10;
+const sal_uInt8 BIFF12_WBVIEW_SHOWTABBAR = 0x20;
+const sal_uInt8 BIFF12_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.
+
+// ----------------------------------------------------------------------------
+
+/** Returns the OOXML pane identifier from the passed BIFF pane id. */
+sal_Int32 lclGetOoxPaneId( sal_Int32 nBiffPaneId, sal_Int32 nDefaultPaneId )
+{
+ static const sal_Int32 spnPaneIds[] = { XML_bottomRight, XML_topRight, XML_bottomLeft, XML_topLeft };
+ return STATIC_ARRAY_SELECT( spnPaneIds, nBiffPaneId, nDefaultPaneId );
+}
+
+} // namespace
+
+// ============================================================================
+
+PaneSelectionModel::PaneSelectionModel() :
+ mnActiveCellId( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+SheetViewModel::SheetViewModel() :
+ 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 ),
+ mbZoomToFit( false )
+{
+ maGridColor.setIndexed( OOX_COLOR_WINDOWTEXT );
+}
+
+bool SheetViewModel::isPageBreakPreview() const
+{
+ return mnViewType == XML_pageBreakPreview;
+}
+
+sal_Int32 SheetViewModel::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 SheetViewModel::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 );
+}
+
+sal_Int32 SheetViewModel::getGridColor( const FilterBase& rFilter ) const
+{
+ return mbDefGridColor ? API_RGB_TRANSPARENT : maGridColor.getColor( rFilter.getGraphicHelper() );
+}
+
+const PaneSelectionModel* SheetViewModel::getPaneSelection( sal_Int32 nPaneId ) const
+{
+ return maPaneSelMap.get( nPaneId ).get();
+}
+
+const PaneSelectionModel* SheetViewModel::getActiveSelection() const
+{
+ return getPaneSelection( mnActivePaneId );
+}
+
+PaneSelectionModel& SheetViewModel::createPaneSelection( sal_Int32 nPaneId )
+{
+ PaneSelectionModelMap::mapped_type& rxPaneSel = maPaneSelMap[ nPaneId ];
+ if( !rxPaneSel )
+ rxPaneSel.reset( new PaneSelectionModel );
+ return *rxPaneSel;
+}
+
+// ----------------------------------------------------------------------------
+
+SheetViewSettings::SheetViewSettings( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper )
+{
+}
+
+void SheetViewSettings::importSheetView( const AttributeList& rAttribs )
+{
+ SheetViewModel& rModel = *createSheetView();
+ rModel.maGridColor.setIndexed( rAttribs.getInteger( XML_colorId, OOX_COLOR_WINDOWTEXT ) );
+ rModel.maFirstPos = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_topLeftCell, OUString() ), getSheetIndex(), false );
+ rModel.mnWorkbookViewId = rAttribs.getToken( XML_workbookViewId, 0 );
+ rModel.mnViewType = rAttribs.getToken( XML_view, XML_normal );
+ rModel.mnCurrentZoom = rAttribs.getInteger( XML_zoomScale, 100 );
+ rModel.mnNormalZoom = rAttribs.getInteger( XML_zoomScaleNormal, 0 );
+ rModel.mnSheetLayoutZoom = rAttribs.getInteger( XML_zoomScaleSheetLayoutView, 0 );
+ rModel.mnPageLayoutZoom = rAttribs.getInteger( XML_zoomScalePageLayoutView, 0 );
+ rModel.mbSelected = rAttribs.getBool( XML_tabSelected, false );
+ rModel.mbRightToLeft = rAttribs.getBool( XML_rightToLeft, false );
+ rModel.mbDefGridColor = rAttribs.getBool( XML_defaultGridColor, true );
+ rModel.mbShowFormulas = rAttribs.getBool( XML_showFormulas, false );
+ rModel.mbShowGrid = rAttribs.getBool( XML_showGridLines, true );
+ rModel.mbShowHeadings = rAttribs.getBool( XML_showRowColHeaders, true );
+ rModel.mbShowZeros = rAttribs.getBool( XML_showZeros, true );
+ rModel.mbShowOutline = rAttribs.getBool( XML_showOutlineSymbols, true );
+}
+
+void SheetViewSettings::importPane( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing sheet view model" );
+ if( !maSheetViews.empty() )
+ {
+ SheetViewModel& rModel = *maSheetViews.back();
+ rModel.maSecondPos = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_topLeftCell, OUString() ), getSheetIndex(), false );
+ rModel.mnActivePaneId = rAttribs.getToken( XML_activePane, XML_topLeft );
+ rModel.mnPaneState = rAttribs.getToken( XML_state, XML_split );
+ rModel.mfSplitX = rAttribs.getDouble( XML_xSplit, 0.0 );
+ rModel.mfSplitY = rAttribs.getDouble( XML_ySplit, 0.0 );
+ }
+}
+
+void SheetViewSettings::importSelection( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importSelection - missing sheet view model" );
+ if( !maSheetViews.empty() )
+ {
+ // pane this selection belongs to
+ sal_Int32 nPaneId = rAttribs.getToken( XML_pane, XML_topLeft );
+ PaneSelectionModel& rSelData = maSheetViews.back()->createPaneSelection( nPaneId );
+ // cursor position
+ rSelData.maActiveCell = getAddressConverter().createValidCellAddress( rAttribs.getString( XML_activeCell, OUString() ), getSheetIndex(), false );
+ rSelData.mnActiveCellId = rAttribs.getInteger( XML_activeCellId, 0 );
+ // selection
+ rSelData.maSelection.clear();
+ getAddressConverter().convertToCellRangeList( rSelData.maSelection, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), false );
+ }
+}
+
+void SheetViewSettings::importChartSheetView( const AttributeList& rAttribs )
+{
+ SheetViewModel& rModel = *createSheetView();
+ rModel.mnWorkbookViewId = rAttribs.getToken( XML_workbookViewId, 0 );
+ rModel.mnCurrentZoom = rAttribs.getInteger( XML_zoomScale, 100 );
+ rModel.mbSelected = rAttribs.getBool( XML_tabSelected, false );
+ rModel.mbZoomToFit = rAttribs.getBool( XML_zoomToFit, false );
+}
+
+void SheetViewSettings::importSheetView( SequenceInputStream& rStrm )
+{
+ SheetViewModel& rModel = *createSheetView();
+ sal_uInt16 nFlags;
+ sal_Int32 nViewType;
+ BinAddress aFirstPos;
+ rStrm >> nFlags >> nViewType >> aFirstPos;
+ rModel.maGridColor.importColorId( rStrm );
+ rModel.mnCurrentZoom = rStrm.readuInt16();
+ rModel.mnNormalZoom = rStrm.readuInt16();
+ rModel.mnSheetLayoutZoom = rStrm.readuInt16();
+ rModel.mnPageLayoutZoom = rStrm.readuInt16();
+ rStrm >> rModel.mnWorkbookViewId;
+
+ rModel.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
+ static const sal_Int32 spnViewTypes[] = { XML_normal, XML_pageBreakPreview, XML_pageLayout };
+ rModel.mnViewType = STATIC_ARRAY_SELECT( spnViewTypes, nViewType, XML_normal );
+ rModel.mbSelected = getFlag( nFlags, BIFF12_SHEETVIEW_SELECTED );
+ rModel.mbRightToLeft = getFlag( nFlags, BIFF12_SHEETVIEW_RIGHTTOLEFT );
+ rModel.mbDefGridColor = getFlag( nFlags, BIFF12_SHEETVIEW_DEFGRIDCOLOR );
+ rModel.mbShowFormulas = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWFORMULAS );
+ rModel.mbShowGrid = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWGRID );
+ rModel.mbShowHeadings = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWHEADINGS );
+ rModel.mbShowZeros = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWZEROS );
+ rModel.mbShowOutline = getFlag( nFlags, BIFF12_SHEETVIEW_SHOWOUTLINE );
+}
+
+void SheetViewSettings::importPane( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing sheet view model" );
+ if( !maSheetViews.empty() )
+ {
+ SheetViewModel& rModel = *maSheetViews.back();
+
+ BinAddress aSecondPos;
+ sal_Int32 nActivePaneId;
+ sal_uInt8 nFlags;
+ rStrm >> rModel.mfSplitX >> rModel.mfSplitY >> aSecondPos >> nActivePaneId >> nFlags;
+
+ rModel.maSecondPos = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false );
+ rModel.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft );
+ rModel.mnPaneState = getFlagValue( nFlags, BIFF12_PANE_FROZEN, getFlagValue( nFlags, BIFF12_PANE_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split );
+ }
+}
+
+void SheetViewSettings::importSelection( SequenceInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importSelection - missing sheet view model" );
+ if( !maSheetViews.empty() )
+ {
+ // pane this selection belongs to
+ sal_Int32 nPaneId = rStrm.readInt32();
+ PaneSelectionModel& rPaneSel = maSheetViews.back()->createPaneSelection( lclGetOoxPaneId( nPaneId, -1 ) );
+ // cursor position
+ BinAddress aActiveCell;
+ rStrm >> aActiveCell >> rPaneSel.mnActiveCellId;
+ rPaneSel.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false );
+ // selection
+ BinRangeList aSelection;
+ rStrm >> aSelection;
+ rPaneSel.maSelection.clear();
+ getAddressConverter().convertToCellRangeList( rPaneSel.maSelection, aSelection, getSheetIndex(), false );
+ }
+}
+
+void SheetViewSettings::importChartSheetView( SequenceInputStream& rStrm )
+{
+ SheetViewModel& rModel = *createSheetView();
+ sal_uInt16 nFlags;
+ rStrm >> nFlags >> rModel.mnCurrentZoom >> rModel.mnWorkbookViewId;
+
+ rModel.mbSelected = getFlag( nFlags, BIFF12_CHARTSHEETVIEW_SELECTED );
+ rModel.mbZoomToFit = getFlag( nFlags, BIFF12_CHARTSHEETVIEW_ZOOMTOFIT );
+}
+
+void SheetViewSettings::importWindow2( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( maSheetViews.empty(), "SheetViewSettings::importWindow2 - multiple WINDOW2 records" );
+ SheetViewModel& rModel = *createSheetView();
+ if( getBiff() == BIFF2 )
+ {
+ rModel.mbShowFormulas = rStrm.readuInt8() != 0;
+ rModel.mbShowGrid = rStrm.readuInt8() != 0;
+ rModel.mbShowHeadings = rStrm.readuInt8() != 0;
+ rModel.mnPaneState = (rStrm.readuInt8() == 0) ? XML_split : XML_frozen;
+ rModel.mbShowZeros = rStrm.readuInt8() != 0;
+ BinAddress aFirstPos;
+ rStrm >> aFirstPos;
+ rModel.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
+ rModel.mbDefGridColor = rStrm.readuInt8() != 0;
+ rModel.maGridColor.importColorRgb( rStrm );
+ }
+ else
+ {
+ sal_uInt16 nFlags;
+ BinAddress aFirstPos;
+ rStrm >> nFlags >> aFirstPos;
+
+ rModel.maFirstPos = getAddressConverter().createValidCellAddress( aFirstPos, getSheetIndex(), false );
+ rModel.mnPaneState = getFlagValue( nFlags, BIFF_WINDOW2_FROZEN, getFlagValue( nFlags, BIFF_WINDOW2_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split );
+ rModel.mbSelected = getFlag( nFlags, BIFF_WINDOW2_SELECTED );
+ rModel.mbRightToLeft = getFlag( nFlags, BIFF_WINDOW2_RIGHTTOLEFT );
+ rModel.mbDefGridColor = getFlag( nFlags, BIFF_WINDOW2_DEFGRIDCOLOR );
+ rModel.mbShowFormulas = getFlag( nFlags, BIFF_WINDOW2_SHOWFORMULAS );
+ rModel.mbShowGrid = getFlag( nFlags, BIFF_WINDOW2_SHOWGRID );
+ rModel.mbShowHeadings = getFlag( nFlags, BIFF_WINDOW2_SHOWHEADINGS );
+ rModel.mbShowZeros = getFlag( nFlags, BIFF_WINDOW2_SHOWZEROS );
+ rModel.mbShowOutline = getFlag( nFlags, BIFF_WINDOW2_SHOWOUTLINE );
+
+ if( getBiff() == BIFF8 )
+ {
+ rModel.mnViewType = getFlagValue( nFlags, BIFF_WINDOW2_PAGEBREAKMODE, XML_pageBreakPreview, XML_normal );
+
+ rModel.maGridColor.importColorId( rStrm );
+ // zoom data not included in chart sheets
+ if( (getSheetType() != SHEETTYPE_CHARTSHEET) && (rStrm.getRemaining() >= 6) )
+ {
+ rStrm.skip( 2 );
+ sal_uInt16 nPageZoom, nNormalZoom;
+ rStrm >> nPageZoom >> nNormalZoom;
+ rModel.mnSheetLayoutZoom = nPageZoom;
+ rModel.mnNormalZoom = nNormalZoom;
+ }
+ }
+ else
+ {
+ rModel.maGridColor.importColorRgb( rStrm );
+ }
+ }
+}
+
+void SheetViewSettings::importPane( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing leading WINDOW2 record" );
+ if( !maSheetViews.empty() )
+ {
+ sal_uInt8 nActivePaneId;
+ sal_uInt16 nSplitX, nSplitY;
+ BinAddress aSecondPos;
+ rStrm >> nSplitX >> nSplitY >> aSecondPos >> nActivePaneId;
+
+ SheetViewModel& rModel = *maSheetViews.back();
+ rModel.mfSplitX = nSplitX;
+ rModel.mfSplitY = nSplitY;
+ rModel.maSecondPos = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false );
+ rModel.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft );
+ }
+}
+
+void SheetViewSettings::importScl( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importScl - missing leading WINDOW2 record" );
+ if( !maSheetViews.empty() )
+ {
+ sal_uInt16 nNum, nDenom;
+ rStrm >> nNum >> nDenom;
+ OSL_ENSURE( nDenom > 0, "SheetViewSettings::importScl - invalid denominator" );
+ if( nDenom > 0 )
+ maSheetViews.back()->mnCurrentZoom = getLimitedValue< sal_Int32, sal_uInt16 >( (nNum * 100) / nDenom, 10, 400 );
+ }
+}
+
+void SheetViewSettings::importSelection( BiffInputStream& rStrm )
+{
+ OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing leading WINDOW2 record" );
+ if( !maSheetViews.empty() )
+ {
+ // pane this selection belongs to
+ sal_uInt8 nPaneId = rStrm.readuInt8();
+ PaneSelectionModel& rPaneSel = maSheetViews.back()->createPaneSelection( lclGetOoxPaneId( nPaneId, -1 ) );
+ // cursor position
+ BinAddress aActiveCell;
+ sal_uInt16 nActiveCellId;
+ rStrm >> aActiveCell >> nActiveCellId;
+ rPaneSel.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false );
+ rPaneSel.mnActiveCellId = nActiveCellId;
+ // selection
+ rPaneSel.maSelection.clear();
+ BinRangeList aSelection;
+ aSelection.read( rStrm, false );
+ getAddressConverter().convertToCellRangeList( rPaneSel.maSelection, aSelection, getSheetIndex(), false );
+ }
+}
+
+void SheetViewSettings::finalizeImport()
+{
+ // force creation of sheet view model to get the Excel defaults
+ SheetViewModelRef xModel = maSheetViews.empty() ? createSheetView() : maSheetViews.front();
+
+ // #i59590# #158194# special handling for chart sheets (Excel ignores some settings in chart sheets)
+ if( getSheetType() == SHEETTYPE_CHARTSHEET )
+ {
+ xModel->maPaneSelMap.clear();
+ xModel->maFirstPos = xModel->maSecondPos = CellAddress( getSheetIndex(), 0, 0 );
+ xModel->mnViewType = XML_normal;
+ xModel->mnActivePaneId = XML_topLeft;
+ xModel->mnPaneState = XML_split;
+ xModel->mfSplitX = xModel->mfSplitY = 0.0;
+ xModel->mbRightToLeft = false;
+ xModel->mbDefGridColor = true;
+ xModel->mbShowFormulas = false;
+ xModel->mbShowGrid = true;
+ xModel->mbShowHeadings = true;
+ xModel->mbShowZeros = true;
+ xModel->mbShowOutline = true;
+ }
+
+ // sheet selected (active sheet must be selected)
+ bool bSelected = xModel->mbSelected || (getSheetIndex() == getViewSettings().getActiveCalcSheet());
+
+ // visible area and current cursor position (selection not supported via API)
+ CellAddress aFirstPos = xModel->maFirstPos;
+ const PaneSelectionModel* pPaneSel = xModel->getActiveSelection();
+ CellAddress aCursor = pPaneSel ? pPaneSel->maActiveCell : aFirstPos;
+
+ // freeze/split position default
+ sal_Int16 nHSplitMode = API_SPLITMODE_NONE;
+ sal_Int16 nVSplitMode = API_SPLITMODE_NONE;
+ sal_Int32 nHSplitPos = 0;
+ sal_Int32 nVSplitPos = 0;
+ // active pane default
+ sal_Int16 nActivePane = API_SPLITPANE_BOTTOMLEFT;
+
+ // freeze/split position
+ if( (xModel->mnPaneState == XML_frozen) || (xModel->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( (xModel->mfSplitX >= 1.0) && (xModel->maFirstPos.Column + xModel->mfSplitX <= rMaxApiPos.Column) )
+ nHSplitPos = static_cast< sal_Int32 >( xModel->maFirstPos.Column + xModel->mfSplitX );
+ nHSplitMode = (nHSplitPos > 0) ? API_SPLITMODE_FREEZE : API_SPLITMODE_NONE;
+ if( (xModel->mfSplitY >= 1.0) && (xModel->maFirstPos.Row + xModel->mfSplitY <= rMaxApiPos.Row) )
+ nVSplitPos = static_cast< sal_Int32 >( xModel->maFirstPos.Row + xModel->mfSplitY );
+ nVSplitMode = (nVSplitPos > 0) ? API_SPLITMODE_FREEZE : API_SPLITMODE_NONE;
+ }
+ else if( xModel->mnPaneState == XML_split )
+ {
+ // split window: view settings API uses twips...
+ nHSplitPos = getLimitedValue< sal_Int32, double >( xModel->mfSplitX + 0.5, 0, SAL_MAX_INT32 );
+ nHSplitMode = (nHSplitPos > 0) ? API_SPLITMODE_SPLIT : API_SPLITMODE_NONE;
+ nVSplitPos = getLimitedValue< sal_Int32, double >( xModel->mfSplitY + 0.5, 0, SAL_MAX_INT32 );
+ nVSplitMode = (nVSplitPos > 0) ? API_SPLITMODE_SPLIT : API_SPLITMODE_NONE;
+ }
+
+ // active pane
+ switch( xModel->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;
+ }
+
+ // write the sheet view settings into the property sequence
+ PropertyMap aPropMap;
+ aPropMap[ PROP_TableSelected ] <<= bSelected;
+ aPropMap[ PROP_CursorPositionX ] <<= aCursor.Column;
+ aPropMap[ PROP_CursorPositionY ] <<= aCursor.Row;
+ aPropMap[ PROP_HorizontalSplitMode ] <<= nHSplitMode;
+ aPropMap[ PROP_VerticalSplitMode ] <<= nVSplitMode;
+ aPropMap[ PROP_HorizontalSplitPositionTwips ] <<= nHSplitPos;
+ aPropMap[ PROP_VerticalSplitPositionTwips ] <<= nVSplitPos;
+ aPropMap[ PROP_ActiveSplitRange ] <<= nActivePane;
+ aPropMap[ PROP_PositionLeft ] <<= aFirstPos.Column;
+ aPropMap[ PROP_PositionTop ] <<= aFirstPos.Row;
+ aPropMap[ PROP_PositionRight ] <<= xModel->maSecondPos.Column;
+ aPropMap[ PROP_PositionBottom ] <<= ((nVSplitPos > 0) ? xModel->maSecondPos.Row : xModel->maFirstPos.Row);
+ aPropMap[ PROP_ZoomType ] <<= API_ZOOMTYPE_PERCENT;
+ aPropMap[ PROP_ZoomValue ] <<= static_cast< sal_Int16 >( xModel->getNormalZoom() );
+ aPropMap[ PROP_PageViewZoomValue ] <<= static_cast< sal_Int16 >( xModel->getPageBreakZoom() );
+ aPropMap[ PROP_GridColor ] <<= xModel->getGridColor( getBaseFilter() );
+ aPropMap[ PROP_ShowPageBreakPreview ] <<= xModel->isPageBreakPreview();
+ aPropMap[ PROP_ShowFormulas ] <<= xModel->mbShowFormulas;
+ aPropMap[ PROP_ShowGrid ] <<= xModel->mbShowGrid;
+ aPropMap[ PROP_HasColumnRowHeaders ] <<= xModel->mbShowHeadings;
+ aPropMap[ PROP_ShowZeroValues ] <<= xModel->mbShowZeros;
+ aPropMap[ PROP_IsOutlineSymbolsSet ] <<= xModel->mbShowOutline;
+
+ // store sheet view settings in global view settings object
+ getViewSettings().setSheetViewSettings( getSheetIndex(), xModel, Any( aPropMap.makePropertyValueSequence() ) );
+}
+
+bool SheetViewSettings::isSheetRightToLeft() const
+{
+ return !maSheetViews.empty() && maSheetViews.front()->mbRightToLeft;
+}
+
+// private --------------------------------------------------------------------
+
+SheetViewModelRef SheetViewSettings::createSheetView()
+{
+ SheetViewModelRef xModel( new SheetViewModel );
+ maSheetViews.push_back( xModel );
+ return xModel;
+}
+
+// ============================================================================
+
+WorkbookViewModel::WorkbookViewModel() :
+ 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 ),
+ mbValidOleSize( false )
+{
+}
+
+void ViewSettings::importWorkbookView( const AttributeList& rAttribs )
+{
+ WorkbookViewModel& rModel = createWorkbookView();
+ rModel.mnWinX = rAttribs.getInteger( XML_xWindow, 0 );
+ rModel.mnWinY = rAttribs.getInteger( XML_yWindow, 0 );
+ rModel.mnWinWidth = rAttribs.getInteger( XML_windowWidth, 0 );
+ rModel.mnWinHeight = rAttribs.getInteger( XML_windowHeight, 0 );
+ rModel.mnActiveSheet = rAttribs.getInteger( XML_activeTab, 0 );
+ rModel.mnFirstVisSheet = rAttribs.getInteger( XML_firstSheet, 0 );
+ rModel.mnTabBarWidth = rAttribs.getInteger( XML_tabRatio, 600 );
+ rModel.mnVisibility = rAttribs.getToken( XML_visibility, XML_visible );
+ rModel.mbShowTabBar = rAttribs.getBool( XML_showSheetTabs, true );
+ rModel.mbShowHorScroll = rAttribs.getBool( XML_showHorizontalScroll, true );
+ rModel.mbShowVerScroll = rAttribs.getBool( XML_showVerticalScroll, true );
+ rModel.mbMinimized = rAttribs.getBool( XML_minimized, false );
+}
+
+void ViewSettings::importOleSize( const AttributeList& rAttribs )
+{
+ OUString aRange = rAttribs.getString( XML_ref, OUString() );
+ mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aRange, 0, true, false );
+}
+
+void ViewSettings::importWorkbookView( SequenceInputStream& rStrm )
+{
+ WorkbookViewModel& rModel = createWorkbookView();
+ sal_uInt8 nFlags;
+ rStrm >> rModel.mnWinX >> rModel.mnWinY >> rModel.mnWinWidth >> rModel.mnWinHeight >> rModel.mnTabBarWidth >> rModel.mnFirstVisSheet >> rModel.mnActiveSheet >> nFlags;
+ rModel.mnVisibility = getFlagValue( nFlags, BIFF12_WBVIEW_HIDDEN, XML_hidden, XML_visible );
+ rModel.mbShowTabBar = getFlag( nFlags, BIFF12_WBVIEW_SHOWTABBAR );
+ rModel.mbShowHorScroll = getFlag( nFlags, BIFF12_WBVIEW_SHOWHORSCROLL );
+ rModel.mbShowVerScroll = getFlag( nFlags, BIFF12_WBVIEW_SHOWVERSCROLL );
+ rModel.mbMinimized = getFlag( nFlags, BIFF12_WBVIEW_MINIMIZED );
+}
+
+void ViewSettings::importOleSize( SequenceInputStream& rStrm )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aBinRange, 0, true, false );
+}
+
+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( maBookViews.empty() || ((getBiff() == BIFF4) && isWorkbookFile()),
+ "ViewSettings::importWindow1 - multiple WINDOW1 records" );
+ WorkbookViewModel& rModel = createWorkbookView();
+ rModel.mnWinX = nWinX;
+ rModel.mnWinY = nWinY;
+ rModel.mnWinWidth = nWinWidth;
+ rModel.mnWinHeight = nWinHeight;
+
+ if( getBiff() <= BIFF4 )
+ {
+ sal_uInt8 nHidden;
+ rStrm >> nHidden;
+ rModel.mnVisibility = (nHidden == 0) ? XML_visible : XML_hidden;
+ }
+ else
+ {
+ sal_uInt16 nFlags, nActiveTab, nFirstVisTab, nSelectCnt, nTabBarWidth;
+ rStrm >> nFlags >> nActiveTab >> nFirstVisTab >> nSelectCnt >> nTabBarWidth;
+
+ rModel.mnActiveSheet = nActiveTab;
+ rModel.mnFirstVisSheet = nFirstVisTab;
+ rModel.mnTabBarWidth = nTabBarWidth;
+ rModel.mnVisibility = getFlagValue( nFlags, BIFF_WINDOW1_HIDDEN, XML_hidden, XML_visible );
+ rModel.mbMinimized = getFlag( nFlags, BIFF_WINDOW1_MINIMIZED );
+ rModel.mbShowHorScroll = getFlag( nFlags, BIFF_WINDOW1_SHOWHORSCROLL );
+ rModel.mbShowVerScroll = getFlag( nFlags, BIFF_WINDOW1_SHOWVERSCROLL );
+ rModel.mbShowTabBar = getFlag( nFlags, BIFF_WINDOW1_SHOWTABBAR );
+ }
+}
+
+void ViewSettings::importOleSize( BiffInputStream& rStrm )
+{
+ rStrm.skip( 2 );
+ BinRange aBinRange;
+ aBinRange.read( rStrm, false );
+ mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aBinRange, 0, true, false );
+}
+
+void ViewSettings::setSheetViewSettings( sal_Int16 nSheet, const SheetViewModelRef& rxSheetView, const Any& rProperties )
+{
+ maSheetViews[ nSheet ] = rxSheetView;
+ maSheetProps[ nSheet ] = rProperties;
+}
+
+void ViewSettings::setSheetUsedArea( const CellRangeAddress& rUsedArea )
+{
+ maSheetUsedAreas[ rUsedArea.Sheet ] = rUsedArea;
+}
+
+void ViewSettings::finalizeImport()
+{
+ const WorksheetBuffer& rWorksheets = getWorksheets();
+ if( rWorksheets.getWorksheetCount() <= 0 ) return;
+
+ // force creation of workbook view model to get the Excel defaults
+ const WorkbookViewModel& rModel = maBookViews.empty() ? createWorkbookView() : *maBookViews.front();
+
+ // show object mode is part of workbook settings
+ sal_Int16 nShowMode = getWorkbookSettings().getApiShowObjectMode();
+
+ // view settings for all sheets
+ Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getGlobalFactory() );
+ if( !xSheetsNC.is() ) return;
+ for( SheetPropertiesMap::const_iterator aIt = maSheetProps.begin(), aEnd = maSheetProps.end(); aIt != aEnd; ++aIt )
+ ContainerHelper::insertByName( xSheetsNC, rWorksheets.getCalcSheetName( aIt->first ), aIt->second );
+
+ // use active sheet to set sheet properties that are document-global in Calc
+ sal_Int16 nActiveSheet = getActiveCalcSheet();
+ SheetViewModelRef& rxActiveSheetView = maSheetViews[ nActiveSheet ];
+ OSL_ENSURE( rxActiveSheetView.get(), "ViewSettings::finalizeImport - missing active sheet view settings" );
+ if( !rxActiveSheetView )
+ rxActiveSheetView.reset( new SheetViewModel );
+
+ Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getGlobalFactory() );
+ if( xContainer.is() ) try
+ {
+ PropertyMap aPropMap;
+ aPropMap[ PROP_Tables ] <<= xSheetsNC;
+ aPropMap[ PROP_ActiveTable ] <<= rWorksheets.getCalcSheetName( nActiveSheet );
+ aPropMap[ PROP_HasHorizontalScrollBar ] <<= rModel.mbShowHorScroll;
+ aPropMap[ PROP_HasVerticalScrollBar ] <<= rModel.mbShowVerScroll;
+ aPropMap[ PROP_HasSheetTabs ] <<= rModel.mbShowTabBar;
+ aPropMap[ PROP_RelativeHorizontalTabbarWidth ] <<= double( rModel.mnTabBarWidth / 1000.0 );
+ aPropMap[ PROP_ShowObjects ] <<= nShowMode;
+ aPropMap[ PROP_ShowCharts ] <<= nShowMode;
+ aPropMap[ PROP_ShowDrawing ] <<= nShowMode;
+ aPropMap[ PROP_GridColor ] <<= rxActiveSheetView->getGridColor( getBaseFilter() );
+ aPropMap[ PROP_ShowPageBreakPreview ] <<= rxActiveSheetView->isPageBreakPreview();
+ aPropMap[ PROP_ShowFormulas ] <<= rxActiveSheetView->mbShowFormulas;
+ aPropMap[ PROP_ShowGrid ] <<= rxActiveSheetView->mbShowGrid;
+ aPropMap[ PROP_HasColumnRowHeaders ] <<= rxActiveSheetView->mbShowHeadings;
+ aPropMap[ PROP_ShowZeroValues ] <<= rxActiveSheetView->mbShowZeros;
+ aPropMap[ PROP_IsOutlineSymbolsSet ] <<= rxActiveSheetView->mbShowOutline;
+
+ xContainer->insertByIndex( 0, Any( aPropMap.makePropertyValueSequence() ) );
+ 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" );
+ }
+
+ /* Set visible area to be used if this document is an embedded OLE object.
+ #i44077# If a new OLE object is inserted from file, there is no OLESIZE
+ record in the Excel file. In this case, use the used area calculated
+ from file contents (used cells and drawing objects). */
+ maOleSize.Sheet = nActiveSheet;
+ const CellRangeAddress* pVisibleArea = mbValidOleSize ?
+ &maOleSize : ContainerHelper::getMapElement( maSheetUsedAreas, nActiveSheet );
+ if( pVisibleArea )
+ {
+ // calculate the visible area in units of 1/100 mm
+ PropertySet aRangeProp( getCellRangeFromDoc( *pVisibleArea ) );
+ Point aPos;
+ Size aSize;
+ if( aRangeProp.getProperty( aPos, PROP_Position ) && aRangeProp.getProperty( aSize, PROP_Size ) )
+ {
+ // set the visible area as sequence of long at the media descriptor
+ Sequence< sal_Int32 > aWinExtent( 4 );
+ aWinExtent[ 0 ] = aPos.X;
+ aWinExtent[ 1 ] = aPos.Y;
+ aWinExtent[ 2 ] = aPos.X + aSize.Width;
+ aWinExtent[ 3 ] = aPos.Y + aSize.Height;
+ getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "WinExtent" ) ] <<= aWinExtent;
+ }
+ }
+}
+
+sal_Int16 ViewSettings::getActiveCalcSheet() const
+{
+ return maBookViews.empty() ? 0 : ::std::max< sal_Int16 >( getWorksheets().getCalcSheetIndex( maBookViews.front()->mnActiveSheet ), 0 );
+}
+
+// private --------------------------------------------------------------------
+
+WorkbookViewModel& ViewSettings::createWorkbookView()
+{
+ WorkbookViewModelRef xModel( new WorkbookViewModel );
+ maBookViews.push_back( xModel );
+ return *xModel;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx
new file mode 100644
index 000000000000..dce3c8eb461e
--- /dev/null
+++ b/oox/source/xls/workbookfragment.cxx
@@ -0,0 +1,727 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/workbookfragment.hxx"
+
+#include <com/sun/star/table/CellAddress.hpp>
+#include "oox/core/filterbase.hxx"
+#include "oox/drawingml/themefragmenthandler.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/progressbar.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/ole/olestorage.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/chartsheetfragment.hxx"
+#include "oox/xls/connectionsfragment.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/externallinkfragment.hxx"
+#include "oox/xls/pivotcachebuffer.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"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+using namespace ::oox::core;
+
+using ::oox::drawingml::ThemeFragmentHandler;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const double PROGRESS_LENGTH_GLOBALS = 0.1; /// 10% of progress bar for globals import.
+
+} // namespace
+
+// ============================================================================
+
+WorkbookFragment::WorkbookFragment( const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ WorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+ContextHandlerRef WorkbookFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( workbook ) ) return this;
+ break;
+
+ case XLS_TOKEN( workbook ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheets ):
+ case XLS_TOKEN( bookViews ):
+ case XLS_TOKEN( externalReferences ):
+ case XLS_TOKEN( definedNames ):
+ case XLS_TOKEN( pivotCaches ): return this;
+
+ case XLS_TOKEN( fileSharing ): getWorkbookSettings().importFileSharing( rAttribs ); break;
+ case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break;
+ case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break;
+ case XLS_TOKEN( oleSize ): getViewSettings().importOleSize( rAttribs ); break;
+ }
+ break;
+
+ case XLS_TOKEN( sheets ):
+ if( nElement == XLS_TOKEN( sheet ) ) getWorksheets().importSheet( rAttribs );
+ break;
+ case XLS_TOKEN( bookViews ):
+ if( nElement == XLS_TOKEN( workbookView ) ) getViewSettings().importWorkbookView( rAttribs );
+ break;
+ case XLS_TOKEN( externalReferences ):
+ if( nElement == XLS_TOKEN( externalReference ) ) importExternalReference( rAttribs );
+ break;
+ case XLS_TOKEN( definedNames ):
+ if( nElement == XLS_TOKEN( definedName ) ) { importDefinedName( rAttribs ); return this; } // collect formula
+ break;
+ case XLS_TOKEN( pivotCaches ):
+ if( nElement == XLS_TOKEN( pivotCache ) ) importPivotCache( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+void WorkbookFragment::onCharacters( const OUString& rChars )
+{
+ if( isCurrentElement( XLS_TOKEN( definedName ) ) && mxCurrName.get() )
+ mxCurrName->setFormula( rChars );
+}
+
+ContextHandlerRef WorkbookFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_WORKBOOK ) return this;
+ break;
+
+ case BIFF12_ID_WORKBOOK:
+ switch( nRecId )
+ {
+ case BIFF12_ID_SHEETS:
+ case BIFF12_ID_BOOKVIEWS:
+ case BIFF12_ID_EXTERNALREFS:
+ case BIFF12_ID_PIVOTCACHES: return this;
+
+ case BIFF12_ID_FILESHARING: getWorkbookSettings().importFileSharing( rStrm ); break;
+ case BIFF12_ID_WORKBOOKPR: getWorkbookSettings().importWorkbookPr( rStrm ); break;
+ case BIFF12_ID_CALCPR: getWorkbookSettings().importCalcPr( rStrm ); break;
+ case BIFF12_ID_OLESIZE: getViewSettings().importOleSize( rStrm ); break;
+ case BIFF12_ID_DEFINEDNAME: getDefinedNames().importDefinedName( rStrm ); break;
+ }
+ break;
+
+ case BIFF12_ID_SHEETS:
+ if( nRecId == BIFF12_ID_SHEET ) getWorksheets().importSheet( rStrm );
+ break;
+ case BIFF12_ID_BOOKVIEWS:
+ if( nRecId == BIFF12_ID_WORKBOOKVIEW ) getViewSettings().importWorkbookView( rStrm );
+ break;
+
+ case BIFF12_ID_EXTERNALREFS:
+ switch( nRecId )
+ {
+ case BIFF12_ID_EXTERNALREF: importExternalRef( rStrm ); break;
+ case BIFF12_ID_EXTERNALSELF: getExternalLinks().importExternalSelf( rStrm ); break;
+ case BIFF12_ID_EXTERNALSAME: getExternalLinks().importExternalSame( rStrm ); break;
+ case BIFF12_ID_EXTERNALADDIN: getExternalLinks().importExternalAddin( rStrm ); break;
+ case BIFF12_ID_EXTERNALSHEETS: getExternalLinks().importExternalSheets( rStrm ); break;
+ }
+ break;
+
+ case BIFF12_ID_PIVOTCACHES:
+ if( nRecId == BIFF12_ID_PIVOTCACHE ) importPivotCache( rStrm );
+ }
+ return 0;
+}
+
+const RecordInfo* WorkbookFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_BOOKVIEWS, BIFF12_ID_BOOKVIEWS + 1 },
+ { BIFF12_ID_EXTERNALREFS, BIFF12_ID_EXTERNALREFS + 1 },
+ { BIFF12_ID_FUNCTIONGROUPS, BIFF12_ID_FUNCTIONGROUPS + 2 },
+ { BIFF12_ID_PIVOTCACHE, BIFF12_ID_PIVOTCACHE + 1 },
+ { BIFF12_ID_PIVOTCACHES, BIFF12_ID_PIVOTCACHES + 1 },
+ { BIFF12_ID_SHEETS, BIFF12_ID_SHEETS + 1 },
+ { BIFF12_ID_WORKBOOK, BIFF12_ID_WORKBOOK + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void WorkbookFragment::finalizeImport()
+{
+ ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
+
+ // read the theme substream
+ OUString aThemeFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) );
+ if( aThemeFragmentPath.getLength() > 0 )
+ importOoxFragment( new ThemeFragmentHandler( getFilter(), aThemeFragmentPath, getTheme() ) );
+ xGlobalSegment->setPosition( 0.25 );
+
+ // read the styles substream (requires finalized theme buffer)
+ OUString aStylesFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "styles" ) );
+ if( aStylesFragmentPath.getLength() > 0 )
+ importOoxFragment( new StylesFragment( *this, aStylesFragmentPath ) );
+ xGlobalSegment->setPosition( 0.5 );
+
+ // read the shared string table substream (requires finalized styles buffer)
+ OUString aSstFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "sharedStrings" ) );
+ if( aSstFragmentPath.getLength() > 0 )
+ importOoxFragment( new SharedStringsFragment( *this, aSstFragmentPath ) );
+ xGlobalSegment->setPosition( 0.75 );
+
+ // read the connections substream
+ OUString aConnFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "connections" ) );
+ if( aConnFragmentPath.getLength() > 0 )
+ importOoxFragment( new ConnectionsFragment( *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::vector< FragmentHandlerRef > SheetFragmentVector;
+ SheetFragmentVector aSheetFragments;
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ sal_Int32 nWorksheetCount = rWorksheets.getWorksheetCount();
+ for( sal_Int32 nWorksheet = 0; nWorksheet < nWorksheetCount; ++nWorksheet )
+ {
+ sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet );
+ const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getWorksheetRelId( nWorksheet ) );
+ if( (nCalcSheet >= 0) && pRelation )
+ {
+ // get fragment path of the sheet
+ OUString aFragmentPath = getFragmentPathFromRelation( *pRelation );
+ OSL_ENSURE( aFragmentPath.getLength() > 0, "WorkbookFragment::finalizeImport - cannot access sheet fragment" );
+ if( aFragmentPath.getLength() > 0 )
+ {
+ ::rtl::Reference< WorksheetFragmentBase > xFragment;
+ double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet);
+ ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength );
+
+ // create the fragment according to the sheet type
+ if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "worksheet" ) )
+ {
+ xFragment.set( new WorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nCalcSheet ) );
+ }
+ else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "chartsheet" ) )
+ {
+ xFragment.set( new ChartsheetFragment( *this, aFragmentPath, xSheetSegment, nCalcSheet ) );
+ }
+ else if( (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlMacrosheet" )) ||
+ (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlIntlMacrosheet" )) )
+ {
+ xFragment.set( new WorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nCalcSheet ) );
+ }
+ else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "dialogsheet" ) )
+ {
+ xFragment.set( new WorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nCalcSheet ) );
+ }
+
+ // insert the fragment into the map
+ OSL_ENSURE( xFragment.is(), "WorkbookFragment::finalizeImport - unknown sheet type" );
+ OSL_ENSURE( !xFragment.is() || xFragment->isValidSheet(), "WorkbookFragment::finalizeImport - missing sheet in document" );
+ if( xFragment.is() && xFragment->isValidSheet() )
+ aSheetFragments.push_back( xFragment.get() );
+ }
+ }
+ }
+
+ // create all defined names and database ranges
+ getDefinedNames().finalizeImport();
+ getTables().finalizeImport();
+
+ // load all worksheets
+ for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt )
+ {
+ // import the sheet fragment
+ importOoxFragment( *aIt );
+ // delete fragment object, will free all allocated sheet buffers
+ aIt->clear();
+ }
+
+ // open the VBA project storage
+ OUString aVbaFragmentPath = getFragmentPathFromFirstType( CREATE_MSOFFICE_RELATION_TYPE( "vbaProject" ) );
+ if( aVbaFragmentPath.getLength() > 0 )
+ {
+ Reference< XInputStream > xInStrm = getBaseFilter().openInputStream( aVbaFragmentPath );
+ if( xInStrm.is() )
+ setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getGlobalFactory(), xInStrm, false ) ) );
+ }
+
+ // final conversions, e.g. calculation settings and view settings
+ finalizeWorkbookImport();
+}
+
+// private --------------------------------------------------------------------
+
+void WorkbookFragment::importExternalReference( const AttributeList& rAttribs )
+{
+ if( ExternalLink* pExtLink = getExternalLinks().importExternalReference( rAttribs ).get() )
+ importExternalLinkFragment( *pExtLink );
+}
+
+void WorkbookFragment::importDefinedName( const AttributeList& rAttribs )
+{
+ mxCurrName = getDefinedNames().importDefinedName( rAttribs );
+}
+
+void WorkbookFragment::importPivotCache( const AttributeList& rAttribs )
+{
+ sal_Int32 nCacheId = rAttribs.getInteger( XML_cacheId, -1 );
+ OUString aRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
+ importPivotCacheDefFragment( aRelId, nCacheId );
+}
+
+void WorkbookFragment::importExternalRef( SequenceInputStream& rStrm )
+{
+ if( ExternalLink* pExtLink = getExternalLinks().importExternalRef( rStrm ).get() )
+ importExternalLinkFragment( *pExtLink );
+}
+
+void WorkbookFragment::importPivotCache( SequenceInputStream& rStrm )
+{
+ sal_Int32 nCacheId = rStrm.readInt32();
+ OUString aRelId = BiffHelper::readString( rStrm );
+ importPivotCacheDefFragment( aRelId, nCacheId );
+}
+
+void WorkbookFragment::importExternalLinkFragment( ExternalLink& rExtLink )
+{
+ OUString aFragmentPath = getFragmentPathFromRelId( rExtLink.getRelId() );
+ if( aFragmentPath.getLength() > 0 )
+ importOoxFragment( new ExternalLinkFragment( *this, aFragmentPath, rExtLink ) );
+}
+
+void WorkbookFragment::importPivotCacheDefFragment( const OUString& rRelId, sal_Int32 nCacheId )
+{
+ // pivot caches will be imported on demand, here we just store the fragment path in the buffer
+ getPivotCaches().registerPivotCacheFragment( nCacheId, getFragmentPathFromRelId( rRelId ) );
+}
+
+// ============================================================================
+
+BiffWorkbookFragment::BiffWorkbookFragment( const WorkbookHelper& rHelper, const OUString& rStrmName ) :
+ BiffWorkbookFragmentBase( rHelper, rStrmName )
+{
+}
+
+bool BiffWorkbookFragment::importFragment()
+{
+ bool bRet = false;
+
+ BiffFragmentType eFragment = startFragment( 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( *xGlobalsProgress );
+ // load sheet fragments (do not return false in bRet on missing/broken sheets)
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ bool bNextSheet = bRet;
+ for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet )
+ {
+ // try to start a new sheet fragment
+ double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet);
+ ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
+ BiffFragmentType eSheetFragment = startFragment( getBiff(), rWorksheets.getBiffRecordHandle( nWorksheet ) );
+ sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet );
+ bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet );
+ }
+ }
+ break;
+
+ case BIFF_FRAGMENT_WORKSPACE:
+ {
+ bRet = importWorkspaceFragment();
+ // sheets are embedded in workspace fragment, nothing to do here
+ }
+ break;
+
+ case BIFF_FRAGMENT_WORKSHEET:
+ case BIFF_FRAGMENT_CHARTSHEET:
+ case BIFF_FRAGMENT_MACROSHEET:
+ {
+ /* Single sheet without globals
+ - #i62752# possible in all BIFF versions
+ - do not return false in bRet on missing/broken sheets. */
+ getWorksheets().initializeSingleSheet();
+ importSheetFragment( getProgressBar(), eFragment, 0 );
+ // success, even if stream is broken
+ bRet = true;
+ }
+ break;
+
+ default:;
+ }
+
+ // final conversions, e.g. calculation settings and view settings
+ if( bRet )
+ finalizeWorkbookImport();
+
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importWorkspaceFragment()
+{
+ // 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;
+ BiffInputStream& rStrm = getInputStream();
+ 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 = getCodecHelper().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 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet )
+ {
+ // 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() / (nWorksheetCount - nWorksheet);
+ ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
+ /* Read current sheet name (sheet substreams may not be in the
+ same order as SHEET records are). */
+ rStrm.skip( 4 );
+ OUString aSheetName = rStrm.readByteStringUC( false, getTextEncoding() );
+ sal_Int16 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName );
+ // load the sheet fragment records
+ BiffFragmentType eSheetFragment = startFragment( getBiff() );
+ bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCurrSheet );
+ // do not return false in bRet on missing/broken sheets
+ }
+ }
+
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgressBar )
+{
+ WorkbookSettings& rWorkbookSett = getWorkbookSettings();
+ ViewSettings& rViewSett = getViewSettings();
+ SharedStringsBuffer& rSharedStrings = getSharedStrings();
+ StylesBuffer& rStyles = getStyles();
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ PivotCacheBuffer& rPivotCaches = getPivotCaches();
+ bool bHasVbaProject = false;
+ bool bEmptyVbaProject = false;
+
+ // 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;
+ BiffInputStream& rStrm = getInputStream();
+ 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( BiffHelper::isBofRecord( rStrm ) || (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 = getCodecHelper().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 BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); 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 BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); 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 BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); 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_OLESIZE: rViewSett.importOleSize( rStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break;
+ case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( 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 BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); 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_OLESIZE: rViewSett.importOleSize( rStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break;
+ case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( 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_VBAPROJECT: bHasVbaProject = true; break;
+ case BIFF_ID_VBAPROJECTEMPTY: bEmptyVbaProject = true; 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 );
+ if( bRet )
+ {
+ 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();
+ // context handler implementing import of external link records
+ BiffExternalSheetDataContext aSheetContext( *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 )
+ aSheetContext.importRecord( rStrm );
+ // finalize global buffers
+ getDefinedNames().finalizeImport();
+ // seek back to the EOF record of the workbook globals fragment
+ bRet = rStrm.startRecordByHandle( nEofHandle );
+ }
+
+ // open the VBA project storage
+ if( bHasVbaProject && !bEmptyVbaProject )
+ setVbaProjectStorage( getBaseFilter().openSubStorage( CREATE_OUSTRING( "_VBA_PROJECT_CUR" ), false ) );
+
+ // #i56376# missing EOF - rewind before worksheet BOF record (see above)
+ if( bRet && BiffHelper::isBofRecord( rStrm ) )
+ rStrm.rewindRecord();
+
+ rProgressBar.setPosition( 1.0 );
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int16 nCalcSheet )
+{
+ // no Calc sheet - skip the fragment
+ if( nCalcSheet < 0 )
+ return skipFragment();
+
+ // find the sheet type for this fragment
+ WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET;
+ switch( eFragment )
+ {
+ case BIFF_FRAGMENT_WORKSHEET: eSheetType = SHEETTYPE_WORKSHEET; break;
+ case BIFF_FRAGMENT_CHARTSHEET: eSheetType = SHEETTYPE_CHARTSHEET; break;
+ case BIFF_FRAGMENT_MACROSHEET: eSheetType = SHEETTYPE_MACROSHEET; break;
+ case BIFF_FRAGMENT_MODULESHEET: eSheetType = SHEETTYPE_MODULESHEET; break;
+ case BIFF_FRAGMENT_EMPTYSHEET: eSheetType = SHEETTYPE_EMPTYSHEET; break;
+ default: return false;
+ }
+
+ /* #i11183# Clear buffers that are used per-sheet, e.g. external links in
+ BIFF4W and BIFF5 files, or defined names in BIFF4W files. */
+ createBuffersPerSheet( nCalcSheet );
+
+ // preprocess some records
+ BiffInputStream& rStrm = getInputStream();
+ switch( getBiff() )
+ {
+ // load the workbook globals fragment records in BIFF2-BIFF4
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ {
+ // remember current record to seek back below
+ sal_Int64 nRecHandle = rStrm.getRecHandle();
+ // import the global records
+ ISegmentProgressBarRef xGlobalsProgress = rProgressBar.createSegment( PROGRESS_LENGTH_GLOBALS );
+ importGlobalsFragment( *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 ).importFragment();
+ // 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_MACROSHEET:
+ case SHEETTYPE_DIALOGSHEET:
+ xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nCalcSheet ) );
+ break;
+ case SHEETTYPE_CHARTSHEET:
+ xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nCalcSheet ) );
+ break;
+ case SHEETTYPE_MODULESHEET:
+ case SHEETTYPE_EMPTYSHEET:
+ xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nCalcSheet ) );
+ break;
+ }
+ // load the sheet fragment records
+ return xFragment->isValidSheet() && xFragment->importFragment();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx
new file mode 100644
index 000000000000..8cd2748101d7
--- /dev/null
+++ b/oox/source/xls/workbookhelper.cxx
@@ -0,0 +1,947 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/workbookhelper.hxx"
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <osl/thread.h>
+#include "oox/drawingml/theme.hxx"
+#include "oox/helper/progressbar.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/ole/vbaproject.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/biffcodec.hxx"
+#include "oox/xls/connectionsbuffer.hxx"
+#include "oox/xls/defnamesbuffer.hxx"
+#include "oox/xls/excelchartconverter.hxx"
+#include "oox/xls/excelfilter.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/pivotcachebuffer.hxx"
+#include "oox/xls/pivottablebuffer.hxx"
+#include "oox/xls/scenariobuffer.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/tablebuffer.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::BinaryFilterBase;
+using ::oox::core::FilterBase;
+using ::oox::core::FragmentHandler;
+using ::oox::core::XmlFilterBase;
+using ::oox::drawingml::Theme;
+using ::rtl::OUString;
+
+// ============================================================================
+
+bool IgnoreCaseCompare::operator()( const OUString& rName1, const OUString& rName2 ) const
+{
+ // there is no wrapper in rtl::OUString, TODO: compare with collator
+ return ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0;
+}
+
+// ============================================================================
+
+class WorkbookData
+{
+public:
+ explicit WorkbookData( ExcelFilter& rFilter );
+ explicit WorkbookData( ExcelBiffFilter& 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; }
+ /** Returns the index of the current sheet in the Calc document. */
+ inline sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; }
+ /** Sets the index of the current sheet in the Calc document. */
+ inline void setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; }
+ /** Returns the VBA project storage. */
+ inline StorageRef getVbaProjectStorage() const { return mxVbaPrjStrg; }
+ /** Sets the VBA project storage. */
+ inline void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; }
+
+ // document model ---------------------------------------------------------
+
+ /** Returns a reference to the source/target spreadsheet document model. */
+ inline Reference< XSpreadsheetDocument > getDocument() const { return mxDoc; }
+ /** 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 and returns a defined name on-the-fly in the Calc document. */
+ Reference< XNamedRange > createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const;
+ /** Creates and returns a database range on-the-fly in the Calc document. */
+ Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const;
+ /** Creates and returns a com.sun.star.style.Style object for cells or pages. */
+ Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle ) const;
+
+ // 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 scenarios collection. */
+ inline ScenarioBuffer& getScenarios() const { return *mxScenarios; }
+ /** Returns the collection of external data connections. */
+ inline ConnectionsBuffer& getConnections() const { return *mxConnections; }
+ /** Returns the collection of pivot caches. */
+ inline PivotCacheBuffer& getPivotCaches() const { return *mxPivotCaches; }
+ /** Returns the collection of pivot tables. */
+ inline PivotTableBuffer& getPivotTables() { 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 chart object converter. */
+ inline ExcelChartConverter& getChartConverter() const { return *mxChartConverter; }
+ /** Returns the page/print settings converter. */
+ inline PageSettingsConverter& getPageSettingsConverter() const { return *mxPageSettConverter; }
+
+ // OOXML/BIFF12 specific --------------------------------------------------
+
+ /** Returns the base OOXML/BIFF12 filter object. */
+ inline XmlFilterBase& getOoxFilter() const { return *mpOoxFilter; }
+
+ // BIFF2-BIFF8 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( sal_Int16 nSheet );
+ /** Returns the codec helper that stores the encoder/decoder object. */
+ inline BiffCodecHelper& getCodecHelper() { return *mxCodecHelper; }
+
+private:
+ /** Initializes some basic members and sets needed document properties. */
+ void initialize( bool bWorkbookFile );
+ /** 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 ::boost::shared_ptr< ThemeBuffer > ThemeBfrRef;
+ 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< ScenarioBuffer > ScenarioBfrPtr;
+ typedef ::std::auto_ptr< ConnectionsBuffer > ConnectionsBfrPtr;
+ typedef ::std::auto_ptr< PivotCacheBuffer > PivotCacheBfrPtr;
+ typedef ::std::auto_ptr< PivotTableBuffer > PivotTableBfrPtr;
+ typedef ::std::auto_ptr< FormulaParser > FormulaParserPtr;
+ typedef ::std::auto_ptr< UnitConverter > UnitConvPtr;
+ typedef ::std::auto_ptr< AddressConverter > AddressConvPtr;
+ typedef ::std::auto_ptr< ExcelChartConverter > ExcelChartConvPtr;
+ typedef ::std::auto_ptr< PageSettingsConverter > PageSettConvPtr;
+ typedef ::std::auto_ptr< BiffCodecHelper > BiffCodecHelperPtr;
+
+ OUString maCellStyles; /// Style family name for cell styles.
+ OUString maPageStyles; /// Style family 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.
+ ExcelFilterBase& mrExcelBase; /// Base object for registration of this structure.
+ FilterType meFilterType; /// File type of the filter.
+ ProgressBarPtr mxProgressBar; /// The progress bar.
+ StorageRef mxVbaPrjStrg; /// Storage containing the VBA project.
+ sal_Int16 mnCurrSheet; /// Current sheet index in Calc dcument.
+ bool mbWorkbook; /// True = multi-sheet file.
+
+ // buffers
+ WorkbookSettPtr mxWorkbookSettings; /// Global workbook settings.
+ ViewSettingsPtr mxViewSettings; /// Workbook and sheet view settings.
+ WorksheetBfrPtr mxWorksheets; /// Sheet info buffer.
+ ThemeBfrRef 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).
+ ScenarioBfrPtr mxScenarios; /// All scenarios.
+ ConnectionsBfrPtr mxConnections; /// All external data connections.
+ PivotCacheBfrPtr mxPivotCaches; /// All pivot caches in the document.
+ PivotTableBfrPtr mxPivotTables; /// All pivot tables in the document.
+
+ // converters
+ FormulaParserPtr mxFmlaParser; /// Import formula parser.
+ UnitConvPtr mxUnitConverter; /// General unit converter.
+ AddressConvPtr mxAddrConverter; /// Cell address and cell range address converter.
+ ExcelChartConvPtr mxChartConverter; /// Chart object converter.
+ PageSettConvPtr mxPageSettConverter; /// Page/print settings converter.
+
+ // OOXML/BIFF12 specific
+ XmlFilterBase* mpOoxFilter; /// Base OOXML/BIFF12 filter object.
+
+ // BIFF2-BIFF8 specific
+ BinaryFilterBase* mpBiffFilter; /// Base BIFF2-BIFF8 filter object.
+ BiffCodecHelperPtr mxCodecHelper; /// Encoder/decoder helper.
+ 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.
+};
+
+// ----------------------------------------------------------------------------
+
+WorkbookData::WorkbookData( ExcelFilter& rFilter ) :
+ mrBaseFilter( rFilter ),
+ mrExcelBase( rFilter ),
+ meFilterType( FILTER_OOXML ),
+ mpOoxFilter( &rFilter ),
+ mpBiffFilter( 0 ),
+ meBiff( BIFF_UNKNOWN )
+{
+ // register at the filter, needed for virtual callbacks (even during construction)
+ mrExcelBase.registerWorkbookData( *this );
+ initialize( true );
+}
+
+WorkbookData::WorkbookData( ExcelBiffFilter& rFilter, BiffType eBiff ) :
+ mrBaseFilter( rFilter ),
+ mrExcelBase( rFilter ),
+ meFilterType( FILTER_BIFF ),
+ mpOoxFilter( 0 ),
+ mpBiffFilter( &rFilter ),
+ meBiff( eBiff )
+{
+ // register at the filter, needed for virtual callbacks (even during construction)
+ mrExcelBase.registerWorkbookData( *this );
+ initialize( eBiff >= BIFF5 );
+}
+
+WorkbookData::~WorkbookData()
+{
+ finalize();
+ mrExcelBase.unregisterWorkbookData();
+}
+
+// document model -------------------------------------------------------------
+
+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 ? maPageStyles : maCellStyles ), UNO_QUERY );
+ }
+ 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;
+ try
+ {
+ Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
+ xStyle.set( xStylesNC->getByName( rStyleName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xStyle.is(), "WorkbookData::getStyleObject - cannot access style object" );
+ return xStyle;
+}
+
+Reference< XNamedRange > WorkbookData::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const
+{
+ // create the name and insert it into the Calc document
+ Reference< XNamedRange > xNamedRange;
+ if( orName.getLength() > 0 ) try
+ {
+ // find an unused name
+ PropertySet aDocProps( mxDoc );
+ Reference< XNamedRanges > xNamedRanges( aDocProps.getAnyProperty( PROP_NamedRanges ), UNO_QUERY_THROW );
+ Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY_THROW );
+ orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
+ // create the named range
+ xNamedRanges->addNewByName( orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags );
+ xNamedRange.set( xNamedRanges->getByName( orName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xNamedRange.is(), "WorkbookData::createNamedRangeObject - cannot create defined name" );
+ return xNamedRange;
+}
+
+Reference< XDatabaseRange > WorkbookData::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
+{
+ // validate cell range
+ CellRangeAddress aDestRange = rRangeAddr;
+ bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true );
+
+ // create database range and insert it into the Calc document
+ Reference< XDatabaseRange > xDatabaseRange;
+ if( bValidRange && (orName.getLength() > 0) ) try
+ {
+ // find an unused name
+ PropertySet aDocProps( mxDoc );
+ Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW );
+ Reference< XNameAccess > xNameAccess( xDatabaseRanges, UNO_QUERY_THROW );
+ orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
+ // create the database range
+ xDatabaseRanges->addNewByName( orName, aDestRange );
+ xDatabaseRange.set( xDatabaseRanges->getByName( orName ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xDatabaseRange.is(), "WorkbookData::createDatabaseRangeObject - cannot create database range" );
+ return xDatabaseRange;
+}
+
+Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
+{
+ Reference< XStyle > xStyle;
+ try
+ {
+ Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
+ xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW );
+ orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), false );
+ }
+ 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( sal_Int16 nSheet )
+{
+ // set mnCurrSheet to enable usage of WorkbookHelper::getCurrentSheetIndex()
+ mnCurrSheet = nSheet;
+ switch( meBiff )
+ {
+ case BIFF2:
+ case BIFF3:
+ OSL_ENSURE( mnCurrSheet == 0, "WorkbookData::createBuffersPerSheet - unexpected sheet index" );
+ mxDefNames->setLocalCalcSheet( mnCurrSheet );
+ break;
+
+ case BIFF4:
+ OSL_ENSURE( mbWorkbook || (mnCurrSheet == 0), "WorkbookData::createBuffersPerSheet - unexpected sheet index" );
+ // #i11183# sheets in BIFF4W files have own styles and names
+ if( mbWorkbook && (mnCurrSheet > 0) )
+ {
+ mxStyles.reset( new StylesBuffer( *this ) );
+ mxDefNames.reset( new DefinedNamesBuffer( *this ) );
+ mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
+ }
+ mxDefNames->setLocalCalcSheet( mnCurrSheet );
+ break;
+
+ case BIFF5:
+ // BIFF5 stores external references per sheet
+ mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
+ break;
+
+ case BIFF8:
+ break;
+
+ case BIFF_UNKNOWN:
+ break;
+ }
+ mnCurrSheet = -1;
+}
+
+// private --------------------------------------------------------------------
+
+void WorkbookData::initialize( bool bWorkbookFile )
+{
+ maCellStyles = CREATE_OUSTRING( "CellStyles" );
+ maPageStyles = CREATE_OUSTRING( "PageStyles" );
+ maCellStyleServ = CREATE_OUSTRING( "com.sun.star.style.CellStyle" );
+ maPageStyleServ = CREATE_OUSTRING( "com.sun.star.style.PageStyle" );
+ mnCurrSheet = -1;
+ mbWorkbook = bWorkbookFile;
+ meTextEnc = osl_getThreadTextEncoding();
+ mbHasCodePage = false;
+
+ // the spreadsheet document
+ mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY );
+ OSL_ENSURE( mxDoc.is(), "WorkbookData::initialize - no spreadsheet document" );
+
+ mxWorkbookSettings.reset( new WorkbookSettings( *this ) );
+ mxViewSettings.reset( new ViewSettings( *this ) );
+ mxWorksheets.reset( new WorksheetBuffer( *this ) );
+ mxTheme.reset( new ThemeBuffer( *this ) );
+ mxStyles.reset( new StylesBuffer( *this ) );
+ mxSharedStrings.reset( new SharedStringsBuffer( *this ) );
+ mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
+ mxDefNames.reset( new DefinedNamesBuffer( *this ) );
+ mxTables.reset( new TableBuffer( *this ) );
+ mxScenarios.reset( new ScenarioBuffer( *this ) );
+ mxConnections.reset( new ConnectionsBuffer( *this ) );
+ mxPivotCaches.reset( new PivotCacheBuffer( *this ) );
+ mxPivotTables.reset( new PivotTableBuffer( *this ) );
+
+ mxUnitConverter.reset( new UnitConverter( *this ) );
+ mxAddrConverter.reset( new AddressConverter( *this ) );
+ mxChartConverter.reset( new ExcelChartConverter( *this ) );
+ mxPageSettConverter.reset( new PageSettingsConverter( *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( PROP_IsChangeReadOnlyEnabled, true );
+ // #i76026# disable Undo while loading the document
+ aPropSet.setProperty( PROP_IsUndoEnabled, false );
+ // #i79826# disable calculating automatic row height while loading the document
+ aPropSet.setProperty( PROP_IsAdjustHeightEnabled, false );
+ // disable automatic update of linked sheets and DDE links
+ aPropSet.setProperty( PROP_IsExecuteLinkEnabled, false );
+ // #i79890# disable automatic update of defined names
+ Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), 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( *this ) );
+ }
+ else if( mrBaseFilter.isExportFilter() )
+ {
+ //! TODO: localize progress bar text
+ mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Saving..." ) ) );
+ }
+
+ // filter specific
+ switch( getFilterType() )
+ {
+ case FILTER_BIFF:
+ mxCodecHelper.reset( new BiffCodecHelper( *this ) );
+ break;
+
+ case FILTER_OOXML:
+ break;
+
+ case FILTER_UNKNOWN:
+ break;
+ }
+}
+
+void WorkbookData::finalize()
+{
+ // set some document properties needed after import
+ if( mrBaseFilter.isImportFilter() )
+ {
+ PropertySet aPropSet( mxDoc );
+ // #i74668# do not insert default sheets
+ aPropSet.setProperty( PROP_IsLoaded, true );
+ // #i79890# enable automatic update of defined names (before IsAdjustHeightEnabled!)
+ Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY );
+ if( xLockable.is() )
+ xLockable->removeActionLock();
+ // enable automatic update of linked sheets and DDE links
+ aPropSet.setProperty( PROP_IsExecuteLinkEnabled, true );
+ // #i79826# enable updating automatic row height after loading the document
+ aPropSet.setProperty( PROP_IsAdjustHeightEnabled, true );
+ // #i76026# enable Undo after loading the document
+ aPropSet.setProperty( PROP_IsUndoEnabled, true );
+ // disable editing read-only documents (e.g. from read-only files)
+ aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, false );
+ // #111099# open forms in alive mode (has no effect, if no controls in document)
+ aPropSet.setProperty( PROP_ApplyFormDesignMode, false );
+ }
+}
+
+// ============================================================================
+
+WorkbookHelper::~WorkbookHelper()
+{
+}
+
+// filter ---------------------------------------------------------------------
+
+FilterBase& WorkbookHelper::getBaseFilter() const
+{
+ return mrBookData.getBaseFilter();
+}
+
+Reference< XMultiServiceFactory > WorkbookHelper::getGlobalFactory() const
+{
+ return mrBookData.getBaseFilter().getServiceFactory();
+}
+
+FilterType WorkbookHelper::getFilterType() const
+{
+ return mrBookData.getFilterType();
+}
+
+SegmentProgressBar& WorkbookHelper::getProgressBar() const
+{
+ return mrBookData.getProgressBar();
+}
+
+bool WorkbookHelper::isWorkbookFile() const
+{
+ return mrBookData.isWorkbookFile();
+}
+
+sal_Int16 WorkbookHelper::getCurrentSheetIndex() const
+{
+ return mrBookData.getCurrentSheetIndex();
+}
+
+void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet )
+{
+ mrBookData.setCurrentSheetIndex( nSheet );
+}
+
+void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg )
+{
+ mrBookData.setVbaProjectStorage( rxVbaPrjStrg );
+}
+
+void WorkbookHelper::finalizeWorkbookImport()
+{
+ // workbook settings, document and sheet view settings
+ mrBookData.getWorkbookSettings().finalizeImport();
+ mrBookData.getViewSettings().finalizeImport();
+
+ /* Insert all pivot tables. Must be done after loading all sheets, because
+ data pilots expect existing source data on creation. */
+ mrBookData.getPivotTables().finalizeImport();
+
+ /* Insert scenarios after all sheet processing is done, because new hidden
+ sheets are created for scenarios which would confuse code that relies
+ on certain sheet indexes. Must be done after pivot tables too. */
+ mrBookData.getScenarios().finalizeImport();
+
+ /* Set 'Default' page style to automatic page numbering (default is manual
+ number 1). Otherwise hidden sheets (e.g. for scenarios) which have
+ 'Default' page style will break automatic page numbering for following
+ sheets. Automatic numbering is set by passing the value 0. */
+ PropertySet aDefPageStyle( getStyleObject( CREATE_OUSTRING( "Default" ), true ) );
+ aDefPageStyle.setProperty< sal_Int16 >( PROP_FirstPageNumber, 0 );
+
+ /* Import the VBA project (after finalizing workbook settings which
+ contains the workbook code name). */
+ StorageRef xVbaPrjStrg = mrBookData.getVbaProjectStorage();
+ if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
+ getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() );
+}
+
+// document model -------------------------------------------------------------
+
+Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const
+{
+ return mrBookData.getDocument();
+}
+
+Reference< XMultiServiceFactory > WorkbookHelper::getDocumentFactory() const
+{
+ return mrBookData.getBaseFilter().getModelFactory();
+}
+
+Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 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< XSpreadsheet > WorkbookHelper::getSheetFromDoc( const OUString& rSheet ) const
+{
+ Reference< XSpreadsheet > xSheet;
+ try
+ {
+ Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
+ xSheet.set( xSheetsNA->getByName( rSheet ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+ return xSheet;
+}
+
+Reference< XCell > WorkbookHelper::getCellFromDoc( const CellAddress& rAddress ) const
+{
+ Reference< XCell > xCell;
+ try
+ {
+ Reference< XSpreadsheet > xSheet( getSheetFromDoc( rAddress.Sheet ), UNO_SET_THROW );
+ xCell = xSheet->getCellByPosition( rAddress.Column, rAddress.Row );
+ }
+ catch( Exception& )
+ {
+ }
+ return xCell;
+}
+
+Reference< XCellRange > WorkbookHelper::getCellRangeFromDoc( const CellRangeAddress& rRange ) const
+{
+ Reference< XCellRange > xRange;
+ try
+ {
+ Reference< XSpreadsheet > xSheet( getSheetFromDoc( rRange.Sheet ), UNO_SET_THROW );
+ xRange = xSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
+ }
+ catch( Exception& )
+ {
+ }
+ return xRange;
+}
+
+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< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const
+{
+ return mrBookData.createNamedRangeObject( orName, nNameFlags );
+}
+
+Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
+{
+ return mrBookData.createDatabaseRangeObject( orName, rRangeAddr );
+}
+
+Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
+{
+ return mrBookData.createStyleObject( orStyleName, bPageStyle );
+}
+
+// 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();
+}
+
+ScenarioBuffer& WorkbookHelper::getScenarios() const
+{
+ return mrBookData.getScenarios();
+}
+
+ConnectionsBuffer& WorkbookHelper::getConnections() const
+{
+ return mrBookData.getConnections();
+}
+
+PivotCacheBuffer& WorkbookHelper::getPivotCaches() const
+{
+ return mrBookData.getPivotCaches();
+}
+
+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();
+}
+
+ExcelChartConverter& WorkbookHelper::getChartConverter() const
+{
+ return mrBookData.getChartConverter();
+}
+
+PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const
+{
+ return mrBookData.getPageSettingsConverter();
+}
+
+// OOXML/BIFF12 specific ------------------------------------------------------
+
+XmlFilterBase& WorkbookHelper::getOoxFilter() const
+{
+ OSL_ENSURE( mrBookData.getFilterType() == FILTER_OOXML, "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( sal_Int16 nSheet )
+{
+ mrBookData.createBuffersPerSheet( nSheet );
+}
+
+BiffCodecHelper& WorkbookHelper::getCodecHelper() const
+{
+ return mrBookData.getCodecHelper();
+}
+
+// ============================================================================
+
+namespace prv {
+
+WorkbookDataOwner::WorkbookDataOwner( WorkbookDataRef xBookData ) :
+ mxBookData( xBookData )
+{
+}
+
+WorkbookDataOwner::~WorkbookDataOwner()
+{
+}
+
+} // namespace prv
+
+// ----------------------------------------------------------------------------
+
+WorkbookHelperRoot::WorkbookHelperRoot( ExcelFilter& rFilter ) :
+ prv::WorkbookDataOwner( prv::WorkbookDataRef( new WorkbookData( rFilter ) ) ),
+ WorkbookHelper( *mxBookData )
+{
+}
+
+WorkbookHelperRoot::WorkbookHelperRoot( ExcelBiffFilter& 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..6889d42ed2f6
--- /dev/null
+++ b/oox/source/xls/workbooksettings.cxx
@@ -0,0 +1,366 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/workbooksettings.hxx"
+
+#include <com/sun/star/sheet/XCalculatable.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::comphelper::MediaDescriptor;
+using ::oox::core::CodecHelper;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt32 BIFF12_WORKBOOKPR_DATE1904 = 0x00000001;
+const sal_uInt32 BIFF12_WORKBOOKPR_STRIPEXT = 0x00000080;
+
+const sal_uInt16 BIFF12_CALCPR_A1 = 0x0002;
+const sal_uInt16 BIFF12_CALCPR_ITERATE = 0x0004;
+const sal_uInt16 BIFF12_CALCPR_FULLPRECISION = 0x0008;
+const sal_uInt16 BIFF12_CALCPR_CALCCOMPLETED = 0x0010;
+const sal_uInt16 BIFF12_CALCPR_CALCONSAVE = 0x0020;
+const sal_uInt16 BIFF12_CALCPR_CONCURRENT = 0x0040;
+const sal_uInt16 BIFF12_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
+
+// ============================================================================
+
+FileSharingModel::FileSharingModel() :
+ mnPasswordHash( 0 ),
+ mbRecommendReadOnly( false )
+{
+}
+
+// ============================================================================
+
+WorkbookSettingsModel::WorkbookSettingsModel() :
+ mnShowObjectMode( XML_all ),
+ mnUpdateLinksMode( XML_userSet ),
+ mnDefaultThemeVer( -1 ),
+ mbDateMode1904( false ),
+ mbSaveExtLinkValues( true )
+{
+}
+
+void WorkbookSettingsModel::setBiffObjectMode( sal_uInt16 nObjMode )
+{
+ static const sal_Int32 spnObjModes[] = { XML_all, XML_placeholders, XML_none };
+ mnShowObjectMode = STATIC_ARRAY_SELECT( spnObjModes, nObjMode, XML_all );
+}
+
+// ============================================================================
+
+CalcSettingsModel::CalcSettingsModel() :
+ 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::importFileSharing( const AttributeList& rAttribs )
+{
+ maFileSharing.maUserName = rAttribs.getXString( XML_userName, OUString() );
+ maFileSharing.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_reservationPassword );
+ maFileSharing.mbRecommendReadOnly = rAttribs.getBool( XML_readOnlyRecommended, false );
+}
+
+void WorkbookSettings::importWorkbookPr( const AttributeList& rAttribs )
+{
+ maBookSettings.maCodeName = rAttribs.getString( XML_codeName, OUString() );
+ maBookSettings.mnShowObjectMode = rAttribs.getToken( XML_showObjects, XML_all );
+ maBookSettings.mnUpdateLinksMode = rAttribs.getToken( XML_updateLinks, XML_userSet );
+ maBookSettings.mnDefaultThemeVer = rAttribs.getInteger( XML_defaultThemeVersion, -1 );
+ maBookSettings.mbSaveExtLinkValues = rAttribs.getBool( XML_saveExternalLinkValues, true );
+ setDateMode( rAttribs.getBool( XML_date1904, false ) );
+}
+
+void WorkbookSettings::importCalcPr( const AttributeList& rAttribs )
+{
+ maCalcSettings.mfIterateDelta = rAttribs.getDouble( XML_iterateDelta, 0.0001 );
+ maCalcSettings.mnCalcId = rAttribs.getInteger( XML_calcId, -1 );
+ maCalcSettings.mnRefMode = rAttribs.getToken( XML_refMode, XML_A1 );
+ maCalcSettings.mnCalcMode = rAttribs.getToken( XML_calcMode, XML_auto );
+ maCalcSettings.mnIterateCount = rAttribs.getInteger( XML_iterateCount, 100 );
+ maCalcSettings.mnProcCount = rAttribs.getInteger( XML_concurrentManualCount, -1 );
+ maCalcSettings.mbCalcOnSave = rAttribs.getBool( XML_calcOnSave, true );
+ maCalcSettings.mbCalcCompleted = rAttribs.getBool( XML_calcCompleted, true );
+ maCalcSettings.mbFullPrecision = rAttribs.getBool( XML_fullPrecision, true );
+ maCalcSettings.mbIterate = rAttribs.getBool( XML_iterate, false );
+ maCalcSettings.mbConcurrent = rAttribs.getBool( XML_concurrentCalc, true );
+}
+
+void WorkbookSettings::importFileSharing( SequenceInputStream& rStrm )
+{
+ maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0;
+ rStrm >> maFileSharing.mnPasswordHash >> maFileSharing.maUserName;
+}
+
+void WorkbookSettings::importWorkbookPr( SequenceInputStream& rStrm )
+{
+ sal_uInt32 nFlags;
+ rStrm >> nFlags >> maBookSettings.mnDefaultThemeVer >> maBookSettings.maCodeName;
+ maBookSettings.setBiffObjectMode( extractValue< sal_uInt16 >( nFlags, 13, 2 ) );
+ // set flag means: strip external link values
+ maBookSettings.mbSaveExtLinkValues = !getFlag( nFlags, BIFF12_WORKBOOKPR_STRIPEXT );
+ setDateMode( getFlag( nFlags, BIFF12_WORKBOOKPR_DATE1904 ) );
+}
+
+void WorkbookSettings::importCalcPr( SequenceInputStream& rStrm )
+{
+ sal_Int32 nCalcMode, nProcCount;
+ sal_uInt16 nFlags;
+ rStrm >> maCalcSettings.mnCalcId >> nCalcMode >> maCalcSettings.mnIterateCount >> maCalcSettings.mfIterateDelta >> nProcCount >> nFlags;
+
+ static const sal_Int32 spnCalcModes[] = { XML_manual, XML_auto, XML_autoNoTable };
+ maCalcSettings.mnRefMode = getFlagValue( nFlags, BIFF12_CALCPR_A1, XML_A1, XML_R1C1 );
+ maCalcSettings.mnCalcMode = STATIC_ARRAY_SELECT( spnCalcModes, nCalcMode, XML_auto );
+ maCalcSettings.mnProcCount = getFlagValue< sal_Int32 >( nFlags, BIFF12_CALCPR_MANUALPROC, nProcCount, -1 );
+ maCalcSettings.mbCalcOnSave = getFlag( nFlags, BIFF12_CALCPR_CALCONSAVE );
+ maCalcSettings.mbCalcCompleted = getFlag( nFlags, BIFF12_CALCPR_CALCCOMPLETED );
+ maCalcSettings.mbFullPrecision = getFlag( nFlags, BIFF12_CALCPR_FULLPRECISION );
+ maCalcSettings.mbIterate = getFlag( nFlags, BIFF12_CALCPR_ITERATE );
+ maCalcSettings.mbConcurrent = getFlag( nFlags, BIFF12_CALCPR_CONCURRENT );
+}
+
+void WorkbookSettings::setSaveExtLinkValues( bool bSaveExtLinks )
+{
+ maBookSettings.mbSaveExtLinkValues = bSaveExtLinks;
+}
+
+void WorkbookSettings::importBookBool( BiffInputStream& rStrm )
+{
+ // value of 0 means save external values, value of 1 means strip external values
+ maBookSettings.mbSaveExtLinkValues = rStrm.readuInt16() == 0;
+}
+
+void WorkbookSettings::importCalcCount( BiffInputStream& rStrm )
+{
+ maCalcSettings.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 };
+ maCalcSettings.mnCalcMode = STATIC_ARRAY_SELECT( spnCalcModes, nCalcMode, XML_auto );
+}
+
+void WorkbookSettings::importCodeName( BiffInputStream& rStrm )
+{
+ maBookSettings.maCodeName = rStrm.readUniString();
+}
+
+void WorkbookSettings::importDateMode( BiffInputStream& rStrm )
+{
+ setDateMode( rStrm.readuInt16() != 0 );
+}
+
+void WorkbookSettings::importDelta( BiffInputStream& rStrm )
+{
+ rStrm >> maCalcSettings.mfIterateDelta;
+}
+
+void WorkbookSettings::importFileSharing( BiffInputStream& rStrm )
+{
+ maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0;
+ rStrm >> maFileSharing.mnPasswordHash;
+ if( getBiff() == BIFF8 )
+ {
+ sal_uInt16 nStrLen = rStrm.readuInt16();
+ // there is no string flags field if string is empty
+ if( nStrLen > 0 )
+ maFileSharing.maUserName = rStrm.readUniStringBody( nStrLen );
+ }
+ else
+ {
+ maFileSharing.maUserName = rStrm.readByteStringUC( false, getTextEncoding() );
+ }
+}
+
+void WorkbookSettings::importHideObj( BiffInputStream& rStrm )
+{
+ maBookSettings.setBiffObjectMode( rStrm.readuInt16() );
+}
+
+void WorkbookSettings::importIteration( BiffInputStream& rStrm )
+{
+ maCalcSettings.mbIterate = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::importPrecision( BiffInputStream& rStrm )
+{
+ maCalcSettings.mbFullPrecision = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::importRefMode( BiffInputStream& rStrm )
+{
+ maCalcSettings.mnRefMode = (rStrm.readuInt16() == 0) ? XML_R1C1 : XML_A1;
+}
+
+void WorkbookSettings::importSaveRecalc( BiffInputStream& rStrm )
+{
+ maCalcSettings.mbCalcOnSave = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::importUncalced( BiffInputStream& )
+{
+ // existence of this record indicates incomplete recalc
+ maCalcSettings.mbCalcCompleted = false;
+}
+
+void WorkbookSettings::importUsesElfs( BiffInputStream& rStrm )
+{
+ maCalcSettings.mbUseNlr = rStrm.readuInt16() != 0;
+}
+
+void WorkbookSettings::finalizeImport()
+{
+ // default settings
+ PropertySet aPropSet( getDocument() );
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ case FILTER_BIFF:
+ aPropSet.setProperty( PROP_IgnoreCase, true ); // always in Excel
+ aPropSet.setProperty( PROP_RegularExpressions, false ); // not supported in Excel
+ break;
+ case FILTER_UNKNOWN:
+ break;
+ }
+
+ // write protection
+ if( maFileSharing.mbRecommendReadOnly || (maFileSharing.mnPasswordHash != 0) ) try
+ {
+ getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true;
+
+ Reference< XPropertySet > xDocumentSettings( getDocumentFactory()->createInstance(
+ CREATE_OUSTRING( "com.sun.star.document.Settings" ) ), UNO_QUERY_THROW );
+ PropertySet aSettingsProp( xDocumentSettings );
+ if( maFileSharing.mbRecommendReadOnly )
+ aSettingsProp.setProperty( PROP_LoadReadonly, true );
+// if( maFileSharing.mnPasswordHash != 0 )
+// aSettingsProp.setProperty( PROP_ModifyPasswordHash, static_cast< sal_Int32 >( maFileSharing.mnPasswordHash ) );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // calculation settings
+ Date aNullDate = getNullDate();
+
+ aPropSet.setProperty( PROP_NullDate, aNullDate );
+ aPropSet.setProperty( PROP_IsIterationEnabled, maCalcSettings.mbIterate );
+ aPropSet.setProperty( PROP_IterationCount, maCalcSettings.mnIterateCount );
+ aPropSet.setProperty( PROP_IterationEpsilon, maCalcSettings.mfIterateDelta );
+ aPropSet.setProperty( PROP_CalcAsShown, !maCalcSettings.mbFullPrecision );
+ aPropSet.setProperty( PROP_LookUpLabels, maCalcSettings.mbUseNlr );
+
+ Reference< XNumberFormatsSupplier > xNumFmtsSupp( getDocument(), UNO_QUERY );
+ if( xNumFmtsSupp.is() )
+ {
+ PropertySet aNumFmtProp( xNumFmtsSupp->getNumberFormatSettings() );
+ aNumFmtProp.setProperty( PROP_NullDate, aNullDate );
+ }
+
+ Reference< XCalculatable > xCalculatable( getDocument(), UNO_QUERY );
+ if( xCalculatable.is() )
+ xCalculatable->enableAutomaticCalculation( (maCalcSettings.mnCalcMode == XML_auto) || (maCalcSettings.mnCalcMode == XML_autoNoTable) );
+
+ // VBA code name
+ aPropSet.setProperty( PROP_CodeName, maBookSettings.maCodeName );
+}
+
+sal_Int16 WorkbookSettings::getApiShowObjectMode() const
+{
+ switch( maBookSettings.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;
+}
+
+Date WorkbookSettings::getNullDate() const
+{
+ static const Date saDate1900( 30, 12, 1899 ), saDate1904( 1, 1, 1904 );
+ return maBookSettings.mbDateMode1904 ? saDate1904 : saDate1900;
+}
+
+void WorkbookSettings::setDateMode( bool bDateMode1904 )
+{
+ maBookSettings.mbDateMode1904 = bDateMode1904;
+ getUnitConverter().finalizeNullDate( getNullDate() );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/worksheetbuffer.cxx b/oox/source/xls/worksheetbuffer.cxx
new file mode 100644
index 000000000000..6144c35d6a55
--- /dev/null
+++ b/oox/source/xls/worksheetbuffer.cxx
@@ -0,0 +1,258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheetbuffer.hxx"
+
+#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/XExternalSheetName.hpp>
+#include <com/sun/star/sheet/XSheetLinkable.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/excelhandlers.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+SheetInfoModel::SheetInfoModel() :
+ mnBiffHandle( -1 ),
+ mnSheetId( -1 ),
+ mnState( XML_visible )
+{
+}
+
+// ============================================================================
+
+WorksheetBuffer::WorksheetBuffer( const WorkbookHelper& rHelper ) :
+ WorkbookHelper( rHelper )
+{
+}
+
+/*static*/ OUString WorksheetBuffer::getBaseFileName( const OUString& rUrl )
+{
+ sal_Int32 nFileNamePos = ::std::max< sal_Int32 >( rUrl.lastIndexOf( '/' ) + 1, 0 );
+ sal_Int32 nExtPos = rUrl.lastIndexOf( '.' );
+ if( nExtPos <= nFileNamePos ) nExtPos = rUrl.getLength();
+ return rUrl.copy( nFileNamePos, nExtPos - nFileNamePos );
+}
+
+void WorksheetBuffer::initializeSingleSheet()
+{
+ OSL_ENSURE( maSheetInfos.empty(), "WorksheetBuffer::initializeSingleSheet - invalid call" );
+ SheetInfoModel aModel;
+ aModel.maName = getBaseFileName( getBaseFilter().getFileUrl() );
+ insertSheet( aModel );
+}
+
+void WorksheetBuffer::importSheet( const AttributeList& rAttribs )
+{
+ SheetInfoModel aModel;
+ aModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
+ aModel.maName = rAttribs.getXString( XML_name, OUString() );
+ aModel.mnSheetId = rAttribs.getInteger( XML_sheetId, -1 );
+ aModel.mnState = rAttribs.getToken( XML_state, XML_visible );
+ insertSheet( aModel );
+}
+
+void WorksheetBuffer::importSheet( SequenceInputStream& rStrm )
+{
+ sal_Int32 nState;
+ SheetInfoModel aModel;
+ rStrm >> nState >> aModel.mnSheetId >> aModel.maRelId >> aModel.maName;
+ static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden };
+ aModel.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible );
+ insertSheet( aModel );
+}
+
+void WorksheetBuffer::importSheet( BiffInputStream& rStrm )
+{
+ SheetInfoModel aModel;
+ if( getBiff() >= BIFF5 )
+ {
+ rStrm.enableDecoder( false );
+ aModel.mnBiffHandle = rStrm.readuInt32();
+ rStrm.enableDecoder( true );
+ sal_uInt16 nState = rStrm.readuInt16();
+ static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden };
+ aModel.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible );
+ }
+ aModel.maName = (getBiff() == BIFF8) ?
+ rStrm.readUniStringBody( rStrm.readuInt8() ) :
+ rStrm.readByteStringUC( false, getTextEncoding() );
+ insertSheet( aModel );
+}
+
+sal_Int16 WorksheetBuffer::insertEmptySheet( const OUString& rPreferredName, bool bVisible )
+{
+ return createSheet( rPreferredName, SAL_MAX_INT32, bVisible ).first;
+}
+
+sal_Int32 WorksheetBuffer::getWorksheetCount() const
+{
+ return static_cast< sal_Int32 >( maSheetInfos.size() );
+}
+
+OUString WorksheetBuffer::getWorksheetRelId( sal_Int32 nWorksheet ) const
+{
+ const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get();
+ return pSheetInfo ? pSheetInfo->maRelId : OUString();
+}
+
+sal_Int64 WorksheetBuffer::getBiffRecordHandle( sal_Int32 nWorksheet ) const
+{
+ const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get();
+ return pSheetInfo ? pSheetInfo->mnBiffHandle : -1;
+}
+
+sal_Int16 WorksheetBuffer::getCalcSheetIndex( sal_Int32 nWorksheet ) const
+{
+ const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get();
+ return pSheetInfo ? pSheetInfo->mnCalcSheet : -1;
+}
+
+OUString WorksheetBuffer::getCalcSheetName( sal_Int32 nWorksheet ) const
+{
+ const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get();
+ return pSheetInfo ? pSheetInfo->maCalcName : OUString();
+}
+
+sal_Int16 WorksheetBuffer::getCalcSheetIndex( const OUString& rWorksheetName ) const
+{
+ const SheetInfo* pSheetInfo = maSheetInfosByName.get( rWorksheetName ).get();
+ return pSheetInfo ? pSheetInfo->mnCalcSheet : -1;
+}
+
+OUString WorksheetBuffer::getCalcSheetName( const OUString& rWorksheetName ) const
+{
+ if( const SheetInfo* pSheetInfo = maSheetInfosByName.get( rWorksheetName ).get() )
+ {
+ bool bIsQuoted = pSheetInfo->maName != rWorksheetName;
+ return bIsQuoted ? pSheetInfo->maCalcQuotedName : pSheetInfo->maCalcName;
+ }
+ return OUString();
+}
+
+// private --------------------------------------------------------------------
+
+namespace {
+
+OUString lclQuoteName( const OUString& rName )
+{
+ OUStringBuffer aBuffer( rName );
+ // duplicate all quote characters
+ for( sal_Int32 nPos = aBuffer.getLength() - 1; nPos >= 0; --nPos )
+ if( aBuffer.charAt( nPos ) == '\'' )
+ aBuffer.insert( nPos, sal_Unicode( '\'' ) );
+ // add outer quotes and return
+ return aBuffer.insert( 0, sal_Unicode( '\'' ) ).append( sal_Unicode( '\'' ) ).makeStringAndClear();
+}
+
+} // namespace
+
+WorksheetBuffer::SheetInfo::SheetInfo( const SheetInfoModel& rModel, sal_Int16 nCalcSheet, const OUString& rCalcName ) :
+ SheetInfoModel( rModel ),
+ maCalcName( rCalcName ),
+ maCalcQuotedName( lclQuoteName( rCalcName ) ),
+ mnCalcSheet( nCalcSheet )
+{
+}
+
+WorksheetBuffer::IndexNamePair WorksheetBuffer::createSheet( const OUString& rPreferredName, sal_Int32 nSheetPos, bool bVisible )
+{
+ try
+ {
+ Reference< XSpreadsheets > xSheets( getDocument()->getSheets(), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xSheetsIA( xSheets, UNO_QUERY_THROW );
+ Reference< XNameAccess > xSheetsNA( xSheets, UNO_QUERY_THROW );
+ sal_Int16 nCalcSheet = -1;
+ OUString aSheetName = (rPreferredName.getLength() == 0) ? CREATE_OUSTRING( "Sheet" ) : rPreferredName;
+ PropertySet aPropSet;
+ if( nSheetPos < xSheetsIA->getCount() )
+ {
+ nCalcSheet = static_cast< sal_Int16 >( nSheetPos );
+ // existing sheet - try to rename
+ Reference< XNamed > xSheetName( xSheetsIA->getByIndex( nSheetPos ), UNO_QUERY_THROW );
+ if( xSheetName->getName() != aSheetName )
+ {
+ aSheetName = ContainerHelper::getUnusedName( xSheetsNA, aSheetName, ' ' );
+ xSheetName->setName( aSheetName );
+ }
+ aPropSet.set( xSheetName );
+ }
+ else
+ {
+ nCalcSheet = static_cast< sal_Int16 >( xSheetsIA->getCount() );
+ // new sheet - insert with unused name
+ aSheetName = ContainerHelper::getUnusedName( xSheetsNA, aSheetName, ' ' );
+ xSheets->insertNewByName( aSheetName, nCalcSheet );
+ aPropSet.set( xSheetsIA->getByIndex( nCalcSheet ) );
+ }
+
+ // sheet properties
+ aPropSet.setProperty( PROP_IsVisible, bVisible );
+
+ // return final sheet index if sheet exists
+ return IndexNamePair( nCalcSheet, aSheetName );
+ }
+ catch( Exception& )
+ {
+ OSL_ENSURE( false, "WorksheetBuffer::createSheet - cannot insert or rename worksheet" );
+ }
+ return IndexNamePair( -1, OUString() );
+}
+
+void WorksheetBuffer::insertSheet( const SheetInfoModel& rModel )
+{
+ sal_Int32 nWorksheet = static_cast< sal_Int32 >( maSheetInfos.size() );
+ IndexNamePair aIndexName = createSheet( rModel.maName, nWorksheet, rModel.mnState == XML_visible );
+ ::boost::shared_ptr< SheetInfo > xSheetInfo( new SheetInfo( rModel, aIndexName.first, aIndexName.second ) );
+ maSheetInfos.push_back( xSheetInfo );
+ maSheetInfosByName[ rModel.maName ] = xSheetInfo;
+ maSheetInfosByName[ lclQuoteName( rModel.maName ) ] = xSheetInfo;
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx
new file mode 100644
index 000000000000..4867c7c350c1
--- /dev/null
+++ b/oox/source/xls/worksheetfragment.cxx
@@ -0,0 +1,1230 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheetfragment.hxx"
+
+#include "oox/core/filterbase.hxx"
+#include "oox/core/relations.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/autofilterbuffer.hxx"
+#include "oox/xls/autofiltercontext.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/commentsfragment.hxx"
+#include "oox/xls/condformatcontext.hxx"
+#include "oox/xls/drawingfragment.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/pivottablefragment.hxx"
+#include "oox/xls/querytablefragment.hxx"
+#include "oox/xls/scenariobuffer.hxx"
+#include "oox/xls/scenariocontext.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"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+using namespace ::oox::core;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt16 BIFF_COLINFO_HIDDEN = 0x0001;
+const sal_uInt16 BIFF_COLINFO_SHOWPHONETIC = 0x0008;
+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_SHRFEATHEAD_SHEETPROT = 2;
+
+const sal_Int32 BIFF12_OLEOBJECT_CONTENT = 1;
+const sal_Int32 BIFF12_OLEOBJECT_ICON = 4;
+const sal_Int32 BIFF12_OLEOBJECT_ALWAYS = 1;
+const sal_Int32 BIFF12_OLEOBJECT_ONCALL = 3;
+const sal_uInt16 BIFF12_OLEOBJECT_LINKED = 0x0001;
+const sal_uInt16 BIFF12_OLEOBJECT_AUTOLOAD = 0x0002;
+
+} // namespace
+
+// ============================================================================
+
+DataValidationsContext::DataValidationsContext( WorksheetFragmentBase& rFragment ) :
+ WorksheetContextBase( rFragment )
+{
+}
+
+ContextHandlerRef DataValidationsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( dataValidations ):
+ if( nElement == XLS_TOKEN( dataValidation ) )
+ {
+ importDataValidation( rAttribs );
+ return this;
+ }
+ break;
+ case XLS_TOKEN( dataValidation ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( formula1 ):
+ case XLS_TOKEN( formula2 ):
+ return this; // collect formulas in onCharacters()
+ }
+ break;
+ }
+ return 0;
+}
+
+namespace {
+
+ApiTokenSequence lclImportDataValFormula( FormulaParser& rParser, const OUString& rFormula, const CellAddress& rBaseAddress )
+{
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( rBaseAddress );
+ rParser.importFormula( aContext, rFormula );
+ return aContext.getTokens();
+}
+
+} // namespace
+
+void DataValidationsContext::onCharacters( const OUString& rChars )
+{
+ if( mxValModel.get() ) switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( formula1 ):
+ mxValModel->maTokens1 = lclImportDataValFormula(
+ getFormulaParser(), rChars, mxValModel->maRanges.getBaseAddress() );
+ // process string list of a list validation (convert to list of string tokens)
+ if( mxValModel->mnType == XML_list )
+ getFormulaParser().convertStringToStringList( mxValModel->maTokens1, ',', true );
+ break;
+ case XLS_TOKEN( formula2 ):
+ mxValModel->maTokens2 = lclImportDataValFormula(
+ getFormulaParser(), rChars, mxValModel->maRanges.getBaseAddress() );
+ break;
+ }
+}
+
+void DataValidationsContext::onEndElement()
+{
+ if( isCurrentElement( XLS_TOKEN( dataValidation ) ) && mxValModel.get() )
+ {
+ setValidation( *mxValModel );
+ mxValModel.reset();
+ }
+}
+
+
+ContextHandlerRef DataValidationsContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ if( nRecId == BIFF12_ID_DATAVALIDATION )
+ importDataValidation( rStrm );
+ return 0;
+}
+
+void DataValidationsContext::importDataValidation( const AttributeList& rAttribs )
+{
+ mxValModel.reset( new ValidationModel );
+ getAddressConverter().convertToCellRangeList( mxValModel->maRanges, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), true );
+ mxValModel->maInputTitle = rAttribs.getXString( XML_promptTitle, OUString() );
+ mxValModel->maInputMessage = rAttribs.getXString( XML_prompt, OUString() );
+ mxValModel->maErrorTitle = rAttribs.getXString( XML_errorTitle, OUString() );
+ mxValModel->maErrorMessage = rAttribs.getXString( XML_error, OUString() );
+ mxValModel->mnType = rAttribs.getToken( XML_type, XML_none );
+ mxValModel->mnOperator = rAttribs.getToken( XML_operator, XML_between );
+ mxValModel->mnErrorStyle = rAttribs.getToken( XML_errorStyle, XML_stop );
+ mxValModel->mbShowInputMsg = rAttribs.getBool( XML_showInputMessage, false );
+ mxValModel->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! */
+ mxValModel->mbNoDropDown = rAttribs.getBool( XML_showDropDown, false );
+ mxValModel->mbAllowBlank = rAttribs.getBool( XML_allowBlank, false );
+}
+
+void DataValidationsContext::importDataValidation( SequenceInputStream& rStrm )
+{
+ ValidationModel aModel;
+
+ sal_uInt32 nFlags;
+ BinRangeList aRanges;
+ rStrm >> nFlags >> aRanges >> aModel.maErrorTitle >> aModel.maErrorMessage >> aModel.maInputTitle >> aModel.maInputMessage;
+
+ // equal flags in all BIFFs
+ aModel.setBiffType( extractValue< sal_uInt8 >( nFlags, 0, 4 ) );
+ aModel.setBiffOperator( extractValue< sal_uInt8 >( nFlags, 20, 4 ) );
+ aModel.setBiffErrorStyle( extractValue< sal_uInt8 >( nFlags, 4, 3 ) );
+ aModel.mbAllowBlank = getFlag( nFlags, BIFF_DATAVAL_ALLOWBLANK );
+ aModel.mbNoDropDown = getFlag( nFlags, BIFF_DATAVAL_NODROPDOWN );
+ aModel.mbShowInputMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWINPUT );
+ aModel.mbShowErrorMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWERROR );
+
+ // cell range list
+ getAddressConverter().convertToCellRangeList( aModel.maRanges, aRanges, getSheetIndex(), true );
+
+ // condition formula(s)
+ FormulaParser& rParser = getFormulaParser();
+ TokensFormulaContext aContext( true, false );
+ aContext.setBaseAddress( aModel.maRanges.getBaseAddress() );
+ rParser.importFormula( aContext, rStrm );
+ aModel.maTokens1 = aContext.getTokens();
+ rParser.importFormula( aContext, rStrm );
+ aModel.maTokens2 = aContext.getTokens();
+ // process string list of a list validation (convert to list of string tokens)
+ if( (aModel.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) )
+ rParser.convertStringToStringList( aModel.maTokens1, ',', true );
+
+ // set validation data
+ setValidation( aModel );
+}
+
+// ============================================================================
+
+WorksheetFragment::WorksheetFragment( const WorkbookHelper& rHelper,
+ const OUString& rFragmentPath, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath, rxProgressBar, eSheetType, nSheet )
+{
+ // import data tables related to this worksheet
+ RelationsRef xTableRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATION_TYPE( "table" ) );
+ for( Relations::const_iterator aIt = xTableRels->begin(), aEnd = xTableRels->end(); aIt != aEnd; ++aIt )
+ importOoxFragment( new TableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) );
+
+ // import comments related to this worksheet
+ OUString aCommentsFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "comments" ) );
+ if( aCommentsFragmentPath.getLength() > 0 )
+ importOoxFragment( new CommentsFragment( *this, aCommentsFragmentPath ) );
+}
+
+ContextHandlerRef WorksheetFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT: switch( getSheetType() )
+ {
+ case SHEETTYPE_WORKSHEET: return (nElement == XLS_TOKEN( worksheet )) ? this : 0;
+ case SHEETTYPE_CHARTSHEET: return 0;
+ case SHEETTYPE_MACROSHEET: return (nElement == XM_TOKEN( macrosheet )) ? this : 0;
+ case SHEETTYPE_DIALOGSHEET: return (nElement == XLS_TOKEN( dialogsheet )) ? this : 0;
+ case SHEETTYPE_MODULESHEET: return 0;
+ case SHEETTYPE_EMPTYSHEET: return 0;
+ }
+ break;
+
+ case XLS_TOKEN( worksheet ):
+ case XM_TOKEN( macrosheet ):
+ case XLS_TOKEN( dialogsheet ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheetData ): return new SheetDataContext( *this );
+ case XLS_TOKEN( conditionalFormatting ): return new CondFormatContext( *this );
+ case XLS_TOKEN( dataValidations ): return new DataValidationsContext( *this );
+ case XLS_TOKEN( autoFilter ): return new AutoFilterContext( *this, getAutoFilters().createAutoFilter() );
+ case XLS_TOKEN( scenarios ): return new ScenariosContext( *this );
+
+ case XLS_TOKEN( sheetViews ):
+ case XLS_TOKEN( cols ):
+ case XLS_TOKEN( mergeCells ):
+ case XLS_TOKEN( hyperlinks ):
+ case XLS_TOKEN( rowBreaks ):
+ case XLS_TOKEN( colBreaks ):
+ case XLS_TOKEN( oleObjects ):
+ case XLS_TOKEN( controls ): return this;
+
+ case XLS_TOKEN( sheetPr ): getWorksheetSettings().importSheetPr( rAttribs ); return this;
+ case XLS_TOKEN( dimension ): importDimension( rAttribs ); break;
+ case XLS_TOKEN( sheetFormatPr ): importSheetFormatPr( rAttribs ); break;
+ case XLS_TOKEN( sheetProtection ): getWorksheetSettings().importSheetProtection( rAttribs ); break;
+ case XLS_TOKEN( phoneticPr ): getWorksheetSettings().importPhoneticPr( rAttribs ); break;
+ case XLS_TOKEN( printOptions ): getPageSettings().importPrintOptions( rAttribs ); break;
+ case XLS_TOKEN( pageMargins ): getPageSettings().importPageMargins( rAttribs ); break;
+ case XLS_TOKEN( pageSetup ): getPageSettings().importPageSetup( getRelations(), rAttribs ); break;
+ case XLS_TOKEN( headerFooter ): getPageSettings().importHeaderFooter( rAttribs ); return this;
+ case XLS_TOKEN( picture ): getPageSettings().importPicture( getRelations(), rAttribs ); break;
+ case XLS_TOKEN( drawing ): importDrawing( rAttribs ); break;
+ case XLS_TOKEN( legacyDrawing ): importLegacyDrawing( rAttribs ); break;
+ }
+ break;
+
+ case XLS_TOKEN( sheetPr ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( tabColor ): getWorksheetSettings().importTabColor( rAttribs ); break;
+ case XLS_TOKEN( outlinePr ): getWorksheetSettings().importOutlinePr( rAttribs ); break;
+ case XLS_TOKEN( pageSetUpPr ): importPageSetUpPr( rAttribs ); break;
+ }
+ break;
+
+ case XLS_TOKEN( sheetViews ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheetView ): getSheetViewSettings().importSheetView( rAttribs ); return this;
+ }
+ break;
+ case XLS_TOKEN( sheetView ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( pane ): getSheetViewSettings().importPane( rAttribs ); break;
+ case XLS_TOKEN( selection ): getSheetViewSettings().importSelection( rAttribs ); break;
+ }
+ break;
+
+ case XLS_TOKEN( cols ):
+ if( nElement == XLS_TOKEN( col ) ) importCol( rAttribs );
+ break;
+ case XLS_TOKEN( mergeCells ):
+ if( nElement == XLS_TOKEN( mergeCell ) ) importMergeCell( rAttribs );
+ break;
+ case XLS_TOKEN( hyperlinks ):
+ if( nElement == XLS_TOKEN( hyperlink ) ) importHyperlink( rAttribs );
+ break;
+ case XLS_TOKEN( rowBreaks ):
+ if( nElement == XLS_TOKEN( brk ) ) importBrk( rAttribs, true );
+ break;
+ case XLS_TOKEN( colBreaks ):
+ if( nElement == XLS_TOKEN( brk ) ) importBrk( rAttribs, false );
+ break;
+
+ case XLS_TOKEN( headerFooter ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( firstHeader ):
+ case XLS_TOKEN( firstFooter ):
+ case XLS_TOKEN( oddHeader ):
+ case XLS_TOKEN( oddFooter ):
+ case XLS_TOKEN( evenHeader ):
+ case XLS_TOKEN( evenFooter ): return this; // collect h/f contents in onCharacters()
+ }
+ break;
+
+ case XLS_TOKEN( oleObjects ):
+ if( nElement == XLS_TOKEN( oleObject ) ) importOleObject( rAttribs );
+ break;
+ case XLS_TOKEN( controls ):
+ if( nElement == XLS_TOKEN( control ) ) importControl( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+void WorksheetFragment::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ 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, getCurrentElement() );
+ break;
+ }
+}
+
+ContextHandlerRef WorksheetFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_WORKSHEET ) return this;
+ break;
+
+ case BIFF12_ID_WORKSHEET:
+ switch( nRecId )
+ {
+ case BIFF12_ID_SHEETDATA: return new SheetDataContext( *this );
+ case BIFF12_ID_CONDFORMATTING: return new CondFormatContext( *this );
+ case BIFF12_ID_DATAVALIDATIONS: return new DataValidationsContext( *this );
+ case BIFF12_ID_AUTOFILTER: return new AutoFilterContext( *this, getAutoFilters().createAutoFilter() );
+ case BIFF12_ID_SCENARIOS: return new ScenariosContext( *this );
+
+ case BIFF12_ID_SHEETVIEWS:
+ case BIFF12_ID_COLS:
+ case BIFF12_ID_MERGECELLS:
+ case BIFF12_ID_ROWBREAKS:
+ case BIFF12_ID_COLBREAKS:
+ case BIFF12_ID_OLEOBJECTS:
+ case BIFF12_ID_CONTROLS: return this;
+
+ case BIFF12_ID_SHEETPR: getWorksheetSettings().importSheetPr( rStrm ); break;
+ case BIFF12_ID_DIMENSION: importDimension( rStrm ); break;
+ case BIFF12_ID_SHEETFORMATPR: importSheetFormatPr( rStrm ); break;
+ case BIFF12_ID_HYPERLINK: importHyperlink( rStrm ); break;
+ case BIFF12_ID_PAGEMARGINS: getPageSettings().importPageMargins( rStrm ); break;
+ case BIFF12_ID_PAGESETUP: getPageSettings().importPageSetup( getRelations(), rStrm ); break;
+ case BIFF12_ID_PRINTOPTIONS: getPageSettings().importPrintOptions( rStrm ); break;
+ case BIFF12_ID_HEADERFOOTER: getPageSettings().importHeaderFooter( rStrm ); break;
+ case BIFF12_ID_PICTURE: getPageSettings().importPicture( getRelations(), rStrm ); break;
+ case BIFF12_ID_SHEETPROTECTION: getWorksheetSettings().importSheetProtection( rStrm ); break;
+ case BIFF12_ID_PHONETICPR: getWorksheetSettings().importPhoneticPr( rStrm ); break;
+ case BIFF12_ID_DRAWING: importDrawing( rStrm ); break;
+ case BIFF12_ID_LEGACYDRAWING: importLegacyDrawing( rStrm ); break;
+ }
+ break;
+
+ case BIFF12_ID_SHEETVIEWS:
+ switch( nRecId )
+ {
+ case BIFF12_ID_SHEETVIEW: getSheetViewSettings().importSheetView( rStrm ); return this;
+ }
+ break;
+ case BIFF12_ID_SHEETVIEW:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PANE: getSheetViewSettings().importPane( rStrm ); break;
+ case BIFF12_ID_SELECTION: getSheetViewSettings().importSelection( rStrm ); break;
+ }
+ break;
+
+ case BIFF12_ID_COLS:
+ if( nRecId == BIFF12_ID_COL ) importCol( rStrm );
+ break;
+ case BIFF12_ID_MERGECELLS:
+ if( nRecId == BIFF12_ID_MERGECELL ) importMergeCell( rStrm );
+ break;
+ case BIFF12_ID_ROWBREAKS:
+ if( nRecId == BIFF12_ID_BRK ) importBrk( rStrm, true );
+ break;
+ case BIFF12_ID_COLBREAKS:
+ if( nRecId == BIFF12_ID_BRK ) importBrk( rStrm, false );
+ break;
+ case BIFF12_ID_OLEOBJECTS:
+ if( nRecId == BIFF12_ID_OLEOBJECT ) importOleObject( rStrm );
+ break;
+ case BIFF12_ID_CONTROLS:
+ if( nRecId == BIFF12_ID_CONTROL ) importControl( rStrm );
+ break;
+ }
+ return 0;
+}
+
+const RecordInfo* WorksheetFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_AUTOFILTER, BIFF12_ID_AUTOFILTER + 1 },
+ { BIFF12_ID_CFRULE, BIFF12_ID_CFRULE + 1 },
+ { BIFF12_ID_COLBREAKS, BIFF12_ID_COLBREAKS + 1 },
+ { BIFF12_ID_COLORSCALE, BIFF12_ID_COLORSCALE + 1 },
+ { BIFF12_ID_COLS, BIFF12_ID_COLS + 1 },
+ { BIFF12_ID_CONDFORMATTING, BIFF12_ID_CONDFORMATTING + 1 },
+ { BIFF12_ID_CONTROLS, BIFF12_ID_CONTROLS + 2 },
+ { BIFF12_ID_CUSTOMFILTERS, BIFF12_ID_CUSTOMFILTERS + 1 },
+ { BIFF12_ID_CUSTOMSHEETVIEW, BIFF12_ID_CUSTOMSHEETVIEW + 1 },
+ { BIFF12_ID_CUSTOMSHEETVIEWS, BIFF12_ID_CUSTOMSHEETVIEWS + 3 },
+ { BIFF12_ID_DATABAR, BIFF12_ID_DATABAR + 1 },
+ { BIFF12_ID_DATAVALIDATIONS, BIFF12_ID_DATAVALIDATIONS + 1 },
+ { BIFF12_ID_DISCRETEFILTERS, BIFF12_ID_DISCRETEFILTERS + 1 },
+ { BIFF12_ID_FILTERCOLUMN, BIFF12_ID_FILTERCOLUMN + 1 },
+ { BIFF12_ID_HEADERFOOTER, BIFF12_ID_HEADERFOOTER + 1 },
+ { BIFF12_ID_ICONSET, BIFF12_ID_ICONSET + 1 },
+ { BIFF12_ID_MERGECELLS, BIFF12_ID_MERGECELLS + 1 },
+ { BIFF12_ID_OLEOBJECTS, BIFF12_ID_OLEOBJECTS + 2 },
+ { BIFF12_ID_ROW, -1 },
+ { BIFF12_ID_ROWBREAKS, BIFF12_ID_ROWBREAKS + 1 },
+ { BIFF12_ID_SCENARIO, BIFF12_ID_SCENARIO + 1 },
+ { BIFF12_ID_SCENARIOS, BIFF12_ID_SCENARIOS + 1 },
+ { BIFF12_ID_SHEETDATA, BIFF12_ID_SHEETDATA + 1 },
+ { BIFF12_ID_SHEETVIEW, BIFF12_ID_SHEETVIEW + 1 },
+ { BIFF12_ID_SHEETVIEWS, BIFF12_ID_SHEETVIEWS + 1 },
+ { BIFF12_ID_TABLEPARTS, BIFF12_ID_TABLEPARTS + 2 },
+ { BIFF12_ID_WORKSHEET, BIFF12_ID_WORKSHEET + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void WorksheetFragment::initializeImport()
+{
+ // initial processing in base class WorksheetHelper
+ initializeWorksheetImport();
+
+ // import query table fragments related to this worksheet
+ RelationsRef xQueryRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATION_TYPE( "queryTable" ) );
+ for( Relations::const_iterator aIt = xQueryRels->begin(), aEnd = xQueryRels->end(); aIt != aEnd; ++aIt )
+ importOoxFragment( new QueryTableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) );
+
+ // import pivot table fragments related to this worksheet
+ RelationsRef xPivotRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATION_TYPE( "pivotTable" ) );
+ for( Relations::const_iterator aIt = xPivotRels->begin(), aEnd = xPivotRels->end(); aIt != aEnd; ++aIt )
+ importOoxFragment( new PivotTableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) );
+}
+
+void WorksheetFragment::finalizeImport()
+{
+ // final processing in base class WorksheetHelper
+ finalizeWorksheetImport();
+}
+
+// private --------------------------------------------------------------------
+
+void WorksheetFragment::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 WorksheetFragment::importDimension( const AttributeList& rAttribs )
+{
+ CellRangeAddress aRange;
+ getAddressConverter().convertToCellRangeUnchecked( aRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex() );
+ /* OOXML stores the used area, if existing, or "A1" if the sheet is empty.
+ In case of "A1", the dimension at the WorksheetHelper object will not
+ be set. If the cell A1 exists, the used area will be updated while
+ importing the cell. */
+ if( (aRange.EndColumn > 0) || (aRange.EndRow > 0) )
+ extendUsedArea( aRange );
+}
+
+void WorksheetFragment::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 WorksheetFragment::importCol( const AttributeList& rAttribs )
+{
+ ColumnModel aModel;
+ aModel.mnFirstCol = rAttribs.getInteger( XML_min, -1 );
+ aModel.mnLastCol = rAttribs.getInteger( XML_max, -1 );
+ aModel.mfWidth = rAttribs.getDouble( XML_width, 0.0 );
+ aModel.mnXfId = rAttribs.getInteger( XML_style, -1 );
+ aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
+ aModel.mbShowPhonetic = rAttribs.getBool( XML_phonetic, false );
+ aModel.mbHidden = rAttribs.getBool( XML_hidden, false );
+ aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
+ // set column properties in the current sheet
+ setColumnModel( aModel );
+}
+
+void WorksheetFragment::importMergeCell( const AttributeList& rAttribs )
+{
+ CellRangeAddress aRange;
+ if( getAddressConverter().convertToCellRange( aRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex(), true, true ) )
+ setMergedRange( aRange );
+}
+
+void WorksheetFragment::importHyperlink( const AttributeList& rAttribs )
+{
+ HyperlinkModel aModel;
+ if( getAddressConverter().convertToCellRange( aModel.maRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex(), true, true ) )
+ {
+ aModel.maTarget = getRelations().getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ aModel.maLocation = rAttribs.getXString( XML_location, OUString() );
+ aModel.maDisplay = rAttribs.getXString( XML_display, OUString() );
+ aModel.maTooltip = rAttribs.getXString( XML_tooltip, OUString() );
+ setHyperlink( aModel );
+ }
+}
+
+void WorksheetFragment::importBrk( const AttributeList& rAttribs, bool bRowBreak )
+{
+ PageBreakModel aModel;
+ aModel.mnColRow = rAttribs.getInteger( XML_id, 0 );
+ aModel.mnMin = rAttribs.getInteger( XML_id, 0 );
+ aModel.mnMax = rAttribs.getInteger( XML_id, 0 );
+ aModel.mbManual = rAttribs.getBool( XML_man, false );
+ setPageBreak( aModel, bRowBreak );
+}
+
+void WorksheetFragment::importDrawing( const AttributeList& rAttribs )
+{
+ setDrawingPath( getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) ) );
+}
+
+void WorksheetFragment::importLegacyDrawing( const AttributeList& rAttribs )
+{
+ setVmlDrawingPath( getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) ) );
+}
+
+void WorksheetFragment::importOleObject( const AttributeList& rAttribs )
+{
+ ::oox::vml::OleObjectInfo aInfo;
+ aInfo.setShapeId( rAttribs.getInteger( XML_shapeId, 0 ) );
+ OSL_ENSURE( rAttribs.hasAttribute( XML_link ) != rAttribs.hasAttribute( R_TOKEN( id ) ),
+ "WorksheetFragment::importOleObject - OLE object must be either linked or embedded" );
+ aInfo.mbLinked = rAttribs.hasAttribute( XML_link );
+ if( aInfo.mbLinked )
+ aInfo.maTargetLink = getFormulaParser().importOleTargetLink( rAttribs.getString( XML_link, OUString() ) );
+ else if( rAttribs.hasAttribute( R_TOKEN( id ) ) )
+ importEmbeddedOleData( aInfo.maEmbeddedData, rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ aInfo.maProgId = rAttribs.getString( XML_progId, OUString() );
+ aInfo.mbShowAsIcon = rAttribs.getToken( XML_dvAspect, XML_DVASPECT_CONTENT ) == XML_DVASPECT_ICON;
+ aInfo.mbAutoUpdate = rAttribs.getToken( XML_oleUpdate, XML_OLEUPDATE_ONCALL ) == XML_OLEUPDATE_ALWAYS;
+ aInfo.mbAutoLoad = rAttribs.getBool( XML_autoLoad, false );
+ getVmlDrawing().registerOleObject( aInfo );
+}
+
+void WorksheetFragment::importControl( const AttributeList& rAttribs )
+{
+ ::oox::vml::ControlInfo aInfo;
+ aInfo.setShapeId( rAttribs.getInteger( XML_shapeId, 0 ) );
+ aInfo.maFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ aInfo.maName = rAttribs.getString( XML_name, OUString() );
+ getVmlDrawing().registerControl( aInfo );
+}
+
+void WorksheetFragment::importDimension( SequenceInputStream& rStrm )
+{
+ BinRange aBinRange;
+ aBinRange.read( rStrm );
+ CellRangeAddress aRange;
+ getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() );
+ /* BIFF12 stores the used area, if existing, or "A1" if the sheet is
+ empty. In case of "A1", the dimension at the WorksheetHelper object
+ will not be set. If the cell A1 exists, the used area will be updated
+ while importing the cell. */
+ if( (aRange.EndColumn > 0) || (aRange.EndRow > 0) )
+ extendUsedArea( aRange );
+}
+
+void WorksheetFragment::importSheetFormatPr( SequenceInputStream& 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 BIFF12, convert to entire character
+ setDefaultColumnWidth( static_cast< double >( nDefaultWidth ) / 256.0 );
+ // row height is in twips in BIFF12, convert to points; equal flags in all BIFFs
+ 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 WorksheetFragment::importCol( SequenceInputStream& rStrm )
+{
+ ColumnModel aModel;
+
+ sal_Int32 nWidth;
+ sal_uInt16 nFlags;
+ rStrm >> aModel.mnFirstCol >> aModel.mnLastCol >> nWidth >> aModel.mnXfId >> nFlags;
+
+ // column indexes are 0-based in BIFF12, but ColumnModel expects 1-based
+ ++aModel.mnFirstCol;
+ ++aModel.mnLastCol;
+ // width is stored as 1/256th of a character in BIFF12, convert to entire character
+ aModel.mfWidth = static_cast< double >( nWidth ) / 256.0;
+ // equal flags in all BIFFs
+ aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 );
+ aModel.mbShowPhonetic = getFlag( nFlags, BIFF_COLINFO_SHOWPHONETIC );
+ aModel.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN );
+ aModel.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED );
+ // set column properties in the current sheet
+ setColumnModel( aModel );
+}
+
+void WorksheetFragment::importMergeCell( SequenceInputStream& rStrm )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ CellRangeAddress aRange;
+ if( getAddressConverter().convertToCellRange( aRange, aBinRange, getSheetIndex(), true, true ) )
+ setMergedRange( aRange );
+}
+
+void WorksheetFragment::importHyperlink( SequenceInputStream& rStrm )
+{
+ BinRange aBinRange;
+ rStrm >> aBinRange;
+ HyperlinkModel aModel;
+ if( getAddressConverter().convertToCellRange( aModel.maRange, aBinRange, getSheetIndex(), true, true ) )
+ {
+ aModel.maTarget = getRelations().getExternalTargetFromRelId( BiffHelper::readString( rStrm ) );
+ rStrm >> aModel.maLocation >> aModel.maTooltip >> aModel.maDisplay;
+ setHyperlink( aModel );
+ }
+}
+
+void WorksheetFragment::importBrk( SequenceInputStream& rStrm, bool bRowBreak )
+{
+ PageBreakModel aModel;
+ sal_Int32 nManual;
+ rStrm >> aModel.mnColRow >> aModel.mnMin >> aModel.mnMax >> nManual;
+ aModel.mbManual = nManual != 0;
+ setPageBreak( aModel, bRowBreak );
+}
+
+void WorksheetFragment::importDrawing( SequenceInputStream& rStrm )
+{
+ setDrawingPath( getFragmentPathFromRelId( BiffHelper::readString( rStrm ) ) );
+}
+
+void WorksheetFragment::importLegacyDrawing( SequenceInputStream& rStrm )
+{
+ setVmlDrawingPath( getFragmentPathFromRelId( BiffHelper::readString( rStrm ) ) );
+}
+
+void WorksheetFragment::importOleObject( SequenceInputStream& rStrm )
+{
+ ::oox::vml::OleObjectInfo aInfo;
+ sal_Int32 nAspect, nUpdateMode, nShapeId;
+ sal_uInt16 nFlags;
+ rStrm >> nAspect >> nUpdateMode >> nShapeId >> nFlags >> aInfo.maProgId;
+ aInfo.mbLinked = getFlag( nFlags, BIFF12_OLEOBJECT_LINKED );
+ if( aInfo.mbLinked )
+ aInfo.maTargetLink = getFormulaParser().importOleTargetLink( rStrm );
+ else
+ importEmbeddedOleData( aInfo.maEmbeddedData, BiffHelper::readString( rStrm ) );
+ aInfo.setShapeId( nShapeId );
+ aInfo.mbShowAsIcon = nAspect == BIFF12_OLEOBJECT_ICON;
+ aInfo.mbAutoUpdate = nUpdateMode == BIFF12_OLEOBJECT_ALWAYS;
+ aInfo.mbAutoLoad = getFlag( nFlags, BIFF12_OLEOBJECT_AUTOLOAD );
+ getVmlDrawing().registerOleObject( aInfo );
+}
+
+void WorksheetFragment::importControl( SequenceInputStream& rStrm )
+{
+ ::oox::vml::ControlInfo aInfo;
+ aInfo.setShapeId( rStrm.readInt32() );
+ aInfo.maFragmentPath = getFragmentPathFromRelId( BiffHelper::readString( rStrm ) );
+ rStrm >> aInfo.maName;
+ getVmlDrawing().registerControl( aInfo );
+}
+
+void WorksheetFragment::importEmbeddedOleData( StreamDataSequence& orEmbeddedData, const OUString& rRelId )
+{
+ OUString aFragmentPath = getFragmentPathFromRelId( rRelId );
+ if( aFragmentPath.getLength() > 0 )
+ getBaseFilter().importBinaryData( orEmbeddedData, aFragmentPath );
+}
+
+// ============================================================================
+
+BiffWorksheetFragment::BiffWorksheetFragment( const BiffWorkbookFragmentBase& rParent,
+ const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ BiffWorksheetFragmentBase( rParent, rxProgressBar, eSheetType, nSheet )
+{
+}
+
+BiffWorksheetFragment::~BiffWorksheetFragment()
+{
+}
+
+bool BiffWorksheetFragment::importFragment()
+{
+ // 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
+ BiffInputStream& rStrm = getInputStream();
+ while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
+ {
+ if( BiffHelper::isBofRecord( rStrm ) )
+ {
+ // skip unknown embedded fragments (BOF/EOF blocks)
+ skipFragment();
+ }
+ else
+ {
+ // cache base stream position to detect if record is already processed
+ sal_Int64 nStrmPos = rStrm.tellBase();
+ sal_uInt16 nRecId = rStrm.getRecId();
+
+ 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_AUTOFILTER: importAutoFilter( rStrm ); break;
+ 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_PTDEFINITION: importPTDefinition( 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_AUTOFILTER: importAutoFilter( rStrm ); break;
+ case BIFF_ID_CFHEADER: rCondFormats.importCfHeader( rStrm ); break;
+ case BIFF_ID_CODENAME: rWorksheetSett.importCodeName( 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_PAGESETUP: rPageSett.importPageSetup( rStrm ); break;
+ case BIFF_ID_PHONETICPR: rWorksheetSett.importPhoneticPr( rStrm ); break;
+ case BIFF_ID_PICTURE: rPageSett.importPicture( rStrm ); break;
+ case BIFF_ID_PTDEFINITION: importPTDefinition( rStrm ); break;
+ case BIFF_ID_QUERYTABLE: importQueryTable( rStrm ); break;
+ case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( rStrm ); break;
+ case BIFF_ID_SCENARIOS: importScenarios( rStrm ); break;
+ case BIFF_ID_SCENPROTECT: rWorksheetSett.importScenProtect( rStrm ); break;
+ case BIFF_ID_SCL: rSheetViewSett.importScl( rStrm ); break;
+ case BIFF_ID_SHEETEXT: rWorksheetSett.importSheetExt( rStrm ); break;
+ case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( rStrm ); break;
+ case BIFF_ID_SHAREDFEATHEAD: importSharedFeatHead( 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 record context objects
+ if( rStrm.tellBase() == nStrmPos )
+ {
+ // first, try cell table records
+ aSheetData.importRecord( rStrm );
+ // handle another open record context
+ if( mxContext.get() )
+ {
+ // if it was a cell table record, forget the other record context
+ if( rStrm.tellBase() == nStrmPos )
+ mxContext->importRecord( rStrm );
+ else
+ mxContext.reset();
+ }
+ }
+ }
+ }
+
+ // final processing in base class WorksheetHelper
+ finalizeWorksheetImport();
+ return rStrm.getRecId() == BIFF_ID_EOF;
+}
+
+// private --------------------------------------------------------------------
+
+void BiffWorksheetFragment::importAutoFilter( BiffInputStream& rStrm )
+{
+ mxContext.reset( new BiffAutoFilterContext( *this, getAutoFilters().createAutoFilter() ) );
+ mxContext->importRecord( rStrm );
+}
+
+void BiffWorksheetFragment::importColInfo( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFirstCol, nLastCol, nWidth, nXfId, nFlags;
+ rStrm >> nFirstCol >> nLastCol >> nWidth >> nXfId >> nFlags;
+
+ ColumnModel aModel;
+ // column indexes are 0-based in BIFF, but ColumnModel expects 1-based
+ aModel.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1;
+ aModel.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1;
+ // width is stored as 1/256th of a character in BIFF, convert to entire character
+ aModel.mfWidth = static_cast< double >( nWidth ) / 256.0;
+ aModel.mnXfId = nXfId;
+ aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 );
+ aModel.mbShowPhonetic = getFlag( nFlags, BIFF_COLINFO_SHOWPHONETIC );
+ aModel.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN );
+ aModel.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED );
+ // set column properties in the current sheet
+ setColumnModel( aModel );
+}
+
+void BiffWorksheetFragment::importColumnDefault( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFirstCol, nLastCol, nXfId;
+ rStrm >> nFirstCol >> nLastCol >> nXfId;
+ setDefaultColumnFormat( nFirstCol, nLastCol, nXfId );
+}
+
+void BiffWorksheetFragment::importColWidth( BiffInputStream& rStrm )
+{
+ sal_uInt8 nFirstCol, nLastCol;
+ sal_uInt16 nWidth;
+ rStrm >> nFirstCol >> nLastCol >> nWidth;
+
+ ColumnModel aModel;
+ // column indexes are 0-based in BIFF, but ColumnModel expects 1-based
+ aModel.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1;
+ aModel.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1;
+ // width is stored as 1/256th of a character in BIFF, convert to entire character
+ aModel.mfWidth = static_cast< double >( nWidth ) / 256.0;
+ // set column properties in the current sheet
+ setColumnModel( aModel );
+}
+
+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
+}
+
+namespace {
+
+OUString lclReadDataValMessage( BiffInputStream& rStrm )
+{
+ // empty strings are single NUL characters (string length is 1)
+ OUString aMessage = rStrm.readUniString( true );
+ if( (aMessage.getLength() == 1) && (aMessage[ 0 ] == 0) )
+ aMessage = OUString();
+ return aMessage;
+}
+
+ApiTokenSequence lclReadDataValFormula( BiffInputStream& rStrm, FormulaParser& rParser )
+{
+ sal_uInt16 nFmlaSize = rStrm.readuInt16();
+ rStrm.skip( 2 );
+ // enable NUL characters, string list is single tStr token with NUL separators
+ TokensFormulaContext aContext( true, false, true );
+ rParser.importFormula( aContext, rStrm, &nFmlaSize );
+ return aContext.getTokens();
+}
+
+} // namespace
+
+void BiffWorksheetFragment::importDataValidation( BiffInputStream& rStrm )
+{
+ ValidationModel aModel;
+
+ // flags
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+ aModel.setBiffType( extractValue< sal_uInt8 >( nFlags, 0, 4 ) );
+ aModel.setBiffOperator( extractValue< sal_uInt8 >( nFlags, 20, 4 ) );
+ aModel.setBiffErrorStyle( extractValue< sal_uInt8 >( nFlags, 4, 3 ) );
+ aModel.mbAllowBlank = getFlag( nFlags, BIFF_DATAVAL_ALLOWBLANK );
+ aModel.mbNoDropDown = getFlag( nFlags, BIFF_DATAVAL_NODROPDOWN );
+ aModel.mbShowInputMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWINPUT );
+ aModel.mbShowErrorMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWERROR );
+
+ // message strings
+ aModel.maInputTitle = lclReadDataValMessage( rStrm );
+ aModel.maErrorTitle = lclReadDataValMessage( rStrm );
+ aModel.maInputMessage = lclReadDataValMessage( rStrm );
+ aModel.maErrorMessage = lclReadDataValMessage( rStrm );
+
+ // condition formula(s)
+ FormulaParser& rParser = getFormulaParser();
+ aModel.maTokens1 = lclReadDataValFormula( rStrm, rParser );
+ aModel.maTokens2 = lclReadDataValFormula( rStrm, rParser );
+ // process string list of a list validation (convert to list of string tokens)
+ if( (aModel.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) )
+ rParser.convertStringToStringList( aModel.maTokens1, '\0', true );
+
+ // cell range list
+ BinRangeList aRanges;
+ rStrm >> aRanges;
+ getAddressConverter().convertToCellRangeList( aModel.maRanges, aRanges, getSheetIndex(), true );
+
+ // set validation data
+ setValidation( aModel );
+}
+
+void BiffWorksheetFragment::importDimension( BiffInputStream& rStrm )
+{
+ // 32-bit row indexes in BIFF8
+ bool bInt32Rows = (rStrm.getRecId() == BIFF3_ID_DIMENSION) && (getBiff() == BIFF8);
+ BinRange aBinRange;
+ aBinRange.read( rStrm, true, bInt32Rows );
+ /* BIFF stores the used area with end column and end row increased by 1
+ (first unused column and row). */
+ if( (aBinRange.maFirst.mnCol < aBinRange.maLast.mnCol) && (aBinRange.maFirst.mnRow < aBinRange.maLast.mnRow) )
+ {
+ // reduce range to used area
+ --aBinRange.maLast.mnCol;
+ --aBinRange.maLast.mnRow;
+ CellRangeAddress aRange;
+ getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() );
+ extendUsedArea( aRange );
+ }
+}
+
+void BiffWorksheetFragment::importHyperlink( BiffInputStream& rStrm )
+{
+ HyperlinkModel aModel;
+
+ // 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( aModel.maRange, aBiffRange, getSheetIndex(), true, true ) )
+ return;
+
+ // try to read the StdHlink data
+ if( !::oox::ole::OleHelper::importStdHlink( aModel, rStrm, true ) )
+ return;
+
+ // try to read the optional following 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, true ) &&
+ (aRange.StartColumn == aModel.maRange.StartColumn) &&
+ (aRange.StartRow == aModel.maRange.StartRow) &&
+ (aRange.EndColumn == aModel.maRange.EndColumn) &&
+ (aRange.EndRow == aModel.maRange.EndRow) )
+ {
+ /* This time, we have no string length, no flag field, and a
+ null-terminated 16-bit character array. */
+ aModel.maTooltip = rStrm.readNulUnicodeArray();
+ }
+ }
+
+ // store the hyperlink settings
+ setHyperlink( aModel );
+}
+
+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 )
+{
+ PageBreakModel aModel;
+ aModel.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.isEof() && (nIndex < nCount); ++nIndex )
+ {
+ aModel.mnColRow = rStrm.readuInt16();
+ setPageBreak( aModel, bRowBreak );
+ if( bBiff8 )
+ rStrm.skip( 4 );
+ }
+}
+
+void BiffWorksheetFragment::importPTDefinition( BiffInputStream& rStrm )
+{
+ mxContext.reset( new BiffPivotTableContext( *this ) );
+ mxContext->importRecord( rStrm );
+}
+
+void BiffWorksheetFragment::importQueryTable( BiffInputStream& rStrm )
+{
+ mxContext.reset( new BiffQueryTableContext( *this ) );
+ mxContext->importRecord( rStrm );
+}
+
+void BiffWorksheetFragment::importScenarios( BiffInputStream& rStrm )
+{
+ getScenarios().createSheetScenarios( getSheetIndex() ).importScenarios( rStrm );
+}
+
+void BiffWorksheetFragment::importSharedFeatHead( BiffInputStream& rStrm )
+{
+ rStrm.skip( 12 );
+ sal_uInt16 nType = rStrm.readuInt16();
+ rStrm.skip( 5 );
+ switch( nType )
+ {
+ case BIFF_SHRFEATHEAD_SHEETPROT:
+ if( rStrm.getRemaining() >= 4 )
+ getWorksheetSettings().importSheetProtection( rStrm );
+ break;
+ }
+}
+
+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 );
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx
new file mode 100644
index 000000000000..48ffac388cfd
--- /dev/null
+++ b/oox/source/xls/worksheethelper.cxx
@@ -0,0 +1,2291 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheethelper.hxx"
+
+#include <algorithm>
+#include <list>
+#include <utility>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/TableValidationVisibility.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/ValidationAlertStyle.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/XLabelRanges.hpp>
+#include <com/sun/star/sheet/XMultiFormulaTokens.hpp>
+#include <com/sun/star/sheet/XMultipleOperation.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+#include <com/sun/star/sheet/XSheetOutline.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/xls/addressconverter.hxx"
+#include "oox/xls/autofilterbuffer.hxx"
+#include "oox/xls/commentsbuffer.hxx"
+#include "oox/xls/condformatbuffer.hxx"
+#include "oox/xls/drawingfragment.hxx"
+#include "oox/xls/formulaparser.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/querytablebuffer.hxx"
+#include "oox/xls/sharedformulabuffer.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/stylesbuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+#include "oox/xls/worksheetsettings.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+namespace {
+
+void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, const CellRangeAddress& rUsedArea, sal_Int32 nRow )
+{
+ if( rxProgressBar.get() && (rUsedArea.StartRow <= nRow) && (nRow <= rUsedArea.EndRow) )
+ {
+ double fPosition = static_cast< double >( nRow - rUsedArea.StartRow + 1 ) / (rUsedArea.EndRow - rUsedArea.StartRow + 1);
+ if( rxProgressBar->getPosition() < fPosition )
+ rxProgressBar->setPosition( fPosition );
+ }
+}
+
+void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, double fPosition )
+{
+ if( rxProgressBar.get() )
+ rxProgressBar->setPosition( fPosition );
+}
+
+// ----------------------------------------------------------------------------
+
+struct ValueRange
+{
+ sal_Int32 mnFirst;
+ sal_Int32 mnLast;
+
+ inline explicit ValueRange( sal_Int32 nValue ) : mnFirst( nValue ), mnLast( nValue ) {}
+ inline explicit ValueRange( sal_Int32 nFirst, sal_Int32 nLast ) : mnFirst( nFirst ), mnLast( nLast ) {}
+};
+
+typedef ::std::vector< ValueRange > ValueRangeVector;
+
+// ----------------------------------------------------------------------------
+
+struct ValueRangeComp
+{
+ inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; }
+};
+
+typedef ::std::vector< ValueRange > ValueRangeVector;
+
+// ----------------------------------------------------------------------------
+
+class ValueRangeSet
+{
+public:
+ inline explicit ValueRangeSet() {}
+
+ void insert( sal_Int32 nValue );
+ void intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const;
+
+private:
+ ValueRangeVector maData;
+};
+
+void ValueRangeSet::insert( sal_Int32 nValue )
+{
+ // find the first range that contains nValue or that follows nValue
+ ValueRangeVector::iterator aBeg = maData.begin();
+ ValueRangeVector::iterator aEnd = maData.end();
+ ValueRangeVector::iterator aNext = ::std::lower_bound( aBeg, aEnd, nValue, ValueRangeComp() );
+
+ // nothing to do if found range contains nValue
+ if( (aNext == aEnd) || (nValue < aNext->mnFirst) )
+ {
+ ValueRangeVector::iterator aPrev = (aNext == aBeg) ? aEnd : (aNext - 1);
+ bool bJoinPrev = (aPrev != aEnd) && (aPrev->mnLast + 1 == nValue);
+ bool bJoinNext = (aNext != aEnd) && (aNext->mnFirst - 1 == nValue);
+ if( bJoinPrev && bJoinNext )
+ {
+ aPrev->mnLast = aNext->mnLast;
+ maData.erase( aNext );
+ }
+ else if( bJoinPrev )
+ ++aPrev->mnLast;
+ else if( bJoinNext )
+ --aNext->mnFirst;
+ else
+ maData.insert( aNext, ValueRange( nValue ) );
+ }
+}
+
+void ValueRangeSet::intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const
+{
+ orRanges.clear();
+ // find the range that contains nFirst or the first range that follows nFirst
+ ValueRangeVector::const_iterator aIt = ::std::lower_bound( maData.begin(), maData.end(), nFirst, ValueRangeComp() );
+ for( ValueRangeVector::const_iterator aEnd = maData.end(); (aIt != aEnd) && (aIt->mnFirst <= nLast); ++aIt )
+ orRanges.push_back( ValueRange( ::std::max( aIt->mnFirst, nFirst ), ::std::min( aIt->mnLast, nLast ) ) );
+}
+
+} // namespace
+
+// ============================================================================
+// ============================================================================
+
+void CellModel::reset()
+{
+ mxCell.clear();
+ maValueStr = maFormulaRef = OUString();
+ mnCellType = mnFormulaType = XML_TOKEN_INVALID;
+ mnSharedId = mnXfId = mnNumFmtId = -1;
+ mbHasValueStr = mbShowPhonetic = false;
+}
+
+// ----------------------------------------------------------------------------
+
+DataTableModel::DataTableModel() :
+ mb2dTable( false ),
+ mbRowTable( false ),
+ mbRef1Deleted( false ),
+ mbRef2Deleted( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ColumnModel::ColumnModel() :
+ mnFirstCol( -1 ),
+ mnLastCol( -1 ),
+ mfWidth( 0.0 ),
+ mnXfId( -1 ),
+ mnLevel( 0 ),
+ mbShowPhonetic( false ),
+ mbHidden( false ),
+ mbCollapsed( false )
+{
+}
+
+bool ColumnModel::tryExpand( const ColumnModel& rModel )
+{
+ bool bExpandable =
+ (mnFirstCol <= rModel.mnFirstCol) &&
+ (rModel.mnFirstCol <= mnLastCol + 1) &&
+ (mfWidth == rModel.mfWidth) &&
+ // ignore mnXfId, cell formatting is always set directly
+ (mnLevel == rModel.mnLevel) &&
+ (mbHidden == rModel.mbHidden) &&
+ (mbCollapsed == rModel.mbCollapsed);
+
+ if( bExpandable )
+ mnLastCol = rModel.mnLastCol;
+ return bExpandable;
+}
+
+// ----------------------------------------------------------------------------
+
+RowModel::RowModel() :
+ 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 RowModel::tryExpand( const RowModel& rModel )
+{
+ bool bExpandable =
+ (mnFirstRow <= rModel.mnFirstRow) &&
+ (rModel.mnFirstRow <= mnLastRow + 1) &&
+ (mfHeight == rModel.mfHeight) &&
+ // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly
+ (mnLevel == rModel.mnLevel) &&
+ (mbCustomHeight == rModel.mbCustomHeight) &&
+ (mbHidden == rModel.mbHidden) &&
+ (mbCollapsed == rModel.mbCollapsed);
+
+ if( bExpandable )
+ mnLastRow = rModel.mnLastRow;
+ return bExpandable;
+}
+
+// ----------------------------------------------------------------------------
+
+PageBreakModel::PageBreakModel() :
+ mnColRow( 0 ),
+ mbManual( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+HyperlinkModel::HyperlinkModel()
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ValidationModel::ValidationModel() :
+ mnType( XML_none ),
+ mnOperator( XML_between ),
+ mnErrorStyle( XML_stop ),
+ mbShowInputMsg( false ),
+ mbShowErrorMsg( false ),
+ mbNoDropDown( false ),
+ mbAllowBlank( false )
+{
+}
+
+void ValidationModel::setBiffType( 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 ValidationModel::setBiffOperator( 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 ValidationModel::setBiffErrorStyle( 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,
+ const ISegmentProgressBarRef& rxProgressBar,
+ WorksheetType eSheetType,
+ sal_Int16 nSheet );
+
+ /** Returns true, if this helper refers to an existing Calc sheet. */
+ inline bool isValidSheet() const { return mxSheet.is(); }
+
+ /** 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 maUsedArea.Sheet; }
+ /** Returns the XSpreadsheet interface of the current sheet. */
+ inline const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >&
+ getSheet() 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 XDrawPage interface of the draw page of the current sheet. */
+ Reference< XDrawPage > getDrawPage() const;
+ /** Returns the size of the entire drawing page in 1/100 mm. */
+ Size getDrawPageSize() const;
+
+ /** Returns the absolute position of the top-left corner of the cell in 1/100 mm. */
+ Point getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const;
+ /** Returns the size of the cell in 1/100 mm. */
+ Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const;
+
+ /** Returns the address of the cell that contains the passed point in 1/100 mm. */
+ CellAddress getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const;
+ /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */
+ CellRangeAddress getCellRangeFromRectangle( const Rectangle& rRect ) 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 buffer for all cell comments in this sheet. */
+ inline CommentsBuffer& getComments() { return maComments; }
+ /** Returns the auto filters for the sheet. */
+ inline AutoFilterBuffer& getAutoFilters() { return maAutoFilters; }
+ /** Returns the buffer for all web query tables in this sheet. */
+ inline QueryTableBuffer& getQueryTables() { return maQueryTables; }
+ /** 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; }
+ /** Returns the VML drawing page for this sheet (OOXML/BIFF12 only!). */
+ inline VmlDrawing& getVmlDrawing() { return *mxVmlDrawing; }
+
+ /** Changes the current sheet type. */
+ inline void setSheetType( WorksheetType eSheetType ) { meSheetType = eSheetType; }
+ /** Stores the cell format at the passed address. */
+ void setCellFormat( const CellModel& rModel );
+ /** 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 PageBreakModel& rModel, bool bRowBreak );
+ /** Inserts the hyperlink URL into the spreadsheet. */
+ void setHyperlink( const HyperlinkModel& rModel );
+ /** Inserts the data validation settings into the spreadsheet. */
+ void setValidation( const ValidationModel& rModel );
+ /** Sets the path to the DrawingML fragment of this sheet. */
+ void setDrawingPath( const OUString& rDrawingPath );
+ /** Sets the path to the legacy VML drawing fragment of this sheet. */
+ void setVmlDrawingPath( const OUString& rVmlDrawingPath );
+
+ /** Extends the used area of this sheet by the passed cell position. */
+ void extendUsedArea( const CellAddress& rAddress );
+ /** Extends the used area of this sheet by the passed cell range. */
+ void extendUsedArea( const CellRangeAddress& rRange );
+ /** Extends the shape bounding box by the position and size of the passed rectangle. */
+ void extendShapeBoundingBox( const Rectangle& rShapeRect );
+
+ /** 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 setColumnModel( const ColumnModel& rModel );
+
+ /** 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 setRowModel( const RowModel& rModel );
+
+ /** Converts column default cell formatting. */
+ void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const;
+ /** Converts row default cell formatting. */
+ void convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) const;
+
+ /** 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, ColumnModel > ColumnModelMap;
+ typedef ::std::map< sal_Int32, RowModel > RowModelMap;
+ typedef ::std::list< HyperlinkModel > HyperlinkModelList;
+ typedef ::std::list< ValidationModel > ValidationModelList;
+
+ struct XfIdRowRange
+ {
+ sal_Int32 mnFirstRow; /// Index of first row.
+ sal_Int32 mnLastRow; /// Index of last row.
+ sal_Int32 mnXfId; /// XF identifier for the row range.
+
+ explicit XfIdRowRange();
+ bool intersects( const CellRangeAddress& rRange ) const;
+ void set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId );
+ bool tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId );
+ };
+
+ 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 CellModel& rModel );
+ bool tryExpand( const CellModel& rModel );
+ 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& rRange );
+ 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 row range. */
+ void writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const;
+ /** 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;
+ /** Generates the final URL for the passed hyperlink. */
+ OUString getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const;
+ /** Inserts a hyperlinks into the specified cell. */
+ void insertHyperlink( 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();
+ /** Merges the passed merged range and updates right/bottom cell borders. */
+ void finalizeMergedRange( const CellRangeAddress& rRange );
+
+ /** 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 ColumnModel& rModel );
+
+ /** 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 RowModel& rModel, 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 );
+
+ /** Imports the drawings of the sheet (DML, VML), and updates the used area. */
+ void finalizeDrawings();
+
+private:
+ typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr;
+
+ 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 maUrlTextField; /// Service name for a URL text field.
+ const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter.
+ CellRangeAddress maUsedArea; /// Used area of the sheet, and sheet index of the sheet.
+ ColumnModel maDefColModel; /// Default column formatting.
+ ColumnModelMap maColModels; /// Columns sorted by first column index.
+ RowModel maDefRowModel; /// Default row formatting.
+ RowModelMap maRowModels; /// Rows sorted by row index.
+ HyperlinkModelList maHyperlinks; /// Cell ranges containing hyperlinks.
+ ValidationModelList maValidations; /// Cell ranges containing data validation settings.
+ XfIdRowRange maXfIdRowRange; /// Cached XF identifier for a range of rows.
+ XfIdRangeMap maXfIdRanges; /// Collected XF identifiers for cell ranges.
+ MergedRangeList maMergedRanges; /// Merged cell ranges.
+ MergedRangeList maCenterFillRanges; /// Merged cell ranges from 'center across' or 'fill' alignment.
+ ValueRangeSet maManualRowHeights; /// Rows that need manual height independent from own settings.
+ WorksheetSettings maSheetSett; /// Global settings for this sheet.
+ SharedFormulaBuffer maSharedFmlas; /// Buffer for shared formulas in this sheet.
+ CondFormatBuffer maCondFormats; /// Buffer for conditional formattings.
+ CommentsBuffer maComments; /// Buffer for all cell comments in this sheet.
+ AutoFilterBuffer maAutoFilters; /// Sheet auto filters (not associated to a table).
+ QueryTableBuffer maQueryTables; /// Buffer for all web query tables in this sheet.
+ PageSettings maPageSett; /// Page/print settings for this sheet.
+ SheetViewSettings maSheetViewSett; /// View settings for this sheet.
+ VmlDrawingPtr mxVmlDrawing; /// Collection of all VML shapes.
+ OUString maDrawingPath; /// Path to DrawingML fragment.
+ OUString maVmlDrawingPath; /// Path to legacy VML drawing fragment.
+ Rectangle maShapeBoundingBox; /// Bounding box for all shapes from all drawings.
+ ISegmentProgressBarRef mxProgressBar; /// Sheet progress bar.
+ ISegmentProgressBarRef mxRowProgress; /// Progress bar for row/cell processing.
+ ISegmentProgressBarRef mxFinalProgress; /// Progress bar for finalization.
+ WorksheetType meSheetType; /// Type of this sheet.
+ Reference< XSpreadsheet > mxSheet; /// Reference to the current sheet.
+ bool mbHasDefWidth; /// True = default column width is set from defaultColWidth attribute.
+};
+
+// ----------------------------------------------------------------------------
+
+WorksheetData::WorksheetData( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ WorkbookHelper( rHelper ),
+ maTrueFormula( CREATE_OUSTRING( "=TRUE()" ) ),
+ maFalseFormula( CREATE_OUSTRING( "=FALSE()" ) ),
+ maSheetCellRanges( CREATE_OUSTRING( "com.sun.star.sheet.SheetCellRanges" ) ),
+ maUrlTextField( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ),
+ mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ),
+ maUsedArea( nSheet, SAL_MAX_INT32, SAL_MAX_INT32, -1, -1 ),
+ maSheetSett( *this ),
+ maSharedFmlas( *this ),
+ maCondFormats( *this ),
+ maComments( *this ),
+ maAutoFilters( *this ),
+ maQueryTables( *this ),
+ maPageSett( *this ),
+ maSheetViewSett( *this ),
+ mxProgressBar( rxProgressBar ),
+ meSheetType( eSheetType ),
+ mbHasDefWidth( false )
+{
+ mxSheet = getSheetFromDoc( nSheet );
+ if( !mxSheet.is() )
+ maUsedArea.Sheet = -1;
+
+ // default column settings (width and hidden state may be updated later)
+ maDefColModel.mfWidth = 8.5;
+ maDefColModel.mnXfId = -1;
+ maDefColModel.mnLevel = 0;
+ maDefColModel.mbHidden = false;
+ maDefColModel.mbCollapsed = false;
+
+ // default row settings (height and hidden state may be updated later)
+ maDefRowModel.mfHeight = 0.0;
+ maDefRowModel.mnXfId = -1;
+ maDefRowModel.mnLevel = 0;
+ maDefRowModel.mbCustomHeight = false;
+ maDefRowModel.mbCustomFormat = false;
+ maDefRowModel.mbShowPhonetic = false;
+ maDefRowModel.mbHidden = false;
+ maDefRowModel.mbCollapsed = false;
+
+ // buffers
+ if( getFilterType() == FILTER_OOXML )
+ mxVmlDrawing.reset( new VmlDrawing( *this ) );
+
+ // prepare progress bars
+ 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
+ {
+ xRanges.set( getDocumentFactory()->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(), UNO_SET_THROW );
+ 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(), UNO_SET_THROW );
+ 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( getSheetIndex(), 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( getSheetIndex(), 0, nFirstRow, 0, nLastRow ) ), UNO_QUERY );
+ if( xRange.is() )
+ xRows = xRange->getRows();
+ }
+ return xRows;
+}
+
+Reference< XDrawPage > WorksheetData::getDrawPage() const
+{
+ Reference< XDrawPage > xDrawPage;
+ try
+ {
+ xDrawPage = Reference< XDrawPageSupplier >( mxSheet, UNO_QUERY_THROW )->getDrawPage();
+ }
+ catch( Exception& )
+ {
+ }
+ return xDrawPage;
+}
+
+Size WorksheetData::getDrawPageSize() const
+{
+ Size aSize;
+ PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) );
+ aRangeProp.getProperty( aSize, PROP_Size );
+ return aSize;
+}
+
+Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ Point aPoint;
+ PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) );
+ aCellProp.getProperty( aPoint, PROP_Position );
+ return aPoint;
+}
+
+Size WorksheetData::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ Size aSize;
+ PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) );
+ aCellProp.getProperty( aSize, PROP_Size );
+ return aSize;
+}
+
+namespace {
+
+inline sal_Int32 lclGetMidAddr( sal_Int32 nBegAddr, sal_Int32 nEndAddr, sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos )
+{
+ // use sal_Int64 to prevent integer overflow
+ return nBegAddr + 1 + static_cast< sal_Int32 >( static_cast< sal_Int64 >( nEndAddr - nBegAddr - 2 ) * (nSearchPos - nBegPos) / (nEndPos - nBegPos) );
+}
+
+bool lclPrepareInterval( sal_Int32 nBegAddr, sal_Int32& rnMidAddr, sal_Int32 nEndAddr,
+ sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos )
+{
+ // searched position before nBegPos -> use nBegAddr
+ if( nSearchPos <= nBegPos )
+ {
+ rnMidAddr = nBegAddr;
+ return false;
+ }
+
+ // searched position after nEndPos, or begin next to end -> use nEndAddr
+ if( (nSearchPos >= nEndPos) || (nBegAddr + 1 >= nEndAddr) )
+ {
+ rnMidAddr = nEndAddr;
+ return false;
+ }
+
+ /* Otherwise find mid address according to position. lclGetMidAddr() will
+ return an address between nBegAddr and nEndAddr. */
+ rnMidAddr = lclGetMidAddr( nBegAddr, nEndAddr, nBegPos, nEndPos, nSearchPos );
+ return true;
+}
+
+bool lclUpdateInterval( sal_Int32& rnBegAddr, sal_Int32& rnMidAddr, sal_Int32& rnEndAddr,
+ sal_Int32& rnBegPos, sal_Int32 nMidPos, sal_Int32& rnEndPos, sal_Int32 nSearchPos )
+{
+ // nSearchPos < nMidPos: use the interval [begin,mid] in the next iteration
+ if( nSearchPos < nMidPos )
+ {
+ // if rnBegAddr is next to rnMidAddr, the latter is the column/row in question
+ if( rnBegAddr + 1 >= rnMidAddr )
+ return false;
+ // otherwise, set interval end to mid
+ rnEndPos = nMidPos;
+ rnEndAddr = rnMidAddr;
+ rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos );
+ return true;
+ }
+
+ // nSearchPos > nMidPos: use the interval [mid,end] in the next iteration
+ if( nSearchPos > nMidPos )
+ {
+ // if rnMidAddr is next to rnEndAddr, the latter is the column/row in question
+ if( rnMidAddr + 1 >= rnEndAddr )
+ {
+ rnMidAddr = rnEndAddr;
+ return false;
+ }
+ // otherwise, set interval start to mid
+ rnBegPos = nMidPos;
+ rnBegAddr = rnMidAddr;
+ rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos );
+ return true;
+ }
+
+ // nSearchPos == nMidPos: rnMidAddr is the column/row in question, do not loop anymore
+ return false;
+}
+
+} // namespace
+
+CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const
+{
+ // starting cell address and its position in drawing layer (top-left edge)
+ sal_Int32 nBegCol = 0;
+ sal_Int32 nBegRow = 0;
+ Point aBegPos( 0, 0 );
+
+ // end cell address and its position in drawing layer (bottom-right edge)
+ sal_Int32 nEndCol = mrMaxApiPos.Column + 1;
+ sal_Int32 nEndRow = mrMaxApiPos.Row + 1;
+ Point aEndPos( rDrawPageSize.Width, rDrawPageSize.Height );
+
+ // starting point for interval search
+ sal_Int32 nMidCol, nMidRow;
+ bool bLoopCols = lclPrepareInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aEndPos.X, rPosition.X );
+ bool bLoopRows = lclPrepareInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aEndPos.Y, rPosition.Y );
+ Point aMidPos = getCellPosition( nMidCol, nMidRow );
+
+ /* The loop will find the column/row index of the cell right of/below
+ the cell containing the passed point, unless the point is located at
+ the top or left border of the containing cell. */
+ while( bLoopCols || bLoopRows )
+ {
+ bLoopCols = bLoopCols && lclUpdateInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aMidPos.X, aEndPos.X, rPosition.X );
+ bLoopRows = bLoopRows && lclUpdateInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aMidPos.Y, aEndPos.Y, rPosition.Y );
+ aMidPos = getCellPosition( nMidCol, nMidRow );
+ }
+
+ /* The cell left of/above the current search position contains the passed
+ point, unless the point is located on the top/left border of the cell,
+ or the last column/row of the sheet has been reached. */
+ if( aMidPos.X > rPosition.X ) --nMidCol;
+ if( aMidPos.Y > rPosition.Y ) --nMidRow;
+ return CellAddress( getSheetIndex(), nMidCol, nMidRow );
+}
+
+CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRect ) const
+{
+ Size aPageSize = getDrawPageSize();
+ CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ), aPageSize );
+ Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height );
+ CellAddress aEndAddr = getCellAddressFromPosition( aBotRight, aPageSize );
+ bool bMultiCols = aStartAddr.Column < aEndAddr.Column;
+ bool bMultiRows = aStartAddr.Row < aEndAddr.Row;
+ if( bMultiCols || bMultiRows )
+ {
+ /* Reduce end position of the cell range to previous column or row, if
+ the rectangle ends exactly between two columns or rows. */
+ Point aEndPos = getCellPosition( aEndAddr.Column, aEndAddr.Row );
+ if( bMultiCols && (aBotRight.X <= aEndPos.X) )
+ --aEndAddr.Column;
+ if( bMultiRows && (aBotRight.Y <= aEndPos.Y) )
+ --aEndAddr.Row;
+ }
+ return CellRangeAddress( getSheetIndex(), aStartAddr.Column, aStartAddr.Row, aEndAddr.Column, aEndAddr.Row );
+}
+
+void WorksheetData::setCellFormat( const CellModel& rModel )
+{
+ if( rModel.mxCell.is() && ((rModel.mnXfId >= 0) || (rModel.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( rModel.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 )
+ {
+ // check that range cannot be merged with current row, and that range is not in cached row range
+ if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) )
+ {
+ 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( rModel ) )
+ maXfIdRanges[ RowColKey( rModel.maAddress.Row, rModel.maAddress.Column ) ].set( rModel );
+
+ // update merged ranges for 'center across selection' and 'fill'
+ if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() )
+ {
+ sal_Int32 nHorAlign = pXf->getAlignment().getModel().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( rModel.mnCellType != XML_TOKEN_INVALID )
+ maCenterFillRanges.push_back( MergedRange( rModel.maAddress, nHorAlign ) );
+ else if( !maCenterFillRanges.empty() )
+ maCenterFillRanges.rbegin()->tryExpand( rModel.maAddress, nHorAlign );
+ }
+ }
+ }
+}
+
+void WorksheetData::setMergedRange( const CellRangeAddress& rRange )
+{
+ maMergedRanges.push_back( MergedRange( rRange ) );
+}
+
+void WorksheetData::setPageBreak( const PageBreakModel& rModel, bool bRowBreak )
+{
+ if( rModel.mbManual && (rModel.mnColRow > 0) )
+ {
+ PropertySet aPropSet( bRowBreak ? getRow( rModel.mnColRow ) : getColumn( rModel.mnColRow ) );
+ aPropSet.setProperty( PROP_IsStartOfNewPage, true );
+ }
+}
+
+void WorksheetData::setHyperlink( const HyperlinkModel& rModel )
+{
+ maHyperlinks.push_back( rModel );
+}
+
+void WorksheetData::setValidation( const ValidationModel& rModel )
+{
+ maValidations.push_back( rModel );
+}
+
+void WorksheetData::setDrawingPath( const OUString& rDrawingPath )
+{
+ maDrawingPath = rDrawingPath;
+}
+
+void WorksheetData::setVmlDrawingPath( const OUString& rVmlDrawingPath )
+{
+ maVmlDrawingPath = rVmlDrawingPath;
+}
+
+void WorksheetData::extendUsedArea( const CellAddress& rAddress )
+{
+ maUsedArea.StartColumn = ::std::min( maUsedArea.StartColumn, rAddress.Column );
+ maUsedArea.StartRow = ::std::min( maUsedArea.StartRow, rAddress.Row );
+ maUsedArea.EndColumn = ::std::max( maUsedArea.EndColumn, rAddress.Column );
+ maUsedArea.EndRow = ::std::max( maUsedArea.EndRow, rAddress.Row );
+}
+
+void WorksheetData::extendUsedArea( const CellRangeAddress& rRange )
+{
+ extendUsedArea( CellAddress( rRange.Sheet, rRange.StartColumn, rRange.StartRow ) );
+ extendUsedArea( CellAddress( rRange.Sheet, rRange.EndColumn, rRange.EndRow ) );
+}
+
+void WorksheetData::extendShapeBoundingBox( const Rectangle& rShapeRect )
+{
+ if( (maShapeBoundingBox.Width == 0) && (maShapeBoundingBox.Height == 0) )
+ {
+ // width and height of maShapeBoundingBox are assumed to be zero on first cell
+ maShapeBoundingBox = rShapeRect;
+ }
+ else
+ {
+ sal_Int32 nEndX = ::std::max( maShapeBoundingBox.X + maShapeBoundingBox.Width, rShapeRect.X + rShapeRect.Width );
+ sal_Int32 nEndY = ::std::max( maShapeBoundingBox.Y + maShapeBoundingBox.Height, rShapeRect.Y + rShapeRect.Height );
+ maShapeBoundingBox.X = ::std::min( maShapeBoundingBox.X, rShapeRect.X );
+ maShapeBoundingBox.Y = ::std::min( maShapeBoundingBox.Y, rShapeRect.Y );
+ maShapeBoundingBox.Width = nEndX - maShapeBoundingBox.X;
+ maShapeBoundingBox.Height = nEndY - maShapeBoundingBox.Y;
+ }
+}
+
+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
+ const UnitConverter& rUnitConv = getUnitConverter();
+ maDefColModel.mfWidth = rUnitConv.scaleFromMm100(
+ rUnitConv.scaleToMm100( nWidth, UNIT_DIGIT ) + rUnitConv.scaleToMm100( 5, UNIT_SCREENX ), UNIT_DIGIT );
+ }
+}
+
+void WorksheetData::setDefaultColumnWidth( double fWidth )
+{
+ // overrides a width set with setBaseColumnWidth()
+ if( fWidth > 0.0 )
+ {
+ maDefColModel.mfWidth = fWidth;
+ mbHasDefWidth = true;
+ }
+}
+
+void WorksheetData::setColumnModel( const ColumnModel& rModel )
+{
+ // convert 1-based OOXML column indexes to 0-based API column indexes
+ sal_Int32 nFirstCol = rModel.mnFirstCol - 1;
+ sal_Int32 nLastCol = rModel.mnLastCol - 1;
+ if( (0 <= nFirstCol) && (nFirstCol <= mrMaxApiPos.Column) )
+ {
+ // set column formatting directly, nLastCol is checked inside the function
+ convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId );
+ // expand last entry or add new entry
+ if( maColModels.empty() || !maColModels.rbegin()->second.tryExpand( rModel ) )
+ maColModels[ nFirstCol ] = rModel;
+ }
+}
+
+void WorksheetData::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
+{
+ maDefRowModel.mfHeight = fHeight;
+ maDefRowModel.mbCustomHeight = bCustomHeight;
+ maDefRowModel.mbHidden = bHidden;
+ maDefRowModel.mbThickTop = bThickTop;
+ maDefRowModel.mbThickBottom = bThickBottom;
+}
+
+void WorksheetData::setRowModel( const RowModel& rModel )
+{
+ // convert 1-based OOXML row indexes to 0-based API row indexes
+ sal_Int32 nFirstRow = rModel.mnFirstRow - 1;
+ sal_Int32 nLastRow = rModel.mnLastRow - 1;
+ if( (0 <= nFirstRow) && (nFirstRow <= mrMaxApiPos.Row) )
+ {
+ // set row formatting
+ if( rModel.mbCustomFormat )
+ {
+ // try to expand cached row range, if formatting is equal
+ if( (maXfIdRowRange.mnLastRow < 0) || !maXfIdRowRange.tryExpand( nFirstRow, nLastRow, rModel.mnXfId ) )
+ {
+ writeXfIdRowRangeProperties( maXfIdRowRange );
+ maXfIdRowRange.set( nFirstRow, nLastRow, rModel.mnXfId );
+ }
+ }
+ else if( maXfIdRowRange.mnLastRow >= 0 )
+ {
+ // finish last cached row range
+ writeXfIdRowRangeProperties( maXfIdRowRange );
+ maXfIdRowRange.set( -1, -1, -1 );
+ }
+
+ // expand last entry or add new entry
+ if( maRowModels.empty() || !maRowModels.rbegin()->second.tryExpand( rModel ) )
+ maRowModels[ nFirstRow ] = rModel;
+ }
+ lclUpdateProgressBar( mxRowProgress, maUsedArea, nLastRow );
+}
+
+void WorksheetData::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const
+{
+ CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row );
+ if( getAddressConverter().validateCellRange( aRange, true, false ) )
+ {
+ PropertySet aPropSet( getCellRange( aRange ) );
+ getStyles().writeCellXfToPropertySet( aPropSet, nXfId );
+ }
+}
+
+void WorksheetData::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) const
+{
+ CellRangeAddress aRange( getSheetIndex(), 0, nFirstRow, mrMaxApiPos.Column, nLastRow );
+ if( getAddressConverter().validateCellRange( aRange, true, false ) )
+ {
+ PropertySet aPropSet( getCellRange( aRange ) );
+ getStyles().writeCellXfToPropertySet( aPropSet, nXfId );
+ }
+}
+
+void WorksheetData::initializeWorksheetImport()
+{
+ // set default cell style for unused cells
+ PropertySet aPropSet( mxSheet );
+ aPropSet.setProperty( PROP_CellStyle, getStyles().getDefaultStyleName() );
+
+ /* Remember current sheet index in global data, needed by some global
+ objects, e.g. the chart converter. */
+ setCurrentSheetIndex( getSheetIndex() );
+}
+
+void WorksheetData::finalizeWorksheetImport()
+{
+ lclUpdateProgressBar( mxRowProgress, 1.0 );
+ finalizeXfIdRanges();
+ lclUpdateProgressBar( mxFinalProgress, 0.25 );
+ finalizeHyperlinkRanges();
+ finalizeValidationRanges();
+ finalizeMergedRanges();
+ maAutoFilters.finalizeImport( getSheetIndex() );
+ maSheetSett.finalizeImport();
+ maCondFormats.finalizeImport();
+ maQueryTables.finalizeImport();
+ maPageSett.finalizeImport();
+ maSheetViewSett.finalizeImport();
+ maSheetSett.finalizeImport();
+
+ lclUpdateProgressBar( mxFinalProgress, 0.5 );
+ convertColumns();
+ convertRows();
+ lclUpdateProgressBar( mxFinalProgress, 0.75 );
+ finalizeDrawings();
+ lclUpdateProgressBar( mxFinalProgress, 1.0 );
+
+ // reset current sheet index in global data
+ setCurrentSheetIndex( -1 );
+}
+
+// private --------------------------------------------------------------------
+
+WorksheetData::XfIdRowRange::XfIdRowRange() :
+ mnFirstRow( -1 ),
+ mnLastRow( -1 ),
+ mnXfId( -1 )
+{
+}
+
+bool WorksheetData::XfIdRowRange::intersects( const CellRangeAddress& rRange ) const
+{
+ return (rRange.StartRow <= mnLastRow) && (mnFirstRow <= rRange.EndRow);
+}
+
+void WorksheetData::XfIdRowRange::set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId )
+{
+ mnFirstRow = nFirstRow;
+ mnLastRow = nLastRow;
+ mnXfId = nXfId;
+}
+
+bool WorksheetData::XfIdRowRange::tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId )
+{
+ if( mnXfId == nXfId )
+ {
+ if( mnLastRow + 1 == nFirstRow )
+ {
+ mnLastRow = nLastRow;
+ return true;
+ }
+ if( mnFirstRow == nLastRow + 1 )
+ {
+ mnFirstRow = nFirstRow;
+ return true;
+ }
+ }
+ return false;
+}
+
+void WorksheetData::XfIdRange::set( const CellModel& rModel )
+{
+ maRange.Sheet = rModel.maAddress.Sheet;
+ maRange.StartColumn = maRange.EndColumn = rModel.maAddress.Column;
+ maRange.StartRow = maRange.EndRow = rModel.maAddress.Row;
+ mnXfId = rModel.mnXfId;
+ mnNumFmtId = rModel.mnNumFmtId;
+}
+
+bool WorksheetData::XfIdRange::tryExpand( const CellModel& rModel )
+{
+ if( (mnXfId == rModel.mnXfId) && (mnNumFmtId == rModel.mnNumFmtId) &&
+ (maRange.StartRow == rModel.maAddress.Row) &&
+ (maRange.EndRow == rModel.maAddress.Row) &&
+ (maRange.EndColumn + 1 == rModel.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::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const
+{
+ if( (rXfIdRowRange.mnLastRow >= 0) && (rXfIdRowRange.mnXfId >= 0) )
+ convertRowFormat( rXfIdRowRange.mnFirstRow, rXfIdRowRange.mnLastRow, rXfIdRowRange.mnXfId );
+}
+
+void WorksheetData::writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const
+{
+ StylesBuffer& rStyles = getStyles();
+ PropertyMap aPropMap;
+ if( rXfIdRange.mnXfId >= 0 )
+ rStyles.writeCellXfToPropertyMap( aPropMap, rXfIdRange.mnXfId );
+ if( rXfIdRange.mnNumFmtId >= 0 )
+ rStyles.writeNumFmtToPropertyMap( aPropMap, rXfIdRange.mnNumFmtId );
+ PropertySet aPropSet( getCellRange( rXfIdRange.maRange ) );
+ aPropSet.setProperties( aPropMap );
+}
+
+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()
+{
+ // write default formatting of remaining row range
+ writeXfIdRowRangeProperties( maXfIdRowRange );
+ // try to merge remaining inserted ranges
+ mergeXfIdRanges();
+ // write all formatting
+ for( XfIdRangeMap::const_iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); aIt != aEnd; ++aIt )
+ writeXfIdRangeProperties( aIt->second );
+}
+
+void WorksheetData::finalizeHyperlinkRanges() const
+{
+ for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt )
+ {
+ OUString aUrl = getHyperlinkUrl( *aIt );
+ // try to insert URL into each cell of the range
+ if( aUrl.getLength() > 0 )
+ for( CellAddress aAddress( getSheetIndex(), 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 )
+ insertHyperlink( aAddress, aUrl );
+ }
+}
+
+OUString WorksheetData::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const
+{
+ OUStringBuffer aUrlBuffer;
+ if( rHyperlink.maTarget.getLength() > 0 )
+ aUrlBuffer.append( getBaseFilter().getAbsoluteUrl( rHyperlink.maTarget ) );
+ if( rHyperlink.maLocation.getLength() > 0 )
+ aUrlBuffer.append( sal_Unicode( '#' ) ).append( rHyperlink.maLocation );
+ OUString aUrl = aUrlBuffer.makeStringAndClear();
+
+ // convert '#SheetName!A1' to '#SheetName.A1'
+ if( (aUrl.getLength() > 0) && (aUrl[ 0 ] == '#') )
+ {
+ sal_Int32 nSepPos = aUrl.lastIndexOf( '!' );
+ if( nSepPos > 0 )
+ {
+ // replace the exclamation mark with a period
+ aUrl = aUrl.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) );
+ // #i66592# convert sheet names that have been renamed on import
+ OUString aSheetName = aUrl.copy( 1, nSepPos - 1 );
+ OUString aCalcName = getWorksheets().getCalcSheetName( aSheetName );
+ if( aCalcName.getLength() > 0 )
+ aUrl = aUrl.replaceAt( 1, nSepPos - 1, aCalcName );
+ }
+ }
+
+ return aUrl;
+}
+
+void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const
+{
+ Reference< XCell > xCell = getCell( rAddress );
+ if( xCell.is() ) switch( xCell->getType() )
+ {
+ // #i54261# restrict creation of URL field to text cells
+ case ::com::sun::star::table::CellContentType_TEXT:
+ {
+ Reference< XText > xText( xCell, UNO_QUERY );
+ if( xText.is() )
+ {
+ // create a URL field object and set its properties
+ Reference< XTextContent > xUrlField( getDocumentFactory()->createInstance( maUrlTextField ), UNO_QUERY );
+ OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" );
+ if( xUrlField.is() )
+ {
+ // properties of the URL field
+ PropertySet aPropSet( xUrlField );
+ aPropSet.setProperty( PROP_URL, rUrl );
+ aPropSet.setProperty( PROP_Representation, 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::insertHyperlink - cannot insert text field" );
+ }
+ }
+ }
+ }
+ break;
+
+ // fix for #i31050# disabled, HYPERLINK is not able to return numeric value (#i91351#)
+#if 0
+ // #i31050# replace number with HYPERLINK function
+ case ::com::sun::star::table::CellContentType_VALUE:
+ {
+ Reference< XFormulaTokens > xTokens( xCell, UNO_QUERY );
+ OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula interface" );
+ if( xTokens.is() )
+ {
+ SimpleFormulaContext aContext( xTokens, false, false );
+ getFormulaParser().convertNumberToHyperlink( aContext, rUrl, xCell->getValue() );
+ }
+ }
+ break;
+#endif
+
+ default:;
+ }
+}
+
+void WorksheetData::finalizeValidationRanges() const
+{
+ for( ValidationModelList::const_iterator aIt = maValidations.begin(), aEnd = maValidations.end(); aIt != aEnd; ++aIt )
+ {
+ PropertySet aPropSet( getCellRangeList( aIt->maRanges ) );
+
+ Reference< XPropertySet > xValidation( aPropSet.getAnyProperty( PROP_Validation ), UNO_QUERY );
+ if( xValidation.is() )
+ {
+ PropertySet aValProps( xValidation );
+ namespace csss = ::com::sun::star::sheet;
+
+ // convert validation type to API enum
+ ValidationType eType = csss::ValidationType_ANY;
+ switch( aIt->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, "WorksheetData::finalizeValidationRanges - unknown validation type" );
+ }
+ aValProps.setProperty( PROP_Type, eType );
+
+ // convert error alert style to API enum
+ ValidationAlertStyle eAlertStyle = csss::ValidationAlertStyle_STOP;
+ switch( aIt->mnErrorStyle )
+ {
+ case XML_information: eAlertStyle = csss::ValidationAlertStyle_INFO; break;
+ case XML_stop: eAlertStyle = csss::ValidationAlertStyle_STOP; break;
+ case XML_warning: eAlertStyle = csss::ValidationAlertStyle_WARNING; break;
+ default: OSL_ENSURE( false, "WorksheetData::finalizeValidationRanges - unknown error style" );
+ }
+ aValProps.setProperty( PROP_ErrorAlertStyle, eAlertStyle );
+
+ // convert dropdown style to API visibility constants
+ sal_Int16 nVisibility = aIt->mbNoDropDown ? csss::TableValidationVisibility::INVISIBLE : csss::TableValidationVisibility::UNSORTED;
+ aValProps.setProperty( PROP_ShowList, nVisibility );
+
+ // messages
+ aValProps.setProperty( PROP_ShowInputMessage, aIt->mbShowInputMsg );
+ aValProps.setProperty( PROP_InputTitle, aIt->maInputTitle );
+ aValProps.setProperty( PROP_InputMessage, aIt->maInputMessage );
+ aValProps.setProperty( PROP_ShowErrorMessage, aIt->mbShowErrorMsg );
+ aValProps.setProperty( PROP_ErrorTitle, aIt->maErrorTitle );
+ aValProps.setProperty( PROP_ErrorMessage, aIt->maErrorMessage );
+
+ // allow blank cells
+ aValProps.setProperty( PROP_IgnoreBlankCells, aIt->mbAllowBlank );
+
+ try
+ {
+ // condition operator
+ Reference< XSheetCondition > xSheetCond( xValidation, UNO_QUERY_THROW );
+ xSheetCond->setOperator( CondFormatBuffer::convertToApiOperator( aIt->mnOperator ) );
+
+ // condition formulas
+ Reference< XMultiFormulaTokens > xTokens( xValidation, UNO_QUERY_THROW );
+ xTokens->setTokens( 0, aIt->maTokens1 );
+ xTokens->setTokens( 1, aIt->maTokens2 );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // write back validation settings to cell range(s)
+ aPropSet.setProperty( PROP_Validation, xValidation );
+ }
+ }
+}
+
+void WorksheetData::finalizeMergedRanges()
+{
+ 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 )
+{
+ 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
+ Reference< XCell > xTopLeft( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.StartRow ) ), UNO_SET_THROW );
+ PropertySet aTopLeftProp( xTopLeft );
+
+ // copy right border of top-right cell to right border of top-left cell
+ if( bMultiCol )
+ {
+ PropertySet aTopRightProp( getCell( CellAddress( getSheetIndex(), rRange.EndColumn, rRange.StartRow ) ) );
+ BorderLine aLine;
+ if( aTopRightProp.getProperty( aLine, PROP_RightBorder ) )
+ aTopLeftProp.setProperty( PROP_RightBorder, aLine );
+ }
+
+ // copy bottom border of bottom-left cell to bottom border of top-left cell
+ if( bMultiRow )
+ {
+ PropertySet aBottomLeftProp( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.EndRow ) ) );
+ BorderLine aLine;
+ if( aBottomLeftProp.getProperty( aLine, PROP_BottomBorder ) )
+ aTopLeftProp.setProperty( PROP_BottomBorder, aLine );
+ }
+
+ // #i93609# merged range in a single row: test if manual row height is needed
+ if( !bMultiRow )
+ {
+ bool bTextWrap = aTopLeftProp.getBoolProperty( PROP_IsTextWrapped );
+ if( !bTextWrap && (xTopLeft->getType() == ::com::sun::star::table::CellContentType_TEXT) )
+ {
+ Reference< XText > xText( xTopLeft, UNO_QUERY );
+ bTextWrap = xText.is() && (xText->getString().indexOf( '\x0A' ) >= 0);
+ }
+ if( bTextWrap )
+ maManualRowHeights.insert( rRange.StartRow );
+ }
+ }
+ 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( ColumnModelMap::const_iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt )
+ {
+ // convert 1-based OOXML 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 models, use default column model
+ if( nNextCol < nFirstCol )
+ convertColumns( aColLevels, nNextCol, nFirstCol - 1, maDefColModel );
+ // process the column model
+ 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, maDefColModel );
+ // 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 ColumnModel& rModel )
+{
+ PropertySet aPropSet( getColumns( nFirstCol, nLastCol ) );
+
+ // column width: convert 'number of characters' to column width in 1/100 mm
+ sal_Int32 nWidth = getUnitConverter().scaleToMm100( rModel.mfWidth, UNIT_DIGIT );
+ // macro sheets have double width
+ if( meSheetType == SHEETTYPE_MACROSHEET )
+ nWidth *= 2;
+ if( nWidth > 0 )
+ aPropSet.setProperty( PROP_Width, nWidth );
+
+ // hidden columns: TODO: #108683# hide columns later?
+ if( rModel.mbHidden )
+ aPropSet.setProperty( PROP_IsVisible, false );
+
+ // outline settings for this column range
+ convertOutlines( orColLevels, nFirstCol, rModel.mnLevel, rModel.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( RowModelMap::const_iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt )
+ {
+ // convert 1-based OOXML 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 models, use default row model
+ if( nNextRow < nFirstRow )
+ convertRows( aRowLevels, nNextRow, nFirstRow - 1, maDefRowModel );
+ // process the row model
+ convertRows( aRowLevels, nFirstRow, nLastRow, aIt->second, maDefRowModel.mfHeight );
+
+ // cache next row to be processed
+ nNextRow = nLastRow + 1;
+ }
+
+ // remaining default rows to end of sheet
+ convertRows( aRowLevels, nNextRow, nMaxRow, maDefRowModel );
+ // 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 RowModel& rModel, double fDefHeight )
+{
+ // row height: convert points to row height in 1/100 mm
+ double fHeight = (rModel.mfHeight >= 0.0) ? rModel.mfHeight : fDefHeight;
+ sal_Int32 nHeight = getUnitConverter().scaleToMm100( fHeight, UNIT_POINT );
+ if( nHeight > 0 )
+ {
+ ValueRangeVector aManualRows;
+ if( rModel.mbCustomHeight )
+ aManualRows.push_back( ValueRange( nFirstRow, nLastRow ) );
+ else
+ maManualRowHeights.intersect( aManualRows, nFirstRow, nLastRow );
+ for( ValueRangeVector::const_iterator aIt = aManualRows.begin(), aEnd = aManualRows.end(); aIt != aEnd; ++aIt )
+ {
+ PropertySet aPropSet( getRows( aIt->mnFirst, aIt->mnLast ) );
+ aPropSet.setProperty( PROP_Height, nHeight );
+ }
+ }
+
+ // hidden rows: TODO: #108683# hide rows later?
+ if( rModel.mbHidden )
+ {
+ PropertySet aPropSet( getRows( nFirstRow, nLastRow ) );
+ aPropSet.setProperty( PROP_IsVisible, false );
+ }
+
+ // outline settings for this row range
+ convertOutlines( orRowLevels, nFirstRow, rModel.mnLevel, rModel.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( getSheetIndex(), 0, nFirstColRow, 0, nLastColRow );
+ xOutline->group( aRange, ::com::sun::star::table::TableOrientation_ROWS );
+ if( bCollapse )
+ xOutline->hideDetail( aRange );
+ }
+ else
+ {
+ CellRangeAddress aRange( getSheetIndex(), nFirstColRow, 0, nLastColRow, 0 );
+ xOutline->group( aRange, ::com::sun::star::table::TableOrientation_COLUMNS );
+ if( bCollapse )
+ xOutline->hideDetail( aRange );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void WorksheetData::finalizeDrawings()
+{
+ switch( getFilterType() )
+ {
+ case FILTER_OOXML:
+ // import DML and VML
+ if( maDrawingPath.getLength() > 0 )
+ importOoxFragment( new DrawingFragment( *this, maDrawingPath ) );
+ if( maVmlDrawingPath.getLength() > 0 )
+ importOoxFragment( new VmlDrawingFragment( *this, maVmlDrawingPath ) );
+ break;
+
+ case FILTER_BIFF:
+ // TODO: import DFF shapes
+ break;
+
+ case FILTER_UNKNOWN:
+ break;
+ }
+
+ // comments (after callout shapes have been imported from VML/DFF)
+ maComments.finalizeImport();
+
+ /* Extend used area of the sheet by cells covered with drawing objects.
+ Needed if the imported document is inserted as "OLE object from file"
+ and thus does not provide an OLE size property by itself. */
+ if( (maShapeBoundingBox.Width > 0) || (maShapeBoundingBox.Height > 0) )
+ extendUsedArea( getCellRangeFromRectangle( maShapeBoundingBox ) );
+
+ // if no used area is set, default to A1
+ if( maUsedArea.StartColumn > maUsedArea.EndColumn )
+ maUsedArea.StartColumn = maUsedArea.EndColumn = 0;
+ if( maUsedArea.StartRow > maUsedArea.EndRow )
+ maUsedArea.StartRow = maUsedArea.EndRow = 0;
+
+ /* Register the used area of this sheet in global view settings. The
+ global view settings will set the visible area if this document is an
+ embedded OLE object. */
+ getViewSettings().setSheetUsedArea( maUsedArea );
+
+ /* #i103686# Set right-to-left sheet layout. Must be done after all
+ drawing shapes to simplify calculation of shape coordinates. */
+ if( maSheetViewSett.isSheetRightToLeft() )
+ {
+ PropertySet aPropSet( mxSheet );
+ aPropSet.setProperty( PROP_TableLayout, ::com::sun::star::text::WritingMode2::RL_TB );
+ }
+}
+
+// ============================================================================
+// ============================================================================
+
+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::getSheet() const
+{
+ return mrSheetData.getSheet();
+}
+
+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, 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, 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 );
+}
+
+Reference< XDrawPage > WorksheetHelper::getDrawPage() const
+{
+ return mrSheetData.getDrawPage();
+}
+
+Point WorksheetHelper::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ return mrSheetData.getCellPosition( nCol, nRow );
+}
+
+Size WorksheetHelper::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const
+{
+ return mrSheetData.getCellSize( nCol, nRow );
+}
+
+Size WorksheetHelper::getDrawPageSize() const
+{
+ return mrSheetData.getDrawPageSize();
+}
+
+WorksheetSettings& WorksheetHelper::getWorksheetSettings() const
+{
+ return mrSheetData.getWorksheetSettings();
+}
+
+SharedFormulaBuffer& WorksheetHelper::getSharedFormulas() const
+{
+ return mrSheetData.getSharedFormulas();
+}
+
+CondFormatBuffer& WorksheetHelper::getCondFormats() const
+{
+ return mrSheetData.getCondFormats();
+}
+
+CommentsBuffer& WorksheetHelper::getComments() const
+{
+ return mrSheetData.getComments();
+}
+
+AutoFilterBuffer& WorksheetHelper::getAutoFilters() const
+{
+ return mrSheetData.getAutoFilters();
+}
+
+QueryTableBuffer& WorksheetHelper::getQueryTables() const
+{
+ return mrSheetData.getQueryTables();
+}
+
+PageSettings& WorksheetHelper::getPageSettings() const
+{
+ return mrSheetData.getPageSettings();
+}
+
+SheetViewSettings& WorksheetHelper::getSheetViewSettings() const
+{
+ return mrSheetData.getSheetViewSettings();
+}
+
+VmlDrawing& WorksheetHelper::getVmlDrawing() const
+{
+ return mrSheetData.getVmlDrawing();
+}
+
+void WorksheetHelper::setStringCell( const Reference< XCell >& rxCell, const OUString& rText ) const
+{
+ 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::setDateTimeCell( const Reference< XCell >& rxCell, const DateTime& rDateTime ) const
+{
+ OSL_ENSURE( rxCell.is(), "WorksheetHelper::setDateTimeCell - missing cell interface" );
+ // write serial date/time value into the cell
+ double fSerial = getUnitConverter().calcSerialFromDateTime( rDateTime );
+ rxCell->setValue( fSerial );
+ // set appropriate number format
+ using namespace ::com::sun::star::util::NumberFormat;
+ sal_Int16 nStdFmt = (fSerial < 1.0) ? TIME : (((rDateTime.Hours > 0) || (rDateTime.Minutes > 0) || (rDateTime.Seconds > 0)) ? DATETIME : DATE);
+ setStandardNumFmt( rxCell, nStdFmt );
+}
+
+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 formula interface" );
+ if( xTokens.is() )
+ {
+ SimpleFormulaContext aContext( xTokens, false, false );
+ getFormulaParser().convertErrorToFormula( aContext, nErrorCode );
+ }
+}
+
+void WorksheetHelper::setCell( CellModel& orModel ) const
+{
+ OSL_ENSURE( orModel.mxCell.is(), "WorksheetHelper::setCell - missing cell interface" );
+ if( orModel.mbHasValueStr ) switch( orModel.mnCellType )
+ {
+ case XML_b:
+ setBooleanCell( orModel.mxCell, orModel.maValueStr.toDouble() != 0.0 );
+ // #108770# set 'Standard' number format for all Boolean cells
+ orModel.mnNumFmtId = 0;
+ break;
+ case XML_n:
+ orModel.mxCell->setValue( orModel.maValueStr.toDouble() );
+ break;
+ case XML_e:
+ setErrorCell( orModel.mxCell, orModel.maValueStr );
+ break;
+ case XML_str:
+ setStringCell( orModel.mxCell, orModel.maValueStr );
+ break;
+ case XML_s:
+ setSharedStringCell( orModel.mxCell, orModel.maValueStr.toInt32(), orModel.mnXfId );
+ break;
+ }
+}
+
+void WorksheetHelper::setStandardNumFmt( const Reference< XCell >& rxCell, sal_Int16 nStdNumFmt ) const
+{
+ try
+ {
+ Reference< XNumberFormatsSupplier > xNumFmtsSupp( getDocument(), UNO_QUERY_THROW );
+ Reference< XNumberFormatTypes > xNumFmtTypes( xNumFmtsSupp->getNumberFormats(), UNO_QUERY_THROW );
+ sal_Int32 nIndex = xNumFmtTypes->getStandardFormat( nStdNumFmt, Locale() );
+ PropertySet aPropSet( rxCell );
+ aPropSet.setProperty( PROP_NumberFormat, nIndex );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void WorksheetHelper::setSheetType( WorksheetType eSheetType )
+{
+ mrSheetData.setSheetType( eSheetType );
+}
+
+void WorksheetHelper::setCellFormat( const CellModel& rModel )
+{
+ mrSheetData.setCellFormat( rModel );
+}
+
+void WorksheetHelper::setMergedRange( const CellRangeAddress& rRange )
+{
+ mrSheetData.setMergedRange( rRange );
+}
+
+void WorksheetHelper::setPageBreak( const PageBreakModel& rModel, bool bRowBreak )
+{
+ mrSheetData.setPageBreak( rModel, bRowBreak );
+}
+
+void WorksheetHelper::setHyperlink( const HyperlinkModel& rModel )
+{
+ mrSheetData.setHyperlink( rModel );
+}
+
+void WorksheetHelper::setValidation( const ValidationModel& rModel )
+{
+ mrSheetData.setValidation( rModel );
+}
+
+void WorksheetHelper::setTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) const
+{
+ OSL_ENSURE( getAddressConverter().checkCellRange( rRange, true, false ), "WorksheetHelper::setTableOperation - invalid range" );
+ bool bOk = false;
+ if( !rModel.mbRef1Deleted && (rModel.maRef1.getLength() > 0) && (rRange.StartColumn > 0) && (rRange.StartRow > 0) )
+ {
+ CellRangeAddress aOpRange = rRange;
+ CellAddress aRef1, aRef2;
+ if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, mrSheetData.getSheetIndex(), true ) ) try
+ {
+ if( rModel.mb2dTable )
+ {
+ if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.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( rModel.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();
+ PropertySet aPropSet( getSheet() );
+
+ if( !rColRanges.empty() )
+ {
+ Reference< XLabelRanges > xLabelRanges( aPropSet.getAnyProperty( PROP_ColumnLabelRanges ), UNO_QUERY );
+ if( 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() )
+ {
+ Reference< XLabelRanges > xLabelRanges( aPropSet.getAnyProperty( PROP_RowLabelRanges ), UNO_QUERY );
+ if( 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::setDrawingPath( const OUString& rDrawingPath )
+{
+ mrSheetData.setDrawingPath( rDrawingPath );
+}
+
+void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath )
+{
+ mrSheetData.setVmlDrawingPath( rVmlDrawingPath );
+}
+
+void WorksheetHelper::extendUsedArea( const CellAddress& rAddress )
+{
+ mrSheetData.extendUsedArea( rAddress );
+}
+
+void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange )
+{
+ mrSheetData.extendUsedArea( rRange );
+}
+
+void WorksheetHelper::extendShapeBoundingBox( const Rectangle& rShapeRect )
+{
+ mrSheetData.extendShapeBoundingBox( rShapeRect );
+}
+
+void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth )
+{
+ mrSheetData.setBaseColumnWidth( nWidth );
+}
+
+void WorksheetHelper::setDefaultColumnWidth( double fWidth )
+{
+ mrSheetData.setDefaultColumnWidth( fWidth );
+}
+
+void WorksheetHelper::setDefaultColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId )
+{
+ mrSheetData.convertColumnFormat( nFirstCol, nLastCol, nXfId );
+}
+
+void WorksheetHelper::setColumnModel( const ColumnModel& rModel )
+{
+ mrSheetData.setColumnModel( rModel );
+}
+
+void WorksheetHelper::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
+{
+ mrSheetData.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom );
+}
+
+void WorksheetHelper::setRowModel( const RowModel& rModel )
+{
+ mrSheetData.setRowModel( rModel );
+}
+
+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, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
+ prv::WorksheetDataOwner( prv::WorksheetDataRef( new WorksheetData( rHelper, rxProgressBar, 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..cc1aa45f2012
--- /dev/null
+++ b/oox/source/xls/worksheetsettings.cxx
@@ -0,0 +1,348 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/worksheetsettings.hxx"
+
+#include <com/sun/star/util/XProtectable.hpp>
+#include "oox/core/filterbase.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/pagesettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+using ::oox::core::CodecHelper;
+using ::rtl::OUString;
+
+// ============================================================================
+
+namespace {
+
+const sal_uInt8 BIFF12_SHEETPR_FILTERMODE = 0x01;
+const sal_uInt8 BIFF12_SHEETPR_EVAL_CF = 0x02;
+
+const sal_uInt32 BIFF_SHEETEXT_NOTABCOLOR = 0x7F;
+
+const sal_uInt16 BIFF_SHEETPR_DIALOGSHEET = 0x0010;
+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_uInt32 BIFF_SHEETPROT_OBJECTS = 0x00000001;
+const sal_uInt32 BIFF_SHEETPROT_SCENARIOS = 0x00000002;
+const sal_uInt32 BIFF_SHEETPROT_FORMAT_CELLS = 0x00000004;
+const sal_uInt32 BIFF_SHEETPROT_FORMAT_COLUMNS = 0x00000008;
+const sal_uInt32 BIFF_SHEETPROT_FORMAT_ROWS = 0x00000010;
+const sal_uInt32 BIFF_SHEETPROT_INSERT_COLUMNS = 0x00000020;
+const sal_uInt32 BIFF_SHEETPROT_INSERT_ROWS = 0x00000040;
+const sal_uInt32 BIFF_SHEETPROT_INSERT_HLINKS = 0x00000080;
+const sal_uInt32 BIFF_SHEETPROT_DELETE_COLUMNS = 0x00000100;
+const sal_uInt32 BIFF_SHEETPROT_DELETE_ROWS = 0x00000200;
+const sal_uInt32 BIFF_SHEETPROT_SELECT_LOCKED = 0x00000400;
+const sal_uInt32 BIFF_SHEETPROT_SORT = 0x00000800;
+const sal_uInt32 BIFF_SHEETPROT_AUTOFILTER = 0x00001000;
+const sal_uInt32 BIFF_SHEETPROT_PIVOTTABLES = 0x00002000;
+const sal_uInt32 BIFF_SHEETPROT_SELECT_UNLOCKED = 0x00004000;
+
+} // namespace
+
+// ============================================================================
+
+SheetSettingsModel::SheetSettingsModel() :
+ mbFilterMode( false ),
+ mbApplyStyles( false ),
+ mbSummaryBelow( true ),
+ mbSummaryRight( true )
+{
+}
+
+// ============================================================================
+
+SheetProtectionModel::SheetProtectionModel() :
+ 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::importSheetPr( const AttributeList& rAttribs )
+{
+ maSheetSettings.maCodeName = rAttribs.getString( XML_codeName, OUString() );
+ maSheetSettings.mbFilterMode = rAttribs.getBool( XML_filterMode, false );
+}
+
+void WorksheetSettings::importChartSheetPr( const AttributeList& rAttribs )
+{
+ maSheetSettings.maCodeName = rAttribs.getString( XML_codeName, OUString() );
+}
+
+void WorksheetSettings::importTabColor( const AttributeList& rAttribs )
+{
+ maSheetSettings.maTabColor.importColor( rAttribs );
+}
+
+void WorksheetSettings::importOutlinePr( const AttributeList& rAttribs )
+{
+ maSheetSettings.mbApplyStyles = rAttribs.getBool( XML_applyStyles, false );
+ maSheetSettings.mbSummaryBelow = rAttribs.getBool( XML_summaryBelow, true );
+ maSheetSettings.mbSummaryRight = rAttribs.getBool( XML_summaryRight, true );
+}
+
+void WorksheetSettings::importSheetProtection( const AttributeList& rAttribs )
+{
+ maSheetProt.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_password );
+ maSheetProt.mbSheet = rAttribs.getBool( XML_sheet, false );
+ maSheetProt.mbObjects = rAttribs.getBool( XML_objects, false );
+ maSheetProt.mbScenarios = rAttribs.getBool( XML_scenarios, false );
+ maSheetProt.mbFormatCells = rAttribs.getBool( XML_formatCells, true );
+ maSheetProt.mbFormatColumns = rAttribs.getBool( XML_formatColumns, true );
+ maSheetProt.mbFormatRows = rAttribs.getBool( XML_formatRows, true );
+ maSheetProt.mbInsertColumns = rAttribs.getBool( XML_insertColumns, true );
+ maSheetProt.mbInsertRows = rAttribs.getBool( XML_insertRows, true );
+ maSheetProt.mbInsertHyperlinks = rAttribs.getBool( XML_insertHyperlinks, true );
+ maSheetProt.mbDeleteColumns = rAttribs.getBool( XML_deleteColumns, true );
+ maSheetProt.mbDeleteRows = rAttribs.getBool( XML_deleteRows, true );
+ maSheetProt.mbSelectLocked = rAttribs.getBool( XML_selectLockedCells, false );
+ maSheetProt.mbSort = rAttribs.getBool( XML_sort, true );
+ maSheetProt.mbAutoFilter = rAttribs.getBool( XML_autoFilter, true );
+ maSheetProt.mbPivotTables = rAttribs.getBool( XML_pivotTables, true );
+ maSheetProt.mbSelectUnlocked = rAttribs.getBool( XML_selectUnlockedCells, false );
+}
+
+void WorksheetSettings::importChartProtection( const AttributeList& rAttribs )
+{
+ maSheetProt.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_password );
+ maSheetProt.mbSheet = rAttribs.getBool( XML_content, false );
+ maSheetProt.mbObjects = rAttribs.getBool( XML_objects, false );
+}
+
+void WorksheetSettings::importPhoneticPr( const AttributeList& rAttribs )
+{
+ maPhoneticSett.importPhoneticPr( rAttribs );
+}
+
+void WorksheetSettings::importSheetPr( SequenceInputStream& rStrm )
+{
+ sal_uInt16 nFlags1;
+ sal_uInt8 nFlags2;
+ rStrm >> nFlags1 >> nFlags2 >> maSheetSettings.maTabColor;
+ rStrm.skip( 8 ); // sync anchor cell
+ rStrm >> maSheetSettings.maCodeName;
+ // sheet settings
+ maSheetSettings.mbFilterMode = getFlag( nFlags2, BIFF12_SHEETPR_FILTERMODE );
+ // outline settings, equal flags in all BIFFs
+ maSheetSettings.mbApplyStyles = getFlag( nFlags1, BIFF_SHEETPR_APPLYSTYLES );
+ maSheetSettings.mbSummaryRight = getFlag( nFlags1, BIFF_SHEETPR_SYMBOLSRIGHT );
+ maSheetSettings.mbSummaryBelow = getFlag( nFlags1, BIFF_SHEETPR_SYMBOLSBELOW );
+ /* Fit printout to width/height - for whatever reason, this flag is still
+ stored separated from the page settings */
+ getPageSettings().setFitToPagesMode( getFlag( nFlags1, BIFF_SHEETPR_FITTOPAGES ) );
+}
+
+void WorksheetSettings::importChartSheetPr( SequenceInputStream& rStrm )
+{
+ rStrm.skip( 2 ); // flags, contains only the 'published' flag
+ rStrm >> maSheetSettings.maTabColor >> maSheetSettings.maCodeName;
+}
+
+void WorksheetSettings::importSheetProtection( SequenceInputStream& rStrm )
+{
+ rStrm >> maSheetProt.mnPasswordHash;
+ // no flags field for all these boolean flags?!?
+ maSheetProt.mbSheet = rStrm.readInt32() != 0;
+ maSheetProt.mbObjects = rStrm.readInt32() != 0;
+ maSheetProt.mbScenarios = rStrm.readInt32() != 0;
+ maSheetProt.mbFormatCells = rStrm.readInt32() != 0;
+ maSheetProt.mbFormatColumns = rStrm.readInt32() != 0;
+ maSheetProt.mbFormatRows = rStrm.readInt32() != 0;
+ maSheetProt.mbInsertColumns = rStrm.readInt32() != 0;
+ maSheetProt.mbInsertRows = rStrm.readInt32() != 0;
+ maSheetProt.mbInsertHyperlinks = rStrm.readInt32() != 0;
+ maSheetProt.mbDeleteColumns = rStrm.readInt32() != 0;
+ maSheetProt.mbDeleteRows = rStrm.readInt32() != 0;
+ maSheetProt.mbSelectLocked = rStrm.readInt32() != 0;
+ maSheetProt.mbSort = rStrm.readInt32() != 0;
+ maSheetProt.mbAutoFilter = rStrm.readInt32() != 0;
+ maSheetProt.mbPivotTables = rStrm.readInt32() != 0;
+ maSheetProt.mbSelectUnlocked = rStrm.readInt32() != 0;
+}
+
+void WorksheetSettings::importChartProtection( SequenceInputStream& rStrm )
+{
+ rStrm >> maSheetProt.mnPasswordHash;
+ // no flags field for all these boolean flags?!?
+ maSheetProt.mbSheet = rStrm.readInt32() != 0;
+ maSheetProt.mbObjects = rStrm.readInt32() != 0;
+}
+
+void WorksheetSettings::importPhoneticPr( SequenceInputStream& rStrm )
+{
+ maPhoneticSett.importPhoneticPr( rStrm );
+}
+
+void WorksheetSettings::importSheetExt( BiffInputStream& rStrm )
+{
+ rStrm.skip( 16 );
+ sal_uInt32 nFlags;
+ rStrm >> nFlags;
+ sal_uInt8 nColorIdx = extractValue< sal_uInt8 >( nFlags, 0, 7 );
+ if( nColorIdx != BIFF_SHEETEXT_NOTABCOLOR )
+ maSheetSettings.maTabColor.setPaletteClr( nColorIdx );
+}
+
+void WorksheetSettings::importSheetPr( BiffInputStream& rStrm )
+{
+ sal_uInt16 nFlags;
+ rStrm >> nFlags;
+ // worksheet vs. dialogsheet
+ if( getFlag( nFlags, BIFF_SHEETPR_DIALOGSHEET ) )
+ {
+ OSL_ENSURE( getSheetType() == SHEETTYPE_WORKSHEET, "WorksheetSettings::importSheetPr - unexpected sheet type" );
+ setSheetType( SHEETTYPE_DIALOGSHEET );
+ }
+ // outline settings
+ maSheetSettings.mbApplyStyles = getFlag( nFlags, BIFF_SHEETPR_APPLYSTYLES );
+ maSheetSettings.mbSummaryRight = getFlag( nFlags, BIFF_SHEETPR_SYMBOLSRIGHT );
+ maSheetSettings.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 )
+{
+ maSheetProt.mbSheet = rStrm.readuInt16() != 0;
+}
+
+void WorksheetSettings::importObjectProtect( BiffInputStream& rStrm )
+{
+ maSheetProt.mbObjects = rStrm.readuInt16() != 0;
+}
+
+void WorksheetSettings::importScenProtect( BiffInputStream& rStrm )
+{
+ maSheetProt.mbScenarios = rStrm.readuInt16() != 0;
+}
+
+void WorksheetSettings::importPassword( BiffInputStream& rStrm )
+{
+ rStrm >> maSheetProt.mnPasswordHash;
+}
+
+void WorksheetSettings::importSheetProtection( BiffInputStream& rStrm )
+{
+ sal_uInt32 nFlags = rStrm.readuInt32();
+ // set flag means protection is disabled
+ maSheetProt.mbObjects = !getFlag( nFlags, BIFF_SHEETPROT_OBJECTS );
+ maSheetProt.mbScenarios = !getFlag( nFlags, BIFF_SHEETPROT_SCENARIOS );
+ maSheetProt.mbFormatCells = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_CELLS );
+ maSheetProt.mbFormatColumns = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_COLUMNS );
+ maSheetProt.mbFormatRows = !getFlag( nFlags, BIFF_SHEETPROT_FORMAT_ROWS );
+ maSheetProt.mbInsertColumns = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_COLUMNS );
+ maSheetProt.mbInsertRows = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_ROWS );
+ maSheetProt.mbInsertHyperlinks = !getFlag( nFlags, BIFF_SHEETPROT_INSERT_HLINKS );
+ maSheetProt.mbDeleteColumns = !getFlag( nFlags, BIFF_SHEETPROT_DELETE_COLUMNS );
+ maSheetProt.mbDeleteRows = !getFlag( nFlags, BIFF_SHEETPROT_DELETE_ROWS );
+ maSheetProt.mbSelectLocked = !getFlag( nFlags, BIFF_SHEETPROT_SELECT_LOCKED );
+ maSheetProt.mbSort = !getFlag( nFlags, BIFF_SHEETPROT_SORT );
+ maSheetProt.mbAutoFilter = !getFlag( nFlags, BIFF_SHEETPROT_AUTOFILTER );
+ maSheetProt.mbPivotTables = !getFlag( nFlags, BIFF_SHEETPROT_PIVOTTABLES );
+ maSheetProt.mbSelectUnlocked = !getFlag( nFlags, BIFF_SHEETPROT_SELECT_UNLOCKED );
+}
+
+void WorksheetSettings::importCodeName( BiffInputStream& rStrm )
+{
+ maSheetSettings.maCodeName = rStrm.readUniString();
+}
+
+void WorksheetSettings::importPhoneticPr( BiffInputStream& rStrm )
+{
+ maPhoneticSett.importPhoneticPr( rStrm );
+}
+
+void WorksheetSettings::finalizeImport()
+{
+ // sheet protection
+ if( maSheetProt.mbSheet ) try
+ {
+ Reference< XProtectable > xProtectable( getSheet(), UNO_QUERY_THROW );
+ xProtectable->protect( OUString() );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // VBA code name
+ PropertySet aPropSet( getSheet() );
+ aPropSet.setProperty( PROP_CodeName, maSheetSettings.maCodeName );
+
+ // sheet tab color
+ if( !maSheetSettings.maTabColor.isAuto() )
+ {
+ sal_Int32 nColor = maSheetSettings.maTabColor.getColor( getBaseFilter().getGraphicHelper() );
+ aPropSet.setProperty( PROP_TabColor, nColor );
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/util/makefile.mk b/oox/util/makefile.mk
new file mode 100644
index 000000000000..329ced792164
--- /dev/null
+++ b/oox/util/makefile.mk
@@ -0,0 +1,104 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=oox
+TARGET=oox
+USE_DEFFILE=TRUE
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
+# --- Allgemein ----------------------------------------------------
+
+LIB1TARGET= $(SLB)$/$(TARGET).lib
+LIB1FILES= \
+ $(SLB)$/token.lib\
+ $(SLB)$/helper.lib\
+ $(SLB)$/core.lib\
+ $(SLB)$/ole.lib\
+ $(SLB)$/ppt.lib\
+ $(SLB)$/xls.lib\
+ $(SLB)$/vml.lib\
+ $(SLB)$/drawingml.lib\
+ $(SLB)$/diagram.lib\
+ $(SLB)$/chart.lib\
+ $(SLB)$/table.lib\
+ $(SLB)$/shape.lib\
+ $(SLB)$/dump.lib\
+ $(SLB)$/docprop.lib
+
+# --- Shared-Library -----------------------------------------------
+
+SHL1TARGET= $(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB= i$(TARGET)
+SHL1USE_EXPORTS=name
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB)\
+ $(COMPHELPERLIB)\
+ $(RTLLIB) \
+ $(SALLIB) \
+ $(BASEGFXLIB) \
+ $(SAXLIB) \
+ $(XMLSCRIPTLIB)
+
+# link openssl, copied this bit from ucb/source/ucp/webdav/makefile.mk
+.IF "$(GUI)"=="WNT"
+SHL1STDLIBS+= $(OPENSSLLIB)
+.ELSE # WNT
+.IF "$(OS)"=="SOLARIS"
+SHL1STDLIBS+= -lnsl -lsocket -ldl
+.ENDIF # SOLARIS
+.IF "$(SYSTEM_OPENSSL)"=="YES"
+SHL1STDLIBS+= $(OPENSSLLIB)
+.ELSE
+SHL1STDLIBS+= $(OPENSSLLIBST)
+.ENDIF
+.ENDIF # WNT
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1LIBS= $(LIB1TARGET)
+DEF1NAME =$(SHL1TARGET)
+DEFLIB1NAME =$(TARGET)
+
+# --- Targets ----------------------------------------------------------
+.ENDIF # L10N_framework
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/oox.component
+
+$(MISC)/oox.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ oox.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt oox.component
diff --git a/oox/util/makefile.pmk b/oox/util/makefile.pmk
new file mode 100644
index 000000000000..adb0222c2ba2
--- /dev/null
+++ b/oox/util/makefile.pmk
@@ -0,0 +1,30 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+# Reduction of exported symbols:
+CDEFS += -DOOX_DLLIMPLEMENTATION
+VISIBILITY_HIDDEN=TRUE
diff --git a/oox/util/oox.component b/oox/util/oox.component
new file mode 100644
index 000000000000..f6519d5a8664
--- /dev/null
+++ b/oox/util/oox.component
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.oox.core.FastTokenHandler">
+ <service name="com.sun.star.xml.sax.FastTokenHandler"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.FormatDetector">
+ <service name="com.sun.star.frame.ExtendedTypeDetection"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.docprop.DocumentPropertiesImporter">
+ <service name="com.sun.star.document.OOXMLDocumentPropertiesImporter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.WordVbaProjectFilter">
+ <service name="com.sun.star.document.ImportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.ppt.PowerPointImport">
+ <service name="com.sun.star.document.ImportFilter"/>
+ <service name="com.sun.star.document.ExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.ShapeContextHandler">
+ <service name="com.sun.star.xml.sax.FastShapeContextHandler"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.xls.BiffDetector">
+ <service name="com.sun.star.frame.ExtendedTypeDetection"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.xls.ExcelFilter">
+ <service name="com.sun.star.document.ImportFilter"/>
+ <service name="com.sun.star.document.ExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.xls.ExcelBiffFilter">
+ <service name="com.sun.star.document.ImportFilter"/>
+ <service name="com.sun.star.document.ExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.xls.ExcelVbaProjectFilter">
+ <service name="com.sun.star.document.ImportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.oox.xls.FormulaParser">
+ <service name="com.sun.star.sheet.FilterFormulaParser"/>
+ </implementation>
+</component>
diff --git a/oox/workben/ooxml-export-notes.txt b/oox/workben/ooxml-export-notes.txt
new file mode 100644
index 000000000000..8da4582b72b1
--- /dev/null
+++ b/oox/workben/ooxml-export-notes.txt
@@ -0,0 +1,220 @@
+How to install this
+-------------------
+
+> cd instsetoo_native/util
+> LOCALINSTALLDIR=/where/you/want dmake openoffice_en-US PKGFORMAT=installed
+
+OOXML generally
+---------------
+
+- http://www.ecma-international.org/publications/standards/Ecma-376.htm
+- http://www.asahi-net.or.jp/~eb2m-mrt/ooxml/dependencies.html
+
+Related modules
+---------------
+
+- oox
+ - .xlsx and .pptx import
+
+- writerfilter
+ - import of .docx, uses also oox for the graphics etc.
+ - can also parse .doc; but used for ooxml only for now
+
+- filter
+ - the configuration stuff (so that the filters appear in the filepicker)
+
+Old binary filters (export)
+---------------------------
+
+- doc export
+ - sw/source/filter/ww8/wrtww8*
+ - wrtww8.cxx:2191 [SwWW8Writer::StoreDoc()] is the entry point
+
+ - eg.
+ #0 SwWW8Writer::WriteText (this=0x2aaab3dfb7c0) at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:1846
+ #1 0x00002aaaae75a545 in SwWW8Writer::WriteMainText (this=0x2aaab3d6a870)
+ at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:1925
+ #2 0x00002aaaae75e357 in SwWW8Writer::StoreDoc1 (this=0x2aaab3d6a870)
+ at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:2076
+ #3 0x00002aaaae7605ec in SwWW8Writer::StoreDoc (this=0x2aaab3d6a870)
+ at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:2383
+ #4 0x00002aaaae760fd5 in SwWW8Writer::WriteStorage (this=0x2aaab3d6a870)
+ at /local/ooxml/ooxml/sw/source/filter/ww8/wrtww8.cxx:2547
+ #5 0x00002aaaae70b793 in StgWriter::Write (this=0x2aaab3d6a870, rPaM=@0x2b3802a2b640, rStg=@0x2aaab3d621c0,
+ pFName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/writer/writer.cxx:653
+ #6 0x00002aaaae70b84d in Writer::Write (this=0x2aaab3d6a870, rPaM=@0x2b3802a2b640, rStrm=@0x2aaaad979d20,
+ pFName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/writer/writer.cxx:358
+ #7 0x00002aaaae70b993 in Writer::Write (this=0x2aaab3d6a870, rPam=@0x2b3802a2b640, rMed=@0x2aaaad999f30,
+ pFileName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/writer/writer.cxx:385
+ #8 0x00002aaaae6375d7 in SwWriter::Write (this=0x7fffb1b28410, rxWriter=@0x7fffb1b285d0,
+ pRealFileName=0x7fffb1b285c0) at /local/ooxml/ooxml/sw/source/filter/basflt/shellio.cxx:963
+ #9 0x00002aaaae87cc1e in SwDocShell::ConvertTo (this=0xcc27f0, rMedium=@0x2aaaad999f30)
+ at /local/ooxml/ooxml/sw/source/ui/app/docsh.cxx:924
+ #10 0x00002b37faae6b58 in SfxObjectShell::DoLoad ()
+ from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program//libsfxlx.so
+
+- xls export
+ - sc/source/filter/excel/xe*
+
+ - eg.
+ #0 XclExpRecord::Save (this=0x11ae4c0, rStrm=@0x7fff5e6335d0)
+ at /local/ooxml/ooxml/sc/source/filter/excel/xerecord.cxx:88
+ #1 0x00002aaaae562c4a in ExcRecord::Save (this=0x11ae4c0, rStrm=@0x7fff5e6335d0)
+ at /local/ooxml/ooxml/sc/source/filter/excel/excrecds.cxx:168
+ #2 0x00002aaaae54b0fa in XclExpRecordList<XclExpRecordBase>::Save (this=0x11c5d18, rStrm=@0x7fff5e6335d0)
+ at ../inc/xerecord.hxx:281
+ #3 0x00002aaaae547541 in ExcTable::Write (this=0x11c5cf8, rStr=@0x7fff5e6335d0)
+ at /local/ooxml/ooxml/sc/source/filter/excel/excdoc.cxx:455
+ #4 0x00002aaaae5475fb in ExcDocument::Write (this=0x11c5ce0, rSvStrm=@0x2aaab3dcd070)
+ at /local/ooxml/ooxml/sc/source/filter/excel/excdoc.cxx:525
+ #5 0x00002aaaae568add in ExportBiff5::Write (this=0x7fff5e6339c0)
+ at /local/ooxml/ooxml/sc/source/filter/excel/expop2.cxx:119
+ #6 0x00002aaaae54f4af in ScExportExcel5 (rMedium=@0x2aaab3d87410, pDocument=0xce6a00, bBiff8=1 '\001', eNach=1)
+ at /local/ooxml/ooxml/sc/source/filter/excel/excel.cxx:252
+ #7 0x00002aaaadf1b70a in ScDocShell::ConvertTo (this=0xce6990, rMed=@0x2aaab3d87410)
+ at /local/ooxml/ooxml/sc/source/ui/docshell/docsh.cxx:2080
+ #8 0x00002b354dfd8b58 in SfxObjectShell::DoLoad ()
+ from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program//libsfxlx.so
+
+ - Current approach is to add a XclExpRecordBase::SaveXml() method, which
+ would be used to write the XML content (while Save() would continue
+ writing the BIFF format).
+ - Q: How do we get to the Save()/SaveXml() methods (e.g. the SST export code)
+ #0 XclExpSstImpl::Save (this=0x1b170b0, rStrm=@0x7fffd4d5c4a0)
+ at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/xecontent.cxx:224
+ #1 0x00007f68b7e46ff7 in XclExpSst::Save (this=0x1abc300,
+ rStrm=@0x7fffd4d5c4a0)
+ at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/xecontent.cxx:351
+ #2 0x00007f68b7de5090 in XclExpRecordList<XclExpRecordBase>::Save (
+ this=0x1b2d168, rStrm=@0x7fffd4d5c4a0) at ../inc/xerecord.hxx:282
+ // as above, starting at frame 2
+
+ - Thus, to get to the SaveXml() method, we need to add a slew of WriteXml()
+ methods that will (eventually) invoke the SaveXml() methods.
+
+ - ZipStorage for XML handling and StorageRef (XStorage interface)
+ - To construct ZipStorage, need XMultiServiceFactory (!), and
+ XInputStream.
+ - Have an SvStream; need to wrap SvStream with XInputStream
+ - OInputStreamWrapper in <unotools/streamwrap.hxx>
+ - Where do I get XMultiServiceFactory?
+ - Lots of places -- just grep
+ - perhaps XmlFilterBase _does_ make sense here.
+ - Do it anyway.
+ - Looking into having XclExpXmlStream inherit from ZipFilterBase
+ - problem: exception during construction, because ZipStorage hates me:
+ #0 OStorageFactory::createInstanceWithArguments (this=0x10612a0,
+ aArguments=@0x7fffe2ef76d0)
+ at /home/jon/Development/OpenOffice.org/ooxml/package/source/xstor/xfactory.cxx:275
+ #1 0x00007f12d93f0d5c in comphelper::OStorageHelper::GetStorageOfFormatFromStream (aFormat=@0x7fffe2ef7780, xStream=@0x1a502d8, nStorageMode=15,
+ xFactory=@0x1a502c0)
+ at /home/jon/Development/OpenOffice.org/ooxml/comphelper/source/misc/storagehelper.cxx:342
+ #2 0x00007f12c33d1a6d in ZipStorage (this=0x1a92550, rxFactory=@0x1a502c0,
+ rxStream=@0x1a502d8)
+ at /home/jon/Development/OpenOffice.org/ooxml/oox/source/helper/zipstorage.cxx:87
+ #3 0x00007f12c33f089e in oox::core::XmlFilterBase::implCreateStorage (
+ this=0x7fffe2ef7930, rxInStream=@0x1a502d0, rxStream=@0x1a502d8)
+ at /home/jon/Development/OpenOffice.org/ooxml/oox/source/core/xmlfilterbase.cxx:298
+ #4 0x00007f12c33dd204 in oox::core::FilterBase::filter (this=0x7fffe2ef7930,
+ rDescriptor=@0x7fffe2ef78d0)
+ at /home/jon/Development/OpenOffice.org/ooxml/oox/source/core/filterbase.cxx:284
+ #5 0x00007f12c68097a2 in XclExpXmlStream (this=0x7fffe2ef7930,
+ rSMgr=@0x7fffe2ef79a0, rStrm=@0x18d6f90)
+ at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/xestream.cxx:659
+ #6 0x00007f12c674c8c1 in ExcDocument::WriteXml (this=0x15911f0,
+ rStrm=@0x18d6f90)
+ at /home/jon/Development/OpenOffice.org/ooxml/sc/source/filter/excel/excdoc.cxx:575
+ ...
+ - Actual problem: xfactory.cxx:274, the CheckPackageSignature_Impl() call.
+ - fails because the empty file has content (!), thus fails the "package
+ signature check" (which tries to ensure the file format is correct).
+ - Underlying file is an SvFileStream, created in
+ SfxMedium::GetOutStream().
+ - So why's CheckPackageSignature_Impl() fail? Because
+ lcl_ExportExcel2007Xml() had the code:
+
+ SotStorageRef xRootStrg = new SotStorage( pMedStrm, FALSE );
+
+ That is, it was creating an OLE Structured Storage document over the
+ SvStream, and then (later) used the *same* SvStream and passed it to
+ ZipStorage. This caused ZipStorage to complain because OLESS data was
+ already present in the file, with a different file signature than what
+ ZipPackage was expecting (go figure).
+
+- ppt export
+ - sd/source/filter/eppt/*
+ - svx/source/msfilter
+ - for eg. Escher export
+ - Escher: http://chicago.sourceforge.net/devel/docs/escher/index.html
+
+ - eg.
+ #0 PPTWriter (this=0x15807d0, rSvStorage=@0x7fff894f5340, rXModel=@0x142a2e8, rXStatInd=@0x142a2f0, pVBA=0x0,
+ nCnvrtFlags=15) at /local/ooxml/ooxml/sd/source/filter/eppt/eppt.cxx:268
+ #1 0x00002aaab3895719 in ExportPPT (rSvStorage=@0x7fff894f5340, rXModel=@0x142a2e8, rXStatInd=@0x142a2f0,
+ pVBA=0x0, nCnvrtFlags=15) at /local/ooxml/ooxml/sd/source/filter/eppt/eppt.cxx:2503
+ #2 0x00002aaaadef85b7 in SdPage::onParagraphRemoving ()
+ from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program/libsdlx.so
+ #3 0x00002aaaade202e3 in sd::DrawDocShell::ConvertTo ()
+ from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program/libsdlx.so
+ #4 0x00002aec23119b58 in SfxObjectShell::DoLoad ()
+ from /local/ooxml/inst/openoffice.org3.0/program/../basis-link/program//libsfxlx.so
+
+- odp export
+ #0 ZipPackage (this=0x1805e80, xNewFactory=@0x7fffe284e990) at /home/rodo/git/ooxml/package/source/zippackage/ZipPackage.cxx:279
+ #1 0x00002aaaadd3dc94 in ZipPackage_createInstance (xMgr=@0x7fffe284e990) at /home/rodo/git/ooxml/package/source/zippackage/ZipPackage.cxx:1546
+ #2 0x00002b0fca7ab6b3 in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3
+ #3 0x00002b0fca7a7fda in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3
+ #4 0x00002b0fca7a811e in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3
+ #5 0x00002b0fca7aa7cc in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3
+ #6 0x00002b0fca7aacbe in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3
+ #7 0x00002b0fca7aa035 in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/../ure-link/lib/libuno_cppuhelpergcc3.so.3
+ #8 0x00002aaaaadae1b3 in ?? () from /opt/openoffice.org/ure/lib/bootstrap.uno.so
+ #9 0x00002aaaaadaa84c in ?? () from /opt/openoffice.org/ure/lib/bootstrap.uno.so
+ #10 0x00002aaab5c7a7e5 in OStorage_Impl::OpenOwnPackage (this=0x185cac0) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:549
+ #11 0x00002aaab5c7ab3e in OStorage_Impl::ReadContents (this=0x185cac0) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:649
+ #12 0x00002aaab5c7d32f in OStorage_Impl::FindElement (this=0x185cac0, rName=@0x7fffe284f280) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:1387
+ #13 0x00002aaab5c7dc45 in OStorage::hasByName (this=0x1808880, aName=@0x7fffe284f280) at /home/rodo/git/ooxml/package/source/xstor/xstorage.cxx:4045
+ #14 0x00002aaab1fde8c5 in XMLVersionListPersistence::load () from /opt/openoffice.org3.0/program/../basis-link/program/libxolx.so
+ #15 0x00002b0fcb058bb2 in SfxMedium::GetVersionList (this=0x1750050, _bNoReload=false) at /home/rodo/git/ooxml/sfx2/source/doc/docfile.cxx:3247
+ #16 0x00002b0fcb0571b5 in SfxMedium::GetStorage (this=0x1750050) at /home/rodo/git/ooxml/sfx2/source/doc/docfile.cxx:1328
+ #17 0x00002b0fcb05d0d7 in SfxMedium::GetOutputStorage (this=0x1750050) at /home/rodo/git/ooxml/sfx2/source/doc/docfile.cxx:1068
+ #18 0x00002b0fcb091227 in SfxObjectShell::SaveTo_Impl (this=0xf44d60, rMedium=@0x1750050, pSet=0x0) at /home/rodo/git/ooxml/sfx2/source/doc/objstor.cxx:1557
+ #19 0x00002b0fcb09443c in SfxObjectShell::PreDoSaveAs_Impl (this=0xf44d60, rFileName=@0x7fffe2850700, aFilterName=@0x7fffe28507f0, pParams=0xf10c10)
+ at /home/rodo/git/ooxml/sfx2/source/doc/objstor.cxx:2984
+ #20 0x00002b0fcb094ea5 in SfxObjectShell::CommonSaveAs_Impl (this=0xf44d60, aURL=@0x7fffe2850870, aFilterName=@0x7fffe28507f0, aParams=0x1740310)
+ at /home/rodo/git/ooxml/sfx2/source/doc/objstor.cxx:2855
+ #21 0x00002b0fcb0a1da2 in SfxObjectShell::APISaveAs_Impl (this=0xf44d60, aFileName=@0x7fffe2850b70, aParams=0x1740310)
+ at /home/rodo/git/ooxml/sfx2/source/doc/objserv.cxx:432
+ #22 0x00002b0fcb0e74c8 in SfxBaseModel::impl_store (this=0xf96a00, sURL=@0x7fffe28516b0, seqArguments=@0x7fffe2851ae0, bSaveTo=0 '\0')
+ at /home/rodo/git/ooxml/sfx2/source/doc/sfxbasemodel.cxx:2591
+ #23 0x00002b0fcb0f124b in SfxBaseModel::storeAsURL (this=0xf96a00, rURL=@0x7fffe28516b0, rArgs=@0x7fffe2851ae0)
+ at /home/rodo/git/ooxml/sfx2/source/doc/sfxbasemodel.cxx:1568
+ #24 0x00002b0fcb101d3d in SfxStoringHelper::GUIStoreModel (this=0x7fffe28519f0, xModel=@0xf18798, aSlotName=@0x7fffe2852200, aArgsSequence=@0x7fffe2851ae0,
+ bPreselectPassword=0 '\0') at /home/rodo/git/ooxml/sfx2/source/doc/guisaveas.cxx:1529
+ #25 0x00002b0fcb0a4051 in SfxObjectShell::ExecFile_Impl (this=0xf44d60, rReq=@0x1484f20) at /home/rodo/git/ooxml/sfx2/source/doc/objserv.cxx:744
+ #26 0x00002b0fcb0a5c73 in SfxStubSfxObjectShellExecFile_Impl (pShell=0xf44d60, rReq=@0x1484f20) at ../../unxlngx6.pro/inc/sfxslots.hxx:161
+ #27 0x00002b0fcb17f398 in SfxShell::CallExec (this=0xf44d60, pFunc=0x2b0fcb0a5c56 <SfxStubSfxObjectShellExecFile_Impl(SfxShell*, SfxRequest&)>, rReq=@0x1484f20)
+ at ../../inc/sfx2/shell.hxx:226
+ #28 0x00002b0fcb17cec3 in SfxDispatcher::Call_Impl (this=0x110fde0, rShell=@0xf44d60, rSlot=@0x2b0fcb576368, rReq=@0x1484f20, bRecord=1 '\001')
+ at /home/rodo/git/ooxml/sfx2/source/control/dispatch.cxx:338
+ #29 0x00002b0fcb17d3f2 in SfxDispatcher::PostMsgHandler (this=0x110fde0, pReq=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/control/dispatch.cxx:1643
+ #30 0x00002b0fcb17d51d in SfxDispatcher::LinkStubPostMsgHandler (pThis=0x110fde0, pCaller=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/control/dispatch.cxx:1610
+ #31 0x00002b0fcafb3e70 in Link::Call (this=0x11488f8, pCaller=0x1484f20) at /home/rodo/git/ooxml/solver/300/unxlngx6.pro/inc/tools/link.hxx:158
+ #32 0x00002b0fcb1a9952 in GenLink::Call (this=0x11488f8, pCaller=0x1484f20) at ../../inc/sfx2/genlink.hxx:63
+ #33 0x00002b0fcb1a9773 in SfxHintPoster::Event (this=0x11488e0, pPostedHint=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/notify/hintpost.cxx:98
+ #34 0x00002b0fcb1a9984 in SfxHintPoster::DoEvent_Impl (this=0x11488e0, pPostedHint=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/notify/hintpost.cxx:88
+ #35 0x00002b0fcb1a974f in SfxHintPoster::LinkStubDoEvent_Impl (pThis=0x11488e0, pCaller=0x1484f20) at /home/rodo/git/ooxml/sfx2/source/notify/hintpost.cxx:92
+ #36 0x00002b0fccef69f8 in ImplWindowFrameProc () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so
+ #37 0x00002b0fd3f91f8f in SalDisplay::DispatchInternalEvent () from /opt/openoffice.org/basis3.0/program/libvclplug_genlx.so
+ #38 0x00002b0fd0fa4a84 in GtkXLib::userEventFn () from /opt/openoffice.org/basis3.0/program/libvclplug_gtklx.so
+ #39 0x00002b0fd3cb0204 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
+ #40 0x00002b0fd3cb34fd in ?? () from /usr/lib64/libglib-2.0.so.0
+ #41 0x00002b0fd3cb39ce in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
+ #42 0x00002b0fd0fa4fd9 in GtkXLib::Yield () from /opt/openoffice.org/basis3.0/program/libvclplug_gtklx.so
+ #43 0x00002b0fccd1859e in Application::Yield () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so
+ #44 0x00002b0fccd18677 in Application::Execute () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so
+ #45 0x00002b0fc86fd803 in ?? () from /opt/openoffice.org3.0/program/../basis-link/program/libsoffice.so
+ #46 0x00002b0fccd1da24 in ImplSVMain () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so
+ #47 0x00002b0fccd1db15 in SVMain () from /opt/openoffice.org3.0/program/../basis-link/program/libvcllx.so
+ #48 0x00002b0fc872fe6c in soffice_main () from /opt/openoffice.org3.0/program/../basis-link/program/libsoffice.so
+ #49 0x000000000040114b in main ()